perf annotate: Split out read_symbol()
authorSteinar H. Gunderson <sesse@google.com>
Sat, 3 Aug 2024 15:20:07 +0000 (17:20 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 3 Sep 2024 13:15:55 +0000 (10:15 -0300)
The Capstone disassembler code has a useful code snippet to read the
bytes for a given code symbol into memory. Split it out into its own
function, so that the LLVM disassembler can use it in the next patch.

Signed-off-by: Steinar H. Gunderson <sesse@google.com>
Cc: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20240803152008.2818485-2-sesse@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/disasm.c

index d11e75133b239ba3b395e34890c819008d0a03fe..5e9be3487c6ceb3ca53354fae70da7153cec90c5 100644 (file)
@@ -1372,6 +1372,53 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg)
        return 0;
 }
 
+static u8 *
+read_symbol(const char *filename, struct map *map, struct symbol *sym,
+           u64 *len, bool *is_64bit)
+{
+       struct dso *dso = map__dso(map);
+       struct nscookie nsc;
+       u64 start = map__rip_2objdump(map, sym->start);
+       u64 end = map__rip_2objdump(map, sym->end);
+       int fd, count;
+       u8 *buf = NULL;
+       struct find_file_offset_data data = {
+               .ip = start,
+       };
+
+       *is_64bit = false;
+
+       nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
+       fd = open(filename, O_RDONLY);
+       nsinfo__mountns_exit(&nsc);
+       if (fd < 0)
+               return NULL;
+
+       if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data,
+                           is_64bit) == 0)
+               goto err;
+
+       *len = end - start;
+       buf = malloc(*len);
+       if (buf == NULL)
+               goto err;
+
+       count = pread(fd, buf, *len, data.offset);
+       close(fd);
+       fd = -1;
+
+       if ((u64)count != *len)
+               goto err;
+
+       return buf;
+
+err:
+       if (fd >= 0)
+               close(fd);
+       free(buf);
+       return NULL;
+}
+
 static void print_capstone_detail(cs_insn *insn, char *buf, size_t len,
                                  struct annotate_args *args, u64 addr)
 {
@@ -1572,19 +1619,13 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
 {
        struct annotation *notes = symbol__annotation(sym);
        struct map *map = args->ms.map;
-       struct dso *dso = map__dso(map);
-       struct nscookie nsc;
        u64 start = map__rip_2objdump(map, sym->start);
-       u64 end = map__rip_2objdump(map, sym->end);
-       u64 len = end - start;
+       u64 len;
        u64 offset;
-       int i, fd, count;
+       int i, count;
        bool is_64bit = false;
        bool needs_cs_close = false;
        u8 *buf = NULL;
-       struct find_file_offset_data data = {
-               .ip = start,
-       };
        csh handle;
        cs_insn *insn;
        char disasm_buf[512];
@@ -1593,31 +1634,9 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
        if (args->options->objdump_path)
                return -1;
 
-       nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
-       fd = open(filename, O_RDONLY);
-       nsinfo__mountns_exit(&nsc);
-       if (fd < 0)
-               return -1;
-
-       if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data,
-                           &is_64bit) == 0)
-               goto err;
-
-       if (open_capstone_handle(args, is_64bit, &handle) < 0)
-               goto err;
-
-       needs_cs_close = true;
-
-       buf = malloc(len);
+       buf = read_symbol(filename, map, sym, &len, &is_64bit);
        if (buf == NULL)
-               goto err;
-
-       count = pread(fd, buf, len, data.offset);
-       close(fd);
-       fd = -1;
-
-       if ((u64)count != len)
-               goto err;
+               return -1;
 
        /* add the function address and name */
        scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:",
@@ -1635,6 +1654,11 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
 
        annotation_line__add(&dl->al, &notes->src->source);
 
+       if (open_capstone_handle(args, is_64bit, &handle) < 0)
+               goto err;
+
+       needs_cs_close = true;
+
        count = cs_disasm(handle, buf, len, start, len, &insn);
        for (i = 0, offset = 0; i < count; i++) {
                int printed;
@@ -1679,8 +1703,6 @@ out:
        return count < 0 ? count : 0;
 
 err:
-       if (fd >= 0)
-               close(fd);
        if (needs_cs_close) {
                struct disasm_line *tmp;