Skip to content

Commit

Permalink
perf annotate: Add symbol name when using capstone
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Namhyung Kim authored and Arnaldo Carvalho de Melo committed Apr 3, 2024
1 parent 6d17edc commit 92dfc59
Showing 1 changed file with 71 additions and 3 deletions.
74 changes: 71 additions & 3 deletions tools/perf/util/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,12 @@ static int open_capstone_handle(struct annotate_args *args, bool is_64bit,
!strcmp(opt->disassembler_style, "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;
}

Expand All @@ -1388,6 +1394,63 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg)
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,
struct annotate_args *args)
{
Expand Down Expand Up @@ -1458,9 +1521,14 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,

count = cs_disasm(handle, buf, len, start, len, &insn);
for (i = 0, offset = 0; i < count; i++) {
scnprintf(disasm_buf, sizeof(disasm_buf),
" %-7s %s",
insn[i].mnemonic, insn[i].op_str);
int printed;

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->line = disasm_buf;
Expand Down

0 comments on commit 92dfc59

Please sign in to comment.