forked from Minki/linux
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>
This commit is contained in:
parent
e53b00d382
commit
99ca423387
@ -173,54 +173,6 @@ const char *kernel_get_module_path(const char *module)
|
||||
return (dso) ? dso->long_name : NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
/* Copied from unwind.c */
|
||||
static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||
GElf_Shdr *shp, const char *name)
|
||||
{
|
||||
Elf_Scn *sec = NULL;
|
||||
|
||||
while ((sec = elf_nextscn(elf, sec)) != NULL) {
|
||||
char *str;
|
||||
|
||||
gelf_getshdr(sec, shp);
|
||||
str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
|
||||
if (!strcmp(name, str))
|
||||
break;
|
||||
}
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
static int get_text_start_address(const char *exec, unsigned long *address)
|
||||
{
|
||||
Elf *elf;
|
||||
GElf_Ehdr ehdr;
|
||||
GElf_Shdr shdr;
|
||||
int fd, ret = -ENOENT;
|
||||
|
||||
fd = open(exec, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
|
||||
if (elf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (gelf_getehdr(elf, &ehdr) == NULL)
|
||||
goto out;
|
||||
|
||||
if (!elf_section_by_name(elf, &ehdr, &shdr, ".text"))
|
||||
goto out;
|
||||
|
||||
*address = shdr.sh_addr - shdr.sh_offset;
|
||||
ret = 0;
|
||||
out:
|
||||
elf_end(elf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int init_user_exec(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -341,6 +293,34 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_text_start_address(const char *exec, unsigned long *address)
|
||||
{
|
||||
Elf *elf;
|
||||
GElf_Ehdr ehdr;
|
||||
GElf_Shdr shdr;
|
||||
int fd, ret = -ENOENT;
|
||||
|
||||
fd = open(exec, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
|
||||
if (elf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (gelf_getehdr(elf, &ehdr) == NULL)
|
||||
goto out;
|
||||
|
||||
if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL))
|
||||
goto out;
|
||||
|
||||
*address = shdr.sh_addr - shdr.sh_offset;
|
||||
ret = 0;
|
||||
out:
|
||||
elf_end(elf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
|
||||
int ntevs, const char *exec)
|
||||
{
|
||||
|
@ -136,9 +136,8 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||
GElf_Shdr *shp, const char *name,
|
||||
size_t *idx)
|
||||
Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||
GElf_Shdr *shp, const char *name, size_t *idx)
|
||||
{
|
||||
Elf_Scn *sec = NULL;
|
||||
size_t cnt = 1;
|
||||
|
@ -52,6 +52,11 @@ static inline char *bfd_demangle(void __maybe_unused *v,
|
||||
# define PERF_ELF_C_READ_MMAP ELF_C_READ
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||
GElf_Shdr *shp, const char *name, size_t *idx);
|
||||
#endif
|
||||
|
||||
#ifndef DMGL_PARAMS
|
||||
#define DMGL_PARAMS (1 << 0) /* Include function args */
|
||||
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "session.h"
|
||||
#include "perf_regs.h"
|
||||
#include "unwind.h"
|
||||
#include "symbol.h"
|
||||
#include "util.h"
|
||||
|
||||
extern int
|
||||
@ -158,23 +159,6 @@ static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
|
||||
__v; \
|
||||
})
|
||||
|
||||
static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
|
||||
GElf_Shdr *shp, const char *name)
|
||||
{
|
||||
Elf_Scn *sec = NULL;
|
||||
|
||||
while ((sec = elf_nextscn(elf, sec)) != NULL) {
|
||||
char *str;
|
||||
|
||||
gelf_getshdr(sec, shp);
|
||||
str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
|
||||
if (!strcmp(name, str))
|
||||
break;
|
||||
}
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
static u64 elf_section_offset(int fd, const char *name)
|
||||
{
|
||||
Elf *elf;
|
||||
@ -190,7 +174,7 @@ static u64 elf_section_offset(int fd, const char *name)
|
||||
if (gelf_getehdr(elf, &ehdr) == NULL)
|
||||
break;
|
||||
|
||||
if (!elf_section_by_name(elf, &ehdr, &shdr, name))
|
||||
if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
|
||||
break;
|
||||
|
||||
offset = shdr.sh_offset;
|
||||
|
Loading…
Reference in New Issue
Block a user