Blame SOURCES/oprofile-offset.patch

0978ec
From a3742ff269a8d81cb116ec3dd22ef4516de06399 Mon Sep 17 00:00:00 2001
0978ec
From: William Cohen <wcohen@redhat.com>
0978ec
Date: Tue, 24 Sep 2019 09:59:12 -0400
0978ec
Subject: [PATCH] Use the mmap offset to correctly compute the IP location in a
0978ec
 file
0978ec
0978ec
Newer versions of binutils are now now splitting the file into
0978ec
multiple mmap loads.  The assumption that the mmap for the executable
0978ec
code in the file starts at the beginning of the file (that the file
0978ec
offset is always zero) is no longer true.  The computation to convert
0978ec
the IP address into an offset needs to also use the offset.
0978ec
---
0978ec
 libperf_events/operf_sfile.h   |  1 +
0978ec
 libperf_events/operf_utils.cpp | 10 +++++++---
0978ec
 2 files changed, 8 insertions(+), 3 deletions(-)
0978ec
0978ec
diff --git a/libperf_events/operf_sfile.h b/libperf_events/operf_sfile.h
0978ec
index bc003553..4d0576c6 100644
0978ec
--- a/libperf_events/operf_sfile.h
0978ec
+++ b/libperf_events/operf_sfile.h
0978ec
@@ -101,6 +101,7 @@ struct operf_transient {
0978ec
 	u32 tgid;
0978ec
 	vma_t start_addr;
0978ec
 	vma_t end_addr;
0978ec
+	u64 pgoff;
0978ec
 	bool cg;
0978ec
 	// TODO: handle extended
0978ec
 	//void * ext;
0978ec
diff --git a/libperf_events/operf_utils.cpp b/libperf_events/operf_utils.cpp
0978ec
index 70253495..1e9d1e98 100644
0978ec
--- a/libperf_events/operf_utils.cpp
0978ec
+++ b/libperf_events/operf_utils.cpp
0978ec
@@ -320,7 +320,8 @@ static void __handle_mmap_event(event_t * event)
0978ec
 			cout << "PERF_RECORD_MMAP for process " << hex << event->mmap.pid << "/"
0978ec
 			     << event->mmap.tid << ": " << event->mmap.filename << endl;
0978ec
 			cout << "\tstart_addr: " << hex << mapping->start_addr
0978ec
-			     << "; end addr: " << mapping->end_addr << endl;
0978ec
+			     << "; end addr: " << mapping->end_addr
0978ec
+			     << "; pgoff: " << mapping->pgoff << endl;
0978ec
 		}
0978ec
 
0978ec
 		if (event->header.misc & PERF_RECORD_MISC_USER)
0978ec
@@ -465,6 +466,7 @@ static struct operf_transient * __get_operf_trans(struct sample_data * data, boo
0978ec
 		trans.image_len = strlen(trans.image_name);
0978ec
 		trans.start_addr = op_mmap->start_addr;
0978ec
 		trans.end_addr = op_mmap->end_addr;
0978ec
+		trans.pgoff = op_mmap->pgoff;
0978ec
 		trans.tgid = data->pid;
0978ec
 		trans.tid = data->tid;
0978ec
 		trans.cur_procinfo = proc;
0978ec
@@ -474,7 +476,7 @@ static struct operf_transient * __get_operf_trans(struct sample_data * data, boo
0978ec
 		if (trans.in_kernel || trans.is_anon)
0978ec
 			trans.pc = data->ip;
0978ec
 		else
0978ec
-			trans.pc = data->ip - trans.start_addr;
0978ec
+			trans.pc = data->ip + trans.pgoff - trans.start_addr;
0978ec
 
0978ec
 		trans.sample_id = data->id;
0978ec
 		retval = &tran;;
0978ec
@@ -767,7 +769,7 @@ static int __handle_sample_event(event_t * event, u64 sample_type)
0978ec
 		if (trans.is_anon)
0978ec
 			trans.pc = data.ip;
0978ec
 		else
0978ec
-			trans.pc = data.ip - trans.start_addr;
0978ec
+			trans.pc = data.ip + trans.pgoff - trans.start_addr;
0978ec
 		found_trans = true;
0978ec
 	}
0978ec
 
0978ec
@@ -1062,6 +1064,7 @@ void OP_perf_utils::op_get_vsyscall_mapping(pid_t tgid, int output_fd, operf_rec
0978ec
 			size = align_64bit(size);
0978ec
 			mmap.start = start_addr;
0978ec
 			mmap.len = end_addr - mmap.start;
0978ec
+			mmap.pgoff = offset;
0978ec
 			mmap.pid = tgid;
0978ec
 			mmap.tid = tgid;
0978ec
 			mmap.header.size = (sizeof(mmap) -
0978ec
@@ -1133,6 +1136,7 @@ void OP_perf_utils::op_record_process_exec_mmaps(pid_t pid, pid_t tgid, int outp
0978ec
 			size = align_64bit(size);
0978ec
 			mmap.start = start_addr;
0978ec
 			mmap.len = end_addr - mmap.start;
0978ec
+			mmap.pgoff = offset;
0978ec
 			mmap.pid = tgid;
0978ec
 			mmap.tid = pid;
0978ec
 			mmap.header.size = (sizeof(mmap) -
0978ec
-- 
0978ec
2.21.0
0978ec