<div dir="ltr">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.<div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 30, 2017 at 12:25 PM, Peter Smith <span dir="ltr"><<a href="mailto:peter.smith@linaro.org" target="_blank">peter.smith@linaro.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Apologies again, it is worse than I thought. After making the change<br>
the build passes, but the Thunk tests fail with assertion failures in<br>
the Mips Thunk test.<br>
<br>
The MSVC debug implementation of merge uses the _same_ predicate to<br>
check that both sets of input iterators are ordered before even doing<br>
the merge.<br>
<br>
This means that the predicate has to work on both the InputSections<br>
with prior to inserting the thunks, the thunks and the combination of<br>
thunks and no-thunks. In particular a 0 sized section in the Mips<br>
Thunk implementation trips this up.<br>
<br>
I'll need to either:<br>
- Provide a handwritten implementation of merge that only does what a<br>
release build does.<br>
- Disable the debug iterators in MSVC by undefining the macros before<br>
calling merge, then re-enabling them.<br>
- Make a comparison operator that works.<br>
<br>
I'll send out what I come up with for review again. This is more than<br>
just a trivial change.<br>
<span class="m_4474916197337440799HOEnZb"><font color="#888888"><br>
Peter<br>
</font></span><div class="m_4474916197337440799HOEnZb"><div class="m_4474916197337440799h5"><br>
On 30 January 2017 at 17:55, Peter Smith <<a href="mailto:peter.smith@linaro.org" target="_blank">peter.smith@linaro.org</a>> wrote:<br>
> Apologies for the delay, it took a while to get a Windows environment setup.<br>
><br>
> I've tracked it down to the MSVC _Debug_lt_pred which does an<br>
> additional A < B and B < A. This won't compile for:<br>
> auto MergeCmp = [](const ThunkSection<ELFT> *Thunk,<br>
> const InputSection<ELFT> *IS)<br>
> as InputSection<ELFT> *IS can't be cast to ThunkSection<ELFT>* for the<br>
> additional debug pred test.<br>
><br>
> This can be fixed by changing ThunkSection<ELFT> *Thunk to<br>
> InputSection<ELFT> *Thunk.<br>
><br>
> I'll rebase and recommit tomorrow morning (UK time).<br>
><br>
> Peter<br>
><br>
> On 30 January 2017 at 10:20, Peter Smith <<a href="mailto:peter.smith@linaro.org" target="_blank">peter.smith@linaro.org</a>> wrote:<br>
>> My apologies, thanks for reverting it.<br>
>><br>
>> It looks like I'm going to have to set up a MSVC debug build to<br>
>> reproduce and make sure it is fixed as I can't immediately see the<br>
>> problem from the message above. Will resubmit as soon as I can.<br>
>><br>
>> Peter<br>
>><br>
>> On 28 January 2017 at 01:01, Rui Ueyama <<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>> wrote:<br>
>>> Peter,<br>
>>><br>
>>> I had to roll back this in r293352 because it broke MSVC debug build and I<br>
>>> couldn't fix it immediately. Please take a look and re-submit.<br>
>>><br>
>>><br>
>>> D:\llvm-project\lld\ELF\Reloca<wbr>tions.cpp(833): note: see reference to<br>
>>> function template instantiation '_OutIt<br>
>>> std::merge<std::_Vector_iterat<wbr>or<std::_Vector_val<std::_<wbr>Simple_types<lld::elf::InputSe<wbr>ction<ELFT><br>
>>>>>>,std::_Vector_iterator<s<wbr>td::_V<br>
>>> ector_val<std::_Simple_types<l<wbr>ld::elf::ThunkSection<ELFT><br>
>>> *>>>,std::back_insert_iterator<wbr><std::vector<lld::elf::<wbr>InputSection<ELFT><br>
>>> *,std::allocator<_Ty>>>,lld::e<wbr>lf::mergeThunks::<lambda_b339c<wbr>aca889e68d37c4499c447b8b3c1>>(<wbr>_InIt1,_InIt1,_InIt2,_InIt2,_<wbr>OutIt,_Pr)'<br>
>>> being compiled<br>
>>> with<br>
>>> [<br>
>>><br>
>>> _OutIt=std::back_insert_iterat<wbr>or<std::vector<lld::elf::<wbr>InputSection<llvm::object::ELF<wbr>32BE><br>
>>> *,std::allocator<lld::elf::Inp<wbr>utSection<llvm::object::ELF32B<wbr>E> >>>,<br>
>>> ELFT=llvm::object::ELF32BE,<br>
>>> _Ty=lld::elf::InputSection<ll<wbr>vm::object::ELF32BE> *,<br>
>>><br>
>>> _InIt1=std::_Vector_iterator<s<wbr>td::_Vector_val<std::_Simple_t<wbr>ypes<lld::elf::InputSection<ll<wbr>vm::object::ELF32BE><br>
>>>>>>,<br>
>>><br>
>>> _InIt2=std::_Vector_iterator<s<wbr>td::_Vector_val<std::_Simple_t<wbr>ypes<lld::elf::ThunkSection<ll<wbr>vm::object::ELF32BE><br>
>>>>>>,<br>
>>><br>
>>> _Pr=lld::elf::mergeThunks::<la<wbr>mbda_b339caca889e68d37c4499c44<wbr>7b8b3c1><br>
>>> ]<br>
>>> D:\llvm-project\lld\ELF\Reloca<wbr>tions.cpp(924): note: see reference to<br>
>>> function template instantiation 'void<br>
>>> lld::elf::mergeThunks<ELFT>(ll<wbr>d::elf::OutputSection<ELFT><br>
>>> *,std::vector<lld::elf::ThunkS<wbr>ection<ELFT> *,std::allocator<_Ty>> &)' being<br>
>>> compiled<br>
>>> with<br>
>>> [<br>
>>> ELFT=llvm::object::ELF32BE,<br>
>>> _Ty=lld::elf::ThunkSection<ll<wbr>vm::object::ELF32BE> *<br>
>>> ]<br>
>>><br>
>>><br>
>>> On Fri, Jan 27, 2017 at 12:02 PM, Rafael Avila de Espindola via llvm-commits<br>
>>> <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
>>>><br>
>>>> This is really nice. Thanks!<br>
>>>><br>
>>>> Peter Smith via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> writes:<br>
>>>><br>
>>>> > Author: psmith<br>
>>>> > Date: Fri Jan 27 07:10:16 2017<br>
>>>> > New Revision: 293283<br>
>>>> ><br>
>>>> > URL: <a href="http://llvm.org/viewvc/llvm-project?rev=293283&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=293283&view=rev</a><br>
>>>> > Log:<br>
>>>> > [ELF][ARM] Use SyntheticSections for Thunks<br>
>>>> ><br>
>>>> > Thunks are now implemented by redirecting the relocation to the<br>
>>>> > symbol S, to a symbol TS in a Thunk. The Thunk will transfer control<br>
>>>> > to S. This has the following implications:<br>
>>>> > - All the side-effects of Thunks happen within createThunks()<br>
>>>> > - Thunks are no longer stored in InputSections and Symbols no longer<br>
>>>> > need to hold a pointer to a Thunk<br>
>>>> > - The synthetic Thunk sections need to be merged into OutputSections<br>
>>>> ><br>
>>>> > This implementation is almost a direct conversion of the existing<br>
>>>> > Thunks with the following exceptions:<br>
>>>> > - Mips LA25 Thunks are placed before the InputSection that defines<br>
>>>> > the symbol that needs a Thunk.<br>
>>>> > - All ARM Thunks are placed at the end of the OutputSection of the<br>
>>>> > first caller to the Thunk.<br>
>>>> ><br>
>>>> > Range extension Thunks are not supported yet so it is optimistically<br>
>>>> > assumed that all Thunks can be reused.<br>
>>>> ><br>
>>>> > Differential Revision: <a href="https://reviews.llvm.org/D29129" rel="noreferrer" target="_blank">https://reviews.llvm.org/D2912<wbr>9</a><br>
>>>> ><br>
>>>> ><br>
>>>> > Modified:<br>
>>>> > lld/trunk/ELF/InputFiles.cpp<br>
>>>> > lld/trunk/ELF/InputSection.<wbr>cpp<br>
>>>> > lld/trunk/ELF/InputSection.h<br>
>>>> > lld/trunk/ELF/LTO.cpp<br>
>>>> > lld/trunk/ELF/LTO.h<br>
>>>> > lld/trunk/ELF/Relocations.cpp<br>
>>>> > lld/trunk/ELF/Relocations.h<br>
>>>> > lld/trunk/ELF/SymbolTable.cpp<br>
>>>> > lld/trunk/ELF/Symbols.cpp<br>
>>>> > lld/trunk/ELF/Symbols.h<br>
>>>> > lld/trunk/ELF/SyntheticSectio<wbr>ns.cpp<br>
>>>> > lld/trunk/ELF/SyntheticSectio<wbr>ns.h<br>
>>>> > lld/trunk/ELF/Target.cpp<br>
>>>> > lld/trunk/ELF/Target.h<br>
>>>> > lld/trunk/ELF/Thunks.cpp<br>
>>>> > lld/trunk/ELF/Thunks.h<br>
>>>> > lld/trunk/ELF/Writer.cpp<br>
>>>> > lld/trunk/test/ELF/arm-thumb-<wbr>interwork-shared.s<br>
>>>> > lld/trunk/test/ELF/arm-thumb-<wbr>interwork-thunk.s<br>
>>>> > lld/trunk/test/ELF/mips-npic-<wbr>call-pic.s<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/InputFiles.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/InputFiles<wbr>.cpp?rev=293283&r1=293282&r2=<wbr>293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/InputFiles.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/InputFiles.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -488,7 +488,7 @@ SymbolBody *elf::ObjectFile<ELFT>::creat<br>
>>>> > StringRefZ Name = this->StringTable.data() + Sym->st_name;<br>
>>>> > if (Sym->st_shndx == SHN_UNDEF)<br>
>>>> > return new (BAlloc)<br>
>>>> > - Undefined<ELFT>(Name, /*IsLocal=*/true, StOther, Type, this);<br>
>>>> > + Undefined(Name, /*IsLocal=*/true, StOther, Type, this);<br>
>>>> ><br>
>>>> > return new (BAlloc) DefinedRegular<ELFT>(Name, /*IsLocal=*/true,<br>
>>>> > StOther,<br>
>>>> > Type, Value, Size, Sec,<br>
>>>> > this);<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/InputSection.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/InputSecti<wbr>on.cpp?rev=293283&r1=293282&<wbr>r2=293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/InputSection.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/InputSection.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -99,10 +99,6 @@ template <class ELFT> size_t InputSectio<br>
>>>> > if (auto *S = dyn_cast<SyntheticSection<ELFT<wbr>>>(this))<br>
>>>> > return S->getSize();<br>
>>>> ><br>
>>>> > - if (auto *D = dyn_cast<InputSection<ELFT>>(t<wbr>his))<br>
>>>> > - if (D->getThunksSize() > 0)<br>
>>>> > - return D->getThunkOff() + D->getThunksSize();<br>
>>>> > -<br>
>>>> > return Data.size();<br>
>>>> > }<br>
>>>> ><br>
>>>> > @@ -214,21 +210,6 @@ InputSectionBase<ELFT> *InputSection<ELF<br>
>>>> > return Sections[this->Info];<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT> void InputSection<ELFT>::addThunk(c<wbr>onst<br>
>>>> > Thunk<ELFT> *T) {<br>
>>>> > - Thunks.push_back(T);<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > -template <class ELFT> uint64_t InputSection<ELFT>::getThunkOf<wbr>f() const<br>
>>>> > {<br>
>>>> > - return this->Data.size();<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > -template <class ELFT> uint64_t InputSection<ELFT>::getThunksS<wbr>ize()<br>
>>>> > const {<br>
>>>> > - uint64_t Total = 0;<br>
>>>> > - for (const Thunk<ELFT> *T : Thunks)<br>
>>>> > - Total += T->size();<br>
>>>> > - return Total;<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > // This is used for -r. We can't use memcpy to copy relocations because<br>
>>>> > we need<br>
>>>> > // to update symbol table offset and section index for each relocation.<br>
>>>> > So we<br>
>>>> > // copy relocations one by one.<br>
>>>> > @@ -302,11 +283,6 @@ getRelocTargetVA(uint32_t Type, typename<br>
>>>> > return In<ELFT>::Got->getTlsIndexOff(<wbr>) + A -<br>
>>>> > In<ELFT>::Got->getSize();<br>
>>>> > case R_TLSLD_PC:<br>
>>>> > return In<ELFT>::Got->getTlsIndexVA() + A - P;<br>
>>>> > - case R_THUNK_ABS:<br>
>>>> > - return Body.getThunkVA<ELFT>() + A;<br>
>>>> > - case R_THUNK_PC:<br>
>>>> > - case R_THUNK_PLT_PC:<br>
>>>> > - return Body.getThunkVA<ELFT>() + A - P;<br>
>>>> > case R_PPC_TOC:<br>
>>>> > return getPPC64TocBase() + A;<br>
>>>> > case R_TLSGD:<br>
>>>> > @@ -551,19 +527,6 @@ template <class ELFT> void InputSection<<br>
>>>> > // Iterate over all relocation sections that apply to this section.<br>
>>>> > uint8_t *BufEnd = Buf + OutSecOff + Data.size();<br>
>>>> > this->relocate(Buf, BufEnd);<br>
>>>> > -<br>
>>>> > - // The section might have a data/code generated by the linker and<br>
>>>> > need<br>
>>>> > - // to be written after the section. Usually these are thunks - small<br>
>>>> > piece<br>
>>>> > - // of code used to jump between "incompatible" functions like PIC and<br>
>>>> > non-PIC<br>
>>>> > - // or if the jump target too far and its address does not fit to the<br>
>>>> > short<br>
>>>> > - // jump istruction.<br>
>>>> > - if (!Thunks.empty()) {<br>
>>>> > - Buf += OutSecOff + getThunkOff();<br>
>>>> > - for (const Thunk<ELFT> *T : Thunks) {<br>
>>>> > - T->writeTo(Buf);<br>
>>>> > - Buf += T->size();<br>
>>>> > - }<br>
>>>> > - }<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/InputSection.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/InputSecti<wbr>on.h?rev=293283&r1=293282&r2=<wbr>293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/InputSection.h (original)<br>
>>>> > +++ lld/trunk/ELF/InputSection.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -280,17 +280,6 @@ public:<br>
>>>> ><br>
>>>> > InputSectionBase<ELFT> *getRelocatedSection();<br>
>>>> ><br>
>>>> > - // Register thunk related to the symbol. When the section is written<br>
>>>> > - // to a mmap'ed file, target is requested to write an actual thunk<br>
>>>> > code.<br>
>>>> > - // Now thunks is supported for MIPS and ARM target only.<br>
>>>> > - void addThunk(const Thunk<ELFT> *T);<br>
>>>> > -<br>
>>>> > - // The offset of synthetic thunk code from beginning of this section.<br>
>>>> > - uint64_t getThunkOff() const;<br>
>>>> > -<br>
>>>> > - // Size of chunk with thunks code.<br>
>>>> > - uint64_t getThunksSize() const;<br>
>>>> > -<br>
>>>> > template <class RelTy><br>
>>>> > void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);<br>
>>>> ><br>
>>>> > @@ -303,8 +292,6 @@ public:<br>
>>>> > private:<br>
>>>> > template <class RelTy><br>
>>>> > void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);<br>
>>>> > -<br>
>>>> > - llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;<br>
>>>> > };<br>
>>>> ><br>
>>>> > template <class ELFT> InputSection<ELFT> InputSection<ELFT>::Discarded;<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/LTO.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/LTO.cpp?re<wbr>v=293283&r1=293282&r2=293283&<wbr>view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/LTO.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/LTO.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -96,12 +96,12 @@ BitcodeCompiler::BitcodeCompil<wbr>er() : LTO<br>
>>>> ><br>
>>>> > BitcodeCompiler::~BitcodeCompi<wbr>ler() = default;<br>
>>>> ><br>
>>>> > -template <class ELFT> static void undefine(Symbol *S) {<br>
>>>> > - replaceBody<Undefined<ELFT>>(S<wbr>, S->body()->getName(),<br>
>>>> > /*IsLocal=*/false,<br>
>>>> > - STV_DEFAULT, S->body()->Type, nullptr);<br>
>>>> > +static void undefine(Symbol *S) {<br>
>>>> > + replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false,<br>
>>>> > + STV_DEFAULT, S->body()->Type, nullptr);<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT> void BitcodeCompiler::add(BitcodeFi<wbr>le &F) {<br>
>>>> > +void BitcodeCompiler::add(BitcodeFi<wbr>le &F) {<br>
>>>> > lto::InputFile &Obj = *F.Obj;<br>
>>>> > unsigned SymNum = 0;<br>
>>>> > std::vector<Symbol *> Syms = F.getSymbols();<br>
>>>> > @@ -126,7 +126,7 @@ template <class ELFT> void BitcodeCompil<br>
>>>> > R.VisibleToRegularObj =<br>
>>>> > Sym->IsUsedInRegularObj || (R.Prevailing &&<br>
>>>> > Sym->includeInDynsym());<br>
>>>> > if (R.Prevailing)<br>
>>>> > - undefine<ELFT>(Sym);<br>
>>>> > + undefine(Sym);<br>
>>>> > }<br>
>>>> > checkError(LTOObj->add(std::mo<wbr>ve(F.Obj), Resols));<br>
>>>> > }<br>
>>>> > @@ -157,8 +157,3 @@ std::vector<InputFile *> BitcodeCompiler<br>
>>>> > }<br>
>>>> > return Ret;<br>
>>>> > }<br>
>>>> > -<br>
>>>> > -template void BitcodeCompiler::template add<ELF32LE>(BitcodeFile &);<br>
>>>> > -template void BitcodeCompiler::template add<ELF32BE>(BitcodeFile &);<br>
>>>> > -template void BitcodeCompiler::template add<ELF64LE>(BitcodeFile &);<br>
>>>> > -template void BitcodeCompiler::template add<ELF64BE>(BitcodeFile &);<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/LTO.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/LTO.h?rev=<wbr>293283&r1=293282&r2=293283&<wbr>view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/LTO.h (original)<br>
>>>> > +++ lld/trunk/ELF/LTO.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -43,7 +43,7 @@ public:<br>
>>>> > BitcodeCompiler();<br>
>>>> > ~BitcodeCompiler();<br>
>>>> ><br>
>>>> > - template <class ELFT> void add(BitcodeFile &F);<br>
>>>> > + void add(BitcodeFile &F);<br>
>>>> > std::vector<InputFile *> compile();<br>
>>>> ><br>
>>>> > private:<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Relocations.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Relocation<wbr>s.cpp?rev=293283&r1=293282&r2=<wbr>293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Relocations.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/Relocations.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -43,6 +43,7 @@<br>
>>>> ><br>
>>>> > #include "Relocations.h"<br>
>>>> > #include "Config.h"<br>
>>>> > +#include "Memory.h"<br>
>>>> > #include "OutputSections.h"<br>
>>>> > #include "Strings.h"<br>
>>>> > #include "SymbolTable.h"<br>
>>>> > @@ -52,6 +53,7 @@<br>
>>>> ><br>
>>>> > #include "llvm/Support/Endian.h"<br>
>>>> > #include "llvm/Support/raw_ostream.h"<br>
>>>> > +#include <algorithm><br>
>>>> ><br>
>>>> > using namespace llvm;<br>
>>>> > using namespace llvm::ELF;<br>
>>>> > @@ -300,16 +302,14 @@ template <class ELFT> static bool isAbso<br>
>>>> > }<br>
>>>> ><br>
>>>> > static bool needsPlt(RelExpr Expr) {<br>
>>>> > - return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC,<br>
>>>> > - R_THUNK_PLT_PC>(Expr);<br>
>>>> > + return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT,<br>
>>>> > R_PLT_PAGE_PC>(Expr);<br>
>>>> > }<br>
>>>> ><br>
>>>> > // True if this expression is of the form Sym - X, where X is a<br>
>>>> > position in the<br>
>>>> > // file (PC, or GOT for example).<br>
>>>> > static bool isRelExpr(RelExpr Expr) {<br>
>>>> > return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END,<br>
>>>> > R_MIPS_GOTREL,<br>
>>>> > - R_PAGE_PC, R_RELAX_GOT_PC, R_THUNK_PC,<br>
>>>> > R_THUNK_PLT_PC>(<br>
>>>> > - Expr);<br>
>>>> > + R_PAGE_PC, R_RELAX_GOT_PC>(Expr);<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > @@ -321,8 +321,7 @@ static bool isStaticLinkTimeConstant(Rel<br>
>>>> > if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF,<br>
>>>> > R_MIPS_GOT_LOCAL_PAGE,<br>
>>>> > R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_TLSGD,<br>
>>>> > R_GOT_PAGE_PC, R_GOT_PC, R_PLT_PC, R_TLSGD_PC,<br>
>>>> > R_TLSGD,<br>
>>>> > - R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE,<br>
>>>> > R_HINT,<br>
>>>> > - R_THUNK_PC, R_THUNK_PLT_PC>(E))<br>
>>>> > + R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE,<br>
>>>> > R_HINT>(E))<br>
>>>> > return true;<br>
>>>> ><br>
>>>> > // These never do, except if the entire file is position dependent or<br>
>>>> > if<br>
>>>> > @@ -467,7 +466,6 @@ static RelExpr adjustExpr(const elf::Obj<br>
>>>> > if (Expr == R_GOT_PC && !isAbsoluteValue<ELFT>(Body))<br>
>>>> > Expr = Target->adjustRelaxExpr(Type, Data, Expr);<br>
>>>> > }<br>
>>>> > - Expr = Target->getThunkExpr(Expr, Type, &File, Body);<br>
>>>> ><br>
>>>> > if (IsWrite || isStaticLinkTimeConstant<ELFT><wbr>(Expr, Type, Body, S,<br>
>>>> > RelOff))<br>
>>>> > return Expr;<br>
>>>> > @@ -685,7 +683,6 @@ static void scanRelocs(InputSectionBase<<br>
>>>> > continue;<br>
>>>> ><br>
>>>> > if (needsPlt(Expr) ||<br>
>>>> > - isRelExprOneOf<R_THUNK_ABS, R_THUNK_PC, R_THUNK_PLT_PC>(Expr)<br>
>>>> > ||<br>
>>>> > refersToGotEntry(Expr) || !isPreemptible(Body, Type)) {<br>
>>>> > // If the relocation points to something in the file, we can<br>
>>>> > process it.<br>
>>>> > bool Constant =<br>
>>>> > @@ -805,33 +802,126 @@ template <class ELFT> void scanRelocatio<br>
>>>> > scanRelocs(S, S.rels());<br>
>>>> > }<br>
>>>> ><br>
>>>> > +// Insert the Thunks for OutputSection OS into their designated place<br>
>>>> > +// in the Sections vector, and recalculate the InputSection output<br>
>>>> > section<br>
>>>> > +// offsets.<br>
>>>> > +// This may invalidate any output section offsets stored outside of<br>
>>>> > InputSection<br>
>>>> > +template <class ELFT><br>
>>>> > +static void mergeThunks(OutputSection<ELFT<wbr>> *OS,<br>
>>>> > + std::vector<ThunkSection<ELFT> *> &Thunks) {<br>
>>>> > + // Order Thunks in ascending OutSecOff<br>
>>>> > + auto ThunkCmp = [](const ThunkSection<ELFT> *A, const<br>
>>>> > ThunkSection<ELFT> *B) {<br>
>>>> > + return A->OutSecOff < B->OutSecOff;<br>
>>>> > + };<br>
>>>> > + std::stable_sort(Thunks.begin(<wbr>), Thunks.end(), ThunkCmp);<br>
>>>> > +<br>
>>>> > + // Merge sorted vectors of Thunks and InputSections by OutSecOff<br>
>>>> > + std::vector<InputSection<ELFT> *> Tmp;<br>
>>>> > + Tmp.reserve(OS->Sections.size(<wbr>) + Thunks.size());<br>
>>>> > + auto MergeCmp = [](const ThunkSection<ELFT> *Thunk,<br>
>>>> > + const InputSection<ELFT> *IS) {<br>
>>>> > + // All thunks go before any non-executable InputSections<br>
>>>> > + if ((IS->Flags & SHF_EXECINSTR) == 0)<br>
>>>> > + return true;<br>
>>>> > + // Some Thunk Sections such as the Mips LA25 thunk must be placed<br>
>>>> > before<br>
>>>> > + // the InputSections that they target. We represent this by<br>
>>>> > assigning the<br>
>>>> > + // ThunkSection the same OutSecOff and always placing the Thunk<br>
>>>> > first if<br>
>>>> > + // the OutSecOff values are the same.<br>
>>>> > + return Thunk->OutSecOff <= IS->OutSecOff;<br>
>>>> > + };<br>
>>>> > + std::merge(OS->Sections.begin(<wbr>), OS->Sections.end(), Thunks.begin(),<br>
>>>> > + Thunks.end(), std::back_inserter(Tmp), MergeCmp);<br>
>>>> > + OS->Sections = std::move(Tmp);<br>
>>>> > + OS->Size = 0;<br>
>>>> > + OS->assignOffsets();<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +// Process all relocations from the InputSections that have been<br>
>>>> > assigned<br>
>>>> > +// to OutputSections and redirect through Thunks if needed.<br>
>>>> > +//<br>
>>>> > +// createThunks must be called after scanRelocs has created the<br>
>>>> > Relocations for<br>
>>>> > +// each InputSection. It must be called before the static symbol table<br>
>>>> > is<br>
>>>> > +// finalized. If any Thunks are added to an OutputSection the output<br>
>>>> > section<br>
>>>> > +// offsets of the InputSections will change.<br>
>>>> > +//<br>
>>>> > +// FIXME: All Thunks are assumed to be in range of the relocation.<br>
>>>> > Range<br>
>>>> > +// extension Thunks are not yet supported.<br>
>>>> > template <class ELFT><br>
>>>> > void createThunks(ArrayRef<OutputSe<wbr>ctionBase *> OutputSections) {<br>
>>>> > + // Track Symbols that already have a Thunk<br>
>>>> > + DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols;<br>
>>>> > + // Track InputSections that have a ThunkSection placed in front<br>
>>>> > + DenseMap<InputSection<ELFT> *, ThunkSection<ELFT> *> ThunkedSections;<br>
>>>> > + // Track the ThunksSections that need to be inserted into an<br>
>>>> > OutputSection<br>
>>>> > + std::map<OutputSection<ELFT> *, std::vector<ThunkSection<ELFT> *>><br>
>>>> > + ThunkSections;<br>
>>>> > +<br>
>>>> > + // Find or create a Thunk for Body for relocation Type<br>
>>>> > + auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {<br>
>>>> > + auto res = ThunkedSymbols.insert({&Body, nullptr});<br>
>>>> > + if (res.second == true)<br>
>>>> > + res.first->second = addThunk<ELFT>(Type, Body);<br>
>>>> > + return std::make_pair(res.first->seco<wbr>nd, res.second);<br>
>>>> > + };<br>
>>>> > +<br>
>>>> > + // Find or create a ThunkSection to be placed immediately before IS<br>
>>>> > + auto GetISThunkSec = [&](InputSection<ELFT> *IS, OutputSection<ELFT><br>
>>>> > *OS) {<br>
>>>> > + ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS);<br>
>>>> > + if (TS)<br>
>>>> > + return TS;<br>
>>>> > + auto *TOS = cast<OutputSection<ELFT>>(IS-><wbr>OutSec);<br>
>>>> > + TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff);<br>
>>>> > + ThunkSections[OS].push_back(TS<wbr>);<br>
>>>> > + ThunkedSections[IS] = TS;<br>
>>>> > + return TS;<br>
>>>> > + };<br>
>>>> > + // Find or create a ThunkSection to be placed at the end of OS<br>
>>>> > + auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection<ELFT><br>
>>>> > *OS) {<br>
>>>> > + if (TS == nullptr) {<br>
>>>> > + TS = make<ThunkSection<ELFT>>(OS, OS->Size);<br>
>>>> > + ThunkSections[OS].push_back(TS<wbr>);<br>
>>>> > + }<br>
>>>> > + return TS;<br>
>>>> > + };<br>
>>>> > + // Create all the Thunks and insert them into synthetic<br>
>>>> > ThunkSections. The<br>
>>>> > + // ThunkSections are later inserted back into the OutputSection.<br>
>>>> > +<br>
>>>> > + // We separate the creation of ThunkSections from the insertion of<br>
>>>> > the<br>
>>>> > + // ThunkSections back into the OutputSection as ThunkSections are not<br>
>>>> > always<br>
>>>> > + // inserted into the same OutputSection as the caller.<br>
>>>> > for (OutputSectionBase *Base : OutputSections) {<br>
>>>> > auto *OS = dyn_cast<OutputSection<ELFT>>(<wbr>Base);<br>
>>>> > if (OS == nullptr)<br>
>>>> > continue;<br>
>>>> > +<br>
>>>> > + ThunkSection<ELFT> *OSTS = nullptr;<br>
>>>> > for (InputSection<ELFT> *IS : OS->Sections) {<br>
>>>> > - for (const Relocation &Rel : IS->Relocations) {<br>
>>>> > - if (Rel.Sym == nullptr)<br>
>>>> > - continue;<br>
>>>> > - RelExpr Expr = Rel.Expr;<br>
>>>> > - // Some targets might require creation of thunks for<br>
>>>> > relocations.<br>
>>>> > - // Now we support only MIPS which requires LA25 thunk to call<br>
>>>> > PIC<br>
>>>> > - // code from non-PIC one, and ARM which requires interworking.<br>
>>>> > - if (Expr == R_THUNK_ABS || Expr == R_THUNK_PC ||<br>
>>>> > - Expr == R_THUNK_PLT_PC)<br>
>>>> > - addThunk<ELFT>(Rel.Type, *Rel.Sym, *IS);<br>
>>>> > + for (Relocation &Rel : IS->Relocations) {<br>
>>>> > + SymbolBody &Body = *Rel.Sym;<br>
>>>> > + if (Target->needsThunk(Rel.Expr, Rel.Type, IS->getFile(),<br>
>>>> > Body)) {<br>
>>>> > + Thunk<ELFT> *T;<br>
>>>> > + bool IsNew;<br>
>>>> > + std::tie(T, IsNew) = GetThunk(Body, Rel.Type);<br>
>>>> > + if (IsNew) {<br>
>>>> > + // Find or create a ThunkSection for the new Thunk<br>
>>>> > + ThunkSection<ELFT> *TS;<br>
>>>> > + if (auto *TIS = T->getTargetInputSection())<br>
>>>> > + TS = GetISThunkSec(TIS, OS);<br>
>>>> > + else<br>
>>>> > + TS = GetOSThunkSec(OSTS, OS);<br>
>>>> > + TS->addThunk(T);<br>
>>>> > + }<br>
>>>> > + // Redirect relocation to Thunk, we never go via the PLT to a<br>
>>>> > Thunk<br>
>>>> > + Rel.Sym = T->ThunkSym;<br>
>>>> > + Rel.Expr = fromPlt(Rel.Expr);<br>
>>>> > + }<br>
>>>> > }<br>
>>>> > }<br>
>>>> > }<br>
>>>> > - // Added thunks may affect the output section offset<br>
>>>> > - for (OutputSectionBase *Base : OutputSections)<br>
>>>> > - if (auto *OS = dyn_cast<OutputSection<ELFT>>(<wbr>Base))<br>
>>>> > - if (OS->Type == SHT_PROGBITS) {<br>
>>>> > - OS->Size = 0;<br>
>>>> > - OS->assignOffsets();<br>
>>>> > - }<br>
>>>> > +<br>
>>>> > + // Merge all created synthetic ThunkSections back into OutputSection<br>
>>>> > + for (auto &KV : ThunkSections)<br>
>>>> > + mergeThunks<ELFT>(KV.first, KV.second);<br>
>>>> > }<br>
>>>> ><br>
>>>> > template void scanRelocations<ELF32LE>(Input<wbr>SectionBase<ELF32LE> &);<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Relocations.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Relocation<wbr>s.h?rev=293283&r1=293282&r2=<wbr>293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Relocations.h (original)<br>
>>>> > +++ lld/trunk/ELF/Relocations.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -61,9 +61,6 @@ enum RelExpr {<br>
>>>> > R_RELAX_TLS_IE_TO_LE,<br>
>>>> > R_RELAX_TLS_LD_TO_LE,<br>
>>>> > R_SIZE,<br>
>>>> > - R_THUNK_ABS,<br>
>>>> > - R_THUNK_PC,<br>
>>>> > - R_THUNK_PLT_PC,<br>
>>>> > R_TLS,<br>
>>>> > R_TLSDESC,<br>
>>>> > R_TLSDESC_PAGE,<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/SymbolTable.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/SymbolTabl<wbr>e.cpp?rev=293283&r1=293282&r2=<wbr>293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/SymbolTable.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/SymbolTable.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -115,7 +115,7 @@ template <class ELFT> void SymbolTable<E<br>
>>>> > // Compile bitcode files and replace bitcode symbols.<br>
>>>> > LTO.reset(new BitcodeCompiler);<br>
>>>> > for (BitcodeFile *F : BitcodeFiles)<br>
>>>> > - LTO->add<ELFT>(*F);<br>
>>>> > + LTO->add(*F);<br>
>>>> ><br>
>>>> > for (InputFile *File : LTO->compile()) {<br>
>>>> > ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File);<br>
>>>> > @@ -256,7 +256,7 @@ Symbol *SymbolTable<ELFT>::addUndefin<wbr>ed(<br>
>>>> > insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym,<br>
>>>> > File);<br>
>>>> > if (WasInserted) {<br>
>>>> > S->Binding = Binding;<br>
>>>> > - replaceBody<Undefined<ELFT>>(S<wbr>, Name, IsLocal, StOther, Type,<br>
>>>> > File);<br>
>>>> > + replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File);<br>
>>>> > return S;<br>
>>>> > }<br>
>>>> > if (Binding != STB_WEAK) {<br>
>>>> > @@ -428,7 +428,7 @@ void SymbolTable<ELFT>::addShared(S<wbr>hared<br>
>>>> > // Make sure we preempt DSO symbols with default visibility.<br>
>>>> > if (Sym.getVisibility() == STV_DEFAULT)<br>
>>>> > S->ExportDynamic = true;<br>
>>>> > - if (WasInserted || isa<Undefined<ELFT>>(S->body()<wbr>)) {<br>
>>>> > + if (WasInserted || isa<Undefined>(S->body())) {<br>
>>>> > replaceBody<SharedSymbol<ELFT><wbr>>(S, F, Name, Sym, Verdef);<br>
>>>> > if (!S->isWeak())<br>
>>>> > F->IsUsed = true;<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Symbols.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Symbols.cp<wbr>p?rev=293283&r1=293282&r2=2932<wbr>83&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Symbols.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/Symbols.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -132,14 +132,6 @@ bool SymbolBody::isPreemptible() const {<br>
>>>> > return true;<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT> bool SymbolBody::hasThunk() const {<br>
>>>> > - if (auto *DR = dyn_cast<DefinedRegular<ELFT>><wbr>(this))<br>
>>>> > - return DR->ThunkData != nullptr;<br>
>>>> > - if (auto *S = dyn_cast<SharedSymbol<ELFT>>(t<wbr>his))<br>
>>>> > - return S->ThunkData != nullptr;<br>
>>>> > - return false;<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > template <class ELFT><br>
>>>> > typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const<br>
>>>> > {<br>
>>>> > typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);<br>
>>>> > @@ -171,16 +163,6 @@ template <class ELFT> typename ELFT::uin<br>
>>>> > PltIndex * Target->PltEntrySize;<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA()<br>
>>>> > const {<br>
>>>> > - if (const auto *DR = dyn_cast<DefinedRegular<ELFT>><wbr>(this))<br>
>>>> > - return DR->ThunkData->getVA();<br>
>>>> > - if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(t<wbr>his))<br>
>>>> > - return S->ThunkData->getVA();<br>
>>>> > - if (const auto *S = dyn_cast<Undefined<ELFT>>(this<wbr>))<br>
>>>> > - return S->ThunkData->getVA();<br>
>>>> > - fatal("getThunkVA() not supported for Symbol class\n");<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {<br>
>>>> > if (const auto *C = dyn_cast<DefinedCommon>(this))<br>
>>>> > return C->Size;<br>
>>>> > @@ -241,9 +223,8 @@ template <class ELFT> bool DefinedRegula<br>
>>>> > (Section->getFile()->getObj()<wbr>.getHeader()->e_flags &<br>
>>>> > EF_MIPS_PIC);<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <typename ELFT><br>
>>>> > -Undefined<ELFT>::Undefined(St<wbr>ringRefZ Name, bool IsLocal, uint8_t<br>
>>>> > StOther,<br>
>>>> > - uint8_t Type, InputFile *File)<br>
>>>> > +Undefined::Undefined(StringRe<wbr>fZ Name, bool IsLocal, uint8_t StOther,<br>
>>>> > + uint8_t Type, InputFile *File)<br>
>>>> > : SymbolBody(SymbolBody::Undefin<wbr>edKind, Name, IsLocal, StOther,<br>
>>>> > Type) {<br>
>>>> > this->File = File;<br>
>>>> > }<br>
>>>> > @@ -338,11 +319,6 @@ std::string lld::toString(const SymbolBo<br>
>>>> > return B.getName();<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template bool SymbolBody::hasThunk<ELF32LE>(<wbr>) const;<br>
>>>> > -template bool SymbolBody::hasThunk<ELF32BE>(<wbr>) const;<br>
>>>> > -template bool SymbolBody::hasThunk<ELF64LE>(<wbr>) const;<br>
>>>> > -template bool SymbolBody::hasThunk<ELF64BE>(<wbr>) const;<br>
>>>> > -<br>
>>>> > template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;<br>
>>>> > template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;<br>
>>>> > template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;<br>
>>>> > @@ -363,11 +339,6 @@ template uint32_t SymbolBody::template g<br>
>>>> > template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;<br>
>>>> > template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;<br>
>>>> ><br>
>>>> > -template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;<br>
>>>> > -template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;<br>
>>>> > -template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;<br>
>>>> > -template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;<br>
>>>> > -<br>
>>>> > template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>()<br>
>>>> > const;<br>
>>>> > template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>()<br>
>>>> > const;<br>
>>>> > template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>()<br>
>>>> > const;<br>
>>>> > @@ -383,11 +354,6 @@ template uint32_t SymbolBody::template g<br>
>>>> > template uint64_t SymbolBody::template getSize<ELF64LE>() const;<br>
>>>> > template uint64_t SymbolBody::template getSize<ELF64BE>() const;<br>
>>>> ><br>
>>>> > -template class elf::Undefined<ELF32LE>;<br>
>>>> > -template class elf::Undefined<ELF32BE>;<br>
>>>> > -template class elf::Undefined<ELF64LE>;<br>
>>>> > -template class elf::Undefined<ELF64BE>;<br>
>>>> > -<br>
>>>> > template class elf::SharedSymbol<ELF32LE>;<br>
>>>> > template class elf::SharedSymbol<ELF32BE>;<br>
>>>> > template class elf::SharedSymbol<ELF64LE>;<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Symbols.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Symbols.h?<wbr>rev=293283&r1=293282&r2=293283<wbr>&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Symbols.h (original)<br>
>>>> > +++ lld/trunk/ELF/Symbols.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -76,7 +76,6 @@ public:<br>
>>>> ><br>
>>>> > bool isInGot() const { return GotIndex != -1U; }<br>
>>>> > bool isInPlt() const { return PltIndex != -1U; }<br>
>>>> > - template <class ELFT> bool hasThunk() const;<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > typename ELFT::uint getVA(typename ELFT::uint Addend = 0) const;<br>
>>>> > @@ -86,7 +85,6 @@ public:<br>
>>>> > template <class ELFT> typename ELFT::uint getGotPltOffset() const;<br>
>>>> > template <class ELFT> typename ELFT::uint getGotPltVA() const;<br>
>>>> > template <class ELFT> typename ELFT::uint getPltVA() const;<br>
>>>> > - template <class ELFT> typename ELFT::uint getThunkVA() const;<br>
>>>> > template <class ELFT> typename ELFT::uint getSize() const;<br>
>>>> ><br>
>>>> > // The file from which this symbol was created.<br>
>>>> > @@ -210,10 +208,6 @@ public:<br>
>>>> > // If this is null, the symbol is an absolute symbol.<br>
>>>> > InputSectionBase<ELFT> *&Section;<br>
>>>> ><br>
>>>> > - // If non-null the symbol has a Thunk that may be used as an<br>
>>>> > alternative<br>
>>>> > - // destination for callers of this Symbol.<br>
>>>> > - Thunk<ELFT> *ThunkData = nullptr;<br>
>>>> > -<br>
>>>> > private:<br>
>>>> > static InputSectionBase<ELFT> *NullInputSection;<br>
>>>> > };<br>
>>>> > @@ -242,7 +236,7 @@ public:<br>
>>>> > const OutputSectionBase *Section;<br>
>>>> > };<br>
>>>> ><br>
>>>> > -template <class ELFT> class Undefined : public SymbolBody {<br>
>>>> > +class Undefined : public SymbolBody {<br>
>>>> > public:<br>
>>>> > Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t<br>
>>>> > Type,<br>
>>>> > InputFile *F);<br>
>>>> > @@ -251,12 +245,6 @@ public:<br>
>>>> > return S->kind() == UndefinedKind;<br>
>>>> > }<br>
>>>> ><br>
>>>> > - // If non-null the symbol has a Thunk that may be used as an<br>
>>>> > alternative<br>
>>>> > - // destination for callers of this Symbol. When linking a DSO<br>
>>>> > undefined<br>
>>>> > - // symbols are implicitly imported, the symbol lookup will be<br>
>>>> > performed by<br>
>>>> > - // the dynamic loader. A call to an undefined symbol will be given a<br>
>>>> > PLT<br>
>>>> > - // entry and on ARM this may need a Thunk if the caller is in Thumb<br>
>>>> > state.<br>
>>>> > - Thunk<ELFT> *ThunkData = nullptr;<br>
>>>> > InputFile *file() { return this->File; }<br>
>>>> > };<br>
>>>> ><br>
>>>> > @@ -291,9 +279,6 @@ public:<br>
>>>> > // CopyOffset is significant only when needsCopy() is true.<br>
>>>> > uintX_t CopyOffset = 0;<br>
>>>> ><br>
>>>> > - // If non-null the symbol has a Thunk that may be used as an<br>
>>>> > alternative<br>
>>>> > - // destination for callers of this Symbol.<br>
>>>> > - Thunk<ELFT> *ThunkData = nullptr;<br>
>>>> > bool needsCopy() const { return this->NeedsCopyOrPltAddr &&<br>
>>>> > !this->isFunc(); }<br>
>>>> ><br>
>>>> > OutputSection<ELFT> *getBssSectionForCopy() const;<br>
>>>> > @@ -431,8 +416,7 @@ struct Symbol {<br>
>>>> > // ELFT, and we verify this with the static_asserts in replaceBody.<br>
>>>> > llvm::AlignedCharArrayUnion<<br>
>>>> > DefinedCommon, DefinedRegular<llvm::object::E<wbr>LF64LE>,<br>
>>>> > DefinedSynthetic,<br>
>>>> > - Undefined<llvm::object::ELF64L<wbr>E>,<br>
>>>> > SharedSymbol<llvm::object::ELF<wbr>64LE>,<br>
>>>> > - LazyArchive, LazyObject><br>
>>>> > + Undefined, SharedSymbol<llvm::object::ELF<wbr>64LE>, LazyArchive,<br>
>>>> > LazyObject><br>
>>>> > Body;<br>
>>>> ><br>
>>>> > SymbolBody *body() { return reinterpret_cast<SymbolBody<br>
>>>> > *>(Body.buffer); }<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/SyntheticSection<wbr>s.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/SyntheticS<wbr>ections.cpp?rev=293283&r1=<wbr>293282&r2=293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/SyntheticSection<wbr>s.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/SyntheticSection<wbr>s.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -1904,6 +1904,27 @@ void ARMExidxSentinelSection<ELFT>:<wbr>:writ<br>
>>>> > write32le(Buf + 4, 0x1);<br>
>>>> > }<br>
>>>> ><br>
>>>> > +template <class ELFT><br>
>>>> > +ThunkSection<ELFT>::ThunkSect<wbr>ion(OutputSectionBase *OS, uint64_t Off)<br>
>>>> > + : SyntheticSection<ELFT>(SHF_ALL<wbr>OC, SHT_PROGBITS,<br>
>>>> > + sizeof(typename ELFT::uint),<br>
>>>> > ".text.thunk") {<br>
>>>> > + this->OutSec = OS;<br>
>>>> > + this->OutSecOff = Off;<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +template <class ELFT> void ThunkSection<ELFT>::addThunk(T<wbr>hunk<ELFT> *T)<br>
>>>> > {<br>
>>>> > + uint64_t Off = alignTo(Size, T->alignment);<br>
>>>> > + T->Offset = Off;<br>
>>>> > + Thunks.push_back(T);<br>
>>>> > + T->addSymbols(*this);<br>
>>>> > + Size = Off + T->size();<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +template <class ELFT> void ThunkSection<ELFT>::writeTo(ui<wbr>nt8_t *Buf) {<br>
>>>> > + for (const Thunk<ELFT> *T : Thunks)<br>
>>>> > + T->writeTo(Buf + T->Offset, *this);<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > template InputSection<ELF32LE> *elf::createCommonSection();<br>
>>>> > template InputSection<ELF32BE> *elf::createCommonSection();<br>
>>>> > template InputSection<ELF64LE> *elf::createCommonSection();<br>
>>>> > @@ -2046,3 +2067,8 @@ template class elf::ARMExidxSentinelSect<br>
>>>> > template class elf::ARMExidxSentinelSection<E<wbr>LF32BE>;<br>
>>>> > template class elf::ARMExidxSentinelSection<E<wbr>LF64LE>;<br>
>>>> > template class elf::ARMExidxSentinelSection<E<wbr>LF64BE>;<br>
>>>> > +<br>
>>>> > +template class elf::ThunkSection<ELF32LE>;<br>
>>>> > +template class elf::ThunkSection<ELF32BE>;<br>
>>>> > +template class elf::ThunkSection<ELF64LE>;<br>
>>>> > +template class elf::ThunkSection<ELF64BE>;<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/SyntheticSection<wbr>s.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/SyntheticS<wbr>ections.h?rev=293283&r1=<wbr>293282&r2=293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/SyntheticSection<wbr>s.h (original)<br>
>>>> > +++ lld/trunk/ELF/SyntheticSection<wbr>s.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -699,6 +699,26 @@ public:<br>
>>>> > void writeTo(uint8_t *Buf) override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > +// A container for one or more linker generated thunks. Instances of<br>
>>>> > these<br>
>>>> > +// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.<br>
>>>> > +template <class ELFT> class ThunkSection : public<br>
>>>> > SyntheticSection<ELFT> {<br>
>>>> > +public:<br>
>>>> > + // ThunkSection in OS, with desired OutSecOff of Off<br>
>>>> > + ThunkSection(OutputSectionBase *OS, uint64_t Off);<br>
>>>> > +<br>
>>>> > + // Add a newly created Thunk to this container:<br>
>>>> > + // Thunk is given offset from start of this InputSection<br>
>>>> > + // Thunk defines a symbol in this InputSection that can be used as<br>
>>>> > target<br>
>>>> > + // of a relocation<br>
>>>> > + void addThunk(Thunk<ELFT> *T);<br>
>>>> > + size_t getSize() const override { return Size; }<br>
>>>> > + void writeTo(uint8_t *Buf) override;<br>
>>>> > +<br>
>>>> > +private:<br>
>>>> > + std::vector<const Thunk<ELFT> *> Thunks;<br>
>>>> > + size_t Size = 0;<br>
>>>> > +};<br>
>>>> > +<br>
>>>> > template <class ELFT> InputSection<ELFT> *createCommonSection();<br>
>>>> > template <class ELFT> InputSection<ELFT> *createInterpSection();<br>
>>>> > template <class ELFT> MergeInputSection<ELFT> *createCommentSection();<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Target.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Target.cpp<wbr>?rev=293283&r1=293282&r2=29328<wbr>3&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Target.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/Target.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -228,8 +228,8 @@ public:<br>
>>>> > int32_t Index, unsigned RelOff) const override;<br>
>>>> > void addPltSymbols(InputSectionData *IS, uint64_t Off) const<br>
>>>> > override;<br>
>>>> > void addPltHeaderSymbols(InputSecti<wbr>onData *ISD) const override;<br>
>>>> > - RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const<br>
>>>> > InputFile *File,<br>
>>>> > - const SymbolBody &S) const override;<br>
>>>> > + bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile<br>
>>>> > *File,<br>
>>>> > + const SymbolBody &S) const override;<br>
>>>> > void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const<br>
>>>> > override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > @@ -246,8 +246,8 @@ public:<br>
>>>> > void writePltHeader(uint8_t *Buf) const override;<br>
>>>> > void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t<br>
>>>> > PltEntryAddr,<br>
>>>> > int32_t Index, unsigned RelOff) const override;<br>
>>>> > - RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType, const<br>
>>>> > InputFile *File,<br>
>>>> > - const SymbolBody &S) const override;<br>
>>>> > + bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile<br>
>>>> > *File,<br>
>>>> > + const SymbolBody &S) const override;<br>
>>>> > void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const<br>
>>>> > override;<br>
>>>> > bool usesOnlyLowPageBits(uint32_t Type) const override;<br>
>>>> > };<br>
>>>> > @@ -298,10 +298,9 @@ uint64_t TargetInfo::getImplicitAddend(<wbr>c<br>
>>>> ><br>
>>>> > bool TargetInfo::usesOnlyLowPageBit<wbr>s(uint32_t Type) const { return<br>
>>>> > false; }<br>
>>>> ><br>
>>>> > -RelExpr TargetInfo::getThunkExpr(RelEx<wbr>pr Expr, uint32_t RelocType,<br>
>>>> > - const InputFile *File,<br>
>>>> > - const SymbolBody &S) const {<br>
>>>> > - return Expr;<br>
>>>> > +bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,<br>
>>>> > + const InputFile *File, const SymbolBody &S)<br>
>>>> > const {<br>
>>>> > + return false;<br>
>>>> > }<br>
>>>> ><br>
>>>> > bool TargetInfo::isTlsInitialExecRe<wbr>l(uint32_t Type) const { return<br>
>>>> > false; }<br>
>>>> > @@ -1771,15 +1770,15 @@ void ARMTargetInfo::addPltSymbols(I<wbr>nputS<br>
>>>> > addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);<br>
>>>> > }<br>
>>>> ><br>
>>>> > -RelExpr ARMTargetInfo::getThunkExpr(Re<wbr>lExpr Expr, uint32_t RelocType,<br>
>>>> > - const InputFile *File,<br>
>>>> > - const SymbolBody &S) const {<br>
>>>> > +bool ARMTargetInfo::needsThunk(RelE<wbr>xpr Expr, uint32_t RelocType,<br>
>>>> > + const InputFile *File,<br>
>>>> > + const SymbolBody &S) const {<br>
>>>> > // If S is an undefined weak symbol in an executable we don't need a<br>
>>>> > Thunk.<br>
>>>> > // In a DSO calls to undefined symbols, including weak ones get PLT<br>
>>>> > entries<br>
>>>> > // which may need a thunk.<br>
>>>> > if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() &&<br>
>>>> > !Config->Shared)<br>
>>>> > - return Expr;<br>
>>>> > + return false;<br>
>>>> > // A state change from ARM to Thumb and vice versa must go through an<br>
>>>> > // interworking thunk if the relocation type is not R_ARM_CALL or<br>
>>>> > // R_ARM_THM_CALL.<br>
>>>> > @@ -1790,19 +1789,17 @@ RelExpr ARMTargetInfo::getThunkExpr(Re<wbr>lE<br>
>>>> > // Source is ARM, all PLT entries are ARM so no interworking<br>
>>>> > required.<br>
>>>> > // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).<br>
>>>> > if (Expr == R_PC && ((S.getVA<ELF32LE>() & 1) == 1))<br>
>>>> > - return R_THUNK_PC;<br>
>>>> > + return true;<br>
>>>> > break;<br>
>>>> > case R_ARM_THM_JUMP19:<br>
>>>> > case R_ARM_THM_JUMP24:<br>
>>>> > // Source is Thumb, all PLT entries are ARM so interworking is<br>
>>>> > required.<br>
>>>> > // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).<br>
>>>> > - if (Expr == R_PLT_PC)<br>
>>>> > - return R_THUNK_PLT_PC;<br>
>>>> > - if ((S.getVA<ELF32LE>() & 1) == 0)<br>
>>>> > - return R_THUNK_PC;<br>
>>>> > + if (Expr == R_PLT_PC || ((S.getVA<ELF32LE>() & 1) == 0))<br>
>>>> > + return true;<br>
>>>> > break;<br>
>>>> > }<br>
>>>> > - return Expr;<br>
>>>> > + return false;<br>
>>>> > }<br>
>>>> ><br>
>>>> > void ARMTargetInfo::relocateOne(uin<wbr>t8_t *Loc, uint32_t Type,<br>
>>>> > @@ -2215,26 +2212,26 @@ void MipsTargetInfo<ELFT>::writePlt<wbr>(uint<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > -RelExpr MipsTargetInfo<ELFT>::getThunk<wbr>Expr(RelExpr Expr, uint32_t Type,<br>
>>>> > - const InputFile *File,<br>
>>>> > - const SymbolBody &S) const {<br>
>>>> > +bool MipsTargetInfo<ELFT>::needsThu<wbr>nk(RelExpr Expr, uint32_t Type,<br>
>>>> > + const InputFile *File,<br>
>>>> > + const SymbolBody &S) const {<br>
>>>> > // Any MIPS PIC code function is invoked with its address in register<br>
>>>> > $t9.<br>
>>>> > // So if we have a branch instruction from non-PIC code to the PIC<br>
>>>> > one<br>
>>>> > // we cannot make the jump directly and need to create a small stubs<br>
>>>> > // to save the target function address.<br>
>>>> > // See page 3-38<br>
>>>> > <a href="ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf" rel="noreferrer" target="_blank">ftp://www.linux-mips.org/pub/l<wbr>inux/mips/doc/ABI/mipsabi.pdf</a><br>
>>>> > if (Type != R_MIPS_26)<br>
>>>> > - return Expr;<br>
>>>> > + return false;<br>
>>>> > auto *F = dyn_cast_or_null<ELFFileBase<E<wbr>LFT>>(File);<br>
>>>> > if (!F)<br>
>>>> > - return Expr;<br>
>>>> > + return false;<br>
>>>> > // If current file has PIC code, LA25 stub is not required.<br>
>>>> > if (F->getObj().getHeader()->e_fl<wbr>ags & EF_MIPS_PIC)<br>
>>>> > - return Expr;<br>
>>>> > + return false;<br>
>>>> > auto *D = dyn_cast<DefinedRegular<ELFT>><wbr>(&S);<br>
>>>> > // LA25 is required if target file has PIC code<br>
>>>> > // or target symbol is a PIC symbol.<br>
>>>> > - return D && D->isMipsPIC() ? R_THUNK_ABS : Expr;<br>
>>>> > + return D && D->isMipsPIC();<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Target.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Target.h?<wbr>rev=293283&r1=293282&r2=293283<wbr>&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Target.h (original)<br>
>>>> > +++ lld/trunk/ELF/Target.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -41,8 +41,8 @@ public:<br>
>>>> > virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,<br>
>>>> > uint64_t PltEntryAddr, int32_t Index,<br>
>>>> > unsigned RelOff) const {}<br>
>>>> > - virtual void addPltHeaderSymbols(InputSecti<wbr>onData* IS) const {}<br>
>>>> > - virtual void addPltSymbols(InputSectionData<wbr>* IS, uint64_t Off) const<br>
>>>> > {}<br>
>>>> > + virtual void addPltHeaderSymbols(InputSecti<wbr>onData *IS) const {}<br>
>>>> > + virtual void addPltSymbols(InputSectionData *IS, uint64_t Off) const<br>
>>>> > {}<br>
>>>> > // Returns true if a relocation only uses the low bits of a value<br>
>>>> > such that<br>
>>>> > // all those bits are in in the same page. For example, if the<br>
>>>> > relocation<br>
>>>> > // only uses the low 12 bits in a system with 4k pages. If this is<br>
>>>> > true, the<br>
>>>> > @@ -51,14 +51,9 @@ public:<br>
>>>> > virtual bool usesOnlyLowPageBits(uint32_t Type) const;<br>
>>>> ><br>
>>>> > // Decide whether a Thunk is needed for the relocation from File<br>
>>>> > - // targeting S. Returns one of:<br>
>>>> > - // Expr if there is no Thunk required<br>
>>>> > - // R_THUNK_ABS if thunk is required and expression is absolute<br>
>>>> > - // R_THUNK_PC if thunk is required and expression is pc rel<br>
>>>> > - // R_THUNK_PLT_PC if thunk is required to PLT entry and expression is<br>
>>>> > pc rel<br>
>>>> > - virtual RelExpr getThunkExpr(RelExpr Expr, uint32_t RelocType,<br>
>>>> > - const InputFile *File,<br>
>>>> > - const SymbolBody &S) const;<br>
>>>> > + // targeting S.<br>
>>>> > + virtual bool needsThunk(RelExpr Expr, uint32_t RelocType,<br>
>>>> > + const InputFile *File, const SymbolBody &S)<br>
>>>> > const;<br>
>>>> > virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const<br>
>>>> > = 0;<br>
>>>> > virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val)<br>
>>>> > const = 0;<br>
>>>> > virtual ~TargetInfo();<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Thunks.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Thunks.cpp<wbr>?rev=293283&r1=293282&r2=29328<wbr>3&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Thunks.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/Thunks.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -28,6 +28,7 @@<br>
>>>> > #include "Memory.h"<br>
>>>> > #include "OutputSections.h"<br>
>>>> > #include "Symbols.h"<br>
>>>> > +#include "SyntheticSections.h"<br>
>>>> > #include "Target.h"<br>
>>>> > #include "llvm/Support/Casting.h"<br>
>>>> > #include "llvm/Support/ELF.h"<br>
>>>> > @@ -52,53 +53,54 @@ namespace {<br>
>>>> > template <class ELFT><br>
>>>> > class ARMToThumbV7ABSLongThunk final : public Thunk<ELFT> {<br>
>>>> > public:<br>
>>>> > - ARMToThumbV7ABSLongThunk(const SymbolBody &Dest,<br>
>>>> > - const InputSection<ELFT> &Owner)<br>
>>>> > - : Thunk<ELFT>(Dest, Owner) {}<br>
>>>> > + ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest)<br>
>>>> > {}<br>
>>>> ><br>
>>>> > uint32_t size() const override { return 12; }<br>
>>>> > - void writeTo(uint8_t *Buf) const override;<br>
>>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;<br>
>>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > template <class ELFT> class ARMToThumbV7PILongThunk final : public<br>
>>>> > Thunk<ELFT> {<br>
>>>> > public:<br>
>>>> > - ARMToThumbV7PILongThunk(const SymbolBody &Dest,<br>
>>>> > - const InputSection<ELFT> &Owner)<br>
>>>> > - : Thunk<ELFT>(Dest, Owner) {}<br>
>>>> > + ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest)<br>
>>>> > {}<br>
>>>> ><br>
>>>> > uint32_t size() const override { return 16; }<br>
>>>> > - void writeTo(uint8_t *Buf) const override;<br>
>>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;<br>
>>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > class ThumbToARMV7ABSLongThunk final : public Thunk<ELFT> {<br>
>>>> > public:<br>
>>>> > - ThumbToARMV7ABSLongThunk(const SymbolBody &Dest,<br>
>>>> > - const InputSection<ELFT> &Owner)<br>
>>>> > - : Thunk<ELFT>(Dest, Owner) {}<br>
>>>> > + ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest)<br>
>>>> > {<br>
>>>> > + this->alignment = 2;<br>
>>>> > + }<br>
>>>> ><br>
>>>> > uint32_t size() const override { return 10; }<br>
>>>> > - void writeTo(uint8_t *Buf) const override;<br>
>>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;<br>
>>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > template <class ELFT> class ThumbToARMV7PILongThunk final : public<br>
>>>> > Thunk<ELFT> {<br>
>>>> > public:<br>
>>>> > - ThumbToARMV7PILongThunk(const SymbolBody &Dest,<br>
>>>> > - const InputSection<ELFT> &Owner)<br>
>>>> > - : Thunk<ELFT>(Dest, Owner) {}<br>
>>>> > + ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {<br>
>>>> > + this->alignment = 2;<br>
>>>> > + }<br>
>>>> ><br>
>>>> > uint32_t size() const override { return 12; }<br>
>>>> > - void writeTo(uint8_t *Buf) const override;<br>
>>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;<br>
>>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > // MIPS LA25 thunk<br>
>>>> > template <class ELFT> class MipsThunk final : public Thunk<ELFT> {<br>
>>>> > public:<br>
>>>> > - MipsThunk(const SymbolBody &Dest, const InputSection<ELFT> &Owner)<br>
>>>> > - : Thunk<ELFT>(Dest, Owner) {}<br>
>>>> > + MipsThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}<br>
>>>> ><br>
>>>> > uint32_t size() const override { return 16; }<br>
>>>> > - void writeTo(uint8_t *Buf) const override;<br>
>>>> > + void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;<br>
>>>> > + void addSymbols(ThunkSection<ELFT> &IS) override;<br>
>>>> > + InputSection<ELFT> *getTargetInputSection() const override;<br>
>>>> > };<br>
>>>> ><br>
>>>> > } // end anonymous namespace<br>
>>>> > @@ -110,7 +112,8 @@ template <class ELFT> static uint64_t ge<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > -void ARMToThumbV7ABSLongThunk<ELFT><wbr>::writeTo(uint8_t *Buf) const {<br>
>>>> > +void ARMToThumbV7ABSLongThunk<ELFT><wbr>::writeTo(uint8_t *Buf,<br>
>>>> > + ThunkSection<ELFT> &IS)<br>
>>>> > const {<br>
>>>> > const uint8_t Data[] = {<br>
>>>> > 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S<br>
>>>> > 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S<br>
>>>> > @@ -123,7 +126,16 @@ void ARMToThumbV7ABSLongThunk<ELFT><wbr>::wri<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > -void ThumbToARMV7ABSLongThunk<ELFT><wbr>::writeTo(uint8_t *Buf) const {<br>
>>>> > +void ARMToThumbV7ABSLongThunk<ELFT><wbr>::addSymbols(ThunkSection<ELFT<wbr>> &IS)<br>
>>>> > {<br>
>>>> > + this->ThunkSym = addSyntheticLocal(<br>
>>>> > + Saver.save("__ARMToThumbv7ABSL<wbr>ongThunk_" +<br>
>>>> > this->Destination.getName()),<br>
>>>> > + STT_FUNC, this->Offset, size(), &IS);<br>
>>>> > + addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS);<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +template <class ELFT><br>
>>>> > +void ThumbToARMV7ABSLongThunk<ELFT><wbr>::writeTo(uint8_t *Buf,<br>
>>>> > + ThunkSection<ELFT> &IS)<br>
>>>> > const {<br>
>>>> > const uint8_t Data[] = {<br>
>>>> > 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S<br>
>>>> > 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S<br>
>>>> > @@ -136,7 +148,16 @@ void ThumbToARMV7ABSLongThunk<ELFT><wbr>::wri<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > -void ARMToThumbV7PILongThunk<ELFT>:<wbr>:writeTo(uint8_t *Buf) const {<br>
>>>> > +void ThumbToARMV7ABSLongThunk<ELFT><wbr>::addSymbols(ThunkSection<ELFT<wbr>> &IS)<br>
>>>> > {<br>
>>>> > + this->ThunkSym = addSyntheticLocal(<br>
>>>> > + Saver.save("__ThumbToARMv7ABSL<wbr>ongThunk_" +<br>
>>>> > this->Destination.getName()),<br>
>>>> > + STT_FUNC, this->Offset, size(), &IS);<br>
>>>> > + addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS);<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +template <class ELFT><br>
>>>> > +void ARMToThumbV7PILongThunk<ELFT>:<wbr>:writeTo(uint8_t *Buf,<br>
>>>> > + ThunkSection<ELFT> &IS)<br>
>>>> > const {<br>
>>>> > const uint8_t Data[] = {<br>
>>>> > 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P)<br>
>>>> > +8)<br>
>>>> > 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P+4)<br>
>>>> > +8)<br>
>>>> > @@ -144,14 +165,23 @@ void ARMToThumbV7PILongThunk<ELFT>:<wbr>:writ<br>
>>>> > 0x1c, 0xff, 0x2f, 0xe1, // bx r12<br>
>>>> > };<br>
>>>> > uint64_t S = getARMThunkDestVA<ELFT>(this-><wbr>Destination);<br>
>>>> > - uint64_t P = this->getVA();<br>
>>>> > + uint64_t P = this->ThunkSym->template getVA<ELFT>();<br>
>>>> > memcpy(Buf, Data, sizeof(Data));<br>
>>>> > Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, S - P - 16);<br>
>>>> > Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, S - P - 12);<br>
>>>> > }<br>
>>>> ><br>
>>>> > template <class ELFT><br>
>>>> > -void ThumbToARMV7PILongThunk<ELFT>:<wbr>:writeTo(uint8_t *Buf) const {<br>
>>>> > +void ARMToThumbV7PILongThunk<ELFT>:<wbr>:addSymbols(ThunkSection<ELFT> &IS)<br>
>>>> > {<br>
>>>> > + this->ThunkSym = addSyntheticLocal(<br>
>>>> > + Saver.save("__ARMToThumbV7PILo<wbr>ngThunk_" +<br>
>>>> > this->Destination.getName()),<br>
>>>> > + STT_FUNC, this->Offset, size(), &IS);<br>
>>>> > + addSyntheticLocal("$a", STT_NOTYPE, this->Offset, 0, &IS);<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > +template <class ELFT><br>
>>>> > +void ThumbToARMV7PILongThunk<ELFT>:<wbr>:writeTo(uint8_t *Buf,<br>
>>>> > + ThunkSection<ELFT> &IS)<br>
>>>> > const {<br>
>>>> > const uint8_t Data[] = {<br>
>>>> > 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) +<br>
>>>> > 4)<br>
>>>> > 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P+4)<br>
>>>> > + 4)<br>
>>>> > @@ -159,14 +189,23 @@ void ThumbToARMV7PILongThunk<ELFT>:<wbr>:writ<br>
>>>> > 0x60, 0x47, // bx r12<br>
>>>> > };<br>
>>>> > uint64_t S = getARMThunkDestVA<ELFT>(this-><wbr>Destination);<br>
>>>> > - uint64_t P = this->getVA();<br>
>>>> > + uint64_t P = this->ThunkSym->template getVA<ELFT>();<br>
>>>> > memcpy(Buf, Data, sizeof(Data));<br>
>>>> > Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, S - P - 12);<br>
>>>> > Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, S - P - 8);<br>
>>>> > }<br>
>>>> ><br>
>>>> > +template <class ELFT><br>
>>>> > +void ThumbToARMV7PILongThunk<ELFT>:<wbr>:addSymbols(ThunkSection<ELFT> &IS)<br>
>>>> > {<br>
>>>> > + this->ThunkSym = addSyntheticLocal(<br>
>>>> > + Saver.save("__ThumbToARMV7PILo<wbr>ngThunk_" +<br>
>>>> > this->Destination.getName()),<br>
>>>> > + STT_FUNC, this->Offset, size(), &IS);<br>
>>>> > + addSyntheticLocal("$t", STT_NOTYPE, this->Offset, 0, &IS);<br>
>>>> > +}<br>
>>>> > +<br>
>>>> > // Write MIPS LA25 thunk code to call PIC function from the non-PIC<br>
>>>> > one.<br>
>>>> > -template <class ELFT> void MipsThunk<ELFT>::writeTo(uint8<wbr>_t *Buf) const<br>
>>>> > {<br>
>>>> > +template <class ELFT><br>
>>>> > +void MipsThunk<ELFT>::writeTo(uint8<wbr>_t *Buf, ThunkSection<ELFT> &) const<br>
>>>> > {<br>
>>>> > const endianness E = ELFT::TargetEndianness;<br>
>>>> ><br>
>>>> > uint64_t S = this->Destination.template getVA<ELFT>();<br>
>>>> > @@ -178,20 +217,26 @@ template <class ELFT> void MipsThunk<ELF<br>
>>>> > Target->relocateOne(Buf + 8, R_MIPS_LO16, S);<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT><br>
>>>> > -Thunk<ELFT>::Thunk(const SymbolBody &D, const InputSection<ELFT> &O)<br>
>>>> > - : Destination(D), Owner(O), Offset(O.getThunkOff() +<br>
>>>> > O.getThunksSize()) {}<br>
>>>> > +template <class ELFT> void<br>
>>>> > MipsThunk<ELFT>::addSymbols(Th<wbr>unkSection<ELFT> &IS) {<br>
>>>> > + this->ThunkSym = addSyntheticLocal(<br>
>>>> > + Saver.save("__LA25Thunk_" + this->Destination.getName()),<br>
>>>> > STT_FUNC,<br>
>>>> > + this->Offset, size(), &IS);<br>
>>>> > +}<br>
>>>> ><br>
>>>> > -template <class ELFT> typename ELFT::uint Thunk<ELFT>::getVA() const {<br>
>>>> > - return Owner.OutSec->Addr + Owner.OutSecOff + Offset;<br>
>>>> > +template <class ELFT><br>
>>>> > +InputSection<ELFT> *MipsThunk<ELFT>::getTargetInp<wbr>utSection() const {<br>
>>>> > + auto *DR = dyn_cast<DefinedRegular<ELFT>><wbr>(&this->Destination);<br>
>>>> > + return dyn_cast<InputSection<ELFT>>(D<wbr>R->Section);<br>
>>>> > }<br>
>>>> ><br>
>>>> > +template <class ELFT><br>
>>>> > +Thunk<ELFT>::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {}<br>
>>>> > +<br>
>>>> > template <class ELFT> Thunk<ELFT>::~Thunk() = default;<br>
>>>> ><br>
>>>> > // Creates a thunk for Thumb-ARM interworking.<br>
>>>> > template <class ELFT><br>
>>>> > -static Thunk<ELFT> *createThunkArm(uint32_t Reloc, SymbolBody &S,<br>
>>>> > - InputSection<ELFT> &IS) {<br>
>>>> > +static Thunk<ELFT> *addThunkArm(uint32_t Reloc, SymbolBody &S) {<br>
>>>> > // ARM relocations need ARM to Thumb interworking Thunks.<br>
>>>> > // Thumb relocations need Thumb to ARM relocations.<br>
>>>> > // Use position independent Thunks if we require position independent<br>
>>>> > code.<br>
>>>> > @@ -200,71 +245,34 @@ static Thunk<ELFT> *createThunkArm(uint3<br>
>>>> > case R_ARM_PLT32:<br>
>>>> > case R_ARM_JUMP24:<br>
>>>> > if (Config->Pic)<br>
>>>> > - return new (BAlloc) ARMToThumbV7PILongThunk<ELFT>(<wbr>S, IS);<br>
>>>> > - return new (BAlloc) ARMToThumbV7ABSLongThunk<ELFT><wbr>(S, IS);<br>
>>>> > + return make<ARMToThumbV7PILongThunk<E<wbr>LFT>>(S);<br>
>>>> > + return make<ARMToThumbV7ABSLongThunk<<wbr>ELFT>>(S);<br>
>>>> > case R_ARM_THM_JUMP19:<br>
>>>> > case R_ARM_THM_JUMP24:<br>
>>>> > if (Config->Pic)<br>
>>>> > - return new (BAlloc) ThumbToARMV7PILongThunk<ELFT>(<wbr>S, IS);<br>
>>>> > - return new (BAlloc) ThumbToARMV7ABSLongThunk<ELFT><wbr>(S, IS);<br>
>>>> > + return make<ThumbToARMV7PILongThunk<E<wbr>LFT>>(S);<br>
>>>> > + return make<ThumbToARMV7ABSLongThunk<<wbr>ELFT>>(S);<br>
>>>> > }<br>
>>>> > fatal("unrecognized relocation type");<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT><br>
>>>> > -static void addThunkARM(uint32_t Reloc, SymbolBody &S,<br>
>>>> > InputSection<ELFT> &IS) {<br>
>>>> > - // Only one Thunk supported per symbol.<br>
>>>> > - if (S.hasThunk<ELFT>())<br>
>>>> > - return;<br>
>>>> > -<br>
>>>> > - // ARM Thunks are added to the same InputSection as the relocation.<br>
>>>> > This<br>
>>>> > - // isn't strictly necessary but it makes it more likely that a<br>
>>>> > limited range<br>
>>>> > - // branch can reach the Thunk, and it makes Thunks to the PLT section<br>
>>>> > easier<br>
>>>> > - Thunk<ELFT> *T = createThunkArm(Reloc, S, IS);<br>
>>>> > - IS.addThunk(T);<br>
>>>> > - if (auto *Sym = dyn_cast<DefinedRegular<ELFT>><wbr>(&S))<br>
>>>> > - Sym->ThunkData = T;<br>
>>>> > - else if (auto *Sym = dyn_cast<SharedSymbol<ELFT>>(&<wbr>S))<br>
>>>> > - Sym->ThunkData = T;<br>
>>>> > - else if (auto *Sym = dyn_cast<Undefined<ELFT>>(&S))<br>
>>>> > - Sym->ThunkData = T;<br>
>>>> > - else<br>
>>>> > - fatal("symbol not DefinedRegular or Shared");<br>
>>>> > -}<br>
>>>> > -<br>
>>>> > -template <class ELFT><br>
>>>> > -static void addThunkMips(uint32_t RelocType, SymbolBody &S,<br>
>>>> > - InputSection<ELFT> &IS) {<br>
>>>> > - // Only one Thunk supported per symbol.<br>
>>>> > - if (S.hasThunk<ELFT>())<br>
>>>> > - return;<br>
>>>> > -<br>
>>>> > - // Mips Thunks are added to the InputSection defining S.<br>
>>>> > - auto *R = cast<DefinedRegular<ELFT>>(&S)<wbr>;<br>
>>>> > - auto *Sec = cast<InputSection<ELFT>>(R->Se<wbr>ction);<br>
>>>> > - auto *T = new (BAlloc) MipsThunk<ELFT>(S, *Sec);<br>
>>>> > - Sec->addThunk(T);<br>
>>>> > - R->ThunkData = T;<br>
>>>> > +template <class ELFT> static Thunk<ELFT> *addThunkMips(SymbolBody &S) {<br>
>>>> > + return make<MipsThunk<ELFT>>(S);<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template <class ELFT><br>
>>>> > -void addThunk(uint32_t RelocType, SymbolBody &S, InputSection<ELFT><br>
>>>> > &IS) {<br>
>>>> > +template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType,<br>
>>>> > SymbolBody &S) {<br>
>>>> > if (Config->EMachine == EM_ARM)<br>
>>>> > - addThunkARM<ELFT>(RelocType, S, IS);<br>
>>>> > + return addThunkArm<ELFT>(RelocType, S);<br>
>>>> > else if (Config->EMachine == EM_MIPS)<br>
>>>> > - addThunkMips<ELFT>(RelocType, S, IS);<br>
>>>> > - else<br>
>>>> > - llvm_unreachable("add Thunk only supported for ARM and Mips");<br>
>>>> > + return addThunkMips<ELFT>(S);<br>
>>>> > + llvm_unreachable("add Thunk only supported for ARM and Mips");<br>
>>>> > + return nullptr;<br>
>>>> > }<br>
>>>> ><br>
>>>> > -template void addThunk<ELF32LE>(uint32_t, SymbolBody &,<br>
>>>> > - InputSection<ELF32LE> &);<br>
>>>> > -template void addThunk<ELF32BE>(uint32_t, SymbolBody &,<br>
>>>> > - InputSection<ELF32BE> &);<br>
>>>> > -template void addThunk<ELF64LE>(uint32_t, SymbolBody &,<br>
>>>> > - InputSection<ELF64LE> &);<br>
>>>> > -template void addThunk<ELF64BE>(uint32_t, SymbolBody &,<br>
>>>> > - InputSection<ELF64BE> &);<br>
>>>> > +template Thunk<ELF32LE> *addThunk<ELF32LE>(uint32_t, SymbolBody &);<br>
>>>> > +template Thunk<ELF32BE> *addThunk<ELF32BE>(uint32_t, SymbolBody &);<br>
>>>> > +template Thunk<ELF64LE> *addThunk<ELF64LE>(uint32_t, SymbolBody &);<br>
>>>> > +template Thunk<ELF64BE> *addThunk<ELF64BE>(uint32_t, SymbolBody &);<br>
>>>> ><br>
>>>> > template class Thunk<ELF32LE>;<br>
>>>> > template class Thunk<ELF32BE>;<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Thunks.h<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.h?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Thunks.h?<wbr>rev=293283&r1=293282&r2=293283<wbr>&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Thunks.h (original)<br>
>>>> > +++ lld/trunk/ELF/Thunks.h Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -15,8 +15,8 @@<br>
>>>> > namespace lld {<br>
>>>> > namespace elf {<br>
>>>> > class SymbolBody;<br>
>>>> > -template <class ELFT> class InputSection;<br>
>>>> > -<br>
>>>> > +template <class ELFT> class ThunkSection;<br>
>>>> > +class OutputSectionBase;<br>
>>>> > // Class to describe an instance of a Thunk.<br>
>>>> > // A Thunk is a code-sequence inserted by the linker in between a<br>
>>>> > caller and<br>
>>>> > // the callee. The relocation to the callee is redirected to the Thunk,<br>
>>>> > which<br>
>>>> > @@ -24,31 +24,35 @@ template <class ELFT> class InputSection<br>
>>>> > // include transferring control from non-pi to pi and changing state on<br>
>>>> > // targets like ARM.<br>
>>>> > //<br>
>>>> > -// Thunks can be created for DefinedRegular and Shared Symbols. The<br>
>>>> > Thunk<br>
>>>> > -// is stored in a field of the Symbol Destination.<br>
>>>> > -// Thunks to be written to an InputSection are recorded by the<br>
>>>> > InputSection.<br>
>>>> > +// Thunks can be created for DefinedRegular, Shared and Undefined<br>
>>>> > Symbols.<br>
>>>> > +// Thunks are assigned to synthetic ThunkSections<br>
>>>> > template <class ELFT> class Thunk {<br>
>>>> > - typedef typename ELFT::uint uintX_t;<br>
>>>> > -<br>
>>>> > public:<br>
>>>> > - Thunk(const SymbolBody &Destination, const InputSection<ELFT><br>
>>>> > &Owner);<br>
>>>> > + Thunk(const SymbolBody &Destination);<br>
>>>> > virtual ~Thunk();<br>
>>>> ><br>
>>>> > virtual uint32_t size() const { return 0; }<br>
>>>> > - virtual void writeTo(uint8_t *Buf) const {}<br>
>>>> > - uintX_t getVA() const;<br>
>>>> > + virtual void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const {}<br>
>>>> > +<br>
>>>> > + // All Thunks must define at least one symbol ThunkSym so that we can<br>
>>>> > + // redirect relocations to it.<br>
>>>> > + virtual void addSymbols(ThunkSection<ELFT> &IS) {}<br>
>>>> > +<br>
>>>> > + // Some Thunks must be placed immediately before their Target as they<br>
>>>> > elide<br>
>>>> > + // a branch and fall through to the first Symbol in the Target.<br>
>>>> > + virtual InputSection<ELFT> *getTargetInputSection() const { return<br>
>>>> > nullptr; }<br>
>>>> ><br>
>>>> > -protected:<br>
>>>> > + // The alignment requirement for this Thunk, defaults to the size of<br>
>>>> > the<br>
>>>> > + // typical code section alignment.<br>
>>>> > const SymbolBody &Destination;<br>
>>>> > - const InputSection<ELFT> &Owner;<br>
>>>> > + SymbolBody *ThunkSym;<br>
>>>> > uint64_t Offset;<br>
>>>> > + uint32_t alignment = 4;<br>
>>>> > };<br>
>>>> ><br>
>>>> > -// For a Relocation to symbol S from InputSection Src, create a Thunk<br>
>>>> > and<br>
>>>> > -// update the fields of S and the InputSection that the Thunk body will<br>
>>>> > be<br>
>>>> > -// written to. At present there are implementations for ARM and Mips<br>
>>>> > Thunks.<br>
>>>> > -template <class ELFT><br>
>>>> > -void addThunk(uint32_t RelocType, SymbolBody &S, InputSection<ELFT><br>
>>>> > &Src);<br>
>>>> > +// For a Relocation to symbol S create a Thunk to be added to a<br>
>>>> > synthetic<br>
>>>> > +// ThunkSection. At present there are implementations for ARM and Mips<br>
>>>> > Thunks.<br>
>>>> > +template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType,<br>
>>>> > SymbolBody &S);<br>
>>>> ><br>
>>>> > } // namespace elf<br>
>>>> > } // namespace lld<br>
>>>> ><br>
>>>> > Modified: lld/trunk/ELF/Writer.cpp<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/Writer.cpp<wbr>?rev=293283&r1=293282&r2=29328<wbr>3&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/ELF/Writer.cpp (original)<br>
>>>> > +++ lld/trunk/ELF/Writer.cpp Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -1027,6 +1027,12 @@ template <class ELFT> void Writer<ELFT>:<br>
>>>> > if (In<ELFT>::Iplt && !In<ELFT>::Iplt->empty())<br>
>>>> > In<ELFT>::Iplt->addSymbols();<br>
>>>> ><br>
>>>> > + // Some architectures use small displacements for jump instructions.<br>
>>>> > + // It is linker's responsibility to create thunks containing long<br>
>>>> > + // jump instructions if jump targets are too far. Create thunks.<br>
>>>> > + if (Target->NeedsThunks)<br>
>>>> > + createThunks<ELFT>(OutputSecti<wbr>ons);<br>
>>>> > +<br>
>>>> > // Now that we have defined all possible symbols including linker-<br>
>>>> > // synthesized ones. Visit all symbols to give the finishing touches.<br>
>>>> > for (Symbol *S : Symtab<ELFT>::X->getSymbols()) {<br>
>>>> > @@ -1072,12 +1078,6 @@ template <class ELFT> void Writer<ELFT>:<br>
>>>> > fixHeaders();<br>
>>>> > }<br>
>>>> ><br>
>>>> > - // Some architectures use small displacements for jump instructions.<br>
>>>> > - // It is linker's responsibility to create thunks containing long<br>
>>>> > - // jump instructions if jump targets are too far. Create thunks.<br>
>>>> > - if (Target->NeedsThunks)<br>
>>>> > - createThunks<ELFT>(OutputSecti<wbr>ons);<br>
>>>> > -<br>
>>>> > // Fill other section headers. The dynamic table is finalized<br>
>>>> > // at the end because some tags like RELSZ depend on result<br>
>>>> > // of finalizing other sections.<br>
>>>> ><br>
>>>> > Modified: lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-shared.s<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-shared.s?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/test/ELF/arm-<wbr>thumb-interwork-shared.s?rev=<wbr>293283&r1=293282&r2=293283&<wbr>view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-shared.s (original)<br>
>>>> > +++ lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-shared.s Fri Jan 27 07:10:16<br>
>>>> > 2017<br>
>>>> > @@ -16,12 +16,15 @@ sym1:<br>
>>>> ><br>
>>>> > // CHECK: Disassembly of section .text:<br>
>>>> > // CHECK-NEXT: sym1:<br>
>>>> > -// CHECK: 1000: 00 f0 02 b8 b.w #4<br>
>>>> > -// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12<br>
>>>> > +// CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4<br>
>>>> > <__ThumbToARMV7PILongThunk_els<wbr>ewhere+0x4><br>
>>>> > +// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12<br>
>>>> > <__ThumbToARMV7PILongThunk_wea<wbr>kref+0x4><br>
>>>> > +// CHECK: __ThumbToARMV7PILongThunk_else<wbr>where:<br>
>>>> > // CHECK-NEXT: 1008: 40 f2 20 0c movw r12, #32<br>
>>>> > // CHECK-NEXT: 100c: c0 f2 00 0c movt r12, #0<br>
>>>> > // CHECK-NEXT: 1010: fc 44 add r12, pc<br>
>>>> > // CHECK-NEXT: 1012: 60 47 bx r12<br>
>>>> > +<br>
>>>> > +// CHECK: __ThumbToARMV7PILongThunk_weak<wbr>ref:<br>
>>>> > // CHECK-NEXT: 1014: 40 f2 24 0c movw r12, #36<br>
>>>> > // CHECK-NEXT: 1018: c0 f2 00 0c movt r12, #0<br>
>>>> > // CHECK-NEXT: 101c: fc 44 add r12, pc<br>
>>>> ><br>
>>>> > Modified: lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-thunk.s<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk.s?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/test/ELF/arm-<wbr>thumb-interwork-thunk.s?rev=<wbr>293283&r1=293282&r2=293283&<wbr>view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-thunk.s (original)<br>
>>>> > +++ lld/trunk/test/ELF/arm-thumb-i<wbr>nterwork-thunk.s Fri Jan 27 07:10:16<br>
>>>> > 2017<br>
>>>> > @@ -78,62 +78,65 @@ arm_caller:<br>
>>>> > beq arm_callee2<br>
>>>> > bne arm_callee3<br>
>>>> > bx lr<br>
>>>> > -// CHECK-ABS-ARM: Disassembly of section .arm_caller:<br>
>>>> > -// CHECK-ABS-ARM-NEXT: arm_caller:<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1300: 3e ff ff fa blx #-776<br>
>>>> > <thumb_callee1><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1304: 3d ff ff fa blx #-780<br>
>>>> > <thumb_callee1><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1308: 06 00 00 ea b #24<br>
>>>> > <arm_caller+0x28><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 130c: 05 00 00 ea b #20<br>
>>>> > <arm_caller+0x28><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1310: 07 00 00 ea b #28<br>
>>>> > <arm_caller+0x34><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1314: 09 00 00 ea b #36<br>
>>>> > <arm_caller+0x40><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1318: 78 ff ff ea b #-544<br>
>>>> > <arm_callee1><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 131c: b7 00 00 0a beq #732<br>
>>>> > <arm_callee2><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1320: b7 00 00 1a bne #732<br>
>>>> > <arm_callee3><br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1324: 1e ff 2f e1 bx lr<br>
>>>> > +// CHECK-ARM-ABS-ARM: Disassembly of section .arm_caller:<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: arm_caller:<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1300: 3e ff ff fa blx<br>
>>>> > #-776 <thumb_callee1><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1304: 3d ff ff fa blx<br>
>>>> > #-780 <thumb_callee1><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1308: 06 00 00 ea b #24<br>
>>>> > <__ARMToThumbv7ABSLongThunk_th<wbr>umb_callee1><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 130c: 05 00 00 ea b #20<br>
>>>> > <__ARMToThumbv7ABSLongThunk_th<wbr>umb_callee1><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1310: 07 00 00 ea b #28<br>
>>>> > <__ARMToThumbv7ABSLongThunk_th<wbr>umb_callee2><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1314: 09 00 00 ea b #36<br>
>>>> > <__ARMToThumbv7ABSLongThunk_th<wbr>umb_callee3><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1318: 78 ff ff ea b<br>
>>>> > #-544 <arm_callee1><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 131c: b7 00 00 0a beq #732<br>
>>>> > <arm_callee2><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1320: b7 00 00 1a bne #732<br>
>>>> > <arm_callee3><br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1324: 1e ff 2f e1 bx lr<br>
>>>> > +// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thu<wbr>mb_callee1:<br>
>>>> > // 0x1001 = thumb_callee1<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1328: 01 c0 01 e3 movw r12, #4097<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 132c: 00 c0 40 e3 movt r12, #0<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1330: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1328: 01 c0 01 e3 movw r12,<br>
>>>> > #4097<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 132c: 00 c0 40 e3 movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1330: 1c ff 2f e1 bx r12<br>
>>>> > // 0x1501 = thumb_callee2<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1334: 01 c5 01 e3 movw r12, #5377<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1338: 00 c0 40 e3 movt r12, #0<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 133c: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thu<wbr>mb_callee2:<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1334: 01 c5 01 e3 movw r12,<br>
>>>> > #5377<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1338: 00 c0 40 e3 movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 133c: 1c ff 2f e1 bx r12<br>
>>>> > // 0x1503 = thumb_callee3<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1340: 03 c5 01 e3 movw r12, #5379<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1344: 00 c0 40 e3 movt r12, #0<br>
>>>> > -// CHECK-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-ARM-ABS-ARM: __ARMToThumbv7ABSLongThunk_thu<wbr>mb_callee3:<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1340: 03 c5 01 e3 movw r12,<br>
>>>> > #5379<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1344: 00 c0 40 e3 movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ARM-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12<br>
>>>> ><br>
>>>> > // CHECK-PI-ARM: Disassembly of section .arm_caller:<br>
>>>> > // CHECK-PI-ARM-NEXT: arm_caller:<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776<br>
>>>> > <thumb_callee1><br>
>>>> > -// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780<br>
>>>> > <thumb_callee1><br>
>>>> > -// 0x1308 + 8 + 0x18 = 0x1328<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1308: 06 00 00 ea b #24<br>
>>>> > <arm_caller+0x28><br>
>>>> > -// 0x130c + 8 + 0x14 = 0x1328<br>
>>>> > -// CHECK-PI-ARM-NEXT: 130c: 05 00 00 ea b #20<br>
>>>> > <arm_caller+0x28><br>
>>>> > -// 0x1310 + 8 + 0x20 = 0x1338<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1310: 08 00 00 ea b #32<br>
>>>> > <arm_caller+0x38><br>
>>>> > -// 0x1314 + 8 + 0x2c = 0x1348<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1314: 0b 00 00 ea b #44<br>
>>>> > <arm_caller+0x48><br>
>>>> > -// CHECK-PI-ARM-NEXT: 1318: 78 ff ff ea b #-544<br>
>>>> > <arm_callee1><br>
>>>> > -// CHECK-PI-ARM-NEXT: 131c: b7 00 00 0a beq #732<br>
>>>> > <arm_callee2><br>
>>>> > -// CHECK-PI-ARM-NEXT: 1320: b7 00 00 1a bne #732<br>
>>>> > <arm_callee3><br>
>>>> > -// CHECK-PI-ARM-NEXT: 1324: 1e ff 2f e1 bx lr<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776<br>
>>>> > <thumb_callee1><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780<br>
>>>> > <thumb_callee1><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1308: 06 00 00 ea b #24<br>
>>>> > <__ARMToThumbV7PILongThunk_thu<wbr>mb_callee1><br>
>>>> > +// CHECK-PI-ARM-NEXT: 130c: 05 00 00 ea b #20<br>
>>>> > <__ARMToThumbV7PILongThunk_thu<wbr>mb_callee1><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1310: 08 00 00 ea b #32<br>
>>>> > <__ARMToThumbV7PILongThunk_thu<wbr>mb_callee2><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1314: 0b 00 00 ea b #44<br>
>>>> > <__ARMToThumbV7PILongThunk_thu<wbr>mb_callee3><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1318: 78 ff ff ea b #-544<br>
>>>> > <arm_callee1><br>
>>>> > +// CHECK-PI-ARM-NEXT: 131c: b7 00 00 0a beq #732<br>
>>>> > <arm_callee2><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1320: b7 00 00 1a bne #732<br>
>>>> > <arm_callee3><br>
>>>> > +// CHECK-PI-ARM-NEXT: 1324: 1e ff 2f e1 bx lr<br>
>>>> > +// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thum<wbr>b_callee1:<br>
>>>> > // 0x1330 + 8 - 0x337 = 0x1001 = thumb_callee1<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1328: c9 cc 0f e3 movw r12, #64713<br>
>>>> > -// CHECK-PI-ARM-NEXT: 132c: ff cf 4f e3 movt r12, #65535<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1330: 0f c0 8c e0 add r12, r12, pc<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1334: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1328: c9 cc 0f e3 movw r12,<br>
>>>> > #64713<br>
>>>> > +// CHECK-PI-ARM-NEXT: 132c: ff cf 4f e3 movt r12,<br>
>>>> > #65535<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1330: 0f c0 8c e0 add r12, r12,<br>
>>>> > pc<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1334: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thum<wbr>b_callee2:<br>
>>>> > +<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1338: b9 c1 00 e3 movw r12, #441<br>
>>>> > +// CHECK-PI-ARM-NEXT: 133c: 00 c0 40 e3 movt r12, #0<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1340: 0f c0 8c e0 add r12, r12,<br>
>>>> > pc<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1344: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-PI-ARM: __ARMToThumbV7PILongThunk_thum<wbr>b_callee3:<br>
>>>> > // 0x1340 + 8 + 0x1b9 = 0x1501<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1338: b9 c1 00 e3 movw r12, #441<br>
>>>> > -// CHECK-PI-ARM-NEXT: 133c: 00 c0 40 e3 movt r12, #0<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1340: 0f c0 8c e0 add r12, r12, pc<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1344: 1c ff 2f e1 bx r12<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1348: ab c1 00 e3 movw r12, #427<br>
>>>> > +// CHECK-PI-ARM-NEXT: 134c: 00 c0 40 e3 movt r12, #0<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1350: 0f c0 8c e0 add r12, r12,<br>
>>>> > pc<br>
>>>> > +// CHECK-PI-ARM-NEXT: 1354: 1c ff 2f e1 bx r12<br>
>>>> > // 1350 + 8 + 0x1ab = 0x1503<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1348: ab c1 00 e3 movw r12, #427<br>
>>>> > -// CHECK-PI-ARM-NEXT: 134c: 00 c0 40 e3 movt r12, #0<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1350: 0f c0 8c e0 add r12, r12, pc<br>
>>>> > -// CHECK-PI-ARM-NEXT: 1354: 1c ff 2f e1 bx r12<br>
>>>> ><br>
>>>> > // All PLT entries are ARM, no need for interworking thunks<br>
>>>> > // CHECK-PI-ARM-PLT: Disassembly of section .arm_caller:<br>
>>>> > @@ -182,60 +185,58 @@ thumb_caller:<br>
>>>> > bne.w arm_callee3<br>
>>>> > // CHECK-ABS-THUMB: Disassembly of section .thumb_caller:<br>
>>>> > // CHECK-ABS-THUMB-NEXT: thumb_caller:<br>
>>>> > -// 0x1400 + 4 - 0x304 = 0x1100 = arm_callee1<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772<br>
>>>> > -// 0x1404 + 4 - 0x308 = 0x1100 = arm_callee1<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776<br>
>>>> > -// 0x1408 + 4 + 0x14 = 0x520<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20<br>
>>>> > -// 0x140c + 4 + 0x1a = 0x52a<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 140c: 00 f0 0d b8 b.w #26<br>
>>>> > -// 0x1410 + 4 + 0x20 = 0x534<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1410: 00 f0 10 b8 b.w #32<br>
>>>> > -// 0x1414 + 4 + 8 = 0x520<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8<br>
>>>> > -// 0x1418 + 4 + 0xe = 0x52a<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1418: 00 f0 07 80 beq.w #14<br>
>>>> > -// 0x141c + 4 + 0x14 = 0x534<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 141c: 40 f0 0a 80 bne.w #20<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee1+0x4><br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 140c: 00 f0 0d b8 b.w #26<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee2+0x4><br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1410: 00 f0 10 b8 b.w #32<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee3+0x4><br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee1+0x4><br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1418: 00 f0 07 80 beq.w #14<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee2+0x4><br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 141c: 40 f0 0a 80 bne.w #20<br>
>>>> > <__ThumbToARMv7ABSLongThunk_ar<wbr>m_callee3+0x4><br>
>>>> > +// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm<wbr>_callee1:<br>
>>>> > // 0x1100 = arm_callee1<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1420: 41 f2 00 1c movw r12, #4352<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1424: c0 f2 00 0c movt r12, #0<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1428: 60 47 bx r12<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1420: 41 f2 00 1c movw r12,<br>
>>>> > #4352<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1424: c0 f2 00 0c movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1428: 60 47 bx r12<br>
>>>> > +// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm<wbr>_callee2:<br>
>>>> > // 0x1600 = arm_callee2<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 142a: 41 f2 00 6c movw r12, #5632<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 142e: c0 f2 00 0c movt r12, #0<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1432: 60 47 bx r12<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 142a: 41 f2 00 6c movw r12,<br>
>>>> > #5632<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 142e: c0 f2 00 0c movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1432: 60 47 bx r12<br>
>>>> > // 0x1604 = arm_callee3<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1434: 41 f2 04 6c movw r12, #5636<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 1438: c0 f2 00 0c movt r12, #0<br>
>>>> > -// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12<br>
>>>> > +// CHECK-ABS-THUMB: __ThumbToARMv7ABSLongThunk_arm<wbr>_callee3:<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1434: 41 f2 04 6c movw r12, #5636<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 1438: c0 f2 00 0c movt r12,<br>
>>>> > #0<br>
>>>> > +// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12<br>
>>>> ><br>
>>>> > // CHECK-PI-THUMB: Disassembly of section .thumb_caller:<br>
>>>> > // CHECK-PI-THUMB-NEXT: thumb_caller:<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 140c: 00 f0 0e b8 b.w #28<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1410: 00 f0 12 b8 b.w #36<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1418: 00 f0 08 80 beq.w #16<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 141c: 40 f0 0c 80 bne.w #24<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee1+0x4><br>
>>>> > +// CHECK-PI-THUMB-NEXT: 140c: 00 f0 0e b8 b.w #28<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee2+0x4><br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1410: 00 f0 12 b8 b.w #36<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee3+0x4><br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee1+0x4><br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1418: 00 f0 08 80 beq.w #16<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee2+0x4><br>
>>>> > +// CHECK-PI-THUMB-NEXT: 141c: 40 f0 0c 80 bne.w #24<br>
>>>> > <__ThumbToARMV7PILongThunk_arm<wbr>_callee3+0x4><br>
>>>> > +// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_<wbr>callee1:<br>
>>>> > // 0x1428 + 4 - 0x32c = 0x1100 = arm_callee1<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1420: 4f f6 d4 4c movw r12, #64724<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1424: cf f6 ff 7c movt r12, #65535<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1428: fc 44 add r12, pc<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 142a: 60 47 bx r12<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1420: 4f f6 d4 4c movw r12,<br>
>>>> > #64724<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1424: cf f6 ff 7c movt r12,<br>
>>>> > #65535<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1428: fc 44 add r12, pc<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 142a: 60 47 bx r12<br>
>>>> > +// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_<wbr>callee2:<br>
>>>> > // 0x1434 + 4 + 0x1c8 = 0x1600 = arm_callee2<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 142c: 40 f2 c8 1c movw r12, #456<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1430: c0 f2 00 0c movt r12, #0<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1434: fc 44 add r12, pc<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1436: 60 47 bx r12<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 142c: 40 f2 c8 1c movw r12,<br>
>>>> > #456<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1430: c0 f2 00 0c movt r12, #0<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1434: fc 44 add r12, pc<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1436: 60 47 bx r12<br>
>>>> > +// CHECK-PI-THUMB: __ThumbToARMV7PILongThunk_arm_<wbr>callee3:<br>
>>>> > // 0x1440 + 4 + 0x1c0 = 0x1604 = arm_callee3<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1438: 40 f2 c0 1c movw r12, #448<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 143c: c0 f2 00 0c movt r12, #0<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1440: fc 44 add r12, pc<br>
>>>> > -// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1438: 40 f2 c0 1c movw r12,<br>
>>>> > #448<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 143c: c0 f2 00 0c movt r12, #0<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1440: fc 44 add r12, pc<br>
>>>> > +// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12<br>
>>>> ><br>
>>>> > // CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller:<br>
>>>> > // CHECK-PI-THUMB-PLT-NEXT: thumb_caller:<br>
>>>> ><br>
>>>> > Modified: lld/trunk/test/ELF/mips-npic-c<wbr>all-pic.s<br>
>>>> > URL:<br>
>>>> > <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-npic-call-pic.s?rev=293283&r1=293282&r2=293283&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/test/ELF/mips-<wbr>npic-call-pic.s?rev=293283&r1=<wbr>293282&r2=293283&view=diff</a><br>
>>>> ><br>
>>>> > ==============================<wbr>==============================<wbr>==================<br>
>>>> > --- lld/trunk/test/ELF/mips-npic-c<wbr>all-pic.s (original)<br>
>>>> > +++ lld/trunk/test/ELF/mips-npic-c<wbr>all-pic.s Fri Jan 27 07:10:16 2017<br>
>>>> > @@ -15,60 +15,65 @@<br>
>>>> ><br>
>>>> > # CHECK: Disassembly of section .text:<br>
>>>> > # CHECK-NEXT: __start:<br>
>>>> > -# CHECK-NEXT: 20000: 0c 00 80 0e jal 131128<br>
>>>> > <foo1b+0x4><br>
>>>> > -# ^--<br>
>>>> > .pic.foo1a<br>
>>>> > +# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120<br>
>>>> > <__LA25Thunk_foo1a><br>
>>>> > # CHECK-NEXT: 20004: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20008: 0c 00 80 19 jal 131172 <foo2+0x4><br>
>>>> > -# ^--<br>
>>>> > .pic.foo2<br>
>>>> > +# CHECK-NEXT: 20008: 0c 00 80 16 jal 131160<br>
>>>> > <__LA25Thunk_foo2><br>
>>>> > # CHECK-NEXT: 2000c: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20010: 0c 00 80 12 jal 131144<br>
>>>> > <foo1b+0x14><br>
>>>> > -# ^--<br>
>>>> > .pic.foo1b<br>
>>>> > +# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136<br>
>>>> > <__LA25Thunk_foo1b><br>
>>>> > # CHECK-NEXT: 20014: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20018: 0c 00 80 19 jal 131172 <foo2+0x4><br>
>>>> > -# ^--<br>
>>>> > .pic.foo2<br>
>>>> > +# CHECK-NEXT: 20018: 0c 00 80 16 jal 131160<br>
>>>> > <__LA25Thunk_foo2><br>
>>>> > # CHECK-NEXT: 2001c: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20020: 0c 00 80 25 jal 131220<br>
>>>> > <fnpic+0x4><br>
>>>> > -# ^--<br>
>>>> > .pic.fpic<br>
>>>> > +# CHECK-NEXT: 20020: 0c 00 80 1d jal 131188<br>
>>>> > <__LA25Thunk_fpic><br>
>>>> > # CHECK-NEXT: 20024: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20028: 0c 00 80 24 jal 131216 <fnpic><br>
>>>> > +# CHECK-NEXT: 20028: 0c 00 80 28 jal 131232 <fnpic><br>
>>>> > # CHECK-NEXT: 2002c: 00 00 00 00 nop<br>
>>>> > #<br>
>>>> > -# CHECK: foo1a:<br>
>>>> > -# CHECK-NEXT: 20030: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK: foo1b:<br>
>>>> > -# CHECK-NEXT: 20034: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK-NEXT: 20038: 3c 19 00 02 lui $25, 2<br>
>>>> > -# CHECK-NEXT: 2003c: 08 00 80 0c j 131120 <foo1a><br>
>>>> > -# CHECK-NEXT: 20040: 27 39 00 30 addiu $25, $25, 48<br>
>>>> > -# CHECK-NEXT: 20044: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20048: 3c 19 00 02 lui $25, 2<br>
>>>> > -# CHECK-NEXT: 2004c: 08 00 80 0d j 131124 <foo1b><br>
>>>> > -# CHECK-NEXT: 20050: 27 39 00 34 addiu $25, $25, 52<br>
>>>> > +# CHECK: __LA25Thunk_foo1a:<br>
>>>> > +# CHECK-NEXT: 20030: 3c 19 00 02 lui $25, 2<br>
>>>> > +# CHECK-NEXT: 20034: 08 00 80 14 j 131152 <foo1a><br>
>>>> > +# CHECK-NEXT: 20038: 27 39 00 50 addiu $25, $25, 80<br>
>>>> > +# CHECK-NEXT: 2003c: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: __LA25Thunk_foo1b:<br>
>>>> > +# CHECK-NEXT: 20040: 3c 19 00 02 lui $25, 2<br>
>>>> > +# CHECK-NEXT: 20044: 08 00 80 15 j 131156 <foo1b><br>
>>>> > +# CHECK-NEXT: 20048: 27 39 00 54 addiu $25, $25, 84<br>
>>>> > +# CHECK-NEXT: 2004c: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: foo1a:<br>
>>>> > +# CHECK-NEXT: 20050: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: foo1b:<br>
>>>> > # CHECK-NEXT: 20054: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20058: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 2005c: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK: foo2:<br>
>>>> > -# CHECK-NEXT: 20060: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK-NEXT: 20064: 3c 19 00 02 lui $25, 2<br>
>>>> > -# CHECK-NEXT: 20068: 08 00 80 18 j 131168 <foo2><br>
>>>> > -# CHECK-NEXT: 2006c: 27 39 00 60 addiu $25, $25, 96<br>
>>>> > +<br>
>>>> > +# CHECK: __LA25Thunk_foo2:<br>
>>>> > +# CHECK-NEXT: 20058: 3c 19 00 02 lui $25, 2<br>
>>>> > +# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2><br>
>>>> > +# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112<br>
>>>> > +# CHECK-NEXT: 20064: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 20068: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 2006c: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: foo2:<br>
>>>> > # CHECK-NEXT: 20070: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20074: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20078: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 2007c: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK: fpic:<br>
>>>> > -# CHECK-NEXT: 20080: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# CHECK: fnpic:<br>
>>>> > +<br>
>>>> > +# CHECK: __LA25Thunk_fpic:<br>
>>>> > +# CHECK-NEXT: 20074: 3c 19 00 02 lui $25, 2<br>
>>>> > +# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic><br>
>>>> > +# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144<br>
>>>> > +# CHECK-NEXT: 20080: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 20084: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 20088: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 2008c: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: fpic:<br>
>>>> > # CHECK-NEXT: 20090: 00 00 00 00 nop<br>
>>>> > -# CHECK-NEXT: 20094: 3c 19 00 02 lui $25, 2<br>
>>>> > -# CHECK-NEXT: 20098: 08 00 80 20 j 131200 <fpic><br>
>>>> > -# CHECK-NEXT: 2009c: 27 39 00 80 addiu $25, $25, 128<br>
>>>> > +# CHECK-NEXT: 20094: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 20098: 00 00 00 00 nop<br>
>>>> > +# CHECK-NEXT: 2009c: 00 00 00 00 nop<br>
>>>> > +<br>
>>>> > +# CHECK: fnpic:<br>
>>>> > +# CHECK-NEXT: 200a0: 00 00 00 00 nop<br>
>>>> ><br>
>>>> > # Make sure the thunks are created properly no matter how<br>
>>>> > # objects are laid out.<br>
>>>> > @@ -76,54 +81,58 @@<br>
>>>> > # RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe<br>
>>>> > # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s<br>
>>>> ><br>
>>>> > -# REVERSE: foo1a:<br>
>>>> > -# REVERSE-NEXT: 20000: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# REVERSE: foo1b:<br>
>>>> > -# REVERSE-NEXT: 20004: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20008: 3c 19 00 02 lui $25, 2<br>
>>>> > -# REVERSE-NEXT: 2000c: 08 00 80 00 j 131072 <foo1a><br>
>>>> > -# REVERSE-NEXT: 20010: 27 39 00 00 addiu $25, $25, 0<br>
>>>> > -# REVERSE-NEXT: 20014: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20018: 3c 19 00 02 lui $25, 2<br>
>>>> > -# REVERSE-NEXT: 2001c: 08 00 80 01 j 131076 <foo1b><br>
>>>> > -# REVERSE-NEXT: 20020: 27 39 00 04 addiu $25, $25, 4<br>
>>>> > +# REVERSE: Disassembly of section .text:<br>
>>>> > +# REVERSE-NEXT: __LA25Thunk_foo1a:<br>
>>>> > +# REVERSE-NEXT: 20000: 3c 19 00 02 lui $25, 2<br>
>>>> > +# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a><br>
>>>> > +# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32<br>
>>>> > +# REVERSE-NEXT: 2000c: 00 00 00 00 nop<br>
>>>> > +# REVERSE: __LA25Thunk_foo1b:<br>
>>>> > +# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2<br>
>>>> > +# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b><br>
>>>> > +# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36<br>
>>>> > +# REVERSE-NEXT: 2001c: 00 00 00 00 nop<br>
>>>> > +# REVERSE: foo1a:<br>
>>>> > +# REVERSE-NEXT: 20020: 00 00 00 00 nop<br>
>>>> > +# REVERSE: foo1b:<br>
>>>> > # REVERSE-NEXT: 20024: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20028: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 2002c: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# REVERSE: foo2:<br>
>>>> > -# REVERSE-NEXT: 20030: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20034: 3c 19 00 02 lui $25, 2<br>
>>>> > -# REVERSE-NEXT: 20038: 08 00 80 0c j 131120 <foo2><br>
>>>> > -# REVERSE-NEXT: 2003c: 27 39 00 30 addiu $25, $25, 48<br>
>>>> > +# REVERSE: __LA25Thunk_foo2:<br>
>>>> > +# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2<br>
>>>> > +# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2><br>
>>>> > +# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64<br>
>>>> > +# REVERSE-NEXT: 20034: 00 00 00 00 nop<br>
>>>> > +# REVERSE-NEXT: 20038: 00 00 00 00 nop<br>
>>>> > +# REVERSE-NEXT: 2003c: 00 00 00 00 nop<br>
>>>> > +# REVERSE: foo2:<br>
>>>> > # REVERSE-NEXT: 20040: 00 00 00 00 nop<br>
>>>> > # REVERSE-NEXT: 20044: 00 00 00 00 nop<br>
>>>> > # REVERSE-NEXT: 20048: 00 00 00 00 nop<br>
>>>> > # REVERSE-NEXT: 2004c: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# REVERSE: __start:<br>
>>>> > -# REVERSE-NEXT: 20050: 0c 00 80 02 jal 131080<br>
>>>> > <foo1b+0x4><br>
>>>> > +# REVERSE: __start:<br>
>>>> > +# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072<br>
>>>> > <__LA25Thunk_foo1a><br>
>>>> > # REVERSE-NEXT: 20054: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20058: 0c 00 80 0d jal 131124<br>
>>>> > <foo2+0x4><br>
>>>> > +# REVERSE-NEXT: 20058: 0c 00 80 0a jal 131112<br>
>>>> > <__LA25Thunk_foo2><br>
>>>> > # REVERSE-NEXT: 2005c: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20060: 0c 00 80 06 jal 131096<br>
>>>> > <foo1b+0x14><br>
>>>> > +# REVERSE-NEXT: 20060: 0c 00 80 04 jal 131088<br>
>>>> > <__LA25Thunk_foo1b><br>
>>>> > # REVERSE-NEXT: 20064: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20068: 0c 00 80 0d jal 131124<br>
>>>> > <foo2+0x4><br>
>>>> > +# REVERSE-NEXT: 20068: 0c 00 80 0a jal 131112<br>
>>>> > <__LA25Thunk_foo2><br>
>>>> > # REVERSE-NEXT: 2006c: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20070: 0c 00 80 25 jal 131220<br>
>>>> > <fnpic+0x4><br>
>>>> > +# REVERSE-NEXT: 20070: 0c 00 80 20 jal 131200<br>
>>>> > <__LA25Thunk_fpic><br>
>>>> > # REVERSE-NEXT: 20074: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20078: 0c 00 80 24 jal 131216 <fnpic><br>
>>>> > +# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232 <fnpic><br>
>>>> > # REVERSE-NEXT: 2007c: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# REVERSE: fpic:<br>
>>>> > -# REVERSE-NEXT: 20080: 00 00 00 00 nop<br>
>>>> > -#<br>
>>>> > -# REVERSE: fnpic:<br>
>>>> > +# REVERSE: __LA25Thunk_fpic:<br>
>>>> > +# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2<br>
>>>> > +# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic><br>
>>>> > +# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144<br>
>>>> > +# REVERSE-NEXT: 2008c: 00 00 00 00 nop<br>
>>>> > +# REVERSE: fpic:<br>
>>>> > # REVERSE-NEXT: 20090: 00 00 00 00 nop<br>
>>>> > -# REVERSE-NEXT: 20094: 3c 19 00 02 lui $25, 2<br>
>>>> > -# REVERSE-NEXT: 20098: 08 00 80 20 j 131200 <fpic><br>
>>>> > -# REVERSE-NEXT: 2009c: 27 39 00 80 addiu $25, $25, 128<br>
>>>> > +# REVERSE-NEXT: 20094: 00 00 00 00 nop<br>
>>>> > +# REVERSE-NEXT: 20098: 00 00 00 00 nop<br>
>>>> > +# REVERSE-NEXT: 2009c: 00 00 00 00 nop<br>
>>>> > +# REVERSE: fnpic:<br>
>>>> > +# REVERSE-NEXT: 200a0: 00 00 00 00 nop<br>
>>>> ><br>
>>>> > .text<br>
>>>> > .globl __start<br>
>>>> ><br>
>>>> ><br>
>>>> > ______________________________<wbr>_________________<br>
>>>> > llvm-commits mailing list<br>
>>>> > <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
>>>> > <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
>>>> ______________________________<wbr>_________________<br>
>>>> llvm-commits mailing list<br>
>>>> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
>>><br>
>>><br>
</div></div></blockquote></div><br></div></div>