diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 97 |
1 files changed, 51 insertions, 46 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 7821d0e6866f..f06c10f092ba 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -207,8 +207,7 @@ struct dso *dso__new(const char *name) | |||
207 | dso__set_short_name(self, self->name); | 207 | dso__set_short_name(self, self->name); |
208 | for (i = 0; i < MAP__NR_TYPES; ++i) | 208 | for (i = 0; i < MAP__NR_TYPES; ++i) |
209 | self->symbols[i] = self->symbol_names[i] = RB_ROOT; | 209 | self->symbols[i] = self->symbol_names[i] = RB_ROOT; |
210 | self->slen_calculated = 0; | 210 | self->symtab_type = SYMTAB__NOT_FOUND; |
211 | self->origin = DSO__ORIG_NOT_FOUND; | ||
212 | self->loaded = 0; | 211 | self->loaded = 0; |
213 | self->sorted_by_name = 0; | 212 | self->sorted_by_name = 0; |
214 | self->has_build_id = 0; | 213 | self->has_build_id = 0; |
@@ -681,9 +680,9 @@ int dso__load_kallsyms(struct dso *self, const char *filename, | |||
681 | return -1; | 680 | return -1; |
682 | 681 | ||
683 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) | 682 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
684 | self->origin = DSO__ORIG_GUEST_KERNEL; | 683 | self->symtab_type = SYMTAB__GUEST_KALLSYMS; |
685 | else | 684 | else |
686 | self->origin = DSO__ORIG_KERNEL; | 685 | self->symtab_type = SYMTAB__KALLSYMS; |
687 | 686 | ||
688 | return dso__split_kallsyms(self, map, filter); | 687 | return dso__split_kallsyms(self, map, filter); |
689 | } | 688 | } |
@@ -1197,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
1197 | if (curr_dso == NULL) | 1196 | if (curr_dso == NULL) |
1198 | goto out_elf_end; | 1197 | goto out_elf_end; |
1199 | curr_dso->kernel = self->kernel; | 1198 | curr_dso->kernel = self->kernel; |
1199 | curr_dso->long_name = self->long_name; | ||
1200 | curr_dso->long_name_len = self->long_name_len; | ||
1200 | curr_map = map__new2(start, curr_dso, | 1201 | curr_map = map__new2(start, curr_dso, |
1201 | map->type); | 1202 | map->type); |
1202 | if (curr_map == NULL) { | 1203 | if (curr_map == NULL) { |
@@ -1205,7 +1206,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
1205 | } | 1206 | } |
1206 | curr_map->map_ip = identity__map_ip; | 1207 | curr_map->map_ip = identity__map_ip; |
1207 | curr_map->unmap_ip = identity__map_ip; | 1208 | curr_map->unmap_ip = identity__map_ip; |
1208 | curr_dso->origin = self->origin; | 1209 | curr_dso->symtab_type = self->symtab_type; |
1209 | map_groups__insert(kmap->kmaps, curr_map); | 1210 | map_groups__insert(kmap->kmaps, curr_map); |
1210 | dsos__add(&self->node, curr_dso); | 1211 | dsos__add(&self->node, curr_dso); |
1211 | dso__set_loaded(curr_dso, map->type); | 1212 | dso__set_loaded(curr_dso, map->type); |
@@ -1431,21 +1432,21 @@ out: | |||
1431 | char dso__symtab_origin(const struct dso *self) | 1432 | char dso__symtab_origin(const struct dso *self) |
1432 | { | 1433 | { |
1433 | static const char origin[] = { | 1434 | static const char origin[] = { |
1434 | [DSO__ORIG_KERNEL] = 'k', | 1435 | [SYMTAB__KALLSYMS] = 'k', |
1435 | [DSO__ORIG_JAVA_JIT] = 'j', | 1436 | [SYMTAB__JAVA_JIT] = 'j', |
1436 | [DSO__ORIG_BUILD_ID_CACHE] = 'B', | 1437 | [SYMTAB__BUILD_ID_CACHE] = 'B', |
1437 | [DSO__ORIG_FEDORA] = 'f', | 1438 | [SYMTAB__FEDORA_DEBUGINFO] = 'f', |
1438 | [DSO__ORIG_UBUNTU] = 'u', | 1439 | [SYMTAB__UBUNTU_DEBUGINFO] = 'u', |
1439 | [DSO__ORIG_BUILDID] = 'b', | 1440 | [SYMTAB__BUILDID_DEBUGINFO] = 'b', |
1440 | [DSO__ORIG_DSO] = 'd', | 1441 | [SYMTAB__SYSTEM_PATH_DSO] = 'd', |
1441 | [DSO__ORIG_KMODULE] = 'K', | 1442 | [SYMTAB__SYSTEM_PATH_KMODULE] = 'K', |
1442 | [DSO__ORIG_GUEST_KERNEL] = 'g', | 1443 | [SYMTAB__GUEST_KALLSYMS] = 'g', |
1443 | [DSO__ORIG_GUEST_KMODULE] = 'G', | 1444 | [SYMTAB__GUEST_KMODULE] = 'G', |
1444 | }; | 1445 | }; |
1445 | 1446 | ||
1446 | if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) | 1447 | if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND) |
1447 | return '!'; | 1448 | return '!'; |
1448 | return origin[self->origin]; | 1449 | return origin[self->symtab_type]; |
1449 | } | 1450 | } |
1450 | 1451 | ||
1451 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | 1452 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) |
@@ -1478,8 +1479,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1478 | 1479 | ||
1479 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) { | 1480 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) { |
1480 | ret = dso__load_perf_map(self, map, filter); | 1481 | ret = dso__load_perf_map(self, map, filter); |
1481 | self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : | 1482 | self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : |
1482 | DSO__ORIG_NOT_FOUND; | 1483 | SYMTAB__NOT_FOUND; |
1483 | return ret; | 1484 | return ret; |
1484 | } | 1485 | } |
1485 | 1486 | ||
@@ -1487,26 +1488,28 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1487 | * On the first pass, only load images if they have a full symtab. | 1488 | * On the first pass, only load images if they have a full symtab. |
1488 | * Failing that, do a second pass where we accept .dynsym also | 1489 | * Failing that, do a second pass where we accept .dynsym also |
1489 | */ | 1490 | */ |
1490 | for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1; | 1491 | want_symtab = 1; |
1491 | self->origin != DSO__ORIG_NOT_FOUND; | 1492 | restart: |
1492 | self->origin++) { | 1493 | for (self->symtab_type = SYMTAB__BUILD_ID_CACHE; |
1493 | switch (self->origin) { | 1494 | self->symtab_type != SYMTAB__NOT_FOUND; |
1494 | case DSO__ORIG_BUILD_ID_CACHE: | 1495 | self->symtab_type++) { |
1496 | switch (self->symtab_type) { | ||
1497 | case SYMTAB__BUILD_ID_CACHE: | ||
1495 | /* skip the locally configured cache if a symfs is given */ | 1498 | /* skip the locally configured cache if a symfs is given */ |
1496 | if (symbol_conf.symfs[0] || | 1499 | if (symbol_conf.symfs[0] || |
1497 | (dso__build_id_filename(self, name, size) == NULL)) { | 1500 | (dso__build_id_filename(self, name, size) == NULL)) { |
1498 | continue; | 1501 | continue; |
1499 | } | 1502 | } |
1500 | break; | 1503 | break; |
1501 | case DSO__ORIG_FEDORA: | 1504 | case SYMTAB__FEDORA_DEBUGINFO: |
1502 | snprintf(name, size, "%s/usr/lib/debug%s.debug", | 1505 | snprintf(name, size, "%s/usr/lib/debug%s.debug", |
1503 | symbol_conf.symfs, self->long_name); | 1506 | symbol_conf.symfs, self->long_name); |
1504 | break; | 1507 | break; |
1505 | case DSO__ORIG_UBUNTU: | 1508 | case SYMTAB__UBUNTU_DEBUGINFO: |
1506 | snprintf(name, size, "%s/usr/lib/debug%s", | 1509 | snprintf(name, size, "%s/usr/lib/debug%s", |
1507 | symbol_conf.symfs, self->long_name); | 1510 | symbol_conf.symfs, self->long_name); |
1508 | break; | 1511 | break; |
1509 | case DSO__ORIG_BUILDID: { | 1512 | case SYMTAB__BUILDID_DEBUGINFO: { |
1510 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | 1513 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; |
1511 | 1514 | ||
1512 | if (!self->has_build_id) | 1515 | if (!self->has_build_id) |
@@ -1520,34 +1523,24 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1520 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); | 1523 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); |
1521 | } | 1524 | } |
1522 | break; | 1525 | break; |
1523 | case DSO__ORIG_DSO: | 1526 | case SYMTAB__SYSTEM_PATH_DSO: |
1524 | snprintf(name, size, "%s%s", | 1527 | snprintf(name, size, "%s%s", |
1525 | symbol_conf.symfs, self->long_name); | 1528 | symbol_conf.symfs, self->long_name); |
1526 | break; | 1529 | break; |
1527 | case DSO__ORIG_GUEST_KMODULE: | 1530 | case SYMTAB__GUEST_KMODULE: |
1528 | if (map->groups && map->groups->machine) | 1531 | if (map->groups && machine) |
1529 | root_dir = map->groups->machine->root_dir; | 1532 | root_dir = machine->root_dir; |
1530 | else | 1533 | else |
1531 | root_dir = ""; | 1534 | root_dir = ""; |
1532 | snprintf(name, size, "%s%s%s", symbol_conf.symfs, | 1535 | snprintf(name, size, "%s%s%s", symbol_conf.symfs, |
1533 | root_dir, self->long_name); | 1536 | root_dir, self->long_name); |
1534 | break; | 1537 | break; |
1535 | 1538 | ||
1536 | case DSO__ORIG_KMODULE: | 1539 | case SYMTAB__SYSTEM_PATH_KMODULE: |
1537 | snprintf(name, size, "%s%s", symbol_conf.symfs, | 1540 | snprintf(name, size, "%s%s", symbol_conf.symfs, |
1538 | self->long_name); | 1541 | self->long_name); |
1539 | break; | 1542 | break; |
1540 | 1543 | default:; | |
1541 | default: | ||
1542 | /* | ||
1543 | * If we wanted a full symtab but no image had one, | ||
1544 | * relax our requirements and repeat the search. | ||
1545 | */ | ||
1546 | if (want_symtab) { | ||
1547 | want_symtab = 0; | ||
1548 | self->origin = DSO__ORIG_BUILD_ID_CACHE; | ||
1549 | } else | ||
1550 | continue; | ||
1551 | } | 1544 | } |
1552 | 1545 | ||
1553 | /* Name is now the name of the next image to try */ | 1546 | /* Name is now the name of the next image to try */ |
@@ -1574,6 +1567,15 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1574 | } | 1567 | } |
1575 | } | 1568 | } |
1576 | 1569 | ||
1570 | /* | ||
1571 | * If we wanted a full symtab but no image had one, | ||
1572 | * relax our requirements and repeat the search. | ||
1573 | */ | ||
1574 | if (ret <= 0 && want_symtab) { | ||
1575 | want_symtab = 0; | ||
1576 | goto restart; | ||
1577 | } | ||
1578 | |||
1577 | free(name); | 1579 | free(name); |
1578 | if (ret < 0 && strstr(self->name, " (deleted)") != NULL) | 1580 | if (ret < 0 && strstr(self->name, " (deleted)") != NULL) |
1579 | return 0; | 1581 | return 0; |
@@ -1758,9 +1760,9 @@ struct map *machine__new_module(struct machine *self, u64 start, | |||
1758 | return NULL; | 1760 | return NULL; |
1759 | 1761 | ||
1760 | if (machine__is_host(self)) | 1762 | if (machine__is_host(self)) |
1761 | dso->origin = DSO__ORIG_KMODULE; | 1763 | dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE; |
1762 | else | 1764 | else |
1763 | dso->origin = DSO__ORIG_GUEST_KMODULE; | 1765 | dso->symtab_type = SYMTAB__GUEST_KMODULE; |
1764 | map_groups__insert(&self->kmaps, map); | 1766 | map_groups__insert(&self->kmaps, map); |
1765 | return map; | 1767 | return map; |
1766 | } | 1768 | } |
@@ -1836,12 +1838,13 @@ int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1836 | int err = -1, fd; | 1838 | int err = -1, fd; |
1837 | char symfs_vmlinux[PATH_MAX]; | 1839 | char symfs_vmlinux[PATH_MAX]; |
1838 | 1840 | ||
1839 | snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s", | 1841 | snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s", |
1840 | symbol_conf.symfs, vmlinux); | 1842 | symbol_conf.symfs, vmlinux); |
1841 | fd = open(symfs_vmlinux, O_RDONLY); | 1843 | fd = open(symfs_vmlinux, O_RDONLY); |
1842 | if (fd < 0) | 1844 | if (fd < 0) |
1843 | return -1; | 1845 | return -1; |
1844 | 1846 | ||
1847 | dso__set_long_name(self, (char *)vmlinux); | ||
1845 | dso__set_loaded(self, map->type); | 1848 | dso__set_loaded(self, map->type); |
1846 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); | 1849 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); |
1847 | close(fd); | 1850 | close(fd); |
@@ -2403,6 +2406,8 @@ int symbol__init(void) | |||
2403 | if (symbol_conf.initialized) | 2406 | if (symbol_conf.initialized) |
2404 | return 0; | 2407 | return 0; |
2405 | 2408 | ||
2409 | symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); | ||
2410 | |||
2406 | elf_version(EV_CURRENT); | 2411 | elf_version(EV_CURRENT); |
2407 | if (symbol_conf.sort_by_name) | 2412 | if (symbol_conf.sort_by_name) |
2408 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - | 2413 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - |