mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 01:54:09 +08:00
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:
commit
b0aeb45bad
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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") ||
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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(¬es->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;
|
||||
}
|
||||
|
@ -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],
|
||||
|
@ -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)
|
||||
|
@ -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, ¬es->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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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, }
|
||||
};
|
||||
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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';
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -42,7 +42,6 @@ struct map {
|
||||
u64 (*unmap_ip)(struct map *, u64);
|
||||
|
||||
struct dso *dso;
|
||||
struct map_groups *groups;
|
||||
refcount_t refcnt;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, ...);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 : "''",
|
||||
|
@ -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 : "''",
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user