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: a46349227c ("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>
This commit is contained in:
Andrii Nakryiko 2024-10-07 20:28:53 -07:00
commit 1d943a238b
3 changed files with 20 additions and 0 deletions

View File

@ -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

View File

@ -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";

View File

@ -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";