mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-12 21:44:06 +08:00
bpf: bpftool support for dumping data/bss/rodata sections
Add the ability to bpftool to handle BTF Var and DataSec kinds in order to dump them out of btf_dumper_type(). The value has a single object with the section name, which itself holds an array of variables it dumps. A single variable is an object by itself printed along with its name. From there further type information is dumped along with corresponding value information. Example output from .rodata: # ./bpftool m d i 150 [{ "value": { ".rodata": [{ "load_static_data.bar": 18446744073709551615 },{ "num2": 24 },{ "num5": 43947 },{ "num6": 171 },{ "str0": [97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,0,0,0,0,0,0 ] },{ "struct0": { "a": 42, "b": 4278120431, "c": 1229782938247303441 } },{ "struct2": { "a": 0, "b": 0, "c": 0 } } ] } } ] Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
1713d68b3b
commit
817998afa0
@ -309,6 +309,48 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int btf_dumper_var(const struct btf_dumper *d, __u32 type_id,
|
||||||
|
__u8 bit_offset, const void *data)
|
||||||
|
{
|
||||||
|
const struct btf_type *t = btf__type_by_id(d->btf, type_id);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
jsonw_start_object(d->jw);
|
||||||
|
jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
|
||||||
|
ret = btf_dumper_do_type(d, t->type, bit_offset, data);
|
||||||
|
jsonw_end_object(d->jw);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int btf_dumper_datasec(const struct btf_dumper *d, __u32 type_id,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
struct btf_var_secinfo *vsi;
|
||||||
|
const struct btf_type *t;
|
||||||
|
int ret = 0, i, vlen;
|
||||||
|
|
||||||
|
t = btf__type_by_id(d->btf, type_id);
|
||||||
|
if (!t)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
vlen = BTF_INFO_VLEN(t->info);
|
||||||
|
vsi = (struct btf_var_secinfo *)(t + 1);
|
||||||
|
|
||||||
|
jsonw_start_object(d->jw);
|
||||||
|
jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
|
||||||
|
jsonw_start_array(d->jw);
|
||||||
|
for (i = 0; i < vlen; i++) {
|
||||||
|
ret = btf_dumper_do_type(d, vsi[i].type, 0, data + vsi[i].offset);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
jsonw_end_array(d->jw);
|
||||||
|
jsonw_end_object(d->jw);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
|
static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
|
||||||
__u8 bit_offset, const void *data)
|
__u8 bit_offset, const void *data)
|
||||||
{
|
{
|
||||||
@ -341,6 +383,10 @@ static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
|
|||||||
case BTF_KIND_CONST:
|
case BTF_KIND_CONST:
|
||||||
case BTF_KIND_RESTRICT:
|
case BTF_KIND_RESTRICT:
|
||||||
return btf_dumper_modifier(d, type_id, bit_offset, data);
|
return btf_dumper_modifier(d, type_id, bit_offset, data);
|
||||||
|
case BTF_KIND_VAR:
|
||||||
|
return btf_dumper_var(d, type_id, bit_offset, data);
|
||||||
|
case BTF_KIND_DATASEC:
|
||||||
|
return btf_dumper_datasec(d, type_id, data);
|
||||||
default:
|
default:
|
||||||
jsonw_printf(d->jw, "(unsupported-kind");
|
jsonw_printf(d->jw, "(unsupported-kind");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -377,6 +423,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
|
|||||||
{
|
{
|
||||||
const struct btf_type *proto_type;
|
const struct btf_type *proto_type;
|
||||||
const struct btf_array *array;
|
const struct btf_array *array;
|
||||||
|
const struct btf_var *var;
|
||||||
const struct btf_type *t;
|
const struct btf_type *t;
|
||||||
|
|
||||||
if (!type_id) {
|
if (!type_id) {
|
||||||
@ -440,6 +487,18 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
|
|||||||
if (pos == -1)
|
if (pos == -1)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case BTF_KIND_VAR:
|
||||||
|
var = (struct btf_var *)(t + 1);
|
||||||
|
if (var->linkage == BTF_VAR_STATIC)
|
||||||
|
BTF_PRINT_ARG("static ");
|
||||||
|
BTF_PRINT_TYPE(t->type);
|
||||||
|
BTF_PRINT_ARG(" %s",
|
||||||
|
btf__name_by_offset(btf, t->name_off));
|
||||||
|
break;
|
||||||
|
case BTF_KIND_DATASEC:
|
||||||
|
BTF_PRINT_ARG("section (\"%s\") ",
|
||||||
|
btf__name_by_offset(btf, t->name_off));
|
||||||
|
break;
|
||||||
case BTF_KIND_UNKN:
|
case BTF_KIND_UNKN:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -153,11 +153,13 @@ static int do_dump_btf(const struct btf_dumper *d,
|
|||||||
/* start of key-value pair */
|
/* start of key-value pair */
|
||||||
jsonw_start_object(d->jw);
|
jsonw_start_object(d->jw);
|
||||||
|
|
||||||
jsonw_name(d->jw, "key");
|
if (map_info->btf_key_type_id) {
|
||||||
|
jsonw_name(d->jw, "key");
|
||||||
|
|
||||||
ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
|
ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_end_obj;
|
goto err_end_obj;
|
||||||
|
}
|
||||||
|
|
||||||
if (!map_is_per_cpu(map_info->type)) {
|
if (!map_is_per_cpu(map_info->type)) {
|
||||||
jsonw_name(d->jw, "value");
|
jsonw_name(d->jw, "value");
|
||||||
|
Loading…
Reference in New Issue
Block a user