]> Cypherpunks repositories - gostls13.git/commitdiff
debug/pe: rework reading of aux symbols to fix endianity problems
authorThan McIntosh <thanm@google.com>
Fri, 1 Apr 2022 15:12:22 +0000 (11:12 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 6 May 2022 18:07:48 +0000 (18:07 +0000)
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>
src/debug/pe/symbol.go
src/debug/pe/symbols_test.go

index 323fa8c3df6a5e8e70aeec9a7fa370e6d927d9a7..dfbeb114144dcd8afdf2a6c88df32e9f28fd8eb0 100644 (file)
@@ -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
 }
index 5ccf6358306bdf241dfac91cb0b7e1b739e2b423..c4dcd95391f3413010704855acbec1e298866486 100644 (file)
@@ -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",