mirror of
https://github.com/golang/go
synced 2024-11-26 14:26:51 -07:00
cmd/link: separate elf addend size from reloc size
The size of the field may be smaller than the addend, such is the case with R_PPC64_TOC16_HA/LO and similar relocations. Add an extra return value to ldelf.relSize to account for addend size which may be larger than the relocated field, and fix the related ppc64 relocations. Such relocs can be seen in large PIC blobs such as the ppc64le race detector included with golang. Change-Id: I457186fea5d0ec5572b9bbf79bb7fa21a36cc1b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/303990 Run-TryBot: Paul Murphy <murp@ibm.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
parent
e8700f1ce6
commit
975b097307
@ -755,7 +755,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
|
rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
|
||||||
rSize, err := relSize(arch, pn, uint32(relocType))
|
rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
@ -772,10 +772,10 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rSize == 2 {
|
if addendSize == 2 {
|
||||||
rAdd = int64(int16(rAdd))
|
rAdd = int64(int16(rAdd))
|
||||||
}
|
}
|
||||||
if rSize == 4 {
|
if addendSize == 4 {
|
||||||
rAdd = int64(int32(rAdd))
|
rAdd = int64(int32(rAdd))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -947,7 +947,10 @@ func readelfsym(newSym, lookup func(string, int) loader.Sym, l *loader.Loader, a
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
// Return the size of the relocated field, and the size of the addend as the first
|
||||||
|
// and second values. Note, the addend may be larger than the relocation field in
|
||||||
|
// some cases when a relocated value is split across multiple relocations.
|
||||||
|
func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
|
||||||
// TODO(mdempsky): Replace this with a struct-valued switch statement
|
// TODO(mdempsky): Replace this with a struct-valued switch statement
|
||||||
// once golang.org/issue/15164 is fixed or found to not impair cmd/link
|
// once golang.org/issue/15164 is fixed or found to not impair cmd/link
|
||||||
// performance.
|
// performance.
|
||||||
@ -966,7 +969,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||||||
|
|
||||||
switch uint32(arch.Family) | elftype<<16 {
|
switch uint32(arch.Family) | elftype<<16 {
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
|
return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
|
||||||
|
|
||||||
case MIPS | uint32(elf.R_MIPS_HI16)<<16,
|
case MIPS | uint32(elf.R_MIPS_HI16)<<16,
|
||||||
MIPS | uint32(elf.R_MIPS_LO16)<<16,
|
MIPS | uint32(elf.R_MIPS_LO16)<<16,
|
||||||
@ -990,26 +993,18 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||||||
MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
|
MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
|
||||||
MIPS64 | uint32(elf.R_MIPS_64)<<16,
|
MIPS64 | uint32(elf.R_MIPS_64)<<16,
|
||||||
MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16:
|
MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16:
|
||||||
return 4, nil
|
return 4, 4, nil
|
||||||
|
|
||||||
case S390X | uint32(elf.R_390_8)<<16:
|
case S390X | uint32(elf.R_390_8)<<16:
|
||||||
return 1, nil
|
return 1, 1, nil
|
||||||
|
|
||||||
case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
|
case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
|
||||||
PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
|
|
||||||
PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
|
|
||||||
S390X | uint32(elf.R_390_16)<<16,
|
S390X | uint32(elf.R_390_16)<<16,
|
||||||
S390X | uint32(elf.R_390_GOT16)<<16,
|
S390X | uint32(elf.R_390_GOT16)<<16,
|
||||||
S390X | uint32(elf.R_390_PC16)<<16,
|
S390X | uint32(elf.R_390_PC16)<<16,
|
||||||
S390X | uint32(elf.R_390_PC16DBL)<<16,
|
S390X | uint32(elf.R_390_PC16DBL)<<16,
|
||||||
S390X | uint32(elf.R_390_PLT16DBL)<<16:
|
S390X | uint32(elf.R_390_PLT16DBL)<<16:
|
||||||
return 2, nil
|
return 2, 2, nil
|
||||||
|
|
||||||
case ARM | uint32(elf.R_ARM_ABS32)<<16,
|
case ARM | uint32(elf.R_ARM_ABS32)<<16,
|
||||||
ARM | uint32(elf.R_ARM_GOT32)<<16,
|
ARM | uint32(elf.R_ARM_GOT32)<<16,
|
||||||
@ -1057,7 +1052,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||||||
S390X | uint32(elf.R_390_PLT32DBL)<<16,
|
S390X | uint32(elf.R_390_PLT32DBL)<<16,
|
||||||
S390X | uint32(elf.R_390_GOTPCDBL)<<16,
|
S390X | uint32(elf.R_390_GOTPCDBL)<<16,
|
||||||
S390X | uint32(elf.R_390_GOTENT)<<16:
|
S390X | uint32(elf.R_390_GOTENT)<<16:
|
||||||
return 4, nil
|
return 4, 4, nil
|
||||||
|
|
||||||
case AMD64 | uint32(elf.R_X86_64_64)<<16,
|
case AMD64 | uint32(elf.R_X86_64_64)<<16,
|
||||||
AMD64 | uint32(elf.R_X86_64_PC64)<<16,
|
AMD64 | uint32(elf.R_X86_64_PC64)<<16,
|
||||||
@ -1072,11 +1067,11 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||||||
S390X | uint32(elf.R_390_PC64)<<16,
|
S390X | uint32(elf.R_390_PC64)<<16,
|
||||||
S390X | uint32(elf.R_390_GOT64)<<16,
|
S390X | uint32(elf.R_390_GOT64)<<16,
|
||||||
S390X | uint32(elf.R_390_PLT64)<<16:
|
S390X | uint32(elf.R_390_PLT64)<<16:
|
||||||
return 8, nil
|
return 8, 8, nil
|
||||||
|
|
||||||
case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
|
case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
|
RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
|
||||||
return 2, nil
|
return 2, 2, nil
|
||||||
|
|
||||||
case RISCV64 | uint32(elf.R_RISCV_32)<<16,
|
case RISCV64 | uint32(elf.R_RISCV_32)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
|
RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
|
||||||
@ -1088,12 +1083,22 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
|
|||||||
RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
|
RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
|
RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
|
RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
|
||||||
return 4, nil
|
return 4, 4, nil
|
||||||
|
|
||||||
case RISCV64 | uint32(elf.R_RISCV_64)<<16,
|
case RISCV64 | uint32(elf.R_RISCV_64)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
|
RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
|
||||||
RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
|
RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
|
||||||
return 8, nil
|
return 8, 8, nil
|
||||||
|
|
||||||
|
case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
|
||||||
|
PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16:
|
||||||
|
return 2, 4, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user