aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/symbol.c157
-rw-r--r--tools/perf/util/symbol.h2
-rw-r--r--tools/perf/util/thread.c115
-rw-r--r--tools/perf/util/thread.h15
7 files changed, 162 insertions, 133 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index c32e7609b77b..3ebd70b1ef93 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -167,7 +167,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
167 map ? map->dso->long_name : "<not found>"); 167 map ? map->dso->long_name : "<not found>");
168 } else if (event->header.misc & PERF_RECORD_MISC_USER) { 168 } else if (event->header.misc & PERF_RECORD_MISC_USER) {
169 level = '.'; 169 level = '.';
170 map = thread__find_map(thread, ip); 170 map = thread__find_map(thread, MAP__FUNCTION, ip);
171 if (map != NULL) { 171 if (map != NULL) {
172 ip = map->map_ip(map, ip); 172 ip = map->map_ip(map, ip);
173 sym = map__find_symbol(map, ip, symbol_filter); 173 sym = map__find_symbol(map, ip, symbol_filter);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 400bef981c6c..9bd20c2ee3dd 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -422,7 +422,7 @@ resolve_symbol(struct thread *thread, struct map **mapp, u64 *ipp)
422 if (!thread) 422 if (!thread)
423 return NULL; 423 return NULL;
424 424
425 map = thread__find_map(thread, ip); 425 map = thread__find_map(thread, MAP__FUNCTION, ip);
426 if (map != NULL) { 426 if (map != NULL) {
427 /* 427 /*
428 * We have to do this here as we may have a dso 428 * We have to do this here as we may have a dso
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index abe78bbd154a..bf6730c76033 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -945,7 +945,7 @@ static void event__process_sample(const event_t *self, int counter)
945 if (thread == NULL) 945 if (thread == NULL)
946 return; 946 return;
947 947
948 map = thread__find_map(thread, ip); 948 map = thread__find_map(thread, MAP__FUNCTION, ip);
949 if (map != NULL) { 949 if (map != NULL) {
950 ip = map->map_ip(map, ip); 950 ip = map->map_ip(map, ip);
951 sym = map__find_symbol(map, ip, symbol_filter); 951 sym = map__find_symbol(map, ip, symbol_filter);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 581db4c43251..b6a2941e7786 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -29,12 +29,11 @@ enum dso_origin {
29}; 29};
30 30
31static void dsos__add(struct list_head *head, struct dso *dso); 31static void dsos__add(struct list_head *head, struct dso *dso);
32static struct map *kernel_maps__find_by_dso_name(const char *name); 32static struct map *thread__find_map_by_name(struct thread *self, char *name);
33static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 33static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
34static void kernel_maps__insert(struct map *map);
35struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 34struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
36static int dso__load_kernel_sym(struct dso *self, struct map *map, 35static int dso__load_kernel_sym(struct dso *self, struct map *map,
37 symbol_filter_t filter); 36 struct thread *thread, symbol_filter_t filter);
38unsigned int symbol__priv_size; 37unsigned int symbol__priv_size;
39static int vmlinux_path__nr_entries; 38static int vmlinux_path__nr_entries;
40static char **vmlinux_path; 39static char **vmlinux_path;
@@ -44,7 +43,7 @@ static struct symbol_conf symbol_conf__defaults = {
44 .try_vmlinux_path = true, 43 .try_vmlinux_path = true,
45}; 44};
46 45
47static struct rb_root kernel_maps[MAP__NR_TYPES]; 46static struct thread kthread_mem, *kthread = &kthread_mem;
48 47
49bool dso__loaded(const struct dso *self, enum map_type type) 48bool dso__loaded(const struct dso *self, enum map_type type)
50{ 49{
@@ -79,10 +78,10 @@ static void symbols__fixup_end(struct rb_root *self)
79 curr->end = roundup(curr->start, 4096); 78 curr->end = roundup(curr->start, 4096);
80} 79}
81 80
82static void __kernel_maps__fixup_end(struct rb_root *root) 81static void __thread__fixup_maps_end(struct thread *self, enum map_type type)
83{ 82{
84 struct map *prev, *curr; 83 struct map *prev, *curr;
85 struct rb_node *nd, *prevnd = rb_first(root); 84 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
86 85
87 if (prevnd == NULL) 86 if (prevnd == NULL)
88 return; 87 return;
@@ -102,11 +101,11 @@ static void __kernel_maps__fixup_end(struct rb_root *root)
102 curr->end = ~0UL; 101 curr->end = ~0UL;
103} 102}
104 103
105static void kernel_maps__fixup_end(void) 104static void thread__fixup_maps_end(struct thread *self)
106{ 105{
107 int i; 106 int i;
108 for (i = 0; i < MAP__NR_TYPES; ++i) 107 for (i = 0; i < MAP__NR_TYPES; ++i)
109 __kernel_maps__fixup_end(&kernel_maps[i]); 108 __thread__fixup_maps_end(self, i);
110} 109}
111 110
112static struct symbol *symbol__new(u64 start, u64 len, const char *name) 111static struct symbol *symbol__new(u64 start, u64 len, const char *name)
@@ -274,25 +273,16 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
274 return fprintf(fp, "%s", sbuild_id); 273 return fprintf(fp, "%s", sbuild_id);
275} 274}
276 275
277static const char * map_type__name[MAP__NR_TYPES] = { 276size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
278 [MAP__FUNCTION] = "Functions",
279};
280
281size_t dso__fprintf(struct dso *self, FILE *fp)
282{ 277{
283 int i;
284 struct rb_node *nd; 278 struct rb_node *nd;
285 size_t ret = fprintf(fp, "dso: %s (", self->short_name); 279 size_t ret = fprintf(fp, "dso: %s (", self->short_name);
286 280
287 ret += dso__fprintf_buildid(self, fp); 281 ret += dso__fprintf_buildid(self, fp);
288 ret += fprintf(fp, ")\n"); 282 ret += fprintf(fp, ")\n");
289 for (i = 0; i < MAP__NR_TYPES; ++i) { 283 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
290 ret += fprintf(fp, "%s:\n", map_type__name[i]); 284 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
291 285 ret += symbol__fprintf(pos, fp);
292 for (nd = rb_first(&self->symbols[i]); nd; nd = rb_next(nd)) {
293 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
294 ret += symbol__fprintf(pos, fp);
295 }
296 } 286 }
297 287
298 return ret; 288 return ret;
@@ -373,7 +363,7 @@ out_failure:
373 * kernel range is broken in several maps, named [kernel].N, as we don't have 363 * kernel range is broken in several maps, named [kernel].N, as we don't have
374 * the original ELF section names vmlinux have. 364 * the original ELF section names vmlinux have.
375 */ 365 */
376static int dso__split_kallsyms(struct dso *self, struct map *map, 366static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread,
377 symbol_filter_t filter) 367 symbol_filter_t filter)
378{ 368{
379 struct map *curr_map = map; 369 struct map *curr_map = map;
@@ -394,10 +384,10 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
394 *module++ = '\0'; 384 *module++ = '\0';
395 385
396 if (strcmp(self->name, module)) { 386 if (strcmp(self->name, module)) {
397 curr_map = kernel_maps__find_by_dso_name(module); 387 curr_map = thread__find_map_by_name(thread, module);
398 if (curr_map == NULL) { 388 if (curr_map == NULL) {
399 pr_err("/proc/{kallsyms,modules} " 389 pr_debug("/proc/{kallsyms,modules} "
400 "inconsistency!\n"); 390 "inconsistency!\n");
401 return -1; 391 return -1;
402 } 392 }
403 } 393 }
@@ -425,7 +415,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
425 } 415 }
426 416
427 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 417 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
428 kernel_maps__insert(curr_map); 418 __thread__insert_map(thread, curr_map);
429 ++kernel_range; 419 ++kernel_range;
430 } 420 }
431 421
@@ -446,7 +436,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
446 436
447 437
448static int dso__load_kallsyms(struct dso *self, struct map *map, 438static int dso__load_kallsyms(struct dso *self, struct map *map,
449 symbol_filter_t filter) 439 struct thread *thread, symbol_filter_t filter)
450{ 440{
451 if (dso__load_all_kallsyms(self, map) < 0) 441 if (dso__load_all_kallsyms(self, map) < 0)
452 return -1; 442 return -1;
@@ -454,35 +444,13 @@ static int dso__load_kallsyms(struct dso *self, struct map *map,
454 symbols__fixup_end(&self->symbols[map->type]); 444 symbols__fixup_end(&self->symbols[map->type]);
455 self->origin = DSO__ORIG_KERNEL; 445 self->origin = DSO__ORIG_KERNEL;
456 446
457 return dso__split_kallsyms(self, map, filter); 447 return dso__split_kallsyms(self, map, thread, filter);
458}
459
460static size_t __kernel_maps__fprintf(enum map_type type, FILE *fp)
461{
462 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
463 struct rb_node *nd;
464
465 for (nd = rb_first(&kernel_maps[type]); nd; nd = rb_next(nd)) {
466 struct map *pos = rb_entry(nd, struct map, rb_node);
467
468 printed += fprintf(fp, "Map:");
469 printed += map__fprintf(pos, fp);
470 if (verbose > 1) {
471 printed += dso__fprintf(pos->dso, fp);
472 printed += fprintf(fp, "--\n");
473 }
474 }
475
476 return printed;
477} 448}
478 449
479size_t kernel_maps__fprintf(FILE *fp) 450size_t kernel_maps__fprintf(FILE *fp)
480{ 451{
481 size_t printed = fprintf(fp, "Kernel maps:\n"); 452 size_t printed = fprintf(fp, "Kernel maps:\n");
482 int i; 453 printed += thread__fprintf_maps(kthread, fp);
483 for (i = 0; i < MAP__NR_TYPES; ++i)
484 printed += __kernel_maps__fprintf(i, fp);
485
486 return printed + fprintf(fp, "END kernel maps\n"); 454 return printed + fprintf(fp, "END kernel maps\n");
487} 455}
488 456
@@ -772,9 +740,9 @@ out:
772 return 0; 740 return 0;
773} 741}
774 742
775static int dso__load_sym(struct dso *self, struct map *map, const char *name, 743static int dso__load_sym(struct dso *self, struct map *map,
776 int fd, symbol_filter_t filter, int kernel, 744 struct thread *thread, const char *name, int fd,
777 int kmodule) 745 symbol_filter_t filter, int kernel, int kmodule)
778{ 746{
779 struct map *curr_map = map; 747 struct map *curr_map = map;
780 struct dso *curr_dso = self; 748 struct dso *curr_dso = self;
@@ -877,7 +845,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
877 snprintf(dso_name, sizeof(dso_name), 845 snprintf(dso_name, sizeof(dso_name),
878 "%s%s", self->short_name, section_name); 846 "%s%s", self->short_name, section_name);
879 847
880 curr_map = kernel_maps__find_by_dso_name(dso_name); 848 curr_map = thread__find_map_by_name(thread, dso_name);
881 if (curr_map == NULL) { 849 if (curr_map == NULL) {
882 u64 start = sym.st_value; 850 u64 start = sym.st_value;
883 851
@@ -896,7 +864,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
896 curr_map->map_ip = identity__map_ip; 864 curr_map->map_ip = identity__map_ip;
897 curr_map->unmap_ip = identity__map_ip; 865 curr_map->unmap_ip = identity__map_ip;
898 curr_dso->origin = DSO__ORIG_KERNEL; 866 curr_dso->origin = DSO__ORIG_KERNEL;
899 kernel_maps__insert(curr_map); 867 __thread__insert_map(kthread, curr_map);
900 dsos__add(&dsos__kernel, curr_dso); 868 dsos__add(&dsos__kernel, curr_dso);
901 } else 869 } else
902 curr_dso = curr_map->dso; 870 curr_dso = curr_map->dso;
@@ -1121,7 +1089,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1121 dso__set_loaded(self, map->type); 1089 dso__set_loaded(self, map->type);
1122 1090
1123 if (self->kernel) 1091 if (self->kernel)
1124 return dso__load_kernel_sym(self, map, filter); 1092 return dso__load_kernel_sym(self, map, kthread, filter);
1125 1093
1126 name = malloc(size); 1094 name = malloc(size);
1127 if (!name) 1095 if (!name)
@@ -1186,7 +1154,7 @@ compare_build_id:
1186 fd = open(name, O_RDONLY); 1154 fd = open(name, O_RDONLY);
1187 } while (fd < 0); 1155 } while (fd < 0);
1188 1156
1189 ret = dso__load_sym(self, map, name, fd, filter, 0, 0); 1157 ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0);
1190 close(fd); 1158 close(fd);
1191 1159
1192 /* 1160 /*
@@ -1207,16 +1175,11 @@ out:
1207 return ret; 1175 return ret;
1208} 1176}
1209 1177
1210static void kernel_maps__insert(struct map *map) 1178static struct symbol *thread__find_symbol(struct thread *self, u64 ip,
1211{ 1179 enum map_type type, struct map **mapp,
1212 maps__insert(&kernel_maps[map->type], map); 1180 symbol_filter_t filter)
1213}
1214
1215static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type,
1216 struct map **mapp,
1217 symbol_filter_t filter)
1218{ 1181{
1219 struct map *map = maps__find(&kernel_maps[type], ip); 1182 struct map *map = thread__find_map(self, type, ip);
1220 1183
1221 if (mapp) 1184 if (mapp)
1222 *mapp = map; 1185 *mapp = map;
@@ -1224,9 +1187,7 @@ static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type,
1224 if (map) { 1187 if (map) {
1225 ip = map->map_ip(map, ip); 1188 ip = map->map_ip(map, ip);
1226 return map__find_symbol(map, ip, filter); 1189 return map__find_symbol(map, ip, filter);
1227 } else 1190 }
1228 WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps[type]),
1229 "Empty kernel_maps, was symbol__init() called?\n");
1230 1191
1231 return NULL; 1192 return NULL;
1232} 1193}
@@ -1234,14 +1195,14 @@ static struct symbol *kernel_maps__find_symbol(u64 ip, enum map_type type,
1234struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp, 1195struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp,
1235 symbol_filter_t filter) 1196 symbol_filter_t filter)
1236{ 1197{
1237 return kernel_maps__find_symbol(ip, MAP__FUNCTION, mapp, filter); 1198 return thread__find_symbol(kthread, ip, MAP__FUNCTION, mapp, filter);
1238} 1199}
1239 1200
1240static struct map *kernel_maps__find_by_dso_name(const char *name) 1201static struct map *thread__find_map_by_name(struct thread *self, char *name)
1241{ 1202{
1242 struct rb_node *nd; 1203 struct rb_node *nd;
1243 1204
1244 for (nd = rb_first(&kernel_maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 1205 for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
1245 struct map *map = rb_entry(nd, struct map, rb_node); 1206 struct map *map = rb_entry(nd, struct map, rb_node);
1246 1207
1247 if (map->dso && strcmp(map->dso->name, name) == 0) 1208 if (map->dso && strcmp(map->dso->name, name) == 0)
@@ -1285,7 +1246,7 @@ static int dsos__set_modules_path_dir(char *dirname)
1285 (int)(dot - dent->d_name), dent->d_name); 1246 (int)(dot - dent->d_name), dent->d_name);
1286 1247
1287 strxfrchar(dso_name, '-', '_'); 1248 strxfrchar(dso_name, '-', '_');
1288 map = kernel_maps__find_by_dso_name(dso_name); 1249 map = thread__find_map_by_name(kthread, dso_name);
1289 if (map == NULL) 1250 if (map == NULL)
1290 continue; 1251 continue;
1291 1252
@@ -1338,7 +1299,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1338 return self; 1299 return self;
1339} 1300}
1340 1301
1341static int kernel_maps__create_module_maps(void) 1302static int thread__create_module_maps(struct thread *self)
1342{ 1303{
1343 char *line = NULL; 1304 char *line = NULL;
1344 size_t n; 1305 size_t n;
@@ -1395,7 +1356,7 @@ static int kernel_maps__create_module_maps(void)
1395 dso->has_build_id = true; 1356 dso->has_build_id = true;
1396 1357
1397 dso->origin = DSO__ORIG_KMODULE; 1358 dso->origin = DSO__ORIG_KMODULE;
1398 kernel_maps__insert(map); 1359 __thread__insert_map(self, map);
1399 dsos__add(&dsos__kernel, dso); 1360 dsos__add(&dsos__kernel, dso);
1400 } 1361 }
1401 1362
@@ -1410,7 +1371,7 @@ out_failure:
1410 return -1; 1371 return -1;
1411} 1372}
1412 1373
1413static int dso__load_vmlinux(struct dso *self, struct map *map, 1374static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread,
1414 const char *vmlinux, symbol_filter_t filter) 1375 const char *vmlinux, symbol_filter_t filter)
1415{ 1376{
1416 int err = -1, fd; 1377 int err = -1, fd;
@@ -1444,15 +1405,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1444 return -1; 1405 return -1;
1445 1406
1446 dso__set_loaded(self, map->type); 1407 dso__set_loaded(self, map->type);
1447 err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0); 1408 err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0);
1448
1449 close(fd); 1409 close(fd);
1450 1410
1451 return err; 1411 return err;
1452} 1412}
1453 1413
1454static int dso__load_kernel_sym(struct dso *self, struct map *map, 1414static int dso__load_kernel_sym(struct dso *self, struct map *map,
1455 symbol_filter_t filter) 1415 struct thread *thread, symbol_filter_t filter)
1456{ 1416{
1457 int err; 1417 int err;
1458 bool is_kallsyms; 1418 bool is_kallsyms;
@@ -1462,8 +1422,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1462 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1422 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1463 vmlinux_path__nr_entries); 1423 vmlinux_path__nr_entries);
1464 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1424 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1465 err = dso__load_vmlinux(self, map, vmlinux_path[i], 1425 err = dso__load_vmlinux(self, map, thread,
1466 filter); 1426 vmlinux_path[i], filter);
1467 if (err > 0) { 1427 if (err > 0) {
1468 pr_debug("Using %s for symbols\n", 1428 pr_debug("Using %s for symbols\n",
1469 vmlinux_path[i]); 1429 vmlinux_path[i]);
@@ -1478,12 +1438,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1478 if (is_kallsyms) 1438 if (is_kallsyms)
1479 goto do_kallsyms; 1439 goto do_kallsyms;
1480 1440
1481 err = dso__load_vmlinux(self, map, self->long_name, filter); 1441 err = dso__load_vmlinux(self, map, thread, self->long_name, filter);
1482 if (err <= 0) { 1442 if (err <= 0) {
1483 pr_info("The file %s cannot be used, " 1443 pr_info("The file %s cannot be used, "
1484 "trying to use /proc/kallsyms...", self->long_name); 1444 "trying to use /proc/kallsyms...", self->long_name);
1485do_kallsyms: 1445do_kallsyms:
1486 err = dso__load_kallsyms(self, map, filter); 1446 err = dso__load_kallsyms(self, map, thread, filter);
1487 if (err > 0 && !is_kallsyms) 1447 if (err > 0 && !is_kallsyms)
1488 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1448 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1489 } 1449 }
@@ -1535,8 +1495,11 @@ static void __dsos__fprintf(struct list_head *head, FILE *fp)
1535{ 1495{
1536 struct dso *pos; 1496 struct dso *pos;
1537 1497
1538 list_for_each_entry(pos, head, node) 1498 list_for_each_entry(pos, head, node) {
1539 dso__fprintf(pos, fp); 1499 int i;
1500 for (i = 0; i < MAP__NR_TYPES; ++i)
1501 dso__fprintf(pos, i, fp);
1502 }
1540} 1503}
1541 1504
1542void dsos__fprintf(FILE *fp) 1505void dsos__fprintf(FILE *fp)
@@ -1563,10 +1526,10 @@ size_t dsos__fprintf_buildid(FILE *fp)
1563 __dsos__fprintf_buildid(&dsos__user, fp)); 1526 __dsos__fprintf_buildid(&dsos__user, fp));
1564} 1527}
1565 1528
1566static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) 1529static int thread__create_kernel_map(struct thread *self, const char *vmlinux)
1567{ 1530{
1568 struct map *kmap; 1531 struct map *kmap;
1569 struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]"); 1532 struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]");
1570 1533
1571 if (kernel == NULL) 1534 if (kernel == NULL)
1572 return -1; 1535 return -1;
@@ -1588,7 +1551,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
1588 sizeof(kernel->build_id)) == 0) 1551 sizeof(kernel->build_id)) == 0)
1589 kernel->has_build_id = true; 1552 kernel->has_build_id = true;
1590 1553
1591 kernel_maps__insert(kmap); 1554 __thread__insert_map(self, kmap);
1592 dsos__add(&dsos__kernel, kernel); 1555 dsos__add(&dsos__kernel, kernel);
1593 dsos__add(&dsos__user, vdso); 1556 dsos__add(&dsos__user, vdso);
1594 1557
@@ -1656,32 +1619,28 @@ out_fail:
1656 return -1; 1619 return -1;
1657} 1620}
1658 1621
1659static int kernel_maps__init(const struct symbol_conf *conf) 1622int symbol__init(struct symbol_conf *conf)
1660{ 1623{
1661 const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; 1624 const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
1662 1625
1626 elf_version(EV_CURRENT);
1663 symbol__priv_size = pconf->priv_size; 1627 symbol__priv_size = pconf->priv_size;
1628 thread__init(kthread, 0);
1664 1629
1665 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) 1630 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1666 return -1; 1631 return -1;
1667 1632
1668 if (kernel_maps__create_kernel_map(pconf) < 0) { 1633 if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) {
1669 vmlinux_path__exit(); 1634 vmlinux_path__exit();
1670 return -1; 1635 return -1;
1671 } 1636 }
1672 1637
1673 if (pconf->use_modules && kernel_maps__create_module_maps() < 0) 1638 if (pconf->use_modules && thread__create_module_maps(kthread) < 0)
1674 pr_debug("Failed to load list of modules in use, " 1639 pr_debug("Failed to load list of modules in use, "
1675 "continuing...\n"); 1640 "continuing...\n");
1676 /* 1641 /*
1677 * Now that we have all the maps created, just set the ->end of them: 1642 * Now that we have all the maps created, just set the ->end of them:
1678 */ 1643 */
1679 kernel_maps__fixup_end(); 1644 thread__fixup_maps_end(kthread);
1680 return 0; 1645 return 0;
1681} 1646}
1682
1683int symbol__init(struct symbol_conf *conf)
1684{
1685 elf_version(EV_CURRENT);
1686 return kernel_maps__init(conf);
1687}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 8934814d5a64..3f9e4a4d83dd 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -92,7 +92,7 @@ void dsos__fprintf(FILE *fp);
92size_t dsos__fprintf_buildid(FILE *fp); 92size_t dsos__fprintf_buildid(FILE *fp);
93 93
94size_t dso__fprintf_buildid(struct dso *self, FILE *fp); 94size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
95size_t dso__fprintf(struct dso *self, FILE *fp); 95size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
96char dso__symtab_origin(const struct dso *self); 96char dso__symtab_origin(const struct dso *self);
97void dso__set_build_id(struct dso *self, void *build_id); 97void dso__set_build_id(struct dso *self, void *build_id);
98 98
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 1796625f7784..2229f82cd630 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -9,17 +9,26 @@
9static struct rb_root threads; 9static struct rb_root threads;
10static struct thread *last_match; 10static struct thread *last_match;
11 11
12void thread__init(struct thread *self, pid_t pid)
13{
14 int i;
15 self->pid = pid;
16 self->comm = NULL;
17 for (i = 0; i < MAP__NR_TYPES; ++i) {
18 self->maps[i] = RB_ROOT;
19 INIT_LIST_HEAD(&self->removed_maps[i]);
20 }
21}
22
12static struct thread *thread__new(pid_t pid) 23static struct thread *thread__new(pid_t pid)
13{ 24{
14 struct thread *self = zalloc(sizeof(*self)); 25 struct thread *self = zalloc(sizeof(*self));
15 26
16 if (self != NULL) { 27 if (self != NULL) {
17 self->pid = pid; 28 thread__init(self, pid);
18 self->comm = malloc(32); 29 self->comm = malloc(32);
19 if (self->comm) 30 if (self->comm)
20 snprintf(self->comm, 32, ":%d", self->pid); 31 snprintf(self->comm, 32, ":%d", self->pid);
21 self->maps = RB_ROOT;
22 INIT_LIST_HEAD(&self->removed_maps);
23 } 32 }
24 33
25 return self; 34 return self;
@@ -44,24 +53,68 @@ int thread__comm_len(struct thread *self)
44 return self->comm_len; 53 return self->comm_len;
45} 54}
46 55
47static size_t thread__fprintf(struct thread *self, FILE *fp) 56static const char *map_type__name[MAP__NR_TYPES] = {
57 [MAP__FUNCTION] = "Functions",
58};
59
60static size_t __thread__fprintf_maps(struct thread *self,
61 enum map_type type, FILE *fp)
48{ 62{
63 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
49 struct rb_node *nd; 64 struct rb_node *nd;
50 struct map *pos;
51 size_t ret = fprintf(fp, "Thread %d %s\nCurrent maps:\n",
52 self->pid, self->comm);
53 65
54 for (nd = rb_first(&self->maps); nd; nd = rb_next(nd)) { 66 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
55 pos = rb_entry(nd, struct map, rb_node); 67 struct map *pos = rb_entry(nd, struct map, rb_node);
56 ret += map__fprintf(pos, fp); 68 printed += fprintf(fp, "Map:");
69 printed += map__fprintf(pos, fp);
70 if (verbose > 1) {
71 printed += dso__fprintf(pos->dso, type, fp);
72 printed += fprintf(fp, "--\n");
73 }
57 } 74 }
58 75
59 ret = fprintf(fp, "Removed maps:\n"); 76 return printed;
77}
78
79size_t thread__fprintf_maps(struct thread *self, FILE *fp)
80{
81 size_t printed = 0, i;
82 for (i = 0; i < MAP__NR_TYPES; ++i)
83 printed += __thread__fprintf_maps(self, i, fp);
84 return printed;
85}
60 86
61 list_for_each_entry(pos, &self->removed_maps, node) 87static size_t __thread__fprintf_removed_maps(struct thread *self,
62 ret += map__fprintf(pos, fp); 88 enum map_type type, FILE *fp)
89{
90 struct map *pos;
91 size_t printed = 0;
92
93 list_for_each_entry(pos, &self->removed_maps[type], node) {
94 printed += fprintf(fp, "Map:");
95 printed += map__fprintf(pos, fp);
96 if (verbose > 1) {
97 printed += dso__fprintf(pos->dso, type, fp);
98 printed += fprintf(fp, "--\n");
99 }
100 }
101 return printed;
102}
63 103
64 return ret; 104static size_t thread__fprintf_removed_maps(struct thread *self, FILE *fp)
105{
106 size_t printed = 0, i;
107 for (i = 0; i < MAP__NR_TYPES; ++i)
108 printed += __thread__fprintf_removed_maps(self, i, fp);
109 return printed;
110}
111
112static size_t thread__fprintf(struct thread *self, FILE *fp)
113{
114 size_t printed = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
115 printed += thread__fprintf_removed_maps(self, fp);
116 printed += fprintf(fp, "Removed maps:\n");
117 return printed + thread__fprintf_removed_maps(self, fp);
65} 118}
66 119
67struct thread *threads__findnew(pid_t pid) 120struct thread *threads__findnew(pid_t pid)
@@ -117,7 +170,8 @@ struct thread *register_idle_thread(void)
117 170
118static void thread__remove_overlappings(struct thread *self, struct map *map) 171static void thread__remove_overlappings(struct thread *self, struct map *map)
119{ 172{
120 struct rb_node *next = rb_first(&self->maps); 173 struct rb_root *root = &self->maps[map->type];
174 struct rb_node *next = rb_first(root);
121 175
122 while (next) { 176 while (next) {
123 struct map *pos = rb_entry(next, struct map, rb_node); 177 struct map *pos = rb_entry(next, struct map, rb_node);
@@ -132,13 +186,13 @@ static void thread__remove_overlappings(struct thread *self, struct map *map)
132 map__fprintf(pos, stderr); 186 map__fprintf(pos, stderr);
133 } 187 }
134 188
135 rb_erase(&pos->rb_node, &self->maps); 189 rb_erase(&pos->rb_node, root);
136 /* 190 /*
137 * We may have references to this map, for instance in some 191 * We may have references to this map, for instance in some
138 * hist_entry instances, so just move them to a separate 192 * hist_entry instances, so just move them to a separate
139 * list. 193 * list.
140 */ 194 */
141 list_add_tail(&pos->node, &self->removed_maps); 195 list_add_tail(&pos->node, &self->removed_maps[map->type]);
142 } 196 }
143} 197}
144 198
@@ -185,12 +239,26 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
185void thread__insert_map(struct thread *self, struct map *map) 239void thread__insert_map(struct thread *self, struct map *map)
186{ 240{
187 thread__remove_overlappings(self, map); 241 thread__remove_overlappings(self, map);
188 maps__insert(&self->maps, map); 242 maps__insert(&self->maps[map->type], map);
189} 243}
190 244
191int thread__fork(struct thread *self, struct thread *parent) 245static int thread__clone_maps(struct thread *self, struct thread *parent,
246 enum map_type type)
192{ 247{
193 struct rb_node *nd; 248 struct rb_node *nd;
249 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
250 struct map *map = rb_entry(nd, struct map, rb_node);
251 struct map *new = map__clone(map);
252 if (new == NULL)
253 return -ENOMEM;
254 thread__insert_map(self, new);
255 }
256 return 0;
257}
258
259int thread__fork(struct thread *self, struct thread *parent)
260{
261 int i;
194 262
195 if (self->comm) 263 if (self->comm)
196 free(self->comm); 264 free(self->comm);
@@ -198,14 +266,9 @@ int thread__fork(struct thread *self, struct thread *parent)
198 if (!self->comm) 266 if (!self->comm)
199 return -ENOMEM; 267 return -ENOMEM;
200 268
201 for (nd = rb_first(&parent->maps); nd; nd = rb_next(nd)) { 269 for (i = 0; i < MAP__NR_TYPES; ++i)
202 struct map *map = rb_entry(nd, struct map, rb_node); 270 if (thread__clone_maps(self, parent, i) < 0)
203 struct map *new = map__clone(map);
204 if (!new)
205 return -ENOMEM; 271 return -ENOMEM;
206 thread__insert_map(self, new);
207 }
208
209 return 0; 272 return 0;
210} 273}
211 274
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 54580bb80008..3bdd9b2276f0 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -7,20 +7,22 @@
7 7
8struct thread { 8struct thread {
9 struct rb_node rb_node; 9 struct rb_node rb_node;
10 struct rb_root maps; 10 struct rb_root maps[MAP__NR_TYPES];
11 struct list_head removed_maps; 11 struct list_head removed_maps[MAP__NR_TYPES];
12 pid_t pid; 12 pid_t pid;
13 char shortname[3]; 13 char shortname[3];
14 char *comm; 14 char *comm;
15 int comm_len; 15 int comm_len;
16}; 16};
17 17
18void thread__init(struct thread *self, pid_t pid);
18int thread__set_comm(struct thread *self, const char *comm); 19int thread__set_comm(struct thread *self, const char *comm);
19int thread__comm_len(struct thread *self); 20int thread__comm_len(struct thread *self);
20struct thread *threads__findnew(pid_t pid); 21struct thread *threads__findnew(pid_t pid);
21struct thread *register_idle_thread(void); 22struct thread *register_idle_thread(void);
22void thread__insert_map(struct thread *self, struct map *map); 23void thread__insert_map(struct thread *self, struct map *map);
23int thread__fork(struct thread *self, struct thread *parent); 24int thread__fork(struct thread *self, struct thread *parent);
25size_t thread__fprintf_maps(struct thread *self, FILE *fp);
24size_t threads__fprintf(FILE *fp); 26size_t threads__fprintf(FILE *fp);
25 27
26void maps__insert(struct rb_root *maps, struct map *map); 28void maps__insert(struct rb_root *maps, struct map *map);
@@ -29,9 +31,14 @@ struct map *maps__find(struct rb_root *maps, u64 ip);
29struct symbol *kernel_maps__find_function(const u64 ip, struct map **mapp, 31struct symbol *kernel_maps__find_function(const u64 ip, struct map **mapp,
30 symbol_filter_t filter); 32 symbol_filter_t filter);
31 33
32static inline struct map *thread__find_map(struct thread *self, u64 ip) 34static inline struct map *thread__find_map(struct thread *self,
35 enum map_type type, u64 ip)
33{ 36{
34 return self ? maps__find(&self->maps, ip) : NULL; 37 return self ? maps__find(&self->maps[type], ip) : NULL;
35} 38}
36 39
40static inline void __thread__insert_map(struct thread *self, struct map *map)
41{
42 maps__insert(&self->maps[map->type], map);
43}
37#endif /* __PERF_THREAD_H */ 44#endif /* __PERF_THREAD_H */