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

425d11
From 16277e3910c9281d807fc6d3b4ce41c62d7d265e Mon Sep 17 00:00:00 2001
243a81
From: Jerome Marchand <jmarchan@redhat.com>
243a81
Date: Thu, 19 May 2022 16:37:40 +0200
243a81
Subject: [PATCH 3/3] libbpf: Allow kernel_struct_has_field to reach field in
243a81
 unnamed struct or union
243a81
425d11
Some fields can belong to unnamed struct or union (e.g. rcu and
425d11
rcu_users fields of task_struct). In C, they are accessed as if their
425d11
belong directly to the parent of the unnamed struct or union but this
425d11
is not the case for BTF.
243a81
243a81
When looking for a field, kernel_struct_has_field should also look
425d11
reccursively into unnamed structs or unions. That allows code such as
425d11
the following to work as expected:
425d11
425d11
BPF.kernel_struct_has_field('task_struct', 'rcu')
425d11
425d11
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
243a81
---
243a81
 src/cc/libbpf.c | 28 ++++++++++++++++++----------
243a81
 1 file changed, 18 insertions(+), 10 deletions(-)
243a81
243a81
diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
425d11
index 5f7a3f68..bdfde1f5 100644
243a81
--- a/src/cc/libbpf.c
243a81
+++ b/src/cc/libbpf.c
425d11
@@ -1319,12 +1319,27 @@ bool bpf_has_kernel_btf(void)
243a81
   return true;
243a81
 }
243a81
 
243a81
+static int find_member_by_name(struct btf *btf, const struct btf_type *btf_type, const char *field_name) {
243a81
+  const struct btf_member *btf_member = btf_members(btf_type);
243a81
+  int i;
243a81
+
243a81
+  for (i = 0; i < btf_vlen(btf_type); i++, btf_member++) {
243a81
+    const char *name = btf__name_by_offset(btf, btf_member->name_off);
243a81
+    if (!strcmp(name, field_name)) {
243a81
+      return 1;
243a81
+    } else if (name[0] == '\0') {
243a81
+      if (find_member_by_name(btf, btf__type_by_id(btf, btf_member->type), field_name))
243a81
+        return 1;
243a81
+    }
243a81
+  }
243a81
+  return 0;
243a81
+}
243a81
+
243a81
 int kernel_struct_has_field(const char *struct_name, const char *field_name)
243a81
 {
243a81
   const struct btf_type *btf_type;
243a81
-  const struct btf_member *btf_member;
243a81
   struct btf *btf;
243a81
-  int i, ret, btf_id;
243a81
+  int ret, btf_id;
243a81
 
243a81
   btf = libbpf_find_kernel_btf();
243a81
   ret = libbpf_get_error(btf);
425d11
@@ -1338,14 +1353,7 @@ int kernel_struct_has_field(const char *struct_name, const char *field_name)
243a81
   }
243a81
 
243a81
   btf_type = btf__type_by_id(btf, btf_id);
243a81
-  btf_member = btf_members(btf_type);
243a81
-  for (i = 0; i < btf_vlen(btf_type); i++, btf_member++) {
243a81
-    if (!strcmp(btf__name_by_offset(btf, btf_member->name_off), field_name)) {
243a81
-      ret = 1;
243a81
-      goto cleanup;
243a81
-    }
243a81
-  }
243a81
-  ret = 0;
243a81
+  ret = find_member_by_name(btf, btf_type, field_name);
243a81
 
243a81
 cleanup:
243a81
   btf__free(btf);
243a81
-- 
425d11
2.38.1
243a81