diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 07b92c378ae2..6d770ac7be0b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -948,7 +948,12 @@ static int symbol_filter(struct map *map, struct symbol *sym) static int parse_symbols(void) { - if (dsos__load_kernel(vmlinux_name, symbol_filter, 1) <= 0) + struct dso *kernel = dsos__load_kernel(); + + if (kernel == NULL) + return -1; + + if (dso__load_kernel_sym(kernel, symbol_filter, 1) <= 0) return -1; if (dump_symtab) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d3d656f9a621..425a29ba01a9 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -241,6 +241,7 @@ perf_header__adds_write(struct perf_header *self, int fd) buildid_sec = &feat_sec[idx++]; + dsos__load_kernel(); /* * Read the list of loaded modules with its build_ids */ diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 7b4cedeb3020..4d75e745288f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1352,17 +1352,11 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, return err; } -int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, - int use_modules) +int dso__load_kernel_sym(struct dso *self, symbol_filter_t filter, int use_modules) { int err = -1; - struct dso *dso = dso__new(vmlinux); - if (dso == NULL) - return -1; - - dso->short_name = "[kernel]"; - kernel_map = map__new2(0, dso); + kernel_map = map__new2(0, self); if (kernel_map == NULL) goto out_delete_dso; @@ -1374,39 +1368,36 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, use_modules = 0; } - if (vmlinux) { - err = dso__load_vmlinux(dso, kernel_map, vmlinux, filter); - if (err > 0 && use_modules) { - int syms = dsos__load_modules_sym(filter); + err = dso__load_vmlinux(self, kernel_map, self->name, filter); + if (err > 0 && use_modules) { + int syms = dsos__load_modules_sym(filter); - if (syms < 0) - pr_warning("Failed to read module symbols!" - " Continuing...\n"); - else - err += syms; - } + if (syms < 0) + pr_warning("Failed to read module symbols!" + " Continuing...\n"); + else + err += syms; } if (err <= 0) err = kernel_maps__load_kallsyms(filter, use_modules); if (err > 0) { - struct rb_node *node = rb_first(&dso->syms); + struct rb_node *node = rb_first(&self->syms); struct symbol *sym = rb_entry(node, struct symbol, rb_node); kernel_map->start = sym->start; - node = rb_last(&dso->syms); + node = rb_last(&self->syms); sym = rb_entry(node, struct symbol, rb_node); kernel_map->end = sym->end; - dso->origin = DSO__ORIG_KERNEL; + self->origin = DSO__ORIG_KERNEL; kernel_maps__insert(kernel_map); /* * Now that we have all sorted out, just set the ->end of all * maps: */ kernel_maps__fixup_end(); - dsos__add(dso); if (verbose) kernel_maps__fprintf(stderr); @@ -1415,7 +1406,7 @@ int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, return err; out_delete_dso: - dso__delete(dso); + dso__delete(self); return -1; } @@ -1475,18 +1466,36 @@ size_t dsos__fprintf_buildid(FILE *fp) return ret; } -int load_kernel(symbol_filter_t filter) +struct dso *dsos__load_kernel(void) { - if (dsos__load_kernel(vmlinux_name, filter, modules) <= 0) - return -1; + struct dso *kernel = dso__new(vmlinux_name); + if (kernel == NULL) + return NULL; + + kernel->short_name = "[kernel]"; vdso = dso__new("[vdso]"); if (!vdso) - return -1; + return NULL; + if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id, + sizeof(kernel->build_id)) == 0) + kernel->has_build_id = true; + + dsos__add(kernel); dsos__add(vdso); - return 0; + return kernel; +} + +int load_kernel(symbol_filter_t filter) +{ + struct dso *kernel = dsos__load_kernel(); + + if (kernel == NULL) + return -1; + + return dso__load_kernel_sym(kernel, filter, modules); } void symbol__init(unsigned int priv_size) diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index da7ec1af255a..f0593a649c3d 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -77,10 +77,10 @@ void dso__delete(struct dso *self); struct symbol *dso__find_symbol(struct dso *self, u64 ip); -int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, int modules); int dsos__load_modules(void); struct dso *dsos__findnew(const char *name); int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); +int dso__load_kernel_sym(struct dso *self, symbol_filter_t filter, int modules); void dsos__fprintf(FILE *fp); size_t dsos__fprintf_buildid(FILE *fp); @@ -94,6 +94,7 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); bool dsos__read_build_ids(void); int build_id__sprintf(u8 *self, int len, char *bf); +struct dso *dsos__load_kernel(void); int load_kernel(symbol_filter_t filter); void symbol__init(unsigned int priv_size);