Commit 2dc1e488 authored by Yonghong Song's avatar Yonghong Song Committed by Alexei Starovoitov

libbpf: Support BTF_KIND_TYPE_TAG

Add libbpf support for BTF_KIND_TYPE_TAG.
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20211112012614.1505315-1-yhs@fb.com
parent 8c42d2fa
...@@ -299,6 +299,7 @@ static int btf_type_size(const struct btf_type *t) ...@@ -299,6 +299,7 @@ static int btf_type_size(const struct btf_type *t)
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_FLOAT: case BTF_KIND_FLOAT:
case BTF_KIND_TYPE_TAG:
return base_size; return base_size;
case BTF_KIND_INT: case BTF_KIND_INT:
return base_size + sizeof(__u32); return base_size + sizeof(__u32);
...@@ -349,6 +350,7 @@ static int btf_bswap_type_rest(struct btf_type *t) ...@@ -349,6 +350,7 @@ static int btf_bswap_type_rest(struct btf_type *t)
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_FLOAT: case BTF_KIND_FLOAT:
case BTF_KIND_TYPE_TAG:
return 0; return 0;
case BTF_KIND_INT: case BTF_KIND_INT:
*(__u32 *)(t + 1) = bswap_32(*(__u32 *)(t + 1)); *(__u32 *)(t + 1) = bswap_32(*(__u32 *)(t + 1));
...@@ -649,6 +651,7 @@ int btf__align_of(const struct btf *btf, __u32 id) ...@@ -649,6 +651,7 @@ int btf__align_of(const struct btf *btf, __u32 id)
case BTF_KIND_VOLATILE: case BTF_KIND_VOLATILE:
case BTF_KIND_CONST: case BTF_KIND_CONST:
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
case BTF_KIND_TYPE_TAG:
return btf__align_of(btf, t->type); return btf__align_of(btf, t->type);
case BTF_KIND_ARRAY: case BTF_KIND_ARRAY:
return btf__align_of(btf, btf_array(t)->type); return btf__align_of(btf, btf_array(t)->type);
...@@ -2235,6 +2238,22 @@ int btf__add_restrict(struct btf *btf, int ref_type_id) ...@@ -2235,6 +2238,22 @@ int btf__add_restrict(struct btf *btf, int ref_type_id)
return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id); return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id);
} }
/*
* Append new BTF_KIND_TYPE_TAG type with:
* - *value*, non-empty/non-NULL tag value;
* - *ref_type_id* - referenced type ID, it might not exist yet;
* Returns:
* - >0, type ID of newly added BTF type;
* - <0, on error.
*/
int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id)
{
if (!value|| !value[0])
return libbpf_err(-EINVAL);
return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id);
}
/* /*
* Append new BTF_KIND_FUNC type with: * Append new BTF_KIND_FUNC type with:
* - *name*, non-empty/non-NULL name; * - *name*, non-empty/non-NULL name;
...@@ -3639,6 +3658,7 @@ static int btf_dedup_prep(struct btf_dedup *d) ...@@ -3639,6 +3658,7 @@ static int btf_dedup_prep(struct btf_dedup *d)
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_FLOAT: case BTF_KIND_FLOAT:
case BTF_KIND_TYPE_TAG:
h = btf_hash_common(t); h = btf_hash_common(t);
break; break;
case BTF_KIND_INT: case BTF_KIND_INT:
...@@ -3699,6 +3719,7 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) ...@@ -3699,6 +3719,7 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DATASEC: case BTF_KIND_DATASEC:
case BTF_KIND_DECL_TAG: case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
return 0; return 0;
case BTF_KIND_INT: case BTF_KIND_INT:
...@@ -4297,6 +4318,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) ...@@ -4297,6 +4318,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
case BTF_KIND_PTR: case BTF_KIND_PTR:
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_TYPE_TAG:
ref_type_id = btf_dedup_ref_type(d, t->type); ref_type_id = btf_dedup_ref_type(d, t->type);
if (ref_type_id < 0) if (ref_type_id < 0)
return ref_type_id; return ref_type_id;
...@@ -4603,6 +4625,7 @@ int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ct ...@@ -4603,6 +4625,7 @@ int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ct
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG: case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
return visit(&t->type, ctx); return visit(&t->type, ctx);
case BTF_KIND_ARRAY: { case BTF_KIND_ARRAY: {
......
...@@ -227,6 +227,7 @@ LIBBPF_API int btf__add_typedef(struct btf *btf, const char *name, int ref_type_ ...@@ -227,6 +227,7 @@ LIBBPF_API int btf__add_typedef(struct btf *btf, const char *name, int ref_type_
LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id);
LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id);
LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id);
LIBBPF_API int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id);
/* func and func_proto construction APIs */ /* func and func_proto construction APIs */
LIBBPF_API int btf__add_func(struct btf *btf, const char *name, LIBBPF_API int btf__add_func(struct btf *btf, const char *name,
...@@ -458,7 +459,8 @@ static inline bool btf_is_mod(const struct btf_type *t) ...@@ -458,7 +459,8 @@ static inline bool btf_is_mod(const struct btf_type *t)
return kind == BTF_KIND_VOLATILE || return kind == BTF_KIND_VOLATILE ||
kind == BTF_KIND_CONST || kind == BTF_KIND_CONST ||
kind == BTF_KIND_RESTRICT; kind == BTF_KIND_RESTRICT ||
kind == BTF_KIND_TYPE_TAG;
} }
static inline bool btf_is_func(const struct btf_type *t) static inline bool btf_is_func(const struct btf_type *t)
...@@ -491,6 +493,11 @@ static inline bool btf_is_decl_tag(const struct btf_type *t) ...@@ -491,6 +493,11 @@ static inline bool btf_is_decl_tag(const struct btf_type *t)
return btf_kind(t) == BTF_KIND_DECL_TAG; return btf_kind(t) == BTF_KIND_DECL_TAG;
} }
static inline bool btf_is_type_tag(const struct btf_type *t)
{
return btf_kind(t) == BTF_KIND_TYPE_TAG;
}
static inline __u8 btf_int_encoding(const struct btf_type *t) static inline __u8 btf_int_encoding(const struct btf_type *t)
{ {
return BTF_INT_ENCODING(*(__u32 *)(t + 1)); return BTF_INT_ENCODING(*(__u32 *)(t + 1));
......
...@@ -330,6 +330,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d) ...@@ -330,6 +330,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_VAR: case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG: case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
d->type_states[t->type].referenced = 1; d->type_states[t->type].referenced = 1;
break; break;
...@@ -573,6 +574,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) ...@@ -573,6 +574,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
case BTF_KIND_VOLATILE: case BTF_KIND_VOLATILE:
case BTF_KIND_CONST: case BTF_KIND_CONST:
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
case BTF_KIND_TYPE_TAG:
return btf_dump_order_type(d, t->type, through_ptr); return btf_dump_order_type(d, t->type, through_ptr);
case BTF_KIND_FUNC_PROTO: { case BTF_KIND_FUNC_PROTO: {
...@@ -747,6 +749,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) ...@@ -747,6 +749,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
case BTF_KIND_VOLATILE: case BTF_KIND_VOLATILE:
case BTF_KIND_CONST: case BTF_KIND_CONST:
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
case BTF_KIND_TYPE_TAG:
btf_dump_emit_type(d, t->type, cont_id); btf_dump_emit_type(d, t->type, cont_id);
break; break;
case BTF_KIND_ARRAY: case BTF_KIND_ARRAY:
...@@ -1167,6 +1170,7 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id, ...@@ -1167,6 +1170,7 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
case BTF_KIND_CONST: case BTF_KIND_CONST:
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
case BTF_KIND_FUNC_PROTO: case BTF_KIND_FUNC_PROTO:
case BTF_KIND_TYPE_TAG:
id = t->type; id = t->type;
break; break;
case BTF_KIND_ARRAY: case BTF_KIND_ARRAY:
...@@ -1335,6 +1339,11 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, ...@@ -1335,6 +1339,11 @@ static void btf_dump_emit_type_chain(struct btf_dump *d,
case BTF_KIND_RESTRICT: case BTF_KIND_RESTRICT:
btf_dump_printf(d, " restrict"); btf_dump_printf(d, " restrict");
break; break;
case BTF_KIND_TYPE_TAG:
btf_dump_emit_mods(d, decls);
name = btf_name_of(d, t->name_off);
btf_dump_printf(d, " __attribute__((btf_type_tag(\"%s\")))", name);
break;
case BTF_KIND_ARRAY: { case BTF_KIND_ARRAY: {
const struct btf_array *a = btf_array(t); const struct btf_array *a = btf_array(t);
const struct btf_type *next_t; const struct btf_type *next_t;
......
...@@ -197,6 +197,8 @@ enum kern_feature_id { ...@@ -197,6 +197,8 @@ enum kern_feature_id {
FEAT_PERF_LINK, FEAT_PERF_LINK,
/* BTF_KIND_DECL_TAG support */ /* BTF_KIND_DECL_TAG support */
FEAT_BTF_DECL_TAG, FEAT_BTF_DECL_TAG,
/* BTF_KIND_TYPE_TAG support */
FEAT_BTF_TYPE_TAG,
__FEAT_CNT, __FEAT_CNT,
}; };
...@@ -2076,6 +2078,7 @@ static const char *__btf_kind_str(__u16 kind) ...@@ -2076,6 +2078,7 @@ static const char *__btf_kind_str(__u16 kind)
case BTF_KIND_DATASEC: return "datasec"; case BTF_KIND_DATASEC: return "datasec";
case BTF_KIND_FLOAT: return "float"; case BTF_KIND_FLOAT: return "float";
case BTF_KIND_DECL_TAG: return "decl_tag"; case BTF_KIND_DECL_TAG: return "decl_tag";
case BTF_KIND_TYPE_TAG: return "type_tag";
default: return "unknown"; default: return "unknown";
} }
} }
...@@ -2588,8 +2591,10 @@ static bool btf_needs_sanitization(struct bpf_object *obj) ...@@ -2588,8 +2591,10 @@ static bool btf_needs_sanitization(struct bpf_object *obj)
bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT); bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT);
bool has_func = kernel_supports(obj, FEAT_BTF_FUNC); bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);
bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG); bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
return !has_func || !has_datasec || !has_func_global || !has_float || !has_decl_tag; return !has_func || !has_datasec || !has_func_global || !has_float ||
!has_decl_tag || !has_type_tag;
} }
static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
...@@ -2599,6 +2604,7 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) ...@@ -2599,6 +2604,7 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT); bool has_float = kernel_supports(obj, FEAT_BTF_FLOAT);
bool has_func = kernel_supports(obj, FEAT_BTF_FUNC); bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);
bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG); bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
struct btf_type *t; struct btf_type *t;
int i, j, vlen; int i, j, vlen;
...@@ -2657,6 +2663,10 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) ...@@ -2657,6 +2663,10 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
*/ */
t->name_off = 0; t->name_off = 0;
t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 0); t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 0);
} else if (!has_type_tag && btf_is_type_tag(t)) {
/* replace TYPE_TAG with a CONST */
t->name_off = 0;
t->info = BTF_INFO_ENC(BTF_KIND_CONST, 0, 0);
} }
} }
} }
...@@ -4460,6 +4470,22 @@ static int probe_kern_btf_decl_tag(void) ...@@ -4460,6 +4470,22 @@ static int probe_kern_btf_decl_tag(void)
strs, sizeof(strs))); strs, sizeof(strs)));
} }
static int probe_kern_btf_type_tag(void)
{
static const char strs[] = "\0tag";
__u32 types[] = {
/* int */
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* attr */
BTF_TYPE_TYPE_TAG_ENC(1, 1), /* [2] */
/* ptr */
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), /* [3] */
};
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs)));
}
static int probe_kern_array_mmap(void) static int probe_kern_array_mmap(void)
{ {
struct bpf_create_map_attr attr = { struct bpf_create_map_attr attr = {
...@@ -4657,6 +4683,9 @@ static struct kern_feature_desc { ...@@ -4657,6 +4683,9 @@ static struct kern_feature_desc {
[FEAT_BTF_DECL_TAG] = { [FEAT_BTF_DECL_TAG] = {
"BTF_KIND_DECL_TAG support", probe_kern_btf_decl_tag, "BTF_KIND_DECL_TAG support", probe_kern_btf_decl_tag,
}, },
[FEAT_BTF_TYPE_TAG] = {
"BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag,
},
}; };
static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)
......
...@@ -403,6 +403,7 @@ LIBBPF_0.6.0 { ...@@ -403,6 +403,7 @@ LIBBPF_0.6.0 {
bpf_program__set_extra_flags; bpf_program__set_extra_flags;
btf__add_btf; btf__add_btf;
btf__add_decl_tag; btf__add_decl_tag;
btf__add_type_tag;
btf__dedup; btf__dedup;
btf__dedup_deprecated; btf__dedup_deprecated;
btf__raw_data; btf__raw_data;
......
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz) BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
#define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \ #define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \
BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx) BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx)
#define BTF_TYPE_TYPE_TAG_ENC(value, type) \
BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_TYPE_TAG, 0, 0), type)
#ifndef likely #ifndef likely
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment