Commit 8654b4d3 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

bpftool: Support multiple .rodata/.data internal maps in skeleton

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: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarSong Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20211021014404.2635234-6-andrii@kernel.org
parent 25bbbd7a
......@@ -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("\
......
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