[lld] r293352 - Revert "[ELF][ARM] Use SyntheticSections for Thunks"

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 27 16:48:07 PST 2017


Author: ruiu
Date: Fri Jan 27 18:48:06 2017
New Revision: 293352

URL: http://llvm.org/viewvc/llvm-project?rev=293352&view=rev
Log:
Revert "[ELF][ARM] Use SyntheticSections for Thunks"

This reverts commit r293283 because it broke MSVC build.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LTO.cpp
    lld/trunk/ELF/LTO.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Thunks.cpp
    lld/trunk/ELF/Thunks.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/arm-thumb-interwork-shared.s
    lld/trunk/test/ELF/arm-thumb-interwork-thunk.s
    lld/trunk/test/ELF/mips-npic-call-pic.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Jan 27 18:48:06 2017
@@ -488,7 +488,7 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
     StringRefZ Name = this->StringTable.data() + Sym->st_name;
     if (Sym->st_shndx == SHN_UNDEF)
       return new (BAlloc)
-          Undefined(Name, /*IsLocal=*/true, StOther, Type, this);
+          Undefined<ELFT>(Name, /*IsLocal=*/true, StOther, Type, this);
 
     return new (BAlloc) DefinedRegular<ELFT>(Name, /*IsLocal=*/true, StOther,
                                              Type, Value, Size, Sec, this);

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Jan 27 18:48:06 2017
@@ -99,6 +99,10 @@ template <class ELFT> size_t InputSectio
   if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this))
     return S->getSize();
 
+  if (auto *D = dyn_cast<InputSection<ELFT>>(this))
+    if (D->getThunksSize() > 0)
+      return D->getThunkOff() + D->getThunksSize();
+
   return Data.size();
 }
 
@@ -210,6 +214,21 @@ InputSectionBase<ELFT> *InputSection<ELF
   return Sections[this->Info];
 }
 
+template <class ELFT> void InputSection<ELFT>::addThunk(const Thunk<ELFT> *T) {
+  Thunks.push_back(T);
+}
+
+template <class ELFT> uint64_t InputSection<ELFT>::getThunkOff() const {
+  return this->Data.size();
+}
+
+template <class ELFT> uint64_t InputSection<ELFT>::getThunksSize() const {
+  uint64_t Total = 0;
+  for (const Thunk<ELFT> *T : Thunks)
+    Total += T->size();
+  return Total;
+}
+
 // This is used for -r. We can't use memcpy to copy relocations because we need
 // to update symbol table offset and section index for each relocation. So we
 // copy relocations one by one.
@@ -283,6 +302,11 @@ getRelocTargetVA(uint32_t Type, typename
     return In<ELFT>::Got->getTlsIndexOff() + A - In<ELFT>::Got->getSize();
   case R_TLSLD_PC:
     return In<ELFT>::Got->getTlsIndexVA() + A - P;
+  case R_THUNK_ABS:
+    return Body.getThunkVA<ELFT>() + A;
+  case R_THUNK_PC:
+  case R_THUNK_PLT_PC:
+    return Body.getThunkVA<ELFT>() + A - P;
   case R_PPC_TOC:
     return getPPC64TocBase() + A;
   case R_TLSGD:
@@ -527,6 +551,19 @@ template <class ELFT> void InputSection<
   // Iterate over all relocation sections that apply to this section.
   uint8_t *BufEnd = Buf + OutSecOff + Data.size();
   this->relocate(Buf, BufEnd);
+
+  // The section might have a data/code generated by the linker and need
+  // to be written after the section. Usually these are thunks - small piece
+  // of code used to jump between "incompatible" functions like PIC and non-PIC
+  // or if the jump target too far and its address does not fit to the short
+  // jump istruction.
+  if (!Thunks.empty()) {
+    Buf += OutSecOff + getThunkOff();
+    for (const Thunk<ELFT> *T : Thunks) {
+      T->writeTo(Buf);
+      Buf += T->size();
+    }
+  }
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri Jan 27 18:48:06 2017
@@ -280,6 +280,17 @@ public:
 
   InputSectionBase<ELFT> *getRelocatedSection();
 
+  // Register thunk related to the symbol. When the section is written
+  // to a mmap'ed file, target is requested to write an actual thunk code.
+  // Now thunks is supported for MIPS and ARM target only.
+  void addThunk(const Thunk<ELFT> *T);
+
+  // The offset of synthetic thunk code from beginning of this section.
+  uint64_t getThunkOff() const;
+
+  // Size of chunk with thunks code.
+  uint64_t getThunksSize() const;
+
   template <class RelTy>
   void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
 
@@ -292,6 +303,8 @@ public:
 private:
   template <class RelTy>
   void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
+
+  llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
 };
 
 template <class ELFT> InputSection<ELFT> InputSection<ELFT>::Discarded;

Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Fri Jan 27 18:48:06 2017
@@ -96,12 +96,12 @@ BitcodeCompiler::BitcodeCompiler() : LTO
 
 BitcodeCompiler::~BitcodeCompiler() = default;
 
-static void undefine(Symbol *S) {
-  replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false,
-                         STV_DEFAULT, S->body()->Type, nullptr);
+template <class ELFT> static void undefine(Symbol *S) {
+  replaceBody<Undefined<ELFT>>(S, S->body()->getName(), /*IsLocal=*/false,
+                               STV_DEFAULT, S->body()->Type, nullptr);
 }
 
-void BitcodeCompiler::add(BitcodeFile &F) {
+template <class ELFT> void BitcodeCompiler::add(BitcodeFile &F) {
   lto::InputFile &Obj = *F.Obj;
   unsigned SymNum = 0;
   std::vector<Symbol *> Syms = F.getSymbols();
@@ -126,7 +126,7 @@ void BitcodeCompiler::add(BitcodeFile &F
     R.VisibleToRegularObj =
         Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
     if (R.Prevailing)
-      undefine(Sym);
+      undefine<ELFT>(Sym);
   }
   checkError(LTOObj->add(std::move(F.Obj), Resols));
 }
@@ -157,3 +157,8 @@ std::vector<InputFile *> BitcodeCompiler
   }
   return Ret;
 }
+
+template void BitcodeCompiler::template add<ELF32LE>(BitcodeFile &);
+template void BitcodeCompiler::template add<ELF32BE>(BitcodeFile &);
+template void BitcodeCompiler::template add<ELF64LE>(BitcodeFile &);
+template void BitcodeCompiler::template add<ELF64BE>(BitcodeFile &);

Modified: lld/trunk/ELF/LTO.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.h (original)
+++ lld/trunk/ELF/LTO.h Fri Jan 27 18:48:06 2017
@@ -43,7 +43,7 @@ public:
   BitcodeCompiler();
   ~BitcodeCompiler();
 
-  void add(BitcodeFile &F);
+  template <class ELFT> void add(BitcodeFile &F);
   std::vector<InputFile *> compile();
 
 private:

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Jan 27 18:48:06 2017
@@ -43,7 +43,6 @@
 
 #include "Relocations.h"
 #include "Config.h"
-#include "Memory.h"
 #include "OutputSections.h"
 #include "Strings.h"
 #include "SymbolTable.h"
@@ -53,7 +52,6 @@
 
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/raw_ostream.h"
-#include <algorithm>
 
 using namespace llvm;
 using namespace llvm::ELF;
@@ -302,14 +300,16 @@ template <class ELFT> static bool isAbso
 }
 
 static bool needsPlt(RelExpr Expr) {
-  return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC>(Expr);
+  return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC,
+                        R_THUNK_PLT_PC>(Expr);
 }
 
 // True if this expression is of the form Sym - X, where X is a position in the
 // file (PC, or GOT for example).
 static bool isRelExpr(RelExpr Expr) {
   return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
-                        R_PAGE_PC, R_RELAX_GOT_PC>(Expr);
+                        R_PAGE_PC, R_RELAX_GOT_PC, R_THUNK_PC, R_THUNK_PLT_PC>(
+      Expr);
 }
 
 template <class ELFT>
@@ -321,7 +321,8 @@ static bool isStaticLinkTimeConstant(Rel
   if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
                      R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_TLSGD,
                      R_GOT_PAGE_PC, R_GOT_PC, R_PLT_PC, R_TLSGD_PC, R_TLSGD,
-                     R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
+                     R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT,
+                     R_THUNK_PC, R_THUNK_PLT_PC>(E))
     return true;
 
   // These never do, except if the entire file is position dependent or if
@@ -466,6 +467,7 @@ static RelExpr adjustExpr(const elf::Obj
     if (Expr == R_GOT_PC && !isAbsoluteValue<ELFT>(Body))
       Expr = Target->adjustRelaxExpr(Type, Data, Expr);
   }
+  Expr = Target->getThunkExpr(Expr, Type, &File, Body);
 
   if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, S, RelOff))
     return Expr;
