[lld] r293283 - [ELF][ARM] Use SyntheticSections for Thunks
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 31 12:09:13 PST 2017
I'm sorry, Peter. I should have described what I tried in the original
mail. I tried to change the type from ThunkSection to InputSection and saw
the exact same runtime test failure, so I reverted the patch. I'll share
more information next time to not waste your time.
On Mon, Jan 30, 2017 at 12:25 PM, Peter Smith <peter.smith at linaro.org>
wrote:
> Apologies again, it is worse than I thought. After making the change
> the build passes, but the Thunk tests fail with assertion failures in
> the Mips Thunk test.
>
> The MSVC debug implementation of merge uses the _same_ predicate to
> check that both sets of input iterators are ordered before even doing
> the merge.
>
> This means that the predicate has to work on both the InputSections
> with prior to inserting the thunks, the thunks and the combination of
> thunks and no-thunks. In particular a 0 sized section in the Mips
> Thunk implementation trips this up.
>
> I'll need to either:
> - Provide a handwritten implementation of merge that only does what a
> release build does.
> - Disable the debug iterators in MSVC by undefining the macros before
> calling merge, then re-enabling them.
> - Make a comparison operator that works.
>
> I'll send out what I come up with for review again. This is more than
> just a trivial change.
>
> Peter
>
> On 30 January 2017 at 17:55, Peter Smith <peter.smith at linaro.org> wrote:
> > Apologies for the delay, it took a while to get a Windows environment
> setup.
> >
> > I've tracked it down to the MSVC _Debug_lt_pred which does an
> > additional A < B and B < A. This won't compile for:
> > auto MergeCmp = [](const ThunkSection<ELFT> *Thunk,
> > const InputSection<ELFT> *IS)
> > as InputSection<ELFT> *IS can't be cast to ThunkSection<ELFT>* for the
> > additional debug pred test.
> >
> > This can be fixed by changing ThunkSection<ELFT> *Thunk to
> > InputSection<ELFT> *Thunk.
> >
> > I'll rebase and recommit tomorrow morning (UK time).
> >
> > Peter
> >
> > On 30 January 2017 at 10:20, Peter Smith <peter.smith at linaro.org> wrote:
> >> My apologies, thanks for reverting it.
> >>
> >> It looks like I'm going to have to set up a MSVC debug build to
> >> reproduce and make sure it is fixed as I can't immediately see the
> >> problem from the message above. Will resubmit as soon as I can.
> >>
> >> Peter
> >>
> >> On 28 January 2017 at 01:01, Rui Ueyama <ruiu at google.com> wrote:
> >>> Peter,
> >>>
> >>> I had to roll back this in r293352 because it broke MSVC debug build
> and I
> >>> couldn't fix it immediately. Please take a look and re-submit.
> >>>
> >>>
> >>> D:\llvm-project\lld\ELF\Relocations.cpp(833): note: see reference to
> >>> function template instantiation '_OutIt
> >>> std::merge<std::_Vector_iterator<std::_Vector_val<std::_
> Simple_types<lld::elf::InputSection<ELFT>
> >>>>>>,std::_Vector_iterator<std::_V
> >>> ector_val<std::_Simple_types<lld::elf::ThunkSection<ELFT>
> >>> *>>>,std::back_insert_iterator<std::vector<lld::elf::
> InputSection<ELFT>
> >>> *,std::allocator<_Ty>>>,lld::elf::mergeThunks::<lambda_b339c
> aca889e68d37c4499c447b8b3c1>>(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt,_Pr)'
> >>> being compiled
> >>> with
> >>> [
> >>>
> >>> _OutIt=std::back_insert_iterator<std::vector<lld::elf::
> InputSection<llvm::object::ELF32BE>
> >>> *,std::allocator<lld::elf::InputSection<llvm::object::ELF32BE> >>>,
> >>> ELFT=llvm::object::ELF32BE,
> >>> _Ty=lld::elf::InputSection<llvm::object::ELF32BE> *,
> >>>
> >>> _InIt1=std::_Vector_iterator<std::_Vector_val<std::_Simple_t
> ypes<lld::elf::InputSection<llvm::object::ELF32BE>
> >>>>>>,
> >>>
> >>> _InIt2=std::_Vector_iterator<std::_Vector_val<std::_Simple_t
> ypes<lld::elf::ThunkSection<llvm::object::ELF32BE>
> >>>>>>,
> >>>
> >>> _Pr=lld::elf::mergeThunks::<lambda_b339caca889e68d37c4499c447b8b3c1>
> >>> ]
> >>> D:\llvm-project\lld\ELF\Relocations.cpp(924): note: see reference to
> >>> function template instantiation 'void
> >>> lld::elf::mergeThunks<ELFT>(lld::elf::OutputSection<ELFT>
> >>> *,std::vector<lld::elf::ThunkSection<ELFT> *,std::allocator<_Ty>> &)'
> being
> >>> compiled
> >>> with
> >>> [
> >>> ELFT=llvm::object::ELF32BE,
> >>> _Ty=lld::elf::ThunkSection<llvm::object::ELF32BE> *
> >>> ]
> >>>
> >>>
> >>> On Fri, Jan 27, 2017 at 12:02 PM, Rafael Avila de Espindola via
> llvm-commits
> >>> <llvm-commits at lists.llvm.org> wrote:
> >>>>
> >>>> This is really nice. Thanks!
> >>>>
> >>>> Peter Smith via llvm-commits <llvm-commits at lists.llvm.org> writes:
> >>>>
> >>>> > Author: psmith
> >>>> > Date: Fri Jan 27 07:10:16 2017
> >>>> > New Revision: 293283
> >>>> >
> >>>> > URL: http://llvm.org/viewvc/llvm-project?rev=293283&view=rev
> >>>> > Log:
> >>>> > [ELF][ARM] Use SyntheticSections for Thunks
> >>>> >
> >>>> > Thunks are now implemented by redirecting the relocation to the
> >>>> > symbol S, to a symbol TS in a Thunk. The Thunk will transfer control
> >>>> > to S. This has the following implications:
> >>>> > - All the side-effects of Thunks happen within createThunks()
> >>>> > - Thunks are no longer stored in InputSections and Symbols no longer
> >>>> > need to hold a pointer to a Thunk
> >>>> > - The synthetic Thunk sections need to be merged into OutputSections
> >>>> >
> >>>> > This implementation is almost a direct conversion of the existing
> >>>> > Thunks with the following exceptions:
> >>>> > - Mips LA25 Thunks are placed before the InputSection that defines
> >>>> > the symbol that needs a Thunk.
> >>>> > - All ARM Thunks are placed at the end of the OutputSection of the
> >>>> > first caller to the Thunk.
> >>>> >
> >>>> > Range extension Thunks are not supported yet so it is optimistically
> >>>> > assumed that all Thunks can be reused.
> >>>> >
> >>>> > Differential Revision: https://reviews.llvm.org/D29129
> >>>> >
> >>>> >
> >>>> > 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/InputFiles.cpp (original)
> >>>> > +++ lld/trunk/ELF/InputFiles.cpp Fri Jan 27 07:10:16 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<ELFT>(Name, /*IsLocal=*/true, StOther, Type,
> this);
> >>>> > + Undefined(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/InputSecti
> on.cpp?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/InputSection.cpp (original)
> >>>> > +++ lld/trunk/ELF/InputSection.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -99,10 +99,6 @@ 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();
> >>>> > }
> >>>> >
> >>>> > @@ -214,21 +210,6 @@ 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.
> >>>> > @@ -302,11 +283,6 @@ 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:
> >>>> > @@ -551,19 +527,6 @@ 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/InputSecti
> on.h?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/InputSection.h (original)
> >>>> > +++ lld/trunk/ELF/InputSection.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -280,17 +280,6 @@ 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);
> >>>> >
> >>>> > @@ -303,8 +292,6 @@ 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?re
> v=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/LTO.cpp (original)
> >>>> > +++ lld/trunk/ELF/LTO.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -96,12 +96,12 @@ BitcodeCompiler::BitcodeCompiler() : LTO
> >>>> >
> >>>> > BitcodeCompiler::~BitcodeCompiler() = default;
> >>>> >
> >>>> > -template <class ELFT> static void undefine(Symbol *S) {
> >>>> > - replaceBody<Undefined<ELFT>>(S, S->body()->getName(),
> >>>> > /*IsLocal=*/false,
> >>>> > - STV_DEFAULT, S->body()->Type,
> nullptr);
> >>>> > +static void undefine(Symbol *S) {
> >>>> > + replaceBody<Undefined>(S, S->body()->getName(),
> /*IsLocal=*/false,
> >>>> > + STV_DEFAULT, S->body()->Type, nullptr);
> >>>> > }
> >>>> >
> >>>> > -template <class ELFT> void BitcodeCompiler::add(BitcodeFile &F) {
> >>>> > +void BitcodeCompiler::add(BitcodeFile &F) {
> >>>> > lto::InputFile &Obj = *F.Obj;
> >>>> > unsigned SymNum = 0;
> >>>> > std::vector<Symbol *> Syms = F.getSymbols();
> >>>> > @@ -126,7 +126,7 @@ template <class ELFT> void BitcodeCompil
> >>>> > R.VisibleToRegularObj =
> >>>> > Sym->IsUsedInRegularObj || (R.Prevailing &&
> >>>> > Sym->includeInDynsym());
> >>>> > if (R.Prevailing)
> >>>> > - undefine<ELFT>(Sym);
> >>>> > + undefine(Sym);
> >>>> > }
> >>>> > checkError(LTOObj->add(std::move(F.Obj), Resols));
> >>>> > }
> >>>> > @@ -157,8 +157,3 @@ 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=
> 293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/LTO.h (original)
> >>>> > +++ lld/trunk/ELF/LTO.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -43,7 +43,7 @@ public:
> >>>> > BitcodeCompiler();
> >>>> > ~BitcodeCompiler();
> >>>> >
> >>>> > - template <class ELFT> void add(BitcodeFile &F);
> >>>> > + 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/Relocation
> s.cpp?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Relocations.cpp (original)
> >>>> > +++ lld/trunk/ELF/Relocations.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -43,6 +43,7 @@
> >>>> >
> >>>> > #include "Relocations.h"
> >>>> > #include "Config.h"
> >>>> > +#include "Memory.h"
> >>>> > #include "OutputSections.h"
> >>>> > #include "Strings.h"
> >>>> > #include "SymbolTable.h"
> >>>> > @@ -52,6 +53,7 @@
> >>>> >
> >>>> > #include "llvm/Support/Endian.h"
> >>>> > #include "llvm/Support/raw_ostream.h"
> >>>> > +#include <algorithm>
> >>>> >
> >>>> > using namespace llvm;
> >>>> > using namespace llvm::ELF;
> >>>> > @@ -300,16 +302,14 @@ 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,
> >>>> > - R_THUNK_PLT_PC>(Expr);
> >>>> > + return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT,
> >>>> > R_PLT_PAGE_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, R_THUNK_PC,
> >>>> > R_THUNK_PLT_PC>(
> >>>> > - Expr);
> >>>> > + R_PAGE_PC, R_RELAX_GOT_PC>(Expr);
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> > @@ -321,8 +321,7 @@ 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,
> >>>> > - R_THUNK_PC, R_THUNK_PLT_PC>(E))
> >>>> > + R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE,
> >>>> > R_HINT>(E))
> >>>> > return true;
> >>>> >
> >>>> > // These never do, except if the entire file is position
> dependent or
> >>>> > if
> >>>> > @@ -467,7 +466,6 @@ 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;
> >>>> > @@ -685,7 +683,6 @@ 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 =
> >>>> > @@ -805,33 +802,126 @@ 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 (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);
> >>>> > + 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);
> >>>> > + }
> >>>> > }
> >>>> > }
> >>>> > }
> >>>> > - // 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();
> >>>> > - }
> >>>> > +
> >>>> > + // Merge all created synthetic ThunkSections back into
> OutputSection
> >>>> > + for (auto &KV : ThunkSections)
> >>>> > + mergeThunks<ELFT>(KV.first, KV.second);
> >>>> > }
> >>>> >
> >>>> > template void scanRelocations<ELF32LE>(InputSectionBase<ELF32LE>
> &);
> >>>> >
> >>>> > Modified: lld/trunk/ELF/Relocations.h
> >>>> > URL:
> >>>> > http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocation
> s.h?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Relocations.h (original)
> >>>> > +++ lld/trunk/ELF/Relocations.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -61,9 +61,6 @@ 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/SymbolTabl
> e.cpp?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/SymbolTable.cpp (original)
> >>>> > +++ lld/trunk/ELF/SymbolTable.cpp Fri Jan 27 07:10:16 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<ELFT>(*F);
> >>>> > + LTO->add(*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<ELFT>>(S, Name, IsLocal, StOther, Type,
> >>>> > File);
> >>>> > + replaceBody<Undefined>(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<ELFT>>(S->body())) {
> >>>> > + if (WasInserted || isa<Undefined>(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.cp
> p?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Symbols.cpp (original)
> >>>> > +++ lld/trunk/ELF/Symbols.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -132,14 +132,6 @@ 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);
> >>>> > @@ -171,16 +163,6 @@ 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;
> >>>> > @@ -241,9 +223,8 @@ template <class ELFT> bool DefinedRegula
> >>>> > (Section->getFile()->getObj().getHeader()->e_flags &
> >>>> > EF_MIPS_PIC);
> >>>> > }
> >>>> >
> >>>> > -template <typename ELFT>
> >>>> > -Undefined<ELFT>::Undefined(StringRefZ Name, bool IsLocal, uint8_t
> >>>> > StOther,
> >>>> > - uint8_t Type, InputFile *File)
> >>>> > +Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t
> StOther,
> >>>> > + uint8_t Type, InputFile *File)
> >>>> > : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal,
> StOther,
> >>>> > Type) {
> >>>> > this->File = File;
> >>>> > }
> >>>> > @@ -338,11 +319,6 @@ 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;
> >>>> > @@ -363,11 +339,6 @@ 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;
> >>>> > @@ -383,11 +354,6 @@ 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Symbols.h (original)
> >>>> > +++ lld/trunk/ELF/Symbols.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -76,7 +76,6 @@ 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;
> >>>> > @@ -86,7 +85,6 @@ 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.
> >>>> > @@ -210,10 +208,6 @@ 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;
> >>>> > };
> >>>> > @@ -242,7 +236,7 @@ public:
> >>>> > const OutputSectionBase *Section;
> >>>> > };
> >>>> >
> >>>> > -template <class ELFT> class Undefined : public SymbolBody {
> >>>> > +class Undefined : public SymbolBody {
> >>>> > public:
> >>>> > Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t
> >>>> > Type,
> >>>> > InputFile *F);
> >>>> > @@ -251,12 +245,6 @@ 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; }
> >>>> > };
> >>>> >
> >>>> > @@ -291,9 +279,6 @@ 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;
> >>>> > @@ -431,8 +416,7 @@ struct Symbol {
> >>>> > // ELFT, and we verify this with the static_asserts in
> replaceBody.
> >>>> > llvm::AlignedCharArrayUnion<
> >>>> > DefinedCommon, DefinedRegular<llvm::object::ELF64LE>,
> >>>> > DefinedSynthetic,
> >>>> > - Undefined<llvm::object::ELF64LE>,
> >>>> > SharedSymbol<llvm::object::ELF64LE>,
> >>>> > - LazyArchive, LazyObject>
> >>>> > + Undefined, 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/SyntheticS
> ections.cpp?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/SyntheticSections.cpp (original)
> >>>> > +++ lld/trunk/ELF/SyntheticSections.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -1904,6 +1904,27 @@ 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();
> >>>> > @@ -2046,3 +2067,8 @@ 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/SyntheticS
> ections.h?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/SyntheticSections.h (original)
> >>>> > +++ lld/trunk/ELF/SyntheticSections.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -699,6 +699,26 @@ 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Target.cpp (original)
> >>>> > +++ lld/trunk/ELF/Target.cpp Fri Jan 27 07:10:16 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;
> >>>> > - RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const
> >>>> > InputFile *File,
> >>>> > - const SymbolBody &S) const override;
> >>>> > + bool needsThunk(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;
> >>>> > - RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const
> >>>> > InputFile *File,
> >>>> > - const SymbolBody &S) const override;
> >>>> > + bool needsThunk(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,10 +298,9 @@ uint64_t TargetInfo::getImplicitAddend(c
> >>>> >
> >>>> > bool TargetInfo::usesOnlyLowPageBits(uint32_t Type) const { return
> >>>> > false; }
> >>>> >
> >>>> > -RelExpr TargetInfo::getThunkExpr(RelExpr Expr, uint32_t RelocType,
> >>>> > - const InputFile *File,
> >>>> > - const SymbolBody &S) const {
> >>>> > - return Expr;
> >>>> > +bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
> >>>> > + const InputFile *File, const
> SymbolBody &S)
> >>>> > const {
> >>>> > + return false;
> >>>> > }
> >>>> >
> >>>> > bool TargetInfo::isTlsInitialExecRel(uint32_t Type) const { return
> >>>> > false; }
> >>>> > @@ -1771,15 +1770,15 @@ void ARMTargetInfo::addPltSymbols(InputS
> >>>> > addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
> >>>> > }
> >>>> >
> >>>> > -RelExpr ARMTargetInfo::getThunkExpr(RelExpr Expr, uint32_t
> RelocType,
> >>>> > - const InputFile *File,
> >>>> > - const SymbolBody &S) const {
> >>>> > +bool ARMTargetInfo::needsThunk(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 Expr;
> >>>> > + return false;
> >>>> > // 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.
> >>>> > @@ -1790,19 +1789,17 @@ RelExpr ARMTargetInfo::getThunkExpr(RelE
> >>>> > // 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 R_THUNK_PC;
> >>>> > + return true;
> >>>> > 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)
> >>>> > - return R_THUNK_PLT_PC;
> >>>> > - if ((S.getVA<ELF32LE>() & 1) == 0)
> >>>> > - return R_THUNK_PC;
> >>>> > + if (Expr == R_PLT_PC || ((S.getVA<ELF32LE>() & 1) == 0))
> >>>> > + return true;
> >>>> > break;
> >>>> > }
> >>>> > - return Expr;
> >>>> > + return false;
> >>>> > }
> >>>> >
> >>>> > void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
> >>>> > @@ -2215,26 +2212,26 @@ void MipsTargetInfo<ELFT>::writePlt(uint
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> > -RelExpr MipsTargetInfo<ELFT>::getThunkExpr(RelExpr Expr, uint32_t
> Type,
> >>>> > - const InputFile *File,
> >>>> > - const SymbolBody &S)
> const {
> >>>> > +bool MipsTargetInfo<ELFT>::needsThunk(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 Expr;
> >>>> > + return false;
> >>>> > auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
> >>>> > if (!F)
> >>>> > - return Expr;
> >>>> > + return false;
> >>>> > // If current file has PIC code, LA25 stub is not required.
> >>>> > if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
> >>>> > - return Expr;
> >>>> > + return false;
> >>>> > 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() ? R_THUNK_ABS : Expr;
> >>>> > + return D && D->isMipsPIC();
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> >
> >>>> > Modified: lld/trunk/ELF/Target.h
> >>>> > URL:
> >>>> > http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?
> rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Target.h (original)
> >>>> > +++ lld/trunk/ELF/Target.h Fri Jan 27 07:10:16 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,14 +51,9 @@ public:
> >>>> > virtual bool usesOnlyLowPageBits(uint32_t Type) const;
> >>>> >
> >>>> > // Decide whether a Thunk is needed for the relocation from File
> >>>> > - // 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;
> >>>> > + // targeting S.
> >>>> > + virtual bool needsThunk(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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Thunks.cpp (original)
> >>>> > +++ lld/trunk/ELF/Thunks.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -28,6 +28,7 @@
> >>>> > #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"
> >>>> > @@ -52,53 +53,54 @@ namespace {
> >>>> > template <class ELFT>
> >>>> > class ARMToThumbV7ABSLongThunk final : public Thunk<ELFT> {
> >>>> > public:
> >>>> > - ARMToThumbV7ABSLongThunk(const SymbolBody &Dest,
> >>>> > - const InputSection<ELFT> &Owner)
> >>>> > - : Thunk<ELFT>(Dest, Owner) {}
> >>>> > + ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) :
> Thunk<ELFT>(Dest)
> >>>> > {}
> >>>> >
> >>>> > uint32_t size() const override { return 12; }
> >>>> > - void writeTo(uint8_t *Buf) const override;
> >>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const
> override;
> >>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;
> >>>> > };
> >>>> >
> >>>> > template <class ELFT> class ARMToThumbV7PILongThunk final : public
> >>>> > Thunk<ELFT> {
> >>>> > public:
> >>>> > - ARMToThumbV7PILongThunk(const SymbolBody &Dest,
> >>>> > - const InputSection<ELFT> &Owner)
> >>>> > - : Thunk<ELFT>(Dest, Owner) {}
> >>>> > + ARMToThumbV7PILongThunk(const SymbolBody &Dest) :
> Thunk<ELFT>(Dest)
> >>>> > {}
> >>>> >
> >>>> > uint32_t size() const override { return 16; }
> >>>> > - void writeTo(uint8_t *Buf) const override;
> >>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const
> override;
> >>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;
> >>>> > };
> >>>> >
> >>>> > template <class ELFT>
> >>>> > class ThumbToARMV7ABSLongThunk final : public Thunk<ELFT> {
> >>>> > public:
> >>>> > - ThumbToARMV7ABSLongThunk(const SymbolBody &Dest,
> >>>> > - const InputSection<ELFT> &Owner)
> >>>> > - : Thunk<ELFT>(Dest, Owner) {}
> >>>> > + ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) :
> Thunk<ELFT>(Dest)
> >>>> > {
> >>>> > + this->alignment = 2;
> >>>> > + }
> >>>> >
> >>>> > uint32_t size() const override { return 10; }
> >>>> > - void writeTo(uint8_t *Buf) const override;
> >>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const
> override;
> >>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;
> >>>> > };
> >>>> >
> >>>> > template <class ELFT> class ThumbToARMV7PILongThunk final : public
> >>>> > Thunk<ELFT> {
> >>>> > public:
> >>>> > - ThumbToARMV7PILongThunk(const SymbolBody &Dest,
> >>>> > - const InputSection<ELFT> &Owner)
> >>>> > - : Thunk<ELFT>(Dest, Owner) {}
> >>>> > + ThumbToARMV7PILongThunk(const SymbolBody &Dest) :
> Thunk<ELFT>(Dest) {
> >>>> > + this->alignment = 2;
> >>>> > + }
> >>>> >
> >>>> > uint32_t size() const override { return 12; }
> >>>> > - void writeTo(uint8_t *Buf) const override;
> >>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const
> override;
> >>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;
> >>>> > };
> >>>> >
> >>>> > // MIPS LA25 thunk
> >>>> > template <class ELFT> class MipsThunk final : public Thunk<ELFT> {
> >>>> > public:
> >>>> > - MipsThunk(const SymbolBody &Dest, const InputSection<ELFT>
> &Owner)
> >>>> > - : Thunk<ELFT>(Dest, Owner) {}
> >>>> > + MipsThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
> >>>> >
> >>>> > uint32_t size() const override { return 16; }
> >>>> > - void writeTo(uint8_t *Buf) const override;
> >>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const
> override;
> >>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;
> >>>> > + InputSection<ELFT> *getTargetInputSection() const override;
> >>>> > };
> >>>> >
> >>>> > } // end anonymous namespace
> >>>> > @@ -110,7 +112,8 @@ template <class ELFT> static uint64_t ge
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> > -void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf) const {
> >>>> > +void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
> >>>> > + ThunkSection<ELFT>
> &IS)
> >>>> > const {
> >>>> > const uint8_t Data[] = {
> >>>> > 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
> >>>> > 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
> >>>> > @@ -123,7 +126,16 @@ void ARMToThumbV7ABSLongThunk<ELFT>::wri
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> > -void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf) const {
> >>>> > +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 {
> >>>> > const uint8_t Data[] = {
> >>>> > 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
> >>>> > 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
> >>>> > @@ -136,7 +148,16 @@ void ThumbToARMV7ABSLongThunk<ELFT>::wri
> >>>> > }
> >>>> >
> >>>> > template <class ELFT>
> >>>> > -void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf) const {
> >>>> > +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 {
> >>>> > 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)
> >>>> > @@ -144,14 +165,23 @@ void ARMToThumbV7PILongThunk<ELFT>::writ
> >>>> > 0x1c, 0xff, 0x2f, 0xe1, // bx r12
> >>>> > };
> >>>> > uint64_t S = getARMThunkDestVA<ELFT>(this->Destination);
> >>>> > - uint64_t P = this->getVA();
> >>>> > + uint64_t P = this->ThunkSym->template getVA<ELFT>();
> >>>> > 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 ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf) const {
> >>>> > +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 {
> >>>> > 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)
> >>>> > @@ -159,14 +189,23 @@ void ThumbToARMV7PILongThunk<ELFT>::writ
> >>>> > 0x60, 0x47, // bx r12
> >>>> > };
> >>>> > uint64_t S = getARMThunkDestVA<ELFT>(this->Destination);
> >>>> > - uint64_t P = this->getVA();
> >>>> > + uint64_t P = this->ThunkSym->template getVA<ELFT>();
> >>>> > 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)
> const
> >>>> > {
> >>>> > +template <class ELFT>
> >>>> > +void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection<ELFT> &)
> const
> >>>> > {
> >>>> > const endianness E = ELFT::TargetEndianness;
> >>>> >
> >>>> > uint64_t S = this->Destination.template getVA<ELFT>();
> >>>> > @@ -178,20 +217,26 @@ template <class ELFT> void MipsThunk<ELF
> >>>> > Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
> >>>> > }
> >>>> >
> >>>> > -template <class ELFT>
> >>>> > -Thunk<ELFT>::Thunk(const SymbolBody &D, const InputSection<ELFT>
> &O)
> >>>> > - : Destination(D), Owner(O), Offset(O.getThunkOff() +
> >>>> > O.getThunksSize()) {}
> >>>> > +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> typename ELFT::uint Thunk<ELFT>::getVA()
> const {
> >>>> > - return Owner.OutSec->Addr + Owner.OutSecOff + Offset;
> >>>> > +template <class ELFT>
> >>>> > +InputSection<ELFT> *MipsThunk<ELFT>::getTargetInputSection()
> const {
> >>>> > + auto *DR = dyn_cast<DefinedRegular<ELFT>>(&this->Destination);
> >>>> > + return dyn_cast<InputSection<ELFT>>(DR->Section);
> >>>> > }
> >>>> >
> >>>> > +template <class ELFT>
> >>>> > +Thunk<ELFT>::Thunk(const SymbolBody &D) : Destination(D),
> Offset(0) {}
> >>>> > +
> >>>> > template <class ELFT> Thunk<ELFT>::~Thunk() = default;
> >>>> >
> >>>> > // Creates a thunk for Thumb-ARM interworking.
> >>>> > template <class ELFT>
> >>>> > -static Thunk<ELFT> *createThunkArm(uint32_t Reloc, SymbolBody &S,
> >>>> > - InputSection<ELFT> &IS) {
> >>>> > +static Thunk<ELFT> *addThunkArm(uint32_t Reloc, SymbolBody &S) {
> >>>> > // 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.
> >>>> > @@ -200,71 +245,34 @@ static Thunk<ELFT> *createThunkArm(uint3
> >>>> > case R_ARM_PLT32:
> >>>> > case R_ARM_JUMP24:
> >>>> > if (Config->Pic)
> >>>> > - return new (BAlloc) ARMToThumbV7PILongThunk<ELFT>(S, IS);
> >>>> > - return new (BAlloc) ARMToThumbV7ABSLongThunk<ELFT>(S, IS);
> >>>> > + return make<ARMToThumbV7PILongThunk<ELFT>>(S);
> >>>> > + return make<ARMToThumbV7ABSLongThunk<ELFT>>(S);
> >>>> > case R_ARM_THM_JUMP19:
> >>>> > case R_ARM_THM_JUMP24:
> >>>> > if (Config->Pic)
> >>>> > - return new (BAlloc) ThumbToARMV7PILongThunk<ELFT>(S, IS);
> >>>> > - return new (BAlloc) ThumbToARMV7ABSLongThunk<ELFT>(S, IS);
> >>>> > + return make<ThumbToARMV7PILongThunk<ELFT>>(S);
> >>>> > + return make<ThumbToARMV7ABSLongThunk<ELFT>>(S);
> >>>> > }
> >>>> > fatal("unrecognized relocation type");
> >>>> > }
> >>>> >
> >>>> > -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> static Thunk<ELFT> *addThunkMips(SymbolBody
> &S) {
> >>>> > + return make<MipsThunk<ELFT>>(S);
> >>>> > }
> >>>> >
> >>>> > -template <class ELFT>
> >>>> > -void addThunk(uint32_t RelocType, SymbolBody &S, InputSection<ELFT>
> >>>> > &IS) {
> >>>> > +template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType,
> >>>> > SymbolBody &S) {
> >>>> > if (Config->EMachine == EM_ARM)
> >>>> > - addThunkARM<ELFT>(RelocType, S, IS);
> >>>> > + return addThunkArm<ELFT>(RelocType, S);
> >>>> > else if (Config->EMachine == EM_MIPS)
> >>>> > - addThunkMips<ELFT>(RelocType, S, IS);
> >>>> > - else
> >>>> > - llvm_unreachable("add Thunk only supported for ARM and Mips");
> >>>> > + return addThunkMips<ELFT>(S);
> >>>> > + llvm_unreachable("add Thunk only supported for ARM and Mips");
> >>>> > + return nullptr;
> >>>> > }
> >>>> >
> >>>> > -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 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 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Thunks.h (original)
> >>>> > +++ lld/trunk/ELF/Thunks.h Fri Jan 27 07:10:16 2017
> >>>> > @@ -15,8 +15,8 @@
> >>>> > namespace lld {
> >>>> > namespace elf {
> >>>> > class SymbolBody;
> >>>> > -template <class ELFT> class InputSection;
> >>>> > -
> >>>> > +template <class ELFT> class ThunkSection;
> >>>> > +class OutputSectionBase;
> >>>> > // 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,31 +24,35 @@ template <class ELFT> class InputSection
> >>>> > // include transferring control from non-pi to pi and changing
> state on
> >>>> > // targets like ARM.
> >>>> > //
> >>>> > -// 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.
> >>>> > +// Thunks can be created for DefinedRegular, Shared and Undefined
> >>>> > Symbols.
> >>>> > +// Thunks are assigned to synthetic ThunkSections
> >>>> > template <class ELFT> class Thunk {
> >>>> > - typedef typename ELFT::uint uintX_t;
> >>>> > -
> >>>> > public:
> >>>> > - Thunk(const SymbolBody &Destination, const InputSection<ELFT>
> >>>> > &Owner);
> >>>> > + Thunk(const SymbolBody &Destination);
> >>>> > virtual ~Thunk();
> >>>> >
> >>>> > virtual uint32_t size() const { return 0; }
> >>>> > - virtual void writeTo(uint8_t *Buf) const {}
> >>>> > - uintX_t getVA() const;
> >>>> > + 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; }
> >>>> >
> >>>> > -protected:
> >>>> > + // The alignment requirement for this Thunk, defaults to the
> size of
> >>>> > the
> >>>> > + // typical code section alignment.
> >>>> > const SymbolBody &Destination;
> >>>> > - const InputSection<ELFT> &Owner;
> >>>> > + SymbolBody *ThunkSym;
> >>>> > uint64_t Offset;
> >>>> > + uint32_t alignment = 4;
> >>>> > };
> >>>> >
> >>>> > -// 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);
> >>>> > +// 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);
> >>>> >
> >>>> > } // namespace elf
> >>>> > } // namespace lld
> >>>> >
> >>>> > Modified: lld/trunk/ELF/Writer.cpp
> >>>> > URL:
> >>>> > http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp
> ?rev=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/ELF/Writer.cpp (original)
> >>>> > +++ lld/trunk/ELF/Writer.cpp Fri Jan 27 07:10:16 2017
> >>>> > @@ -1027,6 +1027,12 @@ 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()) {
> >>>> > @@ -1072,12 +1078,6 @@ 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/test/ELF/arm-thumb-interwork-shared.s (original)
> >>>> > +++ lld/trunk/test/ELF/arm-thumb-interwork-shared.s Fri Jan 27
> 07:10:16
> >>>> > 2017
> >>>> > @@ -16,12 +16,15 @@ sym1:
> >>>> >
> >>>> > // CHECK: Disassembly of section .text:
> >>>> > // CHECK-NEXT: sym1:
> >>>> > -// CHECK: 1000: 00 f0 02 b8 b.w #4
> >>>> > -// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12
> >>>> > +// 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-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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/test/ELF/arm-thumb-interwork-thunk.s (original)
> >>>> > +++ lld/trunk/test/ELF/arm-thumb-interwork-thunk.s Fri Jan 27
> 07:10:16
> >>>> > 2017
> >>>> > @@ -78,62 +78,65 @@ arm_caller:
> >>>> > beq arm_callee2
> >>>> > bne arm_callee3
> >>>> > bx lr
> >>>> > -// 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
> >>>> > +// 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:
> >>>> > // 0x1001 = thumb_callee1
> >>>> > -// 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
> >>>> > +// 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
> >>>> > // 0x1501 = thumb_callee2
> >>>> > -// 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
> >>>> > +// 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
> >>>> > // 0x1503 = thumb_callee3
> >>>> > -// 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-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-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>
> >>>> > -// 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
> >>>> > +// 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:
> >>>> > // 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-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:
> >>>> > // 0x1340 + 8 + 0x1b9 = 0x1501
> >>>> > -// 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-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
> >>>> > // 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:
> >>>> > @@ -182,60 +185,58 @@ thumb_caller:
> >>>> > bne.w arm_callee3
> >>>> > // CHECK-ABS-THUMB: Disassembly of section .thumb_caller:
> >>>> > // CHECK-ABS-THUMB-NEXT: thumb_caller:
> >>>> > -// 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
> >>>> > +// 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:
> >>>> > // 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-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:
> >>>> > // 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-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: __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-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
> >>>> > -// 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
> >>>> > +// 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:
> >>>> > // 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-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:
> >>>> > // 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-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:
> >>>> > // 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=293283&r1=293282&r2=293283&view=diff
> >>>> >
> >>>> > ============================================================
> ==================
> >>>> > --- lld/trunk/test/ELF/mips-npic-call-pic.s (original)
> >>>> > +++ lld/trunk/test/ELF/mips-npic-call-pic.s Fri Jan 27 07:10:16
> 2017
> >>>> > @@ -15,60 +15,65 @@
> >>>> >
> >>>> > # CHECK: Disassembly of section .text:
> >>>> > # CHECK-NEXT: __start:
> >>>> > -# CHECK-NEXT: 20000: 0c 00 80 0e jal 131128
> >>>> > <foo1b+0x4>
> >>>> > -# ^--
> >>>> > .pic.foo1a
> >>>> > +# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
> >>>> > <__LA25Thunk_foo1a>
> >>>> > # CHECK-NEXT: 20004: 00 00 00 00 nop
> >>>> > -# CHECK-NEXT: 20008: 0c 00 80 19 jal 131172
> <foo2+0x4>
> >>>> > -# ^--
> >>>> > .pic.foo2
> >>>> > +# CHECK-NEXT: 20008: 0c 00 80 16 jal 131160
> >>>> > <__LA25Thunk_foo2>
> >>>> > # CHECK-NEXT: 2000c: 00 00 00 00 nop
> >>>> > -# CHECK-NEXT: 20010: 0c 00 80 12 jal 131144
> >>>> > <foo1b+0x14>
> >>>> > -# ^--
> >>>> > .pic.foo1b
> >>>> > +# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136
> >>>> > <__LA25Thunk_foo1b>
> >>>> > # CHECK-NEXT: 20014: 00 00 00 00 nop
> >>>> > -# CHECK-NEXT: 20018: 0c 00 80 19 jal 131172
> <foo2+0x4>
> >>>> > -# ^--
> >>>> > .pic.foo2
> >>>> > +# CHECK-NEXT: 20018: 0c 00 80 16 jal 131160
> >>>> > <__LA25Thunk_foo2>
> >>>> > # CHECK-NEXT: 2001c: 00 00 00 00 nop
> >>>> > -# CHECK-NEXT: 20020: 0c 00 80 25 jal 131220
> >>>> > <fnpic+0x4>
> >>>> > -# ^--
> >>>> > .pic.fpic
> >>>> > +# CHECK-NEXT: 20020: 0c 00 80 1d jal 131188
> >>>> > <__LA25Thunk_fpic>
> >>>> > # CHECK-NEXT: 20024: 00 00 00 00 nop
> >>>> > -# CHECK-NEXT: 20028: 0c 00 80 24 jal 131216
> <fnpic>
> >>>> > +# CHECK-NEXT: 20028: 0c 00 80 28 jal 131232
> <fnpic>
> >>>> > # CHECK-NEXT: 2002c: 00 00 00 00 nop
> >>>> > #
> >>>> > -# 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: __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-NEXT: 20054: 00 00 00 00 nop
> >>>> > -# 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: __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: 20070: 00 00 00 00 nop
> >>>> > -# 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: __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: 20090: 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
> >>>> > +# 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
> >>>> >
> >>>> > # Make sure the thunks are created properly no matter how
> >>>> > # objects are laid out.
> >>>> > @@ -76,54 +81,58 @@
> >>>> > # 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: 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: 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-NEXT: 20024: 00 00 00 00 nop
> >>>> > -# 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: __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: 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 02 jal 131080
> >>>> > <foo1b+0x4>
> >>>> > +# REVERSE: __start:
> >>>> > +# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072
> >>>> > <__LA25Thunk_foo1a>
> >>>> > # REVERSE-NEXT: 20054: 00 00 00 00 nop
> >>>> > -# REVERSE-NEXT: 20058: 0c 00 80 0d jal 131124
> >>>> > <foo2+0x4>
> >>>> > +# REVERSE-NEXT: 20058: 0c 00 80 0a jal 131112
> >>>> > <__LA25Thunk_foo2>
> >>>> > # REVERSE-NEXT: 2005c: 00 00 00 00 nop
> >>>> > -# REVERSE-NEXT: 20060: 0c 00 80 06 jal 131096
> >>>> > <foo1b+0x14>
> >>>> > +# REVERSE-NEXT: 20060: 0c 00 80 04 jal 131088
> >>>> > <__LA25Thunk_foo1b>
> >>>> > # REVERSE-NEXT: 20064: 00 00 00 00 nop
> >>>> > -# REVERSE-NEXT: 20068: 0c 00 80 0d jal 131124
> >>>> > <foo2+0x4>
> >>>> > +# REVERSE-NEXT: 20068: 0c 00 80 0a jal 131112
> >>>> > <__LA25Thunk_foo2>
> >>>> > # REVERSE-NEXT: 2006c: 00 00 00 00 nop
> >>>> > -# REVERSE-NEXT: 20070: 0c 00 80 25 jal 131220
> >>>> > <fnpic+0x4>
> >>>> > +# REVERSE-NEXT: 20070: 0c 00 80 20 jal 131200
> >>>> > <__LA25Thunk_fpic>
> >>>> > # REVERSE-NEXT: 20074: 00 00 00 00 nop
> >>>> > -# REVERSE-NEXT: 20078: 0c 00 80 24 jal 131216
> <fnpic>
> >>>> > +# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232
> <fnpic>
> >>>> > # REVERSE-NEXT: 2007c: 00 00 00 00 nop
> >>>> > -#
> >>>> > -# REVERSE: fpic:
> >>>> > -# REVERSE-NEXT: 20080: 00 00 00 00 nop
> >>>> > -#
> >>>> > -# REVERSE: fnpic:
> >>>> > +# 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-NEXT: 20090: 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
> >>>> > +# 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
> >>>> >
> >>>> > .text
> >>>> > .globl __start
> >>>> >
> >>>> >
> >>>> > _______________________________________________
> >>>> > llvm-commits mailing list
> >>>> > llvm-commits at lists.llvm.org
> >>>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> >>>> _______________________________________________
> >>>> llvm-commits mailing list
> >>>> llvm-commits at lists.llvm.org
> >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> >>>
> >>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170131/8c6ea8b3/attachment-0001.html>
More information about the llvm-commits
mailing list