perf map: Add accessor for dso
Later changes will add reference count checking for struct map, with dso being the most frequently accessed variable. Add an accessor so that the reference count check is only necessary in one place. Additional changes: - add a dso variable to avoid repeated map__dso calls. - in builtin-mem.c dump_raw_samples, code only partially tested for dso == NULL. Make the possibility of NULL consistent. - in thread.c thread__memcpy fix use of spaces and use tabs. Committer notes: Did missing conversions on these files: tools/perf/arch/powerpc/util/skip-callchain-idx.c tools/perf/arch/powerpc/util/sym-handling.c tools/perf/ui/browsers/hists.c tools/perf/ui/gtk/annotate.c tools/perf/util/cs-etm.c tools/perf/util/thread.c tools/perf/util/unwind-libunwind-local.c tools/perf/util/unwind-libunwind.c Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Darren Hart <dvhart@infradead.org> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: German Gomez <german.gomez@arm.com> Cc: Hao Luo <haoluo@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Miaoqian Lin <linmq006@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Riccardo Mancini <rickyman7@gmail.com> Cc: Shunsuke Nakamura <nakamura.shun@fujitsu.com> Cc: Song Liu <song@kernel.org> Cc: Stephane Eranian <eranian@google.com> Cc: Stephen Brennan <stephen.s.brennan@oracle.com> Cc: Steven Rostedt (VMware) <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Yury Norov <yury.norov@gmail.com> Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
5ab6d715c3
commit
63df0e4bc3
|
@ -255,7 +255,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
|
||||||
thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
|
thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
|
||||||
|
|
||||||
if (al.map)
|
if (al.map)
|
||||||
dso = al.map->dso;
|
dso = map__dso(al.map);
|
||||||
|
|
||||||
if (!dso) {
|
if (!dso) {
|
||||||
pr_debug("%" PRIx64 " dso is NULL\n", ip);
|
pr_debug("%" PRIx64 " dso is NULL\n", ip);
|
||||||
|
|
|
@ -104,7 +104,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
|
||||||
|
|
||||||
lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
|
lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
|
||||||
|
|
||||||
if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
|
if (map__dso(map)->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
|
||||||
tev->point.offset += PPC64LE_LEP_OFFSET;
|
tev->point.offset += PPC64LE_LEP_OFFSET;
|
||||||
else if (lep_offset) {
|
else if (lep_offset) {
|
||||||
if (pev->uprobes)
|
if (pev->uprobes)
|
||||||
|
|
|
@ -205,7 +205,7 @@ static int process_branch_callback(struct evsel *evsel,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (a.map != NULL)
|
if (a.map != NULL)
|
||||||
a.map->dso->hit = 1;
|
map__dso(a.map)->hit = 1;
|
||||||
|
|
||||||
hist__account_cycles(sample->branch_stack, al, sample, false, NULL);
|
hist__account_cycles(sample->branch_stack, al, sample, false, NULL);
|
||||||
|
|
||||||
|
@ -235,10 +235,11 @@ static int evsel__add_sample(struct evsel *evsel, struct perf_sample *sample,
|
||||||
* the DSO?
|
* the DSO?
|
||||||
*/
|
*/
|
||||||
if (al->sym != NULL) {
|
if (al->sym != NULL) {
|
||||||
rb_erase_cached(&al->sym->rb_node,
|
struct dso *dso = map__dso(al->map);
|
||||||
&al->map->dso->symbols);
|
|
||||||
|
rb_erase_cached(&al->sym->rb_node, &dso->symbols);
|
||||||
symbol__delete(al->sym);
|
symbol__delete(al->sym);
|
||||||
dso__reset_find_symbol_cache(al->map->dso);
|
dso__reset_find_symbol_cache(dso);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +321,7 @@ static void hists__find_annotations(struct hists *hists,
|
||||||
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
|
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
struct annotation *notes;
|
struct annotation *notes;
|
||||||
|
|
||||||
if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
|
if (he->ms.sym == NULL || map__dso(he->ms.map)->annotate_warned)
|
||||||
goto find_next;
|
goto find_next;
|
||||||
|
|
||||||
if (ann->sym_hist_filter &&
|
if (ann->sym_hist_filter &&
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
static int buildid__map_cb(struct map *map, void *arg __maybe_unused)
|
static int buildid__map_cb(struct map *map, void *arg __maybe_unused)
|
||||||
{
|
{
|
||||||
const struct dso *dso = map->dso;
|
const struct dso *dso = map__dso(map);
|
||||||
char bid_buf[SBUILD_ID_SIZE];
|
char bid_buf[SBUILD_ID_SIZE];
|
||||||
|
|
||||||
memset(bid_buf, 0, sizeof(bid_buf));
|
memset(bid_buf, 0, sizeof(bid_buf));
|
||||||
|
|
|
@ -753,9 +753,11 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
|
if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
|
||||||
if (!al.map->dso->hit) {
|
struct dso *dso = map__dso(al.map);
|
||||||
al.map->dso->hit = 1;
|
|
||||||
dso__inject_build_id(al.map->dso, tool, machine,
|
if (!dso->hit) {
|
||||||
|
dso->hit = 1;
|
||||||
|
dso__inject_build_id(dso, tool, machine,
|
||||||
sample->cpumode, al.map->flags);
|
sample->cpumode, al.map->flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ static int __cmd_kallsyms(int argc, const char **argv)
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
const struct dso *dso;
|
||||||
struct symbol *symbol = machine__find_kernel_symbol_by_name(machine, argv[i], &map);
|
struct symbol *symbol = machine__find_kernel_symbol_by_name(machine, argv[i], &map);
|
||||||
|
|
||||||
if (symbol == NULL) {
|
if (symbol == NULL) {
|
||||||
|
@ -35,8 +36,9 @@ static int __cmd_kallsyms(int argc, const char **argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dso = map__dso(map);
|
||||||
printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n",
|
printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n",
|
||||||
symbol->name, map->dso->short_name, map->dso->long_name,
|
symbol->name, dso->short_name, dso->long_name,
|
||||||
map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end),
|
map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end),
|
||||||
symbol->start, symbol->end);
|
symbol->start, symbol->end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,7 @@ dump_raw_samples(struct perf_tool *tool,
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
const char *fmt, *field_sep;
|
const char *fmt, *field_sep;
|
||||||
char str[PAGE_SIZE_NAME_LEN];
|
char str[PAGE_SIZE_NAME_LEN];
|
||||||
|
struct dso *dso = NULL;
|
||||||
|
|
||||||
if (machine__resolve(machine, &al, sample) < 0) {
|
if (machine__resolve(machine, &al, sample) < 0) {
|
||||||
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
||||||
|
@ -210,8 +211,11 @@ dump_raw_samples(struct perf_tool *tool,
|
||||||
if (al.filtered || (mem->hide_unresolved && al.sym == NULL))
|
if (al.filtered || (mem->hide_unresolved && al.sym == NULL))
|
||||||
goto out_put;
|
goto out_put;
|
||||||
|
|
||||||
if (al.map != NULL)
|
if (al.map != NULL) {
|
||||||
al.map->dso->hit = 1;
|
dso = map__dso(al.map);
|
||||||
|
if (dso)
|
||||||
|
dso->hit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
field_sep = symbol_conf.field_sep;
|
field_sep = symbol_conf.field_sep;
|
||||||
if (field_sep) {
|
if (field_sep) {
|
||||||
|
@ -252,7 +256,7 @@ dump_raw_samples(struct perf_tool *tool,
|
||||||
symbol_conf.field_sep,
|
symbol_conf.field_sep,
|
||||||
sample->data_src,
|
sample->data_src,
|
||||||
symbol_conf.field_sep,
|
symbol_conf.field_sep,
|
||||||
al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
|
dso ? dso->long_name : "???",
|
||||||
al.sym ? al.sym->name : "???");
|
al.sym ? al.sym->name : "???");
|
||||||
out_put:
|
out_put:
|
||||||
addr_location__put(&al);
|
addr_location__put(&al);
|
||||||
|
|
|
@ -319,7 +319,7 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (al.map != NULL)
|
if (al.map != NULL)
|
||||||
al.map->dso->hit = 1;
|
map__dso(al.map)->hit = 1;
|
||||||
|
|
||||||
if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
|
if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
|
||||||
hist__account_cycles(sample->branch_stack, &al, sample,
|
hist__account_cycles(sample->branch_stack, &al, sample,
|
||||||
|
@ -608,7 +608,7 @@ static void report__warn_kptr_restrict(const struct report *rep)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (kernel_map == NULL ||
|
if (kernel_map == NULL ||
|
||||||
(kernel_map->dso->hit &&
|
(map__dso(kernel_map)->hit &&
|
||||||
(kernel_kmap->ref_reloc_sym == NULL ||
|
(kernel_kmap->ref_reloc_sym == NULL ||
|
||||||
kernel_kmap->ref_reloc_sym->addr == 0))) {
|
kernel_kmap->ref_reloc_sym->addr == 0))) {
|
||||||
const char *desc =
|
const char *desc =
|
||||||
|
@ -848,6 +848,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
|
||||||
|
|
||||||
maps__for_each_entry(maps, rb_node) {
|
maps__for_each_entry(maps, rb_node) {
|
||||||
struct map *map = rb_node->map;
|
struct map *map = rb_node->map;
|
||||||
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
|
printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
|
||||||
indent, "", map->start, map->end,
|
indent, "", map->start, map->end,
|
||||||
|
@ -856,7 +857,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
|
||||||
map->prot & PROT_EXEC ? 'x' : '-',
|
map->prot & PROT_EXEC ? 'x' : '-',
|
||||||
map->flags & MAP_SHARED ? 's' : 'p',
|
map->flags & MAP_SHARED ? 's' : 'p',
|
||||||
map->pgoff,
|
map->pgoff,
|
||||||
map->dso->id.ino, map->dso->name);
|
dso->id.ino, dso->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return printed;
|
return printed;
|
||||||
|
|
|
@ -1011,11 +1011,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
|
||||||
to = entries[i].to;
|
to = entries[i].to;
|
||||||
|
|
||||||
if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
|
if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
|
||||||
!alf.map->dso->adjust_symbols)
|
!map__dso(alf.map)->adjust_symbols)
|
||||||
from = map__map_ip(alf.map, from);
|
from = map__map_ip(alf.map, from);
|
||||||
|
|
||||||
if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
|
if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
|
||||||
!alt.map->dso->adjust_symbols)
|
!map__dso(alt.map)->adjust_symbols)
|
||||||
to = map__map_ip(alt.map, to);
|
to = map__map_ip(alt.map, to);
|
||||||
|
|
||||||
printed += fprintf(fp, " 0x%"PRIx64, from);
|
printed += fprintf(fp, " 0x%"PRIx64, from);
|
||||||
|
@ -1044,6 +1044,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
|
||||||
long offset, len;
|
long offset, len;
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
bool kernel;
|
bool kernel;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (!start || !end)
|
if (!start || !end)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1074,11 +1075,12 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
|
dso = map__dso(al.map);
|
||||||
|
if (!thread__find_map(thread, *cpumode, start, &al) || !dso) {
|
||||||
pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
|
pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
|
if (dso->data.status == DSO_DATA_STATUS_ERROR) {
|
||||||
pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
|
pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1087,10 +1089,10 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
|
||||||
map__load(al.map);
|
map__load(al.map);
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, start);
|
offset = al.map->map_ip(al.map, start);
|
||||||
len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer,
|
len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
|
||||||
end - start + MAXINSN);
|
end - start + MAXINSN);
|
||||||
|
|
||||||
*is64bit = al.map->dso->is_64_bit;
|
*is64bit = dso->is_64_bit;
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
|
pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
|
||||||
start, end);
|
start, end);
|
||||||
|
@ -1104,10 +1106,11 @@ static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srcc
|
||||||
unsigned line;
|
unsigned line;
|
||||||
int len;
|
int len;
|
||||||
char *srccode;
|
char *srccode;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
if (!map || !map->dso)
|
if (!map || !dso)
|
||||||
return 0;
|
return 0;
|
||||||
srcfile = get_srcline_split(map->dso,
|
srcfile = get_srcline_split(dso,
|
||||||
map__rip_2objdump(map, addr),
|
map__rip_2objdump(map, addr),
|
||||||
&line);
|
&line);
|
||||||
if (!srcfile)
|
if (!srcfile)
|
||||||
|
|
|
@ -114,6 +114,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct annotation *notes;
|
struct annotation *notes;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
|
|
||||||
if (!he || !he->ms.sym)
|
if (!he || !he->ms.sym)
|
||||||
|
@ -123,12 +124,12 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
|
||||||
|
|
||||||
sym = he->ms.sym;
|
sym = he->ms.sym;
|
||||||
map = he->ms.map;
|
map = he->ms.map;
|
||||||
|
dso = map__dso(map);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't annotate with just /proc/kallsyms
|
* We can't annotate with just /proc/kallsyms
|
||||||
*/
|
*/
|
||||||
if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
|
if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) {
|
||||||
!dso__is_kcore(map->dso)) {
|
|
||||||
pr_err("Can't annotate %s: No vmlinux file was found in the "
|
pr_err("Can't annotate %s: No vmlinux file was found in the "
|
||||||
"path\n", sym->name);
|
"path\n", sym->name);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
@ -169,6 +170,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
|
||||||
{
|
{
|
||||||
struct utsname uts;
|
struct utsname uts;
|
||||||
int err = uname(&uts);
|
int err = uname(&uts);
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
ui__warning("Out of bounds address found:\n\n"
|
ui__warning("Out of bounds address found:\n\n"
|
||||||
"Addr: %" PRIx64 "\n"
|
"Addr: %" PRIx64 "\n"
|
||||||
|
@ -180,7 +182,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
|
||||||
"Tools: %s\n\n"
|
"Tools: %s\n\n"
|
||||||
"Not all samples will be on the annotation output.\n\n"
|
"Not all samples will be on the annotation output.\n\n"
|
||||||
"Please report to linux-kernel@vger.kernel.org\n",
|
"Please report to linux-kernel@vger.kernel.org\n",
|
||||||
ip, map->dso->long_name, dso__symtab_origin(map->dso),
|
ip, dso->long_name, dso__symtab_origin(dso),
|
||||||
map->start, map->end, sym->start, sym->end,
|
map->start, map->end, sym->start, sym->end,
|
||||||
sym->binding == STB_GLOBAL ? 'g' :
|
sym->binding == STB_GLOBAL ? 'g' :
|
||||||
sym->binding == STB_LOCAL ? 'l' : 'w', sym->name,
|
sym->binding == STB_LOCAL ? 'l' : 'w', sym->name,
|
||||||
|
@ -810,7 +812,8 @@ static void perf_event__process_sample(struct perf_tool *tool,
|
||||||
__map__is_kernel(al.map) && map__has_symbols(al.map)) {
|
__map__is_kernel(al.map) && map__has_symbols(al.map)) {
|
||||||
if (symbol_conf.vmlinux_name) {
|
if (symbol_conf.vmlinux_name) {
|
||||||
char serr[256];
|
char serr[256];
|
||||||
dso__strerror_load(al.map->dso, serr, sizeof(serr));
|
|
||||||
|
dso__strerror_load(map__dso(al.map), serr, sizeof(serr));
|
||||||
ui__warning("The %s file can't be used: %s\n%s",
|
ui__warning("The %s file can't be used: %s\n%s",
|
||||||
symbol_conf.vmlinux_name, serr, msg);
|
symbol_conf.vmlinux_name, serr, msg);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2863,7 +2863,7 @@ static void print_location(FILE *f, struct perf_sample *sample,
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((verbose > 0 || print_dso) && al->map)
|
if ((verbose > 0 || print_dso) && al->map)
|
||||||
fprintf(f, "%s@", al->map->dso->long_name);
|
fprintf(f, "%s@", map__dso(al->map)->long_name);
|
||||||
|
|
||||||
if ((verbose > 0 || print_sym) && al->sym)
|
if ((verbose > 0 || print_sym) && al->sym)
|
||||||
fprintf(f, "%s+0x%" PRIx64, al->sym->name,
|
fprintf(f, "%s+0x%" PRIx64, al->sym->name,
|
||||||
|
|
|
@ -145,6 +145,7 @@ static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode
|
||||||
char *srccode = NULL;
|
char *srccode = NULL;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
u64 addr;
|
u64 addr;
|
||||||
|
|
||||||
|
@ -153,9 +154,10 @@ static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode
|
||||||
|
|
||||||
map = c->al->map;
|
map = c->al->map;
|
||||||
addr = c->al->addr;
|
addr = c->al->addr;
|
||||||
|
dso = map ? map__dso(map) : NULL;
|
||||||
|
|
||||||
if (map && map->dso)
|
if (dso)
|
||||||
srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line);
|
srcfile = get_srcline_split(dso, map__rip_2objdump(map, addr), &line);
|
||||||
|
|
||||||
if (get_srccode) {
|
if (get_srccode) {
|
||||||
if (srcfile)
|
if (srcfile)
|
||||||
|
|
|
@ -237,10 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
char decomp_name[KMOD_DECOMP_LEN];
|
char decomp_name[KMOD_DECOMP_LEN];
|
||||||
bool decomp = false;
|
bool decomp = false;
|
||||||
int ret, err = 0;
|
int ret, err = 0;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
|
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
|
||||||
|
|
||||||
if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) {
|
if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) {
|
||||||
if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
|
if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
|
||||||
pr_debug("Hypervisor address can not be resolved - skipping\n");
|
pr_debug("Hypervisor address can not be resolved - skipping\n");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -250,11 +251,10 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
dso = map__dso(al.map);
|
||||||
|
pr_debug("File is: %s\n", dso->long_name);
|
||||||
|
|
||||||
pr_debug("File is: %s\n", al.map->dso->long_name);
|
if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) {
|
||||||
|
|
||||||
if (al.map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
|
|
||||||
!dso__is_kcore(al.map->dso)) {
|
|
||||||
pr_debug("Unexpected kernel address - skipping\n");
|
pr_debug("Unexpected kernel address - skipping\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
len = al.map->end - addr;
|
len = al.map->end - addr;
|
||||||
|
|
||||||
/* Read the object code using perf */
|
/* Read the object code using perf */
|
||||||
ret_len = dso__data_read_offset(al.map->dso, maps__machine(thread->maps),
|
ret_len = dso__data_read_offset(dso, maps__machine(thread->maps),
|
||||||
al.addr, buf1, len);
|
al.addr, buf1, len);
|
||||||
if (ret_len != len) {
|
if (ret_len != len) {
|
||||||
pr_debug("dso__data_read_offset failed\n");
|
pr_debug("dso__data_read_offset failed\n");
|
||||||
|
@ -287,7 +287,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* objdump struggles with kcore - try each map only once */
|
/* objdump struggles with kcore - try each map only once */
|
||||||
if (dso__is_kcore(al.map->dso)) {
|
if (dso__is_kcore(dso)) {
|
||||||
size_t d;
|
size_t d;
|
||||||
|
|
||||||
for (d = 0; d < state->done_cnt; d++) {
|
for (d = 0; d < state->done_cnt; d++) {
|
||||||
|
@ -304,9 +304,9 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
state->done[state->done_cnt++] = al.map->start;
|
state->done[state->done_cnt++] = al.map->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
objdump_name = al.map->dso->long_name;
|
objdump_name = dso->long_name;
|
||||||
if (dso__needs_decompress(al.map->dso)) {
|
if (dso__needs_decompress(dso)) {
|
||||||
if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
|
if (dso__decompress_kmodule_path(dso, objdump_name,
|
||||||
decomp_name,
|
decomp_name,
|
||||||
sizeof(decomp_name)) < 0) {
|
sizeof(decomp_name)) < 0) {
|
||||||
pr_debug("decompression failed\n");
|
pr_debug("decompression failed\n");
|
||||||
|
@ -335,7 +335,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
|
||||||
len -= ret;
|
len -= ret;
|
||||||
if (len) {
|
if (len) {
|
||||||
pr_debug("Reducing len to %zu\n", len);
|
pr_debug("Reducing len to %zu\n", len);
|
||||||
} else if (dso__is_kcore(al.map->dso)) {
|
} else if (dso__is_kcore(dso)) {
|
||||||
/*
|
/*
|
||||||
* objdump cannot handle very large segments
|
* objdump cannot handle very large segments
|
||||||
* that may be found in kcore.
|
* that may be found in kcore.
|
||||||
|
@ -572,6 +572,7 @@ static int do_test_code_reading(bool try_kcore)
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
bool have_vmlinux, have_kcore, excl_kernel = false;
|
bool have_vmlinux, have_kcore, excl_kernel = false;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
|
|
||||||
|
@ -595,8 +596,9 @@ static int do_test_code_reading(bool try_kcore)
|
||||||
pr_debug("map__load failed\n");
|
pr_debug("map__load failed\n");
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
have_vmlinux = dso__is_vmlinux(map->dso);
|
dso = map__dso(map);
|
||||||
have_kcore = dso__is_kcore(map->dso);
|
have_vmlinux = dso__is_vmlinux(dso);
|
||||||
|
have_kcore = dso__is_kcore(dso);
|
||||||
|
|
||||||
/* 2nd time through we just try kcore */
|
/* 2nd time through we just try kcore */
|
||||||
if (try_kcore && !have_kcore)
|
if (try_kcore && !have_kcore)
|
||||||
|
|
|
@ -179,9 +179,11 @@ void print_hists_in(struct hists *hists)
|
||||||
he = rb_entry(node, struct hist_entry, rb_node_in);
|
he = rb_entry(node, struct hist_entry, rb_node_in);
|
||||||
|
|
||||||
if (!he->filtered) {
|
if (!he->filtered) {
|
||||||
|
struct dso *dso = map__dso(he->ms.map);
|
||||||
|
|
||||||
pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
|
pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
|
||||||
i, thread__comm_str(he->thread),
|
i, thread__comm_str(he->thread),
|
||||||
he->ms.map->dso->short_name,
|
dso->short_name,
|
||||||
he->ms.sym->name, he->stat.period);
|
he->ms.sym->name, he->stat.period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,9 +208,11 @@ void print_hists_out(struct hists *hists)
|
||||||
he = rb_entry(node, struct hist_entry, rb_node);
|
he = rb_entry(node, struct hist_entry, rb_node);
|
||||||
|
|
||||||
if (!he->filtered) {
|
if (!he->filtered) {
|
||||||
|
struct dso *dso = map__dso(he->ms.map);
|
||||||
|
|
||||||
pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n",
|
pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n",
|
||||||
i, thread__comm_str(he->thread), he->thread->tid,
|
i, thread__comm_str(he->thread), he->thread->tid,
|
||||||
he->ms.map->dso->short_name,
|
dso->short_name,
|
||||||
he->ms.sym->name, he->stat.period,
|
he->ms.sym->name, he->stat.period,
|
||||||
he->stat_acc ? he->stat_acc->period : 0);
|
he->stat_acc ? he->stat_acc->period : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,12 +150,12 @@ static void del_hist_entries(struct hists *hists)
|
||||||
typedef int (*test_fn_t)(struct evsel *, struct machine *);
|
typedef int (*test_fn_t)(struct evsel *, struct machine *);
|
||||||
|
|
||||||
#define COMM(he) (thread__comm_str(he->thread))
|
#define COMM(he) (thread__comm_str(he->thread))
|
||||||
#define DSO(he) (he->ms.map->dso->short_name)
|
#define DSO(he) (map__dso(he->ms.map)->short_name)
|
||||||
#define SYM(he) (he->ms.sym->name)
|
#define SYM(he) (he->ms.sym->name)
|
||||||
#define CPU(he) (he->cpu)
|
#define CPU(he) (he->cpu)
|
||||||
#define PID(he) (he->thread->tid)
|
#define PID(he) (he->thread->tid)
|
||||||
#define DEPTH(he) (he->callchain->max_depth)
|
#define DEPTH(he) (he->callchain->max_depth)
|
||||||
#define CDSO(cl) (cl->ms.map->dso->short_name)
|
#define CDSO(cl) (map__dso(cl->ms.map)->short_name)
|
||||||
#define CSYM(cl) (cl->ms.sym->name)
|
#define CSYM(cl) (cl->ms.sym->name)
|
||||||
|
|
||||||
struct result {
|
struct result {
|
||||||
|
|
|
@ -194,7 +194,7 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes
|
||||||
hists__filter_by_thread(hists);
|
hists__filter_by_thread(hists);
|
||||||
|
|
||||||
/* now applying dso filter for 'kernel' */
|
/* now applying dso filter for 'kernel' */
|
||||||
hists->dso_filter = fake_samples[0].map->dso;
|
hists->dso_filter = map__dso(fake_samples[0].map);
|
||||||
hists__filter_by_dso(hists);
|
hists__filter_by_dso(hists);
|
||||||
|
|
||||||
if (verbose > 2) {
|
if (verbose > 2) {
|
||||||
|
@ -288,7 +288,7 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes
|
||||||
|
|
||||||
/* now applying all filters at once. */
|
/* now applying all filters at once. */
|
||||||
hists->thread_filter = fake_samples[1].thread;
|
hists->thread_filter = fake_samples[1].thread;
|
||||||
hists->dso_filter = fake_samples[1].map->dso;
|
hists->dso_filter = map__dso(fake_samples[1].map);
|
||||||
hists__filter_by_thread(hists);
|
hists__filter_by_thread(hists);
|
||||||
hists__filter_by_dso(hists);
|
hists__filter_by_dso(hists);
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ static void del_hist_entries(struct hists *hists)
|
||||||
typedef int (*test_fn_t)(struct evsel *, struct machine *);
|
typedef int (*test_fn_t)(struct evsel *, struct machine *);
|
||||||
|
|
||||||
#define COMM(he) (thread__comm_str(he->thread))
|
#define COMM(he) (thread__comm_str(he->thread))
|
||||||
#define DSO(he) (he->ms.map->dso->short_name)
|
#define DSO(he) (map__dso(he->ms.map)->short_name)
|
||||||
#define SYM(he) (he->ms.sym->name)
|
#define SYM(he) (he->ms.sym->name)
|
||||||
#define CPU(he) (he->cpu)
|
#define CPU(he) (he->cpu)
|
||||||
#define PID(he) (he->thread->tid)
|
#define PID(he) (he->thread->tid)
|
||||||
|
|
|
@ -26,7 +26,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma
|
||||||
|
|
||||||
TEST_ASSERT_VAL("wrong map start", map->start == merged[i].start);
|
TEST_ASSERT_VAL("wrong map start", map->start == merged[i].start);
|
||||||
TEST_ASSERT_VAL("wrong map end", map->end == merged[i].end);
|
TEST_ASSERT_VAL("wrong map end", map->end == merged[i].end);
|
||||||
TEST_ASSERT_VAL("wrong map name", !strcmp(map->dso->name, merged[i].name));
|
TEST_ASSERT_VAL("wrong map name", !strcmp(map__dso(map)->name, merged[i].name));
|
||||||
TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) == 1);
|
TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) == 1);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -102,6 +102,7 @@ static int test_file(struct test_info *ti, char *filename)
|
||||||
{
|
{
|
||||||
struct map *map = NULL;
|
struct map *map = NULL;
|
||||||
int ret, nr;
|
int ret, nr;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
pr_debug("Testing %s\n", filename);
|
pr_debug("Testing %s\n", filename);
|
||||||
|
|
||||||
|
@ -109,7 +110,8 @@ static int test_file(struct test_info *ti, char *filename)
|
||||||
if (ret != TEST_OK)
|
if (ret != TEST_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
nr = dso__load(map->dso, map);
|
dso = map__dso(map);
|
||||||
|
nr = dso__load(dso, map);
|
||||||
if (nr < 0) {
|
if (nr < 0) {
|
||||||
pr_debug("dso__load() failed!\n");
|
pr_debug("dso__load() failed!\n");
|
||||||
ret = TEST_FAIL;
|
ret = TEST_FAIL;
|
||||||
|
@ -122,7 +124,7 @@ static int test_file(struct test_info *ti, char *filename)
|
||||||
goto out_put;
|
goto out_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = test_dso(map->dso);
|
ret = test_dso(dso);
|
||||||
out_put:
|
out_put:
|
||||||
map__put(map);
|
map__put(map);
|
||||||
|
|
||||||
|
|
|
@ -293,15 +293,16 @@ next_pair:
|
||||||
|
|
||||||
maps__for_each_entry(maps, rb_node) {
|
maps__for_each_entry(maps, rb_node) {
|
||||||
struct map *map = rb_node->map;
|
struct map *map = rb_node->map;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
/*
|
/*
|
||||||
* If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
|
* If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
|
||||||
* the kernel will have the path for the vmlinux file being used,
|
* the kernel will have the path for the vmlinux file being used,
|
||||||
* so use the short name, less descriptive but the same ("[kernel]" in
|
* so use the short name, less descriptive but the same ("[kernel]" in
|
||||||
* both cases.
|
* both cases.
|
||||||
*/
|
*/
|
||||||
struct map *pair = maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ?
|
struct map *pair = maps__find_by_name(kallsyms.kmaps, (dso->kernel ?
|
||||||
map->dso->short_name :
|
dso->short_name :
|
||||||
map->dso->name));
|
dso->name));
|
||||||
if (pair) {
|
if (pair) {
|
||||||
pair->priv = 1;
|
pair->priv = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -326,17 +327,19 @@ next_pair:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pair->start == mem_start) {
|
if (pair->start == mem_start) {
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
if (!header_printed) {
|
if (!header_printed) {
|
||||||
pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n");
|
pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n");
|
||||||
header_printed = true;
|
header_printed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
|
pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
|
||||||
map->start, map->end, map->pgoff, map->dso->name);
|
map->start, map->end, map->pgoff, dso->name);
|
||||||
if (mem_end != pair->end)
|
if (mem_end != pair->end)
|
||||||
pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64,
|
pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64,
|
||||||
pair->start, pair->end, pair->pgoff);
|
pair->start, pair->end, pair->pgoff);
|
||||||
pr_info(" %s\n", pair->dso->name);
|
pr_info(" %s\n", dso->name);
|
||||||
pair->priv = 1;
|
pair->priv = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,8 @@ static void ui_browser__init_asm_mode(struct ui_browser *browser)
|
||||||
static int sym_title(struct symbol *sym, struct map *map, char *title,
|
static int sym_title(struct symbol *sym, struct map *map, char *title,
|
||||||
size_t sz, int percent_type)
|
size_t sz, int percent_type)
|
||||||
{
|
{
|
||||||
return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, map->dso->long_name,
|
return snprintf(title, sz, "%s %s [Percent: %s]", sym->name,
|
||||||
|
map__dso(map)->long_name,
|
||||||
percent_type_str(percent_type));
|
percent_type_str(percent_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,20 +965,22 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||||
},
|
},
|
||||||
.opts = opts,
|
.opts = opts,
|
||||||
};
|
};
|
||||||
|
struct dso *dso;
|
||||||
int ret = -1, err;
|
int ret = -1, err;
|
||||||
int not_annotated = list_empty(¬es->src->source);
|
int not_annotated = list_empty(¬es->src->source);
|
||||||
|
|
||||||
if (sym == NULL)
|
if (sym == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ms->map->dso->annotate_warned)
|
dso = map__dso(ms->map);
|
||||||
|
if (dso->annotate_warned)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (not_annotated) {
|
if (not_annotated) {
|
||||||
err = symbol__annotate2(ms, evsel, opts, &browser.arch);
|
err = symbol__annotate2(ms, evsel, opts, &browser.arch);
|
||||||
if (err) {
|
if (err) {
|
||||||
char msg[BUFSIZ];
|
char msg[BUFSIZ];
|
||||||
ms->map->dso->annotate_warned = true;
|
dso->annotate_warned = true;
|
||||||
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
|
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
|
||||||
ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
|
ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
|
||||||
goto out_free_offsets;
|
goto out_free_offsets;
|
||||||
|
|
|
@ -2487,7 +2487,7 @@ static struct symbol *symbol__new_unresolved(u64 addr, struct map *map)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dso__insert_symbol(map->dso, sym);
|
dso__insert_symbol(map__dso(map), sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sym;
|
return sym;
|
||||||
|
@ -2499,7 +2499,9 @@ add_annotate_opt(struct hist_browser *browser __maybe_unused,
|
||||||
struct map_symbol *ms,
|
struct map_symbol *ms,
|
||||||
u64 addr)
|
u64 addr)
|
||||||
{
|
{
|
||||||
if (!ms->map || !ms->map->dso || ms->map->dso->annotate_warned)
|
struct dso *dso = map__dso(ms->map);
|
||||||
|
|
||||||
|
if (!ms->map || !dso || dso->annotate_warned)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!ms->sym)
|
if (!ms->sym)
|
||||||
|
@ -2589,9 +2591,10 @@ static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map
|
||||||
browser->hists->dso_filter = NULL;
|
browser->hists->dso_filter = NULL;
|
||||||
ui_helpline__pop();
|
ui_helpline__pop();
|
||||||
} else {
|
} else {
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"",
|
ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"",
|
||||||
__map__is_kernel(map) ? "the Kernel" : map->dso->short_name);
|
__map__is_kernel(map) ? "the Kernel" : dso->short_name);
|
||||||
browser->hists->dso_filter = map->dso;
|
browser->hists->dso_filter = dso;
|
||||||
perf_hpp__set_elide(HISTC_DSO, true);
|
perf_hpp__set_elide(HISTC_DSO, true);
|
||||||
pstack__push(browser->pstack, &browser->hists->dso_filter);
|
pstack__push(browser->pstack, &browser->hists->dso_filter);
|
||||||
}
|
}
|
||||||
|
@ -2616,7 +2619,7 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act,
|
||||||
|
|
||||||
if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)",
|
if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)",
|
||||||
browser->hists->dso_filter ? "out of" : "into",
|
browser->hists->dso_filter ? "out of" : "into",
|
||||||
__map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0)
|
__map__is_kernel(map) ? "the Kernel" : map__dso(map)->short_name) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
act->ms.map = map;
|
act->ms.map = map;
|
||||||
|
@ -3091,8 +3094,8 @@ do_hotkey: // key came straight from options ui__popup_menu()
|
||||||
|
|
||||||
if (!browser->selection ||
|
if (!browser->selection ||
|
||||||
!browser->selection->map ||
|
!browser->selection->map ||
|
||||||
!browser->selection->map->dso ||
|
!map__dso(browser->selection->map) ||
|
||||||
browser->selection->map->dso->annotate_warned) {
|
map__dso(browser->selection->map)->annotate_warned) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ static int map_browser__run(struct map_browser *browser)
|
||||||
{
|
{
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
if (ui_browser__show(&browser->b, browser->map->dso->long_name,
|
if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name,
|
||||||
"Press ESC to exit, %s / to search",
|
"Press ESC to exit, %s / to search",
|
||||||
verbose > 0 ? "" : "restart with -v to use") < 0)
|
verbose > 0 ? "" : "restart with -v to use") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -106,7 +106,7 @@ int map__browse(struct map *map)
|
||||||
{
|
{
|
||||||
struct map_browser mb = {
|
struct map_browser mb = {
|
||||||
.b = {
|
.b = {
|
||||||
.entries = &map->dso->symbols,
|
.entries = &map__dso(map)->symbols,
|
||||||
.refresh = ui_browser__rb_tree_refresh,
|
.refresh = ui_browser__rb_tree_refresh,
|
||||||
.seek = ui_browser__rb_tree_seek,
|
.seek = ui_browser__rb_tree_seek,
|
||||||
.write = map_browser__write,
|
.write = map_browser__write,
|
||||||
|
|
|
@ -165,6 +165,7 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||||
struct annotation_options *options,
|
struct annotation_options *options,
|
||||||
struct hist_browser_timer *hbt)
|
struct hist_browser_timer *hbt)
|
||||||
{
|
{
|
||||||
|
struct dso *dso = map__dso(ms->map);
|
||||||
struct symbol *sym = ms->sym;
|
struct symbol *sym = ms->sym;
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *notebook;
|
GtkWidget *notebook;
|
||||||
|
@ -172,13 +173,13 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||||
GtkWidget *tab_label;
|
GtkWidget *tab_label;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (ms->map->dso->annotate_warned)
|
if (dso->annotate_warned)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
err = symbol__annotate(ms, evsel, options, NULL);
|
err = symbol__annotate(ms, evsel, options, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
char msg[BUFSIZ];
|
char msg[BUFSIZ];
|
||||||
ms->map->dso->annotate_warned = true;
|
dso->annotate_warned = true;
|
||||||
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
|
symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
|
||||||
ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
|
ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1585,7 +1585,7 @@ static void delete_last_nop(struct symbol *sym)
|
||||||
|
|
||||||
int symbol__strerror_disassemble(struct map_symbol *ms, 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 = ms->map->dso;
|
struct dso *dso = map__dso(ms->map);
|
||||||
|
|
||||||
BUG_ON(buflen == 0);
|
BUG_ON(buflen == 0);
|
||||||
|
|
||||||
|
@ -1727,7 +1727,7 @@ static int symbol__disassemble_bpf(struct symbol *sym,
|
||||||
struct map *map = args->ms.map;
|
struct map *map = args->ms.map;
|
||||||
struct perf_bpil *info_linear;
|
struct perf_bpil *info_linear;
|
||||||
struct disassemble_info info;
|
struct disassemble_info info;
|
||||||
struct dso *dso = map->dso;
|
struct dso *dso = map__dso(map);
|
||||||
int pc = 0, count, sub_id;
|
int pc = 0, count, sub_id;
|
||||||
struct btf *btf = NULL;
|
struct btf *btf = NULL;
|
||||||
char tpath[PATH_MAX];
|
char tpath[PATH_MAX];
|
||||||
|
@ -1950,7 +1950,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
|
||||||
{
|
{
|
||||||
struct annotation_options *opts = args->options;
|
struct annotation_options *opts = args->options;
|
||||||
struct map *map = args->ms.map;
|
struct map *map = args->ms.map;
|
||||||
struct dso *dso = map->dso;
|
struct dso *dso = map__dso(map);
|
||||||
char *command;
|
char *command;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char symfs_filename[PATH_MAX];
|
char symfs_filename[PATH_MAX];
|
||||||
|
@ -2395,7 +2395,7 @@ int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel,
|
||||||
{
|
{
|
||||||
struct map *map = ms->map;
|
struct map *map = ms->map;
|
||||||
struct symbol *sym = ms->sym;
|
struct symbol *sym = ms->sym;
|
||||||
struct dso *dso = map->dso;
|
struct dso *dso = map__dso(map);
|
||||||
char *filename;
|
char *filename;
|
||||||
const char *d_filename;
|
const char *d_filename;
|
||||||
const char *evsel_name = evsel__name(evsel);
|
const char *evsel_name = evsel__name(evsel);
|
||||||
|
@ -2578,7 +2578,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel,
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "%s() %s\nEvent: %s\n\n",
|
fprintf(fp, "%s() %s\nEvent: %s\n\n",
|
||||||
ms->sym->name, ms->map->dso->long_name, ev_name);
|
ms->sym->name, map__dso(ms->map)->long_name, ev_name);
|
||||||
symbol__annotate_fprintf2(ms->sym, fp, opts);
|
symbol__annotate_fprintf2(ms->sym, fp, opts);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -2804,7 +2804,7 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
|
||||||
if (percent_max <= 0.5)
|
if (percent_max <= 0.5)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
al->path = get_srcline(map->dso, notes->start + al->offset, NULL,
|
al->path = get_srcline(map__dso(map), notes->start + al->offset, NULL,
|
||||||
false, true, notes->start + al->offset);
|
false, true, notes->start + al->offset);
|
||||||
insert_source_line(&tmp_root, al, opts);
|
insert_source_line(&tmp_root, al, opts);
|
||||||
}
|
}
|
||||||
|
@ -2823,7 +2823,7 @@ static void symbol__calc_lines(struct map_symbol *ms, struct rb_root *root,
|
||||||
int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel,
|
int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel,
|
||||||
struct annotation_options *opts)
|
struct annotation_options *opts)
|
||||||
{
|
{
|
||||||
struct dso *dso = ms->map->dso;
|
struct dso *dso = map__dso(ms->map);
|
||||||
struct symbol *sym = ms->sym;
|
struct symbol *sym = ms->sym;
|
||||||
struct rb_root source_line = RB_ROOT;
|
struct rb_root source_line = RB_ROOT;
|
||||||
struct hists *hists = evsel__hists(evsel);
|
struct hists *hists = evsel__hists(evsel);
|
||||||
|
@ -2859,7 +2859,7 @@ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel,
|
||||||
int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel,
|
int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel,
|
||||||
struct annotation_options *opts)
|
struct annotation_options *opts)
|
||||||
{
|
{
|
||||||
struct dso *dso = ms->map->dso;
|
struct dso *dso = map__dso(ms->map);
|
||||||
struct symbol *sym = ms->sym;
|
struct symbol *sym = ms->sym;
|
||||||
struct rb_root source_line = RB_ROOT;
|
struct rb_root source_line = RB_ROOT;
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -2560,7 +2560,7 @@ static struct dso *load_dso(const char *name)
|
||||||
if (map__load(map) < 0)
|
if (map__load(map) < 0)
|
||||||
pr_err("File '%s' not found or has no symbols.\n", name);
|
pr_err("File '%s' not found or has no symbols.\n", name);
|
||||||
|
|
||||||
dso = dso__get(map->dso);
|
dso = dso__get(map__dso(map));
|
||||||
|
|
||||||
map__put(map);
|
map__put(map);
|
||||||
|
|
||||||
|
|
|
@ -317,9 +317,9 @@ static int block_dso_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
|
||||||
struct block_fmt *block_fmt = container_of(fmt, struct block_fmt, fmt);
|
struct block_fmt *block_fmt = container_of(fmt, struct block_fmt, fmt);
|
||||||
struct map *map = he->ms.map;
|
struct map *map = he->ms.map;
|
||||||
|
|
||||||
if (map && map->dso) {
|
if (map && map__dso(map)) {
|
||||||
return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width,
|
return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width,
|
||||||
map->dso->short_name);
|
map__dso(map)->short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width,
|
return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width,
|
||||||
|
|
|
@ -57,10 +57,12 @@ static int machine__process_bpf_event_load(struct machine *machine,
|
||||||
struct map *map = maps__find(machine__kernel_maps(machine), addr);
|
struct map *map = maps__find(machine__kernel_maps(machine), addr);
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO;
|
struct dso *dso = map__dso(map);
|
||||||
map->dso->bpf_prog.id = id;
|
|
||||||
map->dso->bpf_prog.sub_id = i;
|
dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO;
|
||||||
map->dso->bpf_prog.env = env;
|
dso->bpf_prog.id = id;
|
||||||
|
dso->bpf_prog.sub_id = i;
|
||||||
|
dso->bpf_prog.env = env;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -59,7 +59,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread__find_map(thread, sample->cpumode, sample->ip, &al))
|
if (thread__find_map(thread, sample->cpumode, sample->ip, &al))
|
||||||
al.map->dso->hit = 1;
|
map__dso(al.map)->hit = 1;
|
||||||
|
|
||||||
thread__put(thread);
|
thread__put(thread);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -701,8 +701,8 @@ static enum match_result match_chain_strings(const char *left,
|
||||||
static enum match_result match_chain_dso_addresses(struct map *left_map, u64 left_ip,
|
static enum match_result match_chain_dso_addresses(struct map *left_map, u64 left_ip,
|
||||||
struct map *right_map, u64 right_ip)
|
struct map *right_map, u64 right_ip)
|
||||||
{
|
{
|
||||||
struct dso *left_dso = left_map ? left_map->dso : NULL;
|
struct dso *left_dso = left_map ? map__dso(left_map) : NULL;
|
||||||
struct dso *right_dso = right_map ? right_map->dso : NULL;
|
struct dso *right_dso = right_map ? map__dso(right_map) : NULL;
|
||||||
|
|
||||||
if (left_dso != right_dso)
|
if (left_dso != right_dso)
|
||||||
return left_dso < right_dso ? MATCH_LT : MATCH_GT;
|
return left_dso < right_dso ? MATCH_LT : MATCH_GT;
|
||||||
|
@ -1174,7 +1174,7 @@ char *callchain_list__sym_name(struct callchain_list *cl,
|
||||||
if (show_dso)
|
if (show_dso)
|
||||||
scnprintf(bf + printed, bfsize - printed, " %s",
|
scnprintf(bf + printed, bfsize - printed, " %s",
|
||||||
cl->ms.map ?
|
cl->ms.map ?
|
||||||
cl->ms.map->dso->short_name :
|
map__dso(cl->ms.map)->short_name :
|
||||||
"unknown");
|
"unknown");
|
||||||
|
|
||||||
return bf;
|
return bf;
|
||||||
|
|
|
@ -865,6 +865,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
struct machine *machine;
|
struct machine *machine;
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
|
struct dso *dso;
|
||||||
struct cs_etm_traceid_queue *tidq;
|
struct cs_etm_traceid_queue *tidq;
|
||||||
|
|
||||||
if (!etmq)
|
if (!etmq)
|
||||||
|
@ -883,27 +884,29 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
|
||||||
thread = etmq->etm->unknown_thread;
|
thread = etmq->etm->unknown_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thread__find_map(thread, cpumode, address, &al) || !al.map->dso)
|
dso = map__dso(al.map);
|
||||||
|
|
||||||
|
if (!thread__find_map(thread, cpumode, address, &al) || !dso)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
|
if (dso->data.status == DSO_DATA_STATUS_ERROR &&
|
||||||
dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE))
|
dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, address);
|
offset = al.map->map_ip(al.map, address);
|
||||||
|
|
||||||
map__load(al.map);
|
map__load(al.map);
|
||||||
|
|
||||||
len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
|
len = dso__data_read_offset(dso, machine, offset, buffer, size);
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n"
|
ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n"
|
||||||
" Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n");
|
" Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n");
|
||||||
if (!al.map->dso->auxtrace_warned) {
|
if (!dso->auxtrace_warned) {
|
||||||
pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
|
pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
|
||||||
address,
|
address,
|
||||||
al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
|
dso->long_name ? dso->long_name : "Unknown");
|
||||||
al.map->dso->auxtrace_warned = true;
|
dso->auxtrace_warned = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,15 +128,17 @@ static void output_sample_callchain_entry(struct perf_tool *tool,
|
||||||
output_json_key_format(out, false, 5, "ip", "\"0x%" PRIx64 "\"", ip);
|
output_json_key_format(out, false, 5, "ip", "\"0x%" PRIx64 "\"", ip);
|
||||||
|
|
||||||
if (al && al->sym && al->sym->namelen) {
|
if (al && al->sym && al->sym->namelen) {
|
||||||
|
struct dso *dso = al->map ? map__dso(al->map) : NULL;
|
||||||
|
|
||||||
fputc(',', out);
|
fputc(',', out);
|
||||||
output_json_key_string(out, false, 5, "symbol", al->sym->name);
|
output_json_key_string(out, false, 5, "symbol", al->sym->name);
|
||||||
|
|
||||||
if (al->map && al->map->dso) {
|
if (dso) {
|
||||||
const char *dso = al->map->dso->short_name;
|
const char *dso_name = dso->short_name;
|
||||||
|
|
||||||
if (dso && strlen(dso) > 0) {
|
if (dso_name && strlen(dso_name) > 0) {
|
||||||
fputc(',', out);
|
fputc(',', out);
|
||||||
output_json_key_string(out, false, 5, "dso", dso);
|
output_json_key_string(out, false, 5, "dso", dso_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (al->map) {
|
if (al->map) {
|
||||||
struct dso *dso = al->map->dso;
|
struct dso *dso = map__dso(al->map);
|
||||||
|
|
||||||
err = db_export__dso(dbe, dso, maps__machine(al->maps));
|
err = db_export__dso(dbe, dso, maps__machine(al->maps));
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -255,7 +255,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
|
||||||
al.addr = node->ip;
|
al.addr = node->ip;
|
||||||
|
|
||||||
if (al.map && !al.sym)
|
if (al.map && !al.sym)
|
||||||
al.sym = dso__find_symbol(al.map->dso, al.addr);
|
al.sym = dso__find_symbol(map__dso(al.map), al.addr);
|
||||||
|
|
||||||
db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
|
db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al)
|
||||||
|
|
||||||
d_al->size = sizeof(*d_al);
|
d_al->size = sizeof(*d_al);
|
||||||
if (al->map) {
|
if (al->map) {
|
||||||
struct dso *dso = al->map->dso;
|
struct dso *dso = map__dso(al->map);
|
||||||
|
|
||||||
if (symbol_conf.show_kernel_path && dso->long_name)
|
if (symbol_conf.show_kernel_path && dso->long_name)
|
||||||
d_al->dso = dso->long_name;
|
d_al->dso = dso->long_name;
|
||||||
|
@ -220,6 +220,7 @@ static const char *dlfilter__srcline(void *ctx, __u32 *line_no)
|
||||||
unsigned int line = 0;
|
unsigned int line = 0;
|
||||||
char *srcfile = NULL;
|
char *srcfile = NULL;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
u64 addr;
|
u64 addr;
|
||||||
|
|
||||||
if (!d->ctx_valid || !line_no)
|
if (!d->ctx_valid || !line_no)
|
||||||
|
@ -231,9 +232,10 @@ static const char *dlfilter__srcline(void *ctx, __u32 *line_no)
|
||||||
|
|
||||||
map = al->map;
|
map = al->map;
|
||||||
addr = al->addr;
|
addr = al->addr;
|
||||||
|
dso = map ? map__dso(map) : NULL;
|
||||||
|
|
||||||
if (map && map->dso)
|
if (dso)
|
||||||
srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line);
|
srcfile = get_srcline_split(dso, map__rip_2objdump(map, addr), &line);
|
||||||
|
|
||||||
*line_no = line;
|
*line_no = line;
|
||||||
return srcfile;
|
return srcfile;
|
||||||
|
@ -279,7 +281,7 @@ have_map:
|
||||||
offset = map->map_ip(map, ip);
|
offset = map->map_ip(map, ip);
|
||||||
if (ip + len >= map->end)
|
if (ip + len >= map->end)
|
||||||
len = map->end - ip;
|
len = map->end - ip;
|
||||||
return dso__data_read_offset(map->dso, d->machine, offset, buf, len);
|
return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct perf_dlfilter_fns perf_dlfilter_fns = {
|
static const struct perf_dlfilter_fns perf_dlfilter_fns = {
|
||||||
|
|
|
@ -685,6 +685,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
|
||||||
struct perf_sample *sample)
|
struct perf_sample *sample)
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (symbol_conf.guest_code && !machine__is_host(machine))
|
if (symbol_conf.guest_code && !machine__is_host(machine))
|
||||||
thread = machine__findnew_guest_code(machine, sample->pid);
|
thread = machine__findnew_guest_code(machine, sample->pid);
|
||||||
|
@ -695,9 +696,11 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
|
||||||
|
|
||||||
dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
|
dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
|
||||||
thread__find_map(thread, sample->cpumode, sample->ip, al);
|
thread__find_map(thread, sample->cpumode, sample->ip, al);
|
||||||
|
dso = al->map ? map__dso(al->map) : NULL;
|
||||||
dump_printf(" ...... dso: %s\n",
|
dump_printf(" ...... dso: %s\n",
|
||||||
al->map ? al->map->dso->long_name :
|
dso
|
||||||
al->level == 'H' ? "[hypervisor]" : "<not found>");
|
? dso->long_name
|
||||||
|
: (al->level == 'H' ? "[hypervisor]" : "<not found>"));
|
||||||
|
|
||||||
if (thread__is_filtered(thread))
|
if (thread__is_filtered(thread))
|
||||||
al->filtered |= (1 << HIST_FILTER__THREAD);
|
al->filtered |= (1 << HIST_FILTER__THREAD);
|
||||||
|
@ -715,8 +718,6 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (al->map) {
|
if (al->map) {
|
||||||
struct dso *dso = al->map->dso;
|
|
||||||
|
|
||||||
if (symbol_conf.dso_list &&
|
if (symbol_conf.dso_list &&
|
||||||
(!dso || !(strlist__has_entry(symbol_conf.dso_list,
|
(!dso || !(strlist__has_entry(symbol_conf.dso_list,
|
||||||
dso->short_name) ||
|
dso->short_name) ||
|
||||||
|
|
|
@ -155,7 +155,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
|
||||||
|
|
||||||
if (print_ip) {
|
if (print_ip) {
|
||||||
/* Show binary offset for userspace addr */
|
/* Show binary offset for userspace addr */
|
||||||
if (map && !map->dso->kernel)
|
if (map && !map__dso(map)->kernel)
|
||||||
printed += fprintf(fp, "%c%16" PRIx64, s, addr);
|
printed += fprintf(fp, "%c%16" PRIx64, s, addr);
|
||||||
else
|
else
|
||||||
printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
|
printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
|
||||||
|
|
|
@ -106,7 +106,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||||
hists__set_col_len(hists, HISTC_THREAD, len + 8);
|
hists__set_col_len(hists, HISTC_THREAD, len + 8);
|
||||||
|
|
||||||
if (h->ms.map) {
|
if (h->ms.map) {
|
||||||
len = dso__name_len(h->ms.map->dso);
|
len = dso__name_len(map__dso(h->ms.map));
|
||||||
hists__new_col_len(hists, HISTC_DSO, len);
|
hists__new_col_len(hists, HISTC_DSO, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||||
symlen += BITS_PER_LONG / 4 + 2 + 3;
|
symlen += BITS_PER_LONG / 4 + 2 + 3;
|
||||||
hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
|
hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
|
||||||
|
|
||||||
symlen = dso__name_len(h->branch_info->from.ms.map->dso);
|
symlen = dso__name_len(map__dso(h->branch_info->from.ms.map));
|
||||||
hists__new_col_len(hists, HISTC_DSO_FROM, symlen);
|
hists__new_col_len(hists, HISTC_DSO_FROM, symlen);
|
||||||
} else {
|
} else {
|
||||||
symlen = unresolved_col_width + 4 + 2;
|
symlen = unresolved_col_width + 4 + 2;
|
||||||
|
@ -135,7 +135,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||||
symlen += BITS_PER_LONG / 4 + 2 + 3;
|
symlen += BITS_PER_LONG / 4 + 2 + 3;
|
||||||
hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
|
hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
|
||||||
|
|
||||||
symlen = dso__name_len(h->branch_info->to.ms.map->dso);
|
symlen = dso__name_len(map__dso(h->branch_info->to.ms.map));
|
||||||
hists__new_col_len(hists, HISTC_DSO_TO, symlen);
|
hists__new_col_len(hists, HISTC_DSO_TO, symlen);
|
||||||
} else {
|
} else {
|
||||||
symlen = unresolved_col_width + 4 + 2;
|
symlen = unresolved_col_width + 4 + 2;
|
||||||
|
@ -180,7 +180,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->mem_info->daddr.ms.map) {
|
if (h->mem_info->daddr.ms.map) {
|
||||||
symlen = dso__name_len(h->mem_info->daddr.ms.map->dso);
|
symlen = dso__name_len(map__dso(h->mem_info->daddr.ms.map));
|
||||||
hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
|
hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
|
||||||
symlen);
|
symlen);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2110,7 +2110,7 @@ static bool hists__filter_entry_by_dso(struct hists *hists,
|
||||||
struct hist_entry *he)
|
struct hist_entry *he)
|
||||||
{
|
{
|
||||||
if (hists->dso_filter != NULL &&
|
if (hists->dso_filter != NULL &&
|
||||||
(he->ms.map == NULL || he->ms.map->dso != hists->dso_filter)) {
|
(he->ms.map == NULL || map__dso(he->ms.map) != hists->dso_filter)) {
|
||||||
he->filtered |= (1 << HIST_FILTER__DSO);
|
he->filtered |= (1 << HIST_FILTER__DSO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -801,17 +801,19 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!thread__find_map(thread, cpumode, *ip, &al) || !al.map->dso) {
|
struct dso *dso;
|
||||||
|
|
||||||
|
if (!thread__find_map(thread, cpumode, *ip, &al) || !map__dso(al.map)) {
|
||||||
if (al.map)
|
if (al.map)
|
||||||
intel_pt_log("ERROR: thread has no dso for %#" PRIx64 "\n", *ip);
|
intel_pt_log("ERROR: thread has no dso for %#" PRIx64 "\n", *ip);
|
||||||
else
|
else
|
||||||
intel_pt_log("ERROR: thread has no map for %#" PRIx64 "\n", *ip);
|
intel_pt_log("ERROR: thread has no map for %#" PRIx64 "\n", *ip);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
dso = map__dso(al.map);
|
||||||
|
|
||||||
if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
|
if (dso->data.status == DSO_DATA_STATUS_ERROR &&
|
||||||
dso__data_status_seen(al.map->dso,
|
dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE))
|
||||||
DSO_DATA_STATUS_SEEN_ITRACE))
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, *ip);
|
offset = al.map->map_ip(al.map, *ip);
|
||||||
|
@ -819,7 +821,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
|
||||||
if (!to_ip && one_map) {
|
if (!to_ip && one_map) {
|
||||||
struct intel_pt_cache_entry *e;
|
struct intel_pt_cache_entry *e;
|
||||||
|
|
||||||
e = intel_pt_cache_lookup(al.map->dso, machine, offset);
|
e = intel_pt_cache_lookup(dso, machine, offset);
|
||||||
if (e &&
|
if (e &&
|
||||||
(!max_insn_cnt || e->insn_cnt <= max_insn_cnt)) {
|
(!max_insn_cnt || e->insn_cnt <= max_insn_cnt)) {
|
||||||
*insn_cnt_ptr = e->insn_cnt;
|
*insn_cnt_ptr = e->insn_cnt;
|
||||||
|
@ -829,8 +831,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
|
||||||
intel_pt_insn->emulated_ptwrite = e->emulated_ptwrite;
|
intel_pt_insn->emulated_ptwrite = e->emulated_ptwrite;
|
||||||
intel_pt_insn->length = e->length;
|
intel_pt_insn->length = e->length;
|
||||||
intel_pt_insn->rel = e->rel;
|
intel_pt_insn->rel = e->rel;
|
||||||
memcpy(intel_pt_insn->buf, e->insn,
|
memcpy(intel_pt_insn->buf, e->insn, INTEL_PT_INSN_BUF_SZ);
|
||||||
INTEL_PT_INSN_BUF_SZ);
|
|
||||||
intel_pt_log_insn_no_data(intel_pt_insn, *ip);
|
intel_pt_log_insn_no_data(intel_pt_insn, *ip);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -842,17 +843,17 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
|
||||||
/* Load maps to ensure dso->is_64_bit has been updated */
|
/* Load maps to ensure dso->is_64_bit has been updated */
|
||||||
map__load(al.map);
|
map__load(al.map);
|
||||||
|
|
||||||
x86_64 = al.map->dso->is_64_bit;
|
x86_64 = dso->is_64_bit;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
len = dso__data_read_offset(al.map->dso, machine,
|
len = dso__data_read_offset(dso, machine,
|
||||||
offset, buf,
|
offset, buf,
|
||||||
INTEL_PT_INSN_BUF_SZ);
|
INTEL_PT_INSN_BUF_SZ);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
intel_pt_log("ERROR: failed to read at offset %#" PRIx64 " ",
|
intel_pt_log("ERROR: failed to read at offset %#" PRIx64 " ",
|
||||||
offset);
|
offset);
|
||||||
if (intel_pt_enable_logging)
|
if (intel_pt_enable_logging)
|
||||||
dso__fprintf(al.map->dso, intel_pt_log_fp());
|
dso__fprintf(dso, intel_pt_log_fp());
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -871,7 +872,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
|
||||||
goto out;
|
goto out;
|
||||||
/* Check for emulated ptwrite */
|
/* Check for emulated ptwrite */
|
||||||
offs = offset + intel_pt_insn->length;
|
offs = offset + intel_pt_insn->length;
|
||||||
eptw = intel_pt_emulated_ptwrite(al.map->dso, machine, offs);
|
eptw = intel_pt_emulated_ptwrite(dso, machine, offs);
|
||||||
intel_pt_insn->emulated_ptwrite = eptw;
|
intel_pt_insn->emulated_ptwrite = eptw;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -906,13 +907,13 @@ out:
|
||||||
if (to_ip) {
|
if (to_ip) {
|
||||||
struct intel_pt_cache_entry *e;
|
struct intel_pt_cache_entry *e;
|
||||||
|
|
||||||
e = intel_pt_cache_lookup(al.map->dso, machine, start_offset);
|
e = intel_pt_cache_lookup(map__dso(al.map), machine, start_offset);
|
||||||
if (e)
|
if (e)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore cache errors */
|
/* Ignore cache errors */
|
||||||
intel_pt_cache_add(al.map->dso, machine, start_offset, insn_cnt,
|
intel_pt_cache_add(map__dso(al.map), machine, start_offset, insn_cnt,
|
||||||
*ip - start_ip, intel_pt_insn);
|
*ip - start_ip, intel_pt_insn);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -983,13 +984,12 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data)
|
||||||
if (!thread)
|
if (!thread)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso)
|
if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, ip);
|
offset = al.map->map_ip(al.map, ip);
|
||||||
|
|
||||||
return intel_pt_match_pgd_ip(ptq->pt, ip, offset,
|
return intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_name);
|
||||||
al.map->dso->long_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intel_pt_pgd_ip(uint64_t ip, void *data)
|
static bool intel_pt_pgd_ip(uint64_t ip, void *data)
|
||||||
|
@ -2744,7 +2744,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
|
||||||
if (map__load(map))
|
if (map__load(map))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
start = dso__first_symbol(map->dso);
|
start = dso__first_symbol(map__dso(map));
|
||||||
|
|
||||||
for (sym = start; sym; sym = dso__next_symbol(sym)) {
|
for (sym = start; sym; sym = dso__next_symbol(sym)) {
|
||||||
if (sym->binding == STB_GLOBAL &&
|
if (sym->binding == STB_GLOBAL &&
|
||||||
|
@ -3381,18 +3381,21 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (; cnt; cnt--, addr--) {
|
for (; cnt; cnt--, addr--) {
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (intel_pt_find_map(thread, cpumode, addr, &al)) {
|
if (intel_pt_find_map(thread, cpumode, addr, &al)) {
|
||||||
if (addr < event->text_poke.addr)
|
if (addr < event->text_poke.addr)
|
||||||
return 0;
|
return 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!al.map->dso || !al.map->dso->auxtrace_cache)
|
dso = map__dso(al.map);
|
||||||
|
if (!dso || !dso->auxtrace_cache)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, addr);
|
offset = al.map->map_ip(al.map, addr);
|
||||||
|
|
||||||
e = intel_pt_cache_lookup(al.map->dso, machine, offset);
|
e = intel_pt_cache_lookup(dso, machine, offset);
|
||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -3405,9 +3408,9 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
|
||||||
if (e->branch != INTEL_PT_BR_NO_BRANCH)
|
if (e->branch != INTEL_PT_BR_NO_BRANCH)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
intel_pt_cache_invalidate(al.map->dso, machine, offset);
|
intel_pt_cache_invalidate(dso, machine, offset);
|
||||||
intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n",
|
intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n",
|
||||||
al.map->dso->long_name, addr);
|
dso->long_name, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
|
||||||
|
|
||||||
static struct dso *machine__kernel_dso(struct machine *machine)
|
static struct dso *machine__kernel_dso(struct machine *machine)
|
||||||
{
|
{
|
||||||
return machine->vmlinux_map->dso;
|
return map__dso(machine->vmlinux_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dsos__init(struct dsos *dsos)
|
static void dsos__init(struct dsos *dsos)
|
||||||
|
@ -879,12 +879,13 @@ static int machine__process_ksymbol_register(struct machine *machine,
|
||||||
struct perf_sample *sample __maybe_unused)
|
struct perf_sample *sample __maybe_unused)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
struct dso *dso;
|
||||||
struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
|
struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
|
||||||
|
|
||||||
if (!map) {
|
if (!map) {
|
||||||
struct dso *dso = dso__new(event->ksymbol.name);
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
dso = dso__new(event->ksymbol.name);
|
||||||
if (dso) {
|
if (dso) {
|
||||||
dso->kernel = DSO_SPACE__KERNEL;
|
dso->kernel = DSO_SPACE__KERNEL;
|
||||||
map = map__new2(0, dso);
|
map = map__new2(0, dso);
|
||||||
|
@ -896,9 +897,9 @@ static int machine__process_ksymbol_register(struct machine *machine,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) {
|
if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) {
|
||||||
map->dso->binary_type = DSO_BINARY_TYPE__OOL;
|
dso->binary_type = DSO_BINARY_TYPE__OOL;
|
||||||
map->dso->data.file_size = event->ksymbol.len;
|
dso->data.file_size = event->ksymbol.len;
|
||||||
dso__set_loaded(map->dso);
|
dso__set_loaded(dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
map->start = event->ksymbol.addr;
|
map->start = event->ksymbol.addr;
|
||||||
|
@ -914,6 +915,8 @@ static int machine__process_ksymbol_register(struct machine *machine,
|
||||||
dso->binary_type = DSO_BINARY_TYPE__BPF_IMAGE;
|
dso->binary_type = DSO_BINARY_TYPE__BPF_IMAGE;
|
||||||
dso__set_long_name(dso, "", false);
|
dso__set_long_name(dso, "", false);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dso = map__dso(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
sym = symbol__new(map->map_ip(map, map->start),
|
sym = symbol__new(map->map_ip(map, map->start),
|
||||||
|
@ -921,7 +924,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
|
||||||
0, 0, event->ksymbol.name);
|
0, 0, event->ksymbol.name);
|
||||||
if (!sym)
|
if (!sym)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
dso__insert_symbol(map->dso, sym);
|
dso__insert_symbol(dso, sym);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,9 +942,11 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
|
||||||
if (map != machine->vmlinux_map)
|
if (map != machine->vmlinux_map)
|
||||||
maps__remove(machine__kernel_maps(machine), map);
|
maps__remove(machine__kernel_maps(machine), map);
|
||||||
else {
|
else {
|
||||||
sym = dso__find_symbol(map->dso, map->map_ip(map, map->start));
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
|
sym = dso__find_symbol(dso, map->map_ip(map, map->start));
|
||||||
if (sym)
|
if (sym)
|
||||||
dso__delete_symbol(map->dso, sym);
|
dso__delete_symbol(dso, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -965,6 +970,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event,
|
||||||
{
|
{
|
||||||
struct map *map = maps__find(machine__kernel_maps(machine), event->text_poke.addr);
|
struct map *map = maps__find(machine__kernel_maps(machine), event->text_poke.addr);
|
||||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
||||||
|
struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
|
|
||||||
if (dump_trace)
|
if (dump_trace)
|
||||||
perf_event__fprintf_text_poke(event, machine, stdout);
|
perf_event__fprintf_text_poke(event, machine, stdout);
|
||||||
|
@ -977,7 +983,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map && map->dso) {
|
if (dso) {
|
||||||
u8 *new_bytes = event->text_poke.bytes + event->text_poke.old_len;
|
u8 *new_bytes = event->text_poke.bytes + event->text_poke.old_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -986,7 +992,7 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event,
|
||||||
* must be done prior to using kernel maps.
|
* must be done prior to using kernel maps.
|
||||||
*/
|
*/
|
||||||
map__load(map);
|
map__load(map);
|
||||||
ret = dso__data_write_cache_addr(map->dso, map, machine,
|
ret = dso__data_write_cache_addr(dso, map, machine,
|
||||||
event->text_poke.addr,
|
event->text_poke.addr,
|
||||||
new_bytes,
|
new_bytes,
|
||||||
event->text_poke.new_len);
|
event->text_poke.new_len);
|
||||||
|
@ -1422,10 +1428,11 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid)
|
||||||
int machine__load_kallsyms(struct machine *machine, const char *filename)
|
int machine__load_kallsyms(struct machine *machine, const char *filename)
|
||||||
{
|
{
|
||||||
struct map *map = machine__kernel_map(machine);
|
struct map *map = machine__kernel_map(machine);
|
||||||
int ret = __dso__load_kallsyms(map->dso, filename, map, true);
|
struct dso *dso = map__dso(map);
|
||||||
|
int ret = __dso__load_kallsyms(dso, filename, map, true);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
dso__set_loaded(map->dso);
|
dso__set_loaded(dso);
|
||||||
/*
|
/*
|
||||||
* Since /proc/kallsyms will have multiple sessions for the
|
* Since /proc/kallsyms will have multiple sessions for the
|
||||||
* kernel, with modules between them, fixup the end of all
|
* kernel, with modules between them, fixup the end of all
|
||||||
|
@ -1440,10 +1447,11 @@ int machine__load_kallsyms(struct machine *machine, const char *filename)
|
||||||
int machine__load_vmlinux_path(struct machine *machine)
|
int machine__load_vmlinux_path(struct machine *machine)
|
||||||
{
|
{
|
||||||
struct map *map = machine__kernel_map(machine);
|
struct map *map = machine__kernel_map(machine);
|
||||||
int ret = dso__load_vmlinux_path(map->dso, map);
|
struct dso *dso = map__dso(map);
|
||||||
|
int ret = dso__load_vmlinux_path(dso, map);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
dso__set_loaded(map->dso);
|
dso__set_loaded(dso);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1485,6 +1493,7 @@ static bool is_kmod_dso(struct dso *dso)
|
||||||
static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m)
|
static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m)
|
||||||
{
|
{
|
||||||
char *long_name;
|
char *long_name;
|
||||||
|
struct dso *dso;
|
||||||
struct map *map = maps__find_by_name(maps, m->name);
|
struct map *map = maps__find_by_name(maps, m->name);
|
||||||
|
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
|
@ -1494,16 +1503,17 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo
|
||||||
if (long_name == NULL)
|
if (long_name == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dso__set_long_name(map->dso, long_name, true);
|
dso = map__dso(map);
|
||||||
dso__kernel_module_get_build_id(map->dso, "");
|
dso__set_long_name(dso, long_name, true);
|
||||||
|
dso__kernel_module_get_build_id(dso, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Full name could reveal us kmod compression, so
|
* Full name could reveal us kmod compression, so
|
||||||
* we need to update the symtab_type if needed.
|
* we need to update the symtab_type if needed.
|
||||||
*/
|
*/
|
||||||
if (m->comp && is_kmod_dso(map->dso)) {
|
if (m->comp && is_kmod_dso(dso)) {
|
||||||
map->dso->symtab_type++;
|
dso->symtab_type++;
|
||||||
map->dso->comp = m->comp;
|
dso->comp = m->comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1602,7 +1612,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
|
||||||
return -1;
|
return -1;
|
||||||
map->end = start + size;
|
map->end = start + size;
|
||||||
|
|
||||||
dso__kernel_module_get_build_id(map->dso, machine->root_dir);
|
dso__kernel_module_get_build_id(map__dso(map), machine->root_dir);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1788,7 +1798,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
|
||||||
map->end = map->start + xm->end - xm->start;
|
map->end = map->start + xm->end - xm->start;
|
||||||
|
|
||||||
if (build_id__is_defined(bid))
|
if (build_id__is_defined(bid))
|
||||||
dso__set_build_id(map->dso, bid);
|
dso__set_build_id(map__dso(map), bid);
|
||||||
|
|
||||||
} else if (is_kernel_mmap) {
|
} else if (is_kernel_mmap) {
|
||||||
const char *symbol_name = xm->name + strlen(mmap_name);
|
const char *symbol_name = xm->name + strlen(mmap_name);
|
||||||
|
@ -2248,18 +2258,20 @@ static char *callchain_srcline(struct map_symbol *ms, u64 ip)
|
||||||
{
|
{
|
||||||
struct map *map = ms->map;
|
struct map *map = ms->map;
|
||||||
char *srcline = NULL;
|
char *srcline = NULL;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (!map || callchain_param.key == CCKEY_FUNCTION)
|
if (!map || callchain_param.key == CCKEY_FUNCTION)
|
||||||
return srcline;
|
return srcline;
|
||||||
|
|
||||||
srcline = srcline__tree_find(&map->dso->srclines, ip);
|
dso = map__dso(map);
|
||||||
|
srcline = srcline__tree_find(&dso->srclines, ip);
|
||||||
if (!srcline) {
|
if (!srcline) {
|
||||||
bool show_sym = false;
|
bool show_sym = false;
|
||||||
bool show_addr = callchain_param.key == CCKEY_ADDRESS;
|
bool show_addr = callchain_param.key == CCKEY_ADDRESS;
|
||||||
|
|
||||||
srcline = get_srcline(map->dso, map__rip_2objdump(map, ip),
|
srcline = get_srcline(dso, map__rip_2objdump(map, ip),
|
||||||
ms->sym, show_sym, show_addr, ip);
|
ms->sym, show_sym, show_addr, ip);
|
||||||
srcline__tree_insert(&map->dso->srclines, ip, srcline);
|
srcline__tree_insert(&dso->srclines, ip, srcline);
|
||||||
}
|
}
|
||||||
|
|
||||||
return srcline;
|
return srcline;
|
||||||
|
@ -3039,6 +3051,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
|
||||||
struct map *map = ms->map;
|
struct map *map = ms->map;
|
||||||
struct inline_node *inline_node;
|
struct inline_node *inline_node;
|
||||||
struct inline_list *ilist;
|
struct inline_list *ilist;
|
||||||
|
struct dso *dso;
|
||||||
u64 addr;
|
u64 addr;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
|
@ -3047,13 +3060,14 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
|
||||||
|
|
||||||
addr = map__map_ip(map, ip);
|
addr = map__map_ip(map, ip);
|
||||||
addr = map__rip_2objdump(map, addr);
|
addr = map__rip_2objdump(map, addr);
|
||||||
|
dso = map__dso(map);
|
||||||
|
|
||||||
inline_node = inlines__tree_find(&map->dso->inlined_nodes, addr);
|
inline_node = inlines__tree_find(&dso->inlined_nodes, addr);
|
||||||
if (!inline_node) {
|
if (!inline_node) {
|
||||||
inline_node = dso__parse_addr_inlines(map->dso, addr, sym);
|
inline_node = dso__parse_addr_inlines(dso, addr, sym);
|
||||||
if (!inline_node)
|
if (!inline_node)
|
||||||
return ret;
|
return ret;
|
||||||
inlines__tree_insert(&map->dso->inlined_nodes, inline_node);
|
inlines__tree_insert(&dso->inlined_nodes, inline_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(ilist, &inline_node->val, list) {
|
list_for_each_entry(ilist, &inline_node->val, list) {
|
||||||
|
@ -3330,7 +3344,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
|
||||||
if (sym == NULL)
|
if (sym == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*modp = __map__is_kmodule(map) ? (char *)map->dso->short_name : NULL;
|
*modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL;
|
||||||
*addrp = map->unmap_ip(map, sym->start);
|
*addrp = map->unmap_ip(map, sym->start);
|
||||||
return sym->name;
|
return sym->name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso)
|
||||||
|
|
||||||
bool __map__is_kernel(const struct map *map)
|
bool __map__is_kernel(const struct map *map)
|
||||||
{
|
{
|
||||||
if (!map->dso->kernel)
|
if (!map__dso(map)->kernel)
|
||||||
return false;
|
return false;
|
||||||
return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) == map;
|
return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) == map;
|
||||||
}
|
}
|
||||||
|
@ -247,8 +247,9 @@ bool __map__is_extra_kernel_map(const struct map *map)
|
||||||
bool __map__is_bpf_prog(const struct map *map)
|
bool __map__is_bpf_prog(const struct map *map)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
|
if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -256,15 +257,16 @@ bool __map__is_bpf_prog(const struct map *map)
|
||||||
* type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can
|
* type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can
|
||||||
* guess the type based on name.
|
* guess the type based on name.
|
||||||
*/
|
*/
|
||||||
name = map->dso->short_name;
|
name = dso->short_name;
|
||||||
return name && (strstr(name, "bpf_prog_") == name);
|
return name && (strstr(name, "bpf_prog_") == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __map__is_bpf_image(const struct map *map)
|
bool __map__is_bpf_image(const struct map *map)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE)
|
if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -272,18 +274,20 @@ bool __map__is_bpf_image(const struct map *map)
|
||||||
* type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can
|
* type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can
|
||||||
* guess the type based on name.
|
* guess the type based on name.
|
||||||
*/
|
*/
|
||||||
name = map->dso->short_name;
|
name = dso->short_name;
|
||||||
return name && is_bpf_image(name);
|
return name && is_bpf_image(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __map__is_ool(const struct map *map)
|
bool __map__is_ool(const struct map *map)
|
||||||
{
|
{
|
||||||
return map->dso && map->dso->binary_type == DSO_BINARY_TYPE__OOL;
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
|
return dso && dso->binary_type == DSO_BINARY_TYPE__OOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool map__has_symbols(const struct map *map)
|
bool map__has_symbols(const struct map *map)
|
||||||
{
|
{
|
||||||
return dso__has_symbols(map->dso);
|
return dso__has_symbols(map__dso(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map__exit(struct map *map)
|
static void map__exit(struct map *map)
|
||||||
|
@ -306,18 +310,23 @@ void map__put(struct map *map)
|
||||||
|
|
||||||
void map__fixup_start(struct map *map)
|
void map__fixup_start(struct map *map)
|
||||||
{
|
{
|
||||||
struct rb_root_cached *symbols = &map->dso->symbols;
|
struct dso *dso = map__dso(map);
|
||||||
|
struct rb_root_cached *symbols = &dso->symbols;
|
||||||
struct rb_node *nd = rb_first_cached(symbols);
|
struct rb_node *nd = rb_first_cached(symbols);
|
||||||
|
|
||||||
if (nd != NULL) {
|
if (nd != NULL) {
|
||||||
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
|
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
|
||||||
|
|
||||||
map->start = sym->start;
|
map->start = sym->start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void map__fixup_end(struct map *map)
|
void map__fixup_end(struct map *map)
|
||||||
{
|
{
|
||||||
struct rb_root_cached *symbols = &map->dso->symbols;
|
struct dso *dso = map__dso(map);
|
||||||
|
struct rb_root_cached *symbols = &dso->symbols;
|
||||||
struct rb_node *nd = rb_last(&symbols->rb_root);
|
struct rb_node *nd = rb_last(&symbols->rb_root);
|
||||||
|
|
||||||
if (nd != NULL) {
|
if (nd != NULL) {
|
||||||
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
|
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
|
||||||
map->end = sym->end;
|
map->end = sym->end;
|
||||||
|
@ -328,18 +337,19 @@ void map__fixup_end(struct map *map)
|
||||||
|
|
||||||
int map__load(struct map *map)
|
int map__load(struct map *map)
|
||||||
{
|
{
|
||||||
const char *name = map->dso->long_name;
|
struct dso *dso = map__dso(map);
|
||||||
|
const char *name = dso->long_name;
|
||||||
int nr;
|
int nr;
|
||||||
|
|
||||||
if (dso__loaded(map->dso))
|
if (dso__loaded(dso))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nr = dso__load(map->dso, map);
|
nr = dso__load(dso, map);
|
||||||
if (nr < 0) {
|
if (nr < 0) {
|
||||||
if (map->dso->has_build_id) {
|
if (dso->has_build_id) {
|
||||||
char sbuild_id[SBUILD_ID_SIZE];
|
char sbuild_id[SBUILD_ID_SIZE];
|
||||||
|
|
||||||
build_id__sprintf(&map->dso->bid, sbuild_id);
|
build_id__sprintf(&dso->bid, sbuild_id);
|
||||||
pr_debug("%s with build id %s not found", name, sbuild_id);
|
pr_debug("%s with build id %s not found", name, sbuild_id);
|
||||||
} else
|
} else
|
||||||
pr_debug("Failed to open %s", name);
|
pr_debug("Failed to open %s", name);
|
||||||
|
@ -371,32 +381,36 @@ struct symbol *map__find_symbol(struct map *map, u64 addr)
|
||||||
if (map__load(map) < 0)
|
if (map__load(map) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return dso__find_symbol(map->dso, addr);
|
return dso__find_symbol(map__dso(map), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
|
struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
|
||||||
{
|
{
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (map__load(map) < 0)
|
if (map__load(map) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!dso__sorted_by_name(map->dso))
|
dso = map__dso(map);
|
||||||
dso__sort_by_name(map->dso);
|
if (!dso__sorted_by_name(dso))
|
||||||
|
dso__sort_by_name(dso);
|
||||||
|
|
||||||
return dso__find_symbol_by_name(map->dso, name);
|
return dso__find_symbol_by_name(dso, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct map *map__clone(struct map *from)
|
struct map *map__clone(struct map *from)
|
||||||
{
|
{
|
||||||
size_t size = sizeof(struct map);
|
size_t size = sizeof(struct map);
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso = map__dso(from);
|
||||||
|
|
||||||
if (from->dso && from->dso->kernel)
|
if (dso && dso->kernel)
|
||||||
size += sizeof(struct kmap);
|
size += sizeof(struct kmap);
|
||||||
|
|
||||||
map = memdup(from, size);
|
map = memdup(from, size);
|
||||||
if (map != NULL) {
|
if (map != NULL) {
|
||||||
refcount_set(&map->refcnt, 1);
|
refcount_set(&map->refcnt, 1);
|
||||||
dso__get(map->dso);
|
dso__get(dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
@ -404,20 +418,23 @@ struct map *map__clone(struct map *from)
|
||||||
|
|
||||||
size_t map__fprintf(struct map *map, FILE *fp)
|
size_t map__fprintf(struct map *map, FILE *fp)
|
||||||
{
|
{
|
||||||
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
|
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
|
||||||
map->start, map->end, map->pgoff, map->dso->name);
|
map->start, map->end, map->pgoff, dso->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
|
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
|
||||||
{
|
{
|
||||||
char buf[symbol_conf.pad_output_len_dso + 1];
|
char buf[symbol_conf.pad_output_len_dso + 1];
|
||||||
const char *dsoname = "[unknown]";
|
const char *dsoname = "[unknown]";
|
||||||
|
const struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
|
|
||||||
if (map && map->dso) {
|
if (dso) {
|
||||||
if (symbol_conf.show_kernel_path && map->dso->long_name)
|
if (symbol_conf.show_kernel_path && dso->long_name)
|
||||||
dsoname = map->dso->long_name;
|
dsoname = dso->long_name;
|
||||||
else
|
else
|
||||||
dsoname = map->dso->name;
|
dsoname = dso->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol_conf.pad_output_len_dso) {
|
if (symbol_conf.pad_output_len_dso) {
|
||||||
|
@ -432,15 +449,17 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym)
|
||||||
{
|
{
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
return SRCLINE_UNKNOWN;
|
return SRCLINE_UNKNOWN;
|
||||||
return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, true, addr);
|
|
||||||
|
return get_srcline(map__dso(map), map__rip_2objdump(map, addr), sym, true, true, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
|
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
|
||||||
FILE *fp)
|
FILE *fp)
|
||||||
{
|
{
|
||||||
|
const struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (map && map->dso) {
|
if (dso) {
|
||||||
char *srcline = map__srcline(map, addr, NULL);
|
char *srcline = map__srcline(map, addr, NULL);
|
||||||
if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)
|
if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)
|
||||||
ret = fprintf(fp, "%s%s", prefix, srcline);
|
ret = fprintf(fp, "%s%s", prefix, srcline);
|
||||||
|
@ -469,6 +488,7 @@ void srccode_state_free(struct srccode_state *state)
|
||||||
u64 map__rip_2objdump(struct map *map, u64 rip)
|
u64 map__rip_2objdump(struct map *map, u64 rip)
|
||||||
{
|
{
|
||||||
struct kmap *kmap = __map__kmap(map);
|
struct kmap *kmap = __map__kmap(map);
|
||||||
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vmlinux does not have program headers for PTI entry trampolines and
|
* vmlinux does not have program headers for PTI entry trampolines and
|
||||||
|
@ -486,18 +506,18 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map->dso->adjust_symbols)
|
if (!dso->adjust_symbols)
|
||||||
return rip;
|
return rip;
|
||||||
|
|
||||||
if (map->dso->rel)
|
if (dso->rel)
|
||||||
return rip - map->pgoff;
|
return rip - map->pgoff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kernel modules also have DSO_TYPE_USER in dso->kernel,
|
* kernel modules also have DSO_TYPE_USER in dso->kernel,
|
||||||
* but all kernel modules are ET_REL, so won't get here.
|
* but all kernel modules are ET_REL, so won't get here.
|
||||||
*/
|
*/
|
||||||
if (map->dso->kernel == DSO_SPACE__USER)
|
if (dso->kernel == DSO_SPACE__USER)
|
||||||
return rip + map->dso->text_offset;
|
return rip + dso->text_offset;
|
||||||
|
|
||||||
return map->unmap_ip(map, rip) - map->reloc;
|
return map->unmap_ip(map, rip) - map->reloc;
|
||||||
}
|
}
|
||||||
|
@ -516,18 +536,20 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
|
||||||
*/
|
*/
|
||||||
u64 map__objdump_2mem(struct map *map, u64 ip)
|
u64 map__objdump_2mem(struct map *map, u64 ip)
|
||||||
{
|
{
|
||||||
if (!map->dso->adjust_symbols)
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
|
if (!dso->adjust_symbols)
|
||||||
return map->unmap_ip(map, ip);
|
return map->unmap_ip(map, ip);
|
||||||
|
|
||||||
if (map->dso->rel)
|
if (dso->rel)
|
||||||
return map->unmap_ip(map, ip + map->pgoff);
|
return map->unmap_ip(map, ip + map->pgoff);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kernel modules also have DSO_TYPE_USER in dso->kernel,
|
* kernel modules also have DSO_TYPE_USER in dso->kernel,
|
||||||
* but all kernel modules are ET_REL, so won't get here.
|
* but all kernel modules are ET_REL, so won't get here.
|
||||||
*/
|
*/
|
||||||
if (map->dso->kernel == DSO_SPACE__USER)
|
if (dso->kernel == DSO_SPACE__USER)
|
||||||
return map->unmap_ip(map, ip - map->dso->text_offset);
|
return map->unmap_ip(map, ip - dso->text_offset);
|
||||||
|
|
||||||
return ip + map->reloc;
|
return ip + map->reloc;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +563,9 @@ bool map__contains_symbol(const struct map *map, const struct symbol *sym)
|
||||||
|
|
||||||
struct kmap *__map__kmap(struct map *map)
|
struct kmap *__map__kmap(struct map *map)
|
||||||
{
|
{
|
||||||
if (!map->dso || !map->dso->kernel)
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
|
if (!dso || !dso->kernel)
|
||||||
return NULL;
|
return NULL;
|
||||||
return (struct kmap *)(map + 1);
|
return (struct kmap *)(map + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,11 @@ u64 map__unmap_ip(const struct map *map, u64 ip);
|
||||||
/* Returns ip */
|
/* Returns ip */
|
||||||
u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip);
|
u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip);
|
||||||
|
|
||||||
|
static inline struct dso *map__dso(const struct map *map)
|
||||||
|
{
|
||||||
|
return map->dso;
|
||||||
|
}
|
||||||
|
|
||||||
static inline size_t map__size(const struct map *map)
|
static inline size_t map__size(const struct map *map)
|
||||||
{
|
{
|
||||||
return map->end - map->start;
|
return map->end - map->start;
|
||||||
|
@ -69,7 +74,7 @@ struct thread;
|
||||||
* Note: caller must ensure map->dso is not NULL (map is loaded).
|
* Note: caller must ensure map->dso is not NULL (map is loaded).
|
||||||
*/
|
*/
|
||||||
#define map__for_each_symbol(map, pos, n) \
|
#define map__for_each_symbol(map, pos, n) \
|
||||||
dso__for_each_symbol(map->dso, pos, n)
|
dso__for_each_symbol(map__dso(map), pos, n)
|
||||||
|
|
||||||
/* map__for_each_symbol_with_name - iterate over the symbols in the given map
|
/* map__for_each_symbol_with_name - iterate over the symbols in the given map
|
||||||
* that have the given name
|
* that have the given name
|
||||||
|
|
|
@ -62,6 +62,7 @@ static int __maps__insert(struct maps *maps, struct map *map)
|
||||||
int maps__insert(struct maps *maps, struct map *map)
|
int maps__insert(struct maps *maps, struct map *map)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
const struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
down_write(maps__lock(maps));
|
down_write(maps__lock(maps));
|
||||||
err = __maps__insert(maps, map);
|
err = __maps__insert(maps, map);
|
||||||
|
@ -70,7 +71,7 @@ int maps__insert(struct maps *maps, struct map *map)
|
||||||
|
|
||||||
++maps->nr_maps;
|
++maps->nr_maps;
|
||||||
|
|
||||||
if (map->dso && map->dso->kernel) {
|
if (dso && dso->kernel) {
|
||||||
struct kmap *kmap = map__kmap(map);
|
struct kmap *kmap = map__kmap(map);
|
||||||
|
|
||||||
if (kmap)
|
if (kmap)
|
||||||
|
@ -253,7 +254,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp)
|
||||||
printed += fprintf(fp, "Map:");
|
printed += fprintf(fp, "Map:");
|
||||||
printed += map__fprintf(pos->map, fp);
|
printed += map__fprintf(pos->map, fp);
|
||||||
if (verbose > 2) {
|
if (verbose > 2) {
|
||||||
printed += dso__fprintf(pos->map->dso, fp);
|
printed += dso__fprintf(map__dso(pos->map), fp);
|
||||||
printed += fprintf(fp, "--\n");
|
printed += fprintf(fp, "--\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +308,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
|
||||||
|
|
||||||
if (use_browser) {
|
if (use_browser) {
|
||||||
pr_debug("overlapping maps in %s (disable tui for more info)\n",
|
pr_debug("overlapping maps in %s (disable tui for more info)\n",
|
||||||
map->dso->name);
|
map__dso(map)->name);
|
||||||
} else {
|
} else {
|
||||||
fputs("overlapping maps:\n", fp);
|
fputs("overlapping maps:\n", fp);
|
||||||
map__fprintf(map, fp);
|
map__fprintf(map, fp);
|
||||||
|
|
|
@ -165,8 +165,9 @@ static struct map *kernel_get_module_map(const char *module)
|
||||||
|
|
||||||
maps__for_each_entry(maps, pos) {
|
maps__for_each_entry(maps, pos) {
|
||||||
/* short_name is "[module]" */
|
/* short_name is "[module]" */
|
||||||
const char *short_name = pos->map->dso->short_name;
|
struct dso *dso = map__dso(pos->map);
|
||||||
u16 short_name_len = pos->map->dso->short_name_len;
|
const char *short_name = dso->short_name;
|
||||||
|
u16 short_name_len = dso->short_name_len;
|
||||||
|
|
||||||
if (strncmp(short_name + 1, module,
|
if (strncmp(short_name + 1, module,
|
||||||
short_name_len - 2) == 0 &&
|
short_name_len - 2) == 0 &&
|
||||||
|
@ -182,13 +183,15 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
|
||||||
/* Init maps of given executable or kernel */
|
/* Init maps of given executable or kernel */
|
||||||
if (user) {
|
if (user) {
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
map = dso__new_map(target);
|
map = dso__new_map(target);
|
||||||
if (map && map->dso) {
|
dso = map ? map__dso(map) : NULL;
|
||||||
mutex_lock(&map->dso->lock);
|
if (dso) {
|
||||||
nsinfo__put(map->dso->nsinfo);
|
mutex_lock(&dso->lock);
|
||||||
map->dso->nsinfo = nsinfo__get(nsi);
|
nsinfo__put(dso->nsinfo);
|
||||||
mutex_unlock(&map->dso->lock);
|
dso->nsinfo = nsinfo__get(nsi);
|
||||||
|
mutex_unlock(&dso->lock);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
} else {
|
} else {
|
||||||
|
@ -341,7 +344,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)
|
||||||
snprintf(module_name, sizeof(module_name), "[%s]", module);
|
snprintf(module_name, sizeof(module_name), "[%s]", module);
|
||||||
map = maps__find_by_name(machine__kernel_maps(host_machine), module_name);
|
map = maps__find_by_name(machine__kernel_maps(host_machine), module_name);
|
||||||
if (map) {
|
if (map) {
|
||||||
dso = map->dso;
|
dso = map__dso(map);
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
pr_debug("Failed to find module %s.\n", module);
|
pr_debug("Failed to find module %s.\n", module);
|
||||||
|
@ -349,7 +352,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)
|
||||||
}
|
}
|
||||||
|
|
||||||
map = machine__kernel_map(host_machine);
|
map = machine__kernel_map(host_machine);
|
||||||
dso = map->dso;
|
dso = map__dso(map);
|
||||||
if (!dso->has_build_id)
|
if (!dso->has_build_id)
|
||||||
dso__read_running_kernel_build_id(dso, host_machine);
|
dso__read_running_kernel_build_id(dso, host_machine);
|
||||||
|
|
||||||
|
@ -3737,6 +3740,7 @@ int show_available_funcs(const char *target, struct nsinfo *nsi,
|
||||||
{
|
{
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = init_probe_symbol_maps(user);
|
ret = init_probe_symbol_maps(user);
|
||||||
|
@ -3762,14 +3766,14 @@ int show_available_funcs(const char *target, struct nsinfo *nsi,
|
||||||
(target) ? : "kernel");
|
(target) ? : "kernel");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (!dso__sorted_by_name(map->dso))
|
dso = map__dso(map);
|
||||||
dso__sort_by_name(map->dso);
|
if (!dso__sorted_by_name(dso))
|
||||||
|
dso__sort_by_name(dso);
|
||||||
|
|
||||||
/* Show all (filtered) symbols */
|
/* Show all (filtered) symbols */
|
||||||
setup_pager();
|
setup_pager();
|
||||||
|
|
||||||
for (nd = rb_first_cached(&map->dso->symbol_names); nd;
|
for (nd = rb_first_cached(&dso->symbol_names); nd; nd = rb_next(nd)) {
|
||||||
nd = rb_next(nd)) {
|
|
||||||
struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
|
struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
|
||||||
|
|
||||||
if (strfilter__compare(_filter, pos->sym.name))
|
if (strfilter__compare(_filter, pos->sym.name))
|
||||||
|
|
|
@ -315,12 +315,14 @@ static SV *perl_process_callchain(struct perf_sample *sample,
|
||||||
|
|
||||||
if (node->ms.map) {
|
if (node->ms.map) {
|
||||||
struct map *map = node->ms.map;
|
struct map *map = node->ms.map;
|
||||||
|
struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
const char *dsoname = "[unknown]";
|
const char *dsoname = "[unknown]";
|
||||||
if (map && map->dso) {
|
|
||||||
if (symbol_conf.show_kernel_path && map->dso->long_name)
|
if (dso) {
|
||||||
dsoname = map->dso->long_name;
|
if (symbol_conf.show_kernel_path && dso->long_name)
|
||||||
|
dsoname = dso->long_name;
|
||||||
else
|
else
|
||||||
dsoname = map->dso->name;
|
dsoname = dso->name;
|
||||||
}
|
}
|
||||||
if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
|
if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
|
||||||
hv_undef(elem);
|
hv_undef(elem);
|
||||||
|
|
|
@ -390,12 +390,13 @@ static PyObject *get_field_numeric_entry(struct tep_event *event,
|
||||||
static const char *get_dsoname(struct map *map)
|
static const char *get_dsoname(struct map *map)
|
||||||
{
|
{
|
||||||
const char *dsoname = "[unknown]";
|
const char *dsoname = "[unknown]";
|
||||||
|
struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
|
|
||||||
if (map && map->dso) {
|
if (dso) {
|
||||||
if (symbol_conf.show_kernel_path && map->dso->long_name)
|
if (symbol_conf.show_kernel_path && dso->long_name)
|
||||||
dsoname = map->dso->long_name;
|
dsoname = dso->long_name;
|
||||||
else
|
else
|
||||||
dsoname = map->dso->name;
|
dsoname = dso->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dsoname;
|
return dsoname;
|
||||||
|
@ -780,9 +781,10 @@ static void set_sym_in_dict(PyObject *dict, struct addr_location *al,
|
||||||
char sbuild_id[SBUILD_ID_SIZE];
|
char sbuild_id[SBUILD_ID_SIZE];
|
||||||
|
|
||||||
if (al->map) {
|
if (al->map) {
|
||||||
pydict_set_item_string_decref(dict, dso_field,
|
struct dso *dso = map__dso(al->map);
|
||||||
_PyUnicode_FromString(al->map->dso->name));
|
|
||||||
build_id__sprintf(&al->map->dso->bid, sbuild_id);
|
pydict_set_item_string_decref(dict, dso_field, _PyUnicode_FromString(dso->name));
|
||||||
|
build_id__sprintf(&dso->bid, sbuild_id);
|
||||||
pydict_set_item_string_decref(dict, dso_bid_field,
|
pydict_set_item_string_decref(dict, dso_bid_field,
|
||||||
_PyUnicode_FromString(sbuild_id));
|
_PyUnicode_FromString(sbuild_id));
|
||||||
pydict_set_item_string_decref(dict, dso_map_start,
|
pydict_set_item_string_decref(dict, dso_map_start,
|
||||||
|
|
|
@ -230,8 +230,8 @@ struct sort_entry sort_comm = {
|
||||||
|
|
||||||
static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
|
static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
|
||||||
{
|
{
|
||||||
struct dso *dso_l = map_l ? map_l->dso : NULL;
|
struct dso *dso_l = map_l ? map__dso(map_l) : NULL;
|
||||||
struct dso *dso_r = map_r ? map_r->dso : NULL;
|
struct dso *dso_r = map_r ? map__dso(map_r) : NULL;
|
||||||
const char *dso_name_l, *dso_name_r;
|
const char *dso_name_l, *dso_name_r;
|
||||||
|
|
||||||
if (!dso_l || !dso_r)
|
if (!dso_l || !dso_r)
|
||||||
|
@ -257,13 +257,13 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
static int _hist_entry__dso_snprintf(struct map *map, char *bf,
|
static int _hist_entry__dso_snprintf(struct map *map, char *bf,
|
||||||
size_t size, unsigned int width)
|
size_t size, unsigned int width)
|
||||||
{
|
{
|
||||||
if (map && map->dso) {
|
const struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
const char *dso_name = verbose > 0 ? map->dso->long_name :
|
const char *dso_name = "[unknown]";
|
||||||
map->dso->short_name;
|
|
||||||
return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return repsep_snprintf(bf, size, "%-*.*s", width, width, "[unknown]");
|
if (dso)
|
||||||
|
dso_name = verbose > 0 ? dso->long_name : dso->short_name;
|
||||||
|
|
||||||
|
return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
|
static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
|
||||||
|
@ -279,7 +279,7 @@ static int hist_entry__dso_filter(struct hist_entry *he, int type, const void *a
|
||||||
if (type != HIST_FILTER__DSO)
|
if (type != HIST_FILTER__DSO)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return dso && (!he->ms.map || he->ms.map->dso != dso);
|
return dso && (!he->ms.map || map__dso(he->ms.map) != dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sort_entry sort_dso = {
|
struct sort_entry sort_dso = {
|
||||||
|
@ -359,11 +359,11 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
|
||||||
if (verbose > 0) {
|
if (verbose > 0) {
|
||||||
char o = map ? dso__symtab_origin(map->dso) : '!';
|
struct dso *dso = map ? map__dso(map) : NULL;
|
||||||
|
char o = dso ? dso__symtab_origin(dso) : '!';
|
||||||
u64 rip = ip;
|
u64 rip = ip;
|
||||||
|
|
||||||
if (map && map->dso && map->dso->kernel
|
if (dso && dso->kernel && dso->adjust_symbols)
|
||||||
&& map->dso->adjust_symbols)
|
|
||||||
rip = map->unmap_ip(map, ip);
|
rip = map->unmap_ip(map, ip);
|
||||||
|
|
||||||
ret += repsep_snprintf(bf, size, "%-#*llx %c ",
|
ret += repsep_snprintf(bf, size, "%-#*llx %c ",
|
||||||
|
@ -641,7 +641,7 @@ static char *hist_entry__get_srcfile(struct hist_entry *e)
|
||||||
if (!map)
|
if (!map)
|
||||||
return no_srcfile;
|
return no_srcfile;
|
||||||
|
|
||||||
sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip),
|
sf = __get_srcline(map__dso(map), map__rip_2objdump(map, e->ip),
|
||||||
e->ms.sym, false, true, true, e->ip);
|
e->ms.sym, false, true, true, e->ip);
|
||||||
if (!strcmp(sf, SRCLINE_UNKNOWN))
|
if (!strcmp(sf, SRCLINE_UNKNOWN))
|
||||||
return no_srcfile;
|
return no_srcfile;
|
||||||
|
@ -982,7 +982,7 @@ static int hist_entry__dso_from_filter(struct hist_entry *he, int type,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return dso && (!he->branch_info || !he->branch_info->from.ms.map ||
|
return dso && (!he->branch_info || !he->branch_info->from.ms.map ||
|
||||||
he->branch_info->from.ms.map->dso != dso);
|
map__dso(he->branch_info->from.ms.map) != dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
|
@ -1014,7 +1014,7 @@ static int hist_entry__dso_to_filter(struct hist_entry *he, int type,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return dso && (!he->branch_info || !he->branch_info->to.ms.map ||
|
return dso && (!he->branch_info || !he->branch_info->to.ms.map ||
|
||||||
he->branch_info->to.ms.map->dso != dso);
|
map__dso(he->branch_info->to.ms.map) != dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
|
@ -1506,6 +1506,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
{
|
{
|
||||||
u64 l, r;
|
u64 l, r;
|
||||||
struct map *l_map, *r_map;
|
struct map *l_map, *r_map;
|
||||||
|
struct dso *l_dso, *r_dso;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!left->mem_info) return -1;
|
if (!left->mem_info) return -1;
|
||||||
|
@ -1525,7 +1526,9 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
if (!l_map) return -1;
|
if (!l_map) return -1;
|
||||||
if (!r_map) return 1;
|
if (!r_map) return 1;
|
||||||
|
|
||||||
rc = dso__cmp_id(l_map->dso, r_map->dso);
|
l_dso = map__dso(l_map);
|
||||||
|
r_dso = map__dso(r_map);
|
||||||
|
rc = dso__cmp_id(l_dso, r_dso);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
/*
|
/*
|
||||||
|
@ -1537,9 +1540,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
|
if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
|
||||||
(!(l_map->flags & MAP_SHARED)) &&
|
(!(l_map->flags & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min &&
|
||||||
!l_map->dso->id.maj && !l_map->dso->id.min &&
|
!l_dso->id.ino && !l_dso->id.ino_generation) {
|
||||||
!l_map->dso->id.ino && !l_map->dso->id.ino_generation) {
|
|
||||||
/* userspace anonymous */
|
/* userspace anonymous */
|
||||||
|
|
||||||
if (left->thread->pid_ > right->thread->pid_) return -1;
|
if (left->thread->pid_ > right->thread->pid_) return -1;
|
||||||
|
@ -1567,6 +1569,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
|
||||||
|
|
||||||
if (he->mem_info) {
|
if (he->mem_info) {
|
||||||
struct map *map = he->mem_info->daddr.ms.map;
|
struct map *map = he->mem_info->daddr.ms.map;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
|
|
||||||
addr = cl_address(he->mem_info->daddr.al_addr, chk_double_cl);
|
addr = cl_address(he->mem_info->daddr.al_addr, chk_double_cl);
|
||||||
ms = &he->mem_info->daddr.ms;
|
ms = &he->mem_info->daddr.ms;
|
||||||
|
@ -1575,8 +1578,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
|
||||||
if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
|
if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
|
||||||
map && !(map->prot & PROT_EXEC) &&
|
map && !(map->prot & PROT_EXEC) &&
|
||||||
(map->flags & MAP_SHARED) &&
|
(map->flags & MAP_SHARED) &&
|
||||||
(map->dso->id.maj || map->dso->id.min ||
|
(dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation))
|
||||||
map->dso->id.ino || map->dso->id.ino_generation))
|
|
||||||
level = 's';
|
level = 's';
|
||||||
else if (!map)
|
else if (!map)
|
||||||
level = 'X';
|
level = 'X';
|
||||||
|
@ -2072,9 +2074,8 @@ sort__dso_size_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
static int _hist_entry__dso_size_snprintf(struct map *map, char *bf,
|
static int _hist_entry__dso_size_snprintf(struct map *map, char *bf,
|
||||||
size_t bf_size, unsigned int width)
|
size_t bf_size, unsigned int width)
|
||||||
{
|
{
|
||||||
if (map && map->dso)
|
if (map && map__dso(map))
|
||||||
return repsep_snprintf(bf, bf_size, "%*d", width,
|
return repsep_snprintf(bf, bf_size, "%*d", width, map__size(map));
|
||||||
map__size(map));
|
|
||||||
|
|
||||||
return repsep_snprintf(bf, bf_size, "%*s", width, "unknown");
|
return repsep_snprintf(bf, bf_size, "%*s", width, "unknown");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1435,7 +1435,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
|
||||||
*curr_mapp = curr_map;
|
*curr_mapp = curr_map;
|
||||||
*curr_dsop = curr_dso;
|
*curr_dsop = curr_dso;
|
||||||
} else
|
} else
|
||||||
*curr_dsop = curr_map->dso;
|
*curr_dsop = map__dso(curr_map);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,6 +791,7 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso)
|
||||||
*root = RB_ROOT_CACHED;
|
*root = RB_ROOT_CACHED;
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
|
struct dso *curr_map_dso;
|
||||||
char *module;
|
char *module;
|
||||||
|
|
||||||
pos = rb_entry(next, struct symbol, rb_node);
|
pos = rb_entry(next, struct symbol, rb_node);
|
||||||
|
@ -808,13 +809,13 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso)
|
||||||
symbol__delete(pos);
|
symbol__delete(pos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
curr_map_dso = map__dso(curr_map);
|
||||||
pos->start -= curr_map->start - curr_map->pgoff;
|
pos->start -= curr_map->start - curr_map->pgoff;
|
||||||
if (pos->end > curr_map->end)
|
if (pos->end > curr_map->end)
|
||||||
pos->end = curr_map->end;
|
pos->end = curr_map->end;
|
||||||
if (pos->end)
|
if (pos->end)
|
||||||
pos->end -= curr_map->start - curr_map->pgoff;
|
pos->end -= curr_map->start - curr_map->pgoff;
|
||||||
symbols__insert(&curr_map->dso->symbols, pos);
|
symbols__insert(&curr_map_dso->symbols, pos);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,12 +857,14 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
|
||||||
|
|
||||||
module = strchr(pos->name, '\t');
|
module = strchr(pos->name, '\t');
|
||||||
if (module) {
|
if (module) {
|
||||||
|
struct dso *curr_map_dso;
|
||||||
|
|
||||||
if (!symbol_conf.use_modules)
|
if (!symbol_conf.use_modules)
|
||||||
goto discard_symbol;
|
goto discard_symbol;
|
||||||
|
|
||||||
*module++ = '\0';
|
*module++ = '\0';
|
||||||
|
curr_map_dso = map__dso(curr_map);
|
||||||
if (strcmp(curr_map->dso->short_name, module)) {
|
if (strcmp(curr_map_dso->short_name, module)) {
|
||||||
if (curr_map != initial_map &&
|
if (curr_map != initial_map &&
|
||||||
dso->kernel == DSO_SPACE__KERNEL_GUEST &&
|
dso->kernel == DSO_SPACE__KERNEL_GUEST &&
|
||||||
machine__is_default_guest(machine)) {
|
machine__is_default_guest(machine)) {
|
||||||
|
@ -872,7 +875,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
|
||||||
* symbols are in its kmap. Mark it as
|
* symbols are in its kmap. Mark it as
|
||||||
* loaded.
|
* loaded.
|
||||||
*/
|
*/
|
||||||
dso__set_loaded(curr_map->dso);
|
dso__set_loaded(curr_map_dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_map = maps__find_by_name(kmaps, module);
|
curr_map = maps__find_by_name(kmaps, module);
|
||||||
|
@ -884,8 +887,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
|
||||||
curr_map = initial_map;
|
curr_map = initial_map;
|
||||||
goto discard_symbol;
|
goto discard_symbol;
|
||||||
}
|
}
|
||||||
|
curr_map_dso = map__dso(curr_map);
|
||||||
if (curr_map->dso->loaded &&
|
if (curr_map_dso->loaded &&
|
||||||
!machine__is_default_guest(machine))
|
!machine__is_default_guest(machine))
|
||||||
goto discard_symbol;
|
goto discard_symbol;
|
||||||
}
|
}
|
||||||
|
@ -954,8 +957,10 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
|
||||||
}
|
}
|
||||||
add_symbol:
|
add_symbol:
|
||||||
if (curr_map != initial_map) {
|
if (curr_map != initial_map) {
|
||||||
|
struct dso *curr_map_dso = map__dso(curr_map);
|
||||||
|
|
||||||
rb_erase_cached(&pos->rb_node, root);
|
rb_erase_cached(&pos->rb_node, root);
|
||||||
symbols__insert(&curr_map->dso->symbols, pos);
|
symbols__insert(&curr_map_dso->symbols, pos);
|
||||||
++moved;
|
++moved;
|
||||||
} else
|
} else
|
||||||
++count;
|
++count;
|
||||||
|
@ -969,7 +974,7 @@ discard_symbol:
|
||||||
if (curr_map != initial_map &&
|
if (curr_map != initial_map &&
|
||||||
dso->kernel == DSO_SPACE__KERNEL_GUEST &&
|
dso->kernel == DSO_SPACE__KERNEL_GUEST &&
|
||||||
machine__is_default_guest(maps__machine(kmaps))) {
|
machine__is_default_guest(maps__machine(kmaps))) {
|
||||||
dso__set_loaded(curr_map->dso);
|
dso__set_loaded(map__dso(curr_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
return count + moved;
|
return count + moved;
|
||||||
|
@ -1143,13 +1148,14 @@ static int do_validate_kcore_modules(const char *filename, struct maps *kmaps)
|
||||||
maps__for_each_entry(kmaps, old_node) {
|
maps__for_each_entry(kmaps, old_node) {
|
||||||
struct map *old_map = old_node->map;
|
struct map *old_map = old_node->map;
|
||||||
struct module_info *mi;
|
struct module_info *mi;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (!__map__is_kmodule(old_map)) {
|
if (!__map__is_kmodule(old_map)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
dso = map__dso(old_map);
|
||||||
/* Module must be in memory at the same address */
|
/* Module must be in memory at the same address */
|
||||||
mi = find_module(old_map->dso->short_name, &modules);
|
mi = find_module(dso->short_name, &modules);
|
||||||
if (!mi || mi->start != old_map->start) {
|
if (!mi || mi->start != old_map->start) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2047,14 +2053,17 @@ out:
|
||||||
|
|
||||||
static int map__strcmp(const void *a, const void *b)
|
static int map__strcmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const struct map *ma = *(const struct map **)a, *mb = *(const struct map **)b;
|
const struct dso *dso_a = map__dso(*(const struct map **)a);
|
||||||
return strcmp(ma->dso->short_name, mb->dso->short_name);
|
const struct dso *dso_b = map__dso(*(const struct map **)b);
|
||||||
|
|
||||||
|
return strcmp(dso_a->short_name, dso_b->short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int map__strcmp_name(const void *name, const void *b)
|
static int map__strcmp_name(const void *name, const void *b)
|
||||||
{
|
{
|
||||||
const struct map *map = *(const struct map **)b;
|
const struct dso *dso = map__dso(*(const struct map **)b);
|
||||||
return strcmp(name, map->dso->short_name);
|
|
||||||
|
return strcmp(name, dso->short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __maps__sort_by_name(struct maps *maps)
|
void __maps__sort_by_name(struct maps *maps)
|
||||||
|
@ -2111,10 +2120,13 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
|
||||||
|
|
||||||
down_read(maps__lock(maps));
|
down_read(maps__lock(maps));
|
||||||
|
|
||||||
if (maps->last_search_by_name &&
|
if (maps->last_search_by_name) {
|
||||||
strcmp(maps->last_search_by_name->dso->short_name, name) == 0) {
|
const struct dso *dso = map__dso(maps->last_search_by_name);
|
||||||
map = maps->last_search_by_name;
|
|
||||||
goto out_unlock;
|
if (strcmp(dso->short_name, name) == 0) {
|
||||||
|
map = maps->last_search_by_name;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If we have maps->maps_by_name, then the name isn't in the rbtree,
|
* If we have maps->maps_by_name, then the name isn't in the rbtree,
|
||||||
|
@ -2127,8 +2139,11 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
|
||||||
|
|
||||||
/* Fallback to traversing the rbtree... */
|
/* Fallback to traversing the rbtree... */
|
||||||
maps__for_each_entry(maps, rb_node) {
|
maps__for_each_entry(maps, rb_node) {
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
map = rb_node->map;
|
map = rb_node->map;
|
||||||
if (strcmp(map->dso->short_name, name) == 0) {
|
dso = map__dso(map);
|
||||||
|
if (strcmp(dso->short_name, name) == 0) {
|
||||||
maps->last_search_by_name = map;
|
maps->last_search_by_name = map;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
|
@ -693,12 +693,14 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t
|
||||||
|
|
||||||
maps__for_each_entry(maps, pos) {
|
maps__for_each_entry(maps, pos) {
|
||||||
struct map *map = pos->map;
|
struct map *map = pos->map;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (!__map__is_kmodule(map))
|
if (!__map__is_kmodule(map))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
dso = map__dso(map);
|
||||||
if (symbol_conf.buildid_mmap2) {
|
if (symbol_conf.buildid_mmap2) {
|
||||||
size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64));
|
size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64));
|
||||||
event->mmap2.header.type = PERF_RECORD_MMAP2;
|
event->mmap2.header.type = PERF_RECORD_MMAP2;
|
||||||
event->mmap2.header.size = (sizeof(event->mmap2) -
|
event->mmap2.header.size = (sizeof(event->mmap2) -
|
||||||
(sizeof(event->mmap2.filename) - size));
|
(sizeof(event->mmap2.filename) - size));
|
||||||
|
@ -708,12 +710,11 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t
|
||||||
event->mmap2.len = map->end - map->start;
|
event->mmap2.len = map->end - map->start;
|
||||||
event->mmap2.pid = machine->pid;
|
event->mmap2.pid = machine->pid;
|
||||||
|
|
||||||
memcpy(event->mmap2.filename, map->dso->long_name,
|
memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1);
|
||||||
map->dso->long_name_len + 1);
|
|
||||||
|
|
||||||
perf_record_mmap2__read_build_id(&event->mmap2, machine, false);
|
perf_record_mmap2__read_build_id(&event->mmap2, machine, false);
|
||||||
} else {
|
} else {
|
||||||
size = PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64));
|
size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64));
|
||||||
event->mmap.header.type = PERF_RECORD_MMAP;
|
event->mmap.header.type = PERF_RECORD_MMAP;
|
||||||
event->mmap.header.size = (sizeof(event->mmap) -
|
event->mmap.header.size = (sizeof(event->mmap) -
|
||||||
(sizeof(event->mmap.filename) - size));
|
(sizeof(event->mmap.filename) - size));
|
||||||
|
@ -723,8 +724,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t
|
||||||
event->mmap.len = map->end - map->start;
|
event->mmap.len = map->end - map->start;
|
||||||
event->mmap.pid = machine->pid;
|
event->mmap.pid = machine->pid;
|
||||||
|
|
||||||
memcpy(event->mmap.filename, map->dso->long_name,
|
memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1);
|
||||||
map->dso->long_name_len + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
|
if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
|
||||||
|
|
|
@ -448,23 +448,27 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
|
||||||
int thread__memcpy(struct thread *thread, struct machine *machine,
|
int thread__memcpy(struct thread *thread, struct machine *machine,
|
||||||
void *buf, u64 ip, int len, bool *is64bit)
|
void *buf, u64 ip, int len, bool *is64bit)
|
||||||
{
|
{
|
||||||
u8 cpumode = PERF_RECORD_MISC_USER;
|
u8 cpumode = PERF_RECORD_MISC_USER;
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
long offset;
|
struct dso *dso;
|
||||||
|
long offset;
|
||||||
|
|
||||||
if (machine__kernel_ip(machine, ip))
|
if (machine__kernel_ip(machine, ip))
|
||||||
cpumode = PERF_RECORD_MISC_KERNEL;
|
cpumode = PERF_RECORD_MISC_KERNEL;
|
||||||
|
|
||||||
if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso ||
|
if (!thread__find_map(thread, cpumode, ip, &al))
|
||||||
al.map->dso->data.status == DSO_DATA_STATUS_ERROR ||
|
return -1;
|
||||||
map__load(al.map) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
offset = al.map->map_ip(al.map, ip);
|
dso = map__dso(al.map);
|
||||||
if (is64bit)
|
|
||||||
*is64bit = al.map->dso->is_64_bit;
|
|
||||||
|
|
||||||
return dso__data_read_offset(al.map->dso, machine, offset, buf, len);
|
if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
offset = al.map->map_ip(al.map, ip);
|
||||||
|
if (is64bit)
|
||||||
|
*is64bit = dso->is_64_bit;
|
||||||
|
|
||||||
|
return dso__data_read_offset(dso, machine, offset, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread__free_stitch_list(struct thread *thread)
|
void thread__free_stitch_list(struct thread *thread)
|
||||||
|
|
|
@ -52,7 +52,7 @@ static int __report_module(struct addr_location *al, u64 ip,
|
||||||
thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al);
|
thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al);
|
||||||
|
|
||||||
if (al->map)
|
if (al->map)
|
||||||
dso = al->map->dso;
|
dso = map__dso(al->map);
|
||||||
|
|
||||||
if (!dso)
|
if (!dso)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -134,17 +134,17 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
|
||||||
{
|
{
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
struct dso *dso;
|
||||||
|
|
||||||
if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) {
|
if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) {
|
||||||
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
|
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
dso = map__dso(al.map);
|
||||||
if (!al.map->dso)
|
if (!dso)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size = dso__data_read_addr(al.map->dso, al.map, ui->machine,
|
size = dso__data_read_addr(dso, al.map, ui->machine, addr, (u8 *) data, sizeof(*data));
|
||||||
addr, (u8 *) data, sizeof(*data));
|
|
||||||
|
|
||||||
return !(size == sizeof(*data));
|
return !(size == sizeof(*data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,7 +328,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui,
|
||||||
maps__for_each_entry(ui->thread->maps, map_node) {
|
maps__for_each_entry(ui->thread->maps, map_node) {
|
||||||
struct map *map = map_node->map;
|
struct map *map = map_node->map;
|
||||||
|
|
||||||
if (map->dso == dso && map->start < base_addr)
|
if (map__dso(map) == dso && map->start < base_addr)
|
||||||
base_addr = map->start;
|
base_addr = map->start;
|
||||||
}
|
}
|
||||||
base_addr -= dso->data.elf_base_addr;
|
base_addr -= dso->data.elf_base_addr;
|
||||||
|
@ -424,19 +424,23 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
|
||||||
{
|
{
|
||||||
struct unwind_info *ui = arg;
|
struct unwind_info *ui = arg;
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
unw_dyn_info_t di;
|
unw_dyn_info_t di;
|
||||||
u64 table_data, segbase, fde_count;
|
u64 table_data, segbase, fde_count;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
map = find_map(ip, ui);
|
map = find_map(ip, ui);
|
||||||
if (!map || !map->dso)
|
if (!map)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
|
dso = map__dso(map);
|
||||||
|
if (!dso)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pr_debug("unwind: find_proc_info dso %s\n", dso->name);
|
||||||
|
|
||||||
/* Check the .eh_frame section for unwinding info */
|
/* Check the .eh_frame section for unwinding info */
|
||||||
if (!read_unwind_spec_eh_frame(map->dso, ui,
|
if (!read_unwind_spec_eh_frame(dso, ui, &table_data, &segbase, &fde_count)) {
|
||||||
&table_data, &segbase, &fde_count)) {
|
|
||||||
memset(&di, 0, sizeof(di));
|
memset(&di, 0, sizeof(di));
|
||||||
di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
|
di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
|
||||||
di.start_ip = map->start;
|
di.start_ip = map->start;
|
||||||
|
@ -452,16 +456,16 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
|
||||||
#ifndef NO_LIBUNWIND_DEBUG_FRAME
|
#ifndef NO_LIBUNWIND_DEBUG_FRAME
|
||||||
/* Check the .debug_frame section for unwinding info */
|
/* Check the .debug_frame section for unwinding info */
|
||||||
if (ret < 0 &&
|
if (ret < 0 &&
|
||||||
!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
|
!read_unwind_spec_debug_frame(dso, ui->machine, &segbase)) {
|
||||||
int fd = dso__data_get_fd(map->dso, ui->machine);
|
int fd = dso__data_get_fd(dso, ui->machine);
|
||||||
int is_exec = elf_is_exec(fd, map->dso->name);
|
int is_exec = elf_is_exec(fd, dso->name);
|
||||||
unw_word_t base = is_exec ? 0 : map->start;
|
unw_word_t base = is_exec ? 0 : map->start;
|
||||||
const char *symfile;
|
const char *symfile;
|
||||||
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
dso__data_put_fd(map->dso);
|
dso__data_put_fd(dso);
|
||||||
|
|
||||||
symfile = map->dso->symsrc_filename ?: map->dso->name;
|
symfile = dso->symsrc_filename ?: dso->name;
|
||||||
|
|
||||||
memset(&di, 0, sizeof(di));
|
memset(&di, 0, sizeof(di));
|
||||||
if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
|
if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
|
||||||
|
@ -513,6 +517,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
|
||||||
unw_word_t *data)
|
unw_word_t *data)
|
||||||
{
|
{
|
||||||
struct map *map;
|
struct map *map;
|
||||||
|
struct dso *dso;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
|
||||||
map = find_map(addr, ui);
|
map = find_map(addr, ui);
|
||||||
|
@ -521,10 +526,12 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map->dso)
|
dso = map__dso(map);
|
||||||
|
|
||||||
|
if (!dso)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size = dso__data_read_addr(map->dso, map, ui->machine,
|
size = dso__data_read_addr(dso, map, ui->machine,
|
||||||
addr, (u8 *) data, sizeof(*data));
|
addr, (u8 *) data, sizeof(*data));
|
||||||
|
|
||||||
return !(size == sizeof(*data));
|
return !(size == sizeof(*data));
|
||||||
|
|
|
@ -22,6 +22,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized
|
||||||
const char *arch;
|
const char *arch;
|
||||||
enum dso_type dso_type;
|
enum dso_type dso_type;
|
||||||
struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
|
struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
|
||||||
|
struct dso *dso = map__dso(map);
|
||||||
struct machine *machine;
|
struct machine *machine;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -29,8 +30,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (maps__addr_space(maps)) {
|
if (maps__addr_space(maps)) {
|
||||||
pr_debug("unwind: thread map already set, dso=%s\n",
|
pr_debug("unwind: thread map already set, dso=%s\n", dso->name);
|
||||||
map->dso->name);
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
*initialized = true;
|
*initialized = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -41,7 +41,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized
|
||||||
if (!machine->env || !machine->env->arch)
|
if (!machine->env || !machine->env->arch)
|
||||||
goto out_register;
|
goto out_register;
|
||||||
|
|
||||||
dso_type = dso__type(map->dso, machine);
|
dso_type = dso__type(dso, machine);
|
||||||
if (dso_type == DSO__TYPE_UNKNOWN)
|
if (dso_type == DSO__TYPE_UNKNOWN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ static enum dso_type machine__thread_dso_type(struct machine *machine,
|
||||||
struct map_rb_node *rb_node;
|
struct map_rb_node *rb_node;
|
||||||
|
|
||||||
maps__for_each_entry(thread->maps, rb_node) {
|
maps__for_each_entry(thread->maps, rb_node) {
|
||||||
struct dso *dso = rb_node->map->dso;
|
struct dso *dso = map__dso(rb_node->map);
|
||||||
|
|
||||||
if (!dso || dso->long_name[0] != '/')
|
if (!dso || dso->long_name[0] != '/')
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue