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.c564
1 files changed, 443 insertions, 121 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index c458c4a371d1..a06131f6259a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,13 +1,19 @@
1#include "util.h" 1#define _GNU_SOURCE
2#include "../perf.h" 2#include <ctype.h>
3#include "sort.h" 3#include <dirent.h>
4#include "string.h" 4#include <errno.h>
5#include <libgen.h>
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <sys/param.h>
12#include <fcntl.h>
13#include <unistd.h>
5#include "symbol.h" 14#include "symbol.h"
6#include "thread.h" 15#include "strlist.h"
7 16
8#include "debug.h"
9
10#include <asm/bug.h>
11#include <libelf.h> 17#include <libelf.h>
12#include <gelf.h> 18#include <gelf.h>
13#include <elf.h> 19#include <elf.h>
@@ -18,22 +24,12 @@
18#define NT_GNU_BUILD_ID 3 24#define NT_GNU_BUILD_ID 3
19#endif 25#endif
20 26
21enum dso_origin {
22 DSO__ORIG_KERNEL = 0,
23 DSO__ORIG_JAVA_JIT,
24 DSO__ORIG_BUILD_ID_CACHE,
25 DSO__ORIG_FEDORA,
26 DSO__ORIG_UBUNTU,
27 DSO__ORIG_BUILDID,
28 DSO__ORIG_DSO,
29 DSO__ORIG_KMODULE,
30 DSO__ORIG_NOT_FOUND,
31};
32
33static void dsos__add(struct list_head *head, struct dso *dso); 27static void dsos__add(struct list_head *head, struct dso *dso);
34static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 28static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
35static int dso__load_kernel_sym(struct dso *self, struct map *map, 29static int dso__load_kernel_sym(struct dso *self, struct map *map,
36 symbol_filter_t filter); 30 symbol_filter_t filter);
31static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
32 symbol_filter_t filter);
37static int vmlinux_path__nr_entries; 33static int vmlinux_path__nr_entries;
38static char **vmlinux_path; 34static char **vmlinux_path;
39 35
@@ -126,16 +122,17 @@ static void map_groups__fixup_end(struct map_groups *self)
126static struct symbol *symbol__new(u64 start, u64 len, const char *name) 122static struct symbol *symbol__new(u64 start, u64 len, const char *name)
127{ 123{
128 size_t namelen = strlen(name) + 1; 124 size_t namelen = strlen(name) + 1;
129 struct symbol *self = zalloc(symbol_conf.priv_size + 125 struct symbol *self = calloc(1, (symbol_conf.priv_size +
130 sizeof(*self) + namelen); 126 sizeof(*self) + namelen));
131 if (self == NULL) 127 if (self == NULL)
132 return NULL; 128 return NULL;
133 129
134 if (symbol_conf.priv_size) 130 if (symbol_conf.priv_size)
135 self = ((void *)self) + symbol_conf.priv_size; 131 self = ((void *)self) + symbol_conf.priv_size;
136 132
137 self->start = start; 133 self->start = start;
138 self->end = len ? start + len - 1 : start; 134 self->end = len ? start + len - 1 : start;
135 self->namelen = namelen - 1;
139 136
140 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); 137 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
141 138
@@ -178,7 +175,7 @@ static void dso__set_basename(struct dso *self)
178 175
179struct dso *dso__new(const char *name) 176struct dso *dso__new(const char *name)
180{ 177{
181 struct dso *self = zalloc(sizeof(*self) + strlen(name) + 1); 178 struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
182 179
183 if (self != NULL) { 180 if (self != NULL) {
184 int i; 181 int i;
@@ -192,6 +189,8 @@ struct dso *dso__new(const char *name)
192 self->loaded = 0; 189 self->loaded = 0;
193 self->sorted_by_name = 0; 190 self->sorted_by_name = 0;
194 self->has_build_id = 0; 191 self->has_build_id = 0;
192 self->kernel = DSO_TYPE_USER;
193 INIT_LIST_HEAD(&self->node);
195 } 194 }
196 195
197 return self; 196 return self;
@@ -408,12 +407,9 @@ int kallsyms__parse(const char *filename, void *arg,
408 char *symbol_name; 407 char *symbol_name;
409 408
410 line_len = getline(&line, &n, file); 409 line_len = getline(&line, &n, file);
411 if (line_len < 0) 410 if (line_len < 0 || !line)
412 break; 411 break;
413 412
414 if (!line)
415 goto out_failure;
416
417 line[--line_len] = '\0'; /* \n */ 413 line[--line_len] = '\0'; /* \n */
418 414
419 len = hex2u64(line, &start); 415 len = hex2u64(line, &start);
@@ -465,6 +461,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
465 * map__split_kallsyms, when we have split the maps per module 461 * map__split_kallsyms, when we have split the maps per module
466 */ 462 */
467 symbols__insert(root, sym); 463 symbols__insert(root, sym);
464
468 return 0; 465 return 0;
469} 466}
470 467
@@ -489,6 +486,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
489 symbol_filter_t filter) 486 symbol_filter_t filter)
490{ 487{
491 struct map_groups *kmaps = map__kmap(map)->kmaps; 488 struct map_groups *kmaps = map__kmap(map)->kmaps;
489 struct machine *machine = kmaps->machine;
492 struct map *curr_map = map; 490 struct map *curr_map = map;
493 struct symbol *pos; 491 struct symbol *pos;
494 int count = 0; 492 int count = 0;
@@ -510,15 +508,33 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
510 *module++ = '\0'; 508 *module++ = '\0';
511 509
512 if (strcmp(curr_map->dso->short_name, module)) { 510 if (strcmp(curr_map->dso->short_name, module)) {
513 curr_map = map_groups__find_by_name(kmaps, map->type, module); 511 if (curr_map != map &&
512 self->kernel == DSO_TYPE_GUEST_KERNEL &&
513 machine__is_default_guest(machine)) {
514 /*
515 * We assume all symbols of a module are
516 * continuous in * kallsyms, so curr_map
517 * points to a module and all its
518 * symbols are in its kmap. Mark it as
519 * loaded.
520 */
521 dso__set_loaded(curr_map->dso,
522 curr_map->type);
523 }
524
525 curr_map = map_groups__find_by_name(kmaps,
526 map->type, module);
514 if (curr_map == NULL) { 527 if (curr_map == NULL) {
515 pr_debug("/proc/{kallsyms,modules} " 528 pr_debug("%s/proc/{kallsyms,modules} "
516 "inconsistency while looking " 529 "inconsistency while looking "
517 "for \"%s\" module!\n", module); 530 "for \"%s\" module!\n",
518 return -1; 531 machine->root_dir, module);
532 curr_map = map;
533 goto discard_symbol;
519 } 534 }
520 535
521 if (curr_map->dso->loaded) 536 if (curr_map->dso->loaded &&
537 !machine__is_default_guest(machine))
522 goto discard_symbol; 538 goto discard_symbol;
523 } 539 }
524 /* 540 /*
@@ -531,13 +547,21 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
531 char dso_name[PATH_MAX]; 547 char dso_name[PATH_MAX];
532 struct dso *dso; 548 struct dso *dso;
533 549
534 snprintf(dso_name, sizeof(dso_name), "[kernel].%d", 550 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
535 kernel_range++); 551 snprintf(dso_name, sizeof(dso_name),
552 "[guest.kernel].%d",
553 kernel_range++);
554 else
555 snprintf(dso_name, sizeof(dso_name),
556 "[kernel].%d",
557 kernel_range++);
536 558
537 dso = dso__new(dso_name); 559 dso = dso__new(dso_name);
538 if (dso == NULL) 560 if (dso == NULL)
539 return -1; 561 return -1;
540 562
563 dso->kernel = self->kernel;
564
541 curr_map = map__new2(pos->start, dso, map->type); 565 curr_map = map__new2(pos->start, dso, map->type);
542 if (curr_map == NULL) { 566 if (curr_map == NULL) {
543 dso__delete(dso); 567 dso__delete(dso);
@@ -561,6 +585,12 @@ discard_symbol: rb_erase(&pos->rb_node, root);
561 } 585 }
562 } 586 }
563 587
588 if (curr_map != map &&
589 self->kernel == DSO_TYPE_GUEST_KERNEL &&
590 machine__is_default_guest(kmaps->machine)) {
591 dso__set_loaded(curr_map->dso, curr_map->type);
592 }
593
564 return count; 594 return count;
565} 595}
566 596
@@ -571,7 +601,10 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
571 return -1; 601 return -1;
572 602
573 symbols__fixup_end(&self->symbols[map->type]); 603 symbols__fixup_end(&self->symbols[map->type]);
574 self->origin = DSO__ORIG_KERNEL; 604 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
605 self->origin = DSO__ORIG_GUEST_KERNEL;
606 else
607 self->origin = DSO__ORIG_KERNEL;
575 608
576 return dso__split_kallsyms(self, map, filter); 609 return dso__split_kallsyms(self, map, filter);
577} 610}
@@ -870,8 +903,8 @@ out_close:
870 if (err == 0) 903 if (err == 0)
871 return nr; 904 return nr;
872out: 905out:
873 pr_warning("%s: problems reading %s PLT info.\n", 906 pr_debug("%s: problems reading %s PLT info.\n",
874 __func__, self->long_name); 907 __func__, self->long_name);
875 return 0; 908 return 0;
876} 909}
877 910
@@ -958,7 +991,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
958 nr_syms = shdr.sh_size / shdr.sh_entsize; 991 nr_syms = shdr.sh_size / shdr.sh_entsize;
959 992
960 memset(&sym, 0, sizeof(sym)); 993 memset(&sym, 0, sizeof(sym));
961 if (!self->kernel) { 994 if (self->kernel == DSO_TYPE_USER) {
962 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 995 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
963 elf_section_by_name(elf, &ehdr, &shdr, 996 elf_section_by_name(elf, &ehdr, &shdr,
964 ".gnu.prelink_undo", 997 ".gnu.prelink_undo",
@@ -990,7 +1023,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
990 1023
991 section_name = elf_sec__name(&shdr, secstrs); 1024 section_name = elf_sec__name(&shdr, secstrs);
992 1025
993 if (self->kernel || kmodule) { 1026 if (self->kernel != DSO_TYPE_USER || kmodule) {
994 char dso_name[PATH_MAX]; 1027 char dso_name[PATH_MAX];
995 1028
996 if (strcmp(section_name, 1029 if (strcmp(section_name,
@@ -1017,6 +1050,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1017 curr_dso = dso__new(dso_name); 1050 curr_dso = dso__new(dso_name);
1018 if (curr_dso == NULL) 1051 if (curr_dso == NULL)
1019 goto out_elf_end; 1052 goto out_elf_end;
1053 curr_dso->kernel = self->kernel;
1020 curr_map = map__new2(start, curr_dso, 1054 curr_map = map__new2(start, curr_dso,
1021 map->type); 1055 map->type);
1022 if (curr_map == NULL) { 1056 if (curr_map == NULL) {
@@ -1025,9 +1059,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1025 } 1059 }
1026 curr_map->map_ip = identity__map_ip; 1060 curr_map->map_ip = identity__map_ip;
1027 curr_map->unmap_ip = identity__map_ip; 1061 curr_map->unmap_ip = identity__map_ip;
1028 curr_dso->origin = DSO__ORIG_KERNEL; 1062 curr_dso->origin = self->origin;
1029 map_groups__insert(kmap->kmaps, curr_map); 1063 map_groups__insert(kmap->kmaps, curr_map);
1030 dsos__add(&dsos__kernel, curr_dso); 1064 dsos__add(&self->node, curr_dso);
1031 dso__set_loaded(curr_dso, map->type); 1065 dso__set_loaded(curr_dso, map->type);
1032 } else 1066 } else
1033 curr_dso = curr_map->dso; 1067 curr_dso = curr_map->dso;
@@ -1089,7 +1123,7 @@ static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1089 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0; 1123 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1090} 1124}
1091 1125
1092static bool __dsos__read_build_ids(struct list_head *head, bool with_hits) 1126bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1093{ 1127{
1094 bool have_build_id = false; 1128 bool have_build_id = false;
1095 struct dso *pos; 1129 struct dso *pos;
@@ -1107,13 +1141,6 @@ static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1107 return have_build_id; 1141 return have_build_id;
1108} 1142}
1109 1143
1110bool dsos__read_build_ids(bool with_hits)
1111{
1112 bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
1113 ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
1114 return kbuildids || ubuildids;
1115}
1116
1117/* 1144/*
1118 * Align offset to 4 bytes as needed for note name and descriptor data. 1145 * Align offset to 4 bytes as needed for note name and descriptor data.
1119 */ 1146 */
@@ -1248,6 +1275,8 @@ char dso__symtab_origin(const struct dso *self)
1248 [DSO__ORIG_BUILDID] = 'b', 1275 [DSO__ORIG_BUILDID] = 'b',
1249 [DSO__ORIG_DSO] = 'd', 1276 [DSO__ORIG_DSO] = 'd',
1250 [DSO__ORIG_KMODULE] = 'K', 1277 [DSO__ORIG_KMODULE] = 'K',
1278 [DSO__ORIG_GUEST_KERNEL] = 'g',
1279 [DSO__ORIG_GUEST_KMODULE] = 'G',
1251 }; 1280 };
1252 1281
1253 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 1282 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
@@ -1263,11 +1292,20 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1263 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1292 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1264 int ret = -1; 1293 int ret = -1;
1265 int fd; 1294 int fd;
1295 struct machine *machine;
1296 const char *root_dir;
1266 1297
1267 dso__set_loaded(self, map->type); 1298 dso__set_loaded(self, map->type);
1268 1299
1269 if (self->kernel) 1300 if (self->kernel == DSO_TYPE_KERNEL)
1270 return dso__load_kernel_sym(self, map, filter); 1301 return dso__load_kernel_sym(self, map, filter);
1302 else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
1303 return dso__load_guest_kernel_sym(self, map, filter);
1304
1305 if (map->groups && map->groups->machine)
1306 machine = map->groups->machine;
1307 else
1308 machine = NULL;
1271 1309
1272 name = malloc(size); 1310 name = malloc(size);
1273 if (!name) 1311 if (!name)
@@ -1321,6 +1359,13 @@ more:
1321 case DSO__ORIG_DSO: 1359 case DSO__ORIG_DSO:
1322 snprintf(name, size, "%s", self->long_name); 1360 snprintf(name, size, "%s", self->long_name);
1323 break; 1361 break;
1362 case DSO__ORIG_GUEST_KMODULE:
1363 if (map->groups && map->groups->machine)
1364 root_dir = map->groups->machine->root_dir;
1365 else
1366 root_dir = "";
1367 snprintf(name, size, "%s%s", root_dir, self->long_name);
1368 break;
1324 1369
1325 default: 1370 default:
1326 goto out; 1371 goto out;
@@ -1374,7 +1419,8 @@ struct map *map_groups__find_by_name(struct map_groups *self,
1374 return NULL; 1419 return NULL;
1375} 1420}
1376 1421
1377static int dso__kernel_module_get_build_id(struct dso *self) 1422static int dso__kernel_module_get_build_id(struct dso *self,
1423 const char *root_dir)
1378{ 1424{
1379 char filename[PATH_MAX]; 1425 char filename[PATH_MAX];
1380 /* 1426 /*
@@ -1384,8 +1430,8 @@ static int dso__kernel_module_get_build_id(struct dso *self)
1384 const char *name = self->short_name + 1; 1430 const char *name = self->short_name + 1;
1385 1431
1386 snprintf(filename, sizeof(filename), 1432 snprintf(filename, sizeof(filename),
1387 "/sys/module/%.*s/notes/.note.gnu.build-id", 1433 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1388 (int)strlen(name - 1), name); 1434 root_dir, (int)strlen(name) - 1, name);
1389 1435
1390 if (sysfs__read_build_id(filename, self->build_id, 1436 if (sysfs__read_build_id(filename, self->build_id,
1391 sizeof(self->build_id)) == 0) 1437 sizeof(self->build_id)) == 0)
@@ -1394,26 +1440,33 @@ static int dso__kernel_module_get_build_id(struct dso *self)
1394 return 0; 1440 return 0;
1395} 1441}
1396 1442
1397static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname) 1443static int map_groups__set_modules_path_dir(struct map_groups *self,
1444 const char *dir_name)
1398{ 1445{
1399 struct dirent *dent; 1446 struct dirent *dent;
1400 DIR *dir = opendir(dirname); 1447 DIR *dir = opendir(dir_name);
1401 1448
1402 if (!dir) { 1449 if (!dir) {
1403 pr_debug("%s: cannot open %s dir\n", __func__, dirname); 1450 pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
1404 return -1; 1451 return -1;
1405 } 1452 }
1406 1453
1407 while ((dent = readdir(dir)) != NULL) { 1454 while ((dent = readdir(dir)) != NULL) {
1408 char path[PATH_MAX]; 1455 char path[PATH_MAX];
1456 struct stat st;
1409 1457
1410 if (dent->d_type == DT_DIR) { 1458 /*sshfs might return bad dent->d_type, so we have to stat*/
1459 sprintf(path, "%s/%s", dir_name, dent->d_name);
1460 if (stat(path, &st))
1461 continue;
1462
1463 if (S_ISDIR(st.st_mode)) {
1411 if (!strcmp(dent->d_name, ".") || 1464 if (!strcmp(dent->d_name, ".") ||
1412 !strcmp(dent->d_name, "..")) 1465 !strcmp(dent->d_name, ".."))
1413 continue; 1466 continue;
1414 1467
1415 snprintf(path, sizeof(path), "%s/%s", 1468 snprintf(path, sizeof(path), "%s/%s",
1416 dirname, dent->d_name); 1469 dir_name, dent->d_name);
1417 if (map_groups__set_modules_path_dir(self, path) < 0) 1470 if (map_groups__set_modules_path_dir(self, path) < 0)
1418 goto failure; 1471 goto failure;
1419 } else { 1472 } else {
@@ -1433,13 +1486,13 @@ static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirna
1433 continue; 1486 continue;
1434 1487
1435 snprintf(path, sizeof(path), "%s/%s", 1488 snprintf(path, sizeof(path), "%s/%s",
1436 dirname, dent->d_name); 1489 dir_name, dent->d_name);
1437 1490
1438 long_name = strdup(path); 1491 long_name = strdup(path);
1439 if (long_name == NULL) 1492 if (long_name == NULL)
1440 goto failure; 1493 goto failure;
1441 dso__set_long_name(map->dso, long_name); 1494 dso__set_long_name(map->dso, long_name);
1442 dso__kernel_module_get_build_id(map->dso); 1495 dso__kernel_module_get_build_id(map->dso, "");
1443 } 1496 }
1444 } 1497 }
1445 1498
@@ -1449,18 +1502,47 @@ failure:
1449 return -1; 1502 return -1;
1450} 1503}
1451 1504
1452static int map_groups__set_modules_path(struct map_groups *self) 1505static char *get_kernel_version(const char *root_dir)
1453{ 1506{
1454 struct utsname uts; 1507 char version[PATH_MAX];
1508 FILE *file;
1509 char *name, *tmp;
1510 const char *prefix = "Linux version ";
1511
1512 sprintf(version, "%s/proc/version", root_dir);
1513 file = fopen(version, "r");
1514 if (!file)
1515 return NULL;
1516
1517 version[0] = '\0';
1518 tmp = fgets(version, sizeof(version), file);
1519 fclose(file);
1520
1521 name = strstr(version, prefix);
1522 if (!name)
1523 return NULL;
1524 name += strlen(prefix);
1525 tmp = strchr(name, ' ');
1526 if (tmp)
1527 *tmp = '\0';
1528
1529 return strdup(name);
1530}
1531
1532static int machine__set_modules_path(struct machine *self)
1533{
1534 char *version;
1455 char modules_path[PATH_MAX]; 1535 char modules_path[PATH_MAX];
1456 1536
1457 if (uname(&uts) < 0) 1537 version = get_kernel_version(self->root_dir);
1538 if (!version)
1458 return -1; 1539 return -1;
1459 1540
1460 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1541 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1461 uts.release); 1542 self->root_dir, version);
1543 free(version);
1462 1544
1463 return map_groups__set_modules_path_dir(self, modules_path); 1545 return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
1464} 1546}
1465 1547
1466/* 1548/*
@@ -1470,8 +1552,8 @@ static int map_groups__set_modules_path(struct map_groups *self)
1470 */ 1552 */
1471static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1553static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1472{ 1554{
1473 struct map *self = zalloc(sizeof(*self) + 1555 struct map *self = calloc(1, (sizeof(*self) +
1474 (dso->kernel ? sizeof(struct kmap) : 0)); 1556 (dso->kernel ? sizeof(struct kmap) : 0)));
1475 if (self != NULL) { 1557 if (self != NULL) {
1476 /* 1558 /*
1477 * ->end will be filled after we load all the symbols 1559 * ->end will be filled after we load all the symbols
@@ -1482,11 +1564,11 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1482 return self; 1564 return self;
1483} 1565}
1484 1566
1485struct map *map_groups__new_module(struct map_groups *self, u64 start, 1567struct map *machine__new_module(struct machine *self, u64 start,
1486 const char *filename) 1568 const char *filename)
1487{ 1569{
1488 struct map *map; 1570 struct map *map;
1489 struct dso *dso = __dsos__findnew(&dsos__kernel, filename); 1571 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
1490 1572
1491 if (dso == NULL) 1573 if (dso == NULL)
1492 return NULL; 1574 return NULL;
@@ -1495,18 +1577,31 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
1495 if (map == NULL) 1577 if (map == NULL)
1496 return NULL; 1578 return NULL;
1497 1579
1498 dso->origin = DSO__ORIG_KMODULE; 1580 if (machine__is_host(self))
1499 map_groups__insert(self, map); 1581 dso->origin = DSO__ORIG_KMODULE;
1582 else
1583 dso->origin = DSO__ORIG_GUEST_KMODULE;
1584 map_groups__insert(&self->kmaps, map);
1500 return map; 1585 return map;
1501} 1586}
1502 1587
1503static int map_groups__create_modules(struct map_groups *self) 1588static int machine__create_modules(struct machine *self)
1504{ 1589{
1505 char *line = NULL; 1590 char *line = NULL;
1506 size_t n; 1591 size_t n;
1507 FILE *file = fopen("/proc/modules", "r"); 1592 FILE *file;
1508 struct map *map; 1593 struct map *map;
1594 const char *modules;
1595 char path[PATH_MAX];
1596
1597 if (machine__is_default_guest(self))
1598 modules = symbol_conf.default_guest_modules;
1599 else {
1600 sprintf(path, "%s/proc/modules", self->root_dir);
1601 modules = path;
1602 }
1509 1603
1604 file = fopen(modules, "r");
1510 if (file == NULL) 1605 if (file == NULL)
1511 return -1; 1606 return -1;
1512 1607
@@ -1538,16 +1633,16 @@ static int map_groups__create_modules(struct map_groups *self)
1538 *sep = '\0'; 1633 *sep = '\0';
1539 1634
1540 snprintf(name, sizeof(name), "[%s]", line); 1635 snprintf(name, sizeof(name), "[%s]", line);
1541 map = map_groups__new_module(self, start, name); 1636 map = machine__new_module(self, start, name);
1542 if (map == NULL) 1637 if (map == NULL)
1543 goto out_delete_line; 1638 goto out_delete_line;
1544 dso__kernel_module_get_build_id(map->dso); 1639 dso__kernel_module_get_build_id(map->dso, self->root_dir);
1545 } 1640 }
1546 1641
1547 free(line); 1642 free(line);
1548 fclose(file); 1643 fclose(file);
1549 1644
1550 return map_groups__set_modules_path(self); 1645 return machine__set_modules_path(self);
1551 1646
1552out_delete_line: 1647out_delete_line:
1553 free(line); 1648 free(line);
@@ -1714,8 +1809,56 @@ out_fixup:
1714 return err; 1809 return err;
1715} 1810}
1716 1811
1717LIST_HEAD(dsos__user); 1812static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1718LIST_HEAD(dsos__kernel); 1813 symbol_filter_t filter)
1814{
1815 int err;
1816 const char *kallsyms_filename = NULL;
1817 struct machine *machine;
1818 char path[PATH_MAX];
1819
1820 if (!map->groups) {
1821 pr_debug("Guest kernel map hasn't the point to groups\n");
1822 return -1;
1823 }
1824 machine = map->groups->machine;
1825
1826 if (machine__is_default_guest(machine)) {
1827 /*
1828 * if the user specified a vmlinux filename, use it and only
1829 * it, reporting errors to the user if it cannot be used.
1830 * Or use file guest_kallsyms inputted by user on commandline
1831 */
1832 if (symbol_conf.default_guest_vmlinux_name != NULL) {
1833 err = dso__load_vmlinux(self, map,
1834 symbol_conf.default_guest_vmlinux_name, filter);
1835 goto out_try_fixup;
1836 }
1837
1838 kallsyms_filename = symbol_conf.default_guest_kallsyms;
1839 if (!kallsyms_filename)
1840 return -1;
1841 } else {
1842 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1843 kallsyms_filename = path;
1844 }
1845
1846 err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1847 if (err > 0)
1848 pr_debug("Using %s for symbols\n", kallsyms_filename);
1849
1850out_try_fixup:
1851 if (err > 0) {
1852 if (kallsyms_filename != NULL) {
1853 machine__mmap_name(machine, path, sizeof(path));
1854 dso__set_long_name(self, strdup(path));
1855 }
1856 map__fixup_start(map);
1857 map__fixup_end(map);
1858 }
1859
1860 return err;
1861}
1719 1862
1720static void dsos__add(struct list_head *head, struct dso *dso) 1863static void dsos__add(struct list_head *head, struct dso *dso)
1721{ 1864{
@@ -1747,21 +1890,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
1747 return dso; 1890 return dso;
1748} 1891}
1749 1892
1750static void __dsos__fprintf(struct list_head *head, FILE *fp) 1893size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1751{ 1894{
1752 struct dso *pos; 1895 struct dso *pos;
1896 size_t ret = 0;
1753 1897
1754 list_for_each_entry(pos, head, node) { 1898 list_for_each_entry(pos, head, node) {
1755 int i; 1899 int i;
1756 for (i = 0; i < MAP__NR_TYPES; ++i) 1900 for (i = 0; i < MAP__NR_TYPES; ++i)
1757 dso__fprintf(pos, i, fp); 1901 ret += dso__fprintf(pos, i, fp);
1758 } 1902 }
1903
1904 return ret;
1759} 1905}
1760 1906
1761void dsos__fprintf(FILE *fp) 1907size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
1762{ 1908{
1763 __dsos__fprintf(&dsos__kernel, fp); 1909 struct rb_node *nd;
1764 __dsos__fprintf(&dsos__user, fp); 1910 size_t ret = 0;
1911
1912 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1913 struct machine *pos = rb_entry(nd, struct machine, rb_node);
1914 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
1915 ret += __dsos__fprintf(&pos->user_dsos, fp);
1916 }
1917
1918 return ret;
1765} 1919}
1766 1920
1767static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, 1921static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
@@ -1779,10 +1933,17 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1779 return ret; 1933 return ret;
1780} 1934}
1781 1935
1782size_t dsos__fprintf_buildid(FILE *fp, bool with_hits) 1936size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
1783{ 1937{
1784 return (__dsos__fprintf_buildid(&dsos__kernel, fp, with_hits) + 1938 struct rb_node *nd;
1785 __dsos__fprintf_buildid(&dsos__user, fp, with_hits)); 1939 size_t ret = 0;
1940
1941 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1942 struct machine *pos = rb_entry(nd, struct machine, rb_node);
1943 ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
1944 ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
1945 }
1946 return ret;
1786} 1947}
1787 1948
1788struct dso *dso__new_kernel(const char *name) 1949struct dso *dso__new_kernel(const char *name)
@@ -1791,55 +1952,98 @@ struct dso *dso__new_kernel(const char *name)
1791 1952
1792 if (self != NULL) { 1953 if (self != NULL) {
1793 dso__set_short_name(self, "[kernel]"); 1954 dso__set_short_name(self, "[kernel]");
1794 self->kernel = 1; 1955 self->kernel = DSO_TYPE_KERNEL;
1795 } 1956 }
1796 1957
1797 return self; 1958 return self;
1798} 1959}
1799 1960
1800void dso__read_running_kernel_build_id(struct dso *self) 1961static struct dso *dso__new_guest_kernel(struct machine *machine,
1962 const char *name)
1801{ 1963{
1802 if (sysfs__read_build_id("/sys/kernel/notes", self->build_id, 1964 char bf[PATH_MAX];
1965 struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
1966
1967 if (self != NULL) {
1968 dso__set_short_name(self, "[guest.kernel]");
1969 self->kernel = DSO_TYPE_GUEST_KERNEL;
1970 }
1971
1972 return self;
1973}
1974
1975void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
1976{
1977 char path[PATH_MAX];
1978
1979 if (machine__is_default_guest(machine))
1980 return;
1981 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
1982 if (sysfs__read_build_id(path, self->build_id,
1803 sizeof(self->build_id)) == 0) 1983 sizeof(self->build_id)) == 0)
1804 self->has_build_id = true; 1984 self->has_build_id = true;
1805} 1985}
1806 1986
1807static struct dso *dsos__create_kernel(const char *vmlinux) 1987static struct dso *machine__create_kernel(struct machine *self)
1808{ 1988{
1809 struct dso *kernel = dso__new_kernel(vmlinux); 1989 const char *vmlinux_name = NULL;
1990 struct dso *kernel;
1810 1991
1811 if (kernel != NULL) { 1992 if (machine__is_host(self)) {
1812 dso__read_running_kernel_build_id(kernel); 1993 vmlinux_name = symbol_conf.vmlinux_name;
1813 dsos__add(&dsos__kernel, kernel); 1994 kernel = dso__new_kernel(vmlinux_name);
1995 } else {
1996 if (machine__is_default_guest(self))
1997 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
1998 kernel = dso__new_guest_kernel(self, vmlinux_name);
1814 } 1999 }
1815 2000
2001 if (kernel != NULL) {
2002 dso__read_running_kernel_build_id(kernel, self);
2003 dsos__add(&self->kernel_dsos, kernel);
2004 }
1816 return kernel; 2005 return kernel;
1817} 2006}
1818 2007
1819int __map_groups__create_kernel_maps(struct map_groups *self, 2008int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
1820 struct map *vmlinux_maps[MAP__NR_TYPES],
1821 struct dso *kernel)
1822{ 2009{
1823 enum map_type type; 2010 enum map_type type;
1824 2011
1825 for (type = 0; type < MAP__NR_TYPES; ++type) { 2012 for (type = 0; type < MAP__NR_TYPES; ++type) {
1826 struct kmap *kmap; 2013 struct kmap *kmap;
1827 2014
1828 vmlinux_maps[type] = map__new2(0, kernel, type); 2015 self->vmlinux_maps[type] = map__new2(0, kernel, type);
1829 if (vmlinux_maps[type] == NULL) 2016 if (self->vmlinux_maps[type] == NULL)
1830 return -1; 2017 return -1;
1831 2018
1832 vmlinux_maps[type]->map_ip = 2019 self->vmlinux_maps[type]->map_ip =
1833 vmlinux_maps[type]->unmap_ip = identity__map_ip; 2020 self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
1834 2021
1835 kmap = map__kmap(vmlinux_maps[type]); 2022 kmap = map__kmap(self->vmlinux_maps[type]);
1836 kmap->kmaps = self; 2023 kmap->kmaps = &self->kmaps;
1837 map_groups__insert(self, vmlinux_maps[type]); 2024 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
1838 } 2025 }
1839 2026
1840 return 0; 2027 return 0;
1841} 2028}
1842 2029
2030int machine__create_kernel_maps(struct machine *self)
2031{
2032 struct dso *kernel = machine__create_kernel(self);
2033
2034 if (kernel == NULL ||
2035 __machine__create_kernel_maps(self, kernel) < 0)
2036 return -1;
2037
2038 if (symbol_conf.use_modules && machine__create_modules(self) < 0)
2039 pr_debug("Problems creating module maps, continuing anyway...\n");
2040 /*
2041 * Now that we have all the maps created, just set the ->end of them:
2042 */
2043 map_groups__fixup_end(&self->kmaps);
2044 return 0;
2045}
2046
1843static void vmlinux_path__exit(void) 2047static void vmlinux_path__exit(void)
1844{ 2048{
1845 while (--vmlinux_path__nr_entries >= 0) { 2049 while (--vmlinux_path__nr_entries >= 0) {
@@ -1895,6 +2099,17 @@ out_fail:
1895 return -1; 2099 return -1;
1896} 2100}
1897 2101
2102size_t vmlinux_path__fprintf(FILE *fp)
2103{
2104 int i;
2105 size_t printed = 0;
2106
2107 for (i = 0; i < vmlinux_path__nr_entries; ++i)
2108 printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);
2109
2110 return printed;
2111}
2112
1898static int setup_list(struct strlist **list, const char *list_str, 2113static int setup_list(struct strlist **list, const char *list_str,
1899 const char *list_name) 2114 const char *list_name)
1900{ 2115{
@@ -1945,22 +2160,129 @@ out_free_comm_list:
1945 return -1; 2160 return -1;
1946} 2161}
1947 2162
1948int map_groups__create_kernel_maps(struct map_groups *self, 2163int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
1949 struct map *vmlinux_maps[MAP__NR_TYPES])
1950{ 2164{
1951 struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name); 2165 struct machine *machine = machines__findnew(self, pid);
1952 2166
1953 if (kernel == NULL) 2167 if (machine == NULL)
1954 return -1; 2168 return -1;
1955 2169
1956 if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0) 2170 return machine__create_kernel_maps(machine);
1957 return -1; 2171}
1958 2172
1959 if (symbol_conf.use_modules && map_groups__create_modules(self) < 0) 2173static int hex(char ch)
1960 pr_debug("Problems creating module maps, continuing anyway...\n"); 2174{
1961 /* 2175 if ((ch >= '0') && (ch <= '9'))
1962 * Now that we have all the maps created, just set the ->end of them: 2176 return ch - '0';
1963 */ 2177 if ((ch >= 'a') && (ch <= 'f'))
1964 map_groups__fixup_end(self); 2178 return ch - 'a' + 10;
1965 return 0; 2179 if ((ch >= 'A') && (ch <= 'F'))
2180 return ch - 'A' + 10;
2181 return -1;
2182}
2183
2184/*
2185 * While we find nice hex chars, build a long_val.
2186 * Return number of chars processed.
2187 */
2188int hex2u64(const char *ptr, u64 *long_val)
2189{
2190 const char *p = ptr;
2191 *long_val = 0;
2192
2193 while (*p) {
2194 const int hex_val = hex(*p);
2195
2196 if (hex_val < 0)
2197 break;
2198
2199 *long_val = (*long_val << 4) | hex_val;
2200 p++;
2201 }
2202
2203 return p - ptr;
2204}
2205
2206char *strxfrchar(char *s, char from, char to)
2207{
2208 char *p = s;
2209
2210 while ((p = strchr(p, from)) != NULL)
2211 *p++ = to;
2212
2213 return s;
2214}
2215
2216int machines__create_guest_kernel_maps(struct rb_root *self)
2217{
2218 int ret = 0;
2219 struct dirent **namelist = NULL;
2220 int i, items = 0;
2221 char path[PATH_MAX];
2222 pid_t pid;
2223
2224 if (symbol_conf.default_guest_vmlinux_name ||
2225 symbol_conf.default_guest_modules ||
2226 symbol_conf.default_guest_kallsyms) {
2227 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
2228 }
2229
2230 if (symbol_conf.guestmount) {
2231 items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
2232 if (items <= 0)
2233 return -ENOENT;
2234 for (i = 0; i < items; i++) {
2235 if (!isdigit(namelist[i]->d_name[0])) {
2236 /* Filter out . and .. */
2237 continue;
2238 }
2239 pid = atoi(namelist[i]->d_name);
2240 sprintf(path, "%s/%s/proc/kallsyms",
2241 symbol_conf.guestmount,
2242 namelist[i]->d_name);
2243 ret = access(path, R_OK);
2244 if (ret) {
2245 pr_debug("Can't access file %s\n", path);
2246 goto failure;
2247 }
2248 machines__create_kernel_maps(self, pid);
2249 }
2250failure:
2251 free(namelist);
2252 }
2253
2254 return ret;
2255}
2256
2257int machine__load_kallsyms(struct machine *self, const char *filename,
2258 enum map_type type, symbol_filter_t filter)
2259{
2260 struct map *map = self->vmlinux_maps[type];
2261 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2262
2263 if (ret > 0) {
2264 dso__set_loaded(map->dso, type);
2265 /*
2266 * Since /proc/kallsyms will have multiple sessions for the
2267 * kernel, with modules between them, fixup the end of all
2268 * sections.
2269 */
2270 __map_groups__fixup_end(&self->kmaps, type);
2271 }
2272
2273 return ret;
2274}
2275
2276int machine__load_vmlinux_path(struct machine *self, enum map_type type,
2277 symbol_filter_t filter)
2278{
2279 struct map *map = self->vmlinux_maps[type];
2280 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2281
2282 if (ret > 0) {
2283 dso__set_loaded(map->dso, type);
2284 map__reloc_vmlinux(map);
2285 }
2286
2287 return ret;
1966} 2288}