Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -444,30 +444,33 @@ } void X86TargetInfo::writePltHeader(uint8_t *Buf) const { - // Executable files and shared object files have - // separate procedure linkage tables. if (Config->Pic) { const uint8_t V[] = { 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx) 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx) - 0x90, 0x90, 0x90, 0x90 // nop; nop; nop; nop + 0x90, 0x90, 0x90, 0x90 // nop }; memcpy(Buf, V, sizeof(V)); + + uint32_t Ebx = In::Got->getVA() + In::Got->getSize(); + uint32_t GotPlt = In::GotPlt->getVA() - Ebx; + write32le(Buf + 2, GotPlt + 4); + write32le(Buf + 8, GotPlt + 8); return; } const uint8_t PltData[] = { 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOT+4) 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOT+8) - 0x90, 0x90, 0x90, 0x90 // nop; nop; nop; nop + 0x90, 0x90, 0x90, 0x90 // nop }; memcpy(Buf, PltData, sizeof(PltData)); - uint32_t Got = In::GotPlt->getVA(); - write32le(Buf + 2, Got + 4); - write32le(Buf + 8, Got + 8); + uint32_t GotPlt = In::GotPlt->getVA(); + write32le(Buf + 2, GotPlt + 4); + write32le(Buf + 8, GotPlt + 8); } -void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, +void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, int32_t Index, unsigned RelOff) const { const uint8_t Inst[] = { @@ -477,10 +480,17 @@ }; memcpy(Buf, Inst, sizeof(Inst)); - // jmp *foo@GOT(%ebx) or jmp *foo_in_GOT - Buf[1] = Config->Pic ? 0xa3 : 0x25; - uint32_t Got = In::GotPlt->getVA(); - write32le(Buf + 2, Config->Shared ? GotEntryAddr - Got : GotEntryAddr); + if (Config->Pic) { + // jmp *foo@GOT(%ebx) + uint32_t Ebx = In::Got->getVA() + In::Got->getSize(); + Buf[1] = 0xa3; + write32le(Buf + 2, GotPltEntryAddr - Ebx); + } else { + // jmp *foo_in_GOT + Buf[1] = 0x25; + write32le(Buf + 2, GotPltEntryAddr); + } + write32le(Buf + 7, RelOff); write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); } Index: lld/trunk/test/ELF/plt-i686.s =================================================================== --- lld/trunk/test/ELF/plt-i686.s +++ lld/trunk/test/ELF/plt-i686.s @@ -135,23 +135,23 @@ // DISASMSHARED-NEXT: 1013: e9 e8 ff ff ff jmp -24 // DISASMSHARED-NEXT: Disassembly of section .plt: // DISASMSHARED-NEXT: .plt: -// DISASMSHARED-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx) -// DISASMSHARED-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx) +// DISASMSHARED-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx) +// DISASMSHARED-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx) // DISASMSHARED-NEXT: 102c: 90 nop // DISASMSHARED-NEXT: 102d: 90 nop // DISASMSHARED-NEXT: 102e: 90 nop // DISASMSHARED-NEXT: 102f: 90 nop -// DISASMSHARED-NEXT: 1030: ff a3 0c 00 00 00 jmpl *12(%ebx) +// DISASMSHARED-NEXT: 1030: ff a3 0c 20 00 00 jmpl *8204(%ebx) // DISASMSHARED-NEXT: 1036: 68 00 00 00 00 pushl $0 // DISASMSHARED-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt> -// DISASMSHARED-NEXT: 1040: ff a3 10 00 00 00 jmpl *16(%ebx) +// DISASMSHARED-NEXT: 1040: ff a3 10 20 00 00 jmpl *8208(%ebx) // DISASMSHARED-NEXT: 1046: 68 08 00 00 00 pushl $8 // DISASMSHARED-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt> // DISASMPIE: Disassembly of section .plt: // DISASMPIE-NEXT: .plt: -// DISASMPIE-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx) -// DISASMPIE-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx) +// DISASMPIE-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx) +// DISASMPIE-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx) // DISASMPIE-NEXT: 102c: 90 nop // DISASMPIE-NEXT: 102d: 90 nop // DISASMPIE-NEXT: 102e: 90 nop