Index: ELF/Arch/X86.cpp =================================================================== --- ELF/Arch/X86.cpp +++ ELF/Arch/X86.cpp @@ -87,9 +87,9 @@ case R_386_TLS_LDO_32: return R_ABS; case R_386_TLS_GD: - return R_TLSGD_GOT_FROM_END; + return R_TLSGD_GOTPLT; case R_386_TLS_LDM: - return R_TLSLD_GOT_FROM_END; + return R_TLSLD_GOTPLT; case R_386_PLT32: return R_PLT_PC; case R_386_PC8: @@ -97,7 +97,7 @@ case R_386_PC32: return R_PC; case R_386_GOTPC: - return R_GOTONLY_PC_FROM_END; + return R_GOTPLTONLY_PC; case R_386_TLS_IE: return R_GOT; case R_386_GOT32: @@ -136,12 +136,12 @@ // of a displacement or an immediate field of a valid machine // instruction. That means a ModRM byte is at Loc[-1]. By taking a look at // the byte, we can determine whether the instruction uses the operand as an - // absolute address (R_GOT) or a register-relative address (R_GOT_FROM_END). - return (Loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOT_FROM_END; + // absolute address (R_GOT) or a register-relative address (R_GOTPLT). + return (Loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOTPLT; case R_386_TLS_GOTIE: - return R_GOT_FROM_END; + return R_GOTPLT; case R_386_GOTOFF: - return R_GOTREL_FROM_END; + return R_GOTPLTREL; case R_386_TLS_LE: return R_TLS; case R_386_TLS_LE_32: @@ -193,16 +193,11 @@ void X86::writePltHeader(uint8_t *Buf) const { if (Config->Pic) { const uint8_t V[] = { - 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl GOTPLT+4(%ebx) - 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *GOTPLT+8(%ebx) + 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx) + 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx) 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; } @@ -229,7 +224,7 @@ if (Config->Pic) { // jmp *foo@GOT(%ebx) - uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); + uint32_t Ebx = In.GotPlt->getVA(); Buf[1] = 0xa3; write32le(Buf + 2, GotPltEntryAddr - Ebx); } else { @@ -445,9 +440,9 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const { const uint8_t Insn[] = { - 0xff, 0xb3, 0, 0, 0, 0, // 0: pushl GOTPLT+4(%ebx) + 0xff, 0xb3, 4, 0, 0, 0, // 0: pushl 4(%ebx) 0x50, // 6: pushl %eax - 0x8b, 0x83, 0, 0, 0, 0, // 7: mov GOTPLT+8(%ebx), %eax + 0x8b, 0x83, 8, 0, 0, 0, // 7: mov 8(%ebx), %eax 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: call next 0xf3, 0x90, // 12: loop: pause 0x0f, 0xae, 0xe8, // 14: lfence @@ -462,11 +457,6 @@ 0xcc, // 2f: int3; padding }; memcpy(Buf, Insn, sizeof(Insn)); - - uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); - uint32_t GotPlt = In.GotPlt->getVA() - Ebx; - write32le(Buf + 2, GotPlt + 4); - write32le(Buf + 9, GotPlt + 8); } void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, @@ -483,7 +473,7 @@ }; memcpy(Buf, Insn, sizeof(Insn)); - uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); + uint32_t Ebx = In.GotPlt->getVA(); unsigned Off = getPltEntryOffset(Index); write32le(Buf + 3, GotPltEntryAddr - Ebx); write32le(Buf + 8, -Off - 12 + 32); Index: ELF/Arch/X86_64.cpp =================================================================== --- ELF/Arch/X86_64.cpp +++ ELF/Arch/X86_64.cpp @@ -111,17 +111,17 @@ return R_PC; case R_X86_64_GOT32: case R_X86_64_GOT64: - return R_GOT_FROM_END; + return R_GOTPLT; case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: - return R_GOTREL_FROM_END; + return R_GOTPLTREL; case R_X86_64_GOTPC32: case R_X86_64_GOTPC64: - return R_GOTONLY_PC_FROM_END; + return R_GOTPLTONLY_PC; case R_X86_64_NONE: return R_NONE; default: Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -624,15 +624,15 @@ return Sym.getGotVA() + A; case R_GOTONLY_PC: return In.Got->getVA() + A - P; - case R_GOTONLY_PC_FROM_END: - return In.Got->getVA() + A - P + In.Got->getSize(); + case R_GOTPLTONLY_PC: + return In.GotPlt->getVA() + A - P; case R_GOTREL: return Sym.getVA(A) - In.Got->getVA(); - case R_GOTREL_FROM_END: - return Sym.getVA(A) - In.Got->getVA() - In.Got->getSize(); - case R_GOT_FROM_END: + case R_GOTPLTREL: + return Sym.getVA(A) - In.GotPlt->getVA(); + case R_GOTPLT: case R_RELAX_TLS_GD_TO_IE_END: - return Sym.getGotOffset() + A - In.Got->getSize(); + return Sym.getGotVA() + A - In.GotPlt->getVA(); case R_TLSLD_GOT_OFF: case R_GOT_OFF: case R_RELAX_TLS_GD_TO_IE_GOT_OFF: @@ -758,12 +758,12 @@ getAArch64Page(P); case R_TLSGD_GOT: return In.Got->getGlobalDynOffset(Sym) + A; - case R_TLSGD_GOT_FROM_END: - return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize(); + case R_TLSGD_GOTPLT: + return In.Got->getVA() + In.Got->getGlobalDynOffset(Sym) + A - In.GotPlt->getVA(); case R_TLSGD_PC: return In.Got->getGlobalDynAddr(Sym) + A - P; - case R_TLSLD_GOT_FROM_END: - return In.Got->getTlsIndexOff() + A - In.Got->getSize(); + case R_TLSLD_GOTPLT: + return In.Got->getVA() + In.Got->getTlsIndexOff() + A - In.GotPlt->getVA(); case R_TLSLD_GOT: return In.Got->getTlsIndexOff() + A; case R_TLSLD_PC: Index: ELF/Relocations.h =================================================================== --- ELF/Relocations.h +++ ELF/Relocations.h @@ -32,13 +32,13 @@ R_ABS, R_ADDEND, R_GOT, - R_GOTONLY_PC, - R_GOTONLY_PC_FROM_END, - R_GOTREL, - R_GOTREL_FROM_END, - R_GOT_FROM_END, R_GOT_OFF, R_GOT_PC, + R_GOTONLY_PC, + R_GOTPLTONLY_PC, + R_GOTPLT, + R_GOTPLTREL, + R_GOTREL, R_HINT, R_NEG_TLS, R_NONE, @@ -61,11 +61,11 @@ R_TLSDESC, R_TLSDESC_CALL, R_TLSGD_GOT, - R_TLSGD_GOT_FROM_END, + R_TLSGD_GOTPLT, R_TLSGD_PC, R_TLSIE_HINT, R_TLSLD_GOT, - R_TLSLD_GOT_FROM_END, + R_TLSLD_GOTPLT, R_TLSLD_GOT_OFF, R_TLSLD_HINT, R_TLSLD_PC, Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -229,7 +229,7 @@ return 1; } - if (oneof( + if (oneof( Expr)) { // Local-Dynamic relocs can be relaxed to Local-Exec. if (!Config->Shared) { @@ -274,7 +274,7 @@ } if (oneof(Expr)) { + R_TLSGD_GOTPLT, R_TLSGD_PC>(Expr)) { if (Config->Shared) { if (In.Got->addDynTlsEntry(Sym)) { uint64_t Off = In.Got->getGlobalDynOffset(Sym); @@ -314,7 +314,7 @@ // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally // defined. - if (oneof(Expr) && !Config->Shared && !Sym.IsPreemptible) { C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym}); @@ -376,13 +376,13 @@ static bool needsGot(RelExpr Expr) { return oneof(Expr); + R_GOT_PC, R_GOTPLT>(Expr); } // True if this expression is of the form Sym - X, where X is a position in the // file (PC, or GOT for example). static bool isRelExpr(RelExpr Expr) { - return oneof(Expr); } @@ -398,11 +398,11 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, InputSectionBase &S, uint64_t RelOff) { // These expressions always compute a constant - if (oneof(E)) return true; @@ -1065,11 +1065,18 @@ Expr = fromPlt(Expr); } - // This relocation does not require got entry, but it is relative to got and - // needs it to be created. Here we request for that. - if (oneof(Expr)) + // If the relocation is relative to GOT or GOTPLT, we need GOT or GOTPLT to be + // created. + if (oneof(Expr)) { + In.GotPlt->HasGotPltOffRel = true; + } else if (oneof(Expr)) { In.Got->HasGotOffRel = true; + } else if (Expr == R_GOTPLT) { + // This x86 and x86_64 specific relocation type is relative to GOTPLT but + // its computation requires .got to exist. + In.GotPlt->HasGotPltOffRel = true; + In.Got->HasGotOffRel = true; + } // Read an addend. int64_t Addend = computeAddend(Rel, End, Sec, Expr, Sym.isLocal()); Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -363,6 +363,10 @@ void writeTo(uint8_t *Buf) override; bool empty() const override; + // Flag to force GotPlt to be in output if we have relocations + // that relies on its address. + bool HasGotPltOffRel = false; + private: std::vector Entries; }; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -650,10 +650,8 @@ bool GotSection::empty() const { // We need to emit a GOT even if it's empty if there's a relocation that is - // relative to GOT(such as GOTOFFREL) or there's a symbol that points to a GOT - // (i.e. _GLOBAL_OFFSET_TABLE_) that the target defines relative to the .got. - return NumEntries == 0 && !HasGotOffRel && - !(ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt); + // relative to GOT(such as GOTOFFREL). + return NumEntries == 0 && !HasGotOffRel; } void GotSection::writeTo(uint8_t *Buf) { @@ -1114,11 +1112,9 @@ } bool GotPltSection::empty() const { - // We need to emit a GOT.PLT even if it's empty if there's a symbol that - // references the _GLOBAL_OFFSET_TABLE_ and the Target defines the symbol - // relative to the .got.plt section. - return Entries.empty() && - !(ElfSym::GlobalOffsetTable && Target->GotBaseSymInGotPlt); + // We need to emit GOTPLT even if it's empty if there's a relocation relative + // to it. + return Entries.empty() && !HasGotPltOffRel; } static StringRef getIgotPltName() { Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -383,6 +383,15 @@ In.IgotPlt = make(); Add(In.IgotPlt); + // _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat + // it as a relocation and ensure the referenced section is created. + if (ElfSym::GlobalOffsetTable && Config->EMachine != EM_MIPS) { + if (Target->GotBaseSymInGotPlt) + In.GotPlt->HasGotPltOffRel = true; + else + In.Got->HasGotOffRel = true; + } + if (Config->GdbIndex) Add(GdbIndexSection::create()); Index: test/ELF/got-i386.s =================================================================== --- test/ELF/got-i386.s +++ test/ELF/got-i386.s @@ -19,7 +19,7 @@ // CHECK: Symbol { // CHECK: Name: bar -// CHECK-NEXT: Value: 0x402000 +// CHECK-NEXT: Value: 0x40200C // CHECK-NEXT: Size: 10 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -28,7 +28,7 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: obj -// CHECK-NEXT: Value: 0x40200A +// CHECK-NEXT: Value: 0x402016 // CHECK-NEXT: Size: 10 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -41,9 +41,9 @@ // 0x40200A + 5 - 15 = addr(.got) = 0x402000 // DISASM: Disassembly of section .text: // DISASM-NEXT: _start: -// DISASM-NEXT: 401000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx) -// DISASM-NEXT: 40100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx) -// DISASM-NEXT: 401014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx) +// DISASM-NEXT: 401000: c7 81 0c 00 00 00 01 00 00 00 movl $1, 12(%ecx) +// DISASM-NEXT: 40100a: c7 81 16 00 00 00 02 00 00 00 movl $2, 22(%ecx) +// DISASM-NEXT: 401014: c7 81 1b 00 00 00 03 00 00 00 movl $3, 27(%ecx) .global _start _start: Index: test/ELF/i386-gotoff-shared.s =================================================================== --- test/ELF/i386-gotoff-shared.s +++ test/ELF/i386-gotoff-shared.s @@ -1,23 +1,15 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared -// RUN: llvm-readobj -s %t.so | FileCheck %s +// RUN: llvm-readelf -S %t.so | FileCheck %s // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s bar: movl bar@GOTOFF(%ebx), %eax mov bar@GOT, %eax -// CHECK: Name: .got -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: SHF_WRITE -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x2050 -// CHECK-NEXT: Offset: 0x2050 -// CHECK-NEXT: Size: 4 +// CHECK: .got.plt PROGBITS 00003000 -// 0x1000 - (0x2050 + 4) = -4180 +// 0x1000 - 0x3000 (.got.plt) = -8192 -// DISASM: 1000: {{.*}} movl -4180(%ebx), %eax +// DISASM: 1000: {{.*}} movl -8192(%ebx), %eax Index: test/ELF/i386-gotpc-dynamic.s =================================================================== --- test/ELF/i386-gotpc-dynamic.s +++ test/ELF/i386-gotpc-dynamic.s @@ -1,28 +1,13 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o # RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared -# RUN: llvm-readobj -s %t.so | FileCheck %s +# RUN: llvm-readelf -S %t.so | FileCheck %s # RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s -# CHECK: Section { -# CHECK: Index: 7 -# CHECK-NEXT: Name: .got -# CHECK-NEXT: Type: SHT_PROGBITS -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_WRITE -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x2030 -# CHECK-NEXT: Offset: -# CHECK-NEXT: Size: -# CHECK-NEXT: Link: -# CHECK-NEXT: Info: -# CHECK-NEXT: AddressAlignment: -# CHECK-NEXT: EntrySize: -# CHECK-NEXT: } +# CHECK: .got.plt PROGBITS 00003000 -## 0x1000 + 4144 = 0x2030 -# DISASM: 1000: {{.*}} movl $4144, %eax +## 0x3000 - 0x1000 = 8192 +# DISASM: 1000: {{.*}} movl $8192, %eax .section .foo,"ax",@progbits foo: Index: test/ELF/i386-gotpc.s =================================================================== --- test/ELF/i386-gotpc.s +++ test/ELF/i386-gotpc.s @@ -1,28 +1,14 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared -// RUN: llvm-readobj -s %t.so | FileCheck %s +// RUN: llvm-readelf -S %t.so | FileCheck %s // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s movl $_GLOBAL_OFFSET_TABLE_, %eax -// CHECK: Name: .got -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: SHF_WRITE -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x2030 - -// CHECK: Name: .got.plt -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: SHF_WRITE -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x3000 +// CHECK: .got.plt PROGBITS 00003000 // DISASM: Disassembly of section .text: // DISASM-NEXT: .text: -// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax -// 0x2030 - 0x1000 = 0x1030 +// DISASM-NEXT: 1000: {{.*}} movl $8192, %eax +// 0x3000 (.got.plt) - 0x1000 = 8192 Index: test/ELF/i386-retpoline-pic-linkerscript.s =================================================================== --- test/ELF/i386-retpoline-pic-linkerscript.s +++ test/ELF/i386-retpoline-pic-linkerscript.s @@ -14,9 +14,9 @@ // CHECK: Disassembly of section .plt: // CHECK-NEXT: .plt: -// CHECK-NEXT: 10: ff b3 ec 00 00 00 pushl 236(%ebx) +// CHECK-NEXT: 10: ff b3 04 00 00 00 pushl 4(%ebx) // CHECK-NEXT: 16: 50 pushl %eax -// CHECK-NEXT: 17: 8b 83 f0 00 00 00 movl 240(%ebx), %eax +// CHECK-NEXT: 17: 8b 83 08 00 00 00 movl 8(%ebx), %eax // CHECK-NEXT: 1d: e8 0e 00 00 00 calll 14 <.plt+0x20> // CHECK-NEXT: 22: f3 90 pause // CHECK-NEXT: 24: 0f ae e8 lfence @@ -36,7 +36,7 @@ // CHECK-NEXT: 3e: c3 retl // CHECK-NEXT: 3f: cc int3 // CHECK-NEXT: 40: 50 pushl %eax -// CHECK-NEXT: 41: 8b 83 f4 00 00 00 movl 244(%ebx), %eax +// CHECK-NEXT: 41: 8b 83 0c 00 00 00 movl 12(%ebx), %eax // CHECK-NEXT: 47: e8 e4 ff ff ff calll -28 <.plt+0x20> // CHECK-NEXT: 4c: e9 d1 ff ff ff jmp -47 <.plt+0x12> // CHECK-NEXT: 51: 68 00 00 00 00 pushl $0 @@ -47,7 +47,7 @@ // CHECK-NEXT: 5e: cc int3 // CHECK-NEXT: 5f: cc int3 // CHECK-NEXT: 60: 50 pushl %eax -// CHECK-NEXT: 61: 8b 83 f8 00 00 00 movl 248(%ebx), %eax +// CHECK-NEXT: 61: 8b 83 10 00 00 00 movl 16(%ebx), %eax // CHECK-NEXT: 67: e8 c4 ff ff ff calll -60 <.plt+0x20> // CHECK-NEXT: 6c: e9 b1 ff ff ff jmp -79 <.plt+0x12> // CHECK-NEXT: 71: 68 08 00 00 00 pushl $8 Index: test/ELF/i386-retpoline-pic.s =================================================================== --- test/ELF/i386-retpoline-pic.s +++ test/ELF/i386-retpoline-pic.s @@ -8,9 +8,9 @@ // CHECK: Disassembly of section .plt: // CHECK-NEXT: .plt: -// CHECK-NEXT: 1010: ff b3 04 30 00 00 pushl 12292(%ebx) +// CHECK-NEXT: 1010: ff b3 04 00 00 00 pushl 4(%ebx) // CHECK-NEXT: 1016: 50 pushl %eax -// CHECK-NEXT: 1017: 8b 83 08 30 00 00 movl 12296(%ebx), %eax +// CHECK-NEXT: 1017: 8b 83 08 00 00 00 movl 8(%ebx), %eax // CHECK-NEXT: 101d: e8 0e 00 00 00 calll 14 <.plt+0x20> // CHECK-NEXT: 1022: f3 90 pause // CHECK-NEXT: 1024: 0f ae e8 lfence @@ -30,7 +30,7 @@ // CHECK-NEXT: 103e: c3 retl // CHECK-NEXT: 103f: cc int3 // CHECK-NEXT: 1040: 50 pushl %eax -// CHECK-NEXT: 1041: 8b 83 0c 30 00 00 movl 12300(%ebx), %eax +// CHECK-NEXT: 1041: 8b 83 0c 00 00 00 movl 12(%ebx), %eax // CHECK-NEXT: 1047: e8 e4 ff ff ff calll -28 <.plt+0x20> // CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12> // CHECK-NEXT: 1051: 68 00 00 00 00 pushl $0 @@ -41,7 +41,7 @@ // CHECK-NEXT: 105e: cc int3 // CHECK-NEXT: 105f: cc int3 // CHECK-NEXT: 1060: 50 pushl %eax -// CHECK-NEXT: 1061: 8b 83 10 30 00 00 movl 12304(%ebx), %eax +// CHECK-NEXT: 1061: 8b 83 10 00 00 00 movl 16(%ebx), %eax // CHECK-NEXT: 1067: e8 c4 ff ff ff calll -60 <.plt+0x20> // CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12> // CHECK-NEXT: 1071: 68 08 00 00 00 pushl $8 Index: test/ELF/plt-i686.s =================================================================== --- test/ELF/plt-i686.s +++ test/ELF/plt-i686.s @@ -139,31 +139,35 @@ // 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 30 00 00 pushl 12292(%ebx) -// DISASMSHARED-NEXT: 1026: ff a3 08 30 00 00 jmpl *12296(%ebx) +// 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: 102c: 90 nop // DISASMSHARED-NEXT: 102d: 90 nop // DISASMSHARED-NEXT: 102e: 90 nop // DISASMSHARED-NEXT: 102f: 90 nop -// DISASMSHARED-NEXT: 1030: ff a3 0c 30 00 00 jmpl *12300(%ebx) +// DISASMSHARED: bar@plt: +// DISASMSHARED-NEXT: 1030: ff a3 0c 00 00 00 jmpl *12(%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 30 00 00 jmpl *12304(%ebx) +// DISASMSHARED: zed@plt: +// DISASMSHARED-NEXT: 1040: ff a3 10 00 00 00 jmpl *16(%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 30 00 00 pushl 12292(%ebx) -// DISASMPIE-NEXT: 1026: ff a3 08 30 00 00 jmpl *12296(%ebx) +// 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: 102c: 90 nop // DISASMPIE-NEXT: 102d: 90 nop // DISASMPIE-NEXT: 102e: 90 nop // DISASMPIE-NEXT: 102f: 90 nop -// DISASMPIE-NEXT: 1030: ff a3 0c 30 00 00 jmpl *12300(%ebx) +// DISASMPIE: bar@plt: +// DISASMPIE-NEXT: 1030: ff a3 0c 00 00 00 jmpl *12(%ebx) // DISASMPIE-NEXT: 1036: 68 00 00 00 00 pushl $0 // DISASMPIE-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt> -// DISASMPIE-NEXT: 1040: ff a3 10 30 00 00 jmpl *12304(%ebx) +// DISASMPIE: zed@plt: +// DISASMPIE-NEXT: 1040: ff a3 10 00 00 00 jmpl *16(%ebx) // DISASMPIE-NEXT: 1046: 68 08 00 00 00 pushl $8 // DISASMPIE-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt> Index: test/ELF/relocation-i686.s =================================================================== --- test/ELF/relocation-i686.s +++ test/ELF/relocation-i686.s @@ -49,25 +49,25 @@ // ADDR-NEXT: Offset: 0x1040 // ADDR-NEXT: Size: 32 -// ADDR: Name: .got ( +// ADDR: Name: .got.plt ( // ADDR-NEXT: Type: SHT_PROGBITS // ADDR-NEXT: Flags [ // ADDR-NEXT: SHF_ALLOC // ADDR-NEXT: SHF_WRITE // ADDR-NEXT: ] -// ADDR-NEXT: Address: 0x402078 +// ADDR-NEXT: Address: 0x403000 // ADDR-NEXT: Offset: -// ADDR-NEXT: Size: 8 +// ADDR-NEXT: Size: .section .R_386_GOTPC,"ax",@progbits R_386_GOTPC: movl $_GLOBAL_OFFSET_TABLE_, %eax -// 0x402078 + 8 - 0x401014 = 8300 +// 0x403000 (.got.plt) - 0x401014 = 8300 // CHECK: Disassembly of section .R_386_GOTPC: // CHECK-NEXT: R_386_GOTPC: -// CHECK-NEXT: 401014: {{.*}} movl $4204, %eax +// CHECK-NEXT: 401014: {{.*}} movl $8172, %eax .section .dynamic_reloc, "ax",@progbits call bar Index: test/ELF/shared.s =================================================================== --- test/ELF/shared.s +++ test/ELF/shared.s @@ -46,7 +46,7 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[DYNSYMADDR:.*]] -// CHECK-NEXT: Offset: 0x150 +// CHECK-NEXT: Offset: 0x170 // CHECK-NEXT: Size: // CHECK-NEXT: Link: [[DYNSTR:.*]] // CHECK-NEXT: Info: 1 Index: test/ELF/tls-dynamic-i686.s =================================================================== --- test/ELF/tls-dynamic-i686.s +++ test/ELF/tls-dynamic-i686.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t -// RUN: ld.lld --hash-style=sysv -shared %t -o %tout +// RUN: ld.lld --hash-style=sysv -shared -z norelro %t -o %tout // RUN: llvm-readobj -sections -relocations %tout | FileCheck %s // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS Index: test/ELF/x86-64-reloc-gotoff64.s =================================================================== --- test/ELF/x86-64-reloc-gotoff64.s +++ test/ELF/x86-64-reloc-gotoff64.s @@ -5,13 +5,7 @@ // RUN: llvm-objdump -d %t.so | FileCheck %s // SECTION: .dynamic DYNAMIC 0000000000002000 -// SECTION: .got PROGBITS 0000000000002070 002070 000000 - -// All the _GLOBAL_OFFSET_TABLE_ occurrences below refer to the address -// of GOT base, not the address of the symbol _GLOBAL_OFFSET_TABLE_. These -// instructions are special and produce GOT base relative relocations. We -// currently use .got end as the GOT base, which is not equal to -// the address of the special symbol _GLOBAL_OFFSET_TABLE_. +// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018 // The assembly is generated by // gcc -O2 -S -mcmodel=medium -fPIC a.c @@ -20,10 +14,10 @@ // extern long _DYNAMIC[] __attribute__((visibility("hidden"))); // long* dynamic() { return _DYNAMIC; } -// 0x2070 (.got end) - 0x1007 = 4201 -// 0x2000 (_DYNAMIC) - 0x2070 (.got end) = -112 -// CHECK: 1000: {{.*}} leaq 4201(%rip), %rdx -// CHECK-NEXT: 1007: {{.*}} movabsq $-112, %rax +// 0x3000 (.got.plt) - 0x1007 = 8185 +// 0x2000 (_DYNAMIC) - 0x3000 (.got.plt) = -4096 +// CHECK: 1000: {{.*}} leaq 8185(%rip), %rdx +// CHECK-NEXT: 1007: {{.*}} movabsq $-4096, %rax .global dynamic dynamic: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx Index: test/ELF/x86-64-reloc-gotpc64.s =================================================================== --- test/ELF/x86-64-reloc-gotpc64.s +++ test/ELF/x86-64-reloc-gotpc64.s @@ -4,11 +4,11 @@ // RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION // RUN: llvm-objdump -d %t.so | FileCheck %s -// SECTION: .got PROGBITS 0000000000002070 002070 000000 +// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018 -// 0x2070 (.got end) - 0x1000 = 4208 +// 0x3000 (.got.plt) - 0x1000 = 8192 // CHECK: gotpc64: -// CHECK-NEXT: 1000: {{.*}} movabsq $4208, %r11 +// CHECK-NEXT: 1000: {{.*}} movabsq $8192, %r11 .global gotpc64 gotpc64: movabsq $_GLOBAL_OFFSET_TABLE_-., %r11