Unable to run minimal binary on machines with CONFIG_DEBUG_INFO_BTF not set.
mayank-ramnani opened this issue · 1 comments
mayank-ramnani commented
Minimal binary from libbpf-bootstrap source was modified to remove usage of global variables and use custom btf path while opening.
- Modified btf source code
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
char LICENSE[] SEC("license") = "Dual BSD/GPL";
SEC("tp/syscalls/sys_enter_write")
int handle_tp(void *ctx)
{
int pid = bpf_get_current_pid_tgid() >> 32;
bpf_printk("BPF triggered from PID %d.\n", pid);
return 0;
}
- Modified C code
/* Open BPF application */
// bpf object open options
char *btf_file;
struct bpf_object_open_opts openopts = {};
openopts.sz = sizeof(struct bpf_object_open_opts);
btf_file = getenv("EXAMPLE_BTF_FILE");
if (btf_file != NULL)
openopts.btf_custom_path = strdup(btf_file);
skel = minimal_bpf__open_opts(&openopts);
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}
/* Load & verify BPF programs */
err = minimal_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup;
}
Execution on Centos 7.9.2009
[root@localhost c]# uname -r
3.10.0-1160.45.1.el7.x86_64
[root@localhost c]# EXAMPLE_BTF_FILE=/tmp/3.10.0-1160.45.1.el7.x86_64.btf ./minimal
libbpf: loading object 'minimal_bpf' from buffer
libbpf: elf: section(3) tp/syscalls/sys_enter_write, size 72, link 0, flags 6, type=1
libbpf: sec 'tp/syscalls/sys_enter_write': found program 'handle_tp' at insn offset 0 (0 bytes), code size 9 insns (72 bytes)
libbpf: elf: section(4) .reltp/syscalls/sys_enter_write, size 16, link 12, flags 40, type=9
libbpf: elf: section(5) license, size 13, link 0, flags 3, type=1
libbpf: license of minimal_bpf is Dual BSD/GPL
libbpf: elf: section(6) .rodata, size 28, link 0, flags 2, type=1
libbpf: elf: section(7) .BTF, size 531, link 0, flags 0, type=1
libbpf: elf: section(9) .BTF.ext, size 128, link 0, flags 0, type=1
libbpf: elf: section(12) .symtab, size 144, link 1, flags 0, type=2
libbpf: looking for externs among 6 symbols...
libbpf: collected 0 externs total
libbpf: map 'minimal_.rodata' (global data): at sec_idx 6, offset 0, flags 480.
libbpf: map 0 is "minimal_.rodata"
libbpf: sec '.reltp/syscalls/sys_enter_write': collecting relocation for section(3) 'tp/syscalls/sys_enter_write'
libbpf: sec '.reltp/syscalls/sys_enter_write': relo #0: insn #2 against '.rodata'
libbpf: prog 'handle_tp': found data map 0 (minimal_.rodata, sec 6, off 0) for insn 2
libbpf: Kernel doesn't support BTF, skipping uploading it.
libbpf: prog 'handle_tp': relo #0: kernel doesn't support global data
libbpf: prog 'handle_tp': failed to relocate data references: -95
libbpf: failed to load object 'minimal_bpf'
libbpf: failed to load BPF skeleton 'minimal_bpf': -95
Failed to load and verify BPF skeleton
Similarly, execution fails on Ubuntu 18.04 (4.15.0-136-generic) even after supplying a btf file obtained from the btfhub archive.
My basic question is as follows:
- Is it even possible to run co-re binaries on kernels with no BTF support by supplying a custom btf file?
mayank-ramnani commented
libbpf: prog 'handle_tp': relo #0: kernel doesn't support global data
This was the issue.
The string in bpf_printk comes under .rodata section of the ELF object file.
.rodata section of an elf can be checked using:
objdump -s -j .rodata ./probe.bpf.o
After removing all the bpf_printk strings, loading was succesful.