2018-03-02 02:01:17 +00:00
|
|
|
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
2018-12-13 03:59:25 +00:00
|
|
|
/* Copyright (C) 2018 Netronome Systems, Inc. */
|
2018-03-02 02:01:17 +00:00
|
|
|
|
2022-10-25 15:03:22 +00:00
|
|
|
#ifndef _GNU_SOURCE
|
2018-07-10 21:43:05 +00:00
|
|
|
#define _GNU_SOURCE
|
2022-10-25 15:03:22 +00:00
|
|
|
#endif
|
2018-03-02 02:01:17 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
2020-01-20 13:06:46 +00:00
|
|
|
#include <bpf/libbpf.h>
|
2022-02-21 12:56:17 +00:00
|
|
|
#include <bpf/libbpf_internal.h>
|
2018-03-02 02:01:17 +00:00
|
|
|
|
|
|
|
#include "disasm.h"
|
|
|
|
#include "json_writer.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "xlated_dumper.h"
|
|
|
|
|
|
|
|
static int kernel_syms_cmp(const void *sym_a, const void *sym_b)
|
|
|
|
{
|
|
|
|
return ((struct kernel_sym *)sym_a)->address -
|
|
|
|
((struct kernel_sym *)sym_b)->address;
|
|
|
|
}
|
|
|
|
|
|
|
|
void kernel_syms_load(struct dump_data *dd)
|
|
|
|
{
|
|
|
|
struct kernel_sym *sym;
|
|
|
|
char buff[256];
|
|
|
|
void *tmp, *address;
|
|
|
|
FILE *fp;
|
|
|
|
|
|
|
|
fp = fopen("/proc/kallsyms", "r");
|
|
|
|
if (!fp)
|
|
|
|
return;
|
|
|
|
|
2019-05-26 10:32:11 +00:00
|
|
|
while (fgets(buff, sizeof(buff), fp)) {
|
2022-02-21 12:56:17 +00:00
|
|
|
tmp = libbpf_reallocarray(dd->sym_mapping, dd->sym_count + 1,
|
|
|
|
sizeof(*dd->sym_mapping));
|
2018-03-02 02:01:17 +00:00
|
|
|
if (!tmp) {
|
|
|
|
out:
|
|
|
|
free(dd->sym_mapping);
|
|
|
|
dd->sym_mapping = NULL;
|
|
|
|
fclose(fp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dd->sym_mapping = tmp;
|
|
|
|
sym = &dd->sym_mapping[dd->sym_count];
|
2023-07-09 02:56:22 +00:00
|
|
|
|
|
|
|
/* module is optional */
|
|
|
|
sym->module[0] = '\0';
|
|
|
|
/* trim the square brackets around the module name */
|
|
|
|
if (sscanf(buff, "%p %*c %s [%[^]]s", &address, sym->name, sym->module) < 2)
|
2018-03-02 02:01:17 +00:00
|
|
|
continue;
|
|
|
|
sym->address = (unsigned long)address;
|
|
|
|
if (!strcmp(sym->name, "__bpf_call_base")) {
|
|
|
|
dd->address_call_base = sym->address;
|
|
|
|
/* sysctl kernel.kptr_restrict was set */
|
|
|
|
if (!sym->address)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (sym->address)
|
|
|
|
dd->sym_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
qsort(dd->sym_mapping, dd->sym_count,
|
|
|
|
sizeof(*dd->sym_mapping), kernel_syms_cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void kernel_syms_destroy(struct dump_data *dd)
|
|
|
|
{
|
|
|
|
free(dd->sym_mapping);
|
|
|
|
}
|
|
|
|
|
tools: bpftool: add delimiters to multi-function JITed dumps
This splits up the contiguous JITed dump obtained via the bpf
system call into more relatable chunks for each function in
the program. If the kernel symbols corresponding to these are
known, they are printed in the header for each JIT image dump
otherwise the masked start address is printed.
Before applying this patch:
# bpftool prog dump jited id 1
0: push %rbp
1: mov %rsp,%rbp
...
70: leaveq
71: retq
72: push %rbp
73: mov %rsp,%rbp
...
dd: leaveq
de: retq
# bpftool -p prog dump jited id 1
[{
"pc": "0x0",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0x71",
"operation": "retq",
"operands": [null
]
},{
"pc": "0x72",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0xde",
"operation": "retq",
"operands": [null
]
}
]
After applying this patch:
# echo 0 > /proc/sys/net/core/bpf_jit_kallsyms
# bpftool prog dump jited id 1
0xffffffffc02c7000:
0: push %rbp
1: mov %rsp,%rbp
...
70: leaveq
71: retq
0xffffffffc02cf000:
0: push %rbp
1: mov %rsp,%rbp
...
6b: leaveq
6c: retq
# bpftool -p prog dump jited id 1
[{
"name": "0xffffffffc02c7000",
"insns": [{
"pc": "0x0",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0x71",
"operation": "retq",
"operands": [null
]
}
]
},{
"name": "0xffffffffc02cf000",
"insns": [{
"pc": "0x0",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0x6c",
"operation": "retq",
"operands": [null
]
}
]
}
]
# echo 1 > /proc/sys/net/core/bpf_jit_kallsyms
# bpftool prog dump jited id 1
bpf_prog_b811aab41a39ad3d_foo:
0: push %rbp
1: mov %rsp,%rbp
...
70: leaveq
71: retq
bpf_prog_cf418ac8b67bebd9_F:
0: push %rbp
1: mov %rsp,%rbp
...
6b: leaveq
6c: retq
# bpftool -p prog dump jited id 1
[{
"name": "bpf_prog_b811aab41a39ad3d_foo",
"insns": [{
"pc": "0x0",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0x71",
"operation": "retq",
"operands": [null
]
}
]
},{
"name": "bpf_prog_cf418ac8b67bebd9_F",
"insns": [{
"pc": "0x0",
"operation": "push",
"operands": ["%rbp"
]
},{
...
},{
"pc": "0x6c",
"operation": "retq",
"operands": [null
]
}
]
}
]
Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-05-24 06:56:54 +00:00
|
|
|
struct kernel_sym *kernel_syms_search(struct dump_data *dd,
|
|
|
|
unsigned long key)
|
2018-03-02 02:01:17 +00:00
|
|
|
{
|
|
|
|
struct kernel_sym sym = {
|
|
|
|
.address = key,
|
|
|
|
};
|
|
|
|
|
|
|
|
return dd->sym_mapping ?
|
|
|
|
bsearch(&sym, dd->sym_mapping, dd->sym_count,
|
|
|
|
sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL;
|
|
|
|
}
|
|
|
|
|
2018-12-14 13:56:01 +00:00
|
|
|
static void __printf(2, 3) print_insn(void *private_data, const char *fmt, ...)
|
2018-03-02 02:01:17 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
vprintf(fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
2018-12-14 13:56:01 +00:00
|
|
|
static void __printf(2, 3)
|
2018-03-23 10:41:29 +00:00
|
|
|
print_insn_for_graph(void *private_data, const char *fmt, ...)
|
2018-03-02 02:01:21 +00:00
|
|
|
{
|
|
|
|
char buf[64], *p;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
p = buf;
|
|
|
|
while (*p != '\0') {
|
|
|
|
if (*p == '\n') {
|
|
|
|
memmove(p + 3, p, strlen(buf) + 1 - (p - buf));
|
|
|
|
/* Align each instruction dump row left. */
|
|
|
|
*p++ = '\\';
|
|
|
|
*p++ = 'l';
|
|
|
|
/* Output multiline concatenation. */
|
|
|
|
*p++ = '\\';
|
|
|
|
} else if (*p == '<' || *p == '>' || *p == '|' || *p == '&') {
|
|
|
|
memmove(p + 1, p, strlen(buf) + 1 - (p - buf));
|
|
|
|
/* Escape special character. */
|
|
|
|
*p++ = '\\';
|
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%s", buf);
|
|
|
|
}
|
|
|
|
|
2018-12-14 13:56:01 +00:00
|
|
|
static void __printf(2, 3)
|
|
|
|
print_insn_json(void *private_data, const char *fmt, ...)
|
2018-03-02 02:01:17 +00:00
|
|
|
{
|
|
|
|
unsigned int l = strlen(fmt);
|
|
|
|
char chomped_fmt[l];
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
if (l > 0) {
|
|
|
|
strncpy(chomped_fmt, fmt, l - 1);
|
|
|
|
chomped_fmt[l - 1] = '\0';
|
|
|
|
}
|
|
|
|
jsonw_vprintf_enquote(json_wtr, chomped_fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *print_call_pcrel(struct dump_data *dd,
|
|
|
|
struct kernel_sym *sym,
|
|
|
|
unsigned long address,
|
|
|
|
const struct bpf_insn *insn)
|
|
|
|
{
|
2018-05-24 06:56:50 +00:00
|
|
|
if (!dd->nr_jited_ksyms)
|
|
|
|
/* Do not show address for interpreted programs */
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"%+d", insn->off);
|
|
|
|
else if (sym)
|
2018-03-02 02:01:17 +00:00
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"%+d#%s", insn->off, sym->name);
|
|
|
|
else
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"%+d#0x%lx", insn->off, address);
|
|
|
|
return dd->scratch_buff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *print_call_helper(struct dump_data *dd,
|
|
|
|
struct kernel_sym *sym,
|
|
|
|
unsigned long address)
|
|
|
|
{
|
|
|
|
if (sym)
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"%s", sym->name);
|
|
|
|
else
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"0x%lx", address);
|
|
|
|
return dd->scratch_buff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *print_call(void *private_data,
|
|
|
|
const struct bpf_insn *insn)
|
|
|
|
{
|
|
|
|
struct dump_data *dd = private_data;
|
|
|
|
unsigned long address = dd->address_call_base + insn->imm;
|
|
|
|
struct kernel_sym *sym;
|
|
|
|
|
2018-05-24 06:56:50 +00:00
|
|
|
if (insn->src_reg == BPF_PSEUDO_CALL &&
|
2019-12-10 18:14:12 +00:00
|
|
|
(__u32) insn->imm < dd->nr_jited_ksyms && dd->jited_ksyms)
|
2018-05-24 06:56:50 +00:00
|
|
|
address = dd->jited_ksyms[insn->imm];
|
|
|
|
|
2018-03-02 02:01:17 +00:00
|
|
|
sym = kernel_syms_search(dd, address);
|
|
|
|
if (insn->src_reg == BPF_PSEUDO_CALL)
|
|
|
|
return print_call_pcrel(dd, sym, address, insn);
|
|
|
|
else
|
|
|
|
return print_call_helper(dd, sym, address);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *print_imm(void *private_data,
|
|
|
|
const struct bpf_insn *insn,
|
|
|
|
__u64 full_imm)
|
|
|
|
{
|
|
|
|
struct dump_data *dd = private_data;
|
|
|
|
|
|
|
|
if (insn->src_reg == BPF_PSEUDO_MAP_FD)
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"map[id:%u]", insn->imm);
|
bpf: implement lookup-free direct value access for maps
This generic extension to BPF maps allows for directly loading
an address residing inside a BPF map value as a single BPF
ldimm64 instruction!
The idea is similar to what BPF_PSEUDO_MAP_FD does today, which
is a special src_reg flag for ldimm64 instruction that indicates
that inside the first part of the double insns's imm field is a
file descriptor which the verifier then replaces as a full 64bit
address of the map into both imm parts. For the newly added
BPF_PSEUDO_MAP_VALUE src_reg flag, the idea is the following:
the first part of the double insns's imm field is again a file
descriptor corresponding to the map, and the second part of the
imm field is an offset into the value. The verifier will then
replace both imm parts with an address that points into the BPF
map value at the given value offset for maps that support this
operation. Currently supported is array map with single entry.
It is possible to support more than just single map element by
reusing both 16bit off fields of the insns as a map index, so
full array map lookup could be expressed that way. It hasn't
been implemented here due to lack of concrete use case, but
could easily be done so in future in a compatible way, since
both off fields right now have to be 0 and would correctly
denote a map index 0.
The BPF_PSEUDO_MAP_VALUE is a distinct flag as otherwise with
BPF_PSEUDO_MAP_FD we could not differ offset 0 between load of
map pointer versus load of map's value at offset 0, and changing
BPF_PSEUDO_MAP_FD's encoding into off by one to differ between
regular map pointer and map value pointer would add unnecessary
complexity and increases barrier for debugability thus less
suitable. Using the second part of the imm field as an offset
into the value does /not/ come with limitations since maximum
possible value size is in u32 universe anyway.
This optimization allows for efficiently retrieving an address
to a map value memory area without having to issue a helper call
which needs to prepare registers according to calling convention,
etc, without needing the extra NULL test, and without having to
add the offset in an additional instruction to the value base
pointer. The verifier then treats the destination register as
PTR_TO_MAP_VALUE with constant reg->off from the user passed
offset from the second imm field, and guarantees that this is
within bounds of the map value. Any subsequent operations are
normally treated as typical map value handling without anything
extra needed from verification side.
The two map operations for direct value access have been added to
array map for now. In future other types could be supported as
well depending on the use case. The main use case for this commit
is to allow for BPF loader support for global variables that
reside in .data/.rodata/.bss sections such that we can directly
load the address of them with minimal additional infrastructure
required. Loader support has been added in subsequent commits for
libbpf library.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-04-09 21:20:03 +00:00
|
|
|
else if (insn->src_reg == BPF_PSEUDO_MAP_VALUE)
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"map[id:%u][0]+%u", insn->imm, (insn + 1)->imm);
|
2021-05-14 00:36:19 +00:00
|
|
|
else if (insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE)
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"map[idx:%u]+%u", insn->imm, (insn + 1)->imm);
|
bpftool: Print subprog address properly
With later hashmap example, using bpftool xlated output may
look like:
int dump_task(struct bpf_iter__task * ctx):
; struct task_struct *task = ctx->task;
0: (79) r2 = *(u64 *)(r1 +8)
; if (task == (void *)0 || called > 0)
...
19: (18) r2 = subprog[+17]
30: (18) r2 = subprog[+25]
...
36: (95) exit
__u64 check_hash_elem(struct bpf_map * map, __u32 * key, __u64 * val,
struct callback_ctx * data):
; struct bpf_iter__task *ctx = data->ctx;
37: (79) r5 = *(u64 *)(r4 +0)
...
55: (95) exit
__u64 check_percpu_elem(struct bpf_map * map, __u32 * key,
__u64 * val, void * unused):
; check_percpu_elem(struct bpf_map *map, __u32 *key, __u64 *val, void *unused)
56: (bf) r6 = r3
...
83: (18) r2 = subprog[-47]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210226204931.3885458-1-yhs@fb.com
2021-02-26 20:49:31 +00:00
|
|
|
else if (insn->src_reg == BPF_PSEUDO_FUNC)
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"subprog[%+d]", insn->imm);
|
2018-03-02 02:01:17 +00:00
|
|
|
else
|
|
|
|
snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
|
|
|
|
"0x%llx", (unsigned long long)full_imm);
|
|
|
|
return dd->scratch_buff;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
bool opcodes, bool linum)
|
2018-03-02 02:01:17 +00:00
|
|
|
{
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
const struct bpf_prog_linfo *prog_linfo = dd->prog_linfo;
|
2018-03-02 02:01:17 +00:00
|
|
|
const struct bpf_insn_cbs cbs = {
|
|
|
|
.cb_print = print_insn_json,
|
|
|
|
.cb_call = print_call,
|
|
|
|
.cb_imm = print_imm,
|
|
|
|
.private_data = dd,
|
|
|
|
};
|
2018-11-19 23:29:21 +00:00
|
|
|
struct bpf_func_info *record;
|
2018-03-02 02:01:17 +00:00
|
|
|
struct bpf_insn *insn = buf;
|
2018-11-19 23:29:21 +00:00
|
|
|
struct btf *btf = dd->btf;
|
2018-03-02 02:01:17 +00:00
|
|
|
bool double_insn = false;
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
unsigned int nr_skip = 0;
|
2018-11-19 23:29:21 +00:00
|
|
|
char func_sig[1024];
|
2018-03-02 02:01:17 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
jsonw_start_array(json_wtr);
|
2018-11-19 23:29:21 +00:00
|
|
|
record = dd->func_info;
|
2018-03-02 02:01:17 +00:00
|
|
|
for (i = 0; i < len / sizeof(*insn); i++) {
|
|
|
|
if (double_insn) {
|
|
|
|
double_insn = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
|
|
|
|
|
|
|
|
jsonw_start_object(json_wtr);
|
2018-11-19 23:29:21 +00:00
|
|
|
|
|
|
|
if (btf && record) {
|
2018-12-06 01:35:47 +00:00
|
|
|
if (record->insn_off == i) {
|
2018-11-19 23:29:21 +00:00
|
|
|
btf_dumper_type_only(btf, record->type_id,
|
|
|
|
func_sig,
|
|
|
|
sizeof(func_sig));
|
|
|
|
if (func_sig[0] != '\0') {
|
|
|
|
jsonw_name(json_wtr, "proto");
|
|
|
|
jsonw_string(json_wtr, func_sig);
|
|
|
|
}
|
|
|
|
record = (void *)record + dd->finfo_rec_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
if (prog_linfo) {
|
|
|
|
const struct bpf_line_info *linfo;
|
|
|
|
|
|
|
|
linfo = bpf_prog_linfo__lfind(prog_linfo, i, nr_skip);
|
|
|
|
if (linfo) {
|
|
|
|
btf_dump_linfo_json(btf, linfo, linum);
|
|
|
|
nr_skip++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-02 02:01:17 +00:00
|
|
|
jsonw_name(json_wtr, "disasm");
|
2018-03-23 10:41:29 +00:00
|
|
|
print_bpf_insn(&cbs, insn + i, true);
|
2018-03-02 02:01:17 +00:00
|
|
|
|
|
|
|
if (opcodes) {
|
|
|
|
jsonw_name(json_wtr, "opcodes");
|
|
|
|
jsonw_start_object(json_wtr);
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "code");
|
|
|
|
jsonw_printf(json_wtr, "\"0x%02hhx\"", insn[i].code);
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "src_reg");
|
|
|
|
jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].src_reg);
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "dst_reg");
|
|
|
|
jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].dst_reg);
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "off");
|
|
|
|
print_hex_data_json((uint8_t *)(&insn[i].off), 2);
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "imm");
|
|
|
|
if (double_insn && i < len - 1)
|
|
|
|
print_hex_data_json((uint8_t *)(&insn[i].imm),
|
|
|
|
12);
|
|
|
|
else
|
|
|
|
print_hex_data_json((uint8_t *)(&insn[i].imm),
|
|
|
|
4);
|
|
|
|
jsonw_end_object(json_wtr);
|
|
|
|
}
|
|
|
|
jsonw_end_object(json_wtr);
|
|
|
|
}
|
|
|
|
jsonw_end_array(json_wtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
bool opcodes, bool linum)
|
2018-03-02 02:01:17 +00:00
|
|
|
{
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
const struct bpf_prog_linfo *prog_linfo = dd->prog_linfo;
|
2018-03-02 02:01:17 +00:00
|
|
|
const struct bpf_insn_cbs cbs = {
|
|
|
|
.cb_print = print_insn,
|
|
|
|
.cb_call = print_call,
|
|
|
|
.cb_imm = print_imm,
|
|
|
|
.private_data = dd,
|
|
|
|
};
|
2018-11-19 23:29:21 +00:00
|
|
|
struct bpf_func_info *record;
|
2018-03-02 02:01:17 +00:00
|
|
|
struct bpf_insn *insn = buf;
|
2018-11-19 23:29:21 +00:00
|
|
|
struct btf *btf = dd->btf;
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
unsigned int nr_skip = 0;
|
2018-03-02 02:01:17 +00:00
|
|
|
bool double_insn = false;
|
2018-11-19 23:29:21 +00:00
|
|
|
char func_sig[1024];
|
2018-03-02 02:01:17 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
2018-11-19 23:29:21 +00:00
|
|
|
record = dd->func_info;
|
2018-03-02 02:01:17 +00:00
|
|
|
for (i = 0; i < len / sizeof(*insn); i++) {
|
|
|
|
if (double_insn) {
|
|
|
|
double_insn = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-11-19 23:29:21 +00:00
|
|
|
if (btf && record) {
|
2018-12-06 01:35:47 +00:00
|
|
|
if (record->insn_off == i) {
|
2018-11-19 23:29:21 +00:00
|
|
|
btf_dumper_type_only(btf, record->type_id,
|
|
|
|
func_sig,
|
|
|
|
sizeof(func_sig));
|
|
|
|
if (func_sig[0] != '\0')
|
|
|
|
printf("%s:\n", func_sig);
|
|
|
|
record = (void *)record + dd->finfo_rec_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-08 00:42:32 +00:00
|
|
|
if (prog_linfo) {
|
|
|
|
const struct bpf_line_info *linfo;
|
|
|
|
|
|
|
|
linfo = bpf_prog_linfo__lfind(prog_linfo, i, nr_skip);
|
|
|
|
if (linfo) {
|
|
|
|
btf_dump_linfo_plain(btf, linfo, "; ",
|
|
|
|
linum);
|
|
|
|
nr_skip++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-02 02:01:17 +00:00
|
|
|
double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
|
|
|
|
|
|
|
|
printf("% 4d: ", i);
|
2018-03-23 10:41:29 +00:00
|
|
|
print_bpf_insn(&cbs, insn + i, true);
|
2018-03-02 02:01:17 +00:00
|
|
|
|
|
|
|
if (opcodes) {
|
|
|
|
printf(" ");
|
|
|
|
fprint_hex(stdout, insn + i, 8, " ");
|
|
|
|
if (double_insn && i < len - 1) {
|
|
|
|
printf(" ");
|
|
|
|
fprint_hex(stdout, insn + i + 1, 8, " ");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-03-02 02:01:21 +00:00
|
|
|
|
|
|
|
void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
|
2023-04-05 13:21:19 +00:00
|
|
|
unsigned int start_idx,
|
|
|
|
bool opcodes, bool linum)
|
2018-03-02 02:01:21 +00:00
|
|
|
{
|
|
|
|
const struct bpf_insn_cbs cbs = {
|
|
|
|
.cb_print = print_insn_for_graph,
|
|
|
|
.cb_call = print_call,
|
|
|
|
.cb_imm = print_imm,
|
|
|
|
.private_data = dd,
|
|
|
|
};
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
const struct bpf_prog_linfo *prog_linfo = dd->prog_linfo;
|
|
|
|
const struct bpf_line_info *last_linfo = NULL;
|
|
|
|
struct bpf_func_info *record = dd->func_info;
|
2018-03-02 02:01:21 +00:00
|
|
|
struct bpf_insn *insn_start = buf_start;
|
|
|
|
struct bpf_insn *insn_end = buf_end;
|
|
|
|
struct bpf_insn *cur = insn_start;
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
struct btf *btf = dd->btf;
|
2023-04-05 13:21:15 +00:00
|
|
|
bool double_insn = false;
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
char func_sig[1024];
|
2018-03-02 02:01:21 +00:00
|
|
|
|
|
|
|
for (; cur <= insn_end; cur++) {
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
unsigned int insn_off;
|
|
|
|
|
2023-04-05 13:21:15 +00:00
|
|
|
if (double_insn) {
|
|
|
|
double_insn = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW);
|
|
|
|
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
insn_off = (unsigned int)(cur - insn_start + start_idx);
|
|
|
|
if (btf && record) {
|
|
|
|
if (record->insn_off == insn_off) {
|
|
|
|
btf_dumper_type_only(btf, record->type_id,
|
|
|
|
func_sig,
|
|
|
|
sizeof(func_sig));
|
|
|
|
if (func_sig[0] != '\0')
|
|
|
|
printf("; %s:\\l\\\n", func_sig);
|
|
|
|
record = (void *)record + dd->finfo_rec_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prog_linfo) {
|
|
|
|
const struct bpf_line_info *linfo;
|
|
|
|
|
|
|
|
linfo = bpf_prog_linfo__lfind(prog_linfo, insn_off, 0);
|
|
|
|
if (linfo && linfo != last_linfo) {
|
2023-04-05 13:21:19 +00:00
|
|
|
btf_dump_linfo_dotlabel(btf, linfo, linum);
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
last_linfo = linfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%d: ", insn_off);
|
2018-03-23 10:41:29 +00:00
|
|
|
print_bpf_insn(&cbs, cur, true);
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
|
2023-04-05 13:21:19 +00:00
|
|
|
if (opcodes) {
|
|
|
|
printf("\\ \\ \\ \\ ");
|
|
|
|
fprint_hex(stdout, cur, 8, " ");
|
|
|
|
if (double_insn && cur <= insn_end - 1) {
|
|
|
|
printf(" ");
|
|
|
|
fprint_hex(stdout, cur + 1, 8, " ");
|
|
|
|
}
|
|
|
|
printf("\\l\\\n");
|
|
|
|
}
|
|
|
|
|
2018-03-02 02:01:21 +00:00
|
|
|
if (cur != insn_end)
|
bpftool: Support inline annotations when dumping the CFG of a program
We support dumping the control flow graph of loaded programs to the DOT
format with bpftool, but so far this feature wouldn't display the source
code lines available through BTF along with the eBPF bytecode. Let's add
support for these annotations, to make it easier to read the graph.
In prog.c, we move the call to dump_xlated_cfg() in order to pass and
use the full struct dump_data, instead of creating a minimal one in
draw_bb_node().
We pass the pointer to this struct down to dump_xlated_for_graph() in
xlated_dumper.c, where most of the logics is added. We deal with BTF
mostly like we do for plain or JSON output, except that we cannot use a
"nr_skip" value to skip a given number of linfo records (we don't
process the BPF instructions linearly, and apart from the root of the
graph we don't know how many records we should skip, so we just store
the last linfo and make sure the new one we find is different before
printing it).
When printing the source instructions to the label of a DOT graph node,
there are a few subtleties to address. We want some special newline
markers, and there are some characters that we must escape. To deal with
them, we introduce a new dedicated function btf_dump_linfo_dotlabel() in
btf_dumper.c. We'll reuse this function in a later commit to format the
filepath, line, and column references as well.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20230405132120.59886-4-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2023-04-05 13:21:16 +00:00
|
|
|
printf("| ");
|
2018-03-02 02:01:21 +00:00
|
|
|
}
|
|
|
|
}
|