|
@@ -26,27 +26,35 @@ enum dso_origin {
|
|
|
|
|
|
static void dsos__add(struct dso *dso);
|
|
static void dsos__add(struct dso *dso);
|
|
static struct dso *dsos__find(const char *name);
|
|
static struct dso *dsos__find(const char *name);
|
|
|
|
+static struct map *map__new2(u64 start, struct dso *dso);
|
|
|
|
+static void kernel_maps__insert(struct map *map);
|
|
|
|
|
|
static struct rb_root kernel_maps;
|
|
static struct rb_root kernel_maps;
|
|
|
|
|
|
-static void dso__set_symbols_end(struct dso *self)
|
|
|
|
|
|
+static void dso__fixup_sym_end(struct dso *self)
|
|
{
|
|
{
|
|
struct rb_node *nd, *prevnd = rb_first(&self->syms);
|
|
struct rb_node *nd, *prevnd = rb_first(&self->syms);
|
|
|
|
+ struct symbol *curr, *prev;
|
|
|
|
|
|
if (prevnd == NULL)
|
|
if (prevnd == NULL)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ curr = rb_entry(prevnd, struct symbol, rb_node);
|
|
|
|
+
|
|
for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
|
|
for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
|
|
- struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
|
|
|
|
- *curr = rb_entry(nd, struct symbol, rb_node);
|
|
|
|
|
|
+ prev = curr;
|
|
|
|
+ curr = rb_entry(nd, struct symbol, rb_node);
|
|
|
|
|
|
if (prev->end == prev->start)
|
|
if (prev->end == prev->start)
|
|
prev->end = curr->start - 1;
|
|
prev->end = curr->start - 1;
|
|
- prevnd = nd;
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /* Last entry */
|
|
|
|
+ if (curr->end == curr->start)
|
|
|
|
+ curr->end = roundup(curr->start, 4096);
|
|
}
|
|
}
|
|
|
|
|
|
-static void kernel_maps__fixup_sym_end(void)
|
|
|
|
|
|
+static void kernel_maps__fixup_end(void)
|
|
{
|
|
{
|
|
struct map *prev, *curr;
|
|
struct map *prev, *curr;
|
|
struct rb_node *nd, *prevnd = rb_first(&kernel_maps);
|
|
struct rb_node *nd, *prevnd = rb_first(&kernel_maps);
|
|
@@ -55,13 +63,17 @@ static void kernel_maps__fixup_sym_end(void)
|
|
return;
|
|
return;
|
|
|
|
|
|
curr = rb_entry(prevnd, struct map, rb_node);
|
|
curr = rb_entry(prevnd, struct map, rb_node);
|
|
- dso__set_symbols_end(curr->dso);
|
|
|
|
|
|
|
|
for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
|
|
for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
|
|
prev = curr;
|
|
prev = curr;
|
|
curr = rb_entry(nd, struct map, rb_node);
|
|
curr = rb_entry(nd, struct map, rb_node);
|
|
prev->end = curr->start - 1;
|
|
prev->end = curr->start - 1;
|
|
- dso__set_symbols_end(curr->dso);
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nd = rb_last(&curr->dso->syms);
|
|
|
|
+ if (nd) {
|
|
|
|
+ struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
|
|
|
|
+ curr->end = sym->end;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -200,13 +212,16 @@ size_t dso__fprintf(struct dso *self, FILE *fp)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v)
|
|
|
|
|
|
+/*
|
|
|
|
+ * Loads the function entries in /proc/kallsyms into kernel_map->dso,
|
|
|
|
+ * so that we can in the next step set the symbol ->end address and then
|
|
|
|
+ * call kernel_maps__split_kallsyms.
|
|
|
|
+ */
|
|
|
|
+static int kernel_maps__load_all_kallsyms(int v)
|
|
{
|
|
{
|
|
- struct map *map = kernel_map;
|
|
|
|
char *line = NULL;
|
|
char *line = NULL;
|
|
size_t n;
|
|
size_t n;
|
|
FILE *file = fopen("/proc/kallsyms", "r");
|
|
FILE *file = fopen("/proc/kallsyms", "r");
|
|
- int count = 0;
|
|
|
|
|
|
|
|
if (file == NULL)
|
|
if (file == NULL)
|
|
goto out_failure;
|
|
goto out_failure;
|
|
@@ -216,7 +231,7 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v)
|
|
struct symbol *sym;
|
|
struct symbol *sym;
|
|
int line_len, len;
|
|
int line_len, len;
|
|
char symbol_type;
|
|
char symbol_type;
|
|
- char *module, *symbol_name;
|
|
|
|
|
|
+ char *symbol_name;
|
|
|
|
|
|
line_len = getline(&line, &n, file);
|
|
line_len = getline(&line, &n, file);
|
|
if (line_len < 0)
|
|
if (line_len < 0)
|
|
@@ -241,20 +256,55 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
symbol_name = line + len + 2;
|
|
symbol_name = line + len + 2;
|
|
- module = strchr(symbol_name, '\t');
|
|
|
|
- if (module) {
|
|
|
|
- char *module_name_end;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Will fix up the end later, when we have all symbols sorted.
|
|
|
|
+ */
|
|
|
|
+ sym = symbol__new(start, 0, symbol_name,
|
|
|
|
+ kernel_map->dso->sym_priv_size, v);
|
|
|
|
|
|
|
|
+ if (sym == NULL)
|
|
|
|
+ goto out_delete_line;
|
|
|
|
+
|
|
|
|
+ dso__insert_symbol(kernel_map->dso, sym);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ free(line);
|
|
|
|
+ fclose(file);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+out_delete_line:
|
|
|
|
+ free(line);
|
|
|
|
+out_failure:
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Split the symbols into maps, making sure there are no overlaps, i.e. the
|
|
|
|
+ * kernel range is broken in several maps, named [kernel].N, as we don't have
|
|
|
|
+ * the original ELF section names vmlinux have.
|
|
|
|
+ */
|
|
|
|
+static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules)
|
|
|
|
+{
|
|
|
|
+ struct map *map = kernel_map;
|
|
|
|
+ struct symbol *pos;
|
|
|
|
+ int count = 0;
|
|
|
|
+ struct rb_node *next = rb_first(&kernel_map->dso->syms);
|
|
|
|
+ int kernel_range = 0;
|
|
|
|
+
|
|
|
|
+ while (next) {
|
|
|
|
+ char *module;
|
|
|
|
+
|
|
|
|
+ pos = rb_entry(next, struct symbol, rb_node);
|
|
|
|
+ next = rb_next(&pos->rb_node);
|
|
|
|
+
|
|
|
|
+ module = strchr(pos->name, '\t');
|
|
|
|
+ if (module) {
|
|
if (!use_modules)
|
|
if (!use_modules)
|
|
- continue;
|
|
|
|
- *module = '\0';
|
|
|
|
- module = strchr(module + 1, '[');
|
|
|
|
- if (!module)
|
|
|
|
- continue;
|
|
|
|
- module_name_end = strchr(module + 1, ']');
|
|
|
|
- if (!module_name_end)
|
|
|
|
- continue;
|
|
|
|
- *(module_name_end + 1) = '\0';
|
|
|
|
|
|
+ goto delete_symbol;
|
|
|
|
+
|
|
|
|
+ *module++ = '\0';
|
|
|
|
+
|
|
if (strcmp(map->dso->name, module)) {
|
|
if (strcmp(map->dso->name, module)) {
|
|
map = kernel_maps__find_by_dso_name(module);
|
|
map = kernel_maps__find_by_dso_name(module);
|
|
if (!map) {
|
|
if (!map) {
|
|
@@ -263,50 +313,77 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- start = map->map_ip(map, start);
|
|
|
|
- } else
|
|
|
|
- map = kernel_map;
|
|
|
|
- /*
|
|
|
|
- * Well fix up the end later, when we have all sorted.
|
|
|
|
- */
|
|
|
|
- sym = symbol__new(start, 0, symbol_name,
|
|
|
|
- map->dso->sym_priv_size, v);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * So that we look just like we get from .ko files,
|
|
|
|
+ * i.e. not prelinked, relative to map->start.
|
|
|
|
+ */
|
|
|
|
+ pos->start = map->map_ip(map, pos->start);
|
|
|
|
+ pos->end = map->map_ip(map, pos->end);
|
|
|
|
+ } else if (map != kernel_map) {
|
|
|
|
+ char dso_name[PATH_MAX];
|
|
|
|
+ struct dso *dso;
|
|
|
|
+
|
|
|
|
+ snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
|
|
|
|
+ kernel_range++);
|
|
|
|
+
|
|
|
|
+ dso = dso__new(dso_name,
|
|
|
|
+ kernel_map->dso->sym_priv_size);
|
|
|
|
+ if (dso == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ map = map__new2(pos->start, dso);
|
|
|
|
+ if (map == NULL) {
|
|
|
|
+ dso__delete(dso);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
|
|
- if (sym == NULL)
|
|
|
|
- goto out_delete_line;
|
|
|
|
|
|
+ map->map_ip = vdso__map_ip;
|
|
|
|
+ kernel_maps__insert(map);
|
|
|
|
+ ++kernel_range;
|
|
|
|
+ }
|
|
|
|
|
|
- if (filter && filter(map, sym))
|
|
|
|
- symbol__delete(sym, map->dso->sym_priv_size);
|
|
|
|
- else {
|
|
|
|
- dso__insert_symbol(map->dso, sym);
|
|
|
|
|
|
+ if (filter && filter(map, pos)) {
|
|
|
|
+delete_symbol:
|
|
|
|
+ rb_erase(&pos->rb_node, &kernel_map->dso->syms);
|
|
|
|
+ symbol__delete(pos, kernel_map->dso->sym_priv_size);
|
|
|
|
+ } else {
|
|
|
|
+ if (map != kernel_map) {
|
|
|
|
+ rb_erase(&pos->rb_node, &kernel_map->dso->syms);
|
|
|
|
+ dso__insert_symbol(map->dso, pos);
|
|
|
|
+ }
|
|
count++;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- free(line);
|
|
|
|
- fclose(file);
|
|
|
|
-
|
|
|
|
return count;
|
|
return count;
|
|
|
|
+}
|
|
|
|
|
|
-out_delete_line:
|
|
|
|
- free(line);
|
|
|
|
-out_failure:
|
|
|
|
- return -1;
|
|
|
|
|
|
+
|
|
|
|
+static int kernel_maps__load_kallsyms(symbol_filter_t filter,
|
|
|
|
+ int use_modules, int v)
|
|
|
|
+{
|
|
|
|
+ if (kernel_maps__load_all_kallsyms(v))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ dso__fixup_sym_end(kernel_map->dso);
|
|
|
|
+
|
|
|
|
+ return kernel_maps__split_kallsyms(filter, use_modules);
|
|
}
|
|
}
|
|
|
|
|
|
-static size_t kernel_maps__fprintf(FILE *fp)
|
|
|
|
|
|
+static size_t kernel_maps__fprintf(FILE *fp, int v)
|
|
{
|
|
{
|
|
size_t printed = fprintf(stderr, "Kernel maps:\n");
|
|
size_t printed = fprintf(stderr, "Kernel maps:\n");
|
|
struct rb_node *nd;
|
|
struct rb_node *nd;
|
|
|
|
|
|
- printed += map__fprintf(kernel_map, fp);
|
|
|
|
- printed += dso__fprintf(kernel_map->dso, fp);
|
|
|
|
-
|
|
|
|
for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) {
|
|
for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) {
|
|
struct map *pos = rb_entry(nd, struct map, rb_node);
|
|
struct map *pos = rb_entry(nd, struct map, rb_node);
|
|
|
|
|
|
|
|
+ printed += fprintf(fp, "Map:");
|
|
printed += map__fprintf(pos, fp);
|
|
printed += map__fprintf(pos, fp);
|
|
- printed += dso__fprintf(pos->dso, fp);
|
|
|
|
|
|
+ if (v > 1) {
|
|
|
|
+ printed += dso__fprintf(pos->dso, fp);
|
|
|
|
+ printed += fprintf(fp, "--\n");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return printed + fprintf(stderr, "END kernel maps\n");
|
|
return printed + fprintf(stderr, "END kernel maps\n");
|
|
@@ -594,6 +671,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
|
|
int fd, symbol_filter_t filter, int kernel,
|
|
int fd, symbol_filter_t filter, int kernel,
|
|
int kmodule, int v)
|
|
int kmodule, int v)
|
|
{
|
|
{
|
|
|
|
+ struct map *curr_map = map;
|
|
|
|
+ struct dso *curr_dso = self;
|
|
|
|
+ size_t dso_name_len = strlen(self->short_name);
|
|
Elf_Data *symstrs, *secstrs;
|
|
Elf_Data *symstrs, *secstrs;
|
|
uint32_t nr_syms;
|
|
uint32_t nr_syms;
|
|
int err = -1;
|
|
int err = -1;
|
|
@@ -660,10 +740,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
|
|
elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
|
|
elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
|
|
struct symbol *f;
|
|
struct symbol *f;
|
|
const char *elf_name;
|
|
const char *elf_name;
|
|
- char *demangled;
|
|
|
|
|
|
+ char *demangled = NULL;
|
|
int is_label = elf_sym__is_label(&sym);
|
|
int is_label = elf_sym__is_label(&sym);
|
|
const char *section_name;
|
|
const char *section_name;
|
|
- u64 sh_offset = 0;
|
|
|
|
|
|
|
|
if (!is_label && !elf_sym__is_function(&sym))
|
|
if (!is_label && !elf_sym__is_function(&sym))
|
|
continue;
|
|
continue;
|
|
@@ -677,14 +756,51 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
|
|
if (is_label && !elf_sec__is_text(&shdr, secstrs))
|
|
if (is_label && !elf_sec__is_text(&shdr, secstrs))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
+ elf_name = elf_sym__name(&sym, symstrs);
|
|
section_name = elf_sec__name(&shdr, secstrs);
|
|
section_name = elf_sec__name(&shdr, secstrs);
|
|
|
|
|
|
- if ((kernel || kmodule)) {
|
|
|
|
- if (strstr(section_name, ".init"))
|
|
|
|
- sh_offset = shdr.sh_offset;
|
|
|
|
|
|
+ if (kernel || kmodule) {
|
|
|
|
+ char dso_name[PATH_MAX];
|
|
|
|
+
|
|
|
|
+ if (strcmp(section_name,
|
|
|
|
+ curr_dso->short_name + dso_name_len) == 0)
|
|
|
|
+ goto new_symbol;
|
|
|
|
+
|
|
|
|
+ if (strcmp(section_name, ".text") == 0) {
|
|
|
|
+ curr_map = map;
|
|
|
|
+ curr_dso = self;
|
|
|
|
+ goto new_symbol;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ snprintf(dso_name, sizeof(dso_name),
|
|
|
|
+ "%s%s", self->short_name, section_name);
|
|
|
|
+
|
|
|
|
+ curr_map = kernel_maps__find_by_dso_name(dso_name);
|
|
|
|
+ if (curr_map == NULL) {
|
|
|
|
+ u64 start = sym.st_value;
|
|
|
|
+
|
|
|
|
+ if (kmodule)
|
|
|
|
+ start += map->start + shdr.sh_offset;
|
|
|
|
+
|
|
|
|
+ curr_dso = dso__new(dso_name, self->sym_priv_size);
|
|
|
|
+ if (curr_dso == NULL)
|
|
|
|
+ goto out_elf_end;
|
|
|
|
+ curr_map = map__new2(start, curr_dso);
|
|
|
|
+ if (curr_map == NULL) {
|
|
|
|
+ dso__delete(curr_dso);
|
|
|
|
+ goto out_elf_end;
|
|
|
|
+ }
|
|
|
|
+ curr_map->map_ip = vdso__map_ip;
|
|
|
|
+ curr_dso->origin = DSO__ORIG_KERNEL;
|
|
|
|
+ kernel_maps__insert(curr_map);
|
|
|
|
+ dsos__add(curr_dso);
|
|
|
|
+ } else
|
|
|
|
+ curr_dso = curr_map->dso;
|
|
|
|
+
|
|
|
|
+ goto new_symbol;
|
|
}
|
|
}
|
|
|
|
|
|
- if (self->adjust_symbols) {
|
|
|
|
|
|
+ if (curr_dso->adjust_symbols) {
|
|
if (v > 2)
|
|
if (v > 2)
|
|
printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
|
|
printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
|
|
(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
|
|
(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
|
|
@@ -696,25 +812,29 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
|
|
* DWARF DW_compile_unit has this, but we don't always have access
|
|
* DWARF DW_compile_unit has this, but we don't always have access
|
|
* to it...
|
|
* to it...
|
|
*/
|
|
*/
|
|
- elf_name = elf_sym__name(&sym, symstrs);
|
|
|
|
demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
|
|
demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
|
|
if (demangled != NULL)
|
|
if (demangled != NULL)
|
|
elf_name = demangled;
|
|
elf_name = demangled;
|
|
-
|
|
|
|
- f = symbol__new(sym.st_value + sh_offset, sym.st_size, elf_name,
|
|
|
|
- self->sym_priv_size, v);
|
|
|
|
|
|
+new_symbol:
|
|
|
|
+ f = symbol__new(sym.st_value, sym.st_size, elf_name,
|
|
|
|
+ curr_dso->sym_priv_size, v);
|
|
free(demangled);
|
|
free(demangled);
|
|
if (!f)
|
|
if (!f)
|
|
goto out_elf_end;
|
|
goto out_elf_end;
|
|
|
|
|
|
- if (filter && filter(map, f))
|
|
|
|
- symbol__delete(f, self->sym_priv_size);
|
|
|
|
|
|
+ if (filter && filter(curr_map, f))
|
|
|
|
+ symbol__delete(f, curr_dso->sym_priv_size);
|
|
else {
|
|
else {
|
|
- dso__insert_symbol(self, f);
|
|
|
|
|
|
+ dso__insert_symbol(curr_dso, f);
|
|
nr++;
|
|
nr++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * For misannotated, zeroed, ASM function sizes.
|
|
|
|
+ */
|
|
|
|
+ if (nr > 0)
|
|
|
|
+ dso__fixup_sym_end(self);
|
|
err = nr;
|
|
err = nr;
|
|
out_elf_end:
|
|
out_elf_end:
|
|
elf_end(elf);
|
|
elf_end(elf);
|
|
@@ -883,27 +1003,17 @@ static void kernel_maps__insert(struct map *map)
|
|
|
|
|
|
struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp)
|
|
struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp)
|
|
{
|
|
{
|
|
- /*
|
|
|
|
- * We can't have kernel_map in kernel_maps because it spans an address
|
|
|
|
- * space that includes the modules. The right way to fix this is to
|
|
|
|
- * create several maps, so that we don't have overlapping ranges with
|
|
|
|
- * modules. For now lets look first on the kernel dso.
|
|
|
|
- */
|
|
|
|
struct map *map = maps__find(&kernel_maps, ip);
|
|
struct map *map = maps__find(&kernel_maps, ip);
|
|
- struct symbol *sym;
|
|
|
|
|
|
+
|
|
|
|
+ if (mapp)
|
|
|
|
+ *mapp = map;
|
|
|
|
|
|
if (map) {
|
|
if (map) {
|
|
ip = map->map_ip(map, ip);
|
|
ip = map->map_ip(map, ip);
|
|
- sym = map->dso->find_symbol(map->dso, ip);
|
|
|
|
- } else {
|
|
|
|
- map = kernel_map;
|
|
|
|
- sym = map->dso->find_symbol(map->dso, ip);
|
|
|
|
|
|
+ return map->dso->find_symbol(map->dso, ip);
|
|
}
|
|
}
|
|
|
|
|
|
- if (mapp)
|
|
|
|
- *mapp = map;
|
|
|
|
-
|
|
|
|
- return sym;
|
|
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
struct map *kernel_maps__find_by_dso_name(const char *name)
|
|
struct map *kernel_maps__find_by_dso_name(const char *name)
|
|
@@ -994,6 +1104,14 @@ static int dsos__load_modules_sym_dir(char *dirname,
|
|
last = rb_last(&map->dso->syms);
|
|
last = rb_last(&map->dso->syms);
|
|
if (last) {
|
|
if (last) {
|
|
struct symbol *sym;
|
|
struct symbol *sym;
|
|
|
|
+ /*
|
|
|
|
+ * We do this here as well, even having the
|
|
|
|
+ * symbol size found in the symtab because
|
|
|
|
+ * misannotated ASM symbols may have the size
|
|
|
|
+ * set to zero.
|
|
|
|
+ */
|
|
|
|
+ dso__fixup_sym_end(map->dso);
|
|
|
|
+
|
|
sym = rb_entry(last, struct symbol, rb_node);
|
|
sym = rb_entry(last, struct symbol, rb_node);
|
|
map->end = map->start + sym->end;
|
|
map->end = map->start + sym->end;
|
|
}
|
|
}
|
|
@@ -1163,17 +1281,11 @@ int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size,
|
|
}
|
|
}
|
|
|
|
|
|
if (err <= 0)
|
|
if (err <= 0)
|
|
- err = maps__load_kallsyms(filter, use_modules, v);
|
|
|
|
|
|
+ err = kernel_maps__load_kallsyms(filter, use_modules, v);
|
|
|
|
|
|
if (err > 0) {
|
|
if (err > 0) {
|
|
struct rb_node *node = rb_first(&dso->syms);
|
|
struct rb_node *node = rb_first(&dso->syms);
|
|
struct symbol *sym = rb_entry(node, struct symbol, rb_node);
|
|
struct symbol *sym = rb_entry(node, struct symbol, rb_node);
|
|
- /*
|
|
|
|
- * Now that we have all sorted out, just set the ->end of all
|
|
|
|
- * symbols that still don't have it.
|
|
|
|
- */
|
|
|
|
- dso__set_symbols_end(dso);
|
|
|
|
- kernel_maps__fixup_sym_end();
|
|
|
|
|
|
|
|
kernel_map->start = sym->start;
|
|
kernel_map->start = sym->start;
|
|
node = rb_last(&dso->syms);
|
|
node = rb_last(&dso->syms);
|
|
@@ -1181,14 +1293,16 @@ int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size,
|
|
kernel_map->end = sym->end;
|
|
kernel_map->end = sym->end;
|
|
|
|
|
|
dso->origin = DSO__ORIG_KERNEL;
|
|
dso->origin = DSO__ORIG_KERNEL;
|
|
|
|
+ kernel_maps__insert(kernel_map);
|
|
/*
|
|
/*
|
|
- * XXX See kernel_maps__find_symbol comment
|
|
|
|
- * 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);
|
|
dsos__add(dso);
|
|
|
|
|
|
if (v > 0)
|
|
if (v > 0)
|
|
- kernel_maps__fprintf(stderr);
|
|
|
|
|
|
+ kernel_maps__fprintf(stderr, v);
|
|
}
|
|
}
|
|
|
|
|
|
return err;
|
|
return err;
|