mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-31 06:14:39 +01:00
perf dso: Support BPF programs in dso__read_symbol()
Set the buffer to the code in the BPF linear info. This enables BPF JIT code disassembly by LLVM and capstone. Move the common but minimal disassmble_bpf_image call to disassemble_objdump so that it is only called after falling back to the objdump option. Similarly move the disassmble_bpf function to disassemble_objdump and rename to disassmble_bpf_libbfd to make it clearer that this support relies on libbfd. Signed-off-by: Ian Rogers <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Alexandre Ghiti <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Athira Rajeev <[email protected]> Cc: Bill Wendling <[email protected]> Cc: Charlie Jenkins <[email protected]> Cc: Collin Funk <[email protected]> Cc: Dmitriy Vyukov <[email protected]> Cc: Dr. David Alan Gilbert <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Haibo Xu <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Justin Stitt <[email protected]> Cc: Li Huafei <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: Nick Desaulniers <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Song Liu <[email protected]> Cc: Stephen Brennan <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
This commit is contained in:
1 parent
9518e10c2b
commit
aa04707f50
4 files changed
+83
-45
No files matched your search
@@ -1521,6 +1521,12 @@ static int symbol__disassemble_objdump(const char *filename, struct symbol *sym,
|
||||
struct child_process objdump_process;
|
||||
int err;
|
||||
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO)
|
||||
return symbol__disassemble_bpf_libbfd(sym, args);
|
||||
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE)
|
||||
return symbol__disassemble_bpf_image(sym, args);
|
||||
|
||||
err = asprintf(&command,
|
||||
"%s %s%s --start-address=0x%016" PRIx64
|
||||
" --stop-address=0x%016" PRIx64
|
||||
@@ -1655,11 +1661,7 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
|
||||
|
||||
pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso__long_name(dso), sym, sym->name);
|
||||
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) {
|
||||
return symbol__disassemble_bpf(sym, args);
|
||||
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) {
|
||||
return symbol__disassemble_bpf_image(sym, args);
|
||||
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) {
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) {
|
||||
return SYMBOL_ANNOTATE_ERRNO__COULDNT_DETERMINE_FILE_TYPE;
|
||||
} else if (dso__is_kcore(dso)) {
|
||||
kce.addr = map__rip_2objdump(map, sym->start);
|
||||
|
||||
+71
-35
@@ -1816,23 +1816,17 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename,
|
||||
const struct map *map, const struct symbol *sym,
|
||||
u8 **out_buf, u64 *out_buf_len, bool *is_64bit)
|
||||
static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename,
|
||||
u64 start, size_t len,
|
||||
u8 **out_buf, u64 *out_buf_len, bool *is_64bit)
|
||||
{
|
||||
struct nscookie nsc;
|
||||
u64 start = map__rip_2objdump(map, sym->start);
|
||||
u64 end = map__rip_2objdump(map, sym->end);
|
||||
int fd, count;
|
||||
u8 *buf = NULL;
|
||||
size_t len;
|
||||
int fd;
|
||||
ssize_t count;
|
||||
struct find_file_offset_data data = {
|
||||
.ip = start,
|
||||
};
|
||||
|
||||
*out_buf = NULL;
|
||||
*out_buf_len = 0;
|
||||
*is_64bit = false;
|
||||
u8 *code_buf = NULL;
|
||||
|
||||
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
|
||||
fd = open(symfs_filename, O_RDONLY);
|
||||
@@ -1840,28 +1834,70 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename,
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0)
|
||||
goto err;
|
||||
|
||||
len = end - start;
|
||||
buf = malloc(len);
|
||||
if (buf == NULL)
|
||||
goto err;
|
||||
|
||||
count = pread(fd, buf, len, data.offset);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
if ((u64)count != len)
|
||||
goto err;
|
||||
|
||||
*out_buf = buf;
|
||||
*out_buf_len = len;
|
||||
return buf;
|
||||
|
||||
err:
|
||||
if (fd >= 0)
|
||||
if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) {
|
||||
close(fd);
|
||||
free(buf);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
code_buf = malloc(len);
|
||||
if (code_buf == NULL) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
count = pread(fd, code_buf, len, data.offset);
|
||||
close(fd);
|
||||
if ((u64)count != len) {
|
||||
free(code_buf);
|
||||
return NULL;
|
||||
}
|
||||
*out_buf = code_buf;
|
||||
*out_buf_len = len;
|
||||
return code_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a symbol into memory for disassembly by a library like capstone of
|
||||
* libLLVM. If memory is allocated out_buf holds it.
|
||||
*/
|
||||
const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename,
|
||||
const struct map *map, const struct symbol *sym,
|
||||
u8 **out_buf, u64 *out_buf_len, bool *is_64bit)
|
||||
{
|
||||
u64 start = map__rip_2objdump(map, sym->start);
|
||||
u64 end = map__rip_2objdump(map, sym->end);
|
||||
size_t len = end - start;
|
||||
|
||||
*out_buf = NULL;
|
||||
*out_buf_len = 0;
|
||||
*is_64bit = false;
|
||||
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) {
|
||||
/*
|
||||
* Note, there is fallback BPF image disassembly in the objdump
|
||||
* version but it currently does nothing.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) {
|
||||
#ifdef HAVE_LIBBPF_SUPPORT
|
||||
struct bpf_prog_info_node *info_node;
|
||||
struct perf_bpil *info_linear;
|
||||
|
||||
*is_64bit = sizeof(void *) == sizeof(u64);
|
||||
info_node = perf_env__find_bpf_prog_info(dso__bpf_prog(dso)->env,
|
||||
dso__bpf_prog(dso)->id);
|
||||
if (!info_node) {
|
||||
errno = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
|
||||
return NULL;
|
||||
}
|
||||
info_linear = info_node->info_linear;
|
||||
assert(len <= info_linear->info.jited_prog_len);
|
||||
*out_buf_len = len;
|
||||
return (const u8 *)(uintptr_t)(info_linear->info.jited_prog_insns);
|
||||
#else
|
||||
pr_debug("No BPF program disassembly support\n");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
return __dso__read_symbol(dso, symfs_filename, start, len,
|
||||
out_buf, out_buf_len, is_64bit);
|
||||
}
|
||||
@@ -448,8 +448,8 @@ out_close:
|
||||
return err;
|
||||
}
|
||||
|
||||
int symbol__disassemble_bpf(struct symbol *sym __maybe_unused,
|
||||
struct annotate_args *args __maybe_unused)
|
||||
int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused,
|
||||
struct annotate_args *args __maybe_unused)
|
||||
{
|
||||
#ifdef HAVE_LIBBPF_SUPPORT
|
||||
struct annotation *notes = symbol__annotation(sym);
|
||||
|
||||
@@ -29,7 +29,7 @@ int libbfd__read_build_id(const char *filename, struct build_id *bid, bool block
|
||||
|
||||
int libbfd_filename__read_debuglink(const char *filename, char *debuglink, size_t size);
|
||||
|
||||
int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args);
|
||||
int symbol__disassemble_bpf_libbfd(struct symbol *sym, struct annotate_args *args);
|
||||
|
||||
#else // !defined(HAVE_LIBBFD_SUPPORT)
|
||||
#include "annotate.h"
|
||||
@@ -72,8 +72,8 @@ static inline int libbfd_filename__read_debuglink(const char *filename __always_
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int symbol__disassemble_bpf(struct symbol *sym __always_unused,
|
||||
struct annotate_args *args __always_unused)
|
||||
static inline int symbol__disassemble_bpf_libbfd(struct symbol *sym __always_unused,
|
||||
struct annotate_args *args __always_unused)
|
||||
{
|
||||
return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user