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
 // use the address of the _stext symbol as the mmap start.  _stext
172
 // use the address of the _stext symbol as the mmap start.  _stext
173
 // offset can be obtained with `nm vmlinux | grep _stext`
173
 // offset can be obtained with `nm vmlinux | grep _stext`
174
 func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, error) {
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
 	if start == 0 && offset == 0 &&
181
 	if start == 0 && offset == 0 &&
178
 		(limit == ^uint64(0) || limit == 0) {
182
 		(limit == ^uint64(0) || limit == 0) {
204
 		if loadSegment.Vaddr == start-offset {
208
 		if loadSegment.Vaddr == start-offset {
205
 			return offset, nil
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
 			// Some kernels look like:
212
 			// Some kernels look like:
209
 			//       VADDR=0xffffffff80200000
213
 			//       VADDR=0xffffffff80200000
210
 			// stextOffset=0xffffffff80200198
214
 			// stextOffset=0xffffffff80200198
211
 			//       Start=0xffffffff83200000
215
 			//       Start=0xffffffff83200000
212
 			//       Limit=0xffffffff84200000
216
 			//       Limit=0xffffffff84200000
213
-			//      Offset=0
217
+			//      Offset=0 (0xc000000000000000 for PowerPC64)
214
 			// So the base should be:
218
 			// So the base should be:
215
 			if stextOffset != nil && (start%pageSize) == (*stextOffset%pageSize) {
219
 			if stextOffset != nil && (start%pageSize) == (*stextOffset%pageSize) {
216
 				// perf uses the address of _stext as start.  Some tools may
220
 				// perf uses the address of _stext as start.  Some tools may

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

37
 	kernelHeader := &elf.ProgHeader{
37
 	kernelHeader := &elf.ProgHeader{
38
 		Vaddr: 0xffffffff81000000,
38
 		Vaddr: 0xffffffff81000000,
39
 	}
39
 	}
40
+	ppc64KernelHeader := &elf.ProgHeader{
41
+		Vaddr: 0xc000000000000000,
42
+	}
40
 
43
 
41
 	testcases := []struct {
44
 	testcases := []struct {
42
 		label                string
45
 		label                string
52
 		{"exec offset 2", fhExec, lsOffset, nil, 0x200000, 0x600000, 0, 0, false},
55
 		{"exec offset 2", fhExec, lsOffset, nil, 0x200000, 0x600000, 0, 0, false},
53
 		{"exec nomap", fhExec, nil, nil, 0, 0, 0, 0, false},
56
 		{"exec nomap", fhExec, nil, nil, 0, 0, 0, 0, false},
54
 		{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0xffffffff82000198, 0xffffffff83000198, 0, 0x1000000, false},
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
 		{"exec chromeos kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10197, 0, 0x7efffe68, false},
59
 		{"exec chromeos kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10197, 0, 0x7efffe68, false},
56
 		{"exec chromeos kernel 2", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10198, 0, 0x7efffe68, false},
60
 		{"exec chromeos kernel 2", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10198, 0, 0x7efffe68, false},
57
 		{"exec chromeos kernel 3", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0x198, 0x100000, 0, 0x7f000000, false},
61
 		{"exec chromeos kernel 3", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0x198, 0x100000, 0, 0x7f000000, false},