[PATCH] D56623: Do not emit a corrupt symbol table entry for .rela_iplt_{start, end}.

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 11 16:57:10 PST 2019


ruiu created this revision.
ruiu added reviewers: grimar, MaskRay.
Herald added subscribers: arichardson, emaste.
Herald added a reviewer: espindola.

If .rela.iplt does not exist, we used to emit a corrupt symbol table
that contains two symbols, .rela_iplt_{start,end}, pointing to a
nonexisting section.

This patch fixes the issue by setting section index 0 to the symbols
if .rel.iplt section does not exist.


https://reviews.llvm.org/D56623

Files:
  lld/ELF/Symbols.cpp
  lld/ELF/Symbols.h
  lld/ELF/Writer.cpp
  lld/test/ELF/gnu-ifunc-empty.s


Index: lld/test/ELF/gnu-ifunc-empty.s
===================================================================
--- /dev/null
+++ lld/test/ELF/gnu-ifunc-empty.s
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+
+// Verifies that .rela_iplt_{start,end} point to a dummy section
+// if .rela.iplt does not exist.
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %t.exe
+// RUN: llvm-objdump -syms %t.exe | FileCheck %s
+
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_end
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_start
+
+.globl _start
+_start:
+ movl $__rela_iplt_start, %edx
+ movl $__rela_iplt_end, %edx
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -911,7 +911,8 @@
   if (Config->Relocatable || needsInterpSection())
     return;
   StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
+  ElfSym::RelaIpltStart =
+      addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 
   S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
   ElfSym::RelaIpltEnd =
@@ -949,8 +950,19 @@
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 
-  if (ElfSym::RelaIpltEnd)
-    ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
+  // .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
+  if (ElfSym::RelaIpltStart) {
+    uint64_t Size = In.RelaIplt->getSize();
+    ElfSym::RelaIpltEnd->Value = Size;
+
+    // If .rela.plt does not exist, use a dummy section value. The loader
+    // reads data between the start and the end symbols, so as long as the two
+    // symbols point to the same location, their actual locations don't matter.
+    if (Size == 0) {
+      ElfSym::RelaIpltStart->Section = Out::ElfHeader;
+      ElfSym::RelaIpltEnd->Section = Out::ElfHeader;
+    }
+  }
 
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
Index: lld/ELF/Symbols.h
===================================================================
--- lld/ELF/Symbols.h
+++ lld/ELF/Symbols.h
@@ -352,7 +352,8 @@
   static Defined *MipsGpDisp;
   static Defined *MipsLocalGp;
 
-  // __rela_iplt_end or __rel_iplt_end
+  // __rel{,a}_iplt_{start,end} symbols.
+  static Defined *RelaIpltStart;
   static Defined *RelaIpltEnd;
 };
 
Index: lld/ELF/Symbols.cpp
===================================================================
--- lld/ELF/Symbols.cpp
+++ lld/ELF/Symbols.cpp
@@ -38,6 +38,7 @@
 Defined *ElfSym::MipsGp;
 Defined *ElfSym::MipsGpDisp;
 Defined *ElfSym::MipsLocalGp;
+Defined *ElfSym::RelaIpltStart;
 Defined *ElfSym::RelaIpltEnd;
 
 static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56623.181398.patch
Type: text/x-patch
Size: 2787 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190112/b6a6708d/attachment.bin>


More information about the llvm-commits mailing list