mirror of
https://github.com/golang/go.git
synced 2025-05-06 08:03:03 +00: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
|
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) {
|
func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) {
|
||||||
if fh.PointerToSymbolTable == 0 {
|
if fh.PointerToSymbolTable == 0 {
|
||||||
return nil, nil
|
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)
|
return nil, fmt.Errorf("fail to seek to symbol table: %v", err)
|
||||||
}
|
}
|
||||||
syms := make([]COFFSymbol, fh.NumberOfSymbols)
|
syms := make([]COFFSymbol, fh.NumberOfSymbols)
|
||||||
err = binary.Read(r, binary.LittleEndian, syms)
|
naux := 0
|
||||||
if err != nil {
|
for k := range syms {
|
||||||
return nil, fmt.Errorf("fail to read symbol table: %v", err)
|
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
|
return syms, nil
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ package pe
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,13 +17,6 @@ type testpoint struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReadCOFFSymbolAuxInfo(t *testing.T) {
|
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{
|
testpoints := map[int]testpoint{
|
||||||
39: testpoint{
|
39: testpoint{
|
||||||
name: ".rdata$.refptr.__native_startup_lock",
|
name: ".rdata$.refptr.__native_startup_lock",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user