@@ -683,6 +685,7 @@ static void scanRelocs(InputSectionBase<
       continue;
 
     if (needsPlt(Expr) ||
+        isRelExprOneOf<R_THUNK_ABS, R_THUNK_PC, R_THUNK_PLT_PC>(Expr) ||
         refersToGotEntry(Expr) || !isPreemptible(Body, Type)) {
       // If the relocation points to something in the file, we can process it.
       bool Constant =
@@ -802,126 +805,33 @@ template <class ELFT> void scanRelocatio
     scanRelocs(S, S.rels());
 }
 
-// Insert the Thunks for OutputSection OS into their designated place
-// in the Sections vector, and recalculate the InputSection output section
-// offsets.
-// This may invalidate any output section offsets stored outside of InputSection
-template <class ELFT>
-static void mergeThunks(OutputSection<ELFT> *OS,
-                        std::vector<ThunkSection<ELFT> *> &Thunks) {
-  // Order Thunks in ascending OutSecOff
-  auto ThunkCmp = [](const ThunkSection<ELFT> *A, const ThunkSection<ELFT> *B) {
-    return A->OutSecOff < B->OutSecOff;
-  };
-  std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
-
-  // Merge sorted vectors of Thunks and InputSections by OutSecOff
-  std::vector<InputSection<ELFT> *> Tmp;
-  Tmp.reserve(OS->Sections.size() + Thunks.size());
-  auto MergeCmp = [](const ThunkSection<ELFT> *Thunk,
-                     const InputSection<ELFT> *IS) {
-    // All thunks go before any non-executable InputSections
-    if ((IS->Flags & SHF_EXECINSTR) == 0)
-      return true;
-    // Some Thunk Sections such as the Mips LA25 thunk must be placed before
-    // the InputSections that they target. We represent this by assigning the
-    // ThunkSection the same OutSecOff and always placing the Thunk first if
-    // the OutSecOff values are the same.
-    return Thunk->OutSecOff <= IS->OutSecOff;
-  };
-  std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(),
-             Thunks.end(), std::back_inserter(Tmp), MergeCmp);
-  OS->Sections = std::move(Tmp);
-  OS->Size = 0;
-  OS->assignOffsets();
-}
-
-// Process all relocations from the InputSections that have been assigned
-// to OutputSections and redirect through Thunks if needed.
-//
-// createThunks must be called after scanRelocs has created the Relocations for
-// each InputSection. It must be called before the static symbol table is
-// finalized. If any Thunks are added to an OutputSection the output section
-// offsets of the InputSections will change.
-//
-// FIXME: All Thunks are assumed to be in range of the relocation. Range
-// extension Thunks are not yet supported.
 template <class ELFT>
 void createThunks(ArrayRef<OutputSectionBase *> OutputSections) {
-  // Track Symbols that already have a Thunk
-  DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols;
-  // Track InputSections that have a ThunkSection placed in front
-  DenseMap<InputSection<ELFT> *, ThunkSection<ELFT> *> ThunkedSections;
-  // Track the ThunksSections that need to be inserted into an OutputSection
-  std::map<OutputSection<ELFT> *, std::vector<ThunkSection<ELFT> *>>
-      ThunkSections;
-
-  // Find or create a Thunk for Body for relocation Type
-  auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {
-    auto res = ThunkedSymbols.insert({&Body, nullptr});
-    if (res.second == true)
-      res.first->second = addThunk<ELFT>(Type, Body);
-    return std::make_pair(res.first->second, res.second);
-  };
-
-  // Find or create a ThunkSection to be placed immediately before IS
-  auto GetISThunkSec = [&](InputSection<ELFT> *IS, OutputSection<ELFT> *OS) {
-    ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS);
-    if (TS)
-      return TS;
-    auto *TOS = cast<OutputSection<ELFT>>(IS->OutSec);
-    TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff);
-    ThunkSections[OS].push_back(TS);
-    ThunkedSections[IS] = TS;
-    return TS;
-  };
-  // Find or create a ThunkSection to be placed at the end of OS
-  auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection<ELFT> *OS) {
-    if (TS == nullptr) {
-      TS = make<ThunkSection<ELFT>>(OS, OS->Size);
-      ThunkSections[OS].push_back(TS);
-    }
-    return TS;
-  };
-  // Create all the Thunks and insert them into synthetic ThunkSections. The
-  // ThunkSections are later inserted back into the OutputSection.
-
-  // We separate the creation of ThunkSections from the insertion of the
-  // ThunkSections back into the OutputSection as ThunkSections are not always
-  // inserted into the same OutputSection as the caller.
   for (OutputSectionBase *Base : OutputSections) {
     auto *OS = dyn_cast<OutputSection<ELFT>>(Base);
     if (OS == nullptr)
       continue;
-
-    ThunkSection<ELFT> *OSTS = nullptr;
     for (InputSection<ELFT> *IS : OS->Sections) {
-      for (Relocation &Rel : IS->Relocations) {
-        SymbolBody &Body = *Rel.Sym;
-        if (Target->needsThunk(Rel.Expr, Rel.Type, IS->getFile(), Body)) {
-          Thunk<ELFT> *T;
-          bool IsNew;
-          std::tie(T, IsNew) = GetThunk(Body, Rel.Type);
-          if (IsNew) {
-            // Find or create a ThunkSection for the new Thunk
-            ThunkSection<ELFT> *TS;
-            if (auto *TIS = T->getTargetInputSection())
-              TS = GetISThunkSec(TIS, OS);
-            else
-              TS = GetOSThunkSec(OSTS, OS);
-            TS->addThunk(T);
-          }
-          // Redirect relocation to Thunk, we never go via the PLT to a Thunk
-          Rel.Sym = T->ThunkSym;
-          Rel.Expr = fromPlt(Rel.Expr);
-        }
+      for (const Relocation &Rel : IS->Relocations) {
+        if (Rel.Sym == nullptr)
+          continue;
+        RelExpr Expr = Rel.Expr;
+        // Some targets might require creation of thunks for relocations.
+        // Now we support only MIPS which requires LA25 thunk to call PIC
+        // code from non-PIC one, and ARM which requires interworking.
+        if (Expr == R_THUNK_ABS || Expr == R_THUNK_PC ||
+            Expr == R_THUNK_PLT_PC)
+          addThunk<ELFT>(Rel.Type, *Rel.Sym, *IS);
       }
     }
   }
-
-  // Merge all created synthetic ThunkSections back into OutputSection
-  for (auto &KV : ThunkSections)
-    mergeThunks<ELFT>(KV.first, KV.second);
+  // Added thunks may affect the output section offset
+  for (OutputSectionBase *Base : OutputSections)
+    if (auto *OS = dyn_cast<OutputSection<ELFT>>(Base))
+      if (OS->Type == SHT_PROGBITS) {
+        OS->Size = 0;
+        OS->assignOffsets();
+      }
 }
 
 template void scanRelocations<ELF32LE>(InputSectionBase<ELF32LE> &);

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Fri Jan 27 18:48:06 2017
@@ -61,6 +61,9 @@ enum RelExpr {
   R_RELAX_TLS_IE_TO_LE,
   R_RELAX_TLS_LD_TO_LE,
   R_SIZE,
+  R_THUNK_ABS,
+  R_THUNK_PC,
+  R_THUNK_PLT_PC,
   R_TLS,
   R_TLSDESC,
   R_TLSDESC_PAGE,

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Jan 27 18:48:06 2017
@@ -115,7 +115,7 @@ template <class ELFT> void SymbolTable<E
   // Compile bitcode files and replace bitcode symbols.
   LTO.reset(new BitcodeCompiler);
   for (BitcodeFile *F : BitcodeFiles)
-    LTO->add(*F);
+    LTO->add<ELFT>(*F);
 
   for (InputFile *File : LTO->compile()) {
     ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File);
@@ -256,7 +256,7 @@ Symbol *SymbolTable<ELFT>::addUndefined(
       insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, File);
   if (WasInserted) {
     S->Binding = Binding;
-    replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File);
+    replaceBody<Undefined<ELFT>>(S, Name, IsLocal, StOther, Type, File);
     return S;
   }
   if (Binding != STB_WEAK) {
@@ -428,7 +428,7 @@ void SymbolTable<ELFT>::addShared(Shared
   // Make sure we preempt DSO symbols with default visibility.
   if (Sym.getVisibility() == STV_DEFAULT)
     S->ExportDynamic = true;
-  if (WasInserted || isa<Undefined>(S->body())) {
+  if (WasInserted || isa<Undefined<ELFT>>(S->body())) {
     replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
     if (!S->isWeak())
       F->IsUsed = true;

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Jan 27 18:48:06 2017
@@ -132,6 +132,14 @@ bool SymbolBody::isPreemptible() const {
   return true;
 }
 
+template <class ELFT> bool SymbolBody::hasThunk() const {
+  if (auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
+    return DR->ThunkData != nullptr;
+  if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
+    return S->ThunkData != nullptr;
+  return false;
+}
+
 template <class ELFT>
 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
@@ -163,6 +171,16 @@ template <class ELFT> typename ELFT::uin
          PltIndex * Target->PltEntrySize;
 }
 
+template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const {
+  if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
+    return DR->ThunkData->getVA();
+  if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
+    return S->ThunkData->getVA();
+  if (const auto *S = dyn_cast<Undefined<ELFT>>(this))
+    return S->ThunkData->getVA();
+  fatal("getThunkVA() not supported for Symbol class\n");
+}
+
 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
   if (const auto *C = dyn_cast<DefinedCommon>(this))
     return C->Size;
@@ -223,8 +241,9 @@ template <class ELFT> bool DefinedRegula
          (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC);
 }
 
-Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
-                     uint8_t Type, InputFile *File)
+template <typename ELFT>
+Undefined<ELFT>::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
+                           uint8_t Type, InputFile *File)
     : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {
   this->File = File;
 }
@@ -319,6 +338,11 @@ std::string lld::toString(const SymbolBo
   return B.getName();
 }
 
+template bool SymbolBody::hasThunk<ELF32LE>() const;
+template bool SymbolBody::hasThunk<ELF32BE>() const;
+template bool SymbolBody::hasThunk<ELF64LE>() const;
+template bool SymbolBody::hasThunk<ELF64BE>() const;
+
 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
@@ -339,6 +363,11 @@ template uint32_t SymbolBody::template g
 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
 
+template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
+template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
+template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
+template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;
+
 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
@@ -354,6 +383,11 @@ template uint32_t SymbolBody::template g
 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
 
+template class elf::Undefined<ELF32LE>;
+template class elf::Undefined<ELF32BE>;
+template class elf::Undefined<ELF64LE>;
+template class elf::Undefined<ELF64BE>;
+
 template class elf::SharedSymbol<ELF32LE>;
 template class elf::SharedSymbol<ELF32BE>;
 template class elf::SharedSymbol<ELF64LE>;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Jan 27 18:48:06 2017
@@ -76,6 +76,7 @@ public:
 
   bool isInGot() const { return GotIndex != -1U; }
   bool isInPlt() const { return PltIndex != -1U; }
+  template <class ELFT> bool hasThunk() const;
 
   template <class ELFT>
   typename ELFT::uint getVA(typename ELFT::uint Addend = 0) const;
@@ -85,6 +86,7 @@ public:
   template <class ELFT> typename ELFT::uint getGotPltOffset() const;
   template <class ELFT> typename ELFT::uint getGotPltVA() const;
   template <class ELFT> typename ELFT::uint getPltVA() const;
+  template <class ELFT> typename ELFT::uint getThunkVA() const;
   template <class ELFT> typename ELFT::uint getSize() const;
 
   // The file from which this symbol was created.
@@ -208,6 +210,10 @@ public:
   // If this is null, the symbol is an absolute symbol.
   InputSectionBase<ELFT> *&Section;
 
+  // If non-null the symbol has a Thunk that may be used as an alternative
+  // destination for callers of this Symbol.
+  Thunk<ELFT> *ThunkData = nullptr;
+
 private:
   static InputSectionBase<ELFT> *NullInputSection;
 };
@@ -236,7 +242,7 @@ public:
   const OutputSectionBase *Section;
 };
 
-class Undefined : public SymbolBody {
+template <class ELFT> class Undefined : public SymbolBody {
 public:
   Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
             InputFile *F);
@@ -245,6 +251,12 @@ public:
     return S->kind() == UndefinedKind;
   }
 
