mirror of
https://github.com/golang/go
synced 2024-11-07 11:56:17 -07:00
cmd/link: store COFF symbol complex type in the LSB instead of the MSB
Microsoft's PE documentation is contradictory. It says that the symbol's complex type [1] is stored in the pesym.Type most significant byte (MSB), but MSVC, LLVM, and mingw store it in the 4 high bits of the less significant byte (LSB). dumpbin understands both encoding. Previous to CL 475355 the Go compiler mixed MSB and LSB encoding. CL 475355 updated to compiler to use the MSB, but this causes problems with mingw, which emits a warning when MSB is used. For reference, LLVM also hit this issue long time ago: https://github.com/llvm/llvm-project/issues/8692 [1] https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#type-representation Change-Id: I7e750bde9c20e2c4c1c023203d7abd6fb26d9d30 Reviewed-on: https://go-review.googlesource.com/c/go/+/475855 Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
a54fe8a270
commit
b37c0602cd
@ -753,13 +753,19 @@ func (f *peFile) writeSymbols(ctxt *Link) {
|
|||||||
if ctxt.IsExternal() {
|
if ctxt.IsExternal() {
|
||||||
peSymType = IMAGE_SYM_TYPE_NULL
|
peSymType = IMAGE_SYM_TYPE_NULL
|
||||||
} else {
|
} else {
|
||||||
peSymType = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
|
// Microsoft's PE documentation is contradictory. It says that the symbol's complex type
|
||||||
|
// is stored in the pesym.Type most significant byte, but MSVC, LLVM, and mingw store it
|
||||||
|
// in the 4 high bits of the less significant byte.
|
||||||
|
peSymType = IMAGE_SYM_DTYPE_ARRAY<<4 + IMAGE_SYM_TYPE_STRUCT
|
||||||
}
|
}
|
||||||
sect, value, err := f.mapToPESection(ldr, s, ctxt.LinkMode)
|
sect, value, err := f.mapToPESection(ldr, s, ctxt.LinkMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
|
switch t {
|
||||||
peSymType = IMAGE_SYM_DTYPE_FUNCTION << 8
|
case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT:
|
||||||
} else {
|
// Microsoft's PE documentation says that the basic type for a function should be
|
||||||
|
// IMAGE_SYM_TYPE_VOID, but the reality is that it uses IMAGE_SYM_TYPE_NULL instead.
|
||||||
|
peSymType = IMAGE_SYM_DTYPE_FUNCTION<<4 + IMAGE_SYM_TYPE_NULL
|
||||||
|
default:
|
||||||
ctxt.Errorf(s, "addpesym: %v", err)
|
ctxt.Errorf(s, "addpesym: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,7 +672,10 @@ func (state *peLoaderState) readpesym(pesym *pe.COFFSymbol) (*loader.SymbolBuild
|
|||||||
|
|
||||||
var s loader.Sym
|
var s loader.Sym
|
||||||
var bld *loader.SymbolBuilder
|
var bld *loader.SymbolBuilder
|
||||||
switch uint8(pesym.Type >> 8) {
|
// Microsoft's PE documentation is contradictory. It says that the symbol's complex type
|
||||||
|
// is stored in the pesym.Type most significant byte, but MSVC, LLVM, and mingw store it
|
||||||
|
// in the 4 high bits of the less significant byte.
|
||||||
|
switch uint8(pesym.Type&0xf0) >> 4 {
|
||||||
default:
|
default:
|
||||||
return nil, 0, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
|
return nil, 0, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user