perf symbols: Add machine helper routines

Created when writing the first 'perf test' regression testing routine.

Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 18acde52
...@@ -377,7 +377,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session, ...@@ -377,7 +377,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
if (is_caller) { if (is_caller) {
addr = data->call_site; addr = data->call_site;
if (!raw_ip) if (!raw_ip)
sym = machine__find_function(machine, addr, &map, NULL); sym = machine__find_kernel_function(machine, addr, &map, NULL);
} else } else
addr = data->ptr; addr = data->ptr;
......
...@@ -30,6 +30,7 @@ struct map { ...@@ -30,6 +30,7 @@ struct map {
u64 start; u64 start;
u64 end; u64 end;
enum map_type type; enum map_type type;
u32 priv;
u64 pgoff; u64 pgoff;
/* ip -> dso rip */ /* ip -> dso rip */
...@@ -66,6 +67,12 @@ struct machine { ...@@ -66,6 +67,12 @@ struct machine {
struct map *vmlinux_maps[MAP__NR_TYPES]; struct map *vmlinux_maps[MAP__NR_TYPES];
}; };
static inline
struct map *machine__kernel_map(struct machine *self, enum map_type type)
{
return self->vmlinux_maps[type];
}
static inline struct kmap *map__kmap(struct map *self) static inline struct kmap *map__kmap(struct map *self)
{ {
return (struct kmap *)(self + 1); return (struct kmap *)(self + 1);
...@@ -173,11 +180,21 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self, ...@@ -173,11 +180,21 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
struct map **mapp, struct map **mapp,
symbol_filter_t filter); symbol_filter_t filter);
static inline struct symbol *machine__find_function(struct machine *self, static inline
u64 addr, struct map **mapp, struct symbol *machine__find_kernel_symbol(struct machine *self,
symbol_filter_t filter) enum map_type type, u64 addr,
struct map **mapp,
symbol_filter_t filter)
{
return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
}
static inline
struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
struct map **mapp,
symbol_filter_t filter)
{ {
return map_groups__find_symbol(&self->kmaps, MAP__FUNCTION, addr, mapp, filter); return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
} }
static inline static inline
......
...@@ -1983,23 +1983,23 @@ void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine ...@@ -1983,23 +1983,23 @@ void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine
self->has_build_id = true; self->has_build_id = true;
} }
static struct dso *dsos__create_kernel(struct machine *machine) static struct dso *machine__create_kernel(struct machine *self)
{ {
const char *vmlinux_name = NULL; const char *vmlinux_name = NULL;
struct dso *kernel; struct dso *kernel;
if (machine__is_host(machine)) { if (machine__is_host(self)) {
vmlinux_name = symbol_conf.vmlinux_name; vmlinux_name = symbol_conf.vmlinux_name;
kernel = dso__new_kernel(vmlinux_name); kernel = dso__new_kernel(vmlinux_name);
} else { } else {
if (machine__is_default_guest(machine)) if (machine__is_default_guest(self))
vmlinux_name = symbol_conf.default_guest_vmlinux_name; vmlinux_name = symbol_conf.default_guest_vmlinux_name;
kernel = dso__new_guest_kernel(machine, vmlinux_name); kernel = dso__new_guest_kernel(self, vmlinux_name);
} }
if (kernel != NULL) { if (kernel != NULL) {
dso__read_running_kernel_build_id(kernel, machine); dso__read_running_kernel_build_id(kernel, self);
dsos__add(&machine->kernel_dsos, kernel); dsos__add(&self->kernel_dsos, kernel);
} }
return kernel; return kernel;
} }
...@@ -2026,6 +2026,23 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) ...@@ -2026,6 +2026,23 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
return 0; return 0;
} }
int machine__create_kernel_maps(struct machine *self)
{
struct dso *kernel = machine__create_kernel(self);
if (kernel == NULL ||
__machine__create_kernel_maps(self, kernel) < 0)
return -1;
if (symbol_conf.use_modules && machine__create_modules(self) < 0)
pr_debug("Problems creating module maps, continuing anyway...\n");
/*
* Now that we have all the maps created, just set the ->end of them:
*/
map_groups__fixup_end(&self->kmaps);
return 0;
}
static void vmlinux_path__exit(void) static void vmlinux_path__exit(void)
{ {
while (--vmlinux_path__nr_entries >= 0) { while (--vmlinux_path__nr_entries >= 0) {
...@@ -2144,25 +2161,12 @@ int symbol__init(void) ...@@ -2144,25 +2161,12 @@ int symbol__init(void)
int machines__create_kernel_maps(struct rb_root *self, pid_t pid) int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
{ {
struct dso *kernel;
struct machine *machine = machines__findnew(self, pid); struct machine *machine = machines__findnew(self, pid);
if (machine == NULL) if (machine == NULL)
return -1; return -1;
kernel = dsos__create_kernel(machine);
if (kernel == NULL)
return -1;
if (__machine__create_kernel_maps(machine, kernel) < 0)
return -1;
if (symbol_conf.use_modules && machine__create_modules(machine) < 0) return machine__create_kernel_maps(machine);
pr_debug("Problems creating module maps, continuing anyway...\n");
/*
* Now that we have all the maps created, just set the ->end of them:
*/
map_groups__fixup_end(&machine->kmaps);
return 0;
} }
static int hex(char ch) static int hex(char ch)
...@@ -2248,3 +2252,36 @@ int machines__create_guest_kernel_maps(struct rb_root *self) ...@@ -2248,3 +2252,36 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
return ret; return ret;
} }
int machine__load_kallsyms(struct machine *self, const char *filename,
enum map_type type, symbol_filter_t filter)
{
struct map *map = self->vmlinux_maps[type];
int ret = dso__load_kallsyms(map->dso, filename, map, filter);
if (ret > 0) {
dso__set_loaded(map->dso, type);
/*
* Since /proc/kallsyms will have multiple sessions for the
* kernel, with modules between them, fixup the end of all
* sections.
*/
__map_groups__fixup_end(&self->kmaps, type);
}
return ret;
}
int machine__load_vmlinux_path(struct machine *self, enum map_type type,
symbol_filter_t filter)
{
struct map *map = self->vmlinux_maps[type];
int ret = dso__load_vmlinux_path(map->dso, map, filter);
if (ret > 0) {
dso__set_loaded(map->dso, type);
map__reloc_vmlinux(map);
}
return ret;
}
...@@ -162,6 +162,11 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map, ...@@ -162,6 +162,11 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
symbol_filter_t filter); symbol_filter_t filter);
int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
symbol_filter_t filter); symbol_filter_t filter);
int machine__load_kallsyms(struct machine *self, const char *filename,
enum map_type type, symbol_filter_t filter);
int machine__load_vmlinux_path(struct machine *self, enum map_type type,
symbol_filter_t filter);
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
...@@ -199,6 +204,8 @@ int kallsyms__parse(const char *filename, void *arg, ...@@ -199,6 +204,8 @@ int kallsyms__parse(const char *filename, void *arg,
char type, u64 start)); char type, u64 start));
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel); int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
int machine__create_kernel_maps(struct machine *self);
int machines__create_kernel_maps(struct rb_root *self, pid_t pid); int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
int machines__create_guest_kernel_maps(struct rb_root *self); int machines__create_guest_kernel_maps(struct rb_root *self);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册