mirror of
https://github.com/golang/go
synced 2024-11-11 19:01:37 -07:00
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>
This commit is contained in:
parent
f495b36ccd
commit
054323d809
@ -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,10 +58,32 @@ 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)
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user