diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-01-16 04:39:49 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-16 14:29:44 -0500 |
commit | 99ca423387a3e718f9887a99475cb5271bc610f2 (patch) | |
tree | 1908d624f75406c10ec0d721cacd1dd20633cd3e /tools | |
parent | e53b00d382f4d8f55bcae301f49863c469fdff65 (diff) |
perf symbols: Export elf_section_by_name and reuse
Remove duplicated elf_section_by_name() functions from unwind.c and
probe-event.c and use one exported elf_section_by_name() instance
defined in symbol-elf.c.
Note that this also moves get_text_start_address() to merge
HAVE_DWARF_SUPPORT defined area.
Reported-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: "David A. Long" <dave.long@linaro.org>
Cc: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: yrl.pp-manager.tt@hitachi.com
Link: http://lkml.kernel.org/r/20140116093949.24403.38093.stgit@kbuild-fedora.novalocal
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/probe-event.c | 76 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 5 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 5 | ||||
-rw-r--r-- | tools/perf/util/unwind.c | 20 |
4 files changed, 37 insertions, 69 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index c68711c50f47..a8a9b6cd93a8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -173,54 +173,6 @@ const char *kernel_get_module_path(const char *module) | |||
173 | return (dso) ? dso->long_name : NULL; | 173 | return (dso) ? dso->long_name : NULL; |
174 | } | 174 | } |
175 | 175 | ||
176 | #ifdef HAVE_DWARF_SUPPORT | ||
177 | /* Copied from unwind.c */ | ||
178 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
179 | GElf_Shdr *shp, const char *name) | ||
180 | { | ||
181 | Elf_Scn *sec = NULL; | ||
182 | |||
183 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
184 | char *str; | ||
185 | |||
186 | gelf_getshdr(sec, shp); | ||
187 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
188 | if (!strcmp(name, str)) | ||
189 | break; | ||
190 | } | ||
191 | |||
192 | return sec; | ||
193 | } | ||
194 | |||
195 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
196 | { | ||
197 | Elf *elf; | ||
198 | GElf_Ehdr ehdr; | ||
199 | GElf_Shdr shdr; | ||
200 | int fd, ret = -ENOENT; | ||
201 | |||
202 | fd = open(exec, O_RDONLY); | ||
203 | if (fd < 0) | ||
204 | return -errno; | ||
205 | |||
206 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
207 | if (elf == NULL) | ||
208 | return -EINVAL; | ||
209 | |||
210 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
211 | goto out; | ||
212 | |||
213 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text")) | ||
214 | goto out; | ||
215 | |||
216 | *address = shdr.sh_addr - shdr.sh_offset; | ||
217 | ret = 0; | ||
218 | out: | ||
219 | elf_end(elf); | ||
220 | return ret; | ||
221 | } | ||
222 | #endif | ||
223 | |||
224 | static int init_user_exec(void) | 176 | static int init_user_exec(void) |
225 | { | 177 | { |
226 | int ret = 0; | 178 | int ret = 0; |
@@ -341,6 +293,34 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | |||
341 | return 0; | 293 | return 0; |
342 | } | 294 | } |
343 | 295 | ||
296 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
297 | { | ||
298 | Elf *elf; | ||
299 | GElf_Ehdr ehdr; | ||
300 | GElf_Shdr shdr; | ||
301 | int fd, ret = -ENOENT; | ||
302 | |||
303 | fd = open(exec, O_RDONLY); | ||
304 | if (fd < 0) | ||
305 | return -errno; | ||
306 | |||
307 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
308 | if (elf == NULL) | ||
309 | return -EINVAL; | ||
310 | |||
311 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
312 | goto out; | ||
313 | |||
314 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL)) | ||
315 | goto out; | ||
316 | |||
317 | *address = shdr.sh_addr - shdr.sh_offset; | ||
318 | ret = 0; | ||
319 | out: | ||
320 | elf_end(elf); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
344 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | 324 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, |
345 | int ntevs, const char *exec) | 325 | int ntevs, const char *exec) |
346 | { | 326 | { |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 4b0a127a4d3b..759456728703 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -136,9 +136,8 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) | |||
136 | return -1; | 136 | return -1; |
137 | } | 137 | } |
138 | 138 | ||
139 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | 139 | Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, |
140 | GElf_Shdr *shp, const char *name, | 140 | GElf_Shdr *shp, const char *name, size_t *idx) |
141 | size_t *idx) | ||
142 | { | 141 | { |
143 | Elf_Scn *sec = NULL; | 142 | Elf_Scn *sec = NULL; |
144 | size_t cnt = 1; | 143 | size_t cnt = 1; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index cbd680361806..fffe2888a1c7 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -52,6 +52,11 @@ static inline char *bfd_demangle(void __maybe_unused *v, | |||
52 | # define PERF_ELF_C_READ_MMAP ELF_C_READ | 52 | # define PERF_ELF_C_READ_MMAP ELF_C_READ |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #ifdef HAVE_LIBELF_SUPPORT | ||
56 | extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
57 | GElf_Shdr *shp, const char *name, size_t *idx); | ||
58 | #endif | ||
59 | |||
55 | #ifndef DMGL_PARAMS | 60 | #ifndef DMGL_PARAMS |
56 | #define DMGL_PARAMS (1 << 0) /* Include function args */ | 61 | #define DMGL_PARAMS (1 << 0) /* Include function args */ |
57 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ | 62 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ |
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 416f22bf3693..742f23bf35ff 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "session.h" | 28 | #include "session.h" |
29 | #include "perf_regs.h" | 29 | #include "perf_regs.h" |
30 | #include "unwind.h" | 30 | #include "unwind.h" |
31 | #include "symbol.h" | ||
31 | #include "util.h" | 32 | #include "util.h" |
32 | 33 | ||
33 | extern int | 34 | extern int |
@@ -158,23 +159,6 @@ static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val, | |||
158 | __v; \ | 159 | __v; \ |
159 | }) | 160 | }) |
160 | 161 | ||
161 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
162 | GElf_Shdr *shp, const char *name) | ||
163 | { | ||
164 | Elf_Scn *sec = NULL; | ||
165 | |||
166 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
167 | char *str; | ||
168 | |||
169 | gelf_getshdr(sec, shp); | ||
170 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
171 | if (!strcmp(name, str)) | ||
172 | break; | ||
173 | } | ||
174 | |||
175 | return sec; | ||
176 | } | ||
177 | |||
178 | static u64 elf_section_offset(int fd, const char *name) | 162 | static u64 elf_section_offset(int fd, const char *name) |
179 | { | 163 | { |
180 | Elf *elf; | 164 | Elf *elf; |
@@ -190,7 +174,7 @@ static u64 elf_section_offset(int fd, const char *name) | |||
190 | if (gelf_getehdr(elf, &ehdr) == NULL) | 174 | if (gelf_getehdr(elf, &ehdr) == NULL) |
191 | break; | 175 | break; |
192 | 176 | ||
193 | if (!elf_section_by_name(elf, &ehdr, &shdr, name)) | 177 | if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL)) |
194 | break; | 178 | break; |
195 | 179 | ||
196 | offset = shdr.sh_offset; | 180 | offset = shdr.sh_offset; |