diff options
| -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; |
