diff options
| author | Than McIntosh <thanm@google.com> | 2022-04-01 11:12:22 -0400 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2022-05-06 18:07:48 +0000 |
| commit | 054323d809cb15d47ca72d0deeadb5cfc2737780 (patch) | |
| tree | 07e29bcb50f59ba71a50083120d76c54717396ef /src/debug/pe | |
| parent | f495b36ccdfe93629cb83f8be79dca662ef68a64 (diff) | |
| download | go-054323d809cb15d47ca72d0deeadb5cfc2737780.tar.xz | |
debug/pe: rework reading of aux symbols to fix endianity problems
This patch reworks CL 394534 to fix things so that reading auxiliary
symbol info works properly in a cross-endian mode (running
debug/pe-based tool on a big-endian system). The previous
implementation read in all symbol records using the primary symbol
format, then just used a pointer cast to convert to the auxiliary
format, which doesn't play well if host and target have different
endianness.
Fixes #52079.
Change-Id: I143d94d9313a265f11ca7befd254bdb150698834
Reviewed-on: https://go-review.googlesource.com/c/go/+/397485
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/debug/pe')
| -rw-r--r-- | src/debug/pe/symbol.go | 51 | ||||
| -rw-r--r-- | src/debug/pe/symbols_test.go | 8 |
2 files changed, 48 insertions, 11 deletions
diff --git a/src/debug/pe/symbol.go b/src/debug/pe/symbol.go index 323fa8c3df..dfbeb11414 100644 --- a/src/debug/pe/symbol.go +++ b/src/debug/pe/symbol.go @@ -23,6 +23,29 @@ type COFFSymbol struct { NumberOfAuxSymbols uint8 } +// readCOFFSymbols reads in the symbol table for a PE file, returning +// a slice of COFFSymbol objects. The PE format includes both primary +// symbols (whose fields are described by COFFSymbol above) and +// auxiliary symbols; all symbols are 18 bytes in size. The auxiliary +// symbols for a given primary symbol are placed following it in the +// array, e.g. +// +// ... +// k+0: regular sym k +// k+1: 1st aux symbol for k +// k+2: 2nd aux symbol for k +// k+3: regular sym k+3 +// k+4: 1st aux symbol for k+3 +// k+5: regular sym k+5 +// k+6: regular sym k+6 +// +// The PE format allows for several possible aux symbol formats. For +// more info see: +// +// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-symbol-records +// +// At the moment this package only provides APIs for looking at +// aux symbols of format 5 (associated with section definition symbols). func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) { if fh.PointerToSymbolTable == 0 { return nil, nil @@ -35,9 +58,31 @@ func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) { return nil, fmt.Errorf("fail to seek to symbol table: %v", err) } syms := make([]COFFSymbol, fh.NumberOfSymbols) - err = binary.Read(r, binary.LittleEndian, syms) - if err != nil { - return nil, fmt.Errorf("fail to read symbol table: %v", err) + naux := 0 + for k := range syms { + if naux == 0 { + // Read a primary symbol. + err = binary.Read(r, binary.LittleEndian, &syms[k]) + if err != nil { + return nil, fmt.Errorf("fail to read symbol table: %v", err) + } + // Record how many auxiliary symbols it has. + naux = int(syms[k].NumberOfAuxSymbols) + } else { + // Read an aux symbol. At the moment we assume all + // aux symbols are format 5 (obviously this doesn't always + // hold; more cases will be needed below if more aux formats + // are supported in the future). + naux-- + aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&syms[k])) + err = binary.Read(r, binary.LittleEndian, aux) + if err != nil { + return nil, fmt.Errorf("fail to read symbol table: %v", err) + } + } + } + if naux != 0 { + return nil, fmt.Errorf("fail to read symbol table: %d aux symbols unread", naux) } return syms, nil } diff --git a/src/debug/pe/symbols_test.go b/src/debug/pe/symbols_test.go index 5ccf635830..c4dcd95391 100644 --- a/src/debug/pe/symbols_test.go +++ b/src/debug/pe/symbols_test.go @@ -6,7 +6,6 @@ package pe import ( "fmt" - "runtime" "testing" ) @@ -18,13 +17,6 @@ type testpoint struct { } func TestReadCOFFSymbolAuxInfo(t *testing.T) { - - switch runtime.GOARCH { - case "mips", "mips64", "ppc64", "s390x": - t.Skipf("Skipping on %s (big endian) until issue #52079 fixed", - runtime.GOARCH) - } - testpoints := map[int]testpoint{ 39: testpoint{ name: ".rdata$.refptr.__native_startup_lock", |
