aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/github.com/google/pprof/internal/elfexec
diff options
context:
space:
mode:
authorHana (Hyang-Ah) Kim <hyangah@gmail.com>2018-11-06 17:48:08 -0500
committerHyang-Ah Hana Kim <hyangah@gmail.com>2018-11-07 12:27:21 +0000
commitc0a40e4fe5d4649672d0d430ca26551841fc4852 (patch)
tree4ccd82b68f0795d68bc43caff3cba7c9fabdb4d8 /src/cmd/vendor/github.com/google/pprof/internal/elfexec
parent1100df58238a1b1c55af148a880b48caf4be6504 (diff)
downloadgo-c0a40e4fe5d4649672d0d430ca26551841fc4852.tar.xz
cmd/vendor: update github.com/google/pprof
Sync @ fde099a (Oct 26, 2018) Also update misc/nacl/testzip.proto to include new testdata. Change-Id: If41590be9f395a591056e89a417b589c4ba71b1a Reviewed-on: https://go-review.googlesource.com/c/147979 Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal/elfexec')
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go28
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go11
2 files changed, 27 insertions, 12 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)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
index 71edd8e51b..ff95c36add 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
@@ -37,6 +37,10 @@ func TestGetBase(t *testing.T) {
kernelHeader := &elf.ProgHeader{
Vaddr: 0xffffffff81000000,
}
+ kernelAslrHeader := &elf.ProgHeader{
+ Vaddr: 0xffffffff80200000,
+ Off: 0x1000,
+ }
ppc64KernelHeader := &elf.ProgHeader{
Vaddr: 0xc000000000000000,
}
@@ -51,12 +55,15 @@ func TestGetBase(t *testing.T) {
wanterr bool
}{
{"exec", fhExec, nil, nil, 0x400000, 0, 0, 0, false},
- {"exec offset", fhExec, lsOffset, nil, 0x400000, 0x800000, 0, 0, false},
+ {"exec offset", fhExec, lsOffset, nil, 0x400000, 0x800000, 0, 0x200000, false},
{"exec offset 2", fhExec, lsOffset, nil, 0x200000, 0x600000, 0, 0, false},
{"exec nomap", fhExec, nil, nil, 0, 0, 0, 0, false},
{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0xffffffff82000198, 0xffffffff83000198, 0, 0x1000000, false},
{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff810002b8), 0xffffffff81000000, 0xffffffffa0000000, 0x0, 0x0, false},
{"exec kernel ASLR", fhExec, kernelHeader, uint64p(0xffffffff810002b8), 0xffffffff81000000, 0xffffffffa0000000, 0xffffffff81000000, 0x0, false},
+ // TODO(aalexand): Figure out where this test case exactly comes from and
+ // whether it's still relevant.
+ {"exec kernel ASLR 2", fhExec, kernelAslrHeader, nil, 0xffffffff83e00000, 0xfffffffffc3fffff, 0x3c00000, 0x3c00000, false},
{"exec PPC64 kernel", fhExec, ppc64KernelHeader, uint64p(0xc000000000000000), 0xc000000000000000, 0xd00000001a730000, 0x0, 0x0, false},
{"exec chromeos kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10197, 0, 0x7efffe68, false},
{"exec chromeos kernel 2", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10198, 0, 0x7efffe68, false},
@@ -85,7 +92,7 @@ func TestGetBase(t *testing.T) {
continue
}
if base != tc.want {
- t.Errorf("%s: want %x, got %x", tc.label, tc.want, base)
+ t.Errorf("%s: want 0x%x, got 0x%x", tc.label, tc.want, base)
}
}
}