From e9ae2826b8712d491362771233ed6bf21ae1a07a Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Thu, 19 May 2022 16:37:40 +0200 Subject: [PATCH 3/3] libbpf: Allow kernel_struct_has_field to reach field in unnamed struct or union Some field can belong to unnamed struct or union. In C, they are accessed as if their belong directly to the parent struct or union but this is not the case for BTF. When looking for a field, kernel_struct_has_field should also look reccursively into unnamed structs or unions. --- src/cc/libbpf.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c index 7410ae1a..e98b8852 100644 --- a/src/cc/libbpf.c +++ b/src/cc/libbpf.c @@ -1302,12 +1302,27 @@ bool bpf_has_kernel_btf(void) return true; } +static int find_member_by_name(struct btf *btf, const struct btf_type *btf_type, const char *field_name) { + const struct btf_member *btf_member = btf_members(btf_type); + int i; + + for (i = 0; i < btf_vlen(btf_type); i++, btf_member++) { + const char *name = btf__name_by_offset(btf, btf_member->name_off); + if (!strcmp(name, field_name)) { + return 1; + } else if (name[0] == '\0') { + if (find_member_by_name(btf, btf__type_by_id(btf, btf_member->type), field_name)) + return 1; + } + } + return 0; +} + int kernel_struct_has_field(const char *struct_name, const char *field_name) { const struct btf_type *btf_type; - const struct btf_member *btf_member; struct btf *btf; - int i, ret, btf_id; + int ret, btf_id; btf = libbpf_find_kernel_btf(); ret = libbpf_get_error(btf); @@ -1321,14 +1336,7 @@ int kernel_struct_has_field(const char *struct_name, const char *field_name) } btf_type = btf__type_by_id(btf, btf_id); - btf_member = btf_members(btf_type); - for (i = 0; i < btf_vlen(btf_type); i++, btf_member++) { - if (!strcmp(btf__name_by_offset(btf, btf_member->name_off), field_name)) { - ret = 1; - goto cleanup; - } - } - ret = 0; + ret = find_member_by_name(btf, btf_type, field_name); cleanup: btf__free(btf); -- 2.35.3