aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/github.com/google/pprof/internal/binutils
diff options
context:
space:
mode:
authorDmitri Shuralyov <dmitshur@golang.org>2021-09-08 10:51:06 -0400
committerDmitri Shuralyov <dmitshur@golang.org>2021-09-08 15:36:36 +0000
commit9581d891ab8c88bbf9e5b5142926fbca653551e6 (patch)
tree3f563b03dc6bdf9f7c8c478f682995b236ae415f /src/cmd/vendor/github.com/google/pprof/internal/binutils
parent8214257347b16a03464ace16bbcf6346fc784a3e (diff)
downloadgo-9581d891ab8c88bbf9e5b5142926fbca653551e6.tar.xz
cmd/pprof: update vendored github.com/google/pprof
Pull in the latest published version of github.com/google/pprof that is available at this time in the Go 1.18 development cycle. Done with: go get -d github.com/google/pprof@latest go mod tidy go mod vendor For #36905. Change-Id: Ib25aa38365ec70a0bed2a8a6527e5823ab9f9ded Reviewed-on: https://go-review.googlesource.com/c/go/+/348410 Trust: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal/binutils')
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go97
2 files changed, 45 insertions, 54 deletions
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
index 24c48e649b..844c7a475d 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go
@@ -76,7 +76,7 @@ func newLLVMSymbolizer(cmd, file string, base uint64, isData bool) (*llvmSymboli
}
j := &llvmSymbolizerJob{
- cmd: exec.Command(cmd, "-inlining", "-demangle=false"),
+ cmd: exec.Command(cmd, "--inlining", "-demangle=false"),
symType: "CODE",
}
if isData {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
index 5ed8a1f9f1..e920eeb2fa 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
@@ -525,6 +525,47 @@ type elfMapping struct {
stextOffset *uint64
}
+// findProgramHeader returns the program segment that matches the current
+// mapping and the given address, or an error if it cannot find a unique program
+// header.
+func (m *elfMapping) findProgramHeader(ef *elf.File, addr uint64) (*elf.ProgHeader, error) {
+ // For user space executables, we try to find the actual program segment that
+ // is associated with the given mapping. Skip this search if limit <= start.
+ // We cannot use just a check on the start address of the mapping to tell if
+ // it's a kernel / .ko module mapping, because with quipper address remapping
+ // enabled, the address would be in the lower half of the address space.
+
+ if m.stextOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) {
+ // For the kernel, find the program segment that includes the .text section.
+ return elfexec.FindTextProgHeader(ef), nil
+ }
+
+ // Fetch all the loadable segments.
+ var phdrs []elf.ProgHeader
+ for i := range ef.Progs {
+ if ef.Progs[i].Type == elf.PT_LOAD {
+ phdrs = append(phdrs, ef.Progs[i].ProgHeader)
+ }
+ }
+ // Some ELF files don't contain any loadable program segments, e.g. .ko
+ // kernel modules. It's not an error to have no header in such cases.
+ if len(phdrs) == 0 {
+ return nil, nil
+ }
+ // Get all program headers associated with the mapping.
+ headers := elfexec.ProgramHeadersForMapping(phdrs, m.offset, m.limit-m.start)
+ if len(headers) == 0 {
+ return nil, errors.New("no program header matches mapping info")
+ }
+ if len(headers) == 1 {
+ return headers[0], nil
+ }
+
+ // Use the file offset corresponding to the address to symbolize, to narrow
+ // down the header.
+ return elfexec.HeaderForFileOffset(headers, addr-m.start+m.offset)
+}
+
// file implements the binutils.ObjFile interface.
type file struct {
b *binrep
@@ -555,27 +596,9 @@ func (f *file) computeBase(addr uint64) error {
}
defer ef.Close()
- var ph *elf.ProgHeader
- // For user space executables, find the actual program segment that is
- // associated with the given mapping. Skip this search if limit <= start.
- // We cannot use just a check on the start address of the mapping to tell if
- // it's a kernel / .ko module mapping, because with quipper address remapping
- // enabled, the address would be in the lower half of the address space.
- if f.m.stextOffset == nil && f.m.start < f.m.limit && f.m.limit < (uint64(1)<<63) {
- // Get all program headers associated with the mapping.
- headers, hasLoadables := elfexec.ProgramHeadersForMapping(ef, f.m.offset, f.m.limit-f.m.start)
-
- // Some ELF files don't contain any loadable program segments, e.g. .ko
- // kernel modules. It's not an error to have no header in such cases.
- if hasLoadables {
- ph, err = matchUniqueHeader(headers, addr-f.m.start+f.m.offset)
- if err != nil {
- return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err)
- }
- }
- } else {
- // For the kernel, find the program segment that includes the .text section.
- ph = elfexec.FindTextProgHeader(ef)
+ ph, err := f.m.findProgramHeader(ef, addr)
+ if err != nil {
+ return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err)
}
base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.stextOffset, f.m.start, f.m.limit, f.m.offset)
@@ -587,38 +610,6 @@ func (f *file) computeBase(addr uint64) error {
return nil
}
-// matchUniqueHeader attempts to identify a unique header from the given list,
-// using the given file offset to disambiguate between multiple segments. It
-// returns an error if the header list is empty or if it cannot identify a
-// unique header.
-func matchUniqueHeader(headers []*elf.ProgHeader, fileOffset uint64) (*elf.ProgHeader, error) {
- if len(headers) == 0 {
- return nil, errors.New("no program header matches mapping info")
- }
- if len(headers) == 1 {
- // Don't use the file offset if we already have a single header.
- return headers[0], nil
- }
- // We have multiple input segments. Attempt to identify a unique one
- // based on the given file offset.
- var ph *elf.ProgHeader
- for _, h := range headers {
- if fileOffset >= h.Off && fileOffset < h.Off+h.Memsz {
- if ph != nil {
- // Assuming no other bugs, this can only happen if we have two or
- // more small program segments that fit on the same page, and a
- // segment other than the last one includes uninitialized data.
- return nil, fmt.Errorf("found second program header (%#v) that matches file offset %x, first program header is %#v. Does first program segment contain uninitialized data?", *h, fileOffset, *ph)
- }
- ph = h
- }
- }
- if ph == nil {
- return nil, fmt.Errorf("no program header matches file offset %x", fileOffset)
- }
- return ph, nil
-}
-
func (f *file) Name() string {
return f.name
}