diff options
author | Andrii Nakryiko <andrii@kernel.org> | 2024-10-07 20:28:53 -0700 |
---|---|---|
committer | Andrii Nakryiko <andrii@kernel.org> | 2024-10-07 20:28:54 -0700 |
commit | 1d943a238b167d1571799ced65b0902f118cdda3 (patch) | |
tree | c28120e0e644495f7e481267a12db2132fa0f8b7 | |
parent | c50fc1cbfd71dcb1d70fd593b2af7c92af465921 (diff) | |
parent | 3c591de2854381e313ec149bc1bbd8360f9ed53b (diff) |
Merge branch 'bpf-static-linker-fix-linking-duplicate-extern-functions'
Eric Long via says:
====================
BPF static linker: fix linking duplicate extern functions
Currently, if `bpftool gen object` tries to link two objects that
contains the same extern function prototype, libbpf will try to get
their (non-existent) size by calling bpf__resolve_size like extern
variables and fail with:
libbpf: global 'whatever': failed to resolve size of underlying type: -22
This should not be the case, and this series adds conditions to update
size only when the BTF kind is not function.
Fixes: a46349227cd8 ("libbpf: Add linker extern resolution support for functions and global variables")
Signed-off-by: Eric Long <i@hack3r.moe>
---
Changes in v4:
- Remove redundant FUNC_PROTO check.
- Merge tests into linked_funcs.
- Link to v3: https://lore.kernel.org/r/20241001-libbpf-dup-extern-funcs-v3-0-42f7774efbf3@hack3r.moe
Changes in v3:
- Simplifiy changes and shorten subjects, according to reviews.
- Remove unused includes in selftests.
- Link to v2: https://lore.kernel.org/r/20240929-libbpf-dup-extern-funcs-v2-0-0cc81de3f79f@hack3r.moe
Changes in v2:
- Fix compile errors. Oops!
- Link to v1: https://lore.kernel.org/r/20240929-libbpf-dup-extern-funcs-v1-0-df15fbd6525b@hack3r.moe
---
====================
Link: https://lore.kernel.org/r/20241002-libbpf-dup-extern-funcs-v4-0-560eb460ff90@hack3r.moe
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
-rw-r--r-- | tools/lib/bpf/linker.c | 4 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/progs/linked_funcs1.c | 8 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/progs/linked_funcs2.c | 8 |
3 files changed, 20 insertions, 0 deletions
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index 81dbbdd79a7c..f83c1c29982c 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -2451,6 +2451,10 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) if (glob_sym && glob_sym->var_idx >= 0) { __s64 sz; + /* FUNCs don't have size, nothing to update */ + if (btf_is_func(t)) + continue; + dst_var = &dst_sec->sec_vars[glob_sym->var_idx]; /* Because underlying BTF type might have * changed, so might its size have changed, so diff --git a/tools/testing/selftests/bpf/progs/linked_funcs1.c b/tools/testing/selftests/bpf/progs/linked_funcs1.c index cc79dddac182..049a1f78de3f 100644 --- a/tools/testing/selftests/bpf/progs/linked_funcs1.c +++ b/tools/testing/selftests/bpf/progs/linked_funcs1.c @@ -63,6 +63,8 @@ extern int set_output_val2(int x); /* here we'll force set_output_ctx2() to be __hidden in the final obj file */ __hidden extern void set_output_ctx2(__u64 *ctx); +void *bpf_cast_to_kern_ctx(void *obj) __ksym; + SEC("?raw_tp/sys_enter") int BPF_PROG(handler1, struct pt_regs *regs, long id) { @@ -86,4 +88,10 @@ int BPF_PROG(handler1, struct pt_regs *regs, long id) return 0; } +/* Generate BTF FUNC record and test linking with duplicate extern functions */ +void kfunc_gen1(void) +{ + bpf_cast_to_kern_ctx(0); +} + char LICENSE[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/linked_funcs2.c b/tools/testing/selftests/bpf/progs/linked_funcs2.c index 942cc5526ddf..96850759fd8d 100644 --- a/tools/testing/selftests/bpf/progs/linked_funcs2.c +++ b/tools/testing/selftests/bpf/progs/linked_funcs2.c @@ -63,6 +63,8 @@ extern int set_output_val1(int x); /* here we'll force set_output_ctx1() to be __hidden in the final obj file */ __hidden extern void set_output_ctx1(__u64 *ctx); +void *bpf_cast_to_kern_ctx(void *obj) __ksym; + SEC("?raw_tp/sys_enter") int BPF_PROG(handler2, struct pt_regs *regs, long id) { @@ -86,4 +88,10 @@ int BPF_PROG(handler2, struct pt_regs *regs, long id) return 0; } +/* Generate BTF FUNC record and test linking with duplicate extern functions */ +void kfunc_gen2(void) +{ + bpf_cast_to_kern_ctx(0); +} + char LICENSE[] SEC("license") = "GPL"; |