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

f869ca
From 16277e3910c9281d807fc6d3b4ce41c62d7d265e 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
f869ca
Some fields can belong to unnamed struct or union (e.g. rcu and
f869ca
rcu_users fields of task_struct). In C, they are accessed as if their
f869ca
belong directly to the parent of the unnamed struct or union but this
f869ca
is not the case for BTF.
80e6d8
80e6d8
When looking for a field, kernel_struct_has_field should also look
f869ca
reccursively into unnamed structs or unions. That allows code such as
f869ca
the following to work as expected:
f869ca
f869ca
BPF.kernel_struct_has_field('task_struct', 'rcu')
f869ca
f869ca
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
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
f869ca
index 5f7a3f68..bdfde1f5 100644
80e6d8
--- a/src/cc/libbpf.c
80e6d8
+++ b/src/cc/libbpf.c
f869ca
@@ -1319,12 +1319,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);
f869ca
@@ -1338,14 +1353,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
-- 
f869ca
2.38.1
80e6d8