diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ac9ad2330f93..e42bf572358c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -9,19 +9,23 @@ #include <errno.h> #include <inttypes.h> #include <libgen.h> +#include <stdlib.h> #include <bpf/bpf.h> #include <bpf/btf.h> #include <bpf/libbpf.h> #include <linux/btf.h> -#include "util.h" +#include "util.h" // hex_width() #include "ui/ui.h" #include "sort.h" #include "build-id.h" #include "color.h" #include "config.h" -#include "cache.h" +#include "dso.h" +#include "env.h" #include "map.h" +#include "map_groups.h" #include "symbol.h" +#include "srcline.h" #include "units.h" #include "debug.h" #include "annotate.h" @@ -30,6 +34,7 @@ #include "bpf-event.h" #include "block-range.h" #include "string2.h" +#include "util/event.h" #include "arch/common.h" #include <regex.h> #include <pthread.h> @@ -37,6 +42,7 @@ #include <linux/kernel.h> #include <linux/string.h> #include <bpf/libbpf.h> +#include <subcmd/parse-options.h> /* FIXME: For the HE_COLORSET */ #include "ui/browser.h" @@ -929,14 +935,14 @@ alloc_histograms: } static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, u64 addr, + struct evsel *evsel, u64 addr, struct perf_sample *sample) { struct annotated_source *src; if (sym == NULL) return 0; - src = symbol__hists(sym, evsel->evlist->nr_entries); + src = symbol__hists(sym, evsel->evlist->core.nr_entries); return (src) ? __symbol__inc_addr_samples(sym, map, src, evsel->idx, addr, sample) : 0; } @@ -1080,13 +1086,13 @@ void annotation__compute_ipc(struct annotation *notes, size_t size) } int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { return symbol__inc_addr_samples(ams->sym, ams->map, evsel, ams->al_addr, sample); } int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, - struct perf_evsel *evsel, u64 ip) + struct evsel *evsel, u64 ip) { return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evsel, ip, sample); } @@ -1122,7 +1128,7 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) goto out; (*rawp)[0] = tmp; - *rawp = skip_spaces(*rawp); + *rawp = strim(*rawp); return 0; @@ -1134,7 +1140,7 @@ struct annotate_args { size_t privsize; struct arch *arch; struct map_symbol ms; - struct perf_evsel *evsel; + struct evsel *evsel; struct annotation_options *options; s64 offset; char *line; @@ -1165,12 +1171,12 @@ static struct annotation_line * annotation_line__new(struct annotate_args *args, size_t privsize) { struct annotation_line *al; - struct perf_evsel *evsel = args->evsel; + struct evsel *evsel = args->evsel; size_t size = privsize + sizeof(*al); int nr = 1; if (perf_evsel__is_group_event(evsel)) - nr = evsel->nr_members; + nr = evsel->core.nr_members; size += sizeof(al->data[0]) * nr; @@ -1359,7 +1365,7 @@ static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_wi static int annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, - struct perf_evsel *evsel, u64 len, int min_pcnt, int printed, + struct evsel *evsel, u64 len, int min_pcnt, int printed, int max_lines, struct annotation_line *queue, int addr_fmt_width, int percent_type) { @@ -1448,7 +1454,7 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start return -1; if (perf_evsel__is_group_event(evsel)) - width *= evsel->nr_members; + width *= evsel->core.nr_members; if (!*al->line) printf(" %*s:\n", width, " "); @@ -1625,6 +1631,19 @@ int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map * case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF: scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation"); break; + case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP: + scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); + break; + case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING: + scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); + break; + case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE: + scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name); + break; + case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF: + scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", + dso->long_name); + break; default: scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); break; @@ -1656,7 +1675,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil build_id_path = strdup(filename); if (!build_id_path) - return -1; + return ENOMEM; /* * old style build-id cache has name of XX/XXXXXXX.. while @@ -1707,13 +1726,13 @@ static int symbol__disassemble_bpf(struct symbol *sym, char tpath[PATH_MAX]; size_t buf_size; int nr_skip = 0; - int ret = -1; char *buf; bfd *bfdf; + int ret; FILE *s; if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO) - return -1; + return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE; pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, sym->name, sym->start, sym->end - sym->start); @@ -1726,8 +1745,10 @@ static int symbol__disassemble_bpf(struct symbol *sym, assert(bfd_check_format(bfdf, bfd_object)); s = open_memstream(&buf, &buf_size); - if (!s) + if (!s) { + ret = errno; goto out; + } init_disassemble_info(&info, s, (fprintf_ftype) fprintf); @@ -1736,8 +1757,10 @@ static int symbol__disassemble_bpf(struct symbol *sym, info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); - if (!info_node) + if (!info_node) { + ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; goto out; + } info_linear = info_node->info_linear; sub_id = dso->bpf_prog.sub_id; @@ -2011,10 +2034,10 @@ static void calc_percent(struct sym_hist *sym_hist, } static void annotation__calc_percent(struct annotation *notes, - struct perf_evsel *leader, s64 len) + struct evsel *leader, s64 len) { struct annotation_line *al, *next; - struct perf_evsel *evsel; + struct evsel *evsel; list_for_each_entry(al, ¬es->src->source, node) { s64 end; @@ -2041,7 +2064,7 @@ static void annotation__calc_percent(struct annotation *notes, } } -void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel) +void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) { struct annotation *notes = symbol__annotation(sym); @@ -2049,7 +2072,7 @@ void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel) } int symbol__annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, size_t privsize, + struct evsel *evsel, size_t privsize, struct annotation_options *options, struct arch **parch) { @@ -2065,11 +2088,11 @@ int symbol__annotate(struct symbol *sym, struct map *map, int err; if (!arch_name) - return -1; + return errno; args.arch = arch = arch__find(arch_name); if (arch == NULL) - return -ENOTSUP; + return ENOTSUP; if (parch) *parch = arch; @@ -2214,7 +2237,7 @@ static void print_summary(struct rb_root *root, const char *filename) } } -static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) +static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evsel->idx); @@ -2241,7 +2264,7 @@ static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start) } int symbol__annotate_printf(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2272,7 +2295,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, len = symbol__size(sym); if (perf_evsel__is_group_event(evsel)) { - width *= evsel->nr_members; + width *= evsel->core.nr_members; perf_evsel__group_desc(evsel, buf, sizeof(buf)); evsel_name = buf; } @@ -2405,7 +2428,7 @@ static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp, return 0; } -int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel, +int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { const char *ev_name = perf_evsel__name(evsel); @@ -2657,7 +2680,7 @@ static void symbol__calc_lines(struct symbol *sym, struct map *map, } int symbol__tty_annotate2(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2685,7 +2708,7 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map, } int symbol__tty_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2956,7 +2979,7 @@ void annotation_line__write(struct annotation_line *al, struct annotation *notes wops->write_graph); } -int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel, +int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel, struct annotation_options *options, struct arch **parch) { struct annotation *notes = symbol__annotation(sym); @@ -2965,10 +2988,10 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *ev notes->offsets = zalloc(size * sizeof(struct annotation_line *)); if (notes->offsets == NULL) - return -1; + return ENOMEM; if (perf_evsel__is_group_event(evsel)) - nr_pcnt = evsel->nr_members; + nr_pcnt = evsel->core.nr_members; err = symbol__annotate(sym, map, evsel, 0, options, parch); if (err) @@ -2991,7 +3014,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *ev out_free_offsets: zfree(¬es->offsets); - return -1; + return err; } #define ANNOTATION__CFG(n) \ |