BPF_CORE_READ(), in addition to handling CO-RE relocations, also allows much
nicer way to read data structures with nested pointers. Instead of writing
a sequence of bpf_probe_read() calls to follow links, one can just write
BPF_CORE_READ(a, b, c, d) to effectively do a->b->c->d read. This is a welcome
ability when porting BCC code, which (in most cases) allows exactly the
intuitive a->b->c->d variant.

This patch adds non-CO-RE variants of BPF_CORE_READ() family of macros for
cases where CO-RE is not supported (e.g., old kernels). In such cases, the
property of shortening a sequence of bpf_probe_read()s to a simple
BPF_PROBE_READ(a, b, c, d) invocation is still desirable, especially when
porting BCC code to libbpf. Yet, no CO-RE relocation is going to be emitted.

Signed-off-by: Andrii Nakryiko <and...@kernel.org>
---
 tools/lib/bpf/bpf_core_read.h | 38 +++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h
index db0c735ceb53..9456aabcb03a 100644
--- a/tools/lib/bpf/bpf_core_read.h
+++ b/tools/lib/bpf/bpf_core_read.h
@@ -308,6 +308,18 @@ enum bpf_enum_value_kind {
                     dst, (src), a, ##__VA_ARGS__)                          \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ_INTO() */
+#define BPF_PROBE_READ_INTO(dst, src, a, ...) ({                           \
+       ___core_read(bpf_probe_read, bpf_probe_read,                        \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER_INTO() */
+#define BPF_PROBE_READ_USER_INTO(dst, src, a, ...) ({                      \
+       ___core_read(bpf_probe_read_user, bpf_probe_read_user,              \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
 /*
  * BPF_CORE_READ_STR_INTO() does same "pointer chasing" as
  * BPF_CORE_READ() for intermediate pointers, but then executes (and returns
@@ -324,6 +336,18 @@ enum bpf_enum_value_kind {
                     dst, (src), a, ##__VA_ARGS__)                          \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ_STR_INTO() */
+#define BPF_PROBE_READ_STR_INTO(dst, src, a, ...) ({                       \
+       ___core_read(bpf_probe_read_str, bpf_probe_read,                    \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER_STR_INTO() */
+#define BPF_PROBE_READ_USER_STR_INTO(dst, src, a, ...) ({                  \
+       ___core_read(bpf_probe_read_user_str, bpf_probe_read_user,          \
+                    dst, (src), a, ##__VA_ARGS__)                          \
+})
+
 /*
  * BPF_CORE_READ() is used to simplify BPF CO-RE relocatable read, especially
  * when there are few pointer chasing steps.
@@ -361,5 +385,19 @@ enum bpf_enum_value_kind {
        __r;                                                                \
 })
 
+/* Non-CO-RE variant of BPF_CORE_READ() */
+#define BPF_PROBE_READ(src, a, ...) ({                                     \
+       ___type((src), a, ##__VA_ARGS__) __r;                               \
+       BPF_PROBE_READ_INTO(&__r, (src), a, ##__VA_ARGS__);                 \
+       __r;                                                                \
+})
+
+/* Non-CO-RE variant of BPF_CORE_READ_USER() */
+#define BPF_PROBE_READ_USER(src, a, ...) ({                                \
+       ___type((src), a, ##__VA_ARGS__) __r;                               \
+       BPF_PROBE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__);            \
+       __r;                                                                \
+})
+
 #endif
 
-- 
2.24.1

Reply via email to