Blame SOURCES/bcc-0.24.0-C9S-libpbf-version-fixes.patch

f5d2bd
From a81f219d7f2bfc70dba1eb12208e3e6ab7c81b50 Mon Sep 17 00:00:00 2001
f5d2bd
From: Jerome Marchand <jmarchan@redhat.com>
f5d2bd
Date: Thu, 24 Mar 2022 16:08:17 +0100
f5d2bd
Subject: [PATCH] C9S: libpbf version fixes
f5d2bd
f5d2bd
Revert "bcc: Replace deprecated libbpf APIs" since the libbpf version
f5d2bd
provided in C9S doesn't provide the new APIs.
f5d2bd
f5d2bd
Remove BPF_MAP_TYPE_BLOOM_FILTER from bps since the libbpf version in
f5d2bd
C9S, doesn't provide bloom filter map.
f5d2bd
f5d2bd
Add definition of struct bpf_core_relo.
f5d2bd
---
f5d2bd
 introspection/bps.c |  1 -
f5d2bd
 src/cc/bcc_btf.cc   | 73 +++++++++++++++++++++++++++++++++++++++-
f5d2bd
 src/cc/libbpf.c     | 82 ++++++---------------------------------------
f5d2bd
 3 files changed, 83 insertions(+), 73 deletions(-)
