Commit 1d5077bd authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf annotate: Another fix for annotate_browser__callq()

The target address is provided by objdump and is not necessary a memory
address.  Add a helper to get the correct address.
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1381747424-3557-8-git-send-email-adrian.hunter@intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent fc1b691d
...@@ -445,14 +445,17 @@ static bool annotate_browser__callq(struct annotate_browser *browser, ...@@ -445,14 +445,17 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
struct annotation *notes; struct annotation *notes;
struct addr_map_symbol target = { struct addr_map_symbol target = {
.map = ms->map, .map = ms->map,
.addr = dl->ops.target.addr, .addr = map__objdump_2mem(ms->map, dl->ops.target.addr),
}; };
char title[SYM_TITLE_MAX_SIZE]; char title[SYM_TITLE_MAX_SIZE];
if (!ins__is_call(dl->ins)) if (!ins__is_call(dl->ins))
return false; return false;
if (map_groups__find_ams(&target, NULL)) { if (map_groups__find_ams(&target, NULL) ||
map__rip_2objdump(target.map, target.map->map_ip(target.map,
target.addr)) !=
dl->ops.target.addr) {
ui_helpline__puts("The called function was not found."); ui_helpline__puts("The called function was not found.");
return true; return true;
} }
......
...@@ -252,10 +252,16 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp) ...@@ -252,10 +252,16 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
return fprintf(fp, "%s", dsoname); return fprintf(fp, "%s", dsoname);
} }
/* /**
* map__rip_2objdump - convert symbol start address to objdump address.
* @map: memory map
* @rip: symbol start address
*
* objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
* map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
* relative to section start. * relative to section start.
*
* Return: Address suitable for passing to "objdump --start-address="
*/ */
u64 map__rip_2objdump(struct map *map, u64 rip) u64 map__rip_2objdump(struct map *map, u64 rip)
{ {
...@@ -268,6 +274,29 @@ u64 map__rip_2objdump(struct map *map, u64 rip) ...@@ -268,6 +274,29 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
return map->unmap_ip(map, rip); return map->unmap_ip(map, rip);
} }
/**
* map__objdump_2mem - convert objdump address to a memory address.
* @map: memory map
* @ip: objdump address
*
* Closely related to map__rip_2objdump(), this function takes an address from
* objdump and converts it to a memory address. Note this assumes that @map
* contains the address. To be sure the result is valid, check it forwards
* e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
*
* Return: Memory address.
*/
u64 map__objdump_2mem(struct map *map, u64 ip)
{
if (!map->dso->adjust_symbols)
return map->unmap_ip(map, ip);
if (map->dso->rel)
return map->unmap_ip(map, ip + map->pgoff);
return ip;
}
void map_groups__init(struct map_groups *mg) void map_groups__init(struct map_groups *mg)
{ {
int i; int i;
......
...@@ -84,6 +84,9 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip) ...@@ -84,6 +84,9 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
u64 map__rip_2objdump(struct map *map, u64 rip); u64 map__rip_2objdump(struct map *map, u64 rip);
/* objdump address -> memory address */
u64 map__objdump_2mem(struct map *map, u64 ip);
struct symbol; struct symbol;
typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment