Commit 9173cac3 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

libbpf: Support .text sub-calls relocations

The LLVM patch https://reviews.llvm.org/D72197 makes LLVM emit function call
relocations within the same section. This includes a default .text section,
which contains any BPF sub-programs. This wasn't the case before and so libbpf
was able to get a way with slightly simpler handling of subprogram call
relocations.

This patch adds support for .text section relocations. It needs to ensure
correct order of relocations, so does two passes:
- first, relocate .text instructions, if there are any relocations in it;
- then process all the other programs and copy over patched .text instructions
for all sub-program calls.

v1->v2:
- break early once .text program is processed.
Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200115190856.2391325-1-andriin@fb.com
parent 5640a771
...@@ -4692,13 +4692,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, ...@@ -4692,13 +4692,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
size_t new_cnt; size_t new_cnt;
int err; int err;
if (prog->idx == obj->efile.text_shndx) { if (prog->idx != obj->efile.text_shndx && prog->main_prog_cnt == 0) {
pr_warn("relo in .text insn %d into off %d (insn #%d)\n",
relo->insn_idx, relo->sym_off, relo->sym_off / 8);
return -LIBBPF_ERRNO__RELOC;
}
if (prog->main_prog_cnt == 0) {
text = bpf_object__find_prog_by_idx(obj, obj->efile.text_shndx); text = bpf_object__find_prog_by_idx(obj, obj->efile.text_shndx);
if (!text) { if (!text) {
pr_warn("no .text section found yet relo into text exist\n"); pr_warn("no .text section found yet relo into text exist\n");
...@@ -4728,6 +4722,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, ...@@ -4728,6 +4722,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
text->insns_cnt, text->section_name, text->insns_cnt, text->section_name,
prog->section_name); prog->section_name);
} }
insn = &prog->insns[relo->insn_idx]; insn = &prog->insns[relo->insn_idx];
insn->imm += relo->sym_off / 8 + prog->main_prog_cnt - relo->insn_idx; insn->imm += relo->sym_off / 8 + prog->main_prog_cnt - relo->insn_idx;
return 0; return 0;
...@@ -4807,8 +4802,28 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path) ...@@ -4807,8 +4802,28 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
return err; return err;
} }
} }
/* ensure .text is relocated first, as it's going to be copied as-is
* later for sub-program calls
*/
for (i = 0; i < obj->nr_programs; i++) {
prog = &obj->programs[i];
if (prog->idx != obj->efile.text_shndx)
continue;
err = bpf_program__relocate(prog, obj);
if (err) {
pr_warn("failed to relocate '%s'\n", prog->section_name);
return err;
}
break;
}
/* now relocate everything but .text, which by now is relocated
* properly, so we can copy raw sub-program instructions as is safely
*/
for (i = 0; i < obj->nr_programs; i++) { for (i = 0; i < obj->nr_programs; i++) {
prog = &obj->programs[i]; prog = &obj->programs[i];
if (prog->idx == obj->efile.text_shndx)
continue;
err = bpf_program__relocate(prog, obj); err = bpf_program__relocate(prog, obj);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment