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.c339
1 files changed, 237 insertions, 102 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 5b276833e2bf..1a367734e016 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -12,6 +12,7 @@
12#include <fcntl.h> 12#include <fcntl.h>
13#include <unistd.h> 13#include <unistd.h>
14#include "build-id.h" 14#include "build-id.h"
15#include "debug.h"
15#include "symbol.h" 16#include "symbol.h"
16#include "strlist.h" 17#include "strlist.h"
17 18
@@ -25,6 +26,8 @@
25#define NT_GNU_BUILD_ID 3 26#define NT_GNU_BUILD_ID 3
26#endif 27#endif
27 28
29static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
30static int elf_read_build_id(Elf *elf, void *bf, size_t size);
28static void dsos__add(struct list_head *head, struct dso *dso); 31static void dsos__add(struct list_head *head, struct dso *dso);
29static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
30static int dso__load_kernel_sym(struct dso *self, struct map *map, 33static int dso__load_kernel_sym(struct dso *self, struct map *map,
@@ -40,6 +43,14 @@ struct symbol_conf symbol_conf = {
40 .try_vmlinux_path = true, 43 .try_vmlinux_path = true,
41}; 44};
42 45
46int dso__name_len(const struct dso *self)
47{
48 if (verbose)
49 return self->long_name_len;
50
51 return self->short_name_len;
52}
53
43bool dso__loaded(const struct dso *self, enum map_type type) 54bool dso__loaded(const struct dso *self, enum map_type type)
44{ 55{
45 return self->loaded & (1 << type); 56 return self->loaded & (1 << type);
@@ -120,7 +131,8 @@ static void map_groups__fixup_end(struct map_groups *self)
120 __map_groups__fixup_end(self, i); 131 __map_groups__fixup_end(self, i);
121} 132}
122 133
123static struct symbol *symbol__new(u64 start, u64 len, const char *name) 134static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
135 const char *name)
124{ 136{
125 size_t namelen = strlen(name) + 1; 137 size_t namelen = strlen(name) + 1;
126 struct symbol *self = calloc(1, (symbol_conf.priv_size + 138 struct symbol *self = calloc(1, (symbol_conf.priv_size +
@@ -133,6 +145,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name)
133 145
134 self->start = start; 146 self->start = start;
135 self->end = len ? start + len - 1 : start; 147 self->end = len ? start + len - 1 : start;
148 self->binding = binding;
136 self->namelen = namelen - 1; 149 self->namelen = namelen - 1;
137 150
138 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); 151 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
@@ -149,8 +162,11 @@ void symbol__delete(struct symbol *self)
149 162
150static size_t symbol__fprintf(struct symbol *self, FILE *fp) 163static size_t symbol__fprintf(struct symbol *self, FILE *fp)
151{ 164{
152 return fprintf(fp, " %llx-%llx %s\n", 165 return fprintf(fp, " %llx-%llx %c %s\n",
153 self->start, self->end, self->name); 166 self->start, self->end,
167 self->binding == STB_GLOBAL ? 'g' :
168 self->binding == STB_LOCAL ? 'l' : 'w',
169 self->name);
154} 170}
155 171
156void dso__set_long_name(struct dso *self, char *name) 172void dso__set_long_name(struct dso *self, char *name)
@@ -215,7 +231,9 @@ void dso__delete(struct dso *self)
215 int i; 231 int i;
216 for (i = 0; i < MAP__NR_TYPES; ++i) 232 for (i = 0; i < MAP__NR_TYPES; ++i)
217 symbols__delete(&self->symbols[i]); 233 symbols__delete(&self->symbols[i]);
218 if (self->long_name != self->name) 234 if (self->sname_alloc)
235 free((char *)self->short_name);
236 if (self->lname_alloc)
219 free(self->long_name); 237 free(self->long_name);
220 free(self); 238 free(self);
221} 239}
@@ -440,6 +458,14 @@ struct process_kallsyms_args {
440 struct dso *dso; 458 struct dso *dso;
441}; 459};
442 460
461static u8 kallsyms2elf_type(char type)
462{
463 if (type == 'W')
464 return STB_WEAK;
465
466 return isupper(type) ? STB_GLOBAL : STB_LOCAL;
467}
468
443static int map__process_kallsym_symbol(void *arg, const char *name, 469static int map__process_kallsym_symbol(void *arg, const char *name,
444 char type, u64 start) 470 char type, u64 start)
445{ 471{
@@ -453,7 +479,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
453 /* 479 /*
454 * Will fix up the end later, when we have all symbols sorted. 480 * Will fix up the end later, when we have all symbols sorted.
455 */ 481 */
456 sym = symbol__new(start, 0, name); 482 sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
457 483
458 if (sym == NULL) 484 if (sym == NULL)
459 return -ENOMEM; 485 return -ENOMEM;
@@ -648,7 +674,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
648 if (len + 2 >= line_len) 674 if (len + 2 >= line_len)
649 continue; 675 continue;
650 676
651 sym = symbol__new(start, size, line + len); 677 sym = symbol__new(start, size, STB_GLOBAL, line + len);
652 678
653 if (sym == NULL) 679 if (sym == NULL)
654 goto out_delete_line; 680 goto out_delete_line;
@@ -860,7 +886,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
860 "%s@plt", elf_sym__name(&sym, symstrs)); 886 "%s@plt", elf_sym__name(&sym, symstrs));
861 887
862 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 888 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
863 sympltname); 889 STB_GLOBAL, sympltname);
864 if (!f) 890 if (!f)
865 goto out_elf_end; 891 goto out_elf_end;
866 892
@@ -882,7 +908,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
882 "%s@plt", elf_sym__name(&sym, symstrs)); 908 "%s@plt", elf_sym__name(&sym, symstrs));
883 909
884 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 910 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
885 sympltname); 911 STB_GLOBAL, sympltname);
886 if (!f) 912 if (!f)
887 goto out_elf_end; 913 goto out_elf_end;
888 914
@@ -933,8 +959,28 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
933 } 959 }
934} 960}
935 961
962static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
963{
964 Elf_Scn *sec = NULL;
965 GElf_Shdr shdr;
966 size_t cnt = 1;
967
968 while ((sec = elf_nextscn(elf, sec)) != NULL) {
969 gelf_getshdr(sec, &shdr);
970
971 if ((addr >= shdr.sh_addr) &&
972 (addr < (shdr.sh_addr + shdr.sh_size)))
973 return cnt;
974
975 ++cnt;
976 }
977
978 return -1;
979}
980
936static int dso__load_sym(struct dso *self, struct map *map, const char *name, 981static int dso__load_sym(struct dso *self, struct map *map, const char *name,
937 int fd, symbol_filter_t filter, int kmodule) 982 int fd, symbol_filter_t filter, int kmodule,
983 int want_symtab)
938{ 984{
939 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL; 985 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
940 struct map *curr_map = map; 986 struct map *curr_map = map;
@@ -944,31 +990,51 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
944 int err = -1; 990 int err = -1;
945 uint32_t idx; 991 uint32_t idx;
946 GElf_Ehdr ehdr; 992 GElf_Ehdr ehdr;
947 GElf_Shdr shdr; 993 GElf_Shdr shdr, opdshdr;
948 Elf_Data *syms; 994 Elf_Data *syms, *opddata = NULL;
949 GElf_Sym sym; 995 GElf_Sym sym;
950 Elf_Scn *sec, *sec_strndx; 996 Elf_Scn *sec, *sec_strndx, *opdsec;
951 Elf *elf; 997 Elf *elf;
952 int nr = 0; 998 int nr = 0;
999 size_t opdidx = 0;
953 1000
954 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 1001 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
955 if (elf == NULL) { 1002 if (elf == NULL) {
956 pr_err("%s: cannot read %s ELF file.\n", __func__, name); 1003 pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
957 goto out_close; 1004 goto out_close;
958 } 1005 }
959 1006
960 if (gelf_getehdr(elf, &ehdr) == NULL) { 1007 if (gelf_getehdr(elf, &ehdr) == NULL) {
961 pr_err("%s: cannot get elf header.\n", __func__); 1008 pr_debug("%s: cannot get elf header.\n", __func__);
962 goto out_elf_end; 1009 goto out_elf_end;
963 } 1010 }
964 1011
1012 /* Always reject images with a mismatched build-id: */
1013 if (self->has_build_id) {
1014 u8 build_id[BUILD_ID_SIZE];
1015
1016 if (elf_read_build_id(elf, build_id,
1017 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1018 goto out_elf_end;
1019
1020 if (!dso__build_id_equal(self, build_id))
1021 goto out_elf_end;
1022 }
1023
965 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 1024 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
966 if (sec == NULL) { 1025 if (sec == NULL) {
1026 if (want_symtab)
1027 goto out_elf_end;
1028
967 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 1029 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
968 if (sec == NULL) 1030 if (sec == NULL)
969 goto out_elf_end; 1031 goto out_elf_end;
970 } 1032 }
971 1033
1034 opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
1035 if (opdsec)
1036 opddata = elf_rawdata(opdsec, NULL);
1037
972 syms = elf_getdata(sec, NULL); 1038 syms = elf_getdata(sec, NULL);
973 if (syms == NULL) 1039 if (syms == NULL)
974 goto out_elf_end; 1040 goto out_elf_end;
@@ -1013,6 +1079,23 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1013 if (!is_label && !elf_sym__is_a(&sym, map->type)) 1079 if (!is_label && !elf_sym__is_a(&sym, map->type))
1014 continue; 1080 continue;
1015 1081
1082 /* Reject ARM ELF "mapping symbols": these aren't unique and
1083 * don't identify functions, so will confuse the profile
1084 * output: */
1085 if (ehdr.e_machine == EM_ARM) {
1086 if (!strcmp(elf_name, "$a") ||
1087 !strcmp(elf_name, "$d") ||
1088 !strcmp(elf_name, "$t"))
1089 continue;
1090 }
1091
1092 if (opdsec && sym.st_shndx == opdidx) {
1093 u32 offset = sym.st_value - opdshdr.sh_addr;
1094 u64 *opd = opddata->d_buf + offset;
1095 sym.st_value = *opd;
1096 sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
1097 }
1098
1016 sec = elf_getscn(elf, sym.st_shndx); 1099 sec = elf_getscn(elf, sym.st_shndx);
1017 if (!sec) 1100 if (!sec)
1018 goto out_elf_end; 1101 goto out_elf_end;
@@ -1086,7 +1169,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1086 if (demangled != NULL) 1169 if (demangled != NULL)
1087 elf_name = demangled; 1170 elf_name = demangled;
1088new_symbol: 1171new_symbol:
1089 f = symbol__new(sym.st_value, sym.st_size, elf_name); 1172 f = symbol__new(sym.st_value, sym.st_size,
1173 GELF_ST_BIND(sym.st_info), elf_name);
1090 free(demangled); 1174 free(demangled);
1091 if (!f) 1175 if (!f)
1092 goto out_elf_end; 1176 goto out_elf_end;
@@ -1151,37 +1235,26 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1151 */ 1235 */
1152#define NOTE_ALIGN(n) (((n) + 3) & -4U) 1236#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1153 1237
1154int filename__read_build_id(const char *filename, void *bf, size_t size) 1238static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1155{ 1239{
1156 int fd, err = -1; 1240 int err = -1;
1157 GElf_Ehdr ehdr; 1241 GElf_Ehdr ehdr;
1158 GElf_Shdr shdr; 1242 GElf_Shdr shdr;
1159 Elf_Data *data; 1243 Elf_Data *data;
1160 Elf_Scn *sec; 1244 Elf_Scn *sec;
1161 Elf_Kind ek; 1245 Elf_Kind ek;
1162 void *ptr; 1246 void *ptr;
1163 Elf *elf;
1164 1247
1165 if (size < BUILD_ID_SIZE) 1248 if (size < BUILD_ID_SIZE)
1166 goto out; 1249 goto out;
1167 1250
1168 fd = open(filename, O_RDONLY);
1169 if (fd < 0)
1170 goto out;
1171
1172 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1173 if (elf == NULL) {
1174 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1175 goto out_close;
1176 }
1177
1178 ek = elf_kind(elf); 1251 ek = elf_kind(elf);
1179 if (ek != ELF_K_ELF) 1252 if (ek != ELF_K_ELF)
1180 goto out_elf_end; 1253 goto out;
1181 1254
1182 if (gelf_getehdr(elf, &ehdr) == NULL) { 1255 if (gelf_getehdr(elf, &ehdr) == NULL) {
1183 pr_err("%s: cannot get elf header.\n", __func__); 1256 pr_err("%s: cannot get elf header.\n", __func__);
1184 goto out_elf_end; 1257 goto out;
1185 } 1258 }
1186 1259
1187 sec = elf_section_by_name(elf, &ehdr, &shdr, 1260 sec = elf_section_by_name(elf, &ehdr, &shdr,
@@ -1190,12 +1263,12 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
1190 sec = elf_section_by_name(elf, &ehdr, &shdr, 1263 sec = elf_section_by_name(elf, &ehdr, &shdr,
1191 ".notes", NULL); 1264 ".notes", NULL);
1192 if (sec == NULL) 1265 if (sec == NULL)
1193 goto out_elf_end; 1266 goto out;
1194 } 1267 }
1195 1268
1196 data = elf_getdata(sec, NULL); 1269 data = elf_getdata(sec, NULL);
1197 if (data == NULL) 1270 if (data == NULL)
1198 goto out_elf_end; 1271 goto out;
1199 1272
1200 ptr = data->d_buf; 1273 ptr = data->d_buf;
1201 while (ptr < (data->d_buf + data->d_size)) { 1274 while (ptr < (data->d_buf + data->d_size)) {
@@ -1217,7 +1290,31 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
1217 } 1290 }
1218 ptr += descsz; 1291 ptr += descsz;
1219 } 1292 }
1220out_elf_end: 1293
1294out:
1295 return err;
1296}
1297
1298int filename__read_build_id(const char *filename, void *bf, size_t size)
1299{
1300 int fd, err = -1;
1301 Elf *elf;
1302
1303 if (size < BUILD_ID_SIZE)
1304 goto out;
1305
1306 fd = open(filename, O_RDONLY);
1307 if (fd < 0)
1308 goto out;
1309
1310 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1311 if (elf == NULL) {
1312 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1313 goto out_close;
1314 }
1315
1316 err = elf_read_build_id(elf, bf, size);
1317
1221 elf_end(elf); 1318 elf_end(elf);
1222out_close: 1319out_close:
1223 close(fd); 1320 close(fd);
@@ -1293,11 +1390,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1293{ 1390{
1294 int size = PATH_MAX; 1391 int size = PATH_MAX;
1295 char *name; 1392 char *name;
1296 u8 build_id[BUILD_ID_SIZE];
1297 int ret = -1; 1393 int ret = -1;
1298 int fd; 1394 int fd;
1299 struct machine *machine; 1395 struct machine *machine;
1300 const char *root_dir; 1396 const char *root_dir;
1397 int want_symtab;
1301 1398
1302 dso__set_loaded(self, map->type); 1399 dso__set_loaded(self, map->type);
1303 1400
@@ -1324,13 +1421,18 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1324 return ret; 1421 return ret;
1325 } 1422 }
1326 1423
1327 self->origin = DSO__ORIG_BUILD_ID_CACHE; 1424 /* Iterate over candidate debug images.
1328 if (dso__build_id_filename(self, name, size) != NULL) 1425 * On the first pass, only load images if they have a full symtab.
1329 goto open_file; 1426 * Failing that, do a second pass where we accept .dynsym also
1330more: 1427 */
1331 do { 1428 for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1;
1332 self->origin++; 1429 self->origin != DSO__ORIG_NOT_FOUND;
1430 self->origin++) {
1333 switch (self->origin) { 1431 switch (self->origin) {
1432 case DSO__ORIG_BUILD_ID_CACHE:
1433 if (dso__build_id_filename(self, name, size) == NULL)
1434 continue;
1435 break;
1334 case DSO__ORIG_FEDORA: 1436 case DSO__ORIG_FEDORA:
1335 snprintf(name, size, "/usr/lib/debug%s.debug", 1437 snprintf(name, size, "/usr/lib/debug%s.debug",
1336 self->long_name); 1438 self->long_name);
@@ -1339,21 +1441,20 @@ more:
1339 snprintf(name, size, "/usr/lib/debug%s", 1441 snprintf(name, size, "/usr/lib/debug%s",
1340 self->long_name); 1442 self->long_name);
1341 break; 1443 break;
1342 case DSO__ORIG_BUILDID: 1444 case DSO__ORIG_BUILDID: {
1343 if (filename__read_build_id(self->long_name, build_id, 1445 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1344 sizeof(build_id))) { 1446
1345 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1447 if (!self->has_build_id)
1346 build_id__sprintf(build_id, sizeof(build_id), 1448 continue;
1347 build_id_hex); 1449
1348 snprintf(name, size, 1450 build_id__sprintf(self->build_id,
1349 "/usr/lib/debug/.build-id/%.2s/%s.debug", 1451 sizeof(self->build_id),
1350 build_id_hex, build_id_hex + 2); 1452 build_id_hex);
1351 if (self->has_build_id) 1453 snprintf(name, size,
1352 goto compare_build_id; 1454 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1353 break; 1455 build_id_hex, build_id_hex + 2);
1354 } 1456 }
1355 self->origin++; 1457 break;
1356 /* Fall thru */
1357 case DSO__ORIG_DSO: 1458 case DSO__ORIG_DSO:
1358 snprintf(name, size, "%s", self->long_name); 1459 snprintf(name, size, "%s", self->long_name);
1359 break; 1460 break;
@@ -1366,36 +1467,41 @@ more:
1366 break; 1467 break;
1367 1468
1368 default: 1469 default:
1369 goto out; 1470 /*
1471 * If we wanted a full symtab but no image had one,
1472 * relax our requirements and repeat the search.
1473 */
1474 if (want_symtab) {
1475 want_symtab = 0;
1476 self->origin = DSO__ORIG_BUILD_ID_CACHE;
1477 } else
1478 continue;
1370 } 1479 }
1371 1480
1372 if (self->has_build_id) { 1481 /* Name is now the name of the next image to try */
1373 if (filename__read_build_id(name, build_id,
1374 sizeof(build_id)) < 0)
1375 goto more;
1376compare_build_id:
1377 if (!dso__build_id_equal(self, build_id))
1378 goto more;
1379 }
1380open_file:
1381 fd = open(name, O_RDONLY); 1482 fd = open(name, O_RDONLY);
1382 } while (fd < 0); 1483 if (fd < 0)
1484 continue;
1383 1485
1384 ret = dso__load_sym(self, map, name, fd, filter, 0); 1486 ret = dso__load_sym(self, map, name, fd, filter, 0,
1385 close(fd); 1487 want_symtab);
1488 close(fd);
1386 1489
1387 /* 1490 /*
1388 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 1491 * Some people seem to have debuginfo files _WITHOUT_ debug
1389 */ 1492 * info!?!?
1390 if (!ret) 1493 */
1391 goto more; 1494 if (!ret)
1495 continue;
1392 1496
1393 if (ret > 0) { 1497 if (ret > 0) {
1394 int nr_plt = dso__synthesize_plt_symbols(self, map, filter); 1498 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1395 if (nr_plt > 0) 1499 if (nr_plt > 0)
1396 ret += nr_plt; 1500 ret += nr_plt;
1501 break;
1502 }
1397 } 1503 }
1398out: 1504
1399 free(name); 1505 free(name);
1400 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 1506 if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1401 return 0; 1507 return 0;
@@ -1494,6 +1600,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
1494 goto out; 1600 goto out;
1495 } 1601 }
1496 dso__set_long_name(map->dso, long_name); 1602 dso__set_long_name(map->dso, long_name);
1603 map->dso->lname_alloc = 1;
1497 dso__kernel_module_get_build_id(map->dso, ""); 1604 dso__kernel_module_get_build_id(map->dso, "");
1498 } 1605 }
1499 } 1606 }
@@ -1656,36 +1763,12 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1656{ 1763{
1657 int err = -1, fd; 1764 int err = -1, fd;
1658 1765
1659 if (self->has_build_id) {
1660 u8 build_id[BUILD_ID_SIZE];
1661
1662 if (filename__read_build_id(vmlinux, build_id,
1663 sizeof(build_id)) < 0) {
1664 pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1665 return -1;
1666 }
1667 if (!dso__build_id_equal(self, build_id)) {
1668 char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1669 vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1670
1671 build_id__sprintf(self->build_id,
1672 sizeof(self->build_id),
1673 expected_build_id);
1674 build_id__sprintf(build_id, sizeof(build_id),
1675 vmlinux_build_id);
1676 pr_debug("build_id in %s is %s while expected is %s, "
1677 "ignoring it\n", vmlinux, vmlinux_build_id,
1678 expected_build_id);
1679 return -1;
1680 }
1681 }
1682
1683 fd = open(vmlinux, O_RDONLY); 1766 fd = open(vmlinux, O_RDONLY);
1684 if (fd < 0) 1767 if (fd < 0)
1685 return -1; 1768 return -1;
1686 1769
1687 dso__set_loaded(self, map->type); 1770 dso__set_loaded(self, map->type);
1688 err = dso__load_sym(self, map, vmlinux, fd, filter, 0); 1771 err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
1689 close(fd); 1772 close(fd);
1690 1773
1691 if (err > 0) 1774 if (err > 0)
@@ -2048,6 +2131,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2048 return 0; 2131 return 0;
2049} 2132}
2050 2133
2134void machine__destroy_kernel_maps(struct machine *self)
2135{
2136 enum map_type type;
2137
2138 for (type = 0; type < MAP__NR_TYPES; ++type) {
2139 struct kmap *kmap;
2140
2141 if (self->vmlinux_maps[type] == NULL)
2142 continue;
2143
2144 kmap = map__kmap(self->vmlinux_maps[type]);
2145 map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
2146 if (kmap->ref_reloc_sym) {
2147 /*
2148 * ref_reloc_sym is shared among all maps, so free just
2149 * on one of them.
2150 */
2151 if (type == MAP__FUNCTION) {
2152 free((char *)kmap->ref_reloc_sym->name);
2153 kmap->ref_reloc_sym->name = NULL;
2154 free(kmap->ref_reloc_sym);
2155 }
2156 kmap->ref_reloc_sym = NULL;
2157 }
2158
2159 map__delete(self->vmlinux_maps[type]);
2160 self->vmlinux_maps[type] = NULL;
2161 }
2162}
2163
2051int machine__create_kernel_maps(struct machine *self) 2164int machine__create_kernel_maps(struct machine *self)
2052{ 2165{
2053 struct dso *kernel = machine__create_kernel(self); 2166 struct dso *kernel = machine__create_kernel(self);
@@ -2189,6 +2302,15 @@ out_free_comm_list:
2189 return -1; 2302 return -1;
2190} 2303}
2191 2304
2305void symbol__exit(void)
2306{
2307 strlist__delete(symbol_conf.sym_list);
2308 strlist__delete(symbol_conf.dso_list);
2309 strlist__delete(symbol_conf.comm_list);
2310 vmlinux_path__exit();
2311 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
2312}
2313
2192int machines__create_kernel_maps(struct rb_root *self, pid_t pid) 2314int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
2193{ 2315{
2194 struct machine *machine = machines__findnew(self, pid); 2316 struct machine *machine = machines__findnew(self, pid);
@@ -2283,6 +2405,19 @@ failure:
2283 return ret; 2405 return ret;
2284} 2406}
2285 2407
2408void machines__destroy_guest_kernel_maps(struct rb_root *self)
2409{
2410 struct rb_node *next = rb_first(self);
2411
2412 while (next) {
2413 struct machine *pos = rb_entry(next, struct machine, rb_node);
2414
2415 next = rb_next(&pos->rb_node);
2416 rb_erase(&pos->rb_node, self);
2417 machine__delete(pos);
2418 }
2419}
2420
2286int machine__load_kallsyms(struct machine *self, const char *filename, 2421int machine__load_kallsyms(struct machine *self, const char *filename,
2287 enum map_type type, symbol_filter_t filter) 2422 enum map_type type, symbol_filter_t filter)
2288{ 2423{