mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-07 00:59:07 +08:00
libbpf: Add enum64 deduplication support
Add enum64 deduplication support. BTF_KIND_ENUM64 handling is very similar to BTF_KIND_ENUM. Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/r/20220607062626.3720166-1-yhs@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Andrii Nakryiko
parent
c3f8eecb16
commit
25238de149
62
src/btf.c
62
src/btf.c
@@ -3582,7 +3582,7 @@ static bool btf_equal_int_tag(struct btf_type *t1, struct btf_type *t2)
|
|||||||
return info1 == info2;
|
return info1 == info2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate type signature hash of ENUM. */
|
/* Calculate type signature hash of ENUM/ENUM64. */
|
||||||
static long btf_hash_enum(struct btf_type *t)
|
static long btf_hash_enum(struct btf_type *t)
|
||||||
{
|
{
|
||||||
long h;
|
long h;
|
||||||
@@ -3616,9 +3616,31 @@ static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool btf_equal_enum64(struct btf_type *t1, struct btf_type *t2)
|
||||||
|
{
|
||||||
|
const struct btf_enum64 *m1, *m2;
|
||||||
|
__u16 vlen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!btf_equal_common(t1, t2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vlen = btf_vlen(t1);
|
||||||
|
m1 = btf_enum64(t1);
|
||||||
|
m2 = btf_enum64(t2);
|
||||||
|
for (i = 0; i < vlen; i++) {
|
||||||
|
if (m1->name_off != m2->name_off || m1->val_lo32 != m2->val_lo32 ||
|
||||||
|
m1->val_hi32 != m2->val_hi32)
|
||||||
|
return false;
|
||||||
|
m1++;
|
||||||
|
m2++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool btf_is_enum_fwd(struct btf_type *t)
|
static inline bool btf_is_enum_fwd(struct btf_type *t)
|
||||||
{
|
{
|
||||||
return btf_is_enum(t) && btf_vlen(t) == 0;
|
return btf_is_any_enum(t) && btf_vlen(t) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
|
static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
|
||||||
@@ -3631,6 +3653,17 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
|
|||||||
t1->size == t2->size;
|
t1->size == t2->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool btf_compat_enum64(struct btf_type *t1, struct btf_type *t2)
|
||||||
|
{
|
||||||
|
if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2))
|
||||||
|
return btf_equal_enum64(t1, t2);
|
||||||
|
|
||||||
|
/* ignore vlen when comparing */
|
||||||
|
return t1->name_off == t2->name_off &&
|
||||||
|
(t1->info & ~0xffff) == (t2->info & ~0xffff) &&
|
||||||
|
t1->size == t2->size;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs,
|
* Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs,
|
||||||
* as referenced type IDs equivalence is established separately during type
|
* as referenced type IDs equivalence is established separately during type
|
||||||
@@ -3843,6 +3876,7 @@ static int btf_dedup_prep(struct btf_dedup *d)
|
|||||||
h = btf_hash_int_decl_tag(t);
|
h = btf_hash_int_decl_tag(t);
|
||||||
break;
|
break;
|
||||||
case BTF_KIND_ENUM:
|
case BTF_KIND_ENUM:
|
||||||
|
case BTF_KIND_ENUM64:
|
||||||
h = btf_hash_enum(t);
|
h = btf_hash_enum(t);
|
||||||
break;
|
break;
|
||||||
case BTF_KIND_STRUCT:
|
case BTF_KIND_STRUCT:
|
||||||
@@ -3932,6 +3966,27 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BTF_KIND_ENUM64:
|
||||||
|
h = btf_hash_enum(t);
|
||||||
|
for_each_dedup_cand(d, hash_entry, h) {
|
||||||
|
cand_id = (__u32)(long)hash_entry->value;
|
||||||
|
cand = btf_type_by_id(d->btf, cand_id);
|
||||||
|
if (btf_equal_enum64(t, cand)) {
|
||||||
|
new_id = cand_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (btf_compat_enum64(t, cand)) {
|
||||||
|
if (btf_is_enum_fwd(t)) {
|
||||||
|
/* resolve fwd to full enum */
|
||||||
|
new_id = cand_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* resolve canonical enum fwd to full enum */
|
||||||
|
d->map[cand_id] = type_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case BTF_KIND_FWD:
|
case BTF_KIND_FWD:
|
||||||
case BTF_KIND_FLOAT:
|
case BTF_KIND_FLOAT:
|
||||||
h = btf_hash_common(t);
|
h = btf_hash_common(t);
|
||||||
@@ -4227,6 +4282,9 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
|
|||||||
case BTF_KIND_ENUM:
|
case BTF_KIND_ENUM:
|
||||||
return btf_compat_enum(cand_type, canon_type);
|
return btf_compat_enum(cand_type, canon_type);
|
||||||
|
|
||||||
|
case BTF_KIND_ENUM64:
|
||||||
|
return btf_compat_enum64(cand_type, canon_type);
|
||||||
|
|
||||||
case BTF_KIND_FWD:
|
case BTF_KIND_FWD:
|
||||||
case BTF_KIND_FLOAT:
|
case BTF_KIND_FLOAT:
|
||||||
return btf_equal_common(cand_type, canon_type);
|
return btf_equal_common(cand_type, canon_type);
|
||||||
|
|||||||
@@ -531,6 +531,11 @@ static inline bool btf_is_type_tag(const struct btf_type *t)
|
|||||||
return btf_kind(t) == BTF_KIND_TYPE_TAG;
|
return btf_kind(t) == BTF_KIND_TYPE_TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_any_enum(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_is_enum(t) || btf_is_enum64(t);
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
|||||||
Reference in New Issue
Block a user