Commit f1f13af9 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarNamhyung 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 459a3df7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ struct dso {
		u32		 status_seen;
		size_t		 file_size;
		struct list_head open_entry;
		u64		 frame_offset;
	} data;

	union { /* Tool specific area */
+20 −11
Original line number Diff line number Diff line
@@ -266,14 +266,17 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
				     u64 *fde_count)
{
	int ret = -EINVAL, fd;
	u64 offset;
	u64 offset = dso->data.frame_offset;

	if (offset == 0) {
		fd = dso__data_fd(dso, machine);
		if (fd < 0)
			return -EINVAL;

		/* Check the .eh_frame section for unwinding info */
		offset = elf_section_offset(fd, ".eh_frame_hdr");
		dso->data.frame_offset = offset;
	}

	if (offset)
		ret = unwind_spec_ehframe(dso, machine, offset,
@@ -287,14 +290,20 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
static int read_unwind_spec_debug_frame(struct dso *dso,
					struct machine *machine, u64 *offset)
{
	int fd = dso__data_fd(dso, machine);
	int fd;
	u64 ofs = dso->data.frame_offset;

	if (ofs == 0) {
		fd = dso__data_fd(dso, machine);
		if (fd < 0)
			return -EINVAL;

		/* Check the .debug_frame section for unwinding info */
	*offset = elf_section_offset(fd, ".debug_frame");
		ofs = elf_section_offset(fd, ".debug_frame");
		dso->data.frame_offset = ofs;
	}

	*offset = ofs;
	if (*offset)
		return 0;