f5d2bd
f5d2bd
diff --git a/introspection/bps.c b/introspection/bps.c
f5d2bd
index 232b23d4..6ec02e6c 100644
f5d2bd
--- a/introspection/bps.c
f5d2bd
+++ b/introspection/bps.c
f5d2bd
@@ -80,7 +80,6 @@ static const char * const map_type_strings[] = {
f5d2bd
   [BPF_MAP_TYPE_RINGBUF] = "ringbuf",
f5d2bd
   [BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage",
f5d2bd
   [BPF_MAP_TYPE_TASK_STORAGE] = "task_storage",
f5d2bd
-  [BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter",
f5d2bd
 };
f5d2bd
 
f5d2bd
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
f5d2bd
diff --git a/src/cc/bcc_btf.cc b/src/cc/bcc_btf.cc
f5d2bd
index 7f551ae8..c78ba823 100644
f5d2bd
--- a/src/cc/bcc_btf.cc
f5d2bd
+++ b/src/cc/bcc_btf.cc
f5d2bd
@@ -170,6 +170,77 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
f5d2bd
         return btf_ext_setup_info(btf_ext, ¶m;;
f5d2bd
 }
f5d2bd
 
f5d2bd
+/* bpf_core_relo_kind encodes which aspect of captured field/type/enum value
f5d2bd
+ * has to be adjusted by relocations.
f5d2bd
+ */
f5d2bd
+enum bpf_core_relo_kind {
f5d2bd
+	BPF_FIELD_BYTE_OFFSET = 0,	/* field byte offset */
f5d2bd
+	BPF_FIELD_BYTE_SIZE = 1,	/* field size in bytes */
f5d2bd
+	BPF_FIELD_EXISTS = 2,		/* field existence in target kernel */
f5d2bd
+	BPF_FIELD_SIGNED = 3,		/* field signedness (0 - unsigned, 1 - signed) */
f5d2bd
+	BPF_FIELD_LSHIFT_U64 = 4,	/* bitfield-specific left bitshift */
f5d2bd
+	BPF_FIELD_RSHIFT_U64 = 5,	/* bitfield-specific right bitshift */
f5d2bd
+	BPF_TYPE_ID_LOCAL = 6,		/* type ID in local BPF object */
f5d2bd
+	BPF_TYPE_ID_TARGET = 7,		/* type ID in target kernel */
f5d2bd
+	BPF_TYPE_EXISTS = 8,		/* type existence in target kernel */
f5d2bd
+	BPF_TYPE_SIZE = 9,		/* type size in bytes */
f5d2bd
+	BPF_ENUMVAL_EXISTS = 10,	/* enum value existence in target kernel */
f5d2bd
+	BPF_ENUMVAL_VALUE = 11,		/* enum value integer value */
f5d2bd
+};
f5d2bd
+
f5d2bd
+/* The minimum bpf_core_relo checked by the loader
f5d2bd
+ *
f5d2bd
+ * CO-RE relocation captures the following data:
f5d2bd
+ * - insn_off - instruction offset (in bytes) within a BPF program that needs
f5d2bd
+ *   its insn->imm field to be relocated with actual field info;
f5d2bd
+ * - type_id - BTF type ID of the "root" (containing) entity of a relocatable
f5d2bd
+ *   type or field;
f5d2bd
+ * - access_str_off - offset into corresponding .BTF string section. String
f5d2bd
+ *   interpretation depends on specific relocation kind:
f5d2bd
+ *     - for field-based relocations, string encodes an accessed field using
f5d2bd
+ *     a sequence of field and array indices, separated by colon (:). It's
f5d2bd
+ *     conceptually very close to LLVM's getelementptr ([0]) instruction's
f5d2bd
+ *     arguments for identifying offset to a field.
f5d2bd
+ *     - for type-based relocations, strings is expected to be just "0";
f5d2bd
+ *     - for enum value-based relocations, string contains an index of enum
f5d2bd
+ *     value within its enum type;
f5d2bd
+ *
f5d2bd
+ * Example to provide a better feel.
f5d2bd
+ *
f5d2bd
+ *   struct sample {
f5d2bd
+ *       int a;
f5d2bd
+ *       struct {
f5d2bd
+ *           int b[10];
f5d2bd
+ *       };
f5d2bd
+ *   };
f5d2bd
+ *
f5d2bd
+ *   struct sample *s = ...;
f5d2bd
+ *   int x = &s->a;     // encoded as "0:0" (a is field #0)
f5d2bd
+ *   int y = &s->b[5];  // encoded as "0:1:0:5" (anon struct is field #1, 
f5d2bd
+ *                      // b is field #0 inside anon struct, accessing elem #5)
f5d2bd
+ *   int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array)
f5d2bd
+ *
f5d2bd
+ * type_id for all relocs in this example  will capture BTF type id of
f5d2bd
+ * `struct sample`.
f5d2bd
+ *
f5d2bd
+ * Such relocation is emitted when using __builtin_preserve_access_index()
f5d2bd
+ * Clang built-in, passing expression that captures field address, e.g.:
f5d2bd
+ *
f5d2bd
+ * bpf_probe_read(&dst, sizeof(dst),
f5d2bd
+ *		  __builtin_preserve_access_index(&src->a.b.c));
f5d2bd
+ *
f5d2bd
+ * In this case Clang will emit field relocation recording necessary data to
f5d2bd
+ * be able to find offset of embedded `a.b.c` field within `src` struct.
f5d2bd
+ *
f5d2bd
+ *   [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
f5d2bd
+ */
f5d2bd
+struct bpf_core_relo {
f5d2bd
+	__u32   insn_off;
f5d2bd
+	__u32   type_id;
f5d2bd
+	__u32   access_str_off;
f5d2bd
+	enum bpf_core_relo_kind kind;
f5d2bd
+};
f5d2bd
+
f5d2bd
 static int btf_ext_setup_core_relos(struct btf_ext *btf_ext)
f5d2bd
 {
f5d2bd
         struct btf_ext_sec_setup_param param = {
f5d2bd
@@ -597,7 +668,7 @@ int BTF::load(uint8_t *btf_sec, uintptr_t btf_sec_size,
f5d2bd
     return -1;
f5d2bd
   }
f5d2bd
 
f5d2bd
-  if (btf__load_into_kernel(btf)) {
f5d2bd
+  if (btf__load(btf)) {
f5d2bd
     btf__free(btf);
f5d2bd
     warning("Loading .BTF section failed\n");
f5d2bd
     return -1;
f5d2bd
diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
f5d2bd
index e6403299..68af4b35 100644
f5d2bd
--- a/src/cc/libbpf.c
f5d2bd
+++ b/src/cc/libbpf.c
f5d2bd
@@ -297,25 +297,6 @@ static uint64_t ptr_to_u64(void *ptr)
f5d2bd
   return (uint64_t) (unsigned long) ptr;
f5d2bd
 }
f5d2bd
 
f5d2bd
-static int libbpf_bpf_map_create(struct bpf_create_map_attr *create_attr)
f5d2bd
-{
f5d2bd
-  LIBBPF_OPTS(bpf_map_create_opts, p);
f5d2bd
-
f5d2bd
-  p.map_flags = create_attr->map_flags;
f5d2bd
-  p.numa_node = create_attr->numa_node;
f5d2bd
-  p.btf_fd = create_attr->btf_fd;
f5d2bd
-  p.btf_key_type_id = create_attr->btf_key_type_id;
f5d2bd
-  p.btf_value_type_id = create_attr->btf_value_type_id;
f5d2bd
-  p.map_ifindex = create_attr->map_ifindex;
f5d2bd
-  if (create_attr->map_type == BPF_MAP_TYPE_STRUCT_OPS)
f5d2bd
-    p.btf_vmlinux_value_type_id = create_attr->btf_vmlinux_value_type_id;
f5d2bd
-  else
f5d2bd
-    p.inner_map_fd = create_attr->inner_map_fd;
f5d2bd
-
f5d2bd
-  return bpf_map_create(create_attr->map_type, create_attr->name, create_attr->key_size,
f5d2bd
-                        create_attr->value_size, create_attr->max_entries, &p);
f5d2bd
-}
f5d2bd
-
f5d2bd
 int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
f5d2bd
 {
f5d2bd
   unsigned name_len = attr->name ? strlen(attr->name) : 0;
f5d2bd
@@ -323,7 +304,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
f5d2bd
 
f5d2bd
   memcpy(map_name, attr->name, min(name_len, BPF_OBJ_NAME_LEN - 1));
f5d2bd
   attr->name = map_name;
f5d2bd
-  int ret = libbpf_bpf_map_create(attr);
f5d2bd
+  int ret = bpf_create_map_xattr(attr);
f5d2bd
 
f5d2bd
   if (ret < 0 && errno == EPERM) {
f5d2bd
     if (!allow_rlimit)
f5d2bd
@@ -335,7 +316,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
f5d2bd
       rl.rlim_max = RLIM_INFINITY;
f5d2bd
       rl.rlim_cur = rl.rlim_max;
f5d2bd
       if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
f5d2bd
-        ret = libbpf_bpf_map_create(attr);
f5d2bd
+        ret = bpf_create_map_xattr(attr);
f5d2bd
     }
f5d2bd
   }
f5d2bd
 
f5d2bd
@@ -345,12 +326,12 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
f5d2bd
     attr->btf_fd = 0;
f5d2bd
     attr->btf_key_type_id = 0;
f5d2bd
     attr->btf_value_type_id = 0;
f5d2bd
-    ret = libbpf_bpf_map_create(attr);
f5d2bd
+    ret = bpf_create_map_xattr(attr);
f5d2bd
   }
f5d2bd
 
f5d2bd
   if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) {
f5d2bd
     map_name[0] = '\0';
f5d2bd
-    ret = libbpf_bpf_map_create(attr);
f5d2bd
+    ret = bpf_create_map_xattr(attr);
f5d2bd
   }
f5d2bd
 
f5d2bd
   if (ret < 0 && errno == EPERM) {
f5d2bd
@@ -363,7 +344,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
f5d2bd
       rl.rlim_max = RLIM_INFINITY;
f5d2bd
       rl.rlim_cur = rl.rlim_max;
f5d2bd
       if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
f5d2bd
-        ret = libbpf_bpf_map_create(attr);
f5d2bd
+        ret = bpf_create_map_xattr(attr);
f5d2bd
     }
f5d2bd
   }
f5d2bd
   return ret;
f5d2bd
@@ -627,47 +608,6 @@ int bpf_prog_get_tag(int fd, unsigned long long *ptag)
f5d2bd
   return 0;
f5d2bd
 }
f5d2bd
 
f5d2bd
-static int libbpf_bpf_prog_load(const struct bpf_load_program_attr *load_attr,
f5d2bd
-                                char *log_buf, size_t log_buf_sz)
f5d2bd
-{
f5d2bd
-  LIBBPF_OPTS(bpf_prog_load_opts, p);
f5d2bd
-
f5d2bd
-  if (!load_attr || !log_buf != !log_buf_sz) {
f5d2bd
-    errno = EINVAL;
f5d2bd
-    return -EINVAL;
f5d2bd
-  }
f5d2bd
-
f5d2bd
-  p.expected_attach_type = load_attr->expected_attach_type;
f5d2bd
-  switch (load_attr->prog_type) {
f5d2bd
-  case BPF_PROG_TYPE_STRUCT_OPS:
f5d2bd
-  case BPF_PROG_TYPE_LSM:
f5d2bd
-    p.attach_btf_id = load_attr->attach_btf_id;
f5d2bd
-    break;
f5d2bd
-  case BPF_PROG_TYPE_TRACING:
f5d2bd
-  case BPF_PROG_TYPE_EXT:
f5d2bd
-    p.attach_btf_id = load_attr->attach_btf_id;
f5d2bd
-    p.attach_prog_fd = load_attr->attach_prog_fd;
f5d2bd
-    break;
f5d2bd
-  default:
f5d2bd
-    p.prog_ifindex = load_attr->prog_ifindex;
f5d2bd
-    p.kern_version = load_attr->kern_version;
f5d2bd
-  }
f5d2bd
-  p.log_level = load_attr->log_level;
f5d2bd
-  p.log_buf = log_buf;
f5d2bd
-  p.log_size = log_buf_sz;
f5d2bd
-  p.prog_btf_fd = load_attr->prog_btf_fd;
f5d2bd
-  p.func_info_rec_size = load_attr->func_info_rec_size;
f5d2bd
-  p.func_info_cnt = load_attr->func_info_cnt;
f5d2bd
-  p.func_info = load_attr->func_info;
f5d2bd
-  p.line_info_rec_size = load_attr->line_info_rec_size;
f5d2bd
-  p.line_info_cnt = load_attr->line_info_cnt;
f5d2bd
-  p.line_info = load_attr->line_info;
f5d2bd
-  p.prog_flags = load_attr->prog_flags;
f5d2bd
-
f5d2bd
-  return bpf_prog_load(load_attr->prog_type, load_attr->name, load_attr->license,
f5d2bd
-                       load_attr->insns, load_attr->insns_cnt, &p);
f5d2bd
-}
f5d2bd
-
f5d2bd
 int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
                         char *log_buf, unsigned log_buf_size, bool allow_rlimit)
