perf tools: Support 'srccode' output
[linux-block.git] / tools / perf / util / map.c
index a0d58b4d9c324b2f4b3e24e374cfb557b14bd8d8..6751301a755c96f745e44ab6fe76e5a8aa62f156 100644 (file)
@@ -19,6 +19,7 @@
 #include "srcline.h"
 #include "namespaces.h"
 #include "unwind.h"
+#include "srccode.h"
 
 static void __maps__insert(struct maps *maps, struct map *map);
 static void __maps__insert_name(struct maps *maps, struct map *map);
@@ -421,6 +422,54 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
        return ret;
 }
 
+int map__fprintf_srccode(struct map *map, u64 addr,
+                        FILE *fp,
+                        struct srccode_state *state)
+{
+       char *srcfile;
+       int ret = 0;
+       unsigned line;
+       int len;
+       char *srccode;
+
+       if (!map || !map->dso)
+               return 0;
+       srcfile = get_srcline_split(map->dso,
+                                   map__rip_2objdump(map, addr),
+                                   &line);
+       if (!srcfile)
+               return 0;
+
+       /* Avoid redundant printing */
+       if (state &&
+           state->srcfile &&
+           !strcmp(state->srcfile, srcfile) &&
+           state->line == line) {
+               free(srcfile);
+               return 0;
+       }
+
+       srccode = find_sourceline(srcfile, line, &len);
+       if (!srccode)
+               goto out_free_line;
+
+       ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);
+       state->srcfile = srcfile;
+       state->line = line;
+       return ret;
+
+out_free_line:
+       free(srcfile);
+       return ret;
+}
+
+
+void srccode_state_free(struct srccode_state *state)
+{
+       zfree(&state->srcfile);
+       state->line = 0;
+}
+
 /**
  * map__rip_2objdump - convert symbol start address to objdump address.
  * @map: memory map