aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-01-16 04:39:49 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-01-16 14:29:44 -0500
commit99ca423387a3e718f9887a99475cb5271bc610f2 (patch)
tree1908d624f75406c10ec0d721cacd1dd20633cd3e /tools
parente53b00d382f4d8f55bcae301f49863c469fdff65 (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.c76
-rw-r--r--tools/perf/util/symbol-elf.c5
-rw-r--r--tools/perf/util/symbol.h5
-rw-r--r--tools/perf/util/unwind.c20
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 */
178static 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
195static 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;
218out:
219 elf_end(elf);
220 return ret;
221}
222#endif
223
224static int init_user_exec(void) 176static 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
296static 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;
319out:
320 elf_end(elf);
321 return ret;
322}
323
344static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, 324static 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
139static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 139Elf_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
56extern 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
33extern int 34extern 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
161static 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
178static u64 elf_section_offset(int fd, const char *name) 162static 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;