[PATCH] D23565: [ELF] Linkerscript: fix relocation offsets

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 16 08:38:53 PDT 2016


evgeny777 created this revision.
evgeny777 added a reviewer: ruiu.
evgeny777 added subscribers: grimar, ikudrin, emaste, davide, llvm-commits.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.

Now, when we assign scripted sections offsets in assignAddresses, we should also fix relocation offsets there, because input section offset is used to calculate relocation offset.
When linker script is used scanRelocs adds relocation entries which offsets begin from the start of input section. We fix them in fixStaticRelocs() and fixDynamicRelocs() by means of adding input section offset, so relocation offset becomes an offset from beginning of output section - the way it should be. 

Repository:
  rL LLVM

https://reviews.llvm.org/D23565

Files:
  ELF/LinkerScript.cpp
  ELF/OutputSections.h

Index: ELF/OutputSections.h
===================================================================
--- ELF/OutputSections.h
+++ ELF/OutputSections.h
@@ -237,9 +237,13 @@
         UseSymVA(UseSymVA), Addend(Addend) {}
 
   uintX_t getOffset() const;
+  void setSectionOffset(uintX_t Offset) { OffsetInSec = Offset; }
   uintX_t getAddend() const;
   uint32_t getSymIndex() const;
-  const OutputSectionBase<ELFT> *getOutputSec() const { return OutputSec; }
+  const OutputSectionBase<ELFT> *getOutputSec() const {
+    return OutputSec ? OutputSec : InputSec->OutSec;
+  }
+  const InputSectionBase<ELFT> *getInputSec() const { return InputSec; }
 
   uint32_t Type;
 
@@ -379,9 +383,10 @@
   typename Base::Kind getKind() const override { return Base::Reloc; }
   static bool classof(const Base *B) { return B->getKind() == Base::Reloc; }
 
+  std::vector<DynamicReloc<ELFT>> Relocs;
+
 private:
   bool Sort;
-  std::vector<DynamicReloc<ELFT>> Relocs;
 };
 
 template <class ELFT>
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -304,6 +304,19 @@
   }
 }
 
+template <class ELFT> static void fixStaticRelocs(InputSection<ELFT> *I) {
+  for (Relocation<ELFT> &R : I->Relocations)
+    R.Offset += I->OutSecOff;
+}
+
+template <class ELFT>
+static void fixDynamicRelocs(OutputSectionBase<ELFT> *OutSec) {
+  for (DynamicReloc<ELFT> &D : Out<ELFT>::RelaDyn->Relocs)
+    if (D.getOutputSec() == OutSec)
+      D.setSectionOffset(D.getOffset() +
+                         cast<InputSection<ELFT>>(D.getInputSec())->OutSecOff);
+}
+
 template <class ELFT> void assignOffsets(OutputSectionBase<ELFT> *Sec) {
   auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec);
   if (!OutSec) {
@@ -330,12 +343,14 @@
       Off = alignTo(Off, I->Alignment);
       I->OutSecOff = Off;
       Off += I->getSize();
+      fixStaticRelocs(I);
     }
     // Update section size inside for-loop, so that SIZEOF
     // works correctly in the case below:
     // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
     Sec->setSize(Off);
   }
+  fixDynamicRelocs(Sec);
 }
 
 template <class ELFT>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23565.68191.patch
Type: text/x-patch
Size: 2162 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160816/3eb672c8/attachment.bin>


More information about the llvm-commits mailing list