Context |
Check |
Description |
netdev/series_format |
warning
|
Series does not have a cover letter
|
netdev/tree_selection |
success
|
Guessed tree name to be net-next, async
|
netdev/ynl |
success
|
Generated files up to date;
no warnings/errors;
no diff in generated;
|
netdev/fixes_present |
success
|
Fixes tag not required for -next series
|
netdev/header_inline |
success
|
No static functions without inline keyword in header files
|
netdev/build_32bit |
success
|
Errors and warnings before: 9 this patch: 7
|
netdev/build_tools |
success
|
No tools touched, skip
|
netdev/cc_maintainers |
fail
|
12 maintainers not CCed: jolsa@kernel.org john.fastabend@gmail.com ast@kernel.org daniel@iogearbox.net martin.lau@linux.dev yonghong.song@linux.dev eddyz87@gmail.com andrii@kernel.org song@kernel.org sdf@fomichev.me kpsingh@kernel.org haoluo@google.com
|
netdev/build_clang |
success
|
Errors and warnings before: 11 this patch: 9
|
netdev/verify_signedoff |
success
|
Signed-off-by tag matches author and committer
|
netdev/deprecated_api |
success
|
None detected
|
netdev/check_selftest |
success
|
No net selftest shell script
|
netdev/verify_fixes |
success
|
No Fixes tag
|
netdev/build_allmodconfig_warn |
success
|
Errors and warnings before: 9 this patch: 7
|
netdev/checkpatch |
warning
|
CHECK: Blank lines aren't necessary before a close brace '}'
WARNING: line length of 81 exceeds 80 columns
WARNING: line length of 82 exceeds 80 columns
WARNING: line length of 88 exceeds 80 columns
WARNING: line length of 90 exceeds 80 columns
|
netdev/build_clang_rust |
success
|
No Rust files in patch. Skipping build
|
netdev/kdoc |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/source_inline |
success
|
Was 0 now: 0
|
bpf/vmtest-bpf-net-VM_Test-3 |
success
|
Logs for Validate matrix.py
|
bpf/vmtest-bpf-net-VM_Test-5 |
success
|
Logs for aarch64-gcc / build-release
|
bpf/vmtest-bpf-net-VM_Test-2 |
success
|
Logs for Unittests
|
bpf/vmtest-bpf-net-VM_Test-0 |
success
|
Logs for Lint
|
bpf/vmtest-bpf-net-VM_Test-1 |
success
|
Logs for ShellCheck
|
bpf/vmtest-bpf-net-VM_Test-4 |
success
|
Logs for aarch64-gcc / build / build for aarch64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-10 |
success
|
Logs for aarch64-gcc / veristat-kernel
|
bpf/vmtest-bpf-net-VM_Test-11 |
success
|
Logs for aarch64-gcc / veristat-meta
|
bpf/vmtest-bpf-net-VM_Test-13 |
success
|
Logs for s390x-gcc / build-release
|
bpf/vmtest-bpf-net-VM_Test-6 |
success
|
Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-9 |
success
|
Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-12 |
success
|
Logs for s390x-gcc / build / build for s390x with gcc
|
bpf/vmtest-bpf-net-VM_Test-16 |
success
|
Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
|
bpf/vmtest-bpf-net-VM_Test-17 |
success
|
Logs for s390x-gcc / veristat-kernel
|
bpf/vmtest-bpf-net-VM_Test-18 |
success
|
Logs for s390x-gcc / veristat-meta
|
bpf/vmtest-bpf-net-VM_Test-19 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-net-VM_Test-20 |
success
|
Logs for x86_64-gcc / build / build for x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-21 |
success
|
Logs for x86_64-gcc / build-release
|
bpf/vmtest-bpf-net-VM_Test-30 |
success
|
Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
|
bpf/vmtest-bpf-net-VM_Test-31 |
success
|
Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
|
bpf/vmtest-bpf-net-VM_Test-36 |
success
|
Logs for x86_64-llvm-17 / veristat-kernel
|
bpf/vmtest-bpf-net-VM_Test-37 |
success
|
Logs for x86_64-llvm-17 / veristat-meta
|
bpf/vmtest-bpf-net-VM_Test-38 |
success
|
Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
|
bpf/vmtest-bpf-net-VM_Test-39 |
success
|
Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
|
bpf/vmtest-bpf-net-VM_Test-45 |
success
|
Logs for x86_64-llvm-18 / veristat-kernel
|
bpf/vmtest-bpf-net-VM_Test-46 |
success
|
Logs for x86_64-llvm-18 / veristat-meta
|
bpf/vmtest-bpf-net-VM_Test-7 |
fail
|
Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-8 |
fail
|
Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-15 |
fail
|
Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
|
bpf/vmtest-bpf-net-VM_Test-35 |
success
|
Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
|
bpf/vmtest-bpf-net-VM_Test-14 |
fail
|
Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
|
bpf/vmtest-bpf-net-VM_Test-22 |
success
|
Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-23 |
fail
|
Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-24 |
fail
|
Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-25 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-26 |
success
|
Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-27 |
success
|
Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
|
bpf/vmtest-bpf-net-VM_Test-28 |
success
|
Logs for x86_64-gcc / veristat-kernel / x86_64-gcc veristat_kernel
|
bpf/vmtest-bpf-net-VM_Test-29 |
success
|
Logs for x86_64-gcc / veristat-meta / x86_64-gcc veristat_meta
|
bpf/vmtest-bpf-net-VM_Test-32 |
success
|
Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
|
bpf/vmtest-bpf-net-VM_Test-33 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
|
bpf/vmtest-bpf-net-VM_Test-34 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
|
bpf/vmtest-bpf-net-VM_Test-44 |
success
|
Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
|
bpf/vmtest-bpf-net-PR |
fail
|
PR summary
|
bpf/vmtest-bpf-net-VM_Test-40 |
success
|
Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
|
bpf/vmtest-bpf-net-VM_Test-41 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
|
bpf/vmtest-bpf-net-VM_Test-42 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
|
bpf/vmtest-bpf-net-VM_Test-43 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
|
@@ -6074,6 +6074,177 @@ skip_mods_and_typedefs(const struct btf *btf, u32 id, u32 *res_id)
return t;
}
+static int init_btf(struct bpf_obj *obj, unsigned int btf_idx, unsigned int btf_ext_idx)
+{
+ Elf_Shdr *shdr = &obj->sechdrs[btf_idx];
+ void *buffer = (void *)obj->hdr + shdr->sh_offset;
+ struct btf_ext_info *ext_segs[3];
+ int seg_num, sec_num;
+ int idx;
+ struct btf_ext_info *seg;
+ const struct btf_ext_info_sec *sec;
+ const char *sec_name;
+ struct btf *btf = btf_init_mem(buffer, shdr->sh_size, 0, 0, 0);
+
+ obj->btf = btf;
+ shdr = &obj->sechdrs[btf_ext_idx];
+ buffer = (void *)obj->hdr + shdr->sh_offset;
+ obj->btf_ext = btf_ext__new(buffer, shdr->sh_size);
+ obj->index.btf = btf_idx;
+ obj->index.btf_ext = btf_ext_idx;
+
+ /* setup .BTF.ext to ELF section mapping */
+ ext_segs[0] = &obj->btf_ext->func_info;
+ ext_segs[1] = &obj->btf_ext->line_info;
+ ext_segs[2] = &obj->btf_ext->core_relo_info;
+ for (seg_num = 0; seg_num < ARRAY_SIZE(ext_segs); seg_num++) {
+ seg = ext_segs[seg_num];
+
+ if (seg->sec_cnt == 0)
+ continue;
+
+ seg->sec_idxs = kcalloc(seg->sec_cnt, sizeof(*seg->sec_idxs), GFP_KERNEL);
+ if (!seg->sec_idxs)
+ return -ENOMEM;
+
+ sec_num = 0;
+ for_each_btf_ext_sec(seg, sec) {
+ /* preventively increment index to avoid doing
+ * this before every continue below
+ */
+ sec_num++;
+
+ sec_name = btf_str_by_offset(obj->btf, sec->sec_name_off);
+ if (str_is_empty(sec_name))
+ continue;
+
+ idx = elf_sec_idx_by_name(obj, sec_name);
+ if (idx < 0)
+ continue;
+ seg->sec_idxs[sec_num - 1] = idx;
+ }
+ }
+ return 0;
+}
+
+static int find_progs(struct bpf_obj *obj, unsigned int sec_idx)
+{
+ unsigned int i;
+ unsigned int prog_sz;
+ unsigned int sec_off;
+ Elf_Shdr *symsec = &obj->sechdrs[obj->index.sym];
+ Elf_Sym *sym = (void *)obj->hdr + symsec->sh_offset;
+ Elf_Shdr *shdr = &obj->sechdrs[sec_idx];
+ struct bpf_prog_obj *progs;
+ int err;
+ struct bpf_insn *insns = NULL;
+ void *buffer;
+ unsigned int insn_cnt, ndx;
+ char *name;
+
+ for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) {
+ name = obj->strtab + sym[i].st_name;
+
+ if (sym[i].st_shndx != sec_idx)
+ continue;
+ if (ELF64_ST_TYPE(sym[i].st_info) != STT_FUNC)
+ continue;
+
+ prog_sz = sym[i].st_size;
+ sec_off = sym[i].st_value;
+ buffer = (void *)obj->hdr + shdr->sh_offset + sec_off;
+
+ insns = kmalloc(prog_sz, GFP_KERNEL);
+ if (!insns)
+ return -ENOMEM;
+
+ memcpy(insns, buffer, prog_sz);
+ insn_cnt = prog_sz / sizeof(struct bpf_insn);
+
+ progs = krealloc_array(obj->progs, obj->nr_programs + 1,
+ sizeof(struct bpf_prog_obj), GFP_KERNEL);
+ if (!progs) {
+ err = -ENOMEM;
+ goto free_insns;
+ }
+
+ obj->progs = progs;
+ ndx = obj->nr_programs;
+ obj->progs[ndx].insn = insns;
+ obj->progs[ndx].insn_cnt = insn_cnt;
+ obj->progs[ndx].sec_idx = sec_idx;
+ obj->progs[ndx].sec_insn_off = sec_off / sizeof(struct bpf_insn);
+ obj->progs[ndx].sec_insn_cnt = insn_cnt;
+ obj->progs[ndx].name = name;
+ obj->progs[ndx].exception_cb_idx = -1;
+ obj->nr_programs++;
+
+ }
+ return 0;
+
+free_insns:
+ kfree(insns);
+ return err;
+}
+
+static int elf_collect(struct bpf_obj *obj)
+{
+ unsigned int i;
+ Elf_Shdr *shdr, *strhdr;
+ unsigned int sym_idx;
+ unsigned int sec_idx = 0;
+ unsigned int btf_idx = 0, btf_ext_idx = 0;
+ int err = 0;
+
+ obj->sechdrs = (void *)obj->hdr + obj->hdr->e_shoff;
+ strhdr = &obj->sechdrs[obj->hdr->e_shstrndx];
+ obj->secstrings = (void *)obj->hdr + strhdr->sh_offset;
+
+ for (i = 1; i < obj->hdr->e_shnum; i++) {
+ shdr = &obj->sechdrs[i];
+ switch (shdr->sh_type) {
+ case SHT_NULL:
+ case SHT_NOBITS:
+ continue;
+ case SHT_SYMTAB:
+ sym_idx = i;
+ fallthrough;
+ default:
+ break;
+ }
+ }
+
+ obj->index.sym = sym_idx;
+ shdr = &obj->sechdrs[sym_idx];
+ obj->index.str = shdr->sh_link;
+ obj->strtab = (char *)obj->hdr + obj->sechdrs[obj->index.str].sh_offset;
+
+ for (i = 1; i < obj->hdr->e_shnum; i++) {
+ shdr = &obj->sechdrs[i];
+ sec_idx = i;
+ if (strcmp(".text", obj->secstrings + shdr->sh_name) == 0)
+ obj->index.text = sec_idx;
+
+ if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0) {
+ err = find_progs(obj, sec_idx);
+ if (err)
+ return err;
+ }
+
+ if (strcmp(".BTF", obj->secstrings + shdr->sh_name) == 0)
+ btf_idx = i;
+
+ if (strcmp(".BTF.ext", obj->secstrings + shdr->sh_name) == 0)
+ btf_ext_idx = i;
+
+ if (strcmp(".addr_space.1", obj->secstrings + shdr->sh_name) == 0)
+ obj->index.arena = sec_idx;
+ }
+
+ err = init_btf(obj, btf_idx, btf_ext_idx);
+ return err;
+}
+
static void free_bpf_obj(struct bpf_obj *obj)
{
int i;
@@ -6305,6 +6476,10 @@ static int load_fd(union bpf_attr *attr)
}
kfree(modules);
+ err = elf_collect(obj);
+ if (err < 0)
+ goto free;
+
return obj_f;
free:
free_bpf_obj(obj);
Using the sysfs entry passed into the subcommand, the previosly loaded elf object file is parsed. The objective of this parse is to identify key elf file sections, specfically the text and btf sections. From there, indicies are saved to relevant sections. Armed with the initial parse info, we search for and create program definitions, along with any respective btf information for them. Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com> --- kernel/bpf/syscall.c | 175 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+)