Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1339,7 +1339,7 @@ // as RelaIplt have. And we still want to emit proper dynamic tags for that // case, so here we always use RelaPlt as marker for the begining of // .rel[a].plt section. - if (IsMain && In.RelaPlt->getParent()->isLive()) { + if (IsMain && (In.RelaPlt->isNeeded() || In.RelaIplt->isNeeded())) { addInSec(DT_JMPREL, In.RelaPlt); Entries.push_back({DT_PLTRELSZ, addPltRelSz}); switch (Config->EMachine) { Index: lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test =================================================================== --- lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test +++ lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -shared %t.o -T %s -o %t +# RUN: llvm-readobj --dynamic-table --sections %t | FileCheck %s + +## In spite of .rela.plt is empty, it might have been preserved because it is +## mentioned in the linker script. However, even in that case, we should not +## produce DT_JMPREL and DT_PLTGOT tags because this can cause a dynamic loader +## to write into slots in .got.plt it considers reserved to support lazy symbol +## resolution. In fact, as .got.plt is also empty, that memory might be +## allocated for something else. + +# CHECK: Sections [ +# CHECK: Name: .rela.plt +# CHECK-NEXT: Type: SHT_RELA +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: 0 +# 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: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: 0 + +# CHECK: DynamicSection [ +# CHECK-NOT: JMPREL +# CHECK-NOT: PLTGOT + +PHDRS { + all PT_LOAD; + dyn PT_DYNAMIC; +} +SECTIONS { + .rela.plt : { *(.rela.plt) }: all + .dynamic : { *(.dynamic) }: all : dyn + .got.plt : {*(.got.plt)}: all +}