aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c113
1 files changed, 63 insertions, 50 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 15ccfba8cdf8..f06c10f092ba 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -11,6 +11,7 @@
11#include <sys/param.h> 11#include <sys/param.h>
12#include <fcntl.h> 12#include <fcntl.h>
13#include <unistd.h> 13#include <unistd.h>
14#include <inttypes.h>
14#include "build-id.h" 15#include "build-id.h"
15#include "debug.h" 16#include "debug.h"
16#include "symbol.h" 17#include "symbol.h"
@@ -153,7 +154,7 @@ static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
153 self->binding = binding; 154 self->binding = binding;
154 self->namelen = namelen - 1; 155 self->namelen = namelen - 1;
155 156
156 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); 157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", __func__, name, start, self->end);
157 158
158 memcpy(self->name, name, namelen); 159 memcpy(self->name, name, namelen);
159 160
@@ -167,7 +168,7 @@ void symbol__delete(struct symbol *self)
167 168
168static size_t symbol__fprintf(struct symbol *self, FILE *fp) 169static size_t symbol__fprintf(struct symbol *self, FILE *fp)
169{ 170{
170 return fprintf(fp, " %llx-%llx %c %s\n", 171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
171 self->start, self->end, 172 self->start, self->end,
172 self->binding == STB_GLOBAL ? 'g' : 173 self->binding == STB_GLOBAL ? 'g' :
173 self->binding == STB_LOCAL ? 'l' : 'w', 174 self->binding == STB_LOCAL ? 'l' : 'w',
@@ -206,8 +207,7 @@ struct dso *dso__new(const char *name)
206 dso__set_short_name(self, self->name); 207 dso__set_short_name(self, self->name);
207 for (i = 0; i < MAP__NR_TYPES; ++i) 208 for (i = 0; i < MAP__NR_TYPES; ++i)
208 self->symbols[i] = self->symbol_names[i] = RB_ROOT; 209 self->symbols[i] = self->symbol_names[i] = RB_ROOT;
209 self->slen_calculated = 0; 210 self->symtab_type = SYMTAB__NOT_FOUND;
210 self->origin = DSO__ORIG_NOT_FOUND;
211 self->loaded = 0; 211 self->loaded = 0;
212 self->sorted_by_name = 0; 212 self->sorted_by_name = 0;
213 self->has_build_id = 0; 213 self->has_build_id = 0;
@@ -680,9 +680,9 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
680 return -1; 680 return -1;
681 681
682 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 682 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
683 self->origin = DSO__ORIG_GUEST_KERNEL; 683 self->symtab_type = SYMTAB__GUEST_KALLSYMS;
684 else 684 else
685 self->origin = DSO__ORIG_KERNEL; 685 self->symtab_type = SYMTAB__KALLSYMS;
686 686
687 return dso__split_kallsyms(self, map, filter); 687 return dso__split_kallsyms(self, map, filter);
688} 688}
@@ -1161,6 +1161,13 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1161 1161
1162 section_name = elf_sec__name(&shdr, secstrs); 1162 section_name = elf_sec__name(&shdr, secstrs);
1163 1163
1164 /* On ARM, symbols for thumb functions have 1 added to
1165 * the symbol address as a flag - remove it */
1166 if ((ehdr.e_machine == EM_ARM) &&
1167 (map->type == MAP__FUNCTION) &&
1168 (sym.st_value & 1))
1169 --sym.st_value;
1170
1164 if (self->kernel != DSO_TYPE_USER || kmodule) { 1171 if (self->kernel != DSO_TYPE_USER || kmodule) {
1165 char dso_name[PATH_MAX]; 1172 char dso_name[PATH_MAX];
1166 1173
@@ -1189,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1189 if (curr_dso == NULL) 1196 if (curr_dso == NULL)
1190 goto out_elf_end; 1197 goto out_elf_end;
1191 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;
1192 curr_map = map__new2(start, curr_dso, 1201 curr_map = map__new2(start, curr_dso,
1193 map->type); 1202 map->type);
1194 if (curr_map == NULL) { 1203 if (curr_map == NULL) {
@@ -1197,7 +1206,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1197 } 1206 }
1198 curr_map->map_ip = identity__map_ip; 1207 curr_map->map_ip = identity__map_ip;
1199 curr_map->unmap_ip = identity__map_ip; 1208 curr_map->unmap_ip = identity__map_ip;
1200 curr_dso->origin = self->origin; 1209 curr_dso->symtab_type = self->symtab_type;
1201 map_groups__insert(kmap->kmaps, curr_map); 1210 map_groups__insert(kmap->kmaps, curr_map);
1202 dsos__add(&self->node, curr_dso); 1211 dsos__add(&self->node, curr_dso);
1203 dso__set_loaded(curr_dso, map->type); 1212 dso__set_loaded(curr_dso, map->type);
@@ -1208,8 +1217,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1208 } 1217 }
1209 1218
1210 if (curr_dso->adjust_symbols) { 1219 if (curr_dso->adjust_symbols) {
1211 pr_debug4("%s: adjusting symbol: st_value: %#Lx " 1220 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1212 "sh_addr: %#Lx sh_offset: %#Lx\n", __func__, 1221 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1213 (u64)sym.st_value, (u64)shdr.sh_addr, 1222 (u64)sym.st_value, (u64)shdr.sh_addr,
1214 (u64)shdr.sh_offset); 1223 (u64)shdr.sh_offset);
1215 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1224 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
@@ -1423,21 +1432,21 @@ out:
1423char dso__symtab_origin(const struct dso *self) 1432char dso__symtab_origin(const struct dso *self)
1424{ 1433{
1425 static const char origin[] = { 1434 static const char origin[] = {
1426 [DSO__ORIG_KERNEL] = 'k', 1435 [SYMTAB__KALLSYMS] = 'k',
1427 [DSO__ORIG_JAVA_JIT] = 'j', 1436 [SYMTAB__JAVA_JIT] = 'j',
1428 [DSO__ORIG_BUILD_ID_CACHE] = 'B', 1437 [SYMTAB__BUILD_ID_CACHE] = 'B',
1429 [DSO__ORIG_FEDORA] = 'f', 1438 [SYMTAB__FEDORA_DEBUGINFO] = 'f',
1430 [DSO__ORIG_UBUNTU] = 'u', 1439 [SYMTAB__UBUNTU_DEBUGINFO] = 'u',
1431 [DSO__ORIG_BUILDID] = 'b', 1440 [SYMTAB__BUILDID_DEBUGINFO] = 'b',
1432 [DSO__ORIG_DSO] = 'd', 1441 [SYMTAB__SYSTEM_PATH_DSO] = 'd',
1433 [DSO__ORIG_KMODULE] = 'K', 1442 [SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
1434 [DSO__ORIG_GUEST_KERNEL] = 'g', 1443 [SYMTAB__GUEST_KALLSYMS] = 'g',
1435 [DSO__ORIG_GUEST_KMODULE] = 'G', 1444 [SYMTAB__GUEST_KMODULE] = 'G',
1436 }; 1445 };
1437 1446
1438 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 1447 if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND)
1439 return '!'; 1448 return '!';
1440 return origin[self->origin]; 1449 return origin[self->symtab_type];
1441} 1450}
1442 1451
1443int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1452int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
@@ -1470,8 +1479,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1470 1479
1471 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1480 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1472 ret = dso__load_perf_map(self, map, filter); 1481 ret = dso__load_perf_map(self, map, filter);
1473 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 1482 self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1474 DSO__ORIG_NOT_FOUND; 1483 SYMTAB__NOT_FOUND;
1475 return ret; 1484 return ret;
1476 } 1485 }
1477 1486
@@ -1479,26 +1488,28 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1479 * 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.
1480 * Failing that, do a second pass where we accept .dynsym also 1489 * Failing that, do a second pass where we accept .dynsym also
1481 */ 1490 */
1482 for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1; 1491 want_symtab = 1;
1483 self->origin != DSO__ORIG_NOT_FOUND; 1492restart:
1484 self->origin++) { 1493 for (self->symtab_type = SYMTAB__BUILD_ID_CACHE;
1485 switch (self->origin) { 1494 self->symtab_type != SYMTAB__NOT_FOUND;
1486 case DSO__ORIG_BUILD_ID_CACHE: 1495 self->symtab_type++) {
1496 switch (self->symtab_type) {
1497 case SYMTAB__BUILD_ID_CACHE:
1487 /* skip the locally configured cache if a symfs is given */ 1498 /* skip the locally configured cache if a symfs is given */
1488 if (symbol_conf.symfs[0] || 1499 if (symbol_conf.symfs[0] ||
1489 (dso__build_id_filename(self, name, size) == NULL)) { 1500 (dso__build_id_filename(self, name, size) == NULL)) {
1490 continue; 1501 continue;
1491 } 1502 }
1492 break; 1503 break;
1493 case DSO__ORIG_FEDORA: 1504 case SYMTAB__FEDORA_DEBUGINFO:
1494 snprintf(name, size, "%s/usr/lib/debug%s.debug", 1505 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1495 symbol_conf.symfs, self->long_name); 1506 symbol_conf.symfs, self->long_name);
1496 break; 1507 break;
1497 case DSO__ORIG_UBUNTU: 1508 case SYMTAB__UBUNTU_DEBUGINFO:
1498 snprintf(name, size, "%s/usr/lib/debug%s", 1509 snprintf(name, size, "%s/usr/lib/debug%s",
1499 symbol_conf.symfs, self->long_name); 1510 symbol_conf.symfs, self->long_name);
1500 break; 1511 break;
1501 case DSO__ORIG_BUILDID: { 1512 case SYMTAB__BUILDID_DEBUGINFO: {
1502 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1513 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1503 1514
1504 if (!self->has_build_id) 1515 if (!self->has_build_id)
@@ -1512,34 +1523,24 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1512 symbol_conf.symfs, build_id_hex, build_id_hex + 2); 1523 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
1513 } 1524 }
1514 break; 1525 break;
1515 case DSO__ORIG_DSO: 1526 case SYMTAB__SYSTEM_PATH_DSO:
1516 snprintf(name, size, "%s%s", 1527 snprintf(name, size, "%s%s",
1517 symbol_conf.symfs, self->long_name); 1528 symbol_conf.symfs, self->long_name);
1518 break; 1529 break;
1519 case DSO__ORIG_GUEST_KMODULE: 1530 case SYMTAB__GUEST_KMODULE:
1520 if (map->groups && map->groups->machine) 1531 if (map->groups && machine)
1521 root_dir = map->groups->machine->root_dir; 1532 root_dir = machine->root_dir;
1522 else 1533 else
1523 root_dir = ""; 1534 root_dir = "";
1524 snprintf(name, size, "%s%s%s", symbol_conf.symfs, 1535 snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1525 root_dir, self->long_name); 1536 root_dir, self->long_name);
1526 break; 1537 break;
1527 1538
1528 case DSO__ORIG_KMODULE: 1539 case SYMTAB__SYSTEM_PATH_KMODULE:
1529 snprintf(name, size, "%s%s", symbol_conf.symfs, 1540 snprintf(name, size, "%s%s", symbol_conf.symfs,
1530 self->long_name); 1541 self->long_name);
1531 break; 1542 break;
1532 1543 default:;
1533 default:
1534 /*
1535 * If we wanted a full symtab but no image had one,
1536 * relax our requirements and repeat the search.
1537 */
1538 if (want_symtab) {
1539 want_symtab = 0;
1540 self->origin = DSO__ORIG_BUILD_ID_CACHE;
1541 } else
1542 continue;
1543 } 1544 }
1544 1545
1545 /* Name is now the name of the next image to try */ 1546 /* Name is now the name of the next image to try */
@@ -1566,6 +1567,15 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1566 } 1567 }
1567 } 1568 }
1568 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
1569 free(name); 1579 free(name);
1570 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 1580 if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1571 return 0; 1581 return 0;
@@ -1750,9 +1760,9 @@ struct map *machine__new_module(struct machine *self, u64 start,
1750 return NULL; 1760 return NULL;
1751 1761
1752 if (machine__is_host(self)) 1762 if (machine__is_host(self))
1753 dso->origin = DSO__ORIG_KMODULE; 1763 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1754 else 1764 else
1755 dso->origin = DSO__ORIG_GUEST_KMODULE; 1765 dso->symtab_type = SYMTAB__GUEST_KMODULE;
1756 map_groups__insert(&self->kmaps, map); 1766 map_groups__insert(&self->kmaps, map);
1757 return map; 1767 return map;
1758} 1768}
@@ -1828,12 +1838,13 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1828 int err = -1, fd; 1838 int err = -1, fd;
1829 char symfs_vmlinux[PATH_MAX]; 1839 char symfs_vmlinux[PATH_MAX];
1830 1840
1831 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s", 1841 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
1832 symbol_conf.symfs, vmlinux); 1842 symbol_conf.symfs, vmlinux);
1833 fd = open(symfs_vmlinux, O_RDONLY); 1843 fd = open(symfs_vmlinux, O_RDONLY);
1834 if (fd < 0) 1844 if (fd < 0)
1835 return -1; 1845 return -1;
1836 1846
1847 dso__set_long_name(self, (char *)vmlinux);
1837 dso__set_loaded(self, map->type); 1848 dso__set_loaded(self, map->type);
1838 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);
1839 close(fd); 1850 close(fd);
@@ -2395,6 +2406,8 @@ int symbol__init(void)
2395 if (symbol_conf.initialized) 2406 if (symbol_conf.initialized)
2396 return 0; 2407 return 0;
2397 2408
2409 symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64));
2410
2398 elf_version(EV_CURRENT); 2411 elf_version(EV_CURRENT);
2399 if (symbol_conf.sort_by_name) 2412 if (symbol_conf.sort_by_name)
2400 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - 2413 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -