<div dir="ltr">Thanks!<div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 21, 2015 at 3:01 PM, Rafael Espindola via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Mon Sep 21 17:01:00 2015<br>
New Revision: 248215<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=248215&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=248215&view=rev</a><br>
Log:<br>
Make InputSection able to relocate itself.<br>
<br>
This matches the organization used in COFF.<br>
<br>
Modified:<br>
    lld/trunk/ELF/Chunks.cpp<br>
    lld/trunk/ELF/Chunks.h<br>
    lld/trunk/ELF/OutputSections.cpp<br>
    lld/trunk/ELF/OutputSections.h<br>
<br>
Modified: lld/trunk/ELF/Chunks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.cpp?rev=248215&r1=248214&r2=248215&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.cpp?rev=248215&r1=248214&r2=248215&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Chunks.cpp (original)<br>
+++ lld/trunk/ELF/Chunks.cpp Mon Sep 21 17:01:00 2015<br>
@@ -10,9 +10,13 @@<br>
 #include "Chunks.h"<br>
 #include "Error.h"<br>
 #include "InputFiles.h"<br>
+#include "OutputSections.h"<br>
+<br>
+#include "llvm/Support/raw_ostream.h"<br>
<br>
 using namespace llvm;<br>
 using namespace llvm::ELF;<br>
+using namespace llvm::object;<br>
<br>
 using namespace lld;<br>
 using namespace lld::elf2;<br>
@@ -21,12 +25,134 @@ template <class ELFT><br>
 InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)<br>
     : File(F), Header(Header) {}<br>
<br>
-template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {<br>
+template <class ELFT><br>
+void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,<br>
+                                     uint32_t Type, uintX_t BaseAddr,<br>
+                                     uintX_t SymVA) {<br>
+  uintX_t Offset = Rel.r_offset;<br>
+  uint8_t *Location = Buf + Offset;<br>
+  switch (Type) {<br>
+  case R_386_32:<br>
+    support::endian::write32le(Location, SymVA);<br>
+    break;<br>
+  default:<br>
+    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';<br>
+    break;<br>
+  }<br>
+}<br>
+<br>
+template <class ELFT><br>
+void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,<br>
+                                     uint32_t Type, uintX_t BaseAddr,<br>
+                                     uintX_t SymVA) {<br>
+  uintX_t Offset = Rel.r_offset;<br>
+  uint8_t *Location = Buf + Offset;<br>
+  switch (Type) {<br>
+  case R_X86_64_PC32:<br>
+    support::endian::write32le(Location,<br>
+                               SymVA + (Rel.r_addend - (BaseAddr + Offset)));<br>
+    break;<br>
+  case R_X86_64_64:<br>
+    support::endian::write64le(Location, SymVA + Rel.r_addend);<br>
+    break;<br>
+  case R_X86_64_32: {<br>
+  case R_X86_64_32S:<br>
+    uint64_t VA = SymVA + Rel.r_addend;<br>
+    if (Type == R_X86_64_32 && !isUInt<32>(VA))<br>
+      error("R_X86_64_32 out of range");<br>
+    else if (!isInt<32>(VA))<br>
+      error("R_X86_64_32S out of range");<br>
+<br>
+    support::endian::write32le(Location, VA);<br>
+    break;<br>
+  }<br>
+  default:<br>
+    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';<br>
+    break;<br>
+  }<br>
+}<br>
+<br>
+template <class ELFT><br>
+template <bool isRela><br>
+void InputSection<ELFT>::relocate(<br>
+    uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,<br>
+    const ObjectFile<ELFT> &File, uintX_t BaseAddr,<br>
+    const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec) {<br>
+  typedef Elf_Rel_Impl<ELFT, isRela> RelType;<br>
+  bool IsMips64EL = File.getObj()->isMips64EL();<br>
+  for (const RelType &RI : Rels) {<br>
+    uint32_t SymIndex = RI.getSymbol(IsMips64EL);<br>
+    uint32_t Type = RI.getType(IsMips64EL);<br>
+    uintX_t SymVA;<br>
+<br>
+    // Handle relocations for local symbols -- they never get<br>
+    // resolved so we don't allocate a SymbolBody.<br>
+    const Elf_Shdr *SymTab = File.getSymbolTable();<br>
+    if (SymIndex < SymTab->sh_info) {<br>
+      const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab);<br>
+      if (!Sym)<br>
+        continue;<br>
+      SymVA = getLocalSymVA(Sym, File);<br>
+    } else {<br>
+      const SymbolBody *Body = File.getSymbolBody(SymIndex);<br>
+      if (!Body)<br>
+        continue;<br>
+      switch (Body->kind()) {<br>
+      case SymbolBody::DefinedRegularKind:<br>
+        SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));<br>
+        break;<br>
+      case SymbolBody::DefinedAbsoluteKind:<br>
+        SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;<br>
+        break;<br>
+      case SymbolBody::DefinedCommonKind: {<br>
+        auto *DC = cast<DefinedCommon<ELFT>>(Body);<br>
+        SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;<br>
+        break;<br>
+      }<br>
+      case SymbolBody::SharedKind:<br>
+        if (relocNeedsPLT(Type)) {<br>
+          SymVA = PltSec.getEntryAddr(*Body);<br>
+          Type = R_X86_64_PC32;<br>
+        } else if (relocNeedsGOT(Type)) {<br>
+          SymVA = GotSec.getEntryAddr(*Body);<br>
+          Type = R_X86_64_PC32;<br>
+        } else {<br>
+          continue;<br>
+        }<br>
+        break;<br>
+      case SymbolBody::UndefinedKind:<br>
+        assert(Body->isWeak() && "Undefined symbol reached writer");<br>
+        SymVA = 0;<br>
+        break;<br>
+      case SymbolBody::LazyKind:<br>
+        llvm_unreachable("Lazy symbol reached writer");<br>
+      }<br>
+    }<br>
+<br>
+    relocateOne(Buf, RI, Type, BaseAddr, SymVA);<br>
+  }<br>
+}<br>
+<br>
+template <class ELFT><br>
+void InputSection<ELFT>::writeTo(uint8_t *Buf, const PltSection<ELFT> &PltSec,<br>
+                                 const GotSection<ELFT> &GotSec) {<br>
   if (Header->sh_type == SHT_NOBITS)<br>
     return;<br>
   // Copy section contents from source object file to output file.<br>
   ArrayRef<uint8_t> Data = *File->getObj()->getSectionContents(Header);<br>
   memcpy(Buf + OutputSectionOff, Data.data(), Data.size());<br>
+<br>
+  const ObjectFile<ELFT> *File = getFile();<br>
+  ELFFile<ELFT> *EObj = File->getObj();<br>
+  uint8_t *Base = Buf + getOutputSectionOff();<br>
+  uintX_t BaseAddr = Out->getVA() + getOutputSectionOff();<br>
+  // Iterate over all relocation sections that apply to this section.<br>
+  for (const Elf_Shdr *RelSec : RelocSections) {<br>
+    if (RelSec->sh_type == SHT_RELA)<br>
+      relocate(Base, EObj->relas(RelSec), *File, BaseAddr, PltSec, GotSec);<br>
+    else<br>
+      relocate(Base, EObj->rels(RelSec), *File, BaseAddr, PltSec, GotSec);<br>
+  }<br>
 }<br>
