Skip to content

Commit 594deca

Browse files
committed
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 <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 9df1a28 commit 594deca

File tree

1 file changed

+34
-70
lines changed
  • src/cmd/link/internal/loadpe

1 file changed

+34
-70
lines changed

src/cmd/link/internal/loadpe/ldpe.go

Lines changed: 34 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"errors"
1818
"fmt"
1919
"io"
20+
"strconv"
2021
"strings"
2122
)
2223

@@ -348,102 +349,65 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
348349
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))
349350
}
350351
pesym := &f.COFFSymbols[r.SymbolTableIndex]
351-
_, gosym, err := state.readpesym(pesym)
352+
_, rSym, err := state.readpesym(pesym)
352353
if err != nil {
353354
return nil, err
354355
}
355-
if gosym == 0 {
356+
if rSym == 0 {
356357
name, err := pesym.FullName(f.StringTable)
357358
if err != nil {
358359
name = string(pesym.Name[:])
359360
}
360361
return nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
361362
}
362363

363-
rSym := gosym
364364
rSize := uint8(4)
365365
rOff := int32(r.VirtualAddress)
366-
var rAdd int64
367366
var rType objabi.RelocType
368367
switch arch.Family {
369368
default:
370369
return nil, fmt.Errorf("%s: unsupported arch %v", pn, arch.Family)
371-
case sys.I386, sys.AMD64:
370+
case sys.I386:
372371
switch r.Type {
373-
default:
374-
return nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, state.sectsyms[rsect], r.Type)
375-
376-
case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
377-
IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
378-
IMAGE_REL_AMD64_ADDR32NB:
379-
if r.Type == IMAGE_REL_AMD64_ADDR32NB {
380-
rType = objabi.R_PEIMAGEOFF
381-
} else {
382-
rType = objabi.R_PCREL
383-
}
384-
385-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
386-
387-
case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
388-
if r.Type == IMAGE_REL_I386_DIR32NB {
389-
rType = objabi.R_PEIMAGEOFF
390-
} else {
391-
rType = objabi.R_ADDR
392-
}
393-
394-
// load addend from image
395-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
396-
397-
case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
398-
rSize = 8
399-
372+
case IMAGE_REL_I386_REL32:
373+
rType = objabi.R_PCREL
374+
case IMAGE_REL_I386_DIR32:
400375
rType = objabi.R_ADDR
401-
402-
// load addend from image
403-
rAdd = int64(binary.LittleEndian.Uint64(state.sectdata[rsect][rOff:]))
376+
case IMAGE_REL_I386_DIR32NB:
377+
rType = objabi.R_PEIMAGEOFF
404378
}
405-
406-
case sys.ARM:
379+
case sys.AMD64:
407380
switch r.Type {
408-
default:
409-
return nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, state.sectsyms[rsect], r.Type)
410-
411-
case IMAGE_REL_ARM_SECREL:
381+
case IMAGE_REL_AMD64_REL32:
412382
rType = objabi.R_PCREL
413-
414-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
415-
416-
case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
417-
if r.Type == IMAGE_REL_ARM_ADDR32NB {
418-
rType = objabi.R_PEIMAGEOFF
419-
} else {
420-
rType = objabi.R_ADDR
421-
}
422-
423-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
424-
425-
case IMAGE_REL_ARM_BRANCH24:
426-
rType = objabi.R_CALLARM
427-
428-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
383+
case IMAGE_REL_AMD64_ADDR32:
384+
rType = objabi.R_ADDR
385+
case IMAGE_REL_AMD64_ADDR64:
386+
rType = objabi.R_ADDR
387+
rSize = 8
388+
case IMAGE_REL_AMD64_ADDR32NB:
389+
rType = objabi.R_PEIMAGEOFF
429390
}
430-
431391
case sys.ARM64:
432392
switch r.Type {
433-
default:
434-
return nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, state.sectsyms[rsect], r.Type)
435-
436-
case IMAGE_REL_ARM64_ADDR32, IMAGE_REL_ARM64_ADDR32NB:
437-
if r.Type == IMAGE_REL_ARM64_ADDR32NB {
438-
rType = objabi.R_PEIMAGEOFF
439-
} else {
440-
rType = objabi.R_ADDR
441-
}
442-
443-
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
393+
case IMAGE_REL_ARM64_ADDR32:
394+
rType = objabi.R_ADDR
395+
case IMAGE_REL_ARM64_ADDR32NB:
396+
rType = objabi.R_PEIMAGEOFF
444397
}
445398
}
446-
399+
if rType == 0 {
400+
return nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, state.sectsyms[rsect], r.Type)
401+
}
402+
var rAdd int64
403+
switch rSize {
404+
default:
405+
panic("unexpected relocation size " + strconv.Itoa(int(rSize)))
406+
case 4:
407+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
408+
case 8:
409+
rAdd = int64(binary.LittleEndian.Uint64(state.sectdata[rsect][rOff:]))
410+
}
447411
// ld -r could generate multiple section symbols for the
448412
// same section but with different values, we have to take
449413
// that into account, or in the case of split resources,

0 commit comments

Comments
 (0)