mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 15:04:27 +08:00
bpftool: Improve skeleton generation for data maps without DATASEC type
It can happen that some data sections (e.g., .rodata.cst16, containing compiler populated string constants) won't have a corresponding BTF DATASEC type. Now that libbpf supports .rodata.* and .data.* sections, situation like that will cause invalid BPF skeleton to be generated that won't compile successfully, as some parts of skeleton would assume memory-mapped struct definitions for each special data section. Fix this by generating empty struct definitions for such data sections. 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-7-andrii@kernel.org
This commit is contained in:
parent
8654b4d35e
commit
ef9356d392
@ -213,22 +213,61 @@ static int codegen_datasecs(struct bpf_object *obj, const char *obj_name)
|
|||||||
struct btf *btf = bpf_object__btf(obj);
|
struct btf *btf = bpf_object__btf(obj);
|
||||||
int n = btf__get_nr_types(btf);
|
int n = btf__get_nr_types(btf);
|
||||||
struct btf_dump *d;
|
struct btf_dump *d;
|
||||||
|
struct bpf_map *map;
|
||||||
|
const struct btf_type *sec;
|
||||||
|
char sec_ident[256], map_ident[256];
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
d = btf_dump__new(btf, NULL, NULL, codegen_btf_dump_printf);
|
d = btf_dump__new(btf, NULL, NULL, codegen_btf_dump_printf);
|
||||||
if (IS_ERR(d))
|
if (IS_ERR(d))
|
||||||
return PTR_ERR(d);
|
return PTR_ERR(d);
|
||||||
|
|
||||||
for (i = 1; i <= n; i++) {
|
bpf_object__for_each_map(map, obj) {
|
||||||
const struct btf_type *t = btf__type_by_id(btf, i);
|
/* only generate definitions for memory-mapped internal maps */
|
||||||
|
if (!bpf_map__is_internal(map))
|
||||||
if (!btf_is_datasec(t))
|
continue;
|
||||||
|
if (!(bpf_map__def(map)->map_flags & BPF_F_MMAPABLE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = codegen_datasec_def(obj, btf, d, t, obj_name);
|
if (!get_map_ident(map, map_ident, sizeof(map_ident)))
|
||||||
if (err)
|
continue;
|
||||||
goto out;
|
|
||||||
|
sec = NULL;
|
||||||
|
for (i = 1; i <= n; i++) {
|
||||||
|
const struct btf_type *t = btf__type_by_id(btf, i);
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
if (!btf_is_datasec(t))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name = btf__str_by_offset(btf, t->name_off);
|
||||||
|
if (!get_datasec_ident(name, sec_ident, sizeof(sec_ident)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(sec_ident, map_ident) == 0) {
|
||||||
|
sec = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In some cases (e.g., sections like .rodata.cst16 containing
|
||||||
|
* compiler allocated string constants only) there will be
|
||||||
|
* special internal maps with no corresponding DATASEC BTF
|
||||||
|
* type. In such case, generate empty structs for each such
|
||||||
|
* map. It will still be memory-mapped and its contents
|
||||||
|
* accessible from user-space through BPF skeleton.
|
||||||
|
*/
|
||||||
|
if (!sec) {
|
||||||
|
printf(" struct %s__%s {\n", obj_name, map_ident);
|
||||||
|
printf(" } *%s;\n", map_ident);
|
||||||
|
} else {
|
||||||
|
err = codegen_datasec_def(obj, btf, d, sec, obj_name);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
btf_dump__free(d);
|
btf_dump__free(d);
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user