diff options
| author | Dmitri Shuralyov <dmitshur@golang.org> | 2021-09-08 10:51:06 -0400 |
|---|---|---|
| committer | Dmitri Shuralyov <dmitshur@golang.org> | 2021-09-08 15:36:36 +0000 |
| commit | 9581d891ab8c88bbf9e5b5142926fbca653551e6 (patch) | |
| tree | 3f563b03dc6bdf9f7c8c478f682995b236ae415f /src/cmd/vendor/github.com/google/pprof/internal/binutils | |
| parent | 8214257347b16a03464ace16bbcf6346fc784a3e (diff) | |
| download | go-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.go | 2 | ||||
| -rw-r--r-- | src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go | 97 |
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 } |
