Search code examples
ebpf

what's func_info in eBPF verifier?


I'm developing an XDP program and I'm facing this error when trying to mount it in NIC driver:

libbpf: failed to guess program type based on ELF section name '.text'
libbpf: supported section(type) names are: socket kprobe/ uprobe/ kretprobe/ uretprobe/ classifier action tracepoint/ tp/ raw_tracepoint/ raw_tp/ tp_btf/ xdp perf_event lwt_in lwt_out lwt_xmit lwt_seg6local cgroup_skb/ingress cgroup_skb/egress cgroup/skb cgroup/sock cgroup/post_bind4 cgroup/post_bind6 cgroup/dev sockops sk_skb/stream_parser sk_skb/stream_verdict sk_skb sk_msg lirc_mode2 flow_dissector cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/recvmsg4 cgroup/recvmsg6 cgroup/sysctl cgroup/getsockopt cgroup/setsockopt
libbpf: load bpf program failed: Invalid argument
libbpf: -- BEGIN DUMP LOG ---
libbpf: 
number of funcs in func_info doesn't match number of subprogs
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
libbpf: -- END LOG --
libbpf: failed to load program '.text'

I searched and found the error is raising when eBPF verifier trying to compare attr->func_info_cnt and env->subprog_cnt but I don't understand how these two values are set before processed by the verifier. I have one XDP program with one section and 6 functions as helpers, I'm not sure if this info can help but I can provide more about the structure of the program if needed.


Solution

  • Did you omit to put your programs in a dedicated ELF section? Something like:

    SEC("xdp")
    int my_prog(struct xdp_md *ctx)
    {
            ...
    }
    

    (Where SEC() is a macro defined in libbpf's bpf_helpers.h header.)

    If you do not specify any ELF section name, clang/LLVM defaults to .text, as in your error message. When you attempt to load a program with libbpf, the library usually guesses the program type from the name of the ELF section into which the program was put. If you do not use a dedicated section name, and do not otherwise specify the program type (for example, in libbpf with bpf_program__set_type()), then libbpf is unable to pick the relevant type for your program.

    This could lead to some of your programs to fail to load. From the error message above, it looks like you use function calls in your program (instead of declaring, for example, your functions as static inline). When your main program passes the verifier, some parts will be missing: The “functions” may not be loaded, so the verifier complains that the expected number of functions/subprograms inferred from the main program (env->subprog_cnt) is different from the number of functions collected by your loader application (attr->func_info_cnt) and passed down to the kernel when loading the program with the bpf() system call.

    If this is the case, you can probably fix the issue either by placing your code in dedicated ELF functions, or by declaring your functions as static inline if you do not require function calls in the generated bytecode.