When generating a light skeleton, libbpf currently records the unstripped name (e.g., `func___compat`) of kfuncs into the external symbol records. However, the kernel's verifier strips suffixes and expects the essential name to resolve `bpf_ksym_exists()` correctly. This breaks backwards-compatibility fallback logic in light skeletons, as the kernel fails to resolve the suffixed kfunc and evaluates `bpf_ksym_exists()` to 0, falsely assuming the kfunc is absent. Fix this by passing `ext->essent_name` when calling `bpf_gen__record_extern()` for BTF_KIND_FUNC. For BTF_KIND_VAR, the behavior is unchanged, preserving suffix compatibility. Signed-off-by: Siddharth Nayyar --- tools/lib/bpf/libbpf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 1368752aa13c..421bfd5e159d 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8309,19 +8309,25 @@ static int bpf_program_record_relos(struct bpf_program *prog) struct reloc_desc *relo = &prog->reloc_desc[i]; struct extern_desc *ext = &obj->externs[relo->ext_idx]; int kind; + const char *name; switch (relo->type) { case RELO_EXTERN_LD64: if (ext->type != EXT_KSYM) continue; - kind = btf_is_var(btf__type_by_id(obj->btf, ext->btf_id)) ? - BTF_KIND_VAR : BTF_KIND_FUNC; - bpf_gen__record_extern(obj->gen_loader, ext->name, + if (btf_is_var(btf__type_by_id(obj->btf, ext->btf_id))) { + kind = BTF_KIND_VAR; + name = ext->name; + } else { + kind = BTF_KIND_FUNC; + name = ext->essent_name ?: ext->name; + } + bpf_gen__record_extern(obj->gen_loader, name, ext->is_weak, !ext->ksym.type_id, true, kind, relo->insn_idx); break; case RELO_EXTERN_CALL: - bpf_gen__record_extern(obj->gen_loader, ext->name, + bpf_gen__record_extern(obj->gen_loader, ext->essent_name ?: ext->name, ext->is_weak, false, false, BTF_KIND_FUNC, relo->insn_idx); break; --- base-commit: e771677c937da5808f7b6c1f0e4a97ec1a84f8a8 change-id: 20260622-bpf-lskel-fixes-cafd1a83dec2 Best regards, -- Siddharth Nayyar