<br>
 template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {<br>
<br>
Modified: lld/trunk/ELF/Chunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.h?rev=248215&r1=248214&r2=248215&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.h?rev=248215&r1=248214&r2=248215&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Chunks.h (original)<br>
+++ lld/trunk/ELF/Chunks.h Mon Sep 21 17:01:00 2015<br>
@@ -18,12 +18,15 @@ namespace elf2 {<br>
<br>
 template <class ELFT> class ObjectFile;<br>
 template <class ELFT> class OutputSection;<br>
+template <class ELFT> class PltSection;<br>
+template <class ELFT> class GotSection;<br>
<br>
 // A chunk corresponding a section of an input file.<br>
 template <class ELFT> class InputSection {<br>
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;<br>
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;<br>
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;<br>
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;<br>
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;<br>
<br>
 public:<br>
@@ -34,7 +37,8 @@ public:<br>
<br>
   // Write this chunk to a mmap'ed file, assuming Buf is pointing to<br>
   // beginning of the output section.<br>
-  void writeTo(uint8_t *Buf);<br>
+  void writeTo(uint8_t *Buf, const PltSection<ELFT> &PltSec,<br>
+               const GotSection<ELFT> &GotSec);<br>
<br>
   StringRef getSectionName() const;<br>
   const Elf_Shdr *getSectionHdr() const { return Header; }<br>
@@ -56,6 +60,18 @@ public:<br>
   SmallVector<const Elf_Shdr *, 1> RelocSections;<br>
<br>
 private:<br>
+  void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,<br>
+                   uintX_t BaseAddr, uintX_t SymVA);<br>
+  void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,<br>
+                   uintX_t BaseAddr, uintX_t SymVA);<br>
+<br>
+  template <bool isRela><br>
+  void relocate(uint8_t *Buf,<br>
+                llvm::iterator_range<<br>
+                    const llvm::object::Elf_Rel_Impl<ELFT, isRela> *> Rels,<br>
+                const ObjectFile<ELFT> &File, uintX_t BaseAddr,<br>
+                const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec);<br>
+<br>
   // The offset from beginning of the output sections this chunk was assigned<br>
   // to. The writer sets a value.<br>
   uint64_t OutputSectionOff = 0;<br>
<br>
Modified: lld/trunk/ELF/OutputSections.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=248215&r1=248214&r2=248215&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=248215&r1=248214&r2=248215&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.cpp (original)<br>
+++ lld/trunk/ELF/OutputSections.cpp Mon Sep 21 17:01:00 2015<br>
@@ -260,53 +260,6 @@ void OutputSection<ELFT>::addChunk(Input<br>
 }<br>
<br>
 template <class ELFT><br>
-void OutputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,<br>
-                                      uint32_t Type, uintX_t BaseAddr,<br>
-                                      uintX_t SymVA) {<br>
-  uintX_t Offset = Rel.r_offset;<br>
-  uint8_t *Location = Buf + Offset;<br>
-  switch (Type) {<br>
-  case R_386_32:<br>
-    support::endian::write32le(Location, SymVA);<br>
-    break;<br>
-  default:<br>
-    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';<br>
-    break;<br>
-  }<br>
-}<br>
-<br>
-template <class ELFT><br>
-void OutputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,<br>
-                                      uint32_t Type, uintX_t BaseAddr,<br>
-                                      uintX_t SymVA) {<br>
-  uintX_t Offset = Rel.r_offset;<br>
-  uint8_t *Location = Buf + Offset;<br>
-  switch (Type) {<br>
-  case R_X86_64_PC32:<br>
-    support::endian::write32le(Location,<br>
-                               SymVA + (Rel.r_addend - (BaseAddr + Offset)));<br>
-    break;<br>
-  case R_X86_64_64:<br>
-    support::endian::write64le(Location, SymVA + Rel.r_addend);<br>
-    break;<br>
-  case R_X86_64_32: {<br>
-  case R_X86_64_32S:<br>
-    uint64_t VA = SymVA + Rel.r_addend;<br>
-    if (Type == R_X86_64_32 && !isUInt<32>(VA))<br>
-      error("R_X86_64_32 out of range");<br>
-    else if (!isInt<32>(VA))<br>
-      error("R_X86_64_32S out of range");<br>
-<br>
-    support::endian::write32le(Location, VA);<br>
-    break;<br>
-  }<br>
-  default:<br>
-    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';<br>
-    break;<br>
-  }<br>
-}<br>
-<br>
-template <class ELFT><br>
 typename ELFFile<ELFT>::uintX_t<br>
 lld::elf2::getSymVA(const DefinedRegular<ELFT> *DR) {<br>
   const InputSection<ELFT> *SC = &DR->Section;<br>
@@ -329,81 +282,9 @@ lld::elf2::getLocalSymVA(const typename<br>
   return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;<br>
 }<br>
<br>
-template <class ELFT><br>
-template <bool isRela><br>
-void OutputSection<ELFT>::relocate(<br>
-    uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,<br>
-    const ObjectFile<ELFT> &File, uintX_t BaseAddr) {<br>
-  typedef Elf_Rel_Impl<ELFT, isRela> RelType;<br>
-  bool IsMips64EL = File.getObj()->isMips64EL();<br>
-  for (const RelType &RI : Rels) {<br>
-    uint32_t SymIndex = RI.getSymbol(IsMips64EL);<br>
-    uint32_t Type = RI.getType(IsMips64EL);<br>
-    uintX_t SymVA;<br>
-<br>
-    // Handle relocations for local symbols -- they never get<br>
-    // resolved so we don't allocate a SymbolBody.<br>
-    const Elf_Shdr *SymTab = File.getSymbolTable();<br>
-    if (SymIndex < SymTab->sh_info) {<br>
-      const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab);<br>
-      if (!Sym)<br>
-        continue;<br>
-      SymVA = getLocalSymVA(Sym, File);<br>
-    } else {<br>
-      const SymbolBody *Body = File.getSymbolBody(SymIndex);<br>
-      if (!Body)<br>
-        continue;<br>
-      switch (Body->kind()) {<br>
-      case SymbolBody::DefinedRegularKind:<br>
-        SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));<br>
-        break;<br>
-      case SymbolBody::DefinedAbsoluteKind:<br>
-        SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;<br>
-        break;<br>
-      case SymbolBody::DefinedCommonKind: {<br>
-        auto *DC = cast<DefinedCommon<ELFT>>(Body);<br>
-        SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;<br>
-        break;<br>
-      }<br>
-      case SymbolBody::SharedKind:<br>
-        if (relocNeedsPLT(Type)) {<br>
-          SymVA = PltSec.getEntryAddr(*Body);<br>
-          Type = R_X86_64_PC32;<br>
-        } else if (relocNeedsGOT(Type)) {<br>
-          SymVA = GotSec.getEntryAddr(*Body);<br>
-          Type = R_X86_64_PC32;<br>
-        } else {<br>
-          continue;<br>
-        }<br>
-        break;<br>
-      case SymbolBody::UndefinedKind:<br>
-        assert(Body->isWeak() && "Undefined symbol reached writer");<br>
-        SymVA = 0;<br>
-        break;<br>
-      case SymbolBody::LazyKind:<br>
-        llvm_unreachable("Lazy symbol reached writer");<br>
-      }<br>
-    }<br>
-<br>
-    relocateOne(Buf, RI, Type, BaseAddr, SymVA);<br>
-  }<br>
-}<br>
-<br>
 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {<br>
-  for (InputSection<ELFT> *C : Chunks) {<br>
-    C->writeTo(Buf);<br>
-    const ObjectFile<ELFT> *File = C->getFile();<br>
-    ELFFile<ELFT> *EObj = File->getObj();<br>
-    uint8_t *Base = Buf + C->getOutputSectionOff();<br>
-    uintX_t BaseAddr = this->getVA() + C->getOutputSectionOff();<br>
-    // Iterate over all relocation sections that apply to this section.<br>
-    for (const Elf_Shdr *RelSec : C->RelocSections) {<br>
-      if (RelSec->sh_type == SHT_RELA)<br>
-        relocate(Base, EObj->relas(RelSec), *File, BaseAddr);<br>
-      else<br>
-        relocate(Base, EObj->rels(RelSec), *File, BaseAddr);<br>
-    }<br>
-  }<br>
+  for (InputSection<ELFT> *C : Chunks)<br>
+    C->writeTo(Buf, PltSec, GotSec);<br>
 }<br>
