mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-05 17:30:15 +08:00
libbpf: Support pointers to static functions in data when linking
A pointer to a static function in data, e.g.
static int (* const handlers[])(void *ctx) = { foo, bar };
is R_BPF_64_ABS64 relocation against .text section symbol with the offset
of the function stored in place. The linker rejects it:
relocation against STT_SECTION in non-exec section is not supported!
so an object with a table of static functions cannot go through
'bpftool gen object', which all selftests do.
Functions move by the offset of input .text in the output section.
Add it to the pointer. Swap bytes if the object is of foreign endianness,
since data sections are kept in the byte order of the object.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260924031042.1690890-12-alexei.starovoitov@gmail.com
This commit is contained in:
1 parent
9b828bca53
commit
3600abb979
1 file changed
+18
@@ -2274,6 +2274,24 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob
|
||||
insn->imm += sec->dst_off / sizeof(struct bpf_insn);
|
||||
else
|
||||
insn->imm += sec->dst_off;
|
||||
} else if (sym_type == R_BPF_64_ABS64 &&
|
||||
(sec->shdr->sh_flags & SHF_EXECINSTR)) {
|
||||
/*
|
||||
* A pointer to a static function in a data section,
|
||||
* which is stored in place as an offset of the
|
||||
* function in its section. Data sections are kept
|
||||
* in the byte order of the object.
|
||||
*/
|
||||
void *ptr = dst_linked_sec->raw_data + dst_rel->r_offset;
|
||||
__u64 off;
|
||||
|
||||
memcpy(&off, ptr, sizeof(off));
|
||||
if (linker->swapped_endian)
|
||||
off = bswap_64(off);
|
||||
off += sec->dst_off;
|
||||
if (linker->swapped_endian)
|
||||
off = bswap_64(off);
|
||||
memcpy(ptr, &off, sizeof(off));
|
||||
} else {
|
||||
pr_warn("relocation against STT_SECTION in non-exec section is not supported!\n");
|
||||
return -EINVAL;
|
||||
|
||||
Reference in new issue
Block a user