diff options
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r-- | tools/perf/util/map.c | 67 |
1 files changed, 27 insertions, 40 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 8bcdf9e54089..9e8304ca343e 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -182,12 +182,6 @@ int map__load(struct map *map, symbol_filter_t filter) | |||
182 | #endif | 182 | #endif |
183 | return -1; | 183 | return -1; |
184 | } | 184 | } |
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 | 185 | ||
192 | return 0; | 186 | return 0; |
193 | } | 187 | } |
@@ -254,14 +248,18 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp) | |||
254 | 248 | ||
255 | /* | 249 | /* |
256 | * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. | 250 | * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. |
257 | * map->dso->adjust_symbols==1 for ET_EXEC-like cases. | 251 | * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is |
252 | * relative to section start. | ||
258 | */ | 253 | */ |
259 | u64 map__rip_2objdump(struct map *map, u64 rip) | 254 | u64 map__rip_2objdump(struct map *map, u64 rip) |
260 | { | 255 | { |
261 | u64 addr = map->dso->adjust_symbols ? | 256 | if (!map->dso->adjust_symbols) |
262 | map->unmap_ip(map, rip) : /* RIP -> IP */ | 257 | return rip; |
263 | rip; | 258 | |
264 | return addr; | 259 | if (map->dso->rel) |
260 | return rip - map->pgoff; | ||
261 | |||
262 | return map->unmap_ip(map, rip); | ||
265 | } | 263 | } |
266 | 264 | ||
267 | void map_groups__init(struct map_groups *mg) | 265 | void map_groups__init(struct map_groups *mg) |
@@ -513,35 +511,6 @@ int map_groups__clone(struct map_groups *mg, | |||
513 | return 0; | 511 | return 0; |
514 | } | 512 | } |
515 | 513 | ||
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) | 514 | void maps__insert(struct rb_root *maps, struct map *map) |
546 | { | 515 | { |
547 | struct rb_node **p = &maps->rb_node; | 516 | struct rb_node **p = &maps->rb_node; |
@@ -586,3 +555,21 @@ struct map *maps__find(struct rb_root *maps, u64 ip) | |||
586 | 555 | ||
587 | return NULL; | 556 | return NULL; |
588 | } | 557 | } |
558 | |||
559 | struct map *maps__first(struct rb_root *maps) | ||
560 | { | ||
561 | struct rb_node *first = rb_first(maps); | ||
562 | |||
563 | if (first) | ||
564 | return rb_entry(first, struct map, rb_node); | ||
565 | return NULL; | ||
566 | } | ||
567 | |||
568 | struct map *maps__next(struct map *map) | ||
569 | { | ||
570 | struct rb_node *next = rb_next(&map->rb_node); | ||
571 | |||
572 | if (next) | ||
573 | return rb_entry(next, struct map, rb_node); | ||
574 | return NULL; | ||
575 | } | ||