Browse Source

Handle PowerPC64 kernel mapping in getBase().

The kernel mapping record has the offset of 0xc000000000000000 on
PowerPC64 along with the same value for the mapping start.  Both values
come from arch/powerpc/Kconfig.  This case is not handled by any of the
conditions in the current getBase() code, so update the existing code
handling the kernel case to handle the PowerPC64 case.
Alexey Alexandrov 8 years ago
parent
commit
52d72a985e
2 changed files with 11 additions and 3 deletions
  1. 7
    3
      internal/elfexec/elfexec.go
  2. 4
    0
      internal/elfexec/elfexec_test.go

+ 7
- 3
internal/elfexec/elfexec.go View File

@@ -172,7 +172,11 @@ func GetBuildID(binary io.ReaderAt) ([]byte, error) {
172 172
 // use the address of the _stext symbol as the mmap start.  _stext
173 173
 // offset can be obtained with `nm vmlinux | grep _stext`
174 174
 func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, error) {
175
-	const pageSize = 4096
175
+	const (
176
+		pageSize = 4096
177
+		// PAGE_OFFSET for PowerPC64, see arch/powerpc/Kconfig in the kernel sources.
178
+		pageOffsetPpc64 = 0xc000000000000000
179
+	)
176 180
 
177 181
 	if start == 0 && offset == 0 &&
178 182
 		(limit == ^uint64(0) || limit == 0) {
@@ -204,13 +208,13 @@ func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint6
204 208
 		if loadSegment.Vaddr == start-offset {
205 209
 			return offset, nil
206 210
 		}
207
-		if start > loadSegment.Vaddr && limit > start && offset == 0 {
211
+		if start >= loadSegment.Vaddr && limit > start && (offset == 0 || offset == pageOffsetPpc64) {
208 212
 			// Some kernels look like:
209 213
 			//       VADDR=0xffffffff80200000
210 214
 			// stextOffset=0xffffffff80200198
211 215
 			//       Start=0xffffffff83200000
212 216
 			//       Limit=0xffffffff84200000
213
-			//      Offset=0
217
+			//      Offset=0 (0xc000000000000000 for PowerPC64)
214 218
 			// So the base should be:
215 219
 			if stextOffset != nil && (start%pageSize) == (*stextOffset%pageSize) {
216 220
 				// perf uses the address of _stext as start.  Some tools may

+ 4
- 0
internal/elfexec/elfexec_test.go View File

@@ -37,6 +37,9 @@ func TestGetBase(t *testing.T) {
37 37
 	kernelHeader := &elf.ProgHeader{
38 38
 		Vaddr: 0xffffffff81000000,
39 39
 	}
40
+	ppc64KernelHeader := &elf.ProgHeader{
41
+		Vaddr: 0xc000000000000000,
42
+	}
40 43
 
41 44
 	testcases := []struct {
42 45
 		label                string
@@ -52,6 +55,7 @@ func TestGetBase(t *testing.T) {
52 55
 		{"exec offset 2", fhExec, lsOffset, nil, 0x200000, 0x600000, 0, 0, false},
53 56
 		{"exec nomap", fhExec, nil, nil, 0, 0, 0, 0, false},
54 57
 		{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0xffffffff82000198, 0xffffffff83000198, 0, 0x1000000, false},
58
+		{"exec PPC64 kernel", fhExec, ppc64KernelHeader, uint64p(0xc000000000000000), 0xc000000000000000, 0xd00000001a730000, 0xc000000000000000, 0x0, false},
55 59
 		{"exec chromeos kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10197, 0, 0x7efffe68, false},
56 60
 		{"exec chromeos kernel 2", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10198, 0, 0x7efffe68, false},
57 61
 		{"exec chromeos kernel 3", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0x198, 0x100000, 0, 0x7f000000, false},