bpftool: Support multiple .rodata/.data internal maps in skeleton
authorAndrii Nakryiko <andrii@kernel.org>
Thu, 21 Oct 2021 01:43:59 +0000 (18:43 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 22 Oct 2021 00:10:10 +0000 (17:10 -0700)
Remove the assumption about only single instance of each of .rodata and
.data internal maps. Nothing changes for '.rodata' and '.data' maps, but new
'.rodata.something' map will get 'rodata_something' section in BPF
skeleton for them (as well as having struct bpf_map * field in maps
section with the same field name).

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20211021014404.2635234-6-andrii@kernel.org
tools/bpf/bpftool/gen.c

index b2ffc18..59afe9a 100644 (file)
@@ -33,6 +33,11 @@ static void sanitize_identifier(char *name)
                        name[i] = '_';
 }
 
+static bool str_has_prefix(const char *str, const char *prefix)
+{
+       return strncmp(str, prefix, strlen(prefix)) == 0;
+}
+
 static bool str_has_suffix(const char *str, const char *suffix)
 {
        size_t i, n1 = strlen(str), n2 = strlen(suffix);
@@ -67,23 +72,47 @@ static void get_header_guard(char *guard, const char *obj_name)
                guard[i] = toupper(guard[i]);
 }
 
-static const char *get_map_ident(const struct bpf_map *map)
+static bool get_map_ident(const struct bpf_map *map, char *buf, size_t buf_sz)
 {
+       static const char *sfxs[] = { ".data", ".rodata", ".bss", ".kconfig" };
        const char *name = bpf_map__name(map);
+       int i, n;
+
+       if (!bpf_map__is_internal(map)) {
+               snprintf(buf, buf_sz, "%s", name);
+               return true;
+       }
+
+       for  (i = 0, n = ARRAY_SIZE(sfxs); i < n; i++) {
+               const char *sfx = sfxs[i], *p;
+
+               p = strstr(name, sfx);
+               if (p) {
+                       snprintf(buf, buf_sz, "%s", p + 1);
+                       sanitize_identifier(buf);
+                       return true;
+               }
+       }
 
-       if (!bpf_map__is_internal(map))
-               return name;
-
-       if (str_has_suffix(name, ".data"))
-               return "data";
-       else if (str_has_suffix(name, ".rodata"))
-               return "rodata";
-       else if (str_has_suffix(name, ".bss"))
-               return "bss";
-       else if (str_has_suffix(name, ".kconfig"))
-               return "kconfig";
-       else
-               return NULL;
+       return false;
+}
+
+static bool get_datasec_ident(const char *sec_name, char *buf, size_t buf_sz)
+{
+       static const char *pfxs[] = { ".data", ".rodata", ".bss", ".kconfig" };
+       int i, n;
+
+       for  (i = 0, n = ARRAY_SIZE(pfxs); i < n; i++) {
+               const char *pfx = pfxs[i];
+
+               if (str_has_prefix(sec_name, pfx)) {
+                       snprintf(buf, buf_sz, "%s", sec_name + 1);
+                       sanitize_identifier(buf);
+                       return true;
+               }
+       }
+
+       return false;
 }
 
 static void codegen_btf_dump_printf(void *ctx, const char *fmt, va_list args)
