The vmlinux.h file generated by bpftool makes use of compiler pragmas in order to install the CO-RE preserve_access_index in all the struct types derived from the BTF info: #ifndef __VMLINUX_H__ #define __VMLINUX_H__ #ifndef BPF_NO_PRESERVE_ACCESS_INDEX #pragma clang attribute push (__attribute__((preserve_access_index)), apply_t = record #endif [... type definitions generated from kernel BTF ... ] #ifndef BPF_NO_PRESERVE_ACCESS_INDEX #pragma clang attribute pop #endif The `clang attribute push/pop' pragmas are specific to clang/llvm and are not supported by GCC. This patch modifies bpftool in order to, instead of using the pragmas, define ATTR_PRESERVE_ACCESS_INDEX to conditionally expand to the CO-RE attribute: #ifndef __VMLINUX_H__ #define __VMLINUX_H__ #ifndef BPF_NO_PRESERVE_ACCESS_INDEX #define ATTR_PRESERVE_ACCESS_INDEX __attribute__((preserve_access_index)) #else #define ATTR_PRESERVE_ACCESS_INDEX #endif [... type definitions generated from kernel BTF ... ] #undef ATTR_PRESERVE_ACCESS_INDEX To make this possible the btf_dump_opts have been expanded with a new configurable field `record_attrs_str', which is a string that gets inserted at the point compiler attributes are expected for each emmited C struct and union type: DECLARE_LIBBPF_OPTS(btf_dump_opts, opts); [...] opts.record_attrs_str = "ATTR_PRESERVE_ACCESS_INDEX"; d = btf_dump__new(btf, btf_dump_printf, NULL, &opts); [...] err = btf_dump__dump_type(d, root_type_ids[i]); Tested in bpf-next master. No regressions. Signed-off-by: Jose E. Marchesi <jose.marchesi@xxxxxxxxxx> Cc: Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> Cc: Yonghong Song <yonghong.song@xxxxxxxxx> Cc: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> Cc: david.faust@xxxxxxxxxx Cc: cupertino.miranda@xxxxxxxxxx --- tools/bpf/bpftool/btf.c | 15 +++++++++------ tools/lib/bpf/btf.h | 9 ++++++++- tools/lib/bpf/btf_dump.c | 8 ++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index 91fcb75babe3..c548dc3b4bd7 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -463,19 +463,24 @@ static void __printf(2, 0) btf_dump_printf(void *ctx, static int dump_btf_c(const struct btf *btf, __u32 *root_type_ids, int root_type_cnt) { + DECLARE_LIBBPF_OPTS(btf_dump_opts, opts); struct btf_dump *d; int err = 0, i; - d = btf_dump__new(btf, btf_dump_printf, NULL, NULL); + opts.record_attrs_str = "ATTR_PRESERVE_ACCESS_INDEX"; + d = btf_dump__new(btf, btf_dump_printf, NULL, &opts); if (!d) return -errno; printf("#ifndef __VMLINUX_H__\n"); printf("#define __VMLINUX_H__\n"); printf("\n"); - printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n"); - printf("#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)\n"); + printf("#ifdef BPF_NO_PRESERVE_ACCESS_INDEX\n"); + printf("#define ATTR_PRESERVE_ACCESS_INDEX\n"); + printf("#else\n"); + printf("#define ATTR_PRESERVE_ACCESS_INDEX __attribute__((preserve_access_index))\n"); printf("#endif\n\n"); + printf("\n"); if (root_type_cnt) { for (i = 0; i < root_type_cnt; i++) { @@ -493,9 +498,7 @@ static int dump_btf_c(const struct btf *btf, } } - printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n"); - printf("#pragma clang attribute pop\n"); - printf("#endif\n"); + printf("#undef ATTR_PRESERVE_ACCESS_INDEX\n"); printf("\n"); printf("#endif /* __VMLINUX_H__ */\n"); diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 8e6880d91c84..f7f9a2c7f96e 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -234,9 +234,16 @@ LIBBPF_API int btf__dedup(struct btf *btf, const struct btf_dedup_opts *opts); struct btf_dump; struct btf_dump_opts { + /* size of this struct, for forward/backward compatibility */ size_t sz; + /* String to be inserted at the point where compiler + * attributes are expected in each emitted C struct and + * union type. + */ + const char *record_attrs_str; + size_t :0; }; -#define btf_dump_opts__last_field sz +#define btf_dump_opts__last_field record_attrs_str typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args); diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 5dbca76b953f..fbc112f31d33 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -116,6 +116,11 @@ struct btf_dump { * data for typed display; allocated if needed. */ struct btf_dump_data *typed_dump; + /* + * string with C attributes to be used in record + * types. + */ + const char *record_attrs_str; }; static size_t str_hash_fn(long key, void *ctx) @@ -167,6 +172,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf, d->printf_fn = printf_fn; d->cb_ctx = ctx; d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *); + d->record_attrs_str = OPTS_GET(opts, record_attrs_str, NULL); d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL); if (IS_ERR(d->type_names)) { @@ -1024,6 +1030,8 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, } if (packed) btf_dump_printf(d, " __attribute__((packed))"); + if (d->record_attrs_str) + btf_dump_printf(d, " %s", d->record_attrs_str); } static const char *missing_base_types[][2] = { -- 2.30.2