perf/core improvements and fixes:

perf record:
 
   Ravi Bangoria:
 
   - Provide an option to print perf_event_open args and syscall return value.
     This was already possible using -v, but then lots of other debug info
     would be output as well, provide a way to show just the syscall args
     and return value, e.g.:
 
       # perf --debug perf-event-open=1 record
       perf_event_attr:
         size                             112
         { sample_period, sample_freq }   4000
         sample_type                      IP|TID|TIME|PERIOD
         read_format                      ID
         disabled                         1
         inherit                          1
       <SNIP>
         ksymbol                          1
         bpf_event                        1
       ------------------------------------------------------------
       sys_perf_event_open: pid 4308  cpu 0  group_fd -1  flags 0x8 = 4
 
 core:
 
 - Remove map->groups, we can get that information in other ways, reduces
   the size of a key data structure and paves the way to have it shared
   by multiple threads.
 
 - Use 'struct map_symbol' in more places, where we already were using a
   'struct map' + 'struct symbol', this helps passing that usual pair of
   information across callchain, browser code, etc.
 
 - Add 'struct map_groups' (where the map_symbol->map is) to 'struct map_symbol',
   to ease annotation code, for instance, where we call from functions in one map
   we're browsing to functions in another DSO, mapped in another 'struct map'.
 
 event parsing:
 
   Ian Rogers:
 
   - Use YYABORT to clear stack after failure, plugging leaks
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCXcrz4AAKCRCyPKLppCJ+
 J5HsAQCq3T5bSxa9OxC5w/+Gu4I+bhSlrUvSpzW9ymOaRDDdQAD/WwEcy+Z9OeKI
 Hd4hwALG7CkNH74bU7SKASFwZvrukgk=
 =G4y0
 -----END PGP SIGNATURE-----

Merge tag 'perf-core-for-mingo-5.5-20191112' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

perf record:

  Ravi Bangoria:

  - Provide an option to print perf_event_open args and syscall return value.
    This was already possible using -v, but then lots of other debug info
    would be output as well, provide a way to show just the syscall args
    and return value, e.g.:

      # perf --debug perf-event-open=1 record
      perf_event_attr:
        size                             112
        { sample_period, sample_freq }   4000
        sample_type                      IP|TID|TIME|PERIOD
        read_format                      ID
        disabled                         1
        inherit                          1
      <SNIP>
        ksymbol                          1
        bpf_event                        1
      ------------------------------------------------------------
      sys_perf_event_open: pid 4308  cpu 0  group_fd -1  flags 0x8 = 4

core:

- Remove map->groups, we can get that information in other ways, reduces
  the size of a key data structure and paves the way to have it shared
  by multiple threads.

- Use 'struct map_symbol' in more places, where we already were using a
  'struct map' + 'struct symbol', this helps passing that usual pair of
  information across callchain, browser code, etc.

- Add 'struct map_groups' (where the map_symbol->map is) to 'struct map_symbol',
  to ease annotation code, for instance, where we call from functions in one map
  we're browsing to functions in another DSO, mapped in another 'struct map'.

event parsing:

  Ian Rogers:

  - Use YYABORT to clear stack after failure, plugging leaks

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2019-11-15 08:33:54 +01:00
commit b0aeb45bad
39 changed files with 347 additions and 358 deletions

View File

@ -24,6 +24,8 @@ OPTIONS
data-convert - data convert command debug messages
stderr - write debug output (option -v) to stderr
in browser mode
perf-event-open - Print perf_event_open() arguments and
return value
--buildid-dir::
Setup buildid cache directory. It has higher priority than

View File

@ -7,7 +7,7 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
char *endptr, *tok, *name;
struct map *map = ms->map;
struct addr_map_symbol target = {
.map = map,
.ms = { .map = map, },
};
tok = strchr(ops->raw, ',');
@ -38,9 +38,9 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
return -1;
target.addr = map__objdump_2mem(map, ops->target.addr);
if (map_groups__find_ams(&target) == 0 &&
map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
ops->target.sym = target.sym;
if (map_groups__find_ams(ms->mg, &target) == 0 &&
map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
ops->target.sym = target.ms.sym;
return 0;
}

View File

@ -83,7 +83,7 @@ static void process_basic_block(struct addr_map_symbol *start,
struct addr_map_symbol *end,
struct branch_flags *flags)
{
struct symbol *sym = start->sym;
struct symbol *sym = start->ms.sym;
struct annotation *notes = sym ? symbol__annotation(sym) : NULL;
struct block_range_iter iter;
struct block_range *entry;
@ -301,9 +301,9 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
struct perf_annotate *ann)
{
if (!ann->use_stdio2)
return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel, &ann->opts);
return symbol__tty_annotate(&he->ms, evsel, &ann->opts);
return symbol__tty_annotate2(he->ms.sym, he->ms.map, evsel, &ann->opts);
return symbol__tty_annotate2(&he->ms, evsel, &ann->opts);
}
static void hists__find_annotations(struct hists *hists,

View File

@ -412,8 +412,8 @@ static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample)
sizeof(key), callcmp);
if (!caller) {
/* found */
if (node->map)
addr = map__unmap_ip(node->map, node->ip);
if (node->ms.map)
addr = map__unmap_ip(node->ms.map, node->ip);
else
addr = node->ip;

View File

@ -680,7 +680,7 @@ static int hists__resort_cb(struct hist_entry *he, void *arg)
if (rep->symbol_ipc && sym && !sym->annotate2) {
struct evsel *evsel = hists_to_evsel(he->hists);
symbol__annotate2(sym, he->ms.map, evsel,
symbol__annotate2(&he->ms, evsel,
&annotation__default_options, NULL);
}

View File

@ -2172,7 +2172,7 @@ static void save_task_callchain(struct perf_sched *sched,
if (node == NULL)
break;
sym = node->sym;
sym = node->ms.sym;
if (sym) {
if (!strcmp(sym->name, "schedule") ||
!strcmp(sym->name, "__schedule") ||

View File

@ -143,12 +143,12 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
return err;
}
err = symbol__annotate(sym, map, evsel, 0, &top->annotation_opts, NULL);
err = symbol__annotate(&he->ms, evsel, 0, &top->annotation_opts, NULL);
if (err == 0) {
top->sym_filter_entry = he;
} else {
char msg[BUFSIZ];
symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
symbol__strerror_disassemble(&he->ms, err, msg, sizeof(msg));
pr_err("Couldn't annotate %s: %s\n", sym->name, msg);
}
@ -257,7 +257,7 @@ static void perf_top__show_details(struct perf_top *top)
printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name);
printf(" Events Pcnt (>=%d%%)\n", top->annotation_opts.min_pcnt);
more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel, &top->annotation_opts);
more = symbol__annotate_printf(&he->ms, top->sym_evsel, &top->annotation_opts);
if (top->evlist->enabled) {
if (top->zero)

View File

@ -59,7 +59,7 @@ int test_dwarf_unwind__krava_1(struct thread *thread);
static int unwind_entry(struct unwind_entry *entry, void *arg)
{
unsigned long *cnt = (unsigned long *) arg;
char *symbol = entry->sym ? entry->sym->name : NULL;
char *symbol = entry->ms.sym ? entry->ms.sym->name : NULL;
static const char *funcs[MAX_STACK] = {
"test__arch_unwind_sample",
"test_dwarf_unwind__thread",

View File

@ -410,7 +410,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
struct evsel *evsel,
struct hist_browser_timer *hbt)
{
struct map_symbol *ms = browser->b.priv;
struct map_symbol *ms = browser->b.priv, target_ms;
struct disasm_line *dl = disasm_line(browser->selection);
struct annotation *notes;
char title[SYM_TITLE_MAX_SIZE];
@ -430,8 +430,11 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
return true;
}
target_ms.mg = ms->mg;
target_ms.map = ms->map;
target_ms.sym = dl->ops.target.sym;
pthread_mutex_unlock(&notes->lock);
symbol__tui_annotate(dl->ops.target.sym, ms->map, evsel, hbt, browser->opts);
symbol__tui_annotate(&target_ms, evsel, hbt, browser->opts);
sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_type);
ui_browser__show_title(&browser->b, title);
return true;
@ -874,7 +877,7 @@ int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts)
{
return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt, opts);
return symbol__tui_annotate(ms, evsel, hbt, opts);
}
int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel,
@ -888,16 +891,12 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel,
return map_symbol__tui_annotate(&he->ms, evsel, hbt, opts);
}
int symbol__tui_annotate(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts)
{
struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
struct map_symbol ms = {
.map = map,
.sym = sym,
};
struct annotate_browser browser = {
.b = {
.refresh = annotate_browser__refresh,
@ -905,7 +904,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
.write = annotate_browser__write,
.filter = disasm_line__filter,
.extra_title_lines = 1, /* for hists__scnprintf_title() */
.priv = &ms,
.priv = ms,
.use_navkeypressed = true,
},
.opts = opts,
@ -915,13 +914,13 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
if (sym == NULL)
return -1;
if (map->dso->annotate_warned)
if (ms->map->dso->annotate_warned)
return -1;
err = symbol__annotate2(sym, map, evsel, opts, &browser.arch);
err = symbol__annotate2(ms, evsel, opts, &browser.arch);
if (err) {
char msg[BUFSIZ];
symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
goto out_free_offsets;
}

View File

@ -2405,16 +2405,15 @@ do_annotate(struct hist_browser *browser, struct popup_action *act)
static int
add_annotate_opt(struct hist_browser *browser __maybe_unused,
struct popup_action *act, char **optstr,
struct map *map, struct symbol *sym)
struct map_symbol *ms)
{
if (sym == NULL || map->dso->annotate_warned)
if (ms->sym == NULL || ms->map->dso->annotate_warned)
return 0;
if (asprintf(optstr, "Annotate %s", sym->name) < 0)
if (asprintf(optstr, "Annotate %s", ms->sym->name) < 0)
return 0;
act->ms.map = map;
act->ms.sym = sym;
act->ms = *ms;
act->fn = do_annotate;
return 1;
}
@ -3115,20 +3114,17 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events,
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
bi->from.map,
bi->from.sym);
if (bi->to.sym != bi->from.sym)
&bi->from.ms);
if (bi->to.ms.sym != bi->from.ms.sym)
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
bi->to.map,
bi->to.sym);
&bi->to.ms);
} else {
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
browser->selection->map,
browser->selection->sym);
browser->selection);
}
skip_annotation:
nr_options += add_thread_opt(browser, &actions[nr_options],

View File

@ -54,10 +54,10 @@ static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
return ret;
}
static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym,
struct map *map, struct disasm_line *dl)
static int perf_gtk__get_offset(char *buf, size_t size, struct map_symbol *ms,
struct disasm_line *dl)
{
u64 start = map__rip_2objdump(map, sym->start);
u64 start = map__rip_2objdump(ms->map, ms->sym->start);
strcpy(buf, "");
@ -91,10 +91,11 @@ static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl)
return ret;
}
static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
struct map *map, struct evsel *evsel,
static int perf_gtk__annotate_symbol(GtkWidget *window, struct map_symbol *ms,
struct evsel *evsel,
struct hist_browser_timer *hbt __maybe_unused)
{
struct symbol *sym = ms->sym;
struct disasm_line *pos, *n;
struct annotation *notes;
GType col_types[MAX_ANN_COLS];
@ -144,7 +145,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
if (ret)
gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos))
if (perf_gtk__get_offset(s, sizeof(s), ms, pos))
gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
if (perf_gtk__get_line(s, sizeof(s), pos))
gtk_list_store_set(store, &iter, ANN_COL__LINE, s, -1);
@ -160,23 +161,23 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
return 0;
}
static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
struct evsel *evsel,
static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt)
{
struct symbol *sym = ms->sym;
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *scrolled_window;
GtkWidget *tab_label;
int err;
if (map->dso->annotate_warned)
if (ms->map->dso->annotate_warned)
return -1;
err = symbol__annotate(sym, map, evsel, 0, &annotation__default_options, NULL);
err = symbol__annotate(ms, evsel, 0, &annotation__default_options, NULL);
if (err) {
char msg[BUFSIZ];
symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
return -1;
}
@ -234,7 +235,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
tab_label);
perf_gtk__annotate_symbol(scrolled_window, sym, map, evsel, hbt);
perf_gtk__annotate_symbol(scrolled_window, ms, evsel, hbt);
return 0;
}
@ -242,7 +243,7 @@ int hist_entry__gtk_annotate(struct hist_entry *he,
struct evsel *evsel,
struct hist_browser_timer *hbt)
{
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
return symbol__gtk_annotate(&he->ms, evsel, hbt);
}
void perf_gtk__show_annotations(void)

