diff options
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go')
| -rw-r--r-- | src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go index 4750ec8129..03083baf12 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go @@ -178,8 +178,7 @@ func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint6 pageOffsetPpc64 = 0xc000000000000000 ) - if start == 0 && offset == 0 && - (limit == ^uint64(0) || limit == 0) { + if start == 0 && offset == 0 && (limit == ^uint64(0) || limit == 0) { // Some tools may introduce a fake mapping that spans the entire // address space. Assume that the address has already been // adjusted, so no additional base adjustment is necessary. @@ -189,9 +188,24 @@ func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint6 switch fh.Type { case elf.ET_EXEC: if loadSegment == nil { - // Fixed-address executable, no adjustment. + // Assume fixed-address executable and so no adjustment. return 0, nil } + if stextOffset == nil && start > 0 && start < 0x8000000000000000 { + // A regular user-mode executable. Compute the base offset using same + // arithmetics as in ET_DYN case below, see the explanation there. + // Ideally, the condition would just be "stextOffset == nil" as that + // represents the address of _stext symbol in the vmlinux image. Alas, + // the caller may skip reading it from the binary (it's expensive to scan + // all the symbols) and so it may be nil even for the kernel executable. + // So additionally check that the start is within the user-mode half of + // the 64-bit address space. + return start - offset + loadSegment.Off - loadSegment.Vaddr, nil + } + // Various kernel heuristics and cases follow. + if loadSegment.Vaddr == start-offset { + return offset, nil + } if start == 0 && limit != 0 { // ChromeOS remaps its kernel to 0. Nothing else should come // down this path. Empirical values: @@ -202,12 +216,6 @@ func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint6 } return -loadSegment.Vaddr, nil } - if loadSegment.Vaddr-loadSegment.Off == start-offset { - return offset, nil - } - if loadSegment.Vaddr == start-offset { - return offset, nil - } if start >= loadSegment.Vaddr && limit > start && (offset == 0 || offset == pageOffsetPpc64 || offset == start) { // Some kernels look like: // VADDR=0xffffffff80200000 @@ -230,7 +238,7 @@ func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint6 // start=0x198 limit=0x2f9fffff offset=0 // VADDR=0xffffffff81000000 // stextOffset=0xffffffff81000198 - return -(*stextOffset - start), nil + return start - *stextOffset, nil } return 0, fmt.Errorf("Don't know how to handle EXEC segment: %v start=0x%x limit=0x%x offset=0x%x", *loadSegment, start, limit, offset) |
