forked from OSchip/llvm-project
[ELF] - R_386_GOT32 relocation calculation fix.
R_386_GOT32 has multiple descriptions: "System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.1" (https://github.com/hjl-tools/x86-psABI/wiki/intel386-psABI-1.1.pdf), p36 contains next calculation for R_386_GOT32: G + A - GOT. SYSTEM V APPLICATION BINARY INTERFACE 4 (https://refspecs.linuxfoundation.org/elf/abi386-4.pdf, p78) tolds us its G + A - P. Oracle docs (https://docs.oracle.com/cd/E19455-01/816-0559/chapter6-26/index.html) says its should be G + A. gold/bfd calculates it as "G + A - GOT", but GOT means the end of the GOT section. Patch fixes current calculation to gold/ld behavior. Differential revision: http://reviews.llvm.org/D15750 llvm-svn: 258115
This commit is contained in:
parent
f82d71f025
commit
ffb673515e
|
@ -426,7 +426,13 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
|
||||||
case R_386_32:
|
case R_386_32:
|
||||||
add32le(Loc, SA);
|
add32le(Loc, SA);
|
||||||
break;
|
break;
|
||||||
case R_386_GOT32:
|
case R_386_GOT32: {
|
||||||
|
uint64_t V = SA - Out<ELF32LE>::Got->getVA() -
|
||||||
|
Out<ELF32LE>::Got->getNumEntries() * 4;
|
||||||
|
checkInt<32>(V, Type);
|
||||||
|
add32le(Loc, V);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case R_386_GOTOFF:
|
case R_386_GOTOFF:
|
||||||
add32le(Loc, SA - Out<ELF32LE>::Got->getVA());
|
add32le(Loc, SA - Out<ELF32LE>::Got->getVA());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,8 +45,8 @@ movl bar@GOT, %eax
|
||||||
// ADDR-NEXT: SHF_ALLOC
|
// ADDR-NEXT: SHF_ALLOC
|
||||||
// ADDR-NEXT: SHF_EXECINSTR
|
// ADDR-NEXT: SHF_EXECINSTR
|
||||||
// ADDR-NEXT: ]
|
// ADDR-NEXT: ]
|
||||||
// ADDR-NEXT: Address: 0x11030
|
// ADDR-NEXT: Address: 0x11040
|
||||||
// ADDR-NEXT: Offset: 0x1030
|
// ADDR-NEXT: Offset: 0x1040
|
||||||
// ADDR-NEXT: Size: 32
|
// ADDR-NEXT: Size: 32
|
||||||
|
|
||||||
// ADDR: Name: .got
|
// ADDR: Name: .got
|
||||||
|
@ -69,16 +69,26 @@ R_386_GOTPC:
|
||||||
|
|
||||||
.section .dynamic_reloc, "ax",@progbits
|
.section .dynamic_reloc, "ax",@progbits
|
||||||
call bar
|
call bar
|
||||||
// 0x11030 - (0x11019 + 5) = 18
|
// addr(.plt) + 16 - (0x11019 + 5) = 50
|
||||||
// CHECK: Disassembly of section .dynamic_reloc:
|
// CHECK: Disassembly of section .dynamic_reloc:
|
||||||
// CHECK-NEXT: .dynamic_reloc:
|
// CHECK-NEXT: .dynamic_reloc:
|
||||||
// CHECK-NEXT: 11019: e8 22 00 00 00 calll 34
|
// CHECK-NEXT: 11019: e8 32 00 00 00 calll 50
|
||||||
|
|
||||||
.section .R_386_GOT32,"ax",@progbits
|
.section .R_386_GOT32,"ax",@progbits
|
||||||
.global R_386_GOT32
|
.global R_386_GOT32
|
||||||
R_386_GOT32:
|
R_386_GOT32:
|
||||||
movl zed@GOT, %eax
|
movl bar@GOT, %eax
|
||||||
// This is the second symbol in the got, so the offset is 4.
|
movl zed@GOT, %eax
|
||||||
|
movl bar+8@GOT, %eax
|
||||||
|
movl zed+4@GOT, %eax
|
||||||
|
|
||||||
|
// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)
|
||||||
|
// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)
|
||||||
|
// 0xFFFFFFF8 + 8 = 0
|
||||||
|
// 0xFFFFFFFC + 4 = 0
|
||||||
// CHECK: Disassembly of section .R_386_GOT32:
|
// CHECK: Disassembly of section .R_386_GOT32:
|
||||||
// CHECK-NEXT: R_386_GOT32:
|
// CHECK-NEXT: R_386_GOT32:
|
||||||
// CHECK-NEXT: 1101e: {{.*}} movl 4, %eax
|
// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax
|
||||||
|
// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax
|
||||||
|
// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax
|
||||||
|
// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax
|
||||||
|
|
Loading…
Reference in New Issue