diff options
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r-- | tools/perf/util/map.c | 75 |
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 | ||
50 | struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, | 50 | struct 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 | */ |
259 | u64 map__rip_2objdump(struct map *map, u64 rip) | 260 | u64 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 | ||
267 | void map_groups__init(struct map_groups *mg) | 271 | void 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 | ||
516 | static u64 map__reloc_map_ip(struct map *map, u64 ip) | ||
517 | { | ||
518 | return ip + (s64)map->pgoff; | ||
519 | } | ||
520 | |||
521 | static u64 map__reloc_unmap_ip(struct map *map, u64 ip) | ||
522 | { | ||
523 | return ip - (s64)map->pgoff; | ||
524 | } | ||
525 | |||
526 | void 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 | |||
545 | void maps__insert(struct rb_root *maps, struct map *map) | 520 | void 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 | |||
565 | struct 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 | |||
574 | struct 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 | } | ||