For raw tracepoint program types libbpf will try to find btf_id of raw tracepoint in vmlinux's BTF. It's a responsiblity of bpf program author to annotate the program with SEC("raw_tracepoint/name") where "name" is a valid raw tracepoint. If "name" is indeed a valid raw tracepoint then in-kernel BTF will have "btf_trace_##name" typedef that points to function prototype of that raw tracepoint. BTF description captures exact argument the kernel C code is passing into raw tracepoint. The kernel verifier will check the types while loading bpf program. libbpf keeps BTF type id in expected_attach_type, but since kernel ignores this attribute for tracing programs copy it into attach_btf_id attribute before loading. Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> --- tools/lib/bpf/bpf.c | 3 +++ tools/lib/bpf/libbpf.c | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index cbb933532981..79046067720f 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -228,6 +228,9 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, memset(&attr, 0, sizeof(attr)); attr.prog_type = load_attr->prog_type; attr.expected_attach_type = load_attr->expected_attach_type; + if (attr.prog_type == BPF_PROG_TYPE_RAW_TRACEPOINT) + /* expected_attach_type is ignored for tracing progs */ + attr.attach_btf_id = attr.expected_attach_type; attr.insn_cnt = (__u32)load_attr->insns_cnt; attr.insns = ptr_to_u64(load_attr->insns); attr.license = ptr_to_u64(load_attr->license); diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a02cdedc4e3f..8bf30a67428c 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4586,6 +4586,23 @@ int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, continue; *prog_type = section_names[i].prog_type; *expected_attach_type = section_names[i].expected_attach_type; + if (*prog_type == BPF_PROG_TYPE_RAW_TRACEPOINT) { + struct btf *btf = bpf_core_find_kernel_btf(); + char raw_tp_btf_name[128] = "btf_trace_"; + char *dst = raw_tp_btf_name + sizeof("btf_trace_") - 1; + int ret; + + if (IS_ERR(btf)) + /* lack of kernel BTF is not a failure */ + return 0; + /* prepend "btf_trace_" prefix per kernel convention */ + strncat(dst, name + section_names[i].len, + sizeof(raw_tp_btf_name) - (dst - raw_tp_btf_name)); + ret = btf__find_by_name(btf, raw_tp_btf_name); + if (ret > 0) + *expected_attach_type = ret; + btf__free(btf); + } return 0; } pr_warning("failed to guess program type based on ELF section name '%s'\n", name); -- 2.23.0