+  // If non-null the symbol has a Thunk that may be used as an alternative
+  // destination for callers of this Symbol. When linking a DSO undefined
+  // symbols are implicitly imported, the symbol lookup will be performed by
+  // the dynamic loader. A call to an undefined symbol will be given a PLT
+  // entry and on ARM this may need a Thunk if the caller is in Thumb state.
+  Thunk<ELFT> *ThunkData = nullptr;
   InputFile *file() { return this->File; }
 };
 
@@ -279,6 +291,9 @@ public:
   // CopyOffset is significant only when needsCopy() is true.
   uintX_t CopyOffset = 0;
 
+  // If non-null the symbol has a Thunk that may be used as an alternative
+  // destination for callers of this Symbol.
+  Thunk<ELFT> *ThunkData = nullptr;
   bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); }
 
   OutputSection<ELFT> *getBssSectionForCopy() const;
@@ -416,7 +431,8 @@ struct Symbol {
   // ELFT, and we verify this with the static_asserts in replaceBody.
   llvm::AlignedCharArrayUnion<
       DefinedCommon, DefinedRegular<llvm::object::ELF64LE>, DefinedSynthetic,
-      Undefined, SharedSymbol<llvm::object::ELF64LE>, LazyArchive, LazyObject>
+      Undefined<llvm::object::ELF64LE>, SharedSymbol<llvm::object::ELF64LE>,
+      LazyArchive, LazyObject>
       Body;
 
   SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Jan 27 18:48:06 2017
@@ -1904,27 +1904,6 @@ void ARMExidxSentinelSection<ELFT>::writ
   write32le(Buf + 4, 0x1);
 }
 
-template <class ELFT>
-ThunkSection<ELFT>::ThunkSection(OutputSectionBase *OS, uint64_t Off)
-    : SyntheticSection<ELFT>(SHF_ALLOC, SHT_PROGBITS,
-                             sizeof(typename ELFT::uint), ".text.thunk") {
-  this->OutSec = OS;
-  this->OutSecOff = Off;
-}
-
-template <class ELFT> void ThunkSection<ELFT>::addThunk(Thunk<ELFT> *T) {
-  uint64_t Off = alignTo(Size, T->alignment);
-  T->Offset = Off;
-  Thunks.push_back(T);
-  T->addSymbols(*this);
-  Size = Off + T->size();
-}
-
-template <class ELFT> void ThunkSection<ELFT>::writeTo(uint8_t *Buf) {
-  for (const Thunk<ELFT> *T : Thunks)
-    T->writeTo(Buf + T->Offset, *this);
-}
-
 template InputSection<ELF32LE> *elf::createCommonSection();
 template InputSection<ELF32BE> *elf::createCommonSection();
 template InputSection<ELF64LE> *elf::createCommonSection();
@@ -2067,8 +2046,3 @@ template class elf::ARMExidxSentinelSect
 template class elf::ARMExidxSentinelSection<ELF32BE>;
 template class elf::ARMExidxSentinelSection<ELF64LE>;
 template class elf::ARMExidxSentinelSection<ELF64BE>;
-
-template class elf::ThunkSection<ELF32LE>;
-template class elf::ThunkSection<ELF32BE>;
-template class elf::ThunkSection<ELF64LE>;
-template class elf::ThunkSection<ELF64BE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Jan 27 18:48:06 2017
@@ -699,26 +699,6 @@ public:
   void writeTo(uint8_t *Buf) override;
 };
 
-// A container for one or more linker generated thunks. Instances of these
-// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.
-template <class ELFT> class ThunkSection : public SyntheticSection<ELFT> {
-public:
-  // ThunkSection in OS, with desired OutSecOff of Off
-  ThunkSection(OutputSectionBase *OS, uint64_t Off);
-
-  // Add a newly created Thunk to this container:
-  // Thunk is given offset from start of this InputSection
-  // Thunk defines a symbol in this InputSection that can be used as target
-  // of a relocation
-  void addThunk(Thunk<ELFT> *T);
-  size_t getSize() const override { return Size; }
-  void writeTo(uint8_t *Buf) override;
-
-private:
-  std::vector<const Thunk<ELFT> *> Thunks;
-  size_t Size = 0;
-};
-
 template <class ELFT> InputSection<ELFT> *createCommonSection();
 template <class ELFT> InputSection<ELFT> *createInterpSection();
 template <class ELFT> MergeInputSection<ELFT> *createCommentSection();

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Jan 27 18:48:06 2017
@@ -228,8 +228,8 @@ public:
                 int32_t Index, unsigned RelOff) const override;
   void addPltSymbols(InputSectionData *IS, uint64_t Off) const override;
   void addPltHeaderSymbols(InputSectionData *ISD) const override;
-  bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
-                  const SymbolBody &S) const override;
+  RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const InputFile *File,
+                       const SymbolBody &S) const override;
   void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
 };
 
@@ -246,8 +246,8 @@ public:
   void writePltHeader(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
                 int32_t Index, unsigned RelOff) const override;
-  bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
-                  const SymbolBody &S) const override;
+  RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const InputFile *File,
+                       const SymbolBody &S) const override;
   void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
   bool usesOnlyLowPageBits(uint32_t Type) const override;
 };
@@ -298,9 +298,10 @@ uint64_t TargetInfo::getImplicitAddend(c
 
 bool TargetInfo::usesOnlyLowPageBits(uint32_t Type) const { return false; }
 
-bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
-                            const InputFile *File, const SymbolBody &S) const {
-  return false;
+RelExpr TargetInfo::getThunkExpr(RelExpr Expr, uint32_t RelocType,
+                                 const InputFile *File,
+                                 const SymbolBody &S) const {
+  return Expr;
 }
 
 bool TargetInfo::isTlsInitialExecRel(uint32_t Type) const { return false; }
@@ -1770,15 +1771,15 @@ void ARMTargetInfo::addPltSymbols(InputS
   addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
 }
 
-bool ARMTargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
-                               const InputFile *File,
-                               const SymbolBody &S) const {
+RelExpr ARMTargetInfo::getThunkExpr(RelExpr Expr, uint32_t RelocType,
+                                    const InputFile *File,
+                                    const SymbolBody &S) const {
   // If S is an undefined weak symbol in an executable we don't need a Thunk.
   // In a DSO calls to undefined symbols, including weak ones get PLT entries
   // which may need a thunk.
   if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() &&
       !Config->Shared)
-    return false;
+    return Expr;
   // A state change from ARM to Thumb and vice versa must go through an
   // interworking thunk if the relocation type is not R_ARM_CALL or
   // R_ARM_THM_CALL.
@@ -1789,17 +1790,19 @@ bool ARMTargetInfo::needsThunk(RelExpr E
     // Source is ARM, all PLT entries are ARM so no interworking required.
     // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
     if (Expr == R_PC && ((S.getVA<ELF32LE>() & 1) == 1))
-      return true;
+      return R_THUNK_PC;
     break;
   case R_ARM_THM_JUMP19:
   case R_ARM_THM_JUMP24:
     // Source is Thumb, all PLT entries are ARM so interworking is required.
     // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
-    if (Expr == R_PLT_PC || ((S.getVA<ELF32LE>() & 1) == 0))
-      return true;
+    if (Expr == R_PLT_PC)
+      return R_THUNK_PLT_PC;
+    if ((S.getVA<ELF32LE>() & 1) == 0)
+      return R_THUNK_PC;
     break;
   }
-  return false;
+  return Expr;
 }
 
 void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
@@ -2212,26 +2215,26 @@ void MipsTargetInfo<ELFT>::writePlt(uint
 }
 
 template <class ELFT>
-bool MipsTargetInfo<ELFT>::needsThunk(RelExpr Expr, uint32_t Type,
-                                      const InputFile *File,
-                                      const SymbolBody &S) const {
+RelExpr MipsTargetInfo<ELFT>::getThunkExpr(RelExpr Expr, uint32_t Type,
+                                           const InputFile *File,
+                                           const SymbolBody &S) const {
   // Any MIPS PIC code function is invoked with its address in register $t9.
   // So if we have a branch instruction from non-PIC code to the PIC one
   // we cannot make the jump directly and need to create a small stubs
   // to save the target function address.
   // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (Type != R_MIPS_26)
-    return false;
+    return Expr;
   auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
   if (!F)
-    return false;
+    return Expr;
   // If current file has PIC code, LA25 stub is not required.
   if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
-    return false;
+    return Expr;
   auto *D = dyn_cast<DefinedRegular<ELFT>>(&S);
   // LA25 is required if target file has PIC code
   // or target symbol is a PIC symbol.
-  return D && D->isMipsPIC();
+  return D && D->isMipsPIC() ? R_THUNK_ABS : Expr;
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Jan 27 18:48:06 2017
@@ -41,8 +41,8 @@ public:
   virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
                         uint64_t PltEntryAddr, int32_t Index,
                         unsigned RelOff) const {}
-  virtual void addPltHeaderSymbols(InputSectionData *IS) const {}
-  virtual void addPltSymbols(InputSectionData *IS, uint64_t Off) const {}
+  virtual void addPltHeaderSymbols(InputSectionData* IS) const {}
+  virtual void addPltSymbols(InputSectionData* IS, uint64_t Off) const {}
   // Returns true if a relocation only uses the low bits of a value such that
   // all those bits are in in the same page. For example, if the relocation
   // only uses the low 12 bits in a system with 4k pages. If this is true, the
@@ -51,9 +51,14 @@ public:
   virtual bool usesOnlyLowPageBits(uint32_t Type) const;
 
   // Decide whether a Thunk is needed for the relocation from File
-  // targeting S.
-  virtual bool needsThunk(RelExpr Expr, uint32_t RelocType,
-                          const InputFile *File, const SymbolBody &S) const;
+  // targeting S. Returns one of:
+  // Expr if there is no Thunk required
+  // R_THUNK_ABS if thunk is required and expression is absolute
+  // R_THUNK_PC if thunk is required and expression is pc rel
+  // R_THUNK_PLT_PC if thunk is required to PLT entry and expression is pc rel
+  virtual RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType,
+                               const InputFile *File,
+                               const SymbolBody &S) const;
   virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const = 0;
   virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0;
   virtual ~TargetInfo();

Modified: lld/trunk/ELF/Thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.cpp (original)
+++ lld/trunk/ELF/Thunks.cpp Fri Jan 27 18:48:06 2017
@@ -28,7 +28,6 @@
 #include "Memory.h"
 #include "OutputSections.h"
 #include "Symbols.h"
-#include "SyntheticSections.h"
 #include "Target.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ELF.h"
