aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-12-13 16:50:29 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-14 10:57:17 -0500
commit4aa65636411ccb12f006a6ad593930655c445ff6 (patch)
tree0f494705a2a7631070a5372bb53f873684b001c2 /tools/perf/util/symbol.c
parentb3165f414416a717f72a376720564012af5a2e01 (diff)
perf session: Move kmaps to perf_session
There is still some more work to do to disentangle map creation from DSO loading, but this happens only for the kernel, and for the early adopters of perf diff, where this disentanglement matters most, we'll be testing different kernels, so no problem here. Further clarification: right now we create the kernel maps for the various modules and discontiguous kernel text maps when loading the DSO, we should do it as a two step process, first creating the maps, for multiple mappings with the same DSO store, then doing the dso load just once, for the first hit on one of the maps sharing this DSO backing store. 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: <1260741029-4430-6-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.c89
1 files changed, 44 insertions, 45 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index d3d9fed74f1d..185b9eec192b 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,5 +1,6 @@
1#include "util.h" 1#include "util.h"
2#include "../perf.h" 2#include "../perf.h"
3#include "session.h"
3#include "string.h" 4#include "string.h"
4#include "symbol.h" 5#include "symbol.h"
5#include "thread.h" 6#include "thread.h"
@@ -31,7 +32,7 @@ enum dso_origin {
31static void dsos__add(struct list_head *head, struct dso *dso); 32static void dsos__add(struct list_head *head, struct dso *dso);
32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 33static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
33static int dso__load_kernel_sym(struct dso *self, struct map *map, 34static int dso__load_kernel_sym(struct dso *self, struct map *map,
34 struct map_groups *mg, symbol_filter_t filter); 35 struct perf_session *session, symbol_filter_t filter);
35unsigned int symbol__priv_size; 36unsigned int symbol__priv_size;
36static int vmlinux_path__nr_entries; 37static int vmlinux_path__nr_entries;
37static char **vmlinux_path; 38static char **vmlinux_path;
@@ -41,9 +42,6 @@ static struct symbol_conf symbol_conf__defaults = {
41 .try_vmlinux_path = true, 42 .try_vmlinux_path = true,
42}; 43};
43 44
44static struct map_groups kmaps_mem;
45struct map_groups *kmaps = &kmaps_mem;
46
47bool dso__loaded(const struct dso *self, enum map_type type) 45bool dso__loaded(const struct dso *self, enum map_type type)
48{ 46{
49 return self->loaded & (1 << type); 47 return self->loaded & (1 << type);
@@ -456,7 +454,7 @@ out_failure:
456 * the original ELF section names vmlinux have. 454 * the original ELF section names vmlinux have.
457 */ 455 */
458static int dso__split_kallsyms(struct dso *self, struct map *map, 456static int dso__split_kallsyms(struct dso *self, struct map *map,
459 struct map_groups *mg, symbol_filter_t filter) 457 struct perf_session *session, symbol_filter_t filter)
460{ 458{
461 struct map *curr_map = map; 459 struct map *curr_map = map;
462 struct symbol *pos; 460 struct symbol *pos;
@@ -473,13 +471,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
473 471
474 module = strchr(pos->name, '\t'); 472 module = strchr(pos->name, '\t');
475 if (module) { 473 if (module) {
476 if (!mg->use_modules) 474 if (!session->use_modules)
477 goto discard_symbol; 475 goto discard_symbol;
478 476
479 *module++ = '\0'; 477 *module++ = '\0';
480 478
481 if (strcmp(self->name, module)) { 479 if (strcmp(self->name, module)) {
482 curr_map = map_groups__find_by_name(mg, map->type, module); 480 curr_map = map_groups__find_by_name(&session->kmaps, map->type, module);
483 if (curr_map == NULL) { 481 if (curr_map == NULL) {
484 pr_debug("/proc/{kallsyms,modules} " 482 pr_debug("/proc/{kallsyms,modules} "
485 "inconsistency!\n"); 483 "inconsistency!\n");
@@ -510,7 +508,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
510 } 508 }
511 509
512 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 510 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
513 map_groups__insert(mg, curr_map); 511 map_groups__insert(&session->kmaps, curr_map);
514 ++kernel_range; 512 ++kernel_range;
515 } 513 }
516 514
@@ -531,7 +529,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
531 529
532 530
533static int dso__load_kallsyms(struct dso *self, struct map *map, 531static int dso__load_kallsyms(struct dso *self, struct map *map,
534 struct map_groups *mg, symbol_filter_t filter) 532 struct perf_session *session, symbol_filter_t filter)
535{ 533{
536 if (dso__load_all_kallsyms(self, map) < 0) 534 if (dso__load_all_kallsyms(self, map) < 0)
537 return -1; 535 return -1;
@@ -539,14 +537,7 @@ static int dso__load_kallsyms(struct dso *self, struct map *map,
539 symbols__fixup_end(&self->symbols[map->type]); 537 symbols__fixup_end(&self->symbols[map->type]);
540 self->origin = DSO__ORIG_KERNEL; 538 self->origin = DSO__ORIG_KERNEL;
541 539
542 return dso__split_kallsyms(self, map, mg, filter); 540 return dso__split_kallsyms(self, map, session, filter);
543}
544
545size_t kernel_maps__fprintf(FILE *fp)
546{
547 size_t printed = fprintf(fp, "Kernel maps:\n");
548 printed += map_groups__fprintf_maps(kmaps, fp);
549 return printed + fprintf(fp, "END kernel maps\n");
550} 541}
551 542
552static int dso__load_perf_map(struct dso *self, struct map *map, 543static int dso__load_perf_map(struct dso *self, struct map *map,
@@ -873,7 +864,7 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
873} 864}
874 865
875static int dso__load_sym(struct dso *self, struct map *map, 866static int dso__load_sym(struct dso *self, struct map *map,
876 struct map_groups *mg, const char *name, int fd, 867 struct perf_session *session, const char *name, int fd,
877 symbol_filter_t filter, int kernel, int kmodule) 868 symbol_filter_t filter, int kernel, int kmodule)
878{ 869{
879 struct map *curr_map = map; 870 struct map *curr_map = map;
@@ -977,7 +968,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
977 snprintf(dso_name, sizeof(dso_name), 968 snprintf(dso_name, sizeof(dso_name),
978 "%s%s", self->short_name, section_name); 969 "%s%s", self->short_name, section_name);
979 970
980 curr_map = map_groups__find_by_name(mg, map->type, dso_name); 971 curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name);
981 if (curr_map == NULL) { 972 if (curr_map == NULL) {
982 u64 start = sym.st_value; 973 u64 start = sym.st_value;
983 974
@@ -996,7 +987,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
996 curr_map->map_ip = identity__map_ip; 987 curr_map->map_ip = identity__map_ip;
997 curr_map->unmap_ip = identity__map_ip; 988 curr_map->unmap_ip = identity__map_ip;
998 curr_dso->origin = DSO__ORIG_KERNEL; 989 curr_dso->origin = DSO__ORIG_KERNEL;
999 map_groups__insert(kmaps, curr_map); 990 map_groups__insert(&session->kmaps, curr_map);
1000 dsos__add(&dsos__kernel, curr_dso); 991 dsos__add(&dsos__kernel, curr_dso);
1001 } else 992 } else
1002 curr_dso = curr_map->dso; 993 curr_dso = curr_map->dso;
@@ -1211,7 +1202,8 @@ char dso__symtab_origin(const struct dso *self)
1211 return origin[self->origin]; 1202 return origin[self->origin];
1212} 1203}
1213 1204
1214int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1205int dso__load(struct dso *self, struct map *map, struct perf_session *session,
1206 symbol_filter_t filter)
1215{ 1207{
1216 int size = PATH_MAX; 1208 int size = PATH_MAX;
1217 char *name; 1209 char *name;
@@ -1222,7 +1214,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1222 dso__set_loaded(self, map->type); 1214 dso__set_loaded(self, map->type);
1223 1215
1224 if (self->kernel) 1216 if (self->kernel)
1225 return dso__load_kernel_sym(self, map, kmaps, filter); 1217 return dso__load_kernel_sym(self, map, session, filter);
1226 1218
1227 name = malloc(size); 1219 name = malloc(size);
1228 if (!name) 1220 if (!name)
@@ -1323,7 +1315,7 @@ struct map *map_groups__find_by_name(struct map_groups *self,
1323 return NULL; 1315 return NULL;
1324} 1316}
1325 1317
1326static int dsos__set_modules_path_dir(char *dirname) 1318static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname)
1327{ 1319{
1328 struct dirent *dent; 1320 struct dirent *dent;
1329 DIR *dir = opendir(dirname); 1321 DIR *dir = opendir(dirname);
@@ -1343,7 +1335,7 @@ static int dsos__set_modules_path_dir(char *dirname)
1343 1335
1344 snprintf(path, sizeof(path), "%s/%s", 1336 snprintf(path, sizeof(path), "%s/%s",
1345 dirname, dent->d_name); 1337 dirname, dent->d_name);
1346 if (dsos__set_modules_path_dir(path) < 0) 1338 if (perf_session__set_modules_path_dir(self, path) < 0)
1347 goto failure; 1339 goto failure;
1348 } else { 1340 } else {
1349 char *dot = strrchr(dent->d_name, '.'), 1341 char *dot = strrchr(dent->d_name, '.'),
@@ -1357,7 +1349,7 @@ static int dsos__set_modules_path_dir(char *dirname)
1357 (int)(dot - dent->d_name), dent->d_name); 1349 (int)(dot - dent->d_name), dent->d_name);
1358 1350
1359 strxfrchar(dso_name, '-', '_'); 1351 strxfrchar(dso_name, '-', '_');
1360 map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name); 1352 map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name);
1361 if (map == NULL) 1353 if (map == NULL)
1362 continue; 1354 continue;
1363 1355
@@ -1377,7 +1369,7 @@ failure:
1377 return -1; 1369 return -1;
1378} 1370}
1379 1371
1380static int dsos__set_modules_path(void) 1372static int perf_session__set_modules_path(struct perf_session *self)
1381{ 1373{
1382 struct utsname uts; 1374 struct utsname uts;
1383 char modules_path[PATH_MAX]; 1375 char modules_path[PATH_MAX];
@@ -1388,7 +1380,7 @@ static int dsos__set_modules_path(void)
1388 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1380 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1389 uts.release); 1381 uts.release);
1390 1382
1391 return dsos__set_modules_path_dir(modules_path); 1383 return perf_session__set_modules_path_dir(self, modules_path);
1392} 1384}
1393 1385
1394/* 1386/*
@@ -1410,7 +1402,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1410 return self; 1402 return self;
1411} 1403}
1412 1404
1413static int map_groups__create_module_maps(struct map_groups *self) 1405static int perf_session__create_module_maps(struct perf_session *self)
1414{ 1406{
1415 char *line = NULL; 1407 char *line = NULL;
1416 size_t n; 1408 size_t n;
@@ -1467,14 +1459,14 @@ static int map_groups__create_module_maps(struct map_groups *self)
1467 dso->has_build_id = true; 1459 dso->has_build_id = true;
1468 1460
1469 dso->origin = DSO__ORIG_KMODULE; 1461 dso->origin = DSO__ORIG_KMODULE;
1470 map_groups__insert(self, map); 1462 map_groups__insert(&self->kmaps, map);
1471 dsos__add(&dsos__kernel, dso); 1463 dsos__add(&dsos__kernel, dso);
1472 } 1464 }
1473 1465
1474 free(line); 1466 free(line);
1475 fclose(file); 1467 fclose(file);
1476 1468
1477 return dsos__set_modules_path(); 1469 return perf_session__set_modules_path(self);
1478 1470
1479out_delete_line: 1471out_delete_line:
1480 free(line); 1472 free(line);
@@ -1483,7 +1475,7 @@ out_failure:
1483} 1475}
1484 1476
1485static int dso__load_vmlinux(struct dso *self, struct map *map, 1477static int dso__load_vmlinux(struct dso *self, struct map *map,
1486 struct map_groups *mg, 1478 struct perf_session *session,
1487 const char *vmlinux, symbol_filter_t filter) 1479 const char *vmlinux, symbol_filter_t filter)
1488{ 1480{
1489 int err = -1, fd; 1481 int err = -1, fd;
@@ -1517,14 +1509,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1517 return -1; 1509 return -1;
1518 1510
1519 dso__set_loaded(self, map->type); 1511 dso__set_loaded(self, map->type);
1520 err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0); 1512 err = dso__load_sym(self, map, session, self->long_name, fd, filter, 1, 0);
1521 close(fd); 1513 close(fd);
1522 1514
1523 return err; 1515 return err;
1524} 1516}
1525 1517
1526static int dso__load_kernel_sym(struct dso *self, struct map *map, 1518static int dso__load_kernel_sym(struct dso *self, struct map *map,
1527 struct map_groups *mg, symbol_filter_t filter) 1519 struct perf_session *session, symbol_filter_t filter)
1528{ 1520{
1529 int err; 1521 int err;
1530 bool is_kallsyms; 1522 bool is_kallsyms;
@@ -1534,7 +1526,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1534 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1526 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1535 vmlinux_path__nr_entries); 1527 vmlinux_path__nr_entries);
1536 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1528 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1537 err = dso__load_vmlinux(self, map, mg, 1529 err = dso__load_vmlinux(self, map, session,
1538 vmlinux_path[i], filter); 1530 vmlinux_path[i], filter);
1539 if (err > 0) { 1531 if (err > 0) {
1540 pr_debug("Using %s for symbols\n", 1532 pr_debug("Using %s for symbols\n",
@@ -1550,12 +1542,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1550 if (is_kallsyms) 1542 if (is_kallsyms)
1551 goto do_kallsyms; 1543 goto do_kallsyms;
1552 1544
1553 err = dso__load_vmlinux(self, map, mg, self->long_name, filter); 1545 err = dso__load_vmlinux(self, map, session, self->long_name, filter);
1554 if (err <= 0) { 1546 if (err <= 0) {
1555 pr_info("The file %s cannot be used, " 1547 pr_info("The file %s cannot be used, "
1556 "trying to use /proc/kallsyms...", self->long_name); 1548 "trying to use /proc/kallsyms...", self->long_name);
1557do_kallsyms: 1549do_kallsyms:
1558 err = dso__load_kallsyms(self, map, mg, filter); 1550 err = dso__load_kallsyms(self, map, session, filter);
1559 if (err > 0 && !is_kallsyms) 1551 if (err > 0 && !is_kallsyms)
1560 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1552 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1561 } 1553 }
@@ -1757,23 +1749,30 @@ int symbol__init(struct symbol_conf *conf)
1757 if (pconf->sort_by_name) 1749 if (pconf->sort_by_name)
1758 symbol__priv_size += (sizeof(struct symbol_name_rb_node) - 1750 symbol__priv_size += (sizeof(struct symbol_name_rb_node) -
1759 sizeof(struct symbol)); 1751 sizeof(struct symbol));
1760 map_groups__init(kmaps);
1761 1752
1762 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) 1753 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1763 return -1; 1754 return -1;
1764 1755
1765 if (map_groups__create_kernel_maps(kmaps, pconf->vmlinux_name) < 0) { 1756 return 0;
1766 vmlinux_path__exit(); 1757}
1758
1759int perf_session__create_kernel_maps(struct perf_session *self,
1760 struct symbol_conf *conf)
1761{
1762 const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
1763
1764 if (map_groups__create_kernel_maps(&self->kmaps,
1765 pconf->vmlinux_name) < 0)
1767 return -1; 1766 return -1;
1768 }
1769 1767
1770 kmaps->use_modules = pconf->use_modules; 1768 self->use_modules = pconf->use_modules;
1771 if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0) 1769
1772 pr_debug("Failed to load list of modules in use, " 1770 if (pconf->use_modules && perf_session__create_module_maps(self) < 0)
1773 "continuing...\n"); 1771 pr_debug("Failed to load list of modules for session %s, "
1772 "continuing...\n", self->filename);
1774 /* 1773 /*
1775 * Now that we have all the maps created, just set the ->end of them: 1774 * Now that we have all the maps created, just set the ->end of them:
1776 */ 1775 */
1777 map_groups__fixup_end(kmaps); 1776 map_groups__fixup_end(&self->kmaps);
1778 return 0; 1777 return 0;
1779} 1778}