perf symbols: Factor out buildid reading routine
authorArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 3 Nov 2009 23:46:10 +0000 (21:46 -0200)
committerIngo Molnar <mingo@elte.hu>
Wed, 4 Nov 2009 11:03:32 +0000 (12:03 +0100)
So that we can run it without having a DSO instance.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <1257291970-8208-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index ac94d7b94f6155da0455f8c82c927fc6497c72f5..e7c7cdb851c29fdaf99b021c38e33a16bc26c69d 100644 (file)
@@ -825,27 +825,27 @@ out_close:
        return err;
 }
 
-#define BUILD_ID_SIZE 128
+#define BUILD_ID_SIZE 20
 
-static char *dso__read_build_id(struct dso *self)
+int filename__read_build_id(const char *filename, void *bf, size_t size)
 {
-       int i;
+       int fd, err = -1;
        GElf_Ehdr ehdr;
        GElf_Shdr shdr;
        Elf_Data *build_id_data;
        Elf_Scn *sec;
-       char *build_id = NULL, *bid;
-       unsigned char *raw;
        Elf *elf;
-       int fd = open(self->long_name, O_RDONLY);
 
+       if (size < BUILD_ID_SIZE)
+               goto out;
+
+       fd = open(filename, O_RDONLY);
        if (fd < 0)
                goto out;
 
        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
        if (elf == NULL) {
-               pr_err("%s: cannot read %s ELF file.\n", __func__,
-                      self->long_name);
+               pr_err("%s: cannot read %s ELF file.\n", __func__, filename);
                goto out_close;
        }
 
@@ -854,29 +854,46 @@ static char *dso__read_build_id(struct dso *self)
                goto out_elf_end;
        }
 
-       sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL);
+       sec = elf_section_by_name(elf, &ehdr, &shdr,
+                                 ".note.gnu.build-id", NULL);
        if (sec == NULL)
                goto out_elf_end;
 
        build_id_data = elf_getdata(sec, NULL);
        if (build_id_data == NULL)
                goto out_elf_end;
-       build_id = malloc(BUILD_ID_SIZE);
+       memcpy(bf, build_id_data->d_buf + 16, BUILD_ID_SIZE);
+       err = BUILD_ID_SIZE;
+out_elf_end:
+       elf_end(elf);
+out_close:
+       close(fd);
+out:
+       return err;
+}
+
+static char *dso__read_build_id(struct dso *self)
+{
+       int i, len;
+       char *build_id = NULL, *bid;
+       unsigned char rawbf[BUILD_ID_SIZE], *raw;
+
+       len = filename__read_build_id(self->long_name, rawbf, sizeof(rawbf));
+       if (len < 0)
+               goto out;
+
+       build_id = malloc(len * 2 + 1);
        if (build_id == NULL)
-               goto out_elf_end;
-       raw = build_id_data->d_buf + 16;
+               goto out;
        bid = build_id;
 
-       for (i = 0; i < 20; ++i) {
+       raw = rawbf;
+       for (i = 0; i < len; ++i) {
                sprintf(bid, "%02x", *raw);
                ++raw;
                bid += 2;
        }
        pr_debug2("%s(%s): %s\n", __func__, self->long_name, build_id);
-out_elf_end:
-       elf_end(elf);
-out_close:
-       close(fd);
 out:
        return build_id;
 }
index 088433062dd4c1d46e20f40276ffe33ef17f4cd7..e0d4a583f8dd45974377f6c7a50380bf6acb348e 100644 (file)
@@ -82,6 +82,8 @@ void dsos__fprintf(FILE *fp);
 size_t dso__fprintf(struct dso *self, FILE *fp);
 char dso__symtab_origin(const struct dso *self);
 
+int filename__read_build_id(const char *filename, void *bf, size_t size);
+
 int load_kernel(symbol_filter_t filter);
 
 void symbol__init(unsigned int priv_size);