@@ -100,24 +129,14 @@ static int codegen_datasec_def(struct bpf_object *obj,
        const char *sec_name = btf__name_by_offset(btf, sec->name_off);
        const struct btf_var_secinfo *sec_var = btf_var_secinfos(sec);
        int i, err, off = 0, pad_cnt = 0, vlen = btf_vlen(sec);
-       const char *sec_ident;
-       char var_ident[256];
+       char var_ident[256], sec_ident[256];
        bool strip_mods = false;
 
-       if (strcmp(sec_name, ".data") == 0) {
-               sec_ident = "data";
-               strip_mods = true;
-       } else if (strcmp(sec_name, ".bss") == 0) {
-               sec_ident = "bss";
-               strip_mods = true;
-       } else if (strcmp(sec_name, ".rodata") == 0) {
-               sec_ident = "rodata";
-               strip_mods = true;
-       } else if (strcmp(sec_name, ".kconfig") == 0) {
-               sec_ident = "kconfig";
-       } else {
+       if (!get_datasec_ident(sec_name, sec_ident, sizeof(sec_ident)))
                return 0;
-       }
+
+       if (strcmp(sec_name, ".kconfig") != 0)
+               strip_mods = true;
 
        printf("        struct %s__%s {\n", obj_name, sec_ident);
        for (i = 0; i < vlen; i++, sec_var++) {
@@ -385,6 +404,7 @@ static void codegen_destroy(struct bpf_object *obj, const char *obj_name)
 {
        struct bpf_program *prog;
        struct bpf_map *map;
+       char ident[256];
 
        codegen("\
                \n\
@@ -405,10 +425,7 @@ static void codegen_destroy(struct bpf_object *obj, const char *obj_name)
        }
 
        bpf_object__for_each_map(map, obj) {
-               const char *ident;
-
-               ident = get_map_ident(map);
-               if (!ident)
+               if (!get_map_ident(map, ident, sizeof(ident)))
                        continue;
                if (bpf_map__is_internal(map) &&
                    (bpf_map__def(map)->map_flags & BPF_F_MMAPABLE))
@@ -432,6 +449,7 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
        struct bpf_object_load_attr load_attr = {};
        DECLARE_LIBBPF_OPTS(gen_loader_opts, opts);
        struct bpf_map *map;
+       char ident[256];
        int err = 0;
 
        err = bpf_object__gen_loader(obj, &opts);
@@ -477,12 +495,10 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
                ",
                obj_name, opts.data_sz);
        bpf_object__for_each_map(map, obj) {
-               const char *ident;
                const void *mmap_data = NULL;
                size_t mmap_size = 0;
 
-               ident = get_map_ident(map);
-               if (!ident)
+               if (!get_map_ident(map, ident, sizeof(ident)))
                        continue;
 
                if (!bpf_map__is_internal(map) ||
@@ -544,15 +560,15 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
                                return err;                                 \n\
                ", obj_name);
        bpf_object__for_each_map(map, obj) {
-               const char *ident, *mmap_flags;
+               const char *mmap_flags;
 
-               ident = get_map_ident(map);
-               if (!ident)
+               if (!get_map_ident(map, ident, sizeof(ident)))
                        continue;
 
                if (!bpf_map__is_internal(map) ||
                    !(bpf_map__def(map)->map_flags & BPF_F_MMAPABLE))
                        continue;
+
                if (bpf_map__def(map)->map_flags & BPF_F_RDONLY_PROG)
                        mmap_flags = "PROT_READ";
                else
@@ -602,7 +618,8 @@ static int do_skeleton(int argc, char **argv)
        DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts);
        char obj_name[MAX_OBJ_NAME_LEN] = "", *obj_data;
        struct bpf_object *obj = NULL;
-       const char *file, *ident;
+       const char *file;
+       char ident[256];
        struct bpf_program *prog;
        int fd, err = -1;
        struct bpf_map *map;
@@ -673,8 +690,7 @@ static int do_skeleton(int argc, char **argv)
        }
 
        bpf_object__for_each_map(map, obj) {
-               ident = get_map_ident(map);
-               if (!ident) {
+               if (!get_map_ident(map, ident, sizeof(ident))) {
                        p_err("ignoring unrecognized internal map '%s'...",
                              bpf_map__name(map));
                        continue;
@@ -727,8 +743,7 @@ static int do_skeleton(int argc, char **argv)
        if (map_cnt) {
                printf("\tstruct {\n");
                bpf_object__for_each_map(map, obj) {
-                       ident = get_map_ident(map);
-                       if (!ident)
+                       if (!get_map_ident(map, ident, sizeof(ident)))
                                continue;
                        if (use_loader)
                                printf("\t\tstruct bpf_map_desc %s;\n", ident);
@@ -897,9 +912,7 @@ static int do_skeleton(int argc, char **argv)
                );
                i = 0;
                bpf_object__for_each_map(map, obj) {
-                       ident = get_map_ident(map);
-
-                       if (!ident)
+                       if (!get_map_ident(map, ident, sizeof(ident)))
                                continue;
 
                        codegen("\