View File

@ -243,7 +243,7 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
char *endptr, *tok, *name;
struct map *map = ms->map;
struct addr_map_symbol target = {
.map = map,
.ms = { .map = map, },
};
ops->target.addr = strtoull(ops->raw, &endptr, 16);
@ -271,9 +271,9 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
find_target:
target.addr = map__objdump_2mem(map, ops->target.addr);
if (map_groups__find_ams(&target) == 0 &&
map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
ops->target.sym = target.sym;
if (map_groups__find_ams(ms->mg, &target) == 0 &&
map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
ops->target.sym = target.ms.sym;
return 0;
@ -332,7 +332,7 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
struct map *map = ms->map;
struct symbol *sym = ms->sym;
struct addr_map_symbol target = {
.map = map,
.ms = { .map = map, },
};
const char *c = strchr(ops->raw, ',');
u64 start, end;
@ -391,9 +391,9 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
* Actual navigation will come next, with further understanding of how
* the symbol searching and disassembly should be done.
*/
if (map_groups__find_ams(&target) == 0 &&
map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
ops->target.sym = target.sym;
if (map_groups__find_ams(ms->mg, &target) == 0 &&
map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
ops->target.sym = target.ms.sym;
if (!ops->target.outside) {
ops->target.offset = target.addr - start;
@ -865,14 +865,15 @@ static int __symbol__account_cycles(struct cyc_hist *ch,
return 0;
}
static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
static int __symbol__inc_addr_samples(struct map_symbol *ms,
struct annotated_source *src, int evidx, u64 addr,
struct perf_sample *sample)
{
struct symbol *sym = ms->sym;
unsigned offset;
struct sym_hist *h;
pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr));
if ((addr < sym->start || addr >= sym->end) &&
(addr != sym->end || sym->start != sym->end)) {
@ -939,17 +940,17 @@ alloc_histograms:
return notes->src;
}
static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
static int symbol__inc_addr_samples(struct map_symbol *ms,
struct evsel *evsel, u64 addr,
struct perf_sample *sample)
{
struct symbol *sym = ms->sym;
struct annotated_source *src;
if (sym == NULL)
return 0;
src = symbol__hists(sym, evsel->evlist->core.nr_entries);
return (src) ? __symbol__inc_addr_samples(sym, map, src, evsel->idx,
addr, sample) : 0;
return src ? __symbol__inc_addr_samples(ms, src, evsel->idx, addr, sample) : 0;
}
static int symbol__account_cycles(u64 addr, u64 start,
@ -997,17 +998,17 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
* it starts on the function start.
*/
if (start &&
(start->sym == ams->sym ||
(ams->sym &&
start->addr == ams->sym->start + ams->map->start)))
(start->ms.sym == ams->ms.sym ||
(ams->ms.sym &&
start->addr == ams->ms.sym->start + ams->ms.map->start)))
saddr = start->al_addr;
if (saddr == 0)
pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n",
ams->addr,
start ? start->addr : 0,
ams->sym ? ams->sym->start + ams->map->start : 0,
ams->ms.sym ? ams->ms.sym->start + ams->ms.map->start : 0,
saddr);
err = symbol__account_cycles(ams->al_addr, saddr, ams->sym, cycles);
err = symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles);
if (err)
pr_debug2("account_cycles failed %d\n", err);
return err;
@ -1093,13 +1094,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 evsel *evsel)
{
return symbol__inc_addr_samples(ams->sym, ams->map, evsel, ams->al_addr, sample);
return symbol__inc_addr_samples(&ams->ms, evsel, ams->al_addr, sample);
}
int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
struct evsel *evsel, u64 ip)
{
return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evsel, ip, sample);
return symbol__inc_addr_samples(&he->ms, evsel, ip, sample);
}
static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms)
@ -1540,13 +1541,13 @@ static int symbol__parse_objdump_line(struct symbol *sym,
/* kcore has no symbols, so add the call target symbol */
if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) {
struct addr_map_symbol target = {
.map = map,
.addr = dl->ops.target.addr,
.ms = { .map = map, },
};
if (!map_groups__find_ams(&target) &&
target.sym->start == target.al_addr)
dl->ops.target.sym = target.sym;
if (!map_groups__find_ams(args->ms.mg, &target) &&
target.ms.sym->start == target.al_addr)
dl->ops.target.sym = target.ms.sym;
}
annotation_line__add(&dl->al, &notes->src->source);
@ -1583,10 +1584,9 @@ static void delete_last_nop(struct symbol *sym)
}
}
int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map,
int errnum, char *buf, size_t buflen)
int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen)
{
struct dso *dso = map->dso;
struct dso *dso = ms->map->dso;
BUG_ON(buflen == 0);
@ -2143,11 +2143,10 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel)
annotation__calc_percent(notes, evsel, symbol__size(sym));
}
int symbol__annotate(struct symbol *sym, struct map *map,
struct evsel *evsel, size_t privsize,
struct annotation_options *options,
struct arch **parch)
int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, size_t privsize,
struct annotation_options *options, struct arch **parch)
{
struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
struct annotate_args args = {
.privsize = privsize,
@ -2177,9 +2176,8 @@ int symbol__annotate(struct symbol *sym, struct map *map,
}
}
args.ms.map = map;
args.ms.sym = sym;
notes->start = map__rip_2objdump(map, sym->start);
args.ms = *ms;
notes->start = map__rip_2objdump(ms->map, sym->start);
return symbol__disassemble(sym, &args);
}
@ -2335,10 +2333,11 @@ static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start)
return 0;
}
int symbol__annotate_printf(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel,
struct annotation_options *opts)
{
struct map *map = ms->map;
struct symbol *sym = ms->sym;
struct dso *dso = map->dso;
char *filename;
const char *d_filename;
@ -2742,30 +2741,29 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
resort_source_line(root, &tmp_root);
}
static void symbol__calc_lines(struct symbol *sym, struct map *map,
struct rb_root *root,
static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root,
struct annotation_options *opts)
{
struct annotation *notes = symbol__annotation(sym);
struct annotation *notes = symbol__annotation(ms->sym);
annotation__calc_lines(notes, map, root, opts);
annotation__calc_lines(notes, ms->map, root, opts);
}
int symbol__tty_annotate2(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel,
struct annotation_options *opts)
{
struct dso *dso = map->dso;
struct dso *dso = ms->map->dso;
struct symbol *sym = ms->sym;
struct rb_root source_line = RB_ROOT;
struct hists *hists = evsel__hists(evsel);
char buf[1024];
if (symbol__annotate2(sym, map, evsel, opts, NULL) < 0)
if (symbol__annotate2(ms, evsel, opts, NULL) < 0)
return -1;
if (opts->print_lines) {
srcline_full_filename = opts->full_path;
symbol__calc_lines(sym, map, &source_line, opts);
symbol__calc_lines(ms, &source_line, opts);
print_summary(&source_line, dso->long_name);
}
@ -2779,25 +2777,25 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map,
return 0;
}
int symbol__tty_annotate(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel,
struct annotation_options *opts)
{
struct dso *dso = map->dso;
struct dso *dso = ms->map->dso;
struct symbol *sym = ms->sym;
struct rb_root source_line = RB_ROOT;
if (symbol__annotate(sym, map, evsel, 0, opts, NULL) < 0)
if (symbol__annotate(ms, evsel, 0, opts, NULL) < 0)
return -1;
symbol__calc_percent(sym, evsel);
if (opts->print_lines) {
srcline_full_filename = opts->full_path;
symbol__calc_lines(sym, map, &source_line, opts);
symbol__calc_lines(ms, &source_line, opts);
print_summary(&source_line, dso->long_name);
}
symbol__annotate_printf(sym, map, evsel, opts);
symbol__annotate_printf(ms, evsel, opts);
annotated_source__purge(symbol__annotation(sym)->src);
@ -3051,9 +3049,10 @@ void annotation_line__write(struct annotation_line *al, struct annotation *notes
wops->write_graph);
}
int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel,
int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
struct annotation_options *options, struct arch **parch)
{
struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
size_t size = symbol__size(sym);
int nr_pcnt = 1, err;
@ -3065,7 +3064,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel,
if (perf_evsel__is_group_event(evsel))
nr_pcnt = evsel->core.nr_members;
err = symbol__annotate(sym, map, evsel, 0, options, parch);
err = symbol__annotate(ms, evsel, 0, options, parch);
if (err)
goto out_free_offsets;

View File

@ -349,11 +349,11 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *samp
struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists);
void symbol__annotate_zero_histograms(struct symbol *sym);
int symbol__annotate(struct symbol *sym, struct map *map,
int symbol__annotate(struct map_symbol *ms,
struct evsel *evsel, size_t privsize,
struct annotation_options *options,
struct arch **parch);
int symbol__annotate2(struct symbol *sym, struct map *map,
int symbol__annotate2(struct map_symbol *ms,
struct evsel *evsel,
struct annotation_options *options,
struct arch **parch);
@ -380,11 +380,9 @@ enum symbol_disassemble_errno {
__SYMBOL_ANNOTATE_ERRNO__END,
};
int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
int errnum, char *buf, size_t buflen);
int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, size_t buflen);
int symbol__annotate_printf(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel,
struct annotation_options *options);
void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
@ -395,20 +393,16 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel,
bool ui__has_annotation(void);
int symbol__tty_annotate(struct symbol *sym, struct map *map,
struct evsel *evsel, struct annotation_options *opts);
int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts);
int symbol__tty_annotate2(struct symbol *sym, struct map *map,
struct evsel *evsel, struct annotation_options *opts);
int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts);
#ifdef HAVE_SLANG_SUPPORT
int symbol__tui_annotate(struct symbol *sym, struct map *map,
struct evsel *evsel,
int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts);
#else
static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
struct map *map __maybe_unused,
static inline int symbol__tui_annotate(struct map_symbol *ms __maybe_unused,
struct evsel *evsel __maybe_unused,
struct hist_browser_timer *hbt __maybe_unused,
struct annotation_options *opts __maybe_unused)

