Blob Blame History Raw
From e9ae2826b8712d491362771233ed6bf21ae1a07a Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
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