diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-27 13:29:20 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-27 14:22:00 -0500 |
commit | 95011c600740837288a3b34b411244a4d9157c4e (patch) | |
tree | f52496d2d378a338e7b0eee9b75e627bdfc4d2f1 /tools/perf/util/symbol.c | |
parent | 23ea4a3fadc6b1692dec935397ea15e2affc1cba (diff) |
perf symbols: Support multiple symtabs in struct thread
Making the routines that were so far specific to the kernel maps
useful for all threads.
This is done by making the kernel maps be contained in a kernel
"thread".
This gets the kernel specific routines closer to the userspace
counterparts, which will help in reducing the boilerplate for
resolving a symbol, as will be demonstrated in the next patches.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259346563-12568-9-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 157 |
1 files changed, 58 insertions, 99 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 581db4c43251..b6a2941e7786 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -29,12 +29,11 @@ enum dso_origin { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static void dsos__add(struct list_head *head, struct dso *dso); | 31 | static void dsos__add(struct list_head *head, struct dso *dso); |
32 | static struct map *kernel_maps__find_by_dso_name(const char *name); | 32 | static struct map *thread__find_map_by_name(struct thread *self, char *name); |
33 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); | 33 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); |
34 | static void kernel_maps__insert(struct map *map); | ||
35 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); | 34 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); |
36 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 35 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
37 | symbol_filter_t filter); | 36 | struct thread *thread, symbol_filter_t filter); |
38 | unsigned int symbol__priv_size; | 37 | unsigned int symbol__priv_size; |
39 | static int vmlinux_path__nr_entries; | 38 | static int vmlinux_path__nr_entries; |
40 | static char **vmlinux_path; | 39 | static char **vmlinux_path; |
@@ -44,7 +43,7 @@ static struct symbol_conf symbol_conf__defaults = { | |||
44 | .try_vmlinux_path = true, | 43 | .try_vmlinux_path = true, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | static struct rb_root kernel_maps[MAP__NR_TYPES]; | 46 | static struct thread kthread_mem, *kthread = &kthread_mem; |
48 | 47 | ||
49 | bool dso__loaded(const struct dso *self, enum map_type type) | 48 | bool dso__loaded(const struct dso *self, enum map_type type) |
50 | { | 49 | { |
@@ -79,10 +78,10 @@ static void symbols__fixup_end(struct rb_root *self) | |||
79 | curr->end = roundup(curr->start, 4096); | 78 | curr->end = roundup(curr->start, 4096); |
80 | } | 79 | } |
81 | 80 | ||
82 | static void __kernel_maps__fixup_end(struct rb_root *root) | 81 | static void __thread__fixup_maps_end(struct thread *self, enum map_type type) |
83 | { | 82 | { |
84 | struct map *prev, *curr; | 83 | struct map *prev, *curr; |
85 | struct rb_node *nd, *prevnd = rb_first(root); | 84 | struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); |
86 | 85 | ||
87 | if (prevnd == NULL) | 86 | if (prevnd == NULL) |
88 | return; | 87 | return; |
@@ -102,11 +101,11 @@ static void __kernel_maps__fixup_end(struct rb_root *root) | |||
102 | curr->end = ~0UL; | 101 | curr->end = ~0UL; |
103 | } | 102 | } |
104 | 103 | ||
105 | static void kernel_maps__fixup_end(void) | 104 | static void thread__fixup_maps_end(struct thread *self) |
106 | { | 105 | { |
107 | int i; | 106 | int i; |
108 | for (i = 0; i < MAP__NR_TYPES; ++i) | 107 | for (i = 0; i < MAP__NR_TYPES; ++i) |
109 | __kernel_maps__fixup_end(&kernel_maps[i]); | 108 | __thread__fixup_maps_end(self, i); |
110 | } | 109 | } |
111 | 110 | ||
112 | static struct symbol *symbol__new(u64 start, u64 len, const char *name) | 111 | static struct symbol *symbol__new(u64 start, u64 len, const char *name) |
@@ -274,25 +273,16 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp) | |||
274 | return fprintf(fp, "%s", sbuild_id); | 273 | return fprintf(fp, "%s", sbuild_id); |
275 | } | 274 | } |
276 | 275 | ||
277 | static const char * map_type__name[MAP__NR_TYPES] = { | 276 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) |
278 | [MAP__FUNCTION] = "Functions", | ||
279 | }; | ||
280 | |||
281 | size_t dso__fprintf(struct dso *self, FILE *fp) | ||
282 | { | 277 | { |
283 | int i; | ||
284 | struct rb_node *nd; | 278 | struct rb_node *nd; |
285 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); | 279 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); |
286 | 280 | ||
287 | ret += dso__fprintf_buildid(self, fp); | 281 | ret += dso__fprintf_buildid(self, fp); |
288 | ret += fprintf(fp, ")\n"); | 282 | ret += fprintf(fp, ")\n"); |
289 | for (i = 0; i < MAP__NR_TYPES; ++i) { | 283 | for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) { |
290 | ret += fprintf(fp, "%s:\n", map_type__name[i]); | 284 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
291 | 285 | ret += symbol__fprintf(pos, fp); | |
292 | for (nd = rb_first(&self->symbols[i]); nd; nd = rb_next(nd)) { | ||
293 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | ||
294 | ret += symbol__fprintf(pos, fp); | ||
295 | } | ||
296 | } | 286 | } |
297 | 287 | ||
298 | return ret; | 288 | return ret; |
@@ -373,7 +363,7 @@ out_failure: | |||
373 | * kernel range is broken in several maps, named [kernel].N, as we don't have | 363 | * kernel range is broken in several maps, named [kernel].N, as we don't have |
374 | * the original ELF section names vmlinux have. | 364 | * the original ELF section names vmlinux have. |
375 | */ | 365 | */ |
376 | static int dso__split_kallsyms(struct dso *self, struct map *map, | 366 | static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread, |
377 | symbol_filter_t filter) | 367 | symbol_filter_t filter) |
378 | { | 368 | { |
379 | struct map *curr_map = map; | 369 | struct map *curr_map = map; |
@@ -394,10 +384,10 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
394 | *module++ = '\0'; | 384 | *module++ = '\0'; |
395 | 385 | ||
396 | if (strcmp(self->name, module)) { | 386 | if (strcmp(self->name, module)) { |
397 | curr_map = kernel_maps__find_by_dso_name(module); | 387 | curr_map = thread__find_map_by_name(thread, module); |
398 | if (curr_map == NULL) { | 388 | if (curr_map == NULL) { |
399 | pr_err("/proc/{kallsyms,modules} " | 389 | pr_debug("/proc/{kallsyms,modules} " |
400 | "inconsistency!\n"); | 390 | "inconsistency!\n"); |
401 | return -1; | 391 | return -1; |
402 | } | 392 | } |
403 | } | 393 | } |
@@ -425,7 +415,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
425 | } | 415 | } |
426 | 416 | ||
427 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; | 417 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; |
428 | kernel_maps__insert(curr_map); | 418 | __thread__insert_map(thread, curr_map); |
429 | ++kernel_range; | 419 | ++kernel_range; |
430 | } | 420 | } |
431 | 421 | ||
@@ -446,7 +436,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
446 | 436 | ||
447 | 437 | ||
448 | static int dso__load_kallsyms(struct dso *self, struct map *map, | 438 | static int dso__load_kallsyms(struct dso *self, struct map *map, |
449 | symbol_filter_t filter) | 439 | struct thread *thread, symbol_filter_t filter) |
450 | { | 440 | { |
451 | if (dso__load_all_kallsyms(self, map) < 0) | 441 | if (dso__load_all_kallsyms(self, map) < 0) |
452 | return -1; | 442 | return -1; |
@@ -454,35 +444,13 @@ static int dso__load_kallsyms(struct dso *self, struct map *map, | |||
454 | symbols__fixup_end(&self->symbols[map->type]); | 444 | symbols__fixup_end(&self->symbols[map->type]); |
455 | self->origin = DSO__ORIG_KERNEL; | 445 | self->origin = DSO__ORIG_KERNEL; |
456 | 446 | ||
457 | return dso__split_kallsyms(self, map, filter); | 447 | return dso__split_kallsyms(self, map, thread, filter); |
458 | } | ||
459 | |||
460 | static size_t __kernel_maps__fprintf(enum map_type type, FILE *fp) | ||
461 | { | ||
462 | size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); | ||
463 | struct rb_node *nd; | ||
464 | |||
465 | for (nd = rb_first(&kernel_maps[type]); nd; nd = rb_next(nd)) { | ||
466 | struct map *pos = rb_entry(nd, struct map, rb_node); | ||
467 | |||
468 | printed += fprintf(fp, "Map:"); | ||
469 | printed += map__fprintf(pos, fp); | ||
470 | if (verbose > 1) { | ||
471 | printed += dso__fprintf(pos->dso, fp); | ||
472 | printed += fprintf(fp, "--\n"); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | return printed; | ||
477 | } | 448 | } |
478 | 449 | ||
479 | size_t kernel_maps__fprintf(FILE *fp) | 450 | size_t kernel_maps__fprintf(FILE *fp) |
480 | { | 451 | { |
481 | size_t printed = fprintf(fp, "Kernel maps:\n"); | 452 | size_t printed = fprintf(fp, "Kernel maps:\n"); |
482 | int i; | 453 | printed += thread__fprintf_maps(kthread, fp); |
483 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
484 | printed += __kernel_maps__fprintf(i, fp); | ||
485 | |||
486 | return printed + fprintf(fp, "END kernel maps\n"); | 454 | return printed + fprintf(fp, "END kernel maps\n"); |
487 | } | 455 | } |
488 | 456 | ||
@@ -772,9 +740,9 @@ out: | |||
772 | return 0; | 740 | return 0; |
773 | } | 741 | } |
774 | 742 | ||
775 | static int dso__load_sym(struct dso *self, struct map *map, const char *name, | 743 | static int dso__load_sym(struct dso *self, struct map *map, |
776 | int fd, symbol_filter_t filter, int kernel, | 744 | struct thread *thread, const char *name, int fd, |
777 | int kmodule) | 745 | symbol_filter_t filter, int kernel, int kmodule) |
778 | { | 746 | { |
779 | struct map *curr_map = map; | 747 | struct map *curr_map = map; |
780 | struct dso *curr_dso = self; | 748 | struct dso *curr_dso = self; |
@@ -877,7 +845,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
877 | snprintf(dso_name, sizeof(dso_name), | 845 | snprintf(dso_name, sizeof(dso_name), |
878 | "%s%s", self->short_name, section_name); | 846 | "%s%s", self->short_name, section_name); |
879 | 847 | ||
880 | curr_map = kernel_maps__find_by_dso_name(dso_name); | 848 | curr_map = thread__find_map_by_name(thread, dso_name); |
881 | if (curr_map == NULL) { | 849 | if (curr_map == NULL) { |
882 | u64 start = sym.st_value; | 850 | u64 start = sym.st_value; |
883 | 851 | ||
@@ -896,7 +864,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
896 | curr_map->map_ip = identity__map_ip; | 864 | curr_map->map_ip = identity__map_ip; |
897 | curr_map->unmap_ip = identity__map_ip; | 865 | curr_map->unmap_ip = identity__map_ip; |
898 | curr_dso->origin = DSO__ORIG_KERNEL; | 866 | curr_dso->origin = DSO__ORIG_KERNEL; |
899 | kernel_maps__insert(curr_map); | 867 | __thread__insert_map(kthread, curr_map); |
900 | dsos__add(&dsos__kernel, curr_dso); | 868 | dsos__add(&dsos__kernel, curr_dso); |
901 | } else | 869 | } else |
902 | curr_dso = curr_map->dso; | 870 | curr_dso = curr_map->dso; |
@@ -1121,7 +1089,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1121 | dso__set_loaded(self, map->type); | 1089 | dso__set_loaded(self, map->type); |
1122 | 1090 | ||
1123 | if (self->kernel) | 1091 | if (self->kernel) |
1124 | return dso__load_kernel_sym(self, map, filter); | 1092 | return dso__load_kernel_sym(self, map, kthread, filter); |
1125 | 1093 | ||
1126 | name = malloc(size); | 1094 | name = malloc(size); |
1127 | if (!name) | 1095 | if (!name) |
@@ -1186,7 +1154,7 @@ compare_build_id: | |||
1186 | fd = open(name, O_RDONLY); | 1154 | fd = open(name, O_RDONLY); |
1187 | } while (fd < 0); | 1155 | } while (fd < 0); |
1188 | 1156 | ||
1189 | ret = dso__load_sym(self, map, name, fd, filter, 0, 0); | 1157 | ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0); |
1190 | close(fd); | 1158 | close(fd); |
1191 | 1159 | ||
1192 | /* | 1160 | /* |
@@ -1207,16 +1175,11 @@ out: | |||
1207 | return ret; | 1175 | return ret; |
1208 | } | 1176 | } |
1209 | 1177 | ||
1210 | static void kernel_maps__insert(struct map *map) | 1178 | static struct symbol *thread__find_symbol(struct thread *self, u64 ip, |
1211 | { | 1179 | enum map_type type, struct map **mapp, |
1212 | maps__insert(&kernel_maps[map->type], map); | 1180 | symbol_filter_t filter) |
1213 | } | ||
1214 | |||
1215 | static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type, | ||
1216 | struct map **mapp, | ||
1217 | symbol_filter_t filter) | ||
1218 | { | 1181 | { |
1219 | struct map *map = maps__find(&kernel_maps[type], ip); | 1182 | struct map *map = thread__find_map(self, type, ip); |
1220 | 1183 | ||
1221 | if (mapp) | 1184 | if (mapp) |
1222 | *mapp = map; | 1185 | *mapp = map; |
@@ -1224,9 +1187,7 @@ static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type, | |||
1224 | if (map) { | 1187 | if (map) { |
1225 | ip = map->map_ip(map, ip); | 1188 | ip = map->map_ip(map, ip); |
1226 | return map__find_symbol(map, ip, filter); | 1189 | return map__find_symbol(map, ip, filter); |
1227 | } else | 1190 | } |
1228 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps[type]), | ||
1229 | "Empty kernel_maps, was symbol__init() called?\n"); | ||
1230 | 1191 | ||
1231 | return NULL; | 1192 | return NULL; |
1232 | } | 1193 | } |
@@ -1234,14 +1195,14 @@ static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type, | |||
1234 | struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp, | 1195 | struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp, |
1235 | symbol_filter_t filter) | 1196 | symbol_filter_t filter) |
1236 | { | 1197 | { |
1237 | return kernel_maps__find_symbol(ip, MAP__FUNCTION, mapp, filter); | 1198 | return thread__find_symbol(kthread, ip, MAP__FUNCTION, mapp, filter); |
1238 | } | 1199 | } |
1239 | 1200 | ||
1240 | static struct map *kernel_maps__find_by_dso_name(const char *name) | 1201 | static struct map *thread__find_map_by_name(struct thread *self, char *name) |
1241 | { | 1202 | { |
1242 | struct rb_node *nd; | 1203 | struct rb_node *nd; |
1243 | 1204 | ||
1244 | for (nd = rb_first(&kernel_maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { | 1205 | for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { |
1245 | struct map *map = rb_entry(nd, struct map, rb_node); | 1206 | struct map *map = rb_entry(nd, struct map, rb_node); |
1246 | 1207 | ||
1247 | if (map->dso && strcmp(map->dso->name, name) == 0) | 1208 | if (map->dso && strcmp(map->dso->name, name) == 0) |
@@ -1285,7 +1246,7 @@ static int dsos__set_modules_path_dir(char *dirname) | |||
1285 | (int)(dot - dent->d_name), dent->d_name); | 1246 | (int)(dot - dent->d_name), dent->d_name); |
1286 | 1247 | ||
1287 | strxfrchar(dso_name, '-', '_'); | 1248 | strxfrchar(dso_name, '-', '_'); |
1288 | map = kernel_maps__find_by_dso_name(dso_name); | 1249 | map = thread__find_map_by_name(kthread, dso_name); |
1289 | if (map == NULL) | 1250 | if (map == NULL) |
1290 | continue; | 1251 | continue; |
1291 | 1252 | ||
@@ -1338,7 +1299,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) | |||
1338 | return self; | 1299 | return self; |
1339 | } | 1300 | } |
1340 | 1301 | ||
1341 | static int kernel_maps__create_module_maps(void) | 1302 | static int thread__create_module_maps(struct thread *self) |
1342 | { | 1303 | { |
1343 | char *line = NULL; | 1304 | char *line = NULL; |
1344 | size_t n; | 1305 | size_t n; |
@@ -1395,7 +1356,7 @@ static int kernel_maps__create_module_maps(void) | |||
1395 | dso->has_build_id = true; | 1356 | dso->has_build_id = true; |
1396 | 1357 | ||
1397 | dso->origin = DSO__ORIG_KMODULE; | 1358 | dso->origin = DSO__ORIG_KMODULE; |
1398 | kernel_maps__insert(map); | 1359 | __thread__insert_map(self, map); |
1399 | dsos__add(&dsos__kernel, dso); | 1360 | dsos__add(&dsos__kernel, dso); |
1400 | } | 1361 | } |
1401 | 1362 | ||
@@ -1410,7 +1371,7 @@ out_failure: | |||
1410 | return -1; | 1371 | return -1; |
1411 | } | 1372 | } |
1412 | 1373 | ||
1413 | static int dso__load_vmlinux(struct dso *self, struct map *map, | 1374 | static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread, |
1414 | const char *vmlinux, symbol_filter_t filter) | 1375 | const char *vmlinux, symbol_filter_t filter) |
1415 | { | 1376 | { |
1416 | int err = -1, fd; | 1377 | int err = -1, fd; |
@@ -1444,15 +1405,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1444 | return -1; | 1405 | return -1; |
1445 | 1406 | ||
1446 | dso__set_loaded(self, map->type); | 1407 | dso__set_loaded(self, map->type); |
1447 | err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0); | 1408 | err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0); |
1448 | |||
1449 | close(fd); | 1409 | close(fd); |
1450 | 1410 | ||
1451 | return err; | 1411 | return err; |
1452 | } | 1412 | } |
1453 | 1413 | ||
1454 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 1414 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
1455 | symbol_filter_t filter) | 1415 | struct thread *thread, symbol_filter_t filter) |
1456 | { | 1416 | { |
1457 | int err; | 1417 | int err; |
1458 | bool is_kallsyms; | 1418 | bool is_kallsyms; |
@@ -1462,8 +1422,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1462 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", | 1422 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", |
1463 | vmlinux_path__nr_entries); | 1423 | vmlinux_path__nr_entries); |
1464 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { | 1424 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { |
1465 | err = dso__load_vmlinux(self, map, vmlinux_path[i], | 1425 | err = dso__load_vmlinux(self, map, thread, |
1466 | filter); | 1426 | vmlinux_path[i], filter); |
1467 | if (err > 0) { | 1427 | if (err > 0) { |
1468 | pr_debug("Using %s for symbols\n", | 1428 | pr_debug("Using %s for symbols\n", |
1469 | vmlinux_path[i]); | 1429 | vmlinux_path[i]); |
@@ -1478,12 +1438,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1478 | if (is_kallsyms) | 1438 | if (is_kallsyms) |
1479 | goto do_kallsyms; | 1439 | goto do_kallsyms; |
1480 | 1440 | ||
1481 | err = dso__load_vmlinux(self, map, self->long_name, filter); | 1441 | err = dso__load_vmlinux(self, map, thread, self->long_name, filter); |
1482 | if (err <= 0) { | 1442 | if (err <= 0) { |
1483 | pr_info("The file %s cannot be used, " | 1443 | pr_info("The file %s cannot be used, " |
1484 | "trying to use /proc/kallsyms...", self->long_name); | 1444 | "trying to use /proc/kallsyms...", self->long_name); |
1485 | do_kallsyms: | 1445 | do_kallsyms: |
1486 | err = dso__load_kallsyms(self, map, filter); | 1446 | err = dso__load_kallsyms(self, map, thread, filter); |
1487 | if (err > 0 && !is_kallsyms) | 1447 | if (err > 0 && !is_kallsyms) |
1488 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); | 1448 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); |
1489 | } | 1449 | } |
@@ -1535,8 +1495,11 @@ static void __dsos__fprintf(struct list_head *head, FILE *fp) | |||
1535 | { | 1495 | { |
1536 | struct dso *pos; | 1496 | struct dso *pos; |
1537 | 1497 | ||
1538 | list_for_each_entry(pos, head, node) | 1498 | list_for_each_entry(pos, head, node) { |
1539 | dso__fprintf(pos, fp); | 1499 | int i; |
1500 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
1501 | dso__fprintf(pos, i, fp); | ||
1502 | } | ||
1540 | } | 1503 | } |
1541 | 1504 | ||
1542 | void dsos__fprintf(FILE *fp) | 1505 | void dsos__fprintf(FILE *fp) |
@@ -1563,10 +1526,10 @@ size_t dsos__fprintf_buildid(FILE *fp) | |||
1563 | __dsos__fprintf_buildid(&dsos__user, fp)); | 1526 | __dsos__fprintf_buildid(&dsos__user, fp)); |
1564 | } | 1527 | } |
1565 | 1528 | ||
1566 | static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | 1529 | static int thread__create_kernel_map(struct thread *self, const char *vmlinux) |
1567 | { | 1530 | { |
1568 | struct map *kmap; | 1531 | struct map *kmap; |
1569 | struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]"); | 1532 | struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]"); |
1570 | 1533 | ||
1571 | if (kernel == NULL) | 1534 | if (kernel == NULL) |
1572 | return -1; | 1535 | return -1; |
@@ -1588,7 +1551,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | |||
1588 | sizeof(kernel->build_id)) == 0) | 1551 | sizeof(kernel->build_id)) == 0) |
1589 | kernel->has_build_id = true; | 1552 | kernel->has_build_id = true; |
1590 | 1553 | ||
1591 | kernel_maps__insert(kmap); | 1554 | __thread__insert_map(self, kmap); |
1592 | dsos__add(&dsos__kernel, kernel); | 1555 | dsos__add(&dsos__kernel, kernel); |
1593 | dsos__add(&dsos__user, vdso); | 1556 | dsos__add(&dsos__user, vdso); |
1594 | 1557 | ||
@@ -1656,32 +1619,28 @@ out_fail: | |||
1656 | return -1; | 1619 | return -1; |
1657 | } | 1620 | } |
1658 | 1621 | ||
1659 | static int kernel_maps__init(const struct symbol_conf *conf) | 1622 | int symbol__init(struct symbol_conf *conf) |
1660 | { | 1623 | { |
1661 | const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; | 1624 | const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; |
1662 | 1625 | ||
1626 | elf_version(EV_CURRENT); | ||
1663 | symbol__priv_size = pconf->priv_size; | 1627 | symbol__priv_size = pconf->priv_size; |
1628 | thread__init(kthread, 0); | ||
1664 | 1629 | ||
1665 | if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) | 1630 | if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) |
1666 | return -1; | 1631 | return -1; |
1667 | 1632 | ||
1668 | if (kernel_maps__create_kernel_map(pconf) < 0) { | 1633 | if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) { |
1669 | vmlinux_path__exit(); | 1634 | vmlinux_path__exit(); |
1670 | return -1; | 1635 | return -1; |
1671 | } | 1636 | } |
1672 | 1637 | ||
1673 | if (pconf->use_modules && kernel_maps__create_module_maps() < 0) | 1638 | if (pconf->use_modules && thread__create_module_maps(kthread) < 0) |
1674 | pr_debug("Failed to load list of modules in use, " | 1639 | pr_debug("Failed to load list of modules in use, " |
1675 | "continuing...\n"); | 1640 | "continuing...\n"); |
1676 | /* | 1641 | /* |
1677 | * Now that we have all the maps created, just set the ->end of them: | 1642 | * Now that we have all the maps created, just set the ->end of them: |
1678 | */ | 1643 | */ |
1679 | kernel_maps__fixup_end(); | 1644 | thread__fixup_maps_end(kthread); |
1680 | return 0; | 1645 | return 0; |
1681 | } | 1646 | } |
1682 | |||
1683 | int symbol__init(struct symbol_conf *conf) | ||
1684 | { | ||
1685 | elf_version(EV_CURRENT); | ||
1686 | return kernel_maps__init(conf); | ||
1687 | } | ||