View File

@ -582,8 +582,8 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
return -1;
}
call->ip = cursor_node->ip;
call->ms.sym = cursor_node->sym;
call->ms.map = map__get(cursor_node->map);
call->ms = cursor_node->ms;
map__get(call->ms.map);
call->srcline = cursor_node->srcline;
if (cursor_node->branch) {
@ -720,21 +720,21 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
/* otherwise fall-back to symbol-based comparison below */
__fallthrough;
case CCKEY_FUNCTION:
if (node->sym && cnode->ms.sym) {
if (node->ms.sym && cnode->ms.sym) {
/*
* Compare inlined frames based on their symbol name
* because different inlined frames will have the same
* symbol start. Otherwise do a faster comparison based
* on the symbol start address.
*/
if (cnode->ms.sym->inlined || node->sym->inlined) {
if (cnode->ms.sym->inlined || node->ms.sym->inlined) {
match = match_chain_strings(cnode->ms.sym->name,
node->sym->name);
node->ms.sym->name);
if (match != MATCH_ERROR)
break;
} else {
match = match_chain_dso_addresses(cnode->ms.map, cnode->ms.sym->start,
node->map, node->sym->start);
node->ms.map, node->ms.sym->start);
break;
}
}
@ -742,7 +742,7 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
__fallthrough;
case CCKEY_ADDRESS:
default:
match = match_chain_dso_addresses(cnode->ms.map, cnode->ip, node->map, node->ip);
match = match_chain_dso_addresses(cnode->ms.map, cnode->ip, node->ms.map, node->ip);
break;
}
@ -1004,8 +1004,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
int err = 0;
list_for_each_entry_safe(list, next_list, &src->val, list) {
callchain_cursor_append(cursor, list->ip,
list->ms.map, list->ms.sym,
callchain_cursor_append(cursor, list->ip, &list->ms,
false, NULL, 0, 0, 0, list->srcline);
list_del_init(&list->list);
map__zput(list->ms.map);
@ -1044,7 +1043,7 @@ int callchain_merge(struct callchain_cursor *cursor,
}
int callchain_cursor_append(struct callchain_cursor *cursor,
u64 ip, struct map *map, struct symbol *sym,
u64 ip, struct map_symbol *ms,
bool branch, struct branch_flags *flags,
int nr_loop_iter, u64 iter_cycles, u64 branch_from,
const char *srcline)
@ -1060,9 +1059,9 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
}
node->ip = ip;
map__zput(node->map);
node->map = map__get(map);
node->sym = sym;
map__zput(node->ms.map);
node->ms = *ms;
map__get(node->ms.map);
node->branch = branch;
node->nr_loop_iter = nr_loop_iter;
node->iter_cycles = iter_cycles;
@ -1107,8 +1106,9 @@ int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *samp
int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
bool hide_unresolved)
{
al->map = node->map;
al->sym = node->sym;
al->mg = node->ms.mg;
al->map = node->ms.map;
al->sym = node->ms.sym;
al->srcline = node->srcline;
al->addr = node->ip;
@ -1119,8 +1119,8 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
goto out;
}
if (al->map->groups == &al->machine->kmaps) {
if (machine__is_host(al->machine)) {
if (al->mg == &al->mg->machine->kmaps) {
if (machine__is_host(al->mg->machine)) {
al->cpumode = PERF_RECORD_MISC_KERNEL;
al->level = 'k';
} else {
@ -1128,7 +1128,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
al->level = 'g';
}
} else {
if (machine__is_host(al->machine)) {
if (machine__is_host(al->mg->machine)) {
al->cpumode = PERF_RECORD_MISC_USER;
al->level = '.';
} else if (perf_guest) {
@ -1571,7 +1571,7 @@ int callchain_cursor__copy(struct callchain_cursor *dst,
if (node == NULL)
break;
rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
rc = callchain_cursor_append(dst, node->ip, &node->ms,
node->branch, &node->branch_flags,
node->nr_loop_iter,
node->iter_cycles,
@ -1597,5 +1597,5 @@ void callchain_cursor_reset(struct callchain_cursor *cursor)
cursor->last = &cursor->first;
for (node = cursor->first; node != NULL; node = node->next)
map__zput(node->map);
map__zput(node->ms.map);
}

View File

@ -141,8 +141,7 @@ struct callchain_list {
*/
struct callchain_cursor_node {
u64 ip;
struct map *map;
struct symbol *sym;
struct map_symbol ms;
const char *srcline;
bool branch;
struct branch_flags branch_flags;
@ -195,7 +194,7 @@ int callchain_merge(struct callchain_cursor *cursor,
void callchain_cursor_reset(struct callchain_cursor *cursor);
int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
struct map *map, struct symbol *sym,
struct map_symbol *ms,
bool branch, struct branch_flags *flags,
int nr_loop_iter, u64 iter_cycles, u64 branch_from,
const char *srcline);

View File

@ -181,7 +181,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
if (al->map) {
struct dso *dso = al->map->dso;
err = db_export__dso(dbe, dso, al->machine);
err = db_export__dso(dbe, dso, al->mg->machine);
if (err)
return err;
*dso_db_id = dso->db_id;
@ -249,9 +249,9 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
* constructing an addr_location struct and then passing it to
* db_ids_from_al() to perform the export.
*/
al.sym = node->sym;
al.map = node->map;
al.machine = machine;
al.sym = node->ms.sym;
al.map = node->ms.map;
al.mg = thread->mg;
al.addr = node->ip;
if (al.map && !al.sym)
@ -360,13 +360,13 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
if (err)
return err;
err = db_export__machine(dbe, al->machine);
err = db_export__machine(dbe, al->mg->machine);
if (err)
return err;
main_thread = thread__main_thread(al->machine, thread);
main_thread = thread__main_thread(al->mg->machine, thread);
err = db_export__threads(dbe, thread, main_thread, al->machine, &comm);
err = db_export__threads(dbe, thread, main_thread, al->mg->machine, &comm);
if (err)
goto out_put;
@ -380,7 +380,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
goto out_put;
if (dbe->cpr) {
struct call_path *cp = call_path_from_sample(dbe, al->machine,
struct call_path *cp = call_path_from_sample(dbe, al->mg->machine,
thread, sample,
evsel);
if (cp) {

View File

@ -24,6 +24,7 @@
#include <linux/ctype.h>
int verbose;
int debug_peo_args;
bool dump_trace = false, quiet = false;
int debug_ordered_events;
static int redirect_to_stderr;
@ -180,6 +181,7 @@ static struct debug_variable {
{ .name = "ordered-events", .ptr = &debug_ordered_events},
{ .name = "stderr", .ptr = &redirect_to_stderr},
{ .name = "data-convert", .ptr = &debug_data_convert },
{ .name = "perf-event-open", .ptr = &debug_peo_args },
{ .name = NULL, }
};

View File

@ -8,6 +8,7 @@
#include <linux/compiler.h>
extern int verbose;
extern int debug_peo_args;
extern bool quiet, dump_trace;
extern int debug_ordered_events;
extern int debug_data_convert;
@ -30,6 +31,14 @@ extern int debug_data_convert;
#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__)
/* Special macro to print perf_event_open arguments/return value. */
#define pr_debug2_peo(fmt, ...) { \
if (debug_peo_args) \
pr_debugN(0, pr_fmt(fmt), ##__VA_ARGS__); \
else \
pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__); \
}
#define pr_time_N(n, var, t, fmt, ...) \
eprintf_time(n, var, t, fmt, ##__VA_ARGS__)

View File

@ -461,7 +461,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
struct machine *machine = mg->machine;
bool load_map = false;
al->machine = machine;
al->mg = mg;
al->thread = thread;
al->addr = addr;
al->cpumode = cpumode;
@ -474,13 +474,13 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
al->level = 'k';
mg = &machine->kmaps;
al->mg = mg = &machine->kmaps;
load_map = true;
} else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
al->level = '.';
} else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
al->level = 'g';
mg = &machine->kmaps;
al->mg = mg = &machine->kmaps;
load_map = true;
} else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
al->level = 'u';

View File

@ -1524,7 +1524,7 @@ static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
static void display_attr(struct perf_event_attr *attr)
{
if (verbose >= 2) {
if (verbose >= 2 || debug_peo_args) {
fprintf(stderr, "%.60s\n", graph_dotted_line);
fprintf(stderr, "perf_event_attr:\n");
perf_event_attr__fprintf(stderr, attr, __open_attr__fprintf, NULL);
@ -1540,7 +1540,7 @@ static int perf_event_open(struct evsel *evsel,
int fd;
while (1) {
pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
pid, cpu, group_fd, flags);
fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, group_fd, flags);
@ -1560,9 +1560,9 @@ static int perf_event_open(struct evsel *evsel,
break;
}
pr_debug2("\nsys_perf_event_open failed, error %d\n", -ENOTSUP);
pr_debug2_peo("\nsys_perf_event_open failed, error %d\n", -ENOTSUP);
evsel->core.attr.precise_ip--;
pr_debug2("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
pr_debug2_peo("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
display_attr(&evsel->core.attr);
}
@ -1681,12 +1681,12 @@ retry_open:
continue;
}
pr_debug2("\nsys_perf_event_open failed, error %d\n",
pr_debug2_peo("\nsys_perf_event_open failed, error %d\n",
err);
goto try_fallback;
}
pr_debug2(" = %d\n", fd);
pr_debug2_peo(" = %d\n", fd);
if (evsel->bpf_fd >= 0) {
int evt_fd = fd;
@ -1754,58 +1754,58 @@ try_fallback:
*/
if (!perf_missing_features.aux_output && evsel->core.attr.aux_output) {
perf_missing_features.aux_output = true;
pr_debug2("Kernel has no attr.aux_output support, bailing out\n");
pr_debug2_peo("Kernel has no attr.aux_output support, bailing out\n");
goto out_close;
} else if (!perf_missing_features.bpf && evsel->core.attr.bpf_event) {
perf_missing_features.bpf = true;
pr_debug2("switching off bpf_event\n");
pr_debug2_peo("switching off bpf_event\n");
goto fallback_missing_features;
} else if (!perf_missing_features.ksymbol && evsel->core.attr.ksymbol) {
perf_missing_features.ksymbol = true;
pr_debug2("switching off ksymbol\n");
pr_debug2_peo("switching off ksymbol\n");
goto fallback_missing_features;
} else if (!perf_missing_features.write_backward && evsel->core.attr.write_backward) {
perf_missing_features.write_backward = true;
pr_debug2("switching off write_backward\n");
pr_debug2_peo("switching off write_backward\n");
goto out_close;
} else if (!perf_missing_features.clockid_wrong && evsel->core.attr.use_clockid) {
perf_missing_features.clockid_wrong = true;
pr_debug2("switching off clockid\n");
pr_debug2_peo("switching off clockid\n");
goto fallback_missing_features;
} else if (!perf_missing_features.clockid && evsel->core.attr.use_clockid) {
perf_missing_features.clockid = true;
pr_debug2("switching off use_clockid\n");
pr_debug2_peo("switching off use_clockid\n");
goto fallback_missing_features;
} else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
perf_missing_features.cloexec = true;
pr_debug2("switching off cloexec flag\n");
pr_debug2_peo("switching off cloexec flag\n");
goto fallback_missing_features;
} else if (!perf_missing_features.mmap2 && evsel->core.attr.mmap2) {
perf_missing_features.mmap2 = true;
pr_debug2("switching off mmap2\n");
pr_debug2_peo("switching off mmap2\n");
goto fallback_missing_features;
} else if (!perf_missing_features.exclude_guest &&
(evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host)) {
perf_missing_features.exclude_guest = true;
pr_debug2("switching off exclude_guest, exclude_host\n");
pr_debug2_peo("switching off exclude_guest, exclude_host\n");
goto fallback_missing_features;
} else if (!perf_missing_features.sample_id_all) {
perf_missing_features.sample_id_all = true;
pr_debug2("switching off sample_id_all\n");
pr_debug2_peo("switching off sample_id_all\n");
goto retry_sample_id;
} else if (!perf_missing_features.lbr_flags &&
(evsel->core.attr.branch_sample_type &
(PERF_SAMPLE_BRANCH_NO_CYCLES |
PERF_SAMPLE_BRANCH_NO_FLAGS))) {
perf_missing_features.lbr_flags = true;
pr_debug2("switching off branch sample type no (cycles/flags)\n");
pr_debug2_peo("switching off branch sample type no (cycles/flags)\n");
goto fallback_missing_features;
} else if (!perf_missing_features.group_read &&
evsel->core.attr.inherit &&
(evsel->core.attr.read_format & PERF_FORMAT_GROUP) &&
perf_evsel__is_group_leader(evsel)) {
perf_missing_features.group_read = true;
pr_debug2("switching off group read\n");
pr_debug2_peo("switching off group read\n");
goto fallback_missing_features;
}
out_close:

View File

@ -125,13 +125,18 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
callchain_cursor_commit(cursor);
while (1) {
struct symbol *sym;
struct map *map;
u64 addr = 0;
node = callchain_cursor_current(cursor);
if (!node)
break;
if (node->sym && node->sym->ignore && print_skip_ignored)
sym = node->ms.sym;
map = node->ms.map;
if (sym && sym->ignore && print_skip_ignored)
goto next;
printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
@ -142,42 +147,42 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
if (print_ip)
printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
if (node->map)
addr = node->map->map_ip(node->map, node->ip);
if (map)
addr = map->map_ip(map, node->ip);
if (print_sym) {
printed += fprintf(fp, " ");
node_al.addr = addr;
node_al.map = node->map;
node_al.map = map;
if (print_symoffset) {
printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
printed += __symbol__fprintf_symname_offs(sym, &node_al,
print_unknown_as_addr,
true, fp);
} else {
printed += __symbol__fprintf_symname(node->sym, &node_al,
printed += __symbol__fprintf_symname(sym, &node_al,
print_unknown_as_addr, fp);
}
}
if (print_dso && (!node->sym || !node->sym->inlined)) {
if (print_dso && (!sym || !sym->inlined)) {
printed += fprintf(fp, " (");
printed += map__fprintf_dsoname(node->map, fp);
printed += map__fprintf_dsoname(map, fp);
printed += fprintf(fp, ")");
}
if (print_srcline)
printed += map__fprintf_srcline(node->map, addr, "\n ", fp);
printed += map__fprintf_srcline(map, addr, "\n ", fp);
if (node->sym && node->sym->inlined)
if (sym && sym->inlined)
printed += fprintf(fp, " (inlined)");
if (!print_oneline)
printed += fprintf(fp, "\n");
/* Add srccode here too? */
if (bt_stop_list && node->sym &&
strlist__has_entry(bt_stop_list, node->sym->name)) {
if (bt_stop_list && sym &&
strlist__has_entry(bt_stop_list, sym->name)) {
break;
}

View File

@ -112,13 +112,13 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
if (h->branch_info) {
if (h->branch_info->from.sym) {
symlen = (int)h->branch_info->from.sym->namelen + 4;
if (h->branch_info->from.ms.sym) {
symlen = (int)h->branch_info->from.ms.sym->namelen + 4;
if (verbose > 0)
symlen += BITS_PER_LONG / 4 + 2 + 3;
hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
symlen = dso__name_len(h->branch_info->from.map->dso);
symlen = dso__name_len(h->branch_info->from.ms.map->dso);
hists__new_col_len(hists, HISTC_DSO_FROM, symlen);
} else {
symlen = unresolved_col_width + 4 + 2;
@ -126,13 +126,13 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
hists__set_unres_dso_col_len(hists, HISTC_DSO_FROM);
}
if (h->branch_info->to.sym) {
symlen = (int)h->branch_info->to.sym->namelen + 4;
if (h->branch_info->to.ms.sym) {
symlen = (int)h->branch_info->to.ms.sym->namelen + 4;
if (verbose > 0)
symlen += BITS_PER_LONG / 4 + 2 + 3;
hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
symlen = dso__name_len(h->branch_info->to.map->dso);
symlen = dso__name_len(h->branch_info->to.ms.map->dso);
hists__new_col_len(hists, HISTC_DSO_TO, symlen);
} else {
symlen = unresolved_col_width + 4 + 2;
@ -149,8 +149,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
}
if (h->mem_info) {
if (h->mem_info->daddr.sym) {
symlen = (int)h->mem_info->daddr.sym->namelen + 4
if (h->mem_info->daddr.ms.sym) {
symlen = (int)h->mem_info->daddr.ms.sym->namelen + 4
+ unresolved_col_width + 2;
hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
symlen);
@ -164,8 +164,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
symlen);
}
if (h->mem_info->iaddr.sym) {
symlen = (int)h->mem_info->iaddr.sym->namelen + 4
if (h->mem_info->iaddr.ms.sym) {
symlen = (int)h->mem_info->iaddr.ms.sym->namelen + 4
+ unresolved_col_width + 2;
hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
symlen);
@ -175,8 +175,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
symlen);
}
if (h->mem_info->daddr.map) {
symlen = dso__name_len(h->mem_info->daddr.map->dso);
if (h->mem_info->daddr.ms.map) {
symlen = dso__name_len(h->mem_info->daddr.ms.map->dso);
hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
symlen);
} else {
@ -443,13 +443,13 @@ static int hist_entry__init(struct hist_entry *he,
memcpy(he->branch_info, template->branch_info,
sizeof(*he->branch_info));
map__get(he->branch_info->from.map);
map__get(he->branch_info->to.map);
map__get(he->branch_info->from.ms.map);
map__get(he->branch_info->to.ms.map);
}
if (he->mem_info) {
map__get(he->mem_info->iaddr.map);
map__get(he->mem_info->daddr.map);
map__get(he->mem_info->iaddr.ms.map);
map__get(he->mem_info->daddr.ms.map);
}
if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
@ -492,13 +492,13 @@ err_rawdata:
err_infos:
if (he->branch_info) {
map__put(he->branch_info->from.map);
map__put(he->branch_info->to.map);
map__put(he->branch_info->from.ms.map);
map__put(he->branch_info->to.ms.map);
zfree(&he->branch_info);
}
if (he->mem_info) {
map__put(he->mem_info->iaddr.map);
map__put(he->mem_info->daddr.map);
map__put(he->mem_info->iaddr.ms.map);
map__put(he->mem_info->daddr.ms.map);
}
err:
map__zput(he->ms.map);
@ -692,6 +692,7 @@ __hists__add_entry(struct hists *hists,
.ino = ns ? ns->link_info[CGROUP_NS_INDEX].ino : 0,
},
.ms = {
.mg = al->mg,
.map = al->map,
.sym = al->sym,
},
@ -759,6 +760,7 @@ struct hist_entry *hists__add_entry_block(struct hists *hists,
.block_info = block_info,
.hists = hists,
.ms = {
.mg = al->mg,
.map = al->map,
.sym = al->sym,
},
@ -893,8 +895,9 @@ iter_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al)
if (iter->curr >= iter->total)
return 0;
al->map = bi[i].to.map;
al->sym = bi[i].to.sym;
al->mg = bi[i].to.ms.mg;
al->map = bi[i].to.ms.map;
al->sym = bi[i].to.ms.sym;
al->addr = bi[i].to.addr;
return 1;
}
@ -912,7 +915,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
bi = iter->priv;
if (iter->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
if (iter->hide_unresolved && !(bi[i].from.ms.sym && bi[i].to.ms.sym))
goto out;
/*
@ -1069,6 +1072,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
.comm = thread__comm(al->thread),
.ip = al->addr,
.ms = {
.mg = al->mg,
.map = al->map,
.sym = al->sym,
},
@ -1251,16 +1255,16 @@ void hist_entry__delete(struct hist_entry *he)
map__zput(he->ms.map);
if (he->branch_info) {
map__zput(he->branch_info->from.map);
map__zput(he->branch_info->to.map);
map__zput(he->branch_info->from.ms.map);
map__zput(he->branch_info->to.ms.map);
free_srcline(he->branch_info->srcline_from);
free_srcline(he->branch_info->srcline_to);
zfree(&he->branch_info);
}
if (he->mem_info) {
map__zput(he->mem_info->iaddr.map);
map__zput(he->mem_info->daddr.map);
map__zput(he->mem_info->iaddr.ms.map);
map__zput(he->mem_info->daddr.ms.map);
mem_info__zput(he->mem_info);
}

View File

@ -1968,8 +1968,9 @@ static void ip__resolve_ams(struct thread *thread,
ams->addr = ip;
ams->al_addr = al.addr;
ams->sym = al.sym;
ams->map = al.map;
ams->ms.mg = al.mg;
ams->ms.sym = al.sym;
ams->ms.map = al.map;
ams->phys_addr = 0;
}
@ -1985,8 +1986,9 @@ static void ip__resolve_data(struct thread *thread,
ams->addr = addr;
ams->al_addr = al.addr;
ams->sym = al.sym;
ams->map = al.map;
ams->ms.mg = al.mg;
ams->ms.sym = al.sym;
ams->ms.map = al.map;
ams->phys_addr = phys_addr;
}
@ -2006,8 +2008,9 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
return mi;
}
static char *callchain_srcline(struct map *map, struct symbol *sym, u64 ip)
static char *callchain_srcline(struct map_symbol *ms, u64 ip)
{
struct map *map = ms->map;
char *srcline = NULL;
if (!map || callchain_param.key == CCKEY_FUNCTION)
@ -2019,7 +2022,7 @@ static char *callchain_srcline(struct map *map, struct symbol *sym, u64 ip)
bool show_addr = callchain_param.key == CCKEY_ADDRESS;
srcline = get_srcline(map->dso, map__rip_2objdump(map, ip),
sym, show_sym, show_addr, ip);
ms->sym, show_sym, show_addr, ip);
srcline__tree_insert(&map->dso->srclines, ip, srcline);
}
@ -2042,6 +2045,7 @@ static int add_callchain_ip(struct thread *thread,
struct iterations *iter,
u64 branch_from)
{
struct map_symbol ms;
struct addr_location al;
int nr_loop_iter = 0;
u64 iter_cycles = 0;
@ -2099,8 +2103,11 @@ static int add_callchain_ip(struct thread *thread,
iter_cycles = iter->cycles;
}
srcline = callchain_srcline(al.map, al.sym, al.addr);
return callchain_cursor_append(cursor, ip, al.map, al.sym,
ms.mg = al.mg;
ms.map = al.map;
ms.sym = al.sym;
srcline = callchain_srcline(&ms, al.addr);
return callchain_cursor_append(cursor, ip, &ms,
branch, flags, nr_loop_iter,
iter_cycles, branch_from, srcline);
}
@ -2448,9 +2455,10 @@ check_calls:
return 0;
}
static int append_inlines(struct callchain_cursor *cursor,
struct map *map, struct symbol *sym, u64 ip)
static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip)
{
struct symbol *sym = ms->sym;
struct map *map = ms->map;
struct inline_node *inline_node;
struct inline_list *ilist;
u64 addr;
@ -2471,8 +2479,11 @@ static int append_inlines(struct callchain_cursor *cursor,
}
list_for_each_entry(ilist, &inline_node->val, list) {
ret = callchain_cursor_append(cursor, ip, map,
ilist->symbol, false,
struct map_symbol ilist_ms = {
.map = map,
.sym = ilist->symbol,
};
ret = callchain_cursor_append(cursor, ip, &ilist_ms, false,
NULL, 0, 0, 0, ilist->srcline);
if (ret != 0)
@ -2488,22 +2499,21 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
const char *srcline = NULL;
u64 addr = entry->ip;
if (symbol_conf.hide_unresolved && entry->sym == NULL)
if (symbol_conf.hide_unresolved && entry->ms.sym == NULL)
return 0;
if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0)
if (append_inlines(cursor, &entry->ms, entry->ip) == 0)
return 0;
/*
* Convert entry->ip from a virtual address to an offset in
* its corresponding binary.
*/
if (entry->map)
addr = map__map_ip(entry->map, entry->ip);
if (entry->ms.map)
addr = map__map_ip(entry->ms.map, entry->ip);
srcline = callchain_srcline(entry->map, entry->sym, addr);
return callchain_cursor_append(cursor, entry->ip,
entry->map, entry->sym,
srcline = callchain_srcline(&entry->ms, addr);
return callchain_cursor_append(cursor, entry->ip, &entry->ms,
false, NULL, 0, 0, 0, srcline);
}

View File

@ -140,7 +140,6 @@ void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
map->map_ip = map__map_ip;
map->unmap_ip = map__unmap_ip;
RB_CLEAR_NODE(&map->rb_node);
map->groups = NULL;
map->erange_warned = false;
refcount_set(&map->refcnt, 1);
}
@ -244,18 +243,11 @@ struct map *map__new2(u64 start, struct dso *dso)
return map;
}
/*
* Use this and __map__is_kmodule() for map instances that are in
* machine->kmaps, and thus have map->groups->machine all properly set, to
* disambiguate between the kernel and modules.
*
* When the need arises, introduce map__is_{kernel,kmodule)() that
* checks (map->groups != NULL && map->groups->machine != NULL &&
* map->dso->kernel) before calling __map__is_{kernel,kmodule}())
*/
bool __map__is_kernel(const struct map *map)
{
return machine__kernel_map(map->groups->machine) == map;
if (!map->dso->kernel)
return false;
return machine__kernel_map(map__kmaps((struct map *)map)->machine) == map;
}
bool __map__is_extra_kernel_map(const struct map *map)
@ -395,7 +387,6 @@ struct map *map__clone(struct map *from)
refcount_set(&map->refcnt, 1);
RB_CLEAR_NODE(&map->rb_node);
dso__get(map->dso);
map->groups = NULL;
}
return map;
@ -589,7 +580,6 @@ void map_groups__init(struct map_groups *mg, struct machine *machine)
void map_groups__insert(struct map_groups *mg, struct map *map)
{
maps__insert(&mg->maps, map);
map->groups = mg;
}
static void __maps__purge(struct maps *maps)
@ -710,20 +700,20 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
return maps__find_symbol_by_name(&mg->maps, name, mapp);
}
int map_groups__find_ams(struct addr_map_symbol *ams)
int map_groups__find_ams(struct map_groups *mg, struct addr_map_symbol *ams)
{
if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
if (ams->map->groups == NULL)
if (ams->addr < ams->ms.map->start || ams->addr >= ams->ms.map->end) {
if (mg == NULL)
return -1;
ams->map = map_groups__find(ams->map->groups, ams->addr);
if (ams->map == NULL)
ams->ms.map = map_groups__find(mg, ams->addr);
if (ams->ms.map == NULL)
return -1;
}
ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
ams->sym = map__find_symbol(ams->map, ams->al_addr);
ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
return ams->sym ? 0 : -1;
return ams->ms.sym ? 0 : -1;
}
static size_t maps__fprintf(struct maps *maps, FILE *fp)
@ -756,11 +746,11 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map)
{
__maps__insert(&mg->maps, map);
__maps__insert_name(&mg->maps, map);
map->groups = mg;
}
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE *fp)
{
struct maps *maps = &mg->maps;
struct rb_root *root;
struct rb_node *next, *first;
int err = 0;
@ -825,7 +815,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
}
before->end = map->start;
__map_groups__insert(pos->groups, before);
__map_groups__insert(mg, before);
if (verbose >= 2 && !use_browser)
map__fprintf(before, fp);
map__put(before);
@ -842,7 +832,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
after->start = map->end;
after->pgoff += map->end - pos->start;
assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end));
__map_groups__insert(pos->groups, after);
__map_groups__insert(mg, after);
if (verbose >= 2 && !use_browser)
map__fprintf(after, fp);
map__put(after);
@ -860,12 +850,6 @@ out:
return err;
}
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
FILE *fp)
{
return maps__fixup_overlappings(&mg->maps, map, fp);
}
/*
* XXX This should not really _copy_ te maps, but refcount them.
*/

View File

@ -42,7 +42,6 @@ struct map {
u64 (*unmap_ip)(struct map *, u64);
struct dso *dso;
struct map_groups *groups;
refcount_t refcnt;
};

View File

@ -100,7 +100,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, const char
struct addr_map_symbol;
int map_groups__find_ams(struct addr_map_symbol *ams);
int map_groups__find_ams(struct map_groups *mg, struct addr_map_symbol *ams);
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE *fp);

View File

@ -4,17 +4,18 @@
#include <linux/types.h>
struct map_groups;
struct map;
struct symbol;
struct map_symbol {
struct map_groups *mg;
struct map *map;
struct symbol *sym;
};
struct addr_map_symbol {
struct map *map;
struct symbol *sym;
struct map_symbol ms;
u64 addr;
u64 al_addr;
u64 phys_addr;

View File

@ -410,7 +410,7 @@ do { \
return -1;
}
if (!mi->daddr.map || !mi->iaddr.map) {
if (!mi->daddr.ms.map || !mi->iaddr.ms.map) {
stats->nomap++;
return -1;
}

View File

@ -284,6 +284,7 @@ PE_NAME opt_pmu_config
do { \
parse_events_terms__delete($2); \
parse_events_terms__delete(orig_terms); \
free(list); \
free($1); \
free(pattern); \
YYABORT; \
@ -550,7 +551,7 @@ tracepoint_name opt_event_config
free($1.event);
if (err) {
free(list);
return -1;
YYABORT;
}
$$ = list;
}

View File

@ -65,6 +65,7 @@ struct perf_env perf_env;
* implementing 'verbose' and 'eprintf'.
*/
int verbose;
int debug_peo_args;
int eprintf(int level, int var, const char *fmt, ...);

View File

@ -294,17 +294,17 @@ static SV *perl_process_callchain(struct perf_sample *sample,
goto exit;
}
if (node->sym) {
if (node->ms.sym) {
HV *sym = newHV();
if (!sym) {
hv_undef(elem);
goto exit;
}
if (!hv_stores(sym, "start", newSVuv(node->sym->start)) ||
!hv_stores(sym, "end", newSVuv(node->sym->end)) ||
!hv_stores(sym, "binding", newSVuv(node->sym->binding)) ||
!hv_stores(sym, "name", newSVpvn(node->sym->name,
node->sym->namelen)) ||
if (!hv_stores(sym, "start", newSVuv(node->ms.sym->start)) ||
!hv_stores(sym, "end", newSVuv(node->ms.sym->end)) ||
!hv_stores(sym, "binding", newSVuv(node->ms.sym->binding)) ||
!hv_stores(sym, "name", newSVpvn(node->ms.sym->name,
node->ms.sym->namelen)) ||
!hv_stores(elem, "sym", newRV_noinc((SV*)sym))) {
hv_undef(sym);
hv_undef(elem);
@ -312,8 +312,8 @@ static SV *perl_process_callchain(struct perf_sample *sample,
}
}
if (node->map) {
struct map *map = node->map;
if (node->ms.map) {
struct map *map = node->ms.map;
const char *dsoname = "[unknown]";
if (map && map->dso) {
if (symbol_conf.show_kernel_path && map->dso->long_name)

View File

@ -428,24 +428,24 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
pydict_set_item_string_decref(pyelem, "ip",
PyLong_FromUnsignedLongLong(node->ip));
if (node->sym) {
if (node->ms.sym) {
PyObject *pysym = PyDict_New();
if (!pysym)
Py_FatalError("couldn't create Python dictionary");
pydict_set_item_string_decref(pysym, "start",
PyLong_FromUnsignedLongLong(node->sym->start));
PyLong_FromUnsignedLongLong(node->ms.sym->start));
pydict_set_item_string_decref(pysym, "end",
PyLong_FromUnsignedLongLong(node->sym->end));
PyLong_FromUnsignedLongLong(node->ms.sym->end));
pydict_set_item_string_decref(pysym, "binding",
_PyLong_FromLong(node->sym->binding));
_PyLong_FromLong(node->ms.sym->binding));
pydict_set_item_string_decref(pysym, "name",
_PyUnicode_FromStringAndSize(node->sym->name,
node->sym->namelen));
_PyUnicode_FromStringAndSize(node->ms.sym->name,
node->ms.sym->namelen));
pydict_set_item_string_decref(pyelem, "sym", pysym);
}
if (node->map) {
const char *dsoname = get_dsoname(node->map);
if (node->ms.map) {
const char *dsoname = get_dsoname(node->ms.map);
pydict_set_item_string_decref(pyelem, "dso",
_PyUnicode_FromString(dsoname));
@ -1127,7 +1127,7 @@ static void python_export_sample_table(struct db_export *dbe,
tuple_set_u64(t, 0, es->db_id);
tuple_set_u64(t, 1, es->evsel->db_id);
tuple_set_u64(t, 2, es->al->machine->db_id);
tuple_set_u64(t, 2, es->al->mg->machine->db_id);
tuple_set_u64(t, 3, es->al->thread->db_id);
tuple_set_u64(t, 4, es->comm_db_id);
tuple_set_u64(t, 5, es->dso_db_id);

View File

@ -287,10 +287,12 @@ sort__sym_sort(struct hist_entry *left, struct hist_entry *right)
return strcmp(right->ms.sym->name, left->ms.sym->name);
}
static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
static int _hist_entry__sym_snprintf(struct map_symbol *ms,
u64 ip, char level, char *bf, size_t size,
unsigned int width)
{
struct symbol *sym = ms->sym;
struct map *map = ms->map;
size_t ret = 0;
if (verbose > 0) {
@ -325,7 +327,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
return _hist_entry__sym_snprintf(&he->ms, he->ip,
he->level, bf, size, width);
}
@ -386,7 +388,7 @@ struct sort_entry sort_srcline = {
static char *addr_map_symbol__srcline(struct addr_map_symbol *ams)
{
return map__srcline(ams->map, ams->al_addr, ams->sym);
return map__srcline(ams->ms.map, ams->al_addr, ams->ms.sym);
}
static int64_t
@ -769,15 +771,15 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
if (!left->branch_info || !right->branch_info)
return cmp_null(left->branch_info, right->branch_info);
return _sort__dso_cmp(left->branch_info->from.map,
right->branch_info->from.map);
return _sort__dso_cmp(left->branch_info->from.ms.map,
right->branch_info->from.ms.map);
}
static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
if (he->branch_info)
return _hist_entry__dso_snprintf(he->branch_info->from.map,
return _hist_entry__dso_snprintf(he->branch_info->from.ms.map,
bf, size, width);
else
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
@ -791,8 +793,8 @@ static int hist_entry__dso_from_filter(struct hist_entry *he, int type,
if (type != HIST_FILTER__DSO)
return -1;
return dso && (!he->branch_info || !he->branch_info->from.map ||
he->branch_info->from.map->dso != dso);
return dso && (!he->branch_info || !he->branch_info->from.ms.map ||
he->branch_info->from.ms.map->dso != dso);
}
static int64_t
@ -801,15 +803,15 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
if (!left->branch_info || !right->branch_info)
return cmp_null(left->branch_info, right->branch_info);
return _sort__dso_cmp(left->branch_info->to.map,
right->branch_info->to.map);
return _sort__dso_cmp(left->branch_info->to.ms.map,
right->branch_info->to.ms.map);
}
static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
if (he->branch_info)
return _hist_entry__dso_snprintf(he->branch_info->to.map,
return _hist_entry__dso_snprintf(he->branch_info->to.ms.map,
bf, size, width);
else
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
@ -823,8 +825,8 @@ static int hist_entry__dso_to_filter(struct hist_entry *he, int type,
if (type != HIST_FILTER__DSO)
return -1;
return dso && (!he->branch_info || !he->branch_info->to.map ||
he->branch_info->to.map->dso != dso);
return dso && (!he->branch_info || !he->branch_info->to.ms.map ||
he->branch_info->to.ms.map->dso != dso);
}
static int64_t
@ -839,10 +841,10 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
from_l = &left->branch_info->from;
from_r = &right->branch_info->from;
if (!from_l->sym && !from_r->sym)
if (!from_l->ms.sym && !from_r->ms.sym)
return _sort__addr_cmp(from_l->addr, from_r->addr);
return _sort__sym_cmp(from_l->sym, from_r->sym);
return _sort__sym_cmp(from_l->ms.sym, from_r->ms.sym);
}
static int64_t
@ -856,10 +858,10 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
to_l = &left->branch_info->to;
to_r = &right->branch_info->to;
if (!to_l->sym && !to_r->sym)
if (!to_l->ms.sym && !to_r->ms.sym)
return _sort__addr_cmp(to_l->addr, to_r->addr);
return _sort__sym_cmp(to_l->sym, to_r->sym);
return _sort__sym_cmp(to_l->ms.sym, to_r->ms.sym);
}
static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
@ -868,8 +870,7 @@ static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
if (he->branch_info) {
struct addr_map_symbol *from = &he->branch_info->from;
return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
he->level, bf, size, width);
return _hist_entry__sym_snprintf(&from->ms, from->addr, he->level, bf, size, width);
}
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
@ -881,8 +882,7 @@ static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
if (he->branch_info) {
struct addr_map_symbol *to = &he->branch_info->to;
return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
he->level, bf, size, width);
return _hist_entry__sym_snprintf(&to->ms, to->addr, he->level, bf, size, width);
}
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
@ -896,8 +896,8 @@ static int hist_entry__sym_from_filter(struct hist_entry *he, int type,
if (type != HIST_FILTER__SYMBOL)
return -1;
return sym && !(he->branch_info && he->branch_info->from.sym &&
strstr(he->branch_info->from.sym->name, sym));
return sym && !(he->branch_info && he->branch_info->from.ms.sym &&
strstr(he->branch_info->from.ms.sym->name, sym));
}
static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
@ -908,8 +908,8 @@ static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
if (type != HIST_FILTER__SYMBOL)
return -1;
return sym && !(he->branch_info && he->branch_info->to.sym &&
strstr(he->branch_info->to.sym->name, sym));
return sym && !(he->branch_info && he->branch_info->to.ms.sym &&
strstr(he->branch_info->to.ms.sym->name, sym));
}
struct sort_entry sort_dso_from = {
@ -1017,16 +1017,13 @@ static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
uint64_t addr = 0;
struct map *map = NULL;
struct symbol *sym = NULL;
struct map_symbol *ms = NULL;
if (he->mem_info) {
addr = he->mem_info->daddr.addr;
map = he->mem_info->daddr.map;
sym = he->mem_info->daddr.sym;
ms = &he->mem_info->daddr.ms;
}
return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
width);
return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
}
int64_t
@ -1046,16 +1043,13 @@ static int hist_entry__iaddr_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
uint64_t addr = 0;
struct map *map = NULL;
struct symbol *sym = NULL;
struct map_symbol *ms = NULL;
if (he->mem_info) {
addr = he->mem_info->iaddr.addr;
map = he->mem_info->iaddr.map;
sym = he->mem_info->iaddr.sym;
ms = &he->mem_info->iaddr.ms;
}
return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
width);
return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
}
static int64_t
@ -1065,9 +1059,9 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
struct map *map_r = NULL;
if (left->mem_info)
map_l = left->mem_info->daddr.map;
map_l = left->mem_info->daddr.ms.map;
if (right->mem_info)
map_r = right->mem_info->daddr.map;
map_r = right->mem_info->daddr.ms.map;
return _sort__dso_cmp(map_l, map_r);
}
@ -1078,7 +1072,7 @@ static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
struct map *map = NULL;
if (he->mem_info)
map = he->mem_info->daddr.map;
map = he->mem_info->daddr.ms.map;
return _hist_entry__dso_snprintf(map, bf, size, width);
}
@ -1208,8 +1202,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
if (left->cpumode > right->cpumode) return -1;
if (left->cpumode < right->cpumode) return 1;
l_map = left->mem_info->daddr.map;
r_map = right->mem_info->daddr.map;
l_map = left->mem_info->daddr.ms.map;
r_map = right->mem_info->daddr.ms.map;
/* if both are NULL, jump to sort on al_addr instead */
if (!l_map && !r_map)
@ -1264,14 +1258,14 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
{
uint64_t addr = 0;
struct map *map = NULL;
struct symbol *sym = NULL;
struct map_symbol *ms = NULL;
char level = he->level;
if (he->mem_info) {
struct map *map = he->mem_info->daddr.ms.map;
addr = cl_address(he->mem_info->daddr.al_addr);
map = he->mem_info->daddr.map;
sym = he->mem_info->daddr.sym;
ms = &he->mem_info->daddr.ms;
/* print [s] for shared data mmaps */
if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
@ -1283,8 +1277,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
else if (!map)
level = 'X';
}
return _hist_entry__sym_snprintf(map, sym, addr, level, bf, size,
width);
return _hist_entry__sym_snprintf(ms, addr, level, bf, size, width);
}
struct sort_entry sort_mispredict = {

View File

@ -934,7 +934,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
* we still are sure to have a reference to this DSO via
* *curr_map->dso.
*/
dsos__add(&map->groups->machine->dsos, curr_dso);
dsos__add(&kmaps->machine->dsos, curr_dso);
/* kmaps already got it */
map__put(curr_map);
dso__set_loaded(curr_dso);

View File

@ -1588,7 +1588,7 @@ int dso__load(struct dso *dso, struct map *map)
char *name;
int ret = -1;
u_int i;
struct machine *machine;
struct machine *machine = NULL;
char *root_dir = (char *) "";
int ss_pos = 0;
struct symsrc ss_[2];
@ -1617,17 +1617,13 @@ int dso__load(struct dso *dso, struct map *map)
goto out;
}
if (map->groups)
machine = map->groups->machine;
else
machine = NULL;
if (dso->kernel) {
if (dso->kernel == DSO_TYPE_KERNEL)
ret = dso__load_kernel_sym(dso, map);
else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
ret = dso__load_guest_kernel_sym(dso, map);
machine = map__kmaps(map)->machine;
if (machine__is(machine, "x86_64"))
machine__map_x86_64_entry_trampolines(machine, dso);
goto out;
@ -2027,15 +2023,9 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map)
{
int err;
const char *kallsyms_filename = NULL;
struct machine *machine;
struct machine *machine = map__kmaps(map)->machine;
char path[PATH_MAX];
if (!map->groups) {
pr_debug("Guest kernel map hasn't the point to groups\n");
return -1;
}
machine = map->groups->machine;
if (machine__is_default_guest(machine)) {
/*
* if the user specified a vmlinux filename, use it and only

View File

@ -107,8 +107,8 @@ struct ref_reloc_sym {
};
struct addr_location {
struct machine *machine;
struct thread *thread;
struct map_groups *mg;
struct map *map;
struct symbol *sym;
const char *srcline;

View File

@ -80,9 +80,10 @@ static int entry(u64 ip, struct unwind_info *ui)
if (__report_module(&al, ip, ui))
return -1;
e->ip = ip;
e->map = al.map;
e->sym = al.sym;
e->ip = ip;
e->ms.mg = al.mg;
e->ms.map = al.map;
e->ms.sym = al.sym;
pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
al.sym ? al.sym->name : "''",

View File

@ -575,9 +575,10 @@ static int entry(u64 ip, struct thread *thread,
struct unwind_entry e;
struct addr_location al;
e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
e.ip = ip;
e.map = al.map;
e.ms.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
e.ip = ip;
e.ms.map = al.map;
e.ms.mg = al.mg;
pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
al.sym ? al.sym->name : "''",

View File

@ -4,17 +4,15 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include "util/map_symbol.h"
struct map;
struct map_groups;
struct perf_sample;
struct symbol;
struct thread;
struct unwind_entry {
struct map *map;
struct symbol *sym;
u64 ip;
struct map_symbol ms;
u64 ip;
};
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);