aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-23 13:39:10 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-23 13:51:48 -0500
commitcc612d8199089413719397c9d92e5823da578eac (patch)
treeaec84294a839bc82b738326ed5f338e6ebc47a30 /tools/perf/util
parent1b290d670ffa883b7e062177463a8efd00eaa2c1 (diff)
perf symbols: Look for vmlinux in more places
Now that we can check the buildid to see if it really matches, this can be done safely: vmlinux /boot/vmlinux /boot/vmlinux-<uts.release> /lib/modules/<uts.release>/build/vmlinux /usr/lib/debug/lib/modules/%s/vmlinux More can be added - if you know about distros that put the vmlinux somewhere else please let us know. 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: <1259001550-8194-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/data_map.c4
-rw-r--r--tools/perf/util/data_map.h2
-rw-r--r--tools/perf/util/header.c2
-rw-r--r--tools/perf/util/symbol.c113
-rw-r--r--tools/perf/util/symbol.h4
5 files changed, 109 insertions, 16 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index e7b6c2bea3de..f318d19b2562 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -101,6 +101,8 @@ out:
101 101
102int mmap_dispatch_perf_file(struct perf_header **pheader, 102int mmap_dispatch_perf_file(struct perf_header **pheader,
103 const char *input_name, 103 const char *input_name,
104 const char *vmlinux_name,
105 bool try_vmlinux_path,
104 int force, 106 int force,
105 int full_paths, 107 int full_paths,
106 int *cwdlen, 108 int *cwdlen,
@@ -171,7 +173,7 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
171 goto out_delete; 173 goto out_delete;
172 174
173 err = -ENOMEM; 175 err = -ENOMEM;
174 if (kernel_maps__init(true) < 0) { 176 if (kernel_maps__init(vmlinux_name, try_vmlinux_path, true) < 0) {
175 pr_err("failed to setup the kernel maps to resolve symbols\n"); 177 pr_err("failed to setup the kernel maps to resolve symbols\n");
176 goto out_delete; 178 goto out_delete;
177 } 179 }
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index ae036ecd7625..3f0d21b3819e 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -23,6 +23,8 @@ struct perf_file_handler {
23void register_perf_file_handler(struct perf_file_handler *handler); 23void register_perf_file_handler(struct perf_file_handler *handler);
24int mmap_dispatch_perf_file(struct perf_header **pheader, 24int mmap_dispatch_perf_file(struct perf_header **pheader,
25 const char *input_name, 25 const char *input_name,
26 const char *vmlinux_name,
27 bool try_vmlinux_path,
26 int force, 28 int force,
27 int full_paths, 29 int full_paths,
28 int *cwdlen, 30 int *cwdlen,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ac3410b8e9e3..1332f8ec04aa 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -257,7 +257,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
257 * Read the kernel buildid nad the list of loaded modules with 257 * Read the kernel buildid nad the list of loaded modules with
258 * its build_ids: 258 * its build_ids:
259 */ 259 */
260 kernel_maps__init(true); 260 kernel_maps__init(NULL, false, true);
261 261
262 /* Write build-ids */ 262 /* Write build-ids */
263 buildid_sec->offset = lseek(fd, 0, SEEK_CUR); 263 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 74b5b8a16951..44d81d5ae8cf 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -34,6 +34,8 @@ static void kernel_maps__insert(struct map *map);
34static int dso__load_kernel_sym(struct dso *self, struct map *map, 34static int dso__load_kernel_sym(struct dso *self, struct map *map,
35 symbol_filter_t filter); 35 symbol_filter_t filter);
36unsigned int symbol__priv_size; 36unsigned int symbol__priv_size;
37static int vmlinux_path__nr_entries;
38static char **vmlinux_path;
37 39
38static struct rb_root kernel_maps; 40static struct rb_root kernel_maps;
39 41
@@ -1386,15 +1388,43 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1386static int dso__load_kernel_sym(struct dso *self, struct map *map, 1388static int dso__load_kernel_sym(struct dso *self, struct map *map,
1387 symbol_filter_t filter) 1389 symbol_filter_t filter)
1388{ 1390{
1389 int err = dso__load_vmlinux(self, map, self->name, filter); 1391 int err;
1392 bool is_kallsyms;
1393
1394 if (vmlinux_path != NULL) {
1395 int i;
1396 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1397 vmlinux_path__nr_entries);
1398 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1399 err = dso__load_vmlinux(self, map, vmlinux_path[i],
1400 filter);
1401 if (err > 0) {
1402 pr_debug("Using %s for symbols\n",
1403 vmlinux_path[i]);
1404 dso__set_long_name(self,
1405 strdup(vmlinux_path[i]));
1406 goto out_fixup;
1407 }
1408 }
1409 }
1410
1411 is_kallsyms = self->long_name[0] == '[';
1412 if (is_kallsyms)
1413 goto do_kallsyms;
1390 1414
1415 err = dso__load_vmlinux(self, map, self->long_name, filter);
1391 if (err <= 0) { 1416 if (err <= 0) {
1417 pr_info("The file %s cannot be used, "
1418 "trying to use /proc/kallsyms...", self->long_name);
1419 sleep(2);
1420do_kallsyms:
1392 err = kernel_maps__load_kallsyms(filter); 1421 err = kernel_maps__load_kallsyms(filter);
1393 if (err > 0) 1422 if (err > 0 && !is_kallsyms)
1394 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1423 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1395 } 1424 }
1396 1425
1397 if (err > 0) { 1426 if (err > 0) {
1427out_fixup:
1398 map__fixup_start(map); 1428 map__fixup_start(map);
1399 map__fixup_end(map); 1429 map__fixup_end(map);
1400 } 1430 }
@@ -1403,9 +1433,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1403} 1433}
1404 1434
1405LIST_HEAD(dsos); 1435LIST_HEAD(dsos);
1406struct dso *vdso; 1436struct dso *vdso;
1407
1408const char *vmlinux_name = "vmlinux";
1409 1437
1410static void dsos__add(struct dso *dso) 1438static void dsos__add(struct dso *dso)
1411{ 1439{
@@ -1457,9 +1485,9 @@ size_t dsos__fprintf_buildid(FILE *fp)
1457 return ret; 1485 return ret;
1458} 1486}
1459 1487
1460static int kernel_maps__create_kernel_map(void) 1488static int kernel_maps__create_kernel_map(const char *vmlinux_name)
1461{ 1489{
1462 struct dso *kernel = dso__new(vmlinux_name); 1490 struct dso *kernel = dso__new(vmlinux_name ?: "[kernel.kallsyms]");
1463 1491
1464 if (kernel == NULL) 1492 if (kernel == NULL)
1465 return -1; 1493 return -1;
@@ -1468,10 +1496,10 @@ static int kernel_maps__create_kernel_map(void)
1468 if (kernel_map == NULL) 1496 if (kernel_map == NULL)
1469 goto out_delete_kernel_dso; 1497 goto out_delete_kernel_dso;
1470 1498
1471 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip; 1499 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip;
1500 kernel->short_name = "[kernel]";
1501 kernel->kernel = 1;
1472 1502
1473 kernel->short_name = "[kernel]";
1474 kernel->kernel = 1;
1475 vdso = dso__new("[vdso]"); 1503 vdso = dso__new("[vdso]");
1476 if (vdso == NULL) 1504 if (vdso == NULL)
1477 goto out_delete_kernel_map; 1505 goto out_delete_kernel_map;
@@ -1494,11 +1522,72 @@ out_delete_kernel_dso:
1494 return -1; 1522 return -1;
1495} 1523}
1496 1524
1497int kernel_maps__init(bool use_modules) 1525static void vmlinux_path__exit(void)
1526{
1527 while (--vmlinux_path__nr_entries >= 0) {
1528 free(vmlinux_path[vmlinux_path__nr_entries]);
1529 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1530 }
1531
1532 free(vmlinux_path);
1533 vmlinux_path = NULL;
1534}
1535
1536static int vmlinux_path__init(void)
1537{
1538 struct utsname uts;
1539 char bf[PATH_MAX];
1540
1541 if (uname(&uts) < 0)
1542 return -1;
1543
1544 vmlinux_path = malloc(sizeof(char *) * 5);
1545 if (vmlinux_path == NULL)
1546 return -1;
1547
1548 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1549 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1550 goto out_fail;
1551 ++vmlinux_path__nr_entries;
1552 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1553 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1554 goto out_fail;
1555 ++vmlinux_path__nr_entries;
1556 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1557 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1558 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1559 goto out_fail;
1560 ++vmlinux_path__nr_entries;
1561 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1562 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1563 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1564 goto out_fail;
1565 ++vmlinux_path__nr_entries;
1566 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1567 uts.release);
1568 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1569 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1570 goto out_fail;
1571 ++vmlinux_path__nr_entries;
1572
1573 return 0;
1574
1575out_fail:
1576 vmlinux_path__exit();
1577 return -1;
1578}
1579
1580int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path,
1581 bool use_modules)
1498{ 1582{
1499 if (kernel_maps__create_kernel_map() < 0) 1583 if (try_vmlinux_path && vmlinux_path__init() < 0)
1500 return -1; 1584 return -1;
1501 1585
1586 if (kernel_maps__create_kernel_map(vmlinux_name) < 0) {
1587 vmlinux_path__exit();
1588 return -1;
1589 }
1590
1502 if (use_modules && kernel_maps__create_module_maps() < 0) 1591 if (use_modules && kernel_maps__create_module_maps() < 0)
1503 pr_debug("Failed to load list of modules in use, " 1592 pr_debug("Failed to load list of modules in use, "
1504 "continuing...\n"); 1593 "continuing...\n");
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 7a129047c47d..8c4d026e067a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -93,7 +93,8 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
93bool dsos__read_build_ids(void); 93bool dsos__read_build_ids(void);
94int build_id__sprintf(u8 *self, int len, char *bf); 94int build_id__sprintf(u8 *self, int len, char *bf);
95 95
96int kernel_maps__init(bool use_modules); 96int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path,
97 bool use_modules);
97size_t kernel_maps__fprintf(FILE *fp); 98size_t kernel_maps__fprintf(FILE *fp);
98 99
99void symbol__init(unsigned int priv_size); 100void symbol__init(unsigned int priv_size);
@@ -101,5 +102,4 @@ void symbol__init(unsigned int priv_size);
101extern struct list_head dsos; 102extern struct list_head dsos;
102extern struct map *kernel_map; 103extern struct map *kernel_map;
103extern struct dso *vdso; 104extern struct dso *vdso;
104extern const char *vmlinux_name;
105#endif /* __PERF_SYMBOL */ 105#endif /* __PERF_SYMBOL */