diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-23 13:39:10 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-23 13:51:48 -0500 |
commit | cc612d8199089413719397c9d92e5823da578eac (patch) | |
tree | aec84294a839bc82b738326ed5f338e6ebc47a30 /tools/perf/util/symbol.c | |
parent | 1b290d670ffa883b7e062177463a8efd00eaa2c1 (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/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 113 |
1 files changed, 101 insertions, 12 deletions
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); | |||
34 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 34 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
35 | symbol_filter_t filter); | 35 | symbol_filter_t filter); |
36 | unsigned int symbol__priv_size; | 36 | unsigned int symbol__priv_size; |
37 | static int vmlinux_path__nr_entries; | ||
38 | static char **vmlinux_path; | ||
37 | 39 | ||
38 | static struct rb_root kernel_maps; | 40 | static struct rb_root kernel_maps; |
39 | 41 | ||
@@ -1386,15 +1388,43 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1386 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 1388 | static 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); | ||
1420 | do_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) { |
1427 | out_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 | ||
1405 | LIST_HEAD(dsos); | 1435 | LIST_HEAD(dsos); |
1406 | struct dso *vdso; | 1436 | struct dso *vdso; |
1407 | |||
1408 | const char *vmlinux_name = "vmlinux"; | ||
1409 | 1437 | ||
1410 | static void dsos__add(struct dso *dso) | 1438 | static 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 | ||
1460 | static int kernel_maps__create_kernel_map(void) | 1488 | static 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 | ||
1497 | int kernel_maps__init(bool use_modules) | 1525 | static 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 | |||
1536 | static 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 | |||
1575 | out_fail: | ||
1576 | vmlinux_path__exit(); | ||
1577 | return -1; | ||
1578 | } | ||
1579 | |||
1580 | int 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"); |