diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index ceefa6568def..561db6361f57 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -41,6 +41,7 @@ struct symbol_conf symbol_conf = { | |||
41 | .exclude_other = true, | 41 | .exclude_other = true, |
42 | .use_modules = true, | 42 | .use_modules = true, |
43 | .try_vmlinux_path = true, | 43 | .try_vmlinux_path = true, |
44 | .symfs = "", | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | int dso__name_len(const struct dso *self) | 47 | int dso__name_len(const struct dso *self) |
@@ -839,8 +840,11 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, | |||
839 | char sympltname[1024]; | 840 | char sympltname[1024]; |
840 | Elf *elf; | 841 | Elf *elf; |
841 | int nr = 0, symidx, fd, err = 0; | 842 | int nr = 0, symidx, fd, err = 0; |
843 | char name[PATH_MAX]; | ||
842 | 844 | ||
843 | fd = open(self->long_name, O_RDONLY); | 845 | snprintf(name, sizeof(name), "%s%s", |
846 | symbol_conf.symfs, self->long_name); | ||
847 | fd = open(name, O_RDONLY); | ||
844 | if (fd < 0) | 848 | if (fd < 0) |
845 | goto out; | 849 | goto out; |
846 | 850 | ||
@@ -1452,16 +1456,19 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1452 | self->origin++) { | 1456 | self->origin++) { |
1453 | switch (self->origin) { | 1457 | switch (self->origin) { |
1454 | case DSO__ORIG_BUILD_ID_CACHE: | 1458 | case DSO__ORIG_BUILD_ID_CACHE: |
1455 | if (dso__build_id_filename(self, name, size) == NULL) | 1459 | /* skip the locally configured cache if a symfs is given */ |
1460 | if (symbol_conf.symfs[0] || | ||
1461 | (dso__build_id_filename(self, name, size) == NULL)) { | ||
1456 | continue; | 1462 | continue; |
1463 | } | ||
1457 | break; | 1464 | break; |
1458 | case DSO__ORIG_FEDORA: | 1465 | case DSO__ORIG_FEDORA: |
1459 | snprintf(name, size, "/usr/lib/debug%s.debug", | 1466 | snprintf(name, size, "%s/usr/lib/debug%s.debug", |
1460 | self->long_name); | 1467 | symbol_conf.symfs, self->long_name); |
1461 | break; | 1468 | break; |
1462 | case DSO__ORIG_UBUNTU: | 1469 | case DSO__ORIG_UBUNTU: |
1463 | snprintf(name, size, "/usr/lib/debug%s", | 1470 | snprintf(name, size, "%s/usr/lib/debug%s", |
1464 | self->long_name); | 1471 | symbol_conf.symfs, self->long_name); |
1465 | break; | 1472 | break; |
1466 | case DSO__ORIG_BUILDID: { | 1473 | case DSO__ORIG_BUILDID: { |
1467 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | 1474 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; |
@@ -1473,19 +1480,26 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1473 | sizeof(self->build_id), | 1480 | sizeof(self->build_id), |
1474 | build_id_hex); | 1481 | build_id_hex); |
1475 | snprintf(name, size, | 1482 | snprintf(name, size, |
1476 | "/usr/lib/debug/.build-id/%.2s/%s.debug", | 1483 | "%s/usr/lib/debug/.build-id/%.2s/%s.debug", |
1477 | build_id_hex, build_id_hex + 2); | 1484 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); |
1478 | } | 1485 | } |
1479 | break; | 1486 | break; |
1480 | case DSO__ORIG_DSO: | 1487 | case DSO__ORIG_DSO: |
1481 | snprintf(name, size, "%s", self->long_name); | 1488 | snprintf(name, size, "%s%s", |
1489 | symbol_conf.symfs, self->long_name); | ||
1482 | break; | 1490 | break; |
1483 | case DSO__ORIG_GUEST_KMODULE: | 1491 | case DSO__ORIG_GUEST_KMODULE: |
1484 | if (map->groups && map->groups->machine) | 1492 | if (map->groups && map->groups->machine) |
1485 | root_dir = map->groups->machine->root_dir; | 1493 | root_dir = map->groups->machine->root_dir; |
1486 | else | 1494 | else |
1487 | root_dir = ""; | 1495 | root_dir = ""; |
1488 | snprintf(name, size, "%s%s", root_dir, self->long_name); | 1496 | snprintf(name, size, "%s%s%s", symbol_conf.symfs, |
1497 | root_dir, self->long_name); | ||
1498 | break; | ||
1499 | |||
1500 | case DSO__ORIG_KMODULE: | ||
1501 | snprintf(name, size, "%s%s", symbol_conf.symfs, | ||
1502 | self->long_name); | ||
1489 | break; | 1503 | break; |
1490 | 1504 | ||
1491 | default: | 1505 | default: |
@@ -1784,17 +1798,20 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1784 | const char *vmlinux, symbol_filter_t filter) | 1798 | const char *vmlinux, symbol_filter_t filter) |
1785 | { | 1799 | { |
1786 | int err = -1, fd; | 1800 | int err = -1, fd; |
1801 | char symfs_vmlinux[PATH_MAX]; | ||
1787 | 1802 | ||
1788 | fd = open(vmlinux, O_RDONLY); | 1803 | snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s", |
1804 | symbol_conf.symfs, vmlinux); | ||
1805 | fd = open(symfs_vmlinux, O_RDONLY); | ||
1789 | if (fd < 0) | 1806 | if (fd < 0) |
1790 | return -1; | 1807 | return -1; |
1791 | 1808 | ||
1792 | dso__set_loaded(self, map->type); | 1809 | dso__set_loaded(self, map->type); |
1793 | err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0); | 1810 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); |
1794 | close(fd); | 1811 | close(fd); |
1795 | 1812 | ||
1796 | if (err > 0) | 1813 | if (err > 0) |
1797 | pr_debug("Using %s for symbols\n", vmlinux); | 1814 | pr_debug("Using %s for symbols\n", symfs_vmlinux); |
1798 | 1815 | ||
1799 | return err; | 1816 | return err; |
1800 | } | 1817 | } |
@@ -1872,6 +1889,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1872 | goto out_fixup; | 1889 | goto out_fixup; |
1873 | } | 1890 | } |
1874 | 1891 | ||
1892 | /* do not try local files if a symfs was given */ | ||
1893 | if (symbol_conf.symfs[0] != 0) | ||
1894 | return -1; | ||
1895 | |||
1875 | /* | 1896 | /* |
1876 | * Say the kernel DSO was created when processing the build-id header table, | 1897 | * Say the kernel DSO was created when processing the build-id header table, |
1877 | * we have a build-id, so check if it is the same as the running kernel, | 1898 | * we have a build-id, so check if it is the same as the running kernel, |
@@ -2262,9 +2283,6 @@ static int vmlinux_path__init(void) | |||
2262 | struct utsname uts; | 2283 | struct utsname uts; |
2263 | char bf[PATH_MAX]; | 2284 | char bf[PATH_MAX]; |
2264 | 2285 | ||
2265 | if (uname(&uts) < 0) | ||
2266 | return -1; | ||
2267 | |||
2268 | vmlinux_path = malloc(sizeof(char *) * 5); | 2286 | vmlinux_path = malloc(sizeof(char *) * 5); |
2269 | if (vmlinux_path == NULL) | 2287 | if (vmlinux_path == NULL) |
2270 | return -1; | 2288 | return -1; |
@@ -2277,6 +2295,14 @@ static int vmlinux_path__init(void) | |||
2277 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | 2295 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) |
2278 | goto out_fail; | 2296 | goto out_fail; |
2279 | ++vmlinux_path__nr_entries; | 2297 | ++vmlinux_path__nr_entries; |
2298 | |||
2299 | /* only try running kernel version if no symfs was given */ | ||
2300 | if (symbol_conf.symfs[0] != 0) | ||
2301 | return 0; | ||
2302 | |||
2303 | if (uname(&uts) < 0) | ||
2304 | return -1; | ||
2305 | |||
2280 | snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); | 2306 | snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); |
2281 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); | 2307 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); |
2282 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | 2308 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) |
@@ -2336,6 +2362,8 @@ static int setup_list(struct strlist **list, const char *list_str, | |||
2336 | 2362 | ||
2337 | int symbol__init(void) | 2363 | int symbol__init(void) |
2338 | { | 2364 | { |
2365 | const char *symfs; | ||
2366 | |||
2339 | if (symbol_conf.initialized) | 2367 | if (symbol_conf.initialized) |
2340 | return 0; | 2368 | return 0; |
2341 | 2369 | ||
@@ -2364,6 +2392,18 @@ int symbol__init(void) | |||
2364 | symbol_conf.sym_list_str, "symbol") < 0) | 2392 | symbol_conf.sym_list_str, "symbol") < 0) |
2365 | goto out_free_comm_list; | 2393 | goto out_free_comm_list; |
2366 | 2394 | ||
2395 | /* | ||
2396 | * A path to symbols of "/" is identical to "" | ||
2397 | * reset here for simplicity. | ||
2398 | */ | ||
2399 | symfs = realpath(symbol_conf.symfs, NULL); | ||
2400 | if (symfs == NULL) | ||
2401 | symfs = symbol_conf.symfs; | ||
2402 | if (strcmp(symfs, "/") == 0) | ||
2403 | symbol_conf.symfs = ""; | ||
2404 | if (symfs != symbol_conf.symfs) | ||
2405 | free((void *)symfs); | ||
2406 | |||
2367 | symbol_conf.initialized = true; | 2407 | symbol_conf.initialized = true; |
2368 | return 0; | 2408 | return 0; |
2369 | 2409 | ||