On Mon, 15 Apr 2024 at 16:55, Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote: > > On Mon, Apr 15, 2024 at 4:58 PM Ard Biesheuvel <ardb+git@xxxxxxxxxx> wrote: > > > > From: Ard Biesheuvel <ardb@xxxxxxxxxx> > > > > If the BTF code is enabled in the build configuration, the start/stop > > BTF markers are guaranteed to exist in the final link but not during the > > first linker pass. > > > > Avoid GOT based relocations to these markers in the final executable by > > providing preliminary definitions that will be used by the first linker > > pass, and superseded by the actual definitions in the subsequent ones. > > > > Make the preliminary definitions dependent on CONFIG_DEBUG_INFO_BTF so > > that inadvertent references to this section will trigger a link failure > > if they occur in code that does not honour CONFIG_DEBUG_INFO_BTF. > > > > Note that Clang will notice that taking the address of__start_BTF cannot > > yield NULL any longer, so testing for that condition is no longer > > needed. > > > > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > > Acked-by: Arnd Bergmann <arnd@xxxxxxxx> > > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > > --- > > include/asm-generic/vmlinux.lds.h | 9 +++++++++ > > kernel/bpf/btf.c | 7 +++++-- > > kernel/bpf/sysfs_btf.c | 6 +++--- > > 3 files changed, 17 insertions(+), 5 deletions(-) > > > > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h > > index e8449be62058..4cb3d88449e5 100644 > > --- a/include/asm-generic/vmlinux.lds.h > > +++ b/include/asm-generic/vmlinux.lds.h > > @@ -456,6 +456,7 @@ > > * independent code. > > */ > > #define PRELIMINARY_SYMBOL_DEFINITIONS \ > > + PRELIMINARY_BTF_DEFINITIONS \ > > PROVIDE(kallsyms_addresses = .); \ > > PROVIDE(kallsyms_offsets = .); \ > > PROVIDE(kallsyms_names = .); \ > > @@ -466,6 +467,14 @@ > > PROVIDE(kallsyms_markers = .); \ > > PROVIDE(kallsyms_seqs_of_names = .); > > > > +#ifdef CONFIG_DEBUG_INFO_BTF > > +#define PRELIMINARY_BTF_DEFINITIONS \ > > + PROVIDE(__start_BTF = .); \ > > + PROVIDE(__stop_BTF = .); > > +#else > > +#define PRELIMINARY_BTF_DEFINITIONS > > +#endif > > + > > > > Is this necessary? > I think so. This actually resulted in Jiri's build failure with v2, and the realization that there was dead code in btf_parse_vmlinux() that happily tried to load the contents of the BTF section if CONFIG_DEBUG_INFO_BTF was not enabled to begin with. So this is another pitfall with weak references: the symbol may unexpectedly be missing altogether rather than only during the first linker pass. > > > The following code (BOUNDED_SECTION_BY) > produces __start_BTF and __stop_BTF symbols > under the same condition. > Indeed. So if CONFIG_DEBUG_INFO_BTF=n, code can still link to __start_BTF and __stop_BTF even though BTF is not enabled. > > > /* > * .BTF > */ > #ifdef CONFIG_DEBUG_INFO_BTF > #define BTF \ > .BTF : AT(ADDR(.BTF) - LOAD_OFFSET) { \ > BOUNDED_SECTION_BY(.BTF, _BTF) \ > } \ > . = ALIGN(4); \ > .BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) { \ > *(.BTF_ids) \ > } > #else > #define BTF > #endif > > > > > > > > > > > > > /* > > * Read only Data > > */ > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > > index 90c4a32d89ff..6d46cee47ae3 100644 > > --- a/kernel/bpf/btf.c > > +++ b/kernel/bpf/btf.c > > @@ -5642,8 +5642,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat > > return ERR_PTR(err); > > } > > > > -extern char __weak __start_BTF[]; > > -extern char __weak __stop_BTF[]; > > +extern char __start_BTF[]; > > +extern char __stop_BTF[]; > > extern struct btf *btf_vmlinux; > > > > #define BPF_MAP_TYPE(_id, _ops) > > @@ -5971,6 +5971,9 @@ struct btf *btf_parse_vmlinux(void) > > struct btf *btf = NULL; > > int err; > > > > + if (!IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) > > + return ERR_PTR(-ENOENT); > > + > > env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN); > > if (!env) > > return ERR_PTR(-ENOMEM); > > diff --git a/kernel/bpf/sysfs_btf.c b/kernel/bpf/sysfs_btf.c > > index ef6911aee3bb..fedb54c94cdb 100644 > > --- a/kernel/bpf/sysfs_btf.c > > +++ b/kernel/bpf/sysfs_btf.c > > @@ -9,8 +9,8 @@ > > #include <linux/sysfs.h> > > > > /* See scripts/link-vmlinux.sh, gen_btf() func for details */ > > -extern char __weak __start_BTF[]; > > -extern char __weak __stop_BTF[]; > > +extern char __start_BTF[]; > > +extern char __stop_BTF[]; > > > > static ssize_t > > btf_vmlinux_read(struct file *file, struct kobject *kobj, > > @@ -32,7 +32,7 @@ static int __init btf_vmlinux_init(void) > > { > > bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF; > > > > - if (!__start_BTF || bin_attr_btf_vmlinux.size == 0) > > + if (bin_attr_btf_vmlinux.size == 0) > > return 0; > > > > btf_kobj = kobject_create_and_add("btf", kernel_kobj); > > -- > > 2.44.0.683.g7961c838ac-goog > > > > > -- > Best Regards > Masahiro Yamada