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