Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf annotate: Fix register usage in data type profiling

On data type profiling, it tried to match register name with a partial
string. For example, it allowed to match with "%rbp)" or "%rdi,8)".

But with recent change in the area, it doesn't match anymore and break
the data type profiling.

Let's pass the correct register name by removing the unwanted part.

Add arch__dwarf_regnum() to handle it in a single place.

Closes: 7d3n23li6drroxrdlpxn7ixehdeszkjdftah3zyngjl2qs22ef@yelcjv53v42o
Reported-by: Dmitry Dolgov <9erthalion6@gmail.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Zecheng Li <zli94@ncsu.edu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
64ea7a46 bb5a920b

+30 -31
+30 -31
tools/perf/util/annotate.c
··· 2447 2447 return 0; 2448 2448 } 2449 2449 2450 + static int arch__dwarf_regnum(const struct arch *arch, const char *str) 2451 + { 2452 + const char *p; 2453 + char *regname, *q; 2454 + int reg; 2455 + 2456 + p = strchr(str, arch->objdump.register_char); 2457 + if (p == NULL) 2458 + return -1; 2459 + 2460 + regname = strdup(p); 2461 + if (regname == NULL) 2462 + return -1; 2463 + 2464 + q = strpbrk(regname, ",) "); 2465 + if (q) 2466 + *q = '\0'; 2467 + 2468 + reg = get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags); 2469 + free(regname); 2470 + return reg; 2471 + } 2472 + 2450 2473 /* 2451 2474 * Get register number and access offset from the given instruction. 2452 2475 * It assumes AT&T x86 asm format like OFFSET(REG). Maybe it needs ··· 2480 2457 struct annotated_op_loc *op_loc) 2481 2458 { 2482 2459 char *p; 2483 - char *regname; 2484 2460 2485 2461 if (arch->objdump.register_char == 0) 2486 2462 return -1; ··· 2504 2482 } 2505 2483 2506 2484 op_loc->offset = strtol(str, &p, 0); 2507 - 2508 - p = strchr(p, arch->objdump.register_char); 2509 - if (p == NULL) 2485 + op_loc->reg1 = arch__dwarf_regnum(arch, p); 2486 + if (op_loc->reg1 == -1) 2510 2487 return -1; 2511 - 2512 - regname = strdup(p); 2513 - if (regname == NULL) 2514 - return -1; 2515 - 2516 - op_loc->reg1 = get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags); 2517 - free(regname); 2518 2488 2519 2489 /* Get the second register */ 2520 - if (op_loc->multi_regs) { 2521 - p = strchr(p + 1, arch->objdump.register_char); 2522 - if (p == NULL) 2523 - return -1; 2490 + if (op_loc->multi_regs) 2491 + op_loc->reg2 = arch__dwarf_regnum(arch, p + 1); 2524 2492 2525 - regname = strdup(p); 2526 - if (regname == NULL) 2527 - return -1; 2528 - 2529 - op_loc->reg2 = get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags); 2530 - free(regname); 2531 - } 2532 2493 return 0; 2533 2494 } 2534 2495 ··· 2590 2585 op_loc->multi_regs = multi_regs; 2591 2586 extract_reg_offset(arch, insn_str, op_loc); 2592 2587 } else { 2593 - char *s, *p = NULL; 2588 + const char *s = insn_str; 2589 + char *p = NULL; 2594 2590 2595 2591 if (arch__is_x86(arch)) { 2596 2592 /* FIXME: Handle other segment registers */ ··· 2605 2599 } 2606 2600 } 2607 2601 2608 - s = strdup(insn_str); 2609 - if (s == NULL) 2610 - return -1; 2611 - 2612 2602 if (*s == arch->objdump.register_char) { 2613 - op_loc->reg1 = get_dwarf_regnum(s, 2614 - arch->id.e_machine, 2615 - arch->id.e_flags); 2603 + op_loc->reg1 = arch__dwarf_regnum(arch, s); 2616 2604 } 2617 2605 else if (*s == arch->objdump.imm_char) { 2618 2606 op_loc->offset = strtol(s + 1, &p, 0); 2619 2607 if (p && p != s + 1) 2620 2608 op_loc->imm = true; 2621 2609 } 2622 - free(s); 2623 2610 } 2624 2611 } 2625 2612