kbuild: Avoid weak external linkage where possible
Subsystems (6)
v2 cover kbuild: Avoid weak external linkage where possible
From: Ard Biesheuvel <[email protected]>
Weak external linkage is intended for cases where a symbol reference can remain unsatisfied in the final link. Taking the address of such a symbol should yield NULL if the reference was not satisfied.
Given that ordinary RIP or PC relative references cannot produce NULL, some kind of indirection is always needed in such cases, and in position independent code, this results in a GOT entry. In ordinary code, it is arch specific but amounts to the same thing.
While unavoidable in some cases, weak references are currently also used to declare symbols that are always defined in the final link, but not in the first linker pass. This means we end up with worse codegen for no good reason. So let's clean this up, by providing preliminary definitions that are only used as a fallback.
Changes since v1:
- update second occurrence of BTF start/end markers
- drop NULL check of __start_BTF[] which is no longer meaningful
- avoid the preliminary BTF symbols if CONFIG_DEBUG_INFO_BTF is not set
- add Andrii's ack to patch #3
- patches #1 and #2 unchanged
Ard Biesheuvel (3):
kallsyms: Avoid weak references for kallsyms symbols
vmlinux: Avoid weak reference to notes section
btf: Avoid weak external references
include/asm-generic/vmlinux.lds.h | 28 ++++++++++++++++++ kernel/bpf/btf.c | 4 +-- kernel/bpf/sysfs_btf.c | 6 ++-- kernel/kallsyms.c | 6 ---- kernel/kallsyms_internal.h | 30 ++++++++------------ kernel/ksysfs.c | 4 +-- lib/buildid.c | 4 +-- 7 files changed, 49 insertions(+), 33 deletions(-)
Signature · 1 line
2.44.0.478.gd926399ef9-goog
PATCH v2 1/3 kallsyms: Avoid weak references for kallsyms symbols
From: Ard Biesheuvel <[email protected]>
kallsyms is a directory of all the symbols in the vmlinux binary, and so creating it is somewhat of a chicken-and-egg problem, as its non-zero size affects the layout of the binary, and therefore the values of the symbols.
For this reason, the kernel is linked more than once, and the first pass does not include any kallsyms data at all. For the linker to accept this, the symbol declarations describing the kallsyms metadata are emitted as having weak linkage, so they can remain unsatisfied. During the subsequent passes, the weak references are satisfied by the kallsyms metadata that was constructed based on information gathered from the preceding passes.
Weak references lead to somewhat worse codegen, because taking their address may need to produce NULL (if the reference was unsatisfied), and this is not usually supported by RIP or PC relative symbol references.
Given that these references are ultimately always satisfied in the final link, let's drop the weak annotation, and instead, provide fallback definitions in the linker script that are only emitted if an unsatisfied reference exists.
While at it, drop the FRV specific annotation that these symbols reside in .rodata - FRV is long gone.
--- include/asm-generic/vmlinux.lds.h | 19 +++++++++++++ kernel/kallsyms.c | 6 ---- kernel/kallsyms_internal.h | 30 ++++++++------------ 3 files changed, 31 insertions(+), 24 deletions(-)
include/asm-generic/vmlinux.lds.h +19 -0
@@ -448,11 +448,30 @@#endif #endif +/* +* Some symbol definitions will not exist yet during the first pass of the +* link, but are guaranteed to exist in the final link. Provide preliminary +* definitions that will be superseded in the final link to avoid having to +* rely on weak external linkage, which requires a GOT when used in position +* independent code. +*/ +#define PRELIMINARY_SYMBOL_DEFINITIONS \ + PROVIDE(kallsyms_addresses = .); \ + PROVIDE(kallsyms_offsets = .); \ + PROVIDE(kallsyms_names = .); \ + PROVIDE(kallsyms_num_syms = .); \ + PROVIDE(kallsyms_relative_base = .); \ + PROVIDE(kallsyms_token_table = .); \ + PROVIDE(kallsyms_token_index = .); \ + PROVIDE(kallsyms_markers = .); \ + PROVIDE(kallsyms_seqs_of_names = .); +/* * Read only Data */ #define RO_DATA (align) \ . = ALIGN((align)); \ + PRELIMINARY_SYMBOL_DEFINITIONS \ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ __start_rodata = .; \ *(.rodata) *(.rodata.*) \
kernel/kallsyms.c +0 -6
@@ -325,12 +325,6 @@ static unsigned long get_symbol_pos(unsigned long addr,unsigned long symbol_start =0 , symbol_end =0 ;unsigned long i, low, high, mid; -/* This kernel should never had been booted. */ -if (!IS_ENABLED (CONFIG_KALLSYMS_BASE_RELATIVE )) -BUG_ON (!kallsyms_addresses); -else -BUG_ON (!kallsyms_offsets); -/* Do a binary search on the sorted kallsyms_addresses array. */ low =0 ; high = kallsyms_num_syms;
kernel/kallsyms_internal.h +12 -18
@@ -5,27 +5,21 @@#include <linux/types.h> /* -* These will be re-linked against their real values -* during the second link stage. +* These will be re-linked against their real values during the second link +* stage. Preliminary values must be provided in the linker script using the +* PROVIDE() directive so that the first link stage can complete successfully. */ -extern const unsigned long kallsyms_addresses[]__weak ; -extern const int kallsyms_offsets[]__weak ; -extern const u8 kallsyms_names[]__weak ; +extern const unsigned long kallsyms_addresses[]; +extern const int kallsyms_offsets[]; +extern const u8 kallsyms_names[]; -/* -* Tell the compiler that the count isn't in the small data section if the arch -* has one (eg: FRV). -*/ -extern const unsigned int kallsyms_num_syms -__section(".rodata") __attribute__((weak)); - -extern const unsigned long kallsyms_relative_base -__section(".rodata") __attribute__((weak)); +extern const unsigned int kallsyms_num_syms; +extern const unsigned long kallsyms_relative_base; -extern const char kallsyms_token_table[]__weak ; -extern const u16 kallsyms_token_index[]__weak ; +extern const char kallsyms_token_table[]; +extern const u16 kallsyms_token_index[]; -extern const unsigned int kallsyms_markers[]__weak ; -extern const u8 kallsyms_seqs_of_names[]__weak ; +extern const unsigned int kallsyms_markers[]; +extern const u8 kallsyms_seqs_of_names[];#endif // LINUX_KALLSYMS_INTERNAL_H_
Signature · 1 line
2.44.0.478.gd926399ef9-goog
Re: [PATCH v2 1/3] kallsyms: Avoid weak references for kallsyms symbols
Quoted 24 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
kallsyms is a directory of all the symbols in the vmlinux binary, and so creating it is somewhat of a chicken-and-egg problem, as its non-zero size affects the layout of the binary, and therefore the values of the symbols.
For this reason, the kernel is linked more than once, and the first pass does not include any kallsyms data at all. For the linker to accept this, the symbol declarations describing the kallsyms metadata are emitted as having weak linkage, so they can remain unsatisfied. During the subsequent passes, the weak references are satisfied by the kallsyms metadata that was constructed based on information gathered from the preceding passes.
Weak references lead to somewhat worse codegen, because taking their address may need to produce NULL (if the reference was unsatisfied), and this is not usually supported by RIP or PC relative symbol references.
Given that these references are ultimately always satisfied in the final link, let's drop the weak annotation, and instead, provide fallback definitions in the linker script that are only emitted if an unsatisfied reference exists.
Quoted 8 lines
While at it, drop the FRV specific annotation that these symbols reside in .rodata - FRV is long gone.
PATCH v2 2/3 vmlinux: Avoid weak reference to notes section
In reply to Ard BiesheuvelFrom: Ard Biesheuvel <[email protected]>
Weak references are references that are permitted to remain unsatisfied in the final link. This means they cannot be implemented using place relative relocations, resulting in GOT entries when using position independent code generation.
The notes section should always exist, so the weak annotations can be omitted.
--- kernel/ksysfs.c | 4 ++-- lib/buildid.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
kernel/ksysfs.c +2 -2
@@ -228,8 +228,8 @@ KERNEL_ATTR_RW(rcu_normal);/* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. */ -extern const void __start_notes__weak ; -extern const void __stop_notes__weak ; +extern const void __start_notes; +extern const void __stop_notes;#define notes_size (&__stop_notes - &__start_notes) static ssize_t notes_read(struct file *filp, struct kobject *kobj,
lib/buildid.c +2 -2
@@ -182,8 +182,8 @@ unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;*/ void __init init_vmlinux_build_id (void ) { -extern const void __start_notes__weak ; -extern const void __stop_notes__weak ; +extern const void __start_notes; +extern const void __stop_notes;unsigned int size = &__stop_notes - &__start_notes;build_id_parse_buf (&__start_notes, vmlinux_build_id, size);
Signature · 1 line
2.44.0.478.gd926399ef9-goog
Re: [PATCH v2 2/3] vmlinux: Avoid weak reference to notes section
Quoted 11 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
Weak references are references that are permitted to remain unsatisfied in the final link. This means they cannot be implemented using place relative relocations, resulting in GOT entries when using position independent code generation.
The notes section should always exist, so the weak annotations can be omitted.
Signed-off-by Ard Biesheuvel <[email protected]>
PATCH v2 3/3 btf: Avoid weak external references
In reply to Ard BiesheuvelFrom: Ard Biesheuvel <[email protected]>
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.
--- include/asm-generic/vmlinux.lds.h | 9 +++++++++ kernel/bpf/btf.c | 4 ++-- kernel/bpf/sysfs_btf.c | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-)
include/asm-generic/vmlinux.lds.h +9 -0
@@ -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 +/* * Read only Data */
kernel/bpf/btf.c +2 -2
@@ -5642,8 +5642,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uatreturn 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)
kernel/bpf/sysfs_btf.c +3 -3
@@ -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);
Signature · 1 line
2.44.0.478.gd926399ef9-goog
Re: [PATCH v2 3/3] btf: Avoid weak external references
Quoted 14 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
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_BTFso that inadvertent references to this section will trigger a link failure if they occur in code that does not honourCONFIG_DEBUG_INFO_BTF.
Quoted 6 lines
Note that Clang will notice that taking the address
of__start_BTFcannot yield NULL any longer, so testing for that condition is no longer needed.Acked-by Andrii Nakryiko <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>
kernel test robot
build botRe: [PATCH v2 3/3] btf: Avoid weak external references
In reply to Ard Biesheuvelkernel test robot noticed the following build errors:
Hi Ard,
kernel test robot noticed the following build errors:
[auto build test ERROR on arnd-asm-generic/master]
[also build test ERROR on bpf-next/master bpf/master linus/master v6.9-rc3 next-20240409] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ard-Biesheuvel/kallsyms-Avoid-weak-references-for-kallsyms-symbols/20240409-230510 base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master patch link: https://lore.kernel.org/r/20240409150132.4097042-8-ardb%2Bgit%40google.com patch subject: [PATCH v2 3/3] btf: Avoid weak external references config: riscv-defconfig (https://download.01.org/0day-ci/archive/20240410/[email protected]/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 8b3b4a92adee40483c27f26c478a384cd69c6f05) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240410/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
>> ld.lld: error: undefined symbol: __start_BTF >>> referenced by btf.c >>> kernel/bpf/btf.o:(btf_parse_vmlinux) in archive vmlinux.a -- >> ld.lld: error: undefined symbol: __stop_BTF >>> referenced by btf.c >>> kernel/bpf/btf.o:(btf_parse_vmlinux) in archive vmlinux.a
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH v2 3/3] btf: Avoid weak external references
In reply to Ard Biesheuvelkernel test robot noticed the following build errors:
Hi Ard,
kernel test robot noticed the following build errors:
[auto build test ERROR on arnd-asm-generic/master]
[also build test ERROR on bpf-next/master bpf/master linus/master v6.9-rc3 next-20240409] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ard-Biesheuvel/kallsyms-Avoid-weak-references-for-kallsyms-symbols/20240409-230510 base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master patch link: https://lore.kernel.org/r/20240409150132.4097042-8-ardb%2Bgit%40google.com patch subject: [PATCH v2 3/3] btf: Avoid weak external references config: s390-defconfig (https://download.01.org/0day-ci/archive/20240410/[email protected]/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 8b3b4a92adee40483c27f26c478a384cd69c6f05) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240410/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
s390x-linux-ld: kernel/bpf/btf.o: in function `btf_parse_vmlinux':
>> kernel/bpf/btf.c:5910:(.text+0x3b72): undefined reference to `__start_BTF' >> s390x-linux-ld: kernel/bpf/btf.c:5911:(.text+0x3b78): undefined reference to `__stop_BTF'
vim +5910 kernel/bpf/btf.c
49f4e6720748c7 Jiri Olsa 2020-07-11 5888
8580ac9404f624 Alexei Starovoitov 2019-10-15 5889 struct btf *btf_parse_vmlinux(void)
8580ac9404f624 Alexei Starovoitov 2019-10-15 5890 {
8580ac9404f624 Alexei Starovoitov 2019-10-15 5891 struct btf_verifier_env *env = NULL;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5892 struct bpf_verifier_log *log;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5893 struct btf *btf = NULL;
49f4e6720748c7 Jiri Olsa 2020-07-11 5894 int err;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5895
8580ac9404f624 Alexei Starovoitov 2019-10-15 5896 env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5897 if (!env)
8580ac9404f624 Alexei Starovoitov 2019-10-15 5898 return ERR_PTR(-ENOMEM);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5899
8580ac9404f624 Alexei Starovoitov 2019-10-15 5900 log = &env->log;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5901 log->level = BPF_LOG_KERNEL;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5902
8580ac9404f624 Alexei Starovoitov 2019-10-15 5903 btf = kzalloc(sizeof(*btf), GFP_KERNEL | __GFP_NOWARN);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5904 if (!btf) {
8580ac9404f624 Alexei Starovoitov 2019-10-15 5905 err = -ENOMEM;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5906 goto errout;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5907 }
8580ac9404f624 Alexei Starovoitov 2019-10-15 5908 env->btf = btf;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5909
90ceddcb495008 Fangrui Song 2020-03-18 @5910 btf->data = __start_BTF;
90ceddcb495008 Fangrui Song 2020-03-18 @5911 btf->data_size = __stop_BTF - __start_BTF;
5329722057d41a Andrii Nakryiko 2020-11-09 5912 btf->kernel_btf = true;
5329722057d41a Andrii Nakryiko 2020-11-09 5913 snprintf(btf->name, sizeof(btf->name), "vmlinux");
8580ac9404f624 Alexei Starovoitov 2019-10-15 5914
8580ac9404f624 Alexei Starovoitov 2019-10-15 5915 err = btf_parse_hdr(env);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5916 if (err)
8580ac9404f624 Alexei Starovoitov 2019-10-15 5917 goto errout;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5918
8580ac9404f624 Alexei Starovoitov 2019-10-15 5919 btf->nohdr_data = btf->data + btf->hdr.hdr_len;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5920
8580ac9404f624 Alexei Starovoitov 2019-10-15 5921 err = btf_parse_str_sec(env);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5922 if (err)
8580ac9404f624 Alexei Starovoitov 2019-10-15 5923 goto errout;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5924
8580ac9404f624 Alexei Starovoitov 2019-10-15 5925 err = btf_check_all_metas(env);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5926 if (err)
8580ac9404f624 Alexei Starovoitov 2019-10-15 5927 goto errout;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5928
eb596b0905584a Kumar Kartikeya Dwivedi 2022-04-19 5929 err = btf_check_type_tags(env, btf, 1);
eb596b0905584a Kumar Kartikeya Dwivedi 2022-04-19 5930 if (err)
eb596b0905584a Kumar Kartikeya Dwivedi 2022-04-19 5931 goto errout;
eb596b0905584a Kumar Kartikeya Dwivedi 2022-04-19 5932
a2d0d62f4d9e35 Andrey Ignatov 2020-06-19 5933 /* btf_parse_vmlinux() runs under bpf_verifier_lock */
49f4e6720748c7 Jiri Olsa 2020-07-11 5934 bpf_ctx_convert.t = btf_type_by_id(btf, bpf_ctx_convert_btf_id[0]);
91cc1a99740e2e Alexei Starovoitov 2019-11-14 5935
d3e42bb0a329fa Martin KaFai Lau 2020-01-27 5936 bpf_struct_ops_init(btf, log);
27ae7997a66174 Martin KaFai Lau 2020-01-08 5937
8580ac9404f624 Alexei Starovoitov 2019-10-15 5938 refcount_set(&btf->refcnt, 1);
5329722057d41a Andrii Nakryiko 2020-11-09 5939
5329722057d41a Andrii Nakryiko 2020-11-09 5940 err = btf_alloc_id(btf);
5329722057d41a Andrii Nakryiko 2020-11-09 5941 if (err)
5329722057d41a Andrii Nakryiko 2020-11-09 5942 goto errout;
5329722057d41a Andrii Nakryiko 2020-11-09 5943
5329722057d41a Andrii Nakryiko 2020-11-09 5944 btf_verifier_env_free(env);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5945 return btf;
8580ac9404f624 Alexei Starovoitov 2019-10-15 5946
8580ac9404f624 Alexei Starovoitov 2019-10-15 5947 errout:
8580ac9404f624 Alexei Starovoitov 2019-10-15 5948 btf_verifier_env_free(env);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5949 if (btf) {
8580ac9404f624 Alexei Starovoitov 2019-10-15 5950 kvfree(btf->types);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5951 kfree(btf);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5952 }
8580ac9404f624 Alexei Starovoitov 2019-10-15 5953 return ERR_PTR(err);
8580ac9404f624 Alexei Starovoitov 2019-10-15 5954 }
8580ac9404f624 Alexei Starovoitov 2019-10-15 5955 Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v2 3/3] btf: Avoid weak external references
In reply to Ard BiesheuvelQuoted 39 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
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_BTFso that inadvertent references to this section will trigger a link failure if they occur in code that does not honourCONFIG_DEBUG_INFO_BTF.Note that Clang will notice that taking the address
of__start_BTFcannot yield NULL any longer, so testing for that condition is no longer needed.Acked-by Andrii Nakryiko <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>--- include/asm-generic/vmlinux.lds.h | 9 +++++++++ kernel/bpf/btf.c | 4 ++-- kernel/bpf/sysfs_btf.c | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-)include/asm-generic/vmlinux.lds.h +1
-0@@ -456,6 +456,7 @@* independent code. */ #define PRELIMINARY_SYMBOL_DEFINITIONS \ + PRELIMINARY_BTF_DEFINITIONS \ PROVIDE(kallsyms_addresses = .); \ PROVIDE(kallsyms_offsets = .); \ PROVIDE(kallsyms_names = .); \
include/asm-generic/vmlinux.lds.h line 476
Quoted 10 lines
include/asm-generic/vmlinux.lds.h +7
-0@@ -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
hi,
I'm getting following compilation fail when CONFIG_DEBUG_INFO_BTF is disabled
[jolsa@krava linux-qemu]$ make
CALL scripts/checksyscalls.sh
DESCEND objtool
INSTALL libsubcmd_headers
UPD include/generated/utsversion.h
CC init/version-timestamp.o
LD .tmp_vmlinux.kallsyms1
ld: kernel/bpf/btf.o: in function `btf_parse_vmlinux':
/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5988: undefined reference to `__start_BTF'
ld: /home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__stop_BTF'
ld: /home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__start_BTF' make[2]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1
make[1]: *** [/home/jolsa/kernel/linux-qemu/Makefile:1160: vmlinux] Error 2
make: *** [Makefile:240: __sub-make] Error 2
maybe the assumption was that kernel/bpf/btf.o is compiled only for CONFIG_DEBUG_INFO_BTF, but it's actually:
obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o
I guess we just need !CONFIG_DEBUG_INFO_BTF version of btf_parse_vmlinux function
jirka
Quoted 47 lines
include/asm-generic/vmlinux.lds.h +1
-0+/* * Read only Data */ kernel/bpf/btf.c +2
-2@@ -5642,8 +5642,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uatreturn 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)kernel/bpf/sysfs_btf.c +3
-3@@ -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);Signature · 1 line
2.44.0.478.gd926399ef9-goog
Re: [PATCH v2 3/3] btf: Avoid weak external references
Quoted 70 lines · Jiri Olsa
Quoted 39 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
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_BTFso that inadvertent references to this section will trigger a link failure if they occur in code that does not honourCONFIG_DEBUG_INFO_BTF.Note that Clang will notice that taking the address
of__start_BTFcannot yield NULL any longer, so testing for that condition is no longer needed.Acked-by Andrii Nakryiko <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>--- include/asm-generic/vmlinux.lds.h | 9 +++++++++ kernel/bpf/btf.c | 4 ++-- kernel/bpf/sysfs_btf.c | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-)include/asm-generic/vmlinux.lds.h +1
-0@@ -456,6 +456,7 @@* independent code. */ #define PRELIMINARY_SYMBOL_DEFINITIONS \ + PRELIMINARY_BTF_DEFINITIONS \ PROVIDE(kallsyms_addresses = .); \ PROVIDE(kallsyms_offsets = .); \ PROVIDE(kallsyms_names = .); \include/asm-generic/vmlinux.lds.h line 476
Quoted 10 lines
include/asm-generic/vmlinux.lds.h +7
-0@@ -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 hi,
I'm getting following compilation fail whenCONFIG_DEBUG_INFO_BTFis disabled[jolsa@krava linux-qemu]$ make
CALLscripts/checksyscalls.sh
DESCEND objtool
INSTALLlibsubcmd_headers
UPDinclude/generated/utsversion.h
CCinit/version-timestamp.o
LD .tmp_vmlinux.kallsyms1
ld:kernel/bpf/btf.o: in function `btf_parse_vmlinux':
/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5988: undefined reference to `__start_BTF'
ld:/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__stop_BTF'
ld:/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__start_BTF' make[2]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1
make[1]: *** [/home/jolsa/kernel/linux-qemu/Makefile:1160: vmlinux] Error 2
make: *** [Makefile:240: __sub-make] Error 2
Quoted 5 lines
maybe the assumption was that
kernel/bpf/btf.ois compiled only forCONFIG_DEBUG_INFO_BTF, but it's actually:obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o
Interesting. I did build test this with and without CONFIG_DEBUG_INFO_BTF, but not with CONFIG_BPF_SYSCALL=y and CONFIG_DEBUG_INFO_BTF=n.
Quoted 3 lines
I guess we just need !CONFIG_DEBUG_INFO_BTF version of
btf_parse_vmlinuxfunction
The below gives me a working build.
kernel/bpf/btf.c +3 -0
@@ -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 );
Re: [PATCH v2 3/3] btf: Avoid weak external references
Quoted 90 lines · Ard Biesheuvel
Quoted 70 lines · Jiri Olsa
Quoted 39 lines · Ard Biesheuvel
From: Ard Biesheuvel <[email protected]>
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_BTFso that inadvertent references to this section will trigger a link failure if they occur in code that does not honourCONFIG_DEBUG_INFO_BTF.Note that Clang will notice that taking the address
of__start_BTFcannot yield NULL any longer, so testing for that condition is no longer needed.Acked-by Andrii Nakryiko <[email protected]>Signed-off-by Ard Biesheuvel <[email protected]>--- include/asm-generic/vmlinux.lds.h | 9 +++++++++ kernel/bpf/btf.c | 4 ++-- kernel/bpf/sysfs_btf.c | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-)include/asm-generic/vmlinux.lds.h +1
-0@@ -456,6 +456,7 @@* independent code. */ #define PRELIMINARY_SYMBOL_DEFINITIONS \ + PRELIMINARY_BTF_DEFINITIONS \ PROVIDE(kallsyms_addresses = .); \ PROVIDE(kallsyms_offsets = .); \ PROVIDE(kallsyms_names = .); \include/asm-generic/vmlinux.lds.h line 476
Quoted 10 lines
include/asm-generic/vmlinux.lds.h +7
-0@@ -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 hi,
I'm getting following compilation fail whenCONFIG_DEBUG_INFO_BTFis disabled[jolsa@krava linux-qemu]$ make
CALLscripts/checksyscalls.sh
DESCEND objtool
INSTALLlibsubcmd_headers
UPDinclude/generated/utsversion.h
CCinit/version-timestamp.o
LD .tmp_vmlinux.kallsyms1
ld:kernel/bpf/btf.o: in function `btf_parse_vmlinux':
/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5988: undefined reference to `__start_BTF'
ld:/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__stop_BTF'
ld:/home/jolsa/kernel/linux-qemu/kernel/bpf/btf.c:5989: undefined reference to `__start_BTF' make[2]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1
make[1]: *** [/home/jolsa/kernel/linux-qemu/Makefile:1160: vmlinux] Error 2
make: *** [Makefile:240: __sub-make] Error 2Quoted 5 lines
maybe the assumption was that
kernel/bpf/btf.ois compiled only forCONFIG_DEBUG_INFO_BTF, but it's actually:obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.oInteresting. I did build test this with and without
CONFIG_DEBUG_INFO_BTF, but not withCONFIG_BPF_SYSCALL=yandCONFIG_DEBUG_INFO_BTF=n.Quoted 3 lines
I guess we just need !CONFIG_DEBUG_INFO_BTF version of
btf_parse_vmlinuxfunctionThe below gives me a working build.
kernel/bpf/btf.c struct btf *btf_parse_vmlinux(void) · line 5975
Quoted 5 lines
kernel/bpf/btf.c +2
-0@@ -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 );
nice, so this basically eliminates the rest of the function, I did not know this would work
build's fine now, thanks
jirka
Quoted 4 lines
kernel/bpf/btf.c +1
-0+ env =kzalloc (sizeof (*env),GFP_KERNEL | __GFP_NOWARN);if (!env)return ERR_PTR (-ENOMEM );