diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-03 18:46:10 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-04 06:03:32 -0500 |
commit | 2643ce11457a99a85c5bed8dd631e35968e6ca5a (patch) | |
tree | f145996b7ba4db29d34a88a755ab6524266f708e /tools/perf/util | |
parent | a2e71271535fde493c32803b1f34789f97efcb5e (diff) |
perf symbols: Factor out buildid reading routine
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>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/symbol.c | 51 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
2 files changed, 36 insertions, 17 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index ac94d7b94f61..e7c7cdb851c2 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -825,27 +825,27 @@ out_close: | |||
825 | return err; | 825 | return err; |
826 | } | 826 | } |
827 | 827 | ||
828 | #define BUILD_ID_SIZE 128 | 828 | #define BUILD_ID_SIZE 20 |
829 | 829 | ||
830 | static char *dso__read_build_id(struct dso *self) | 830 | int filename__read_build_id(const char *filename, void *bf, size_t size) |
831 | { | 831 | { |
832 | int i; | 832 | int fd, err = -1; |
833 | GElf_Ehdr ehdr; | 833 | GElf_Ehdr ehdr; |
834 | GElf_Shdr shdr; | 834 | GElf_Shdr shdr; |
835 | Elf_Data *build_id_data; | 835 | Elf_Data *build_id_data; |
836 | Elf_Scn *sec; | 836 | Elf_Scn *sec; |
837 | char *build_id = NULL, *bid; | ||
838 | unsigned char *raw; | ||
839 | Elf *elf; | 837 | Elf *elf; |
840 | int fd = open(self->long_name, O_RDONLY); | ||
841 | 838 | ||
839 | if (size < BUILD_ID_SIZE) | ||
840 | goto out; | ||
841 | |||
842 | fd = open(filename, O_RDONLY); | ||
842 | if (fd < 0) | 843 | if (fd < 0) |
843 | goto out; | 844 | goto out; |
844 | 845 | ||
845 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | 846 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); |
846 | if (elf == NULL) { | 847 | if (elf == NULL) { |
847 | pr_err("%s: cannot read %s ELF file.\n", __func__, | 848 | pr_err("%s: cannot read %s ELF file.\n", __func__, filename); |
848 | self->long_name); | ||
849 | goto out_close; | 849 | goto out_close; |
850 | } | 850 | } |
851 | 851 | ||
@@ -854,29 +854,46 @@ static char *dso__read_build_id(struct dso *self) | |||
854 | goto out_elf_end; | 854 | goto out_elf_end; |
855 | } | 855 | } |
856 | 856 | ||
857 | sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL); | 857 | sec = elf_section_by_name(elf, &ehdr, &shdr, |
858 | ".note.gnu.build-id", NULL); | ||
858 | if (sec == NULL) | 859 | if (sec == NULL) |
859 | goto out_elf_end; | 860 | goto out_elf_end; |
860 | 861 | ||
861 | build_id_data = elf_getdata(sec, NULL); | 862 | build_id_data = elf_getdata(sec, NULL); |
862 | if (build_id_data == NULL) | 863 | if (build_id_data == NULL) |
863 | goto out_elf_end; | 864 | goto out_elf_end; |
864 | build_id = malloc(BUILD_ID_SIZE); | 865 | memcpy(bf, build_id_data->d_buf + 16, BUILD_ID_SIZE); |
866 | err = BUILD_ID_SIZE; | ||
867 | out_elf_end: | ||
868 | elf_end(elf); | ||
869 | out_close: | ||
870 | close(fd); | ||
871 | out: | ||
872 | return err; | ||
873 | } | ||
874 | |||
875 | static char *dso__read_build_id(struct dso *self) | ||
876 | { | ||
877 | int i, len; | ||
878 | char *build_id = NULL, *bid; | ||
879 | unsigned char rawbf[BUILD_ID_SIZE], *raw; | ||
880 | |||
881 | len = filename__read_build_id(self->long_name, rawbf, sizeof(rawbf)); | ||
882 | if (len < 0) | ||
883 | goto out; | ||
884 | |||
885 | build_id = malloc(len * 2 + 1); | ||
865 | if (build_id == NULL) | 886 | if (build_id == NULL) |
866 | goto out_elf_end; | 887 | goto out; |
867 | raw = build_id_data->d_buf + 16; | ||
868 | bid = build_id; | 888 | bid = build_id; |
869 | 889 | ||
870 | for (i = 0; i < 20; ++i) { | 890 | raw = rawbf; |
891 | for (i = 0; i < len; ++i) { | ||
871 | sprintf(bid, "%02x", *raw); | 892 | sprintf(bid, "%02x", *raw); |
872 | ++raw; | 893 | ++raw; |
873 | bid += 2; | 894 | bid += 2; |
874 | } | 895 | } |
875 | pr_debug2("%s(%s): %s\n", __func__, self->long_name, build_id); | 896 | pr_debug2("%s(%s): %s\n", __func__, self->long_name, build_id); |
876 | out_elf_end: | ||
877 | elf_end(elf); | ||
878 | out_close: | ||
879 | close(fd); | ||
880 | out: | 897 | out: |
881 | return build_id; | 898 | return build_id; |
882 | } | 899 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 088433062dd4..e0d4a583f8dd 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -82,6 +82,8 @@ void dsos__fprintf(FILE *fp); | |||
82 | size_t dso__fprintf(struct dso *self, FILE *fp); | 82 | size_t dso__fprintf(struct dso *self, FILE *fp); |
83 | char dso__symtab_origin(const struct dso *self); | 83 | char dso__symtab_origin(const struct dso *self); |
84 | 84 | ||
85 | int filename__read_build_id(const char *filename, void *bf, size_t size); | ||
86 | |||
85 | int load_kernel(symbol_filter_t filter); | 87 | int load_kernel(symbol_filter_t filter); |
86 | 88 | ||
87 | void symbol__init(unsigned int priv_size); | 89 | void symbol__init(unsigned int priv_size); |