Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -426,7 +426,13 @@ case R_386_32: add32le(Loc, SA); break; - case R_386_GOT32: + case R_386_GOT32: { + uint64_t V = SA - Out::Got->getVA() - + Out::Got->getNumEntries() * 4; + checkInt<32>(V, Type); + add32le(Loc, V); + break; + } case R_386_GOTOFF: add32le(Loc, SA - Out::Got->getVA()); break; Index: lld/trunk/test/ELF/relocation-i686.s =================================================================== --- lld/trunk/test/ELF/relocation-i686.s +++ lld/trunk/test/ELF/relocation-i686.s @@ -45,8 +45,8 @@ // ADDR-NEXT: SHF_ALLOC // ADDR-NEXT: SHF_EXECINSTR // ADDR-NEXT: ] -// ADDR-NEXT: Address: 0x11030 -// ADDR-NEXT: Offset: 0x1030 +// ADDR-NEXT: Address: 0x11040 +// ADDR-NEXT: Offset: 0x1040 // ADDR-NEXT: Size: 32 // ADDR: Name: .got @@ -69,16 +69,26 @@ .section .dynamic_reloc, "ax",@progbits call bar -// 0x11030 - (0x11019 + 5) = 18 +// addr(.plt) + 16 - (0x11019 + 5) = 50 // CHECK: Disassembly of section .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 .global R_386_GOT32 R_386_GOT32: - movl zed@GOT, %eax -// This is the second symbol in the got, so the offset is 4. + movl bar@GOT, %eax + 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-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