diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3ea98fe72f7f..3728b50e52e2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -96,6 +96,7 @@ enum perf_output_field { PERF_OUTPUT_UREGS = 1U << 27, PERF_OUTPUT_METRIC = 1U << 28, PERF_OUTPUT_MISC = 1U << 29, + PERF_OUTPUT_SRCCODE = 1U << 30, }; struct output_option { @@ -132,6 +133,7 @@ struct output_option { {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, {.str = "metric", .field = PERF_OUTPUT_METRIC}, {.str = "misc", .field = PERF_OUTPUT_MISC}, + {.str = "srccode", .field = PERF_OUTPUT_SRCCODE}, }; enum { @@ -424,7 +426,7 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, pr_err("Display of DSO requested but no address to convert.\n"); return -EINVAL; } - if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { + if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) { pr_err("Display of source line number requested but sample IP is not\n" "selected. Hence, no address to lookup the source line number.\n"); return -EINVAL; @@ -907,6 +909,22 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, return len; } +static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr) +{ + struct addr_location al; + int ret = 0; + + memset(&al, 0, sizeof(al)); + thread__find_map(thread, cpumode, addr, &al); + if (!al.map) + return 0; + ret = map__fprintf_srccode(al.map, al.addr, stdout, + &thread->srccode_state); + if (ret) + ret += printf("\n"); + return ret; +} + static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, struct perf_insn *x, u8 *inbuf, int len, int insn, FILE *fp, int *total_cycles) @@ -998,6 +1016,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, x.cpumode, x.cpu, &lastsym, attr, fp); printed += ip__fprintf_jump(br->entries[nr - 1].from, &br->entries[nr - 1], &x, buffer, len, 0, fp, &total_cycles); + if (PRINT_FIELD(SRCCODE)) + printed += print_srccode(thread, x.cpumode, br->entries[nr - 1].from); } /* Print all blocks */ @@ -1027,12 +1047,16 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, if (ip == end) { printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp, &total_cycles); + if (PRINT_FIELD(SRCCODE)) + printed += print_srccode(thread, x.cpumode, ip); break; } else { printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip, dump_insn(&x, ip, buffer + off, len - off, &ilen)); if (ilen == 0) break; + if (PRINT_FIELD(SRCCODE)) + print_srccode(thread, x.cpumode, ip); insn++; } } @@ -1063,6 +1087,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip, dump_insn(&x, sample->ip, buffer, len, NULL)); + if (PRINT_FIELD(SRCCODE)) + print_srccode(thread, x.cpumode, sample->ip); goto out; } for (off = 0; off <= end - start; off += ilen) { @@ -1070,6 +1096,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, dump_insn(&x, start + off, buffer + off, len - off, &ilen)); if (ilen == 0) break; + if (PRINT_FIELD(SRCCODE)) + print_srccode(thread, x.cpumode, start + off); } out: return printed; @@ -1252,7 +1280,16 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample, printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp); printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp); - return printed + fprintf(fp, "\n"); + printed += fprintf(fp, "\n"); + if (PRINT_FIELD(SRCCODE)) { + int ret = map__fprintf_srccode(al->map, al->addr, stdout, + &thread->srccode_state); + if (ret) { + printed += ret; + printed += printf("\n"); + } + } + return printed; } static struct { @@ -1792,6 +1829,12 @@ static void process_event(struct perf_script *script, fprintf(fp, "%16" PRIx64, sample->phys_addr); fprintf(fp, "\n"); + if (PRINT_FIELD(SRCCODE)) { + if (map__fprintf_srccode(al->map, al->addr, stdout, + &thread->srccode_state)) + printf("\n"); + } + if (PRINT_FIELD(METRIC)) perf_sample__fprint_metric(script, thread, evsel, sample, fp); |