diff options
author | Namhyung Kim <namhyung@kernel.org> | 2015-01-29 03:07:21 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-01-29 14:20:42 -0500 |
commit | f1f13af99a903ae873f5373e965508e0486c1c29 (patch) | |
tree | 183674eba3f82637bc6270ac15960cf6e31fa9c2 /tools | |
parent | 459a3df76c99124fd222586be7f10f862547e7a9 (diff) |
perf callchain: Cache eh/debug frame offset for dwarf unwind
When libunwind tries to resolve callchains it needs to know the offset
of .eh_frame_hdr or .debug_frame to access the dso.
Since it will always return the same result for a given DSO, just cache
the result as an optimization.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1422518843-25818-41-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/dso.h | 1 | ||||
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 31 |
2 files changed, 21 insertions, 11 deletions
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 3782c82c6e44..ced92841ff97 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -139,6 +139,7 @@ struct dso { | |||
139 | u32 status_seen; | 139 | u32 status_seen; |
140 | size_t file_size; | 140 | size_t file_size; |
141 | struct list_head open_entry; | 141 | struct list_head open_entry; |
142 | u64 frame_offset; | ||
142 | } data; | 143 | } data; |
143 | 144 | ||
144 | union { /* Tool specific area */ | 145 | union { /* Tool specific area */ |
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 6edf535f65c2..e3c40a520a25 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -266,14 +266,17 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, | |||
266 | u64 *fde_count) | 266 | u64 *fde_count) |
267 | { | 267 | { |
268 | int ret = -EINVAL, fd; | 268 | int ret = -EINVAL, fd; |
269 | u64 offset; | 269 | u64 offset = dso->data.frame_offset; |
270 | 270 | ||
271 | fd = dso__data_fd(dso, machine); | 271 | if (offset == 0) { |
272 | if (fd < 0) | 272 | fd = dso__data_fd(dso, machine); |
273 | return -EINVAL; | 273 | if (fd < 0) |
274 | return -EINVAL; | ||
274 | 275 | ||
275 | /* Check the .eh_frame section for unwinding info */ | 276 | /* Check the .eh_frame section for unwinding info */ |
276 | offset = elf_section_offset(fd, ".eh_frame_hdr"); | 277 | offset = elf_section_offset(fd, ".eh_frame_hdr"); |
278 | dso->data.frame_offset = offset; | ||
279 | } | ||
277 | 280 | ||
278 | if (offset) | 281 | if (offset) |
279 | ret = unwind_spec_ehframe(dso, machine, offset, | 282 | ret = unwind_spec_ehframe(dso, machine, offset, |
@@ -287,14 +290,20 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, | |||
287 | static int read_unwind_spec_debug_frame(struct dso *dso, | 290 | static int read_unwind_spec_debug_frame(struct dso *dso, |
288 | struct machine *machine, u64 *offset) | 291 | struct machine *machine, u64 *offset) |
289 | { | 292 | { |
290 | int fd = dso__data_fd(dso, machine); | 293 | int fd; |
294 | u64 ofs = dso->data.frame_offset; | ||
291 | 295 | ||
292 | if (fd < 0) | 296 | if (ofs == 0) { |
293 | return -EINVAL; | 297 | fd = dso__data_fd(dso, machine); |
298 | if (fd < 0) | ||
299 | return -EINVAL; | ||
294 | 300 | ||
295 | /* Check the .debug_frame section for unwinding info */ | 301 | /* Check the .debug_frame section for unwinding info */ |
296 | *offset = elf_section_offset(fd, ".debug_frame"); | 302 | ofs = elf_section_offset(fd, ".debug_frame"); |
303 | dso->data.frame_offset = ofs; | ||
304 | } | ||
297 | 305 | ||
306 | *offset = ofs; | ||
298 | if (*offset) | 307 | if (*offset) |
299 | return 0; | 308 | return 0; |
300 | 309 | ||