bpftool: Generate externs datasec in BPF skeleton
authorAndrii Nakryiko <andriin@fb.com>
Sat, 14 Dec 2019 01:47:09 +0000 (17:47 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 16 Dec 2019 00:41:12 +0000 (16:41 -0800)
Add support for generation of mmap()-ed read-only view of libbpf-provided
extern variables. As externs are not supposed to be provided by user code
(that's what .data, .bss, and .rodata is for), don't mmap() it initially. Only
after skeleton load is performed, map .extern contents as read-only memory.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20191214014710.3449601-4-andriin@fb.com
tools/bpf/bpftool/gen.c
tools/lib/bpf/libbpf.c

index 7379dae35dcaf97333ae6b7631556a1cad3a5d76..a07c80429c7a375c75ea9244e7b917eb6bce89cc 100644 (file)
@@ -82,6 +82,8 @@ static const char *get_map_ident(const struct bpf_map *map)
                return "rodata";
        else if (str_has_suffix(name, ".bss"))
                return "bss";
+       else if (str_has_suffix(name, ".extern"))
+               return "externs"; /* extern is a C keyword */
        else
                return NULL;
 }
@@ -109,6 +111,8 @@ static int codegen_datasec_def(struct bpf_object *obj,
                sec_ident = "bss";
        else if (strcmp(sec_name, ".rodata") == 0)
                sec_ident = "rodata";
+       else if (strcmp(sec_name, ".extern") == 0)
+               sec_ident = "externs"; /* extern is a C keyword */
        else
                return 0;
 
index 26144706ba0bbe457b9404d7055b0668b3d5ebf5..c9f90bfd2f0d8d822709187ef9cb70d2f0248974 100644 (file)
@@ -7472,7 +7472,8 @@ int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
                        return -ESRCH;
                }
 
-               if (mmaped)
+               /* externs shouldn't be pre-setup from user code */
+               if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_EXTERN)
                        *mmaped = (*map)->mmaped;
        }
 
@@ -7505,7 +7506,6 @@ int bpf_object__load_skeleton(struct bpf_object_skeleton *s)
                size_t mmap_sz = bpf_map_mmap_sz(map);
                int prot, map_fd = bpf_map__fd(map);
                void **mmaped = s->maps[i].mmaped;
-               void *remapped;
 
                if (!mmaped)
                        continue;
@@ -7530,9 +7530,9 @@ int bpf_object__load_skeleton(struct bpf_object_skeleton *s)
                 * as per normal clean up procedure, so we don't need to worry
                 * about it from skeleton's clean up perspective.
                 */
-               remapped = mmap(*mmaped, mmap_sz, prot, MAP_SHARED | MAP_FIXED,
-                               map_fd, 0);
-               if (remapped == MAP_FAILED) {
+               *mmaped = mmap(map->mmaped, mmap_sz, prot,
+                               MAP_SHARED | MAP_FIXED, map_fd, 0);
+               if (*mmaped == MAP_FAILED) {
                        err = -errno;
                        *mmaped = NULL;
                        pr_warn("failed to re-mmap() map '%s': %d\n",