@@ -53,54 +52,53 @@ namespace {
 template <class ELFT>
 class ARMToThumbV7ABSLongThunk final : public Thunk<ELFT> {
 public:
-  ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
+  ARMToThumbV7ABSLongThunk(const SymbolBody &Dest,
+                           const InputSection<ELFT> &Owner)
+      : Thunk<ELFT>(Dest, Owner) {}
 
   uint32_t size() const override { return 12; }
-  void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
-  void addSymbols(ThunkSection<ELFT> &IS) override;
+  void writeTo(uint8_t *Buf) const override;
 };
 
 template <class ELFT> class ARMToThumbV7PILongThunk final : public Thunk<ELFT> {
 public:
-  ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
+  ARMToThumbV7PILongThunk(const SymbolBody &Dest,
+                          const InputSection<ELFT> &Owner)
+      : Thunk<ELFT>(Dest, Owner) {}
 
   uint32_t size() const override { return 16; }
-  void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
-  void addSymbols(ThunkSection<ELFT> &IS) override;
+  void writeTo(uint8_t *Buf) const override;
 };
 
 template <class ELFT>
 class ThumbToARMV7ABSLongThunk final : public Thunk<ELFT> {
 public:
-  ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {
-    this->alignment = 2;
-  }
+  ThumbToARMV7ABSLongThunk(const SymbolBody &Dest,
+                           const InputSection<ELFT> &Owner)
+      : Thunk<ELFT>(Dest, Owner) {}
 
   uint32_t size() const override { return 10; }
-  void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
-  void addSymbols(ThunkSection<ELFT> &IS) override;
+  void writeTo(uint8_t *Buf) const override;
 };
 
 template <class ELFT> class ThumbToARMV7PILongThunk final : public Thunk<ELFT> {
 public:
-  ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {
-    this->alignment = 2;
-  }
+  ThumbToARMV7PILongThunk(const SymbolBody &Dest,
+                          const InputSection<ELFT> &Owner)
+      : Thunk<ELFT>(Dest, Owner) {}
 
   uint32_t size() const override { return 12; }
-  void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
-  void addSymbols(ThunkSection<ELFT> &IS) override;
+  void writeTo(uint8_t *Buf) const override;
 };
 
 // MIPS LA25 thunk
 template <class ELFT> class MipsThunk final : public Thunk<ELFT> {
 public:
-  MipsThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
+  MipsThunk(const SymbolBody &Dest, const InputSection<ELFT> &Owner)
+      : Thunk<ELFT>(Dest, Owner) {}
 
   uint32_t size() const override { return 16; }
-  void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
-  void addSymbols(ThunkSection<ELFT> &IS) override;
-  InputSection<ELFT> *getTargetInputSection() const override;
+  void writeTo(uint8_t *Buf) const override;
 };
 
 } // end anonymous namespace
@@ -112,8 +110,7 @@ template <class ELFT> static uint64_t ge
 }
 
 template <class ELFT>
-void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
-                                             ThunkSection<ELFT> &IS) const {
+void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf) const {
   const uint8_t Data[] = {
       0x00, 0xc0, 0x00, 0xe3, // movw         ip,:lower16:S
       0x00, 0xc0, 0x40, 0xe3, // movt         ip,:upper16:S
@@ -126,16 +123,7 @@ void ARMToThumbV7ABSLongThunk<ELFT>::wri
 }
 
 template <class ELFT>
-void ARMToThumbV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
-  this->ThunkSym = addSyntheticLocal(
-      Saver.save("__ARMToThumbv7ABSLongThunk_" + this->Destination.getName()),
-      STT_FUNC, this->Offset, size(), &IS);
-  addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS);
-}
-
-template <class ELFT>
-void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
-                                             ThunkSection<ELFT> &IS) const {
+void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf) const {
   const uint8_t Data[] = {
       0x40, 0xf2, 0x00, 0x0c, // movw         ip, :lower16:S
       0xc0, 0xf2, 0x00, 0x0c, // movt         ip, :upper16:S
@@ -148,16 +136,7 @@ void ThumbToARMV7ABSLongThunk<ELFT>::wri
 }
 
 template <class ELFT>
-void ThumbToARMV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
-  this->ThunkSym = addSyntheticLocal(
-      Saver.save("__ThumbToARMv7ABSLongThunk_" + this->Destination.getName()),
-      STT_FUNC, this->Offset, size(), &IS);
-  addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS);
-}
-
-template <class ELFT>
-void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
-                                            ThunkSection<ELFT> &IS) const {
+void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf) const {
   const uint8_t Data[] = {
       0xf0, 0xcf, 0x0f, 0xe3, // P:  movw ip,:lower16:S - (P + (L1-P) +8)
       0x00, 0xc0, 0x40, 0xe3, //     movt ip,:upper16:S - (P + (L1-P+4) +8)
@@ -165,23 +144,14 @@ void ARMToThumbV7PILongThunk<ELFT>::writ
       0x1c, 0xff, 0x2f, 0xe1, //     bx r12
   };
   uint64_t S = getARMThunkDestVA<ELFT>(this->Destination);
-  uint64_t P = this->ThunkSym->template getVA<ELFT>();
+  uint64_t P = this->getVA();
   memcpy(Buf, Data, sizeof(Data));
   Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, S - P - 16);
   Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, S - P - 12);
 }
 
 template <class ELFT>
-void ARMToThumbV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
-  this->ThunkSym = addSyntheticLocal(
-      Saver.save("__ARMToThumbV7PILongThunk_" + this->Destination.getName()),
-      STT_FUNC, this->Offset, size(), &IS);
-  addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS);
-}
-
-template <class ELFT>
-void ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
-                                            ThunkSection<ELFT> &IS) const {
+void ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf) const {
   const uint8_t Data[] = {
       0x4f, 0xf6, 0xf4, 0x7c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
       0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P+4) + 4)
@@ -189,23 +159,14 @@ void ThumbToARMV7PILongThunk<ELFT>::writ
       0x60, 0x47,             //     bx   r12
   };
   uint64_t S = getARMThunkDestVA<ELFT>(this->Destination);
-  uint64_t P = this->ThunkSym->template getVA<ELFT>();
+  uint64_t P = this->getVA();
   memcpy(Buf, Data, sizeof(Data));
   Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, S - P - 12);
   Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, S - P - 8);
 }
 
-template <class ELFT>
-void ThumbToARMV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
-  this->ThunkSym = addSyntheticLocal(
-      Saver.save("__ThumbToARMV7PILongThunk_" + this->Destination.getName()),
-      STT_FUNC, this->Offset, size(), &IS);
-  addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS);
-}
-
 // Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
