diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4397a8b6e6cd..3369c7830260 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -49,10 +49,9 @@ struct arch { | |||
49 | void *priv; | 49 | void *priv; |
50 | unsigned int model; | 50 | unsigned int model; |
51 | unsigned int family; | 51 | unsigned int family; |
52 | int (*init)(struct arch *arch); | 52 | int (*init)(struct arch *arch, char *cpuid); |
53 | bool (*ins_is_fused)(struct arch *arch, const char *ins1, | 53 | bool (*ins_is_fused)(struct arch *arch, const char *ins1, |
54 | const char *ins2); | 54 | const char *ins2); |
55 | int (*cpuid_parse)(struct arch *arch, char *cpuid); | ||
56 | struct { | 55 | struct { |
57 | char comment_char; | 56 | char comment_char; |
58 | char skip_functions_char; | 57 | char skip_functions_char; |
@@ -132,10 +131,10 @@ static struct arch architectures[] = { | |||
132 | }, | 131 | }, |
133 | { | 132 | { |
134 | .name = "x86", | 133 | .name = "x86", |
134 | .init = x86__annotate_init, | ||
135 | .instructions = x86__instructions, | 135 | .instructions = x86__instructions, |
136 | .nr_instructions = ARRAY_SIZE(x86__instructions), | 136 | .nr_instructions = ARRAY_SIZE(x86__instructions), |
137 | .ins_is_fused = x86__ins_is_fused, | 137 | .ins_is_fused = x86__ins_is_fused, |
138 | .cpuid_parse = x86__cpuid_parse, | ||
139 | .objdump = { | 138 | .objdump = { |
140 | .comment_char = '#', | 139 | .comment_char = '#', |
141 | }, | 140 | }, |
@@ -166,7 +165,7 @@ static void ins__delete(struct ins_operands *ops) | |||
166 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, | 165 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, |
167 | struct ins_operands *ops) | 166 | struct ins_operands *ops) |
168 | { | 167 | { |
169 | return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->raw); | 168 | return scnprintf(bf, size, "%-6s %s", ins->name, ops->raw); |
170 | } | 169 | } |
171 | 170 | ||
172 | int ins__scnprintf(struct ins *ins, char *bf, size_t size, | 171 | int ins__scnprintf(struct ins *ins, char *bf, size_t size, |
@@ -231,12 +230,12 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size, | |||
231 | struct ins_operands *ops) | 230 | struct ins_operands *ops) |
232 | { | 231 | { |
233 | if (ops->target.name) | 232 | if (ops->target.name) |
234 | return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->target.name); | 233 | return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.name); |
235 | 234 | ||
236 | if (ops->target.addr == 0) | 235 | if (ops->target.addr == 0) |
237 | return ins__raw_scnprintf(ins, bf, size, ops); | 236 | return ins__raw_scnprintf(ins, bf, size, ops); |
238 | 237 | ||
239 | return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr); | 238 | return scnprintf(bf, size, "%-6s *%" PRIx64, ins->name, ops->target.addr); |
240 | } | 239 | } |
241 | 240 | ||
242 | static struct ins_ops call_ops = { | 241 | static struct ins_ops call_ops = { |
@@ -300,7 +299,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size, | |||
300 | c++; | 299 | c++; |
301 | } | 300 | } |
302 | 301 | ||
303 | return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64, | 302 | return scnprintf(bf, size, "%-6s %.*s%" PRIx64, |
304 | ins->name, c ? c - ops->raw : 0, ops->raw, | 303 | ins->name, c ? c - ops->raw : 0, ops->raw, |
305 | ops->target.offset); | 304 | ops->target.offset); |
306 | } | 305 | } |
@@ -373,7 +372,7 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, | |||
373 | if (ops->locked.ins.ops == NULL) | 372 | if (ops->locked.ins.ops == NULL) |
374 | return ins__raw_scnprintf(ins, bf, size, ops); | 373 | return ins__raw_scnprintf(ins, bf, size, ops); |
375 | 374 | ||
376 | printed = scnprintf(bf, size, "%-6.6s ", ins->name); | 375 | printed = scnprintf(bf, size, "%-6s ", ins->name); |
377 | return printed + ins__scnprintf(&ops->locked.ins, bf + printed, | 376 | return printed + ins__scnprintf(&ops->locked.ins, bf + printed, |
378 | size - printed, ops->locked.ops); | 377 | size - printed, ops->locked.ops); |
379 | } | 378 | } |
@@ -449,7 +448,7 @@ out_free_source: | |||
449 | static int mov__scnprintf(struct ins *ins, char *bf, size_t size, | 448 | static int mov__scnprintf(struct ins *ins, char *bf, size_t size, |
450 | struct ins_operands *ops) | 449 | struct ins_operands *ops) |
451 | { | 450 | { |
452 | return scnprintf(bf, size, "%-6.6s %s,%s", ins->name, | 451 | return scnprintf(bf, size, "%-6s %s,%s", ins->name, |
453 | ops->source.name ?: ops->source.raw, | 452 | ops->source.name ?: ops->source.raw, |
454 | ops->target.name ?: ops->target.raw); | 453 | ops->target.name ?: ops->target.raw); |
455 | } | 454 | } |
@@ -489,7 +488,7 @@ static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops | |||
489 | static int dec__scnprintf(struct ins *ins, char *bf, size_t size, | 488 | static int dec__scnprintf(struct ins *ins, char *bf, size_t size, |
490 | struct ins_operands *ops) | 489 | struct ins_operands *ops) |
491 | { | 490 | { |
492 | return scnprintf(bf, size, "%-6.6s %s", ins->name, | 491 | return scnprintf(bf, size, "%-6s %s", ins->name, |
493 | ops->target.name ?: ops->target.raw); | 492 | ops->target.name ?: ops->target.raw); |
494 | } | 493 | } |
495 | 494 | ||
@@ -501,7 +500,7 @@ static struct ins_ops dec_ops = { | |||
501 | static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, | 500 | static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, |
502 | struct ins_operands *ops __maybe_unused) | 501 | struct ins_operands *ops __maybe_unused) |
503 | { | 502 | { |
504 | return scnprintf(bf, size, "%-6.6s", "nop"); | 503 | return scnprintf(bf, size, "%-6s", "nop"); |
505 | } | 504 | } |
506 | 505 | ||
507 | static struct ins_ops nop_ops = { | 506 | static struct ins_ops nop_ops = { |
@@ -606,9 +605,19 @@ static struct arch *arch__find(const char *name) | |||
606 | int symbol__alloc_hist(struct symbol *sym) | 605 | int symbol__alloc_hist(struct symbol *sym) |
607 | { | 606 | { |
608 | struct annotation *notes = symbol__annotation(sym); | 607 | struct annotation *notes = symbol__annotation(sym); |
609 | const size_t size = symbol__size(sym); | 608 | size_t size = symbol__size(sym); |
610 | size_t sizeof_sym_hist; | 609 | size_t sizeof_sym_hist; |
611 | 610 | ||
611 | /* | ||
612 | * Add buffer of one element for zero length symbol. | ||
613 | * When sample is taken from first instruction of | ||
614 | * zero length symbol, perf still resolves it and | ||
615 | * shows symbol name in perf report and allows to | ||
616 | * annotate it. | ||
617 | */ | ||
618 | if (size == 0) | ||
619 | size = 1; | ||
620 | |||
612 | /* Check for overflow when calculating sizeof_sym_hist */ | 621 | /* Check for overflow when calculating sizeof_sym_hist */ |
613 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) | 622 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) |
614 | return -1; | 623 | return -1; |
@@ -915,7 +924,7 @@ void disasm_line__free(struct disasm_line *dl) | |||
915 | int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) | 924 | int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) |
916 | { | 925 | { |
917 | if (raw || !dl->ins.ops) | 926 | if (raw || !dl->ins.ops) |
918 | return scnprintf(bf, size, "%-6.6s %s", dl->ins.name, dl->ops.raw); | 927 | return scnprintf(bf, size, "%-6s %s", dl->ins.name, dl->ops.raw); |
919 | 928 | ||
920 | return ins__scnprintf(&dl->ins, bf, size, &dl->ops); | 929 | return ins__scnprintf(&dl->ins, bf, size, &dl->ops); |
921 | } | 930 | } |
@@ -1447,16 +1456,13 @@ int symbol__disassemble(struct symbol *sym, struct map *map, | |||
1447 | *parch = arch; | 1456 | *parch = arch; |
1448 | 1457 | ||
1449 | if (arch->init) { | 1458 | if (arch->init) { |
1450 | err = arch->init(arch); | 1459 | err = arch->init(arch, cpuid); |
1451 | if (err) { | 1460 | if (err) { |
1452 | pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); | 1461 | pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); |
1453 | return err; | 1462 | return err; |
1454 | } | 1463 | } |
1455 | } | 1464 | } |
1456 | 1465 | ||
1457 | if (arch->cpuid_parse && cpuid) | ||
1458 | arch->cpuid_parse(arch, cpuid); | ||
1459 | |||
1460 | pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, | 1466 | pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, |
1461 | symfs_filename, sym->name, map->unmap_ip(map, sym->start), | 1467 | symfs_filename, sym->name, map->unmap_ip(map, sym->start), |
1462 | map->unmap_ip(map, sym->end)); | 1468 | map->unmap_ip(map, sym->end)); |