[lld] r364639 - [ELF] Do not produce DT_JMPREL and DT_PLTGOT if .rela.plt is empty.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 28 03:14:15 PDT 2019


Author: ikudrin
Date: Fri Jun 28 03:14:14 2019
New Revision: 364639

URL: http://llvm.org/viewvc/llvm-project?rev=364639&view=rev
Log:
[ELF] Do not produce DT_JMPREL and DT_PLTGOT if .rela.plt is empty.

If .rela.plt is mentioned in a linker script, it might be preserved
even if it is empty. In that case, LLD created DT_JMPREL and DT_PLTGOT
dynamic tags. When the tags exist, a dynamic loader writes values into
reserved slots in .got.plt to support lazy symbol resolution.
The problem is that, in fact, the linker has not reserved that space,
and the writing may occur into the memory allocated for something else.

Differential Revision: https://reviews.llvm.org/D63869

Added:
    lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test
Modified:
    lld/trunk/ELF/SyntheticSections.cpp

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=364639&r1=364638&r2=364639&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Jun 28 03:14:14 2019
@@ -1339,7 +1339,7 @@ template <class ELFT> void DynamicSectio
   // 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) {

Added: lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test?rev=364639&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test (added)
+++ lld/trunk/test/ELF/linkerscript/empty-relaplt-dyntags.test Fri Jun 28 03:14:14 2019
@@ -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
+}




More information about the llvm-commits mailing list