Merge remote-tracking branches 'asoc/fix/blackfin', 'asoc/fix/da9055', 'asoc/fix...
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / map.c
index ef5bc913ca7a9fdda7946401e55f9b0295dddfb6..39cd2d0faff65667b32738a8788817b6c670cedb 100644 (file)
@@ -11,6 +11,7 @@
 #include "strlist.h"
 #include "vdso.h"
 #include "build-id.h"
+#include "util.h"
 #include <linux/string.h>
 
 const char *map_type__name[MAP__NR_TYPES] = {
@@ -38,6 +39,7 @@ void map__init(struct map *map, enum map_type type,
        map->start    = start;
        map->end      = end;
        map->pgoff    = pgoff;
+       map->reloc    = 0;
        map->dso      = dso;
        map->map_ip   = map__map_ip;
        map->unmap_ip = map__unmap_ip;
@@ -68,7 +70,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                map->ino = ino;
                map->ino_generation = ino_gen;
 
-               if (anon) {
+               if ((anon || no_dso) && type == MAP__FUNCTION) {
                        snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
                        filename = newfilename;
                }
@@ -92,7 +94,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                         * functions still return NULL, and we avoid the
                         * unnecessary map__load warning.
                         */
-                       if (no_dso)
+                       if (type != MAP__FUNCTION)
                                dso__set_loaded(dso, map->type);
                }
        }
@@ -252,6 +254,22 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
        return fprintf(fp, "%s", dsoname);
 }
 
+int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
+                        FILE *fp)
+{
+       char *srcline;
+       int ret = 0;
+
+       if (map && map->dso) {
+               srcline = get_srcline(map->dso,
+                                     map__rip_2objdump(map, addr));
+               if (srcline != SRCLINE_UNKNOWN)
+                       ret = fprintf(fp, "%s%s", prefix, srcline);
+               free_srcline(srcline);
+       }
+       return ret;
+}
+
 /**
  * map__rip_2objdump - convert symbol start address to objdump address.
  * @map: memory map
@@ -271,7 +289,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
        if (map->dso->rel)
                return rip - map->pgoff;
 
-       return map->unmap_ip(map, rip);
+       return map->unmap_ip(map, rip) - map->reloc;
 }
 
 /**
@@ -294,7 +312,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
        if (map->dso->rel)
                return map->unmap_ip(map, ip + map->pgoff);
 
-       return ip;
+       return ip + map->reloc;
 }
 
 void map_groups__init(struct map_groups *mg)
@@ -369,7 +387,8 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg,
 {
        struct map *map = map_groups__find(mg, type, addr);
 
-       if (map != NULL) {
+       /* Ensure map is loaded before using map->map_ip */
+       if (map != NULL && map__load(map, filter) >= 0) {
                if (mapp != NULL)
                        *mapp = map;
                return map__find_symbol(map, map->map_ip(map, addr), filter);