-template <class ELFT>
-void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection<ELFT> &) const {
+template <class ELFT> void MipsThunk<ELFT>::writeTo(uint8_t *Buf) const {
   const endianness E = ELFT::TargetEndianness;
 
   uint64_t S = this->Destination.template getVA<ELFT>();
@@ -217,26 +178,20 @@ void MipsThunk<ELFT>::writeTo(uint8_t *B
   Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
 }
 
-template <class ELFT> void MipsThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
-  this->ThunkSym = addSyntheticLocal(
-      Saver.save("__LA25Thunk_" + this->Destination.getName()), STT_FUNC,
-      this->Offset, size(), &IS);
-}
-
 template <class ELFT>
-InputSection<ELFT> *MipsThunk<ELFT>::getTargetInputSection() const {
-  auto *DR = dyn_cast<DefinedRegular<ELFT>>(&this->Destination);
-  return dyn_cast<InputSection<ELFT>>(DR->Section);
-}
+Thunk<ELFT>::Thunk(const SymbolBody &D, const InputSection<ELFT> &O)
+    : Destination(D), Owner(O), Offset(O.getThunkOff() + O.getThunksSize()) {}
 
-template <class ELFT>
-Thunk<ELFT>::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {}
+template <class ELFT> typename ELFT::uint Thunk<ELFT>::getVA() const {
+  return Owner.OutSec->Addr + Owner.OutSecOff + Offset;
+}
 
 template <class ELFT> Thunk<ELFT>::~Thunk() = default;
 
 // Creates a thunk for Thumb-ARM interworking.
 template <class ELFT>
-static Thunk<ELFT> *addThunkArm(uint32_t Reloc, SymbolBody &S) {
+static Thunk<ELFT> *createThunkArm(uint32_t Reloc, SymbolBody &S,
+                                   InputSection<ELFT> &IS) {
   // ARM relocations need ARM to Thumb interworking Thunks.
   // Thumb relocations need Thumb to ARM relocations.
   // Use position independent Thunks if we require position independent code.
@@ -245,34 +200,71 @@ static Thunk<ELFT> *addThunkArm(uint32_t
   case R_ARM_PLT32:
   case R_ARM_JUMP24:
     if (Config->Pic)
-      return make<ARMToThumbV7PILongThunk<ELFT>>(S);
-    return make<ARMToThumbV7ABSLongThunk<ELFT>>(S);
+      return new (BAlloc) ARMToThumbV7PILongThunk<ELFT>(S, IS);
+    return new (BAlloc) ARMToThumbV7ABSLongThunk<ELFT>(S, IS);
   case R_ARM_THM_JUMP19:
   case R_ARM_THM_JUMP24:
     if (Config->Pic)
-      return make<ThumbToARMV7PILongThunk<ELFT>>(S);
-    return make<ThumbToARMV7ABSLongThunk<ELFT>>(S);
+      return new (BAlloc) ThumbToARMV7PILongThunk<ELFT>(S, IS);
+    return new (BAlloc) ThumbToARMV7ABSLongThunk<ELFT>(S, IS);
   }
   fatal("unrecognized relocation type");
 }
 
-template <class ELFT> static Thunk<ELFT> *addThunkMips(SymbolBody &S) {
-  return make<MipsThunk<ELFT>>(S);
+template <class ELFT>
+static void addThunkARM(uint32_t Reloc, SymbolBody &S, InputSection<ELFT> &IS) {
+  // Only one Thunk supported per symbol.
+  if (S.hasThunk<ELFT>())
+    return;
+
+  // ARM Thunks are added to the same InputSection as the relocation. This
+  // isn't strictly necessary but it makes it more likely that a limited range
+  // branch can reach the Thunk, and it makes Thunks to the PLT section easier
+  Thunk<ELFT> *T = createThunkArm(Reloc, S, IS);
+  IS.addThunk(T);
+  if (auto *Sym = dyn_cast<DefinedRegular<ELFT>>(&S))
+    Sym->ThunkData = T;
+  else if (auto *Sym = dyn_cast<SharedSymbol<ELFT>>(&S))
+    Sym->ThunkData = T;
+  else if (auto *Sym = dyn_cast<Undefined<ELFT>>(&S))
+    Sym->ThunkData = T;
+  else
+    fatal("symbol not DefinedRegular or Shared");
+}
+
+template <class ELFT>
+static void addThunkMips(uint32_t RelocType, SymbolBody &S,
+                         InputSection<ELFT> &IS) {
+  // Only one Thunk supported per symbol.
+  if (S.hasThunk<ELFT>())
+    return;
+
+  // Mips Thunks are added to the InputSection defining S.
+  auto *R = cast<DefinedRegular<ELFT>>(&S);
+  auto *Sec = cast<InputSection<ELFT>>(R->Section);
+  auto *T = new (BAlloc) MipsThunk<ELFT>(S, *Sec);
+  Sec->addThunk(T);
+  R->ThunkData = T;
 }
 
-template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType, SymbolBody &S) {
+template <class ELFT>
+void addThunk(uint32_t RelocType, SymbolBody &S, InputSection<ELFT> &IS) {
   if (Config->EMachine == EM_ARM)
-    return addThunkArm<ELFT>(RelocType, S);
+    addThunkARM<ELFT>(RelocType, S, IS);
   else if (Config->EMachine == EM_MIPS)
-    return addThunkMips<ELFT>(S);
-  llvm_unreachable("add Thunk only supported for ARM and Mips");
-  return nullptr;
+    addThunkMips<ELFT>(RelocType, S, IS);
+  else
+    llvm_unreachable("add Thunk only supported for ARM and Mips");
 }
 
-template Thunk<ELF32LE> *addThunk<ELF32LE>(uint32_t, SymbolBody &);
-template Thunk<ELF32BE> *addThunk<ELF32BE>(uint32_t, SymbolBody &);
-template Thunk<ELF64LE> *addThunk<ELF64LE>(uint32_t, SymbolBody &);
-template Thunk<ELF64BE> *addThunk<ELF64BE>(uint32_t, SymbolBody &);
+template void addThunk<ELF32LE>(uint32_t, SymbolBody &,
+                                InputSection<ELF32LE> &);
+template void addThunk<ELF32BE>(uint32_t, SymbolBody &,
+                                InputSection<ELF32BE> &);
+template void addThunk<ELF64LE>(uint32_t, SymbolBody &,
+                                InputSection<ELF64LE> &);
+template void addThunk<ELF64BE>(uint32_t, SymbolBody &,
+                                InputSection<ELF64BE> &);
 
 template class Thunk<ELF32LE>;
 template class Thunk<ELF32BE>;

Modified: lld/trunk/ELF/Thunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.h?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.h (original)
+++ lld/trunk/ELF/Thunks.h Fri Jan 27 18:48:06 2017
@@ -15,8 +15,8 @@
 namespace lld {
 namespace elf {
 class SymbolBody;
-template <class ELFT> class ThunkSection;
-class OutputSectionBase;
+template <class ELFT> class InputSection;
+
 // Class to describe an instance of a Thunk.
 // A Thunk is a code-sequence inserted by the linker in between a caller and
 // the callee. The relocation to the callee is redirected to the Thunk, which
@@ -24,35 +24,31 @@ class OutputSectionBase;
 // include transferring control from non-pi to pi and changing state on
 // targets like ARM.
 //
-// Thunks can be created for DefinedRegular, Shared and Undefined Symbols.
-// Thunks are assigned to synthetic ThunkSections
+// Thunks can be created for DefinedRegular and Shared Symbols. The Thunk
+// is stored in a field of the Symbol Destination.
+// Thunks to be written to an InputSection are recorded by the InputSection.
 template <class ELFT> class Thunk {
+  typedef typename ELFT::uint uintX_t;
+
 public:
-  Thunk(const SymbolBody &Destination);
+  Thunk(const SymbolBody &Destination, const InputSection<ELFT> &Owner);
   virtual ~Thunk();
 
   virtual uint32_t size() const { return 0; }
-  virtual void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const {}
-
-  // All Thunks must define at least one symbol ThunkSym so that we can
-  // redirect relocations to it.
-  virtual void addSymbols(ThunkSection<ELFT> &IS) {}
-
-  // Some Thunks must be placed immediately before their Target as they elide
-  // a branch and fall through to the first Symbol in the Target.
-  virtual InputSection<ELFT> *getTargetInputSection() const { return nullptr; }
+  virtual void writeTo(uint8_t *Buf) const {}
+  uintX_t getVA() const;
 
-  // The alignment requirement for this Thunk, defaults to the size of the
-  // typical code section alignment.
+protected:
   const SymbolBody &Destination;
-  SymbolBody *ThunkSym;
+  const InputSection<ELFT> &Owner;
   uint64_t Offset;
-  uint32_t alignment = 4;
 };
 
-// For a Relocation to symbol S create a Thunk to be added to a synthetic
-// ThunkSection. At present there are implementations for ARM and Mips Thunks.
-template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType, SymbolBody &S);
+// For a Relocation to symbol S from InputSection Src, create a Thunk and
+// update the fields of S and the InputSection that the Thunk body will be
+// written to. At present there are implementations for ARM and Mips Thunks.
+template <class ELFT>
+void addThunk(uint32_t RelocType, SymbolBody &S, InputSection<ELFT> &Src);
 
 } // namespace elf
 } // namespace lld

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jan 27 18:48:06 2017
@@ -1027,12 +1027,6 @@ template <class ELFT> void Writer<ELFT>:
   if (In<ELFT>::Iplt && !In<ELFT>::Iplt->empty())
     In<ELFT>::Iplt->addSymbols();
 
-  // Some architectures use small displacements for jump instructions.
-  // It is linker's responsibility to create thunks containing long
-  // jump instructions if jump targets are too far. Create thunks.
-  if (Target->NeedsThunks)
-    createThunks<ELFT>(OutputSections);
-
   // Now that we have defined all possible symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   for (Symbol *S : Symtab<ELFT>::X->getSymbols()) {
@@ -1078,6 +1072,12 @@ template <class ELFT> void Writer<ELFT>:
     fixHeaders();
   }
 
+  // Some architectures use small displacements for jump instructions.
+  // It is linker's responsibility to create thunks containing long
+  // jump instructions if jump targets are too far. Create thunks.
+  if (Target->NeedsThunks)
+    createThunks<ELFT>(OutputSections);
+
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections.

Modified: lld/trunk/test/ELF/arm-thumb-interwork-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-shared.s?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-shared.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-shared.s Fri Jan 27 18:48:06 2017
@@ -16,15 +16,12 @@ sym1:
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: sym1:
-// CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbToARMV7PILongThunk_elsewhere+0x4>
-// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbToARMV7PILongThunk_weakref+0x4>
-// CHECK: __ThumbToARMV7PILongThunk_elsewhere:
+// CHECK:          1000:       00 f0 02 b8     b.w     #4
+// CHECK-NEXT:     1004:       00 f0 06 b8     b.w     #12
 // CHECK-NEXT:     1008:       40 f2 20 0c     movw    r12, #32
 // CHECK-NEXT:     100c:       c0 f2 00 0c     movt    r12, #0
 // CHECK-NEXT:     1010:       fc 44   add     r12, pc
 // CHECK-NEXT:     1012:       60 47   bx      r12
-
-// CHECK: __ThumbToARMV7PILongThunk_weakref:
 // CHECK-NEXT:     1014:       40 f2 24 0c     movw    r12, #36
 // CHECK-NEXT:     1018:       c0 f2 00 0c     movt    r12, #0
 // CHECK-NEXT:     101c:       fc 44   add     r12, pc

Modified: lld/trunk/test/ELF/arm-thumb-interwork-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk.s?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-thunk.s Fri Jan 27 18:48:06 2017
@@ -78,65 +78,62 @@ arm_caller:
  beq arm_callee2
  bne arm_callee3
  bx lr
-// CHECK-ARM-ABS-ARM: Disassembly of section .arm_caller:
-// CHECK-ARM-ABS-ARM-NEXT: arm_caller:
-// CHECK-ARM-ABS-ARM-NEXT:     1300:       3e ff ff fa     blx     #-776 <thumb_callee1>
-// CHECK-ARM-ABS-ARM-NEXT:     1304:       3d ff ff fa     blx     #-780 <thumb_callee1>
-// CHECK-ARM-ABS-ARM-NEXT:     1308:       06 00 00 ea     b       #24 <__ARMToThumbv7ABSLongThunk_thumb_callee1>
-// CHECK-ARM-ABS-ARM-NEXT:     130c:       05 00 00 ea     b       #20 <__ARMToThumbv7ABSLongThunk_thumb_callee1>
-// CHECK-ARM-ABS-ARM-NEXT:     1310:       07 00 00 ea     b       #28 <__ARMToThumbv7ABSLongThunk_thumb_callee2>
-// CHECK-ARM-ABS-ARM-NEXT:     1314:       09 00 00 ea     b       #36 <__ARMToThumbv7ABSLongThunk_thumb_callee3>
-// CHECK-ARM-ABS-ARM-NEXT:     1318:       78 ff ff ea     b       #-544 <arm_callee1>
-// CHECK-ARM-ABS-ARM-NEXT:     131c:       b7 00 00 0a     beq     #732 <arm_callee2>
-// CHECK-ARM-ABS-ARM-NEXT:     1320:       b7 00 00 1a     bne     #732 <arm_callee3>
-// CHECK-ARM-ABS-ARM-NEXT:     1324:       1e ff 2f e1     bx      lr
-// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thumb_callee1:
+// CHECK-ABS-ARM: Disassembly of section .arm_caller:
+// CHECK-ABS-ARM-NEXT: arm_caller:
+// CHECK-ABS-ARM-NEXT: 1300:       3e ff ff fa     blx     #-776 <thumb_callee1>
+// CHECK-ABS-ARM-NEXT: 1304:       3d ff ff fa     blx     #-780 <thumb_callee1>
+// CHECK-ABS-ARM-NEXT: 1308:       06 00 00 ea     b       #24 <arm_caller+0x28>
+// CHECK-ABS-ARM-NEXT: 130c:       05 00 00 ea     b       #20 <arm_caller+0x28>
+// CHECK-ABS-ARM-NEXT: 1310:       07 00 00 ea     b       #28 <arm_caller+0x34>
+// CHECK-ABS-ARM-NEXT: 1314:       09 00 00 ea     b       #36 <arm_caller+0x40>
+// CHECK-ABS-ARM-NEXT: 1318:       78 ff ff ea     b       #-544 <arm_callee1>
+// CHECK-ABS-ARM-NEXT: 131c:       b7 00 00 0a     beq     #732 <arm_callee2>
+// CHECK-ABS-ARM-NEXT: 1320:       b7 00 00 1a     bne     #732 <arm_callee3>
+// CHECK-ABS-ARM-NEXT: 1324:       1e ff 2f e1     bx      lr
 // 0x1001 = thumb_callee1
-// CHECK-ARM-ABS-ARM-NEXT:     1328:       01 c0 01 e3     movw    r12, #4097
-// CHECK-ARM-ABS-ARM-NEXT:     132c:       00 c0 40 e3     movt    r12, #0
-// CHECK-ARM-ABS-ARM-NEXT:     1330:       1c ff 2f e1     bx      r12
+// CHECK-ABS-ARM-NEXT: 1328:       01 c0 01 e3     movw    r12, #4097
+// CHECK-ABS-ARM-NEXT: 132c:       00 c0 40 e3     movt    r12, #0
+// CHECK-ABS-ARM-NEXT: 1330:       1c ff 2f e1     bx      r12
 // 0x1501 = thumb_callee2
-// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thumb_callee2:
-// CHECK-ARM-ABS-ARM-NEXT:     1334:       01 c5 01 e3     movw    r12, #5377
-// CHECK-ARM-ABS-ARM-NEXT:     1338:       00 c0 40 e3     movt    r12, #0
-// CHECK-ARM-ABS-ARM-NEXT:     133c:       1c ff 2f e1     bx      r12
+// CHECK-ABS-ARM-NEXT: 1334:       01 c5 01 e3     movw    r12, #5377
+// CHECK-ABS-ARM-NEXT: 1338:       00 c0 40 e3     movt    r12, #0
+// CHECK-ABS-ARM-NEXT: 133c:       1c ff 2f e1     bx      r12
 // 0x1503 = thumb_callee3
-// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thumb_callee3:
-// CHECK-ARM-ABS-ARM-NEXT:     1340:       03 c5 01 e3     movw    r12, #5379
-// CHECK-ARM-ABS-ARM-NEXT:     1344:       00 c0 40 e3     movt    r12, #0
-// CHECK-ARM-ABS-ARM-NEXT:     1348:       1c ff 2f e1     bx      r12
+// CHECK-ABS-ARM-NEXT: 1340:       03 c5 01 e3     movw    r12, #5379
+// CHECK-ABS-ARM-NEXT: 1344:       00 c0 40 e3     movt    r12, #0
+// CHECK-ABS-ARM-NEXT: 1348:       1c ff 2f e1     bx      r12
 
 // CHECK-PI-ARM: Disassembly of section .arm_caller:
 // CHECK-PI-ARM-NEXT: arm_caller:
-// CHECK-PI-ARM-NEXT:     1300:       3e ff ff fa     blx     #-776 <thumb_callee1>
-// CHECK-PI-ARM-NEXT:     1304:       3d ff ff fa     blx     #-780 <thumb_callee1>
-// CHECK-PI-ARM-NEXT:     1308:       06 00 00 ea     b       #24 <__ARMToThumbV7PILongThunk_thumb_callee1>
-// CHECK-PI-ARM-NEXT:     130c:       05 00 00 ea     b       #20 <__ARMToThumbV7PILongThunk_thumb_callee1>
-// CHECK-PI-ARM-NEXT:     1310:       08 00 00 ea     b       #32 <__ARMToThumbV7PILongThunk_thumb_callee2>
-// CHECK-PI-ARM-NEXT:     1314:       0b 00 00 ea     b       #44 <__ARMToThumbV7PILongThunk_thumb_callee3>
-// CHECK-PI-ARM-NEXT:     1318:       78 ff ff ea     b       #-544 <arm_callee1>
-// CHECK-PI-ARM-NEXT:     131c:       b7 00 00 0a     beq     #732 <arm_callee2>
-// CHECK-PI-ARM-NEXT:     1320:       b7 00 00 1a     bne     #732 <arm_callee3>
-// CHECK-PI-ARM-NEXT:     1324:       1e ff 2f e1     bx      lr
-// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thumb_callee1:
+// CHECK-PI-ARM-NEXT: 1300:       3e ff ff fa     blx     #-776 <thumb_callee1>
+// CHECK-PI-ARM-NEXT: 1304:       3d ff ff fa     blx     #-780 <thumb_callee1>
+// 0x1308 + 8 + 0x18 = 0x1328
+// CHECK-PI-ARM-NEXT: 1308:       06 00 00 ea     b       #24 <arm_caller+0x28>
+// 0x130c + 8 + 0x14 = 0x1328
+// CHECK-PI-ARM-NEXT: 130c:       05 00 00 ea     b       #20 <arm_caller+0x28>
+// 0x1310 + 8 + 0x20 = 0x1338
+// CHECK-PI-ARM-NEXT: 1310:       08 00 00 ea     b       #32 <arm_caller+0x38>
+// 0x1314 + 8 + 0x2c = 0x1348
+// CHECK-PI-ARM-NEXT: 1314:       0b 00 00 ea     b       #44 <arm_caller+0x48>
+// CHECK-PI-ARM-NEXT: 1318:       78 ff ff ea     b       #-544 <arm_callee1>
+// CHECK-PI-ARM-NEXT: 131c:       b7 00 00 0a     beq     #732 <arm_callee2>
+// CHECK-PI-ARM-NEXT: 1320:       b7 00 00 1a     bne     #732 <arm_callee3>
+// CHECK-PI-ARM-NEXT: 1324:       1e ff 2f e1     bx      lr
 // 0x1330 + 8 - 0x337 = 0x1001 = thumb_callee1
-// CHECK-PI-ARM-NEXT:     1328:       c9 cc 0f e3     movw    r12, #64713
-// CHECK-PI-ARM-NEXT:     132c:       ff cf 4f e3     movt    r12, #65535
-// CHECK-PI-ARM-NEXT:     1330:       0f c0 8c e0     add     r12, r12, pc
-// CHECK-PI-ARM-NEXT:     1334:       1c ff 2f e1     bx      r12
-// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thumb_callee2:
-
-// CHECK-PI-ARM-NEXT:     1338:       b9 c1 00 e3     movw    r12, #441
-// CHECK-PI-ARM-NEXT:     133c:       00 c0 40 e3     movt    r12, #0
-// CHECK-PI-ARM-NEXT:     1340:       0f c0 8c e0     add     r12, r12, pc
-// CHECK-PI-ARM-NEXT:     1344:       1c ff 2f e1     bx      r12
-// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thumb_callee3:
+// CHECK-PI-ARM-NEXT: 1328:       c9 cc 0f e3     movw    r12, #64713
+// CHECK-PI-ARM-NEXT: 132c:       ff cf 4f e3     movt    r12, #65535
+// CHECK-PI-ARM-NEXT: 1330:       0f c0 8c e0     add     r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1334:       1c ff 2f e1     bx      r12
 // 0x1340 + 8 + 0x1b9 = 0x1501
-// CHECK-PI-ARM-NEXT:     1348:       ab c1 00 e3     movw    r12, #427
-// CHECK-PI-ARM-NEXT:     134c:       00 c0 40 e3     movt    r12, #0
-// CHECK-PI-ARM-NEXT:     1350:       0f c0 8c e0     add     r12, r12, pc
-// CHECK-PI-ARM-NEXT:     1354:       1c ff 2f e1     bx      r12
+// CHECK-PI-ARM-NEXT: 1338:       b9 c1 00 e3     movw    r12, #441
+// CHECK-PI-ARM-NEXT: 133c:       00 c0 40 e3     movt    r12, #0
+// CHECK-PI-ARM-NEXT: 1340:       0f c0 8c e0     add     r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1344:       1c ff 2f e1     bx      r12
 // 1350 + 8 + 0x1ab = 0x1503
+// CHECK-PI-ARM-NEXT: 1348:       ab c1 00 e3     movw    r12, #427
+// CHECK-PI-ARM-NEXT: 134c:       00 c0 40 e3     movt    r12, #0
+// CHECK-PI-ARM-NEXT: 1350:       0f c0 8c e0     add     r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1354:       1c ff 2f e1     bx      r12
 
 // All PLT entries are ARM, no need for interworking thunks
 // CHECK-PI-ARM-PLT: Disassembly of section .arm_caller:
@@ -185,58 +182,60 @@ thumb_caller:
  bne.w arm_callee3
 // CHECK-ABS-THUMB: Disassembly of section .thumb_caller:
 // CHECK-ABS-THUMB-NEXT: thumb_caller:
-// CHECK-ABS-THUMB-NEXT:     1400:       ff f7 7e ee     blx     #-772
-// CHECK-ABS-THUMB-NEXT:     1404:       ff f7 7c ee     blx     #-776
-// CHECK-ABS-THUMB-NEXT:     1408:       00 f0 0a b8     b.w     #20 <__ThumbToARMv7ABSLongThunk_arm_callee1+0x4>
-// CHECK-ABS-THUMB-NEXT:     140c:       00 f0 0d b8     b.w     #26 <__ThumbToARMv7ABSLongThunk_arm_callee2+0x4>
-// CHECK-ABS-THUMB-NEXT:     1410:       00 f0 10 b8     b.w     #32 <__ThumbToARMv7ABSLongThunk_arm_callee3+0x4>
-// CHECK-ABS-THUMB-NEXT:     1414:       00 f0 04 80     beq.w   #8 <__ThumbToARMv7ABSLongThunk_arm_callee1+0x4>
-// CHECK-ABS-THUMB-NEXT:     1418:       00 f0 07 80     beq.w   #14 <__ThumbToARMv7ABSLongThunk_arm_callee2+0x4>
-// CHECK-ABS-THUMB-NEXT:     141c:       40 f0 0a 80     bne.w   #20 <__ThumbToARMv7ABSLongThunk_arm_callee3+0x4>
-// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm_callee1:
+// 0x1400 + 4 - 0x304 = 0x1100 = arm_callee1
+// CHECK-ABS-THUMB-NEXT: 1400:       ff f7 7e ee     blx     #-772
+// 0x1404 + 4 - 0x308 = 0x1100 = arm_callee1
+// CHECK-ABS-THUMB-NEXT: 1404:       ff f7 7c ee     blx     #-776
+// 0x1408 + 4 + 0x14 = 0x520
+// CHECK-ABS-THUMB-NEXT: 1408:       00 f0 0a b8     b.w     #20
+// 0x140c + 4 + 0x1a = 0x52a
+// CHECK-ABS-THUMB-NEXT: 140c:       00 f0 0d b8     b.w     #26
+// 0x1410 + 4 + 0x20 = 0x534
+// CHECK-ABS-THUMB-NEXT: 1410:       00 f0 10 b8     b.w     #32
+// 0x1414 + 4 + 8 = 0x520
+// CHECK-ABS-THUMB-NEXT: 1414:       00 f0 04 80     beq.w   #8
+// 0x1418 + 4 + 0xe = 0x52a
+// CHECK-ABS-THUMB-NEXT: 1418:       00 f0 07 80     beq.w   #14
+// 0x141c + 4 + 0x14 = 0x534
+// CHECK-ABS-THUMB-NEXT: 141c:       40 f0 0a 80     bne.w   #20
 // 0x1100 = arm_callee1
-// CHECK-ABS-THUMB-NEXT:     1420:       41 f2 00 1c     movw    r12, #4352
-// CHECK-ABS-THUMB-NEXT:     1424:       c0 f2 00 0c     movt    r12, #0
-// CHECK-ABS-THUMB-NEXT:     1428:       60 47   bx      r12
-// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm_callee2:
+// CHECK-ABS-THUMB-NEXT: 1420:       41 f2 00 1c     movw    r12, #4352
+// CHECK-ABS-THUMB-NEXT: 1424:       c0 f2 00 0c     movt    r12, #0
+// CHECK-ABS-THUMB-NEXT: 1428:       60 47   bx      r12
 // 0x1600 = arm_callee2
-// CHECK-ABS-THUMB-NEXT:     142a:       41 f2 00 6c     movw    r12, #5632
-// CHECK-ABS-THUMB-NEXT:     142e:       c0 f2 00 0c     movt    r12, #0
-// CHECK-ABS-THUMB-NEXT:     1432:       60 47   bx      r12
+// CHECK-ABS-THUMB-NEXT: 142a:       41 f2 00 6c     movw    r12, #5632
+// CHECK-ABS-THUMB-NEXT: 142e:       c0 f2 00 0c     movt    r12, #0
+// CHECK-ABS-THUMB-NEXT: 1432:       60 47   bx      r12
 // 0x1604 = arm_callee3
-// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm_callee3:
-// CHECK-ABS-THUMB-NEXT:     1434:   41 f2 04 6c     movw    r12, #5636
-// CHECK-ABS-THUMB-NEXT:     1438:       c0 f2 00 0c     movt    r12, #0
-// CHECK-ABS-THUMB-NEXT:     143c:       60 47   bx      r12
+// CHECK-ABS-THUMB-NEXT: 1434:       41 f2 04 6c     movw    r12, #5636
+// CHECK-ABS-THUMB-NEXT: 1438:       c0 f2 00 0c     movt    r12, #0
+// CHECK-ABS-THUMB-NEXT: 143c:       60 47   bx      r12
 
 // CHECK-PI-THUMB: Disassembly of section .thumb_caller:
 // CHECK-PI-THUMB-NEXT: thumb_caller:
-// CHECK-PI-THUMB-NEXT:     1400:       ff f7 7e ee     blx     #-772
-// CHECK-PI-THUMB-NEXT:     1404:       ff f7 7c ee     blx     #-776
-// CHECK-PI-THUMB-NEXT:     1408:       00 f0 0a b8     b.w     #20 <__ThumbToARMV7PILongThunk_arm_callee1+0x4>
-// CHECK-PI-THUMB-NEXT:     140c:       00 f0 0e b8     b.w     #28 <__ThumbToARMV7PILongThunk_arm_callee2+0x4>
-// CHECK-PI-THUMB-NEXT:     1410:       00 f0 12 b8     b.w     #36 <__ThumbToARMV7PILongThunk_arm_callee3+0x4>
-// CHECK-PI-THUMB-NEXT:     1414:       00 f0 04 80     beq.w   #8 <__ThumbToARMV7PILongThunk_arm_callee1+0x4>
-// CHECK-PI-THUMB-NEXT:     1418:       00 f0 08 80     beq.w   #16 <__ThumbToARMV7PILongThunk_arm_callee2+0x4>
-// CHECK-PI-THUMB-NEXT:     141c:       40 f0 0c 80     bne.w   #24 <__ThumbToARMV7PILongThunk_arm_callee3+0x4>
-// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_callee1:
+// CHECK-PI-THUMB-NEXT: 1400:       ff f7 7e ee     blx     #-772
+// CHECK-PI-THUMB-NEXT: 1404:       ff f7 7c ee     blx     #-776
+// CHECK-PI-THUMB-NEXT: 1408:       00 f0 0a b8     b.w     #20
+// CHECK-PI-THUMB-NEXT: 140c:       00 f0 0e b8     b.w     #28
+// CHECK-PI-THUMB-NEXT: 1410:       00 f0 12 b8     b.w     #36
+// CHECK-PI-THUMB-NEXT: 1414:       00 f0 04 80     beq.w   #8
+// CHECK-PI-THUMB-NEXT: 1418:       00 f0 08 80     beq.w   #16
+// CHECK-PI-THUMB-NEXT: 141c:       40 f0 0c 80     bne.w   #24
 // 0x1428 + 4 - 0x32c = 0x1100 = arm_callee1
-// CHECK-PI-THUMB-NEXT:     1420:       4f f6 d4 4c     movw    r12, #64724
-// CHECK-PI-THUMB-NEXT:     1424:       cf f6 ff 7c     movt    r12, #65535
-// CHECK-PI-THUMB-NEXT:     1428:       fc 44   add     r12, pc
-// CHECK-PI-THUMB-NEXT:     142a:       60 47   bx      r12
-// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_callee2:
+// CHECK-PI-THUMB-NEXT: 1420:       4f f6 d4 4c     movw    r12, #64724
+// CHECK-PI-THUMB-NEXT: 1424:       cf f6 ff 7c     movt    r12, #65535
+// CHECK-PI-THUMB-NEXT: 1428:       fc 44   add     r12, pc
+// CHECK-PI-THUMB-NEXT: 142a:       60 47   bx      r12
 // 0x1434 + 4 + 0x1c8 = 0x1600 = arm_callee2
-// CHECK-PI-THUMB-NEXT:     142c:       40 f2 c8 1c     movw    r12, #456
-// CHECK-PI-THUMB-NEXT:     1430:       c0 f2 00 0c     movt    r12, #0
-// CHECK-PI-THUMB-NEXT:     1434:       fc 44   add     r12, pc
-// CHECK-PI-THUMB-NEXT:     1436:       60 47   bx      r12
-// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_callee3:
+// CHECK-PI-THUMB-NEXT: 142c:       40 f2 c8 1c     movw    r12, #456
+// CHECK-PI-THUMB-NEXT: 1430:       c0 f2 00 0c     movt    r12, #0
+// CHECK-PI-THUMB-NEXT: 1434:       fc 44   add     r12, pc
+// CHECK-PI-THUMB-NEXT: 1436:       60 47   bx      r12
 // 0x1440 + 4 + 0x1c0 = 0x1604 = arm_callee3
-// CHECK-PI-THUMB-NEXT:     1438:       40 f2 c0 1c     movw    r12, #448
-// CHECK-PI-THUMB-NEXT:     143c:       c0 f2 00 0c     movt    r12, #0
-// CHECK-PI-THUMB-NEXT:     1440:       fc 44   add     r12, pc
-// CHECK-PI-THUMB-NEXT:     1442:       60 47   bx      r12
+// CHECK-PI-THUMB-NEXT: 1438:       40 f2 c0 1c     movw    r12, #448
+// CHECK-PI-THUMB-NEXT: 143c:       c0 f2 00 0c     movt    r12, #0
+// CHECK-PI-THUMB-NEXT: 1440:       fc 44   add     r12, pc
+// CHECK-PI-THUMB-NEXT: 1442:       60 47   bx      r12
 
 // CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller:
 // CHECK-PI-THUMB-PLT-NEXT: thumb_caller:

Modified: lld/trunk/test/ELF/mips-npic-call-pic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-npic-call-pic.s?rev=293352&r1=293351&r2=293352&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-npic-call-pic.s (original)
+++ lld/trunk/test/ELF/mips-npic-call-pic.s Fri Jan 27 18:48:06 2017
@@ -15,65 +15,60 @@
 
 # CHECK:     Disassembly of section .text:
 # CHECK-NEXT: __start:
-# CHECK-NEXT:    20000:       0c 00 80 0c     jal     131120 <__LA25Thunk_foo1a>
+# CHECK-NEXT:    20000:       0c 00 80 0e     jal     131128 <foo1b+0x4>
+#                                                            ^-- .pic.foo1a
 # CHECK-NEXT:    20004:       00 00 00 00     nop
-# CHECK-NEXT:    20008:       0c 00 80 16     jal     131160 <__LA25Thunk_foo2>
+# CHECK-NEXT:    20008:       0c 00 80 19     jal     131172 <foo2+0x4>
+#                                                            ^-- .pic.foo2
 # CHECK-NEXT:    2000c:       00 00 00 00     nop
-# CHECK-NEXT:    20010:       0c 00 80 10     jal     131136 <__LA25Thunk_foo1b>
+# CHECK-NEXT:    20010:       0c 00 80 12     jal     131144 <foo1b+0x14>
+#                                                            ^-- .pic.foo1b
 # CHECK-NEXT:    20014:       00 00 00 00     nop
-# CHECK-NEXT:    20018:       0c 00 80 16     jal     131160 <__LA25Thunk_foo2>
+# CHECK-NEXT:    20018:       0c 00 80 19     jal     131172 <foo2+0x4>
+#                                                            ^-- .pic.foo2
 # CHECK-NEXT:    2001c:       00 00 00 00     nop
-# CHECK-NEXT:    20020:       0c 00 80 1d     jal     131188 <__LA25Thunk_fpic>
+# CHECK-NEXT:    20020:       0c 00 80 25     jal     131220 <fnpic+0x4>
+#                                                            ^-- .pic.fpic
 # CHECK-NEXT:    20024:       00 00 00 00     nop
-# CHECK-NEXT:    20028:       0c 00 80 28     jal     131232 <fnpic>
+# CHECK-NEXT:    20028:       0c 00 80 24     jal     131216 <fnpic>
 # CHECK-NEXT:    2002c:       00 00 00 00     nop
 #
-# CHECK: __LA25Thunk_foo1a:
-# CHECK-NEXT:    20030:       3c 19 00 02     lui     $25, 2
-# CHECK-NEXT:    20034:       08 00 80 14     j       131152 <foo1a>
-# CHECK-NEXT:    20038:       27 39 00 50     addiu   $25, $25, 80
-# CHECK-NEXT:    2003c:       00 00 00 00     nop
-
-# CHECK: __LA25Thunk_foo1b:
-# CHECK-NEXT:    20040:       3c 19 00 02     lui     $25, 2
-# CHECK-NEXT:    20044:       08 00 80 15     j       131156 <foo1b>
-# CHECK-NEXT:    20048:       27 39 00 54     addiu   $25, $25, 84
-# CHECK-NEXT:    2004c:       00 00 00 00     nop
-
-# CHECK: foo1a:
-# CHECK-NEXT:    20050:       00 00 00 00     nop
-
-# CHECK: foo1b:
+# CHECK:      foo1a:
+# CHECK-NEXT:    20030:       00 00 00 00     nop
+#
+# CHECK:      foo1b:
+# CHECK-NEXT:    20034:       00 00 00 00     nop
+#
+# CHECK-NEXT:    20038:       3c 19 00 02     lui     $25, 2
+# CHECK-NEXT:    2003c:       08 00 80 0c     j       131120 <foo1a>
+# CHECK-NEXT:    20040:       27 39 00 30     addiu   $25, $25, 48
+# CHECK-NEXT:    20044:       00 00 00 00     nop
+# CHECK-NEXT:    20048:       3c 19 00 02     lui     $25, 2
+# CHECK-NEXT:    2004c:       08 00 80 0d     j       131124 <foo1b>
+# CHECK-NEXT:    20050:       27 39 00 34     addiu   $25, $25, 52
 # CHECK-NEXT:    20054:       00 00 00 00     nop
-
-# CHECK: __LA25Thunk_foo2:
-# CHECK-NEXT:    20058:       3c 19 00 02     lui     $25, 2
-# CHECK-NEXT:    2005c:       08 00 80 1c     j       131184 <foo2>
-# CHECK-NEXT:    20060:       27 39 00 70     addiu   $25, $25, 112
-# CHECK-NEXT:    20064:       00 00 00 00     nop
-# CHECK-NEXT:    20068:       00 00 00 00     nop
-# CHECK-NEXT:    2006c:       00 00 00 00     nop
-
-# CHECK: foo2:
+# CHECK-NEXT:    20058:       00 00 00 00     nop
+# CHECK-NEXT:    2005c:       00 00 00 00     nop
+#
+# CHECK:      foo2:
+# CHECK-NEXT:    20060:       00 00 00 00     nop
+#
+# CHECK-NEXT:    20064:       3c 19 00 02     lui     $25, 2
+# CHECK-NEXT:    20068:       08 00 80 18     j       131168 <foo2>
+# CHECK-NEXT:    2006c:       27 39 00 60     addiu   $25, $25, 96
 # CHECK-NEXT:    20070:       00 00 00 00     nop
-
-# CHECK: __LA25Thunk_fpic:
-# CHECK-NEXT:    20074:       3c 19 00 02     lui     $25, 2
-# CHECK-NEXT:    20078:       08 00 80 24     j       131216 <fpic>
-# CHECK-NEXT:    2007c:       27 39 00 90     addiu   $25, $25, 144
-# CHECK-NEXT:    20080:       00 00 00 00     nop
-# CHECK-NEXT:    20084:       00 00 00 00     nop
-# CHECK-NEXT:    20088:       00 00 00 00     nop
-# CHECK-NEXT:    2008c:       00 00 00 00     nop
-
-# CHECK: fpic:
+# CHECK-NEXT:    20074:       00 00 00 00     nop
+# CHECK-NEXT:    20078:       00 00 00 00     nop
+# CHECK-NEXT:    2007c:       00 00 00 00     nop
+#
+# CHECK:       fpic:
+# CHECK-NEXT:    20080:	      00 00 00 00     nop
+#
+# CHECK:       fnpic:
 # CHECK-NEXT:    20090:       00 00 00 00     nop
-# CHECK-NEXT:    20094:       00 00 00 00     nop
-# CHECK-NEXT:    20098:       00 00 00 00     nop
-# CHECK-NEXT:    2009c:       00 00 00 00     nop
-
-# CHECK: fnpic:
-# CHECK-NEXT:    200a0:       00 00 00 00     nop
+# CHECK-NEXT:    20094:       3c 19 00 02     lui     $25, 2
+# CHECK-NEXT:    20098:       08 00 80 20     j       131200 <fpic>
+# CHECK-NEXT:    2009c:       27 39 00 80     addiu   $25, $25, 128
 
 # Make sure the thunks are created properly no matter how
 # objects are laid out.
@@ -81,58 +76,54 @@
 # RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe
 # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
 
-# REVERSE: Disassembly of section .text:
-# REVERSE-NEXT: __LA25Thunk_foo1a:
-# REVERSE-NEXT:    20000:       3c 19 00 02     lui     $25, 2
-# REVERSE-NEXT:    20004:       08 00 80 08     j       131104 <foo1a>
-# REVERSE-NEXT:    20008:       27 39 00 20     addiu   $25, $25, 32
-# REVERSE-NEXT:    2000c:       00 00 00 00     nop
-# REVERSE: __LA25Thunk_foo1b:
-# REVERSE-NEXT:    20010:       3c 19 00 02     lui     $25, 2
-# REVERSE-NEXT:    20014:       08 00 80 09     j       131108 <foo1b>
-# REVERSE-NEXT:    20018:       27 39 00 24     addiu   $25, $25, 36
-# REVERSE-NEXT:    2001c:       00 00 00 00     nop
-# REVERSE: foo1a:
-# REVERSE-NEXT:    20020:       00 00 00 00     nop
-# REVERSE: foo1b:
+# REVERSE:      foo1a:
+# REVERSE-NEXT:    20000:       00 00 00 00     nop
+#
+# REVERSE:      foo1b:
+# REVERSE-NEXT:    20004:       00 00 00 00     nop
+# REVERSE-NEXT:    20008:       3c 19 00 02     lui     $25, 2
+# REVERSE-NEXT:    2000c:       08 00 80 00     j       131072 <foo1a>
+# REVERSE-NEXT:    20010:       27 39 00 00     addiu   $25, $25, 0
+# REVERSE-NEXT:    20014:       00 00 00 00     nop
+# REVERSE-NEXT:    20018:       3c 19 00 02     lui     $25, 2
+# REVERSE-NEXT:    2001c:       08 00 80 01     j       131076 <foo1b>
+# REVERSE-NEXT:    20020:       27 39 00 04     addiu   $25, $25, 4
 # REVERSE-NEXT:    20024:       00 00 00 00     nop
-# REVERSE: __LA25Thunk_foo2:
-# REVERSE-NEXT:    20028:       3c 19 00 02     lui     $25, 2
-# REVERSE-NEXT:    2002c:       08 00 80 10     j       131136 <foo2>
-# REVERSE-NEXT:    20030:       27 39 00 40     addiu   $25, $25, 64
-# REVERSE-NEXT:    20034:       00 00 00 00     nop
-# REVERSE-NEXT:    20038:       00 00 00 00     nop
-# REVERSE-NEXT:    2003c:       00 00 00 00     nop
-# REVERSE: foo2:
+# REVERSE-NEXT:    20028:       00 00 00 00     nop
+# REVERSE-NEXT:    2002c:       00 00 00 00     nop
+#
+# REVERSE:      foo2:
+# REVERSE-NEXT:    20030:       00 00 00 00     nop
+# REVERSE-NEXT:    20034:       3c 19 00 02     lui     $25, 2
+# REVERSE-NEXT:    20038:       08 00 80 0c     j       131120 <foo2>
+# REVERSE-NEXT:    2003c:       27 39 00 30     addiu   $25, $25, 48
 # REVERSE-NEXT:    20040:       00 00 00 00     nop
 # REVERSE-NEXT:    20044:       00 00 00 00     nop
 # REVERSE-NEXT:    20048:       00 00 00 00     nop
 # REVERSE-NEXT:    2004c:       00 00 00 00     nop
-# REVERSE: __start:
-# REVERSE-NEXT:    20050:       0c 00 80 00     jal     131072 <__LA25Thunk_foo1a>
+#
+# REVERSE:      __start:
+# REVERSE-NEXT:    20050:       0c 00 80 02     jal     131080 <foo1b+0x4>
 # REVERSE-NEXT:    20054:       00 00 00 00     nop
-# REVERSE-NEXT:    20058:       0c 00 80 0a     jal     131112 <__LA25Thunk_foo2>
+# REVERSE-NEXT:    20058:       0c 00 80 0d     jal     131124 <foo2+0x4>
 # REVERSE-NEXT:    2005c:       00 00 00 00     nop
-# REVERSE-NEXT:    20060:       0c 00 80 04     jal     131088 <__LA25Thunk_foo1b>
+# REVERSE-NEXT:    20060:       0c 00 80 06     jal     131096 <foo1b+0x14>
 # REVERSE-NEXT:    20064:       00 00 00 00     nop
-# REVERSE-NEXT:    20068:       0c 00 80 0a     jal     131112 <__LA25Thunk_foo2>
+# REVERSE-NEXT:    20068:       0c 00 80 0d     jal     131124 <foo2+0x4>
 # REVERSE-NEXT:    2006c:       00 00 00 00     nop
-# REVERSE-NEXT:    20070:       0c 00 80 20     jal     131200 <__LA25Thunk_fpic>
+# REVERSE-NEXT:    20070:       0c 00 80 25     jal     131220 <fnpic+0x4>
 # REVERSE-NEXT:    20074:       00 00 00 00     nop
-# REVERSE-NEXT:    20078:       0c 00 80 28     jal     131232 <fnpic>
+# REVERSE-NEXT:    20078:       0c 00 80 24     jal     131216 <fnpic>
 # REVERSE-NEXT:    2007c:       00 00 00 00     nop
-# REVERSE: __LA25Thunk_fpic:
-# REVERSE-NEXT:    20080:       3c 19 00 02     lui     $25, 2
-# REVERSE-NEXT:    20084:       08 00 80 24     j       131216 <fpic>
-# REVERSE-NEXT:    20088:       27 39 00 90     addiu   $25, $25, 144
-# REVERSE-NEXT:    2008c:       00 00 00 00     nop
-# REVERSE: fpic:
+#
+# REVERSE:       fpic:
+# REVERSE-NEXT:    20080:       00 00 00 00     nop
+#
+# REVERSE:       fnpic:
 # REVERSE-NEXT:    20090:       00 00 00 00     nop
-# REVERSE-NEXT:    20094:       00 00 00 00     nop
-# REVERSE-NEXT:    20098:       00 00 00 00     nop
-# REVERSE-NEXT:    2009c:       00 00 00 00     nop
-# REVERSE: fnpic:
-# REVERSE-NEXT:    200a0:       00 00 00 00     nop
+# REVERSE-NEXT:    20094:       3c 19 00 02     lui     $25, 2
+# REVERSE-NEXT:    20098:       08 00 80 20     j       131200 <fpic>
+# REVERSE-NEXT:    2009c:       27 39 00 80     addiu   $25, $25, 128
 
   .text
   .globl __start




More information about the llvm-commits mailing list