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

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