f5d2bd
 {
f5d2bd
@@ -750,7 +690,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
     attr->name = prog_name;
f5d2bd
   }
f5d2bd
 
f5d2bd
-  ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
+  ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
 
f5d2bd
   // func_info/line_info may not be supported in old kernels.
f5d2bd
   if (ret < 0 && attr->func_info && errno == EINVAL) {
f5d2bd
@@ -761,14 +701,14 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
     attr->line_info = NULL;
f5d2bd
     attr->line_info_cnt = 0;
f5d2bd
     attr->line_info_rec_size = 0;
f5d2bd
-    ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
+    ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
   }
f5d2bd
 
f5d2bd
   // BPF object name is not supported on older Kernels.
f5d2bd
   // If we failed due to this, clear the name and try again.
f5d2bd
   if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) {
f5d2bd
     prog_name[0] = '\0';
f5d2bd
-    ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
+    ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
   }
f5d2bd
 
f5d2bd
   if (ret < 0 && errno == EPERM) {
f5d2bd
@@ -787,7 +727,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
       rl.rlim_max = RLIM_INFINITY;
f5d2bd
       rl.rlim_cur = rl.rlim_max;
f5d2bd
       if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
f5d2bd
-        ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
+        ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
f5d2bd
     }
f5d2bd
   }
f5d2bd
 
f5d2bd
@@ -805,7 +745,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
       // If logging is not already enabled, enable it and do the syscall again.
f5d2bd
       if (attr->log_level == 0) {
f5d2bd
         attr->log_level = 1;
f5d2bd
-        ret = libbpf_bpf_prog_load(attr, log_buf, log_buf_size);
f5d2bd
+        ret = bpf_load_program_xattr(attr, log_buf, log_buf_size);
f5d2bd
       }
f5d2bd
       // Print the log message and return.
f5d2bd
       bpf_print_hints(ret, log_buf);
f5d2bd
@@ -829,7 +769,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
f5d2bd
         goto return_result;
f5d2bd
       }
f5d2bd
       tmp_log_buf[0] = 0;
f5d2bd
-      ret = libbpf_bpf_prog_load(attr, tmp_log_buf, tmp_log_buf_size);
f5d2bd
+      ret = bpf_load_program_xattr(attr, tmp_log_buf, tmp_log_buf_size);
f5d2bd
       if (ret < 0 && errno == ENOSPC) {
f5d2bd
         // Temporary buffer size is not enough. Double it and try again.
f5d2bd
         free(tmp_log_buf);
f5d2bd
-- 
f5d2bd
2.36.1
f5d2bd