Blame SOURCES/bcc-0.24.0-libbpf-Allow-kernel_struct_has_field-to-reach-field-.patch

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