[PATCH] D54985: [ELF] Keep empty In.RelaIplt so that __rela_iplt_{start, end} have valid st_shndx

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 27 18:13:56 PST 2018


MaskRay created this revision.
Herald added subscribers: llvm-commits, krytarowski, arichardson, emaste.
Herald added a reviewer: espindola.

This fixes PR36634 (and https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=233397)

In a statically linked executable, if __rela_iplt_{start,end} are
defined with non-existent .rela.plt (In.RelaIplt), the symbols' st_shndx
are 65535 (SHN_XINDEX) which may confuse readelf, objdump, llvm-objdump,
llvm-readelf and some other binutils because the extended symbol table
may not exist.

ld.bfd and gold do not emit empty .rela.plt but seem to use arbitrary
st_shndx for __rela_iplt_{start,end}. We can just emit the empty
.rela.plt .


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D54985

Files:
  ELF/SyntheticSections.cpp
  ELF/SyntheticSections.h
  ELF/Writer.cpp


Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -396,6 +396,7 @@
           ? ".rel.dyn"
           : In.RelaPlt->Name,
       false /*Sort*/);
+  In.RelaIplt->IsIplt = true;
   Add(In.RelaIplt);
 
   In.Plt = make<PltSection>(false);
Index: ELF/SyntheticSections.h
===================================================================
--- ELF/SyntheticSections.h
+++ ELF/SyntheticSections.h
@@ -481,12 +481,17 @@
                 uint64_t OffsetInSec, Symbol *Sym, int64_t Addend, RelExpr Expr,
                 RelType Type);
   void addReloc(const DynamicReloc &Reloc);
-  bool empty() const override { return Relocs.empty(); }
+  bool empty() const override { return Relocs.empty() && !IsIplt; }
   size_t getSize() const override { return Relocs.size() * this->Entsize; }
   size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
   void finalizeContents() override;
+
   int32_t DynamicTag, SizeDynamicTag;
 
+  // Used to keep empty .rela.iplt as otherwise __rela_iplt_start would have an
+  // invalid st_shndx.
+  bool IsIplt = false;
+
 protected:
   std::vector<DynamicReloc> Relocs;
   size_t NumRelativeRelocs = 0;
Index: ELF/SyntheticSections.cpp
===================================================================
--- ELF/SyntheticSections.cpp
+++ ELF/SyntheticSections.cpp
@@ -1496,8 +1496,11 @@
   InputSection *SymTab = Config->Relocatable ? In.SymTab : In.DynSymTab;
   getParent()->Link = SymTab ? SymTab->getParent()->SectionIndex : 0;
 
-  if (In.RelaIplt == this || In.RelaPlt == this)
-    getParent()->Info = In.GotPlt->getParent()->SectionIndex;
+  if (In.RelaIplt == this || In.RelaPlt == this) {
+    uint32_t I = In.GotPlt->getParent()->SectionIndex;
+    if (I != UINT32_MAX)
+      getParent()->Info = I;
+  }
 }
 
 RelrBaseSection::RelrBaseSection()


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54985.175613.patch
Type: text/x-patch
Size: 1875 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181128/9dc3533c/attachment.bin>


More information about the llvm-commits mailing list