Skip to content

Commit b0df8b7

Browse files
author
Jakub Brnak
committed
perf annotate: Add annotation_options.disassembler_used
JIRA: https://issues.redhat.com/browse/RHEL-83785 upstream ======== commit dab8c32 Author: Athira Rajeev <atrajeev@linux.ibm.com> Date: Tue Mar 4 21:11:13 2025 +0530 description =========== When doing "perf annotate", perf tool provides option to use specific disassembler like llvm/objdump/capstone. The order picked is to use llvm first and if that fails fallback to objdump ie to use PERF_DISASM_LLVM, PERF_DISASM_CAPSTONE and PERF_DISASM_OBJDUMP In powerpc, when using "data type" sort keys, first preferred approach is to read the raw instruction from the DSO. In objdump is specified in "--objdump" option, it picks the symbol disassemble using objdump. Currently disasm_line__parse_powerpc() function uses length of the "line" to determine if objdump is used. But there are few cases, where if objdump doesn't recognise the instruction, the disassembled string will be empty. Example: 134cdc: c4 05 82 41 beq 1352a0 <getcwd+0x6e0> 134ce0: ac 00 8e 40 bne cr3,134d8c <getcwd+0x1cc> 134ce4: 0f 00 10 04 pld r9,1028308 ====>134ce8: d4 b0 20 e5 134cec: 16 00 40 39 li r10,22 134cf0: 48 01 21 ea ld r17,328(r1) So depending on length of line will give bad results. Add a new filed to annotation options structure, "struct annotation_options" to save the disassembler used. Use this info to determine if disassembly is done while parsing the disasm line. Reported-by: Tejas Manhas <Tejas.Manhas1@ibm.com> Signed-off-by: Athira Rajeev <atrajeev@linux.ibm.com> Tested-By: Venkat Rao Bagalkote <venkat88@linux.ibm.com> Link: https://lore.kernel.org/r/20250304154114.62093-1-atrajeev@linux.ibm.com Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Jakub Brnak <jbrnak@redhat.com>
1 parent c20b029 commit b0df8b7

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

tools/perf/util/annotate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct annotation_options {
5858
full_addr;
5959
u8 offset_level;
6060
u8 disassemblers[MAX_DISASSEMBLERS];
61+
u8 disassembler_used;
6162
int min_pcnt;
6263
int max_lines;
6364
int context;

tools/perf/util/disasm.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size,
4747

4848
static void ins__sort(struct arch *arch);
4949
static int disasm_line__parse(char *line, const char **namep, char **rawp);
50-
static int disasm_line__parse_powerpc(struct disasm_line *dl);
50+
static int disasm_line__parse_powerpc(struct disasm_line *dl, struct annotate_args *args);
5151
static char *expand_tabs(char *line, char **storage, size_t *storage_len);
5252

5353
static __attribute__((constructor)) void symbol__init_regexpr(void)
@@ -967,24 +967,24 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp)
967967
#define PPC_OP(op) (((op) >> 26) & 0x3F)
968968
#define RAW_BYTES 11
969969

970-
static int disasm_line__parse_powerpc(struct disasm_line *dl)
970+
static int disasm_line__parse_powerpc(struct disasm_line *dl, struct annotate_args *args)
971971
{
972972
char *line = dl->al.line;
973973
const char **namep = &dl->ins.name;
974974
char **rawp = &dl->ops.raw;
975975
char *tmp_raw_insn, *name_raw_insn = skip_spaces(line);
976976
char *name = skip_spaces(name_raw_insn + RAW_BYTES);
977-
int objdump = 0;
977+
int disasm = 0;
978978

979-
if (strlen(line) > RAW_BYTES)
980-
objdump = 1;
979+
if (args->options->disassembler_used)
980+
disasm = 1;
981981

982982
if (name_raw_insn[0] == '\0')
983983
return -1;
984984

985-
if (objdump) {
985+
if (disasm)
986986
disasm_line__parse(name, namep, rawp);
987-
} else
987+
else
988988
*namep = "";
989989

990990
tmp_raw_insn = strndup(name_raw_insn, 11);
@@ -994,7 +994,7 @@ static int disasm_line__parse_powerpc(struct disasm_line *dl)
994994
remove_spaces(tmp_raw_insn);
995995

996996
sscanf(tmp_raw_insn, "%x", &dl->raw.raw_insn);
997-
if (objdump)
997+
if (disasm)
998998
dl->raw.raw_insn = be32_to_cpu(dl->raw.raw_insn);
999999

10001000
return 0;
@@ -1053,7 +1053,7 @@ struct disasm_line *disasm_line__new(struct annotate_args *args)
10531053

10541054
if (args->offset != -1) {
10551055
if (arch__is(args->arch, "powerpc")) {
1056-
if (disasm_line__parse_powerpc(dl) < 0)
1056+
if (disasm_line__parse_powerpc(dl, args) < 0)
10571057
goto out_free_line;
10581058
} else if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0)
10591059
goto out_free_line;
@@ -2294,16 +2294,20 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
22942294

22952295
switch (dis) {
22962296
case PERF_DISASM_LLVM:
2297+
args->options->disassembler_used = PERF_DISASM_LLVM;
22972298
err = symbol__disassemble_llvm(symfs_filename, sym, args);
22982299
break;
22992300
case PERF_DISASM_CAPSTONE:
2301+
args->options->disassembler_used = PERF_DISASM_CAPSTONE;
23002302
err = symbol__disassemble_capstone(symfs_filename, sym, args);
23012303
break;
23022304
case PERF_DISASM_OBJDUMP:
2305+
args->options->disassembler_used = PERF_DISASM_OBJDUMP;
23032306
err = symbol__disassemble_objdump(symfs_filename, sym, args);
23042307
break;
23052308
case PERF_DISASM_UNKNOWN: /* End of disassemblers. */
23062309
default:
2310+
args->options->disassembler_used = PERF_DISASM_UNKNOWN;
23072311
goto out_remove_tmp;
23082312
}
23092313
if (err == 0)

0 commit comments

Comments
 (0)