mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: simplify PE relocations mapping
The code for mapping Windows PE relocations to Go relocations was difficult to follow and contains some duplicated code. Also, it was mapping IMAGE_REL_AMD64_ADDR32 to R_PCREL instead of R_ADDR. This CL commit simplifies the code and fixes the mapping. I haven't been able to coerce mingw-w64 to generate IMAGE_REL_AMD64_ADDR32 relocations, so I haven't been able to test this change. However, the previous implementation was clearly wrong. While here, remove code supporting the unsupported windows/arm support. Updates #71671 Updates #75485 Change-Id: Id0d6f352fa7d5df9e00509fcdf09ca0cb91ca524 Reviewed-on: https://go-review.googlesource.com/c/go/+/672155 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
9df1a289ac
commit
594deca981
1 changed files with 37 additions and 73 deletions
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -348,11 +349,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
|
||||||
return nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
|
return nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
|
||||||
}
|
}
|
||||||
pesym := &f.COFFSymbols[r.SymbolTableIndex]
|
pesym := &f.COFFSymbols[r.SymbolTableIndex]
|
||||||
_, gosym, err := state.readpesym(pesym)
|
_, rSym, err := state.readpesym(pesym)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if gosym == 0 {
|
if rSym == 0 {
|
||||||
name, err := pesym.FullName(f.StringTable)
|
name, err := pesym.FullName(f.StringTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
name = string(pesym.Name[:])
|
name = string(pesym.Name[:])
|
||||||
|
|
@ -360,90 +361,53 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
|
||||||
return nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
|
return nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
rSym := gosym
|
|
||||||
rSize := uint8(4)
|
rSize := uint8(4)
|
||||||
rOff := int32(r.VirtualAddress)
|
rOff := int32(r.VirtualAddress)
|
||||||
var rAdd int64
|
|
||||||
var rType objabi.RelocType
|
var rType objabi.RelocType
|
||||||
switch arch.Family {
|
switch arch.Family {
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%s: unsupported arch %v", pn, arch.Family)
|
return nil, fmt.Errorf("%s: unsupported arch %v", pn, arch.Family)
|
||||||
case sys.I386, sys.AMD64:
|
case sys.I386:
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
case IMAGE_REL_I386_REL32:
|
||||||
return nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, state.sectsyms[rsect], r.Type)
|
|
||||||
|
|
||||||
case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
|
|
||||||
IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
|
|
||||||
IMAGE_REL_AMD64_ADDR32NB:
|
|
||||||
if r.Type == IMAGE_REL_AMD64_ADDR32NB {
|
|
||||||
rType = objabi.R_PEIMAGEOFF
|
|
||||||
} else {
|
|
||||||
rType = objabi.R_PCREL
|
|
||||||
}
|
|
||||||
|
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
|
||||||
|
|
||||||
case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
|
|
||||||
if r.Type == IMAGE_REL_I386_DIR32NB {
|
|
||||||
rType = objabi.R_PEIMAGEOFF
|
|
||||||
} else {
|
|
||||||
rType = objabi.R_ADDR
|
|
||||||
}
|
|
||||||
|
|
||||||
// load addend from image
|
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
|
||||||
|
|
||||||
case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
|
|
||||||
rSize = 8
|
|
||||||
|
|
||||||
rType = objabi.R_ADDR
|
|
||||||
|
|
||||||
// load addend from image
|
|
||||||
rAdd = int64(binary.LittleEndian.Uint64(state.sectdata[rsect][rOff:]))
|
|
||||||
}
|
|
||||||
|
|
||||||
case sys.ARM:
|
|
||||||
switch r.Type {
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, state.sectsyms[rsect], r.Type)
|
|
||||||
|
|
||||||
case IMAGE_REL_ARM_SECREL:
|
|
||||||
rType = objabi.R_PCREL
|
rType = objabi.R_PCREL
|
||||||
|
case IMAGE_REL_I386_DIR32:
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
rType = objabi.R_ADDR
|
||||||
|
case IMAGE_REL_I386_DIR32NB:
|
||||||
case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
|
rType = objabi.R_PEIMAGEOFF
|
||||||
if r.Type == IMAGE_REL_ARM_ADDR32NB {
|
}
|
||||||
rType = objabi.R_PEIMAGEOFF
|
case sys.AMD64:
|
||||||
} else {
|
switch r.Type {
|
||||||
rType = objabi.R_ADDR
|
case IMAGE_REL_AMD64_REL32:
|
||||||
}
|
rType = objabi.R_PCREL
|
||||||
|
case IMAGE_REL_AMD64_ADDR32:
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
rType = objabi.R_ADDR
|
||||||
|
case IMAGE_REL_AMD64_ADDR64:
|
||||||
case IMAGE_REL_ARM_BRANCH24:
|
rType = objabi.R_ADDR
|
||||||
rType = objabi.R_CALLARM
|
rSize = 8
|
||||||
|
case IMAGE_REL_AMD64_ADDR32NB:
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
rType = objabi.R_PEIMAGEOFF
|
||||||
}
|
}
|
||||||
|
|
||||||
case sys.ARM64:
|
case sys.ARM64:
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
case IMAGE_REL_ARM64_ADDR32:
|
||||||
return nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, state.sectsyms[rsect], r.Type)
|
rType = objabi.R_ADDR
|
||||||
|
case IMAGE_REL_ARM64_ADDR32NB:
|
||||||
case IMAGE_REL_ARM64_ADDR32, IMAGE_REL_ARM64_ADDR32NB:
|
rType = objabi.R_PEIMAGEOFF
|
||||||
if r.Type == IMAGE_REL_ARM64_ADDR32NB {
|
|
||||||
rType = objabi.R_PEIMAGEOFF
|
|
||||||
} else {
|
|
||||||
rType = objabi.R_ADDR
|
|
||||||
}
|
|
||||||
|
|
||||||
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if rType == 0 {
|
||||||
|
return nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, state.sectsyms[rsect], r.Type)
|
||||||
|
}
|
||||||
|
var rAdd int64
|
||||||
|
switch rSize {
|
||||||
|
default:
|
||||||
|
panic("unexpected relocation size " + strconv.Itoa(int(rSize)))
|
||||||
|
case 4:
|
||||||
|
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
|
||||||
|
case 8:
|
||||||
|
rAdd = int64(binary.LittleEndian.Uint64(state.sectdata[rsect][rOff:]))
|
||||||
|
}
|
||||||
// ld -r could generate multiple section symbols for the
|
// ld -r could generate multiple section symbols for the
|
||||||
// same section but with different values, we have to take
|
// same section but with different values, we have to take
|
||||||
// that into account, or in the case of split resources,
|
// that into account, or in the case of split resources,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue