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
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
}
import (
"fmt"
- "runtime"
"testing"
)
}
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",