aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c75
1 files changed, 34 insertions, 41 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 8bcdf9e54089..4f6680d2043b 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -48,7 +48,8 @@ void map__init(struct map *map, enum map_type type,
48} 48}
49 49
50struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, 50struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
51 u64 pgoff, u32 pid, char *filename, 51 u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
52 u64 ino_gen, char *filename,
52 enum map_type type) 53 enum map_type type)
53{ 54{
54 struct map *map = malloc(sizeof(*map)); 55 struct map *map = malloc(sizeof(*map));
@@ -62,6 +63,11 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
62 vdso = is_vdso_map(filename); 63 vdso = is_vdso_map(filename);
63 no_dso = is_no_dso_memory(filename); 64 no_dso = is_no_dso_memory(filename);
64 65
66 map->maj = d_maj;
67 map->min = d_min;
68 map->ino = ino;
69 map->ino_generation = ino_gen;
70
65 if (anon) { 71 if (anon) {
66 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); 72 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
67 filename = newfilename; 73 filename = newfilename;
@@ -182,12 +188,6 @@ int map__load(struct map *map, symbol_filter_t filter)
182#endif 188#endif
183 return -1; 189 return -1;
184 } 190 }
185 /*
186 * Only applies to the kernel, as its symtabs aren't relative like the
187 * module ones.
188 */
189 if (map->dso->kernel)
190 map__reloc_vmlinux(map);
191 191
192 return 0; 192 return 0;
193} 193}
@@ -254,14 +254,18 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
254 254
255/* 255/*
256 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. 256 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
257 * map->dso->adjust_symbols==1 for ET_EXEC-like cases. 257 * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
258 * relative to section start.
258 */ 259 */
259u64 map__rip_2objdump(struct map *map, u64 rip) 260u64 map__rip_2objdump(struct map *map, u64 rip)
260{ 261{
261 u64 addr = map->dso->adjust_symbols ? 262 if (!map->dso->adjust_symbols)
262 map->unmap_ip(map, rip) : /* RIP -> IP */ 263 return rip;
263 rip; 264
264 return addr; 265 if (map->dso->rel)
266 return rip - map->pgoff;
267
268 return map->unmap_ip(map, rip);
265} 269}
266 270
267void map_groups__init(struct map_groups *mg) 271void map_groups__init(struct map_groups *mg)
@@ -513,35 +517,6 @@ int map_groups__clone(struct map_groups *mg,
513 return 0; 517 return 0;
514} 518}
515 519
516static u64 map__reloc_map_ip(struct map *map, u64 ip)
517{
518 return ip + (s64)map->pgoff;
519}
520
521static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
522{
523 return ip - (s64)map->pgoff;
524}
525
526void map__reloc_vmlinux(struct map *map)
527{
528 struct kmap *kmap = map__kmap(map);
529 s64 reloc;
530
531 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
532 return;
533
534 reloc = (kmap->ref_reloc_sym->unrelocated_addr -
535 kmap->ref_reloc_sym->addr);
536
537 if (!reloc)
538 return;
539
540 map->map_ip = map__reloc_map_ip;
541 map->unmap_ip = map__reloc_unmap_ip;
542 map->pgoff = reloc;
543}
544
545void maps__insert(struct rb_root *maps, struct map *map) 520void maps__insert(struct rb_root *maps, struct map *map)
546{ 521{
547 struct rb_node **p = &maps->rb_node; 522 struct rb_node **p = &maps->rb_node;
@@ -586,3 +561,21 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
586 561
587 return NULL; 562 return NULL;
588} 563}
564
565struct map *maps__first(struct rb_root *maps)
566{
567 struct rb_node *first = rb_first(maps);
568
569 if (first)
570 return rb_entry(first, struct map, rb_node);
571 return NULL;
572}
573
574struct map *maps__next(struct map *map)
575{
576 struct rb_node *next = rb_next(&map->rb_node);
577
578 if (next)
579 return rb_entry(next, struct map, rb_node);
580 return NULL;
581}