mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
perf annotate: Add symbol name when using capstone
This is to keep the existing behavior with objdump. It needs to show
symbol information of global variables like below:
Percent | Source code & Disassembly of elf for cycles:P (1 samples, percent: local period)
------------------------------------------------------------------------------------------------
: 0 0xffffffff81338f70 <vm_normal_page>:
0.00 : ffffffff81338f70: endbr64
0.00 : ffffffff81338f74: callq 0xffffffff81083a40
0.00 : ffffffff81338f79: movq %rdi, %r8
0.00 : ffffffff81338f7c: movq %rdx, %rdi
0.00 : ffffffff81338f7f: callq *0x17021c3(%rip) # ffffffff82a3b148 <pv_ops+0x1e8>
0.00 : ffffffff81338f85: movq 0xffbf3c(%rip), %rdx # ffffffff82334ec8 <physical_mask>
0.00 : ffffffff81338f8c: testq %rax, %rax ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.00 : ffffffff81338f8f: je 0xffffffff81338fd0 here
0.00 : ffffffff81338f91: movq %rax, %rcx
0.00 : ffffffff81338f94: andl $1, %ecx
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-6-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
6d17edc113
commit
92dfc59463
@@ -1368,6 +1368,12 @@ static int open_capstone_handle(struct annotate_args *args, bool is_64bit,
|
|||||||
!strcmp(opt->disassembler_style, "att"))
|
!strcmp(opt->disassembler_style, "att"))
|
||||||
cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resolving address operands to symbols is implemented
|
||||||
|
* on x86 by investigating instruction details.
|
||||||
|
*/
|
||||||
|
cs_option(*handle, CS_OPT_DETAIL, CS_OPT_ON);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,6 +1394,63 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_capstone_detail(cs_insn *insn, char *buf, size_t len,
|
||||||
|
struct annotate_args *args, u64 addr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct map *map = args->ms.map;
|
||||||
|
struct symbol *sym;
|
||||||
|
|
||||||
|
/* TODO: support more architectures */
|
||||||
|
if (!arch__is(args->arch, "x86"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (insn->detail == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < insn->detail->x86.op_count; i++) {
|
||||||
|
cs_x86_op *op = &insn->detail->x86.operands[i];
|
||||||
|
u64 orig_addr;
|
||||||
|
|
||||||
|
if (op->type != X86_OP_MEM)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* only print RIP-based global symbols for now */
|
||||||
|
if (op->mem.base != X86_REG_RIP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* get the target address */
|
||||||
|
orig_addr = addr + insn->size + op->mem.disp;
|
||||||
|
addr = map__objdump_2mem(map, orig_addr);
|
||||||
|
|
||||||
|
if (map__dso(map)->kernel) {
|
||||||
|
/*
|
||||||
|
* The kernel maps can be splitted into sections,
|
||||||
|
* let's find the map first and the search the symbol.
|
||||||
|
*/
|
||||||
|
map = maps__find(map__kmaps(map), addr);
|
||||||
|
if (map == NULL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert it to map-relative address for search */
|
||||||
|
addr = map__map_ip(map, addr);
|
||||||
|
|
||||||
|
sym = map__find_symbol(map, addr);
|
||||||
|
if (sym == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (addr == sym->start) {
|
||||||
|
scnprintf(buf, len, "\t# %"PRIx64" <%s>",
|
||||||
|
orig_addr, sym->name);
|
||||||
|
} else {
|
||||||
|
scnprintf(buf, len, "\t# %"PRIx64" <%s+%#"PRIx64">",
|
||||||
|
orig_addr, sym->name, addr - sym->start);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
|
static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
|
||||||
struct annotate_args *args)
|
struct annotate_args *args)
|
||||||
{
|
{
|
||||||
@@ -1458,9 +1521,14 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
|
|||||||
|
|
||||||
count = cs_disasm(handle, buf, len, start, len, &insn);
|
count = cs_disasm(handle, buf, len, start, len, &insn);
|
||||||
for (i = 0, offset = 0; i < count; i++) {
|
for (i = 0, offset = 0; i < count; i++) {
|
||||||
scnprintf(disasm_buf, sizeof(disasm_buf),
|
int printed;
|
||||||
" %-7s %s",
|
|
||||||
insn[i].mnemonic, insn[i].op_str);
|
printed = scnprintf(disasm_buf, sizeof(disasm_buf),
|
||||||
|
" %-7s %s",
|
||||||
|
insn[i].mnemonic, insn[i].op_str);
|
||||||
|
print_capstone_detail(&insn[i], disasm_buf + printed,
|
||||||
|
sizeof(disasm_buf) - printed, args,
|
||||||
|
start + offset);
|
||||||
|
|
||||||
args->offset = offset;
|
args->offset = offset;
|
||||||
args->line = disasm_buf;
|
args->line = disasm_buf;
|
||||||
|
|||||||
Reference in New Issue
Block a user