Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -144,8 +144,11 @@ } uint64_t Symbol::getPltVA() const { - if (this->IsInIplt) + if (this->IsInIplt) { + if (Config->ZRetpolineplt) + return In.Iplt->getVA() + Target->getPltEntryOffset(PltIndex); return In.Iplt->getVA() + PltIndex * Target->PltEntrySize; + } return In.Plt->getVA() + Target->getPltEntryOffset(PltIndex); } Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2280,7 +2280,8 @@ PltSection::PltSection(bool IsIplt) : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, Config->EMachine == EM_PPC64 ? ".glink" : ".plt"), - HeaderSize(IsIplt ? 0 : Target->PltHeaderSize), IsIplt(IsIplt) { + HeaderSize(IsIplt && !Config->ZRetpolineplt ? 0 : Target->PltHeaderSize), + IsIplt(IsIplt) { // The PLT needs to be writable on SPARC as the dynamic linker will // modify the instructions in the PLT entries. if (Config->EMachine == EM_SPARCV9) @@ -2290,7 +2291,7 @@ void PltSection::writeTo(uint8_t *Buf) { // At beginning of PLT but not the IPLT, we have code to call the dynamic // linker to resolve dynsyms at runtime. Write such code. - if (!IsIplt) + if (!IsIplt || Config->ZRetpolineplt) Target->writePltHeader(Buf); size_t Off = HeaderSize; // The IPlt is immediately after the Plt, account for this in RelOff Index: test/ELF/x86-64-retpoline-znow-static-iplt.s =================================================================== --- /dev/null +++ test/ELF/x86-64-retpoline-znow-static-iplt.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -z retpolineplt -z now %t.o -o %t +# RUN: llvm-objdump -d -no-show-raw-insn %t | FileCheck %s + +#0x201001+5 + 42 = 0x201030 (foo@plt) +# CHECK: _start: +# CHECK-NEXT: 201001: callq 42 + +#Static IPLT header due to -z retpolineplt +# CHECK: {{^}}.plt: +# CHECK-NEXT: 201010: callq 11 <.plt+0x10> +# CHECK-NEXT: 201015: pause +# CHECK-NEXT: 201017: lfence +#foo@plt +# CHECK: 201030: movq 4041(%rip), %r11 +# CHECK-NEXT: 201037: jmp -44 <.plt> + +.type foo STT_GNU_IFUNC +.globl foo +foo: + ret + +.globl _start +_start: + call foo