<br>
 template <bool Is64Bits><br>
@@ -582,5 +463,21 @@ getSymVA(const DefinedRegular<ELF64LE> *<br>
<br>
 template typename ELFFile<ELF64BE>::uintX_t<br>
 getSymVA(const DefinedRegular<ELF64BE> *DR);<br>
+<br>
+template typename ELFFile<ELF32LE>::uintX_t<br>
+lld::elf2::getLocalSymVA(const typename ELFFile<ELF32LE>::Elf_Sym *Sym,<br>
+                         const ObjectFile<ELF32LE> &File);<br>
+<br>
+template typename ELFFile<ELF32BE>::uintX_t<br>
+lld::elf2::getLocalSymVA(const typename ELFFile<ELF32BE>::Elf_Sym *Sym,<br>
+                         const ObjectFile<ELF32BE> &File);<br>
+<br>
+template typename ELFFile<ELF64LE>::uintX_t<br>
+lld::elf2::getLocalSymVA(const typename ELFFile<ELF64LE>::Elf_Sym *Sym,<br>
+                         const ObjectFile<ELF64LE> &File);<br>
+<br>
+template typename ELFFile<ELF64BE>::uintX_t<br>
+lld::elf2::getLocalSymVA(const typename ELFFile<ELF64BE>::Elf_Sym *Sym,<br>
+                         const ObjectFile<ELF64BE> &File);<br>
 }<br>
 }<br>
<br>
Modified: lld/trunk/ELF/OutputSections.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=248215&r1=248214&r2=248215&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=248215&r1=248214&r2=248215&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.h (original)<br>
+++ lld/trunk/ELF/OutputSections.h Mon Sep 21 17:01:00 2015<br>
@@ -245,17 +245,6 @@ public:<br>
   void addChunk(InputSection<ELFT> *C);<br>
   void writeTo(uint8_t *Buf) override;<br>
<br>
-  template <bool isRela><br>
-  void relocate(uint8_t *Buf,<br>
-                llvm::iterator_range<<br>
-                    const llvm::object::Elf_Rel_Impl<ELFT, isRela> *> Rels,<br>
-                const ObjectFile<ELFT> &File, uintX_t BaseAddr);<br>
-<br>
-  void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,<br>
-                   uintX_t BaseAddr, uintX_t SymVA);<br>
-  void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,<br>
-                   uintX_t BaseAddr, uintX_t SymVA);<br>
-<br>
 private:<br>
   std::vector<InputSection<ELFT> *> Chunks;<br>
   const PltSection<ELFT> &PltSec;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>