libbpf: Preliminary support for fd_idx
authorAlexei Starovoitov <ast@kernel.org>
Fri, 14 May 2021 00:36:15 +0000 (17:36 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Tue, 18 May 2021 22:33:41 +0000 (00:33 +0200)
Prep libbpf to use FD_IDX kernel feature when generating loader program.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210514003623.28033-14-alexei.starovoitov@gmail.com
tools/lib/bpf/libbpf.c

index 29e26fabe2eef5f32ac729601ed65925ad1239bb..f398ca83167e534675b8374ef7fc2465d250ec7b 100644 (file)
@@ -412,6 +412,8 @@ struct module_btf {
        int fd;
 };
 
+struct bpf_gen;
+
 struct bpf_object {
        char name[BPF_OBJ_NAME_LEN];
        char license[64];
@@ -432,6 +434,8 @@ struct bpf_object {
        bool loaded;
        bool has_subcalls;
 
+       struct bpf_gen *gen_loader;
+
        /*
         * Information when doing elf related work. Only valid if fd
         * is valid.
@@ -6388,19 +6392,34 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
 
                switch (relo->type) {
                case RELO_LD64:
-                       insn[0].src_reg = BPF_PSEUDO_MAP_FD;
-                       insn[0].imm = obj->maps[relo->map_idx].fd;
+                       if (obj->gen_loader) {
+                               insn[0].src_reg = BPF_PSEUDO_MAP_IDX;
+                               insn[0].imm = relo->map_idx;
+                       } else {
+                               insn[0].src_reg = BPF_PSEUDO_MAP_FD;
+                               insn[0].imm = obj->maps[relo->map_idx].fd;
+                       }
                        break;
                case RELO_DATA:
-                       insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
                        insn[1].imm = insn[0].imm + relo->sym_off;
-                       insn[0].imm = obj->maps[relo->map_idx].fd;
+                       if (obj->gen_loader) {
+                               insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
+                               insn[0].imm = relo->map_idx;
+                       } else {
+                               insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+                               insn[0].imm = obj->maps[relo->map_idx].fd;
+                       }
                        break;
                case RELO_EXTERN_VAR:
                        ext = &obj->externs[relo->sym_off];
                        if (ext->type == EXT_KCFG) {
-                               insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
-                               insn[0].imm = obj->maps[obj->kconfig_map_idx].fd;
+                               if (obj->gen_loader) {
+                                       insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
+                                       insn[0].imm = obj->kconfig_map_idx;
+                               } else {
+                                       insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+                                       insn[0].imm = obj->maps[obj->kconfig_map_idx].fd;
+                               }
                                insn[1].imm = ext->kcfg.data_off;
                        } else /* EXT_KSYM */ {
                                if (ext->ksym.type_id) { /* typed ksyms */