summaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2019-04-09 17:20:15 -0400
committerAlexei Starovoitov <ast@kernel.org>2019-04-09 20:05:47 -0400
commit817998afa038c156bbc1a6e69c48aa26282cc41f (patch)
tree0b9dd4132343ed490f7162d3ab75690304b2f722 /tools/bpf/bpftool
parent1713d68b3bf039d029afd74653c9325f5003ccbe (diff)
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>
Diffstat (limited to 'tools/bpf/bpftool')
-rw-r--r--tools/bpf/bpftool/btf_dumper.c59
-rw-r--r--tools/bpf/bpftool/map.c10
2 files changed, 65 insertions, 4 deletions
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index e63bce0755eb..8cafb9b31467 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -309,6 +309,48 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
309 return ret; 309 return ret;
310} 310}
311 311
312static int btf_dumper_var(const struct btf_dumper *d, __u32 type_id,
313 __u8 bit_offset, const void *data)
314{
315 const struct btf_type *t = btf__type_by_id(d->btf, type_id);
316 int ret;
317
318 jsonw_start_object(d->jw);
319 jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
320 ret = btf_dumper_do_type(d, t->type, bit_offset, data);
321 jsonw_end_object(d->jw);
322
323 return ret;
324}
325
326static int btf_dumper_datasec(const struct btf_dumper *d, __u32 type_id,
327 const void *data)
328{
329 struct btf_var_secinfo *vsi;
330 const struct btf_type *t;
331 int ret = 0, i, vlen;
332
333 t = btf__type_by_id(d->btf, type_id);
334 if (!t)
335 return -EINVAL;
336
337 vlen = BTF_INFO_VLEN(t->info);
338 vsi = (struct btf_var_secinfo *)(t + 1);
339
340 jsonw_start_object(d->jw);
341 jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
342 jsonw_start_array(d->jw);
343 for (i = 0; i < vlen; i++) {
344 ret = btf_dumper_do_type(d, vsi[i].type, 0, data + vsi[i].offset);
345 if (ret)
346 break;
347 }
348 jsonw_end_array(d->jw);
349 jsonw_end_object(d->jw);
350
351 return ret;
352}
353
312static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id, 354static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
313 __u8 bit_offset, const void *data) 355 __u8 bit_offset, const void *data)
314{ 356{
@@ -341,6 +383,10 @@ static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
341 case BTF_KIND_CONST: 383 case BTF_KIND_CONST:
342 case BTF_KIND_RESTRICT: 384 case BTF_KIND_RESTRICT:
343 return btf_dumper_modifier(d, type_id, bit_offset, data); 385 return btf_dumper_modifier(d, type_id, bit_offset, data);
386 case BTF_KIND_VAR:
387 return btf_dumper_var(d, type_id, bit_offset, data);
388 case BTF_KIND_DATASEC:
389 return btf_dumper_datasec(d, type_id, data);
344 default: 390 default:
345 jsonw_printf(d->jw, "(unsupported-kind"); 391 jsonw_printf(d->jw, "(unsupported-kind");
346 return -EINVAL; 392 return -EINVAL;
@@ -377,6 +423,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
377{ 423{
378 const struct btf_type *proto_type; 424 const struct btf_type *proto_type;
379 const struct btf_array *array; 425 const struct btf_array *array;
426 const struct btf_var *var;
380 const struct btf_type *t; 427 const struct btf_type *t;
381 428
382 if (!type_id) { 429 if (!type_id) {
@@ -440,6 +487,18 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
440 if (pos == -1) 487 if (pos == -1)
441 return -1; 488 return -1;
442 break; 489 break;
490 case BTF_KIND_VAR:
491 var = (struct btf_var *)(t + 1);
492 if (var->linkage == BTF_VAR_STATIC)
493 BTF_PRINT_ARG("static ");
494 BTF_PRINT_TYPE(t->type);
495 BTF_PRINT_ARG(" %s",
496 btf__name_by_offset(btf, t->name_off));
497 break;
498 case BTF_KIND_DATASEC:
499 BTF_PRINT_ARG("section (\"%s\") ",
500 btf__name_by_offset(btf, t->name_off));
501 break;
443 case BTF_KIND_UNKN: 502 case BTF_KIND_UNKN:
444 default: 503 default:
445 return -1; 504 return -1;
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index e0c650d91784..e96903078991 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -153,11 +153,13 @@ static int do_dump_btf(const struct btf_dumper *d,
153 /* start of key-value pair */ 153 /* start of key-value pair */
154 jsonw_start_object(d->jw); 154 jsonw_start_object(d->jw);
155 155
156 jsonw_name(d->jw, "key"); 156 if (map_info->btf_key_type_id) {
157 jsonw_name(d->jw, "key");
157 158
158 ret = btf_dumper_type(d, map_info->btf_key_type_id, key); 159 ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
159 if (ret) 160 if (ret)
160 goto err_end_obj; 161 goto err_end_obj;
162 }
161 163
162 if (!map_is_per_cpu(map_info->type)) { 164 if (!map_is_per_cpu(map_info->type)) {
163 jsonw_name(d->jw, "value"); 165 jsonw_name(d->jw, "value");