Revert "bar"
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 18 Mar 2016 18:11:26 +0000 (18:11 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 18 Mar 2016 18:11:26 +0000 (18:11 +0000)
This reverts commit r263799.
It was a mistake. Sorry about that.

llvm-svn: 263801

lld/ELF/InputSection.cpp
lld/ELF/InputSection.h
lld/ELF/OutputSections.cpp
lld/ELF/Writer.cpp

index 169c9f4..79f5abb 100644 (file)
@@ -215,10 +215,89 @@ static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA,
   return Body.getGotVA<ELFT>();
 }
 
-template <class ELFT> void InputSectionBase<ELFT>::relocate(uint8_t *Buf) {
-  for (const Relocation &Rel : Relocations) {
-    uint8_t *Pos = Buf + Rel.Offset;
-    *(uint64_t *)Pos = Rel.Sym->getVA<ELFT>(0);
+template <class ELFT>
+template <class RelTy>
+void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
+                                      iterator_range<const RelTy *> Rels) {
+  size_t Num = Rels.end() - Rels.begin();
+  for (size_t I = 0; I < Num; ++I) {
+    const RelTy &RI = *(Rels.begin() + I);
+    uintX_t Offset = getOffset(RI.r_offset);
+    if (Offset == (uintX_t)-1)
+      continue;
+
+    uintX_t A = getAddend<ELFT>(RI);
+    uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
+    uint32_t Type = RI.getType(Config->Mips64EL);
+    uint8_t *BufLoc = Buf + Offset;
+    uintX_t AddrLoc = OutSec->getVA() + Offset;
+
+    if (Target->pointsToLocalDynamicGotEntry(Type) &&
+        !Target->canRelaxTls(Type, nullptr)) {
+      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
+                          Out<ELFT>::Got->getTlsIndexVA() + A);
+      continue;
+    }
+
+    SymbolBody &Body = File->getSymbolBody(SymIndex).repl();
+
+    if (Target->canRelaxTls(Type, &Body)) {
+      uintX_t SymVA;
+      if (Target->needsGot(Type, Body))
+        SymVA = Body.getGotVA<ELFT>();
+      else
+        SymVA = Body.getVA<ELFT>();
+      // By optimizing TLS relocations, it is sometimes needed to skip
+      // relocations that immediately follow TLS relocations. This function
+      // knows how many slots we need to skip.
+      I += Target->relaxTls(BufLoc, BufEnd, Type, AddrLoc, SymVA, Body);
+      continue;
+    }
+
+    // PPC64 has a special relocation representing the TOC base pointer
+    // that does not have a corresponding symbol.
+    if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) {
+      uintX_t SymVA = getPPC64TocBase() + A;
+      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0);
+      continue;
+    }
+
+    if (Target->isTlsGlobalDynamicRel(Type) &&
+        !Target->canRelaxTls(Type, &Body)) {
+      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
+                          Out<ELFT>::Got->getGlobalDynAddr(Body) + A);
+      continue;
+    }
+
+    uintX_t SymVA = Body.getVA<ELFT>(A);
+    uint8_t *PairedLoc = nullptr;
+    if (Config->EMachine == EM_MIPS)
+      PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end());
+
+    if (Target->needsPlt<ELFT>(Type, Body)) {
+      SymVA = Body.getPltVA<ELFT>() + A;
+    } else if (Target->needsGot(Type, Body)) {
+      if (Config->EMachine == EM_MIPS)
+        SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, PairedLoc) + A;
+      else
+        SymVA = Body.getGotVA<ELFT>() + A;
+      if (Body.IsTls)
+        Type = Target->getTlsGotRel(Type);
+    } else if (Target->isSizeRel(Type) && Body.isPreemptible()) {
+      // A SIZE relocation is supposed to set a symbol size, but if a symbol
+      // can be preempted, the size at runtime may be different than link time.
+      // If that's the case, we leave the field alone rather than filling it
+      // with a possibly incorrect value.
+      continue;
+    } else if (Config->EMachine == EM_MIPS) {
+      SymVA = adjustMipsSymVA<ELFT>(Type, *File, Body, AddrLoc, SymVA) + A;
+    } else if (!Target->needsCopyRel<ELFT>(Type, Body) &&
+               Body.isPreemptible()) {
+      continue;
+    }
+    uintX_t Size = Body.getSize<ELFT>();
+    Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A,
+                        PairedLoc);
   }
 }
 
@@ -242,7 +321,14 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
 
   memcpy(Buf + OutSecOff, Data.data(), Data.size());
 
-  this->relocate(Buf);
+  uint8_t *BufEnd = Buf + OutSecOff + Data.size();
+  // Iterate over all relocation sections that apply to this section.
+  for (const Elf_Shdr *RelSec : this->RelocSections) {
+    if (RelSec->sh_type == SHT_RELA)
+      this->relocate(Buf, BufEnd, EObj.relas(RelSec));
+    else
+      this->relocate(Buf, BufEnd, EObj.rels(RelSec));
+  }
 }
 
 template <class ELFT>
index 1644f81..0b6117e 100644 (file)
@@ -23,12 +23,6 @@ template <class ELFT> class ObjectFile;
 template <class ELFT> class OutputSection;
 template <class ELFT> class OutputSectionBase;
 
-struct Relocation {
-  enum RelType { R_64 } Type;
-  uint64_t Offset;
-  SymbolBody *Sym;
-};
-
 // This corresponds to a section of an input file.
 template <class ELFT> class InputSectionBase {
 protected:
@@ -81,8 +75,9 @@ public:
   InputSectionBase<ELFT> *getRelocTarget(const Elf_Rel &Rel) const;
   InputSectionBase<ELFT> *getRelocTarget(const Elf_Rela &Rel) const;
 
-  void relocate(uint8_t *Buf);
-  std::vector<Relocation> Relocations;
+  template <class RelTy>
+  void relocate(uint8_t *Buf, uint8_t *BufEnd,
+                llvm::iterator_range<const RelTy *> Rels);
 
 private:
   template <class RelTy>
index 042bc44..b456ac6 100644 (file)
@@ -1168,8 +1168,16 @@ template <class ELFT> void EHOutputSection<ELFT>::writeTo(uint8_t *Buf) {
     }
   }
 
-  for (EHInputSection<ELFT> *S : Sections)
-    S->relocate(Buf);
+  for (EHInputSection<ELFT> *S : Sections) {
+    const Elf_Shdr *RelSec = S->RelocSection;
+    if (!RelSec)
+      continue;
+    ELFFile<ELFT> &EObj = S->getFile()->getObj();
+    if (RelSec->sh_type == SHT_RELA)
+      S->relocate(Buf, nullptr, EObj.relas(RelSec));
+    else
+      S->relocate(Buf, nullptr, EObj.rels(RelSec));
+  }
 }
 
 template <class ELFT>
index f732965..377eed4 100644 (file)
@@ -466,11 +466,8 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C,
     // We can however do better than just copying the incoming relocation. We
     // can process some of it and and just ask the dynamic linker to add the
     // load address.
-    if (!Config->Pic || Target->isRelRelative(Type) ||
-        Target->isSizeRel(Type)) {
-      C.Relocations.push_back({Relocation::R_64, RI.r_offset, &Body});
+    if (!Config->Pic || Target->isRelRelative(Type) || Target->isSizeRel(Type))
       continue;
-    }
 
     uintX_t Addend = getAddend<ELFT>(RI);
     if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) {