[lld] r273532 - Fix a bug that MIPS thunks can overwrite other section contents.

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 29 14:14:54 PDT 2016


Hi,

Thanks for fixing the bug and sorry for being slow on code review the
last few days (and introducing the bug in the first place).

I am afraid that this had a noticeable impact on link time. I think
that the problem is the extra calls to getOffset. In the attached file
"master" is the old revision and "patch" is this one.

If the problem is indeed the extra calls, I think the way to avoid it
is to map each input offset once and the way to do is to rewrite the
relocation walk to look something like

if (Target->needsThunks) {
  walk the relocations creating thunks and, in general, adding to a
worklist relacations that might need a thunk.
  while the worklist has a relocation that needs a thunk:
    create more thunks
}
Walk the relocations as we did before. We now have enough info to map
input offset to output offset and can do it only once.

We are still pretty fast and correctness is more important, so this is
not critical, but something we should look into at some point.

I will upload the updated lld-speed-test.tar.xz and post the link.

Cheers,
Rafael


On 23 June 2016 at 00:33, Rui Ueyama via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: ruiu
> Date: Wed Jun 22 23:33:42 2016
> New Revision: 273532
>
> URL: http://llvm.org/viewvc/llvm-project?rev=273532&view=rev
> Log:
> Fix a bug that MIPS thunks can overwrite other section contents.
>
> Peter Smith found while trying to support thunk creation for ARM that
> LLD sometimes creates broken thunks for MIPS. The cause of the bug is
> that we assign file offsets to input sections too early. We need to
> create all sections and then assign section offsets because appending
> thunks changes file offsets for all following sections.
>
> This patch separates the pass to assign file offsets from thunk
> creation pass. This effectively reverts r265673.
>
> Differential Revision: http://reviews.llvm.org/D21598
>
> Modified:
>     lld/trunk/ELF/InputSection.cpp
>     lld/trunk/ELF/InputSection.h
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/OutputSections.h
>     lld/trunk/ELF/Relocations.cpp
>     lld/trunk/ELF/Relocations.h
>     lld/trunk/ELF/Writer.cpp
>     lld/trunk/test/ELF/mips-npic-call-pic.s
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Wed Jun 22 23:33:42 2016
> @@ -56,7 +56,7 @@ ArrayRef<uint8_t> InputSectionBase<ELFT>
>  }
>
>  template <class ELFT>
> -typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) {
> +typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
>    switch (SectionKind) {
>    case Regular:
>      return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
> @@ -80,7 +80,7 @@ typename ELFT::uint InputSectionBase<ELF
>
>  template <class ELFT>
>  typename ELFT::uint
> -InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) {
> +InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) const {
>    return getOffset(Sym.Value);
>  }
>
> @@ -297,8 +297,8 @@ void InputSectionBase<ELFT>::relocate(ui
>    }
>
>    const unsigned Bits = sizeof(uintX_t) * 8;
> -  for (const Relocation &Rel : Relocations) {
> -    uintX_t Offset = Rel.Offset;
> +  for (const Relocation<ELFT> &Rel : Relocations) {
> +    uintX_t Offset = Rel.InputSec->getOffset(Rel.Offset);
>      uint8_t *BufLoc = Buf + Offset;
>      uint32_t Type = Rel.Type;
>      uintX_t A = Rel.Addend;
> @@ -422,13 +422,13 @@ void EhInputSection<ELFT>::split() {
>  }
>
>  template <class ELFT>
> -typename ELFT::uint EhInputSection<ELFT>::getOffset(uintX_t Offset) {
> +typename ELFT::uint EhInputSection<ELFT>::getOffset(uintX_t Offset) const {
>    // The file crtbeginT.o has relocations pointing to the start of an empty
>    // .eh_frame that is known to be the first in the link. It does that to
>    // identify the start of the output .eh_frame. Handle this special case.
>    if (this->getSectionHdr()->sh_size == 0)
>      return Offset;
> -  SectionPiece *Piece = this->getSectionPiece(Offset);
> +  const SectionPiece *Piece = this->getSectionPiece(Offset);
>    if (Piece->OutputOff == size_t(-1))
>      return -1; // Not in the output
>
> @@ -506,6 +506,13 @@ bool MergeInputSection<ELFT>::classof(co
>  // Do binary search to get a section piece at a given input offset.
>  template <class ELFT>
>  SectionPiece *SplitInputSection<ELFT>::getSectionPiece(uintX_t Offset) {
> +  auto *This = static_cast<const SplitInputSection<ELFT> *>(this);
> +  return const_cast<SectionPiece *>(This->getSectionPiece(Offset));
> +}
> +
> +template <class ELFT>
> +const SectionPiece *
> +SplitInputSection<ELFT>::getSectionPiece(uintX_t Offset) const {
>    ArrayRef<uint8_t> D = this->getSectionData();
>    StringRef Data((const char *)D.data(), D.size());
>    uintX_t Size = Data.size();
> @@ -524,14 +531,14 @@ SectionPiece *SplitInputSection<ELFT>::g
>  // Because contents of a mergeable section is not contiguous in output,
>  // it is not just an addition to a base output offset.
>  template <class ELFT>
> -typename ELFT::uint MergeInputSection<ELFT>::getOffset(uintX_t Offset) {
> +typename ELFT::uint MergeInputSection<ELFT>::getOffset(uintX_t Offset) const {
>    auto It = OffsetMap.find(Offset);
>    if (It != OffsetMap.end())
>      return It->second;
>
>    // If Offset is not at beginning of a section piece, it is not in the map.
>    // In that case we need to search from the original section piece vector.
> -  SectionPiece &Piece = *this->getSectionPiece(Offset);
> +  const SectionPiece &Piece = *this->getSectionPiece(Offset);
>    assert(Piece.Live);
>    uintX_t Addend = Offset - Piece.InputOff;
>    return Piece.OutputOff + Addend;
>
> Modified: lld/trunk/ELF/InputSection.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.h (original)
> +++ lld/trunk/ELF/InputSection.h Wed Jun 22 23:33:42 2016
> @@ -70,16 +70,16 @@ public:
>    StringRef getSectionName() const;
>    const Elf_Shdr *getSectionHdr() const { return Header; }
>    ObjectFile<ELFT> *getFile() const { return File; }
> -  uintX_t getOffset(const DefinedRegular<ELFT> &Sym);
> +  uintX_t getOffset(const DefinedRegular<ELFT> &Sym) const;
>
>    // Translate an offset in the input section to an offset in the output
>    // section.
> -  uintX_t getOffset(uintX_t Offset);
> +  uintX_t getOffset(uintX_t Offset) const;
>
>    ArrayRef<uint8_t> getSectionData() const;
>
>    void relocate(uint8_t *Buf, uint8_t *BufEnd);
> -  std::vector<Relocation> Relocations;
> +  std::vector<Relocation<ELFT>> Relocations;
>  };
>
>  template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
> @@ -125,6 +125,7 @@ public:
>
>    // Returns the SectionPiece at a given input section offset.
>    SectionPiece *getSectionPiece(uintX_t Offset);
> +  const SectionPiece *getSectionPiece(uintX_t Offset) const;
>  };
>
>  // This corresponds to a SHF_MERGE section of an input file.
> @@ -143,7 +144,7 @@ public:
>
>    // Translate an offset in the input section to an offset
>    // in the output section.
> -  uintX_t getOffset(uintX_t Offset);
> +  uintX_t getOffset(uintX_t Offset) const;
>
>    void finalizePieces();
>
> @@ -163,7 +164,7 @@ public:
>
>    // Translate an offset in the input section to an offset in the output
>    // section.
> -  uintX_t getOffset(uintX_t Offset);
> +  uintX_t getOffset(uintX_t Offset) const;
>
>    // Relocation section that refer to this one.
>    const Elf_Shdr *RelocSection = nullptr;
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Wed Jun 22 23:33:42 2016
> @@ -351,13 +351,11 @@ template <class ELFT> void RelocationSec
>    for (const DynamicReloc<ELFT> &Rel : Relocs) {
>      auto *P = reinterpret_cast<Elf_Rela *>(Buf);
>      Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
> -    SymbolBody *Sym = Rel.Sym;
>
>      if (Config->Rela)
> -      P->r_addend = Rel.UseSymVA ? Sym->getVA<ELFT>(Rel.Addend) : Rel.Addend;
> -    P->r_offset = Rel.OffsetInSec + Rel.OffsetSec->getVA();
> -    uint32_t SymIdx = (!Rel.UseSymVA && Sym) ? Sym->DynsymIndex : 0;
> -    P->setSymbolAndType(SymIdx, Rel.Type, Config->Mips64EL);
> +      P->r_addend = Rel.getAddend();
> +    P->r_offset = Rel.getOffset();
> +    P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
>    }
>
>    if (Sort) {
> @@ -836,11 +834,16 @@ static int getPriority(StringRef S) {
>    return V;
>  }
>
> -template <class ELFT>
> -void OutputSection<ELFT>::forEachInputSection(
> -    std::function<void(InputSectionBase<ELFT> *)> F) {
> -  for (InputSection<ELFT> *S : Sections)
> -    F(S);
> +// This function is called after we sort input sections
> +// and scan relocations to setup sections' offsets.
> +template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
> +  uintX_t Off = this->Header.sh_size;
> +  for (InputSection<ELFT> *S : Sections) {
> +    Off = alignTo(Off, S->Alignment);
> +    S->OutSecOff = Off;
> +    Off += S->getSize();
> +  }
> +  this->Header.sh_size = Off;
>  }
>
>  // Sorts input sections by section name suffixes, so that .foo.N comes
> @@ -947,13 +950,6 @@ template <class ELFT>
>  EhOutputSection<ELFT>::EhOutputSection()
>      : OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
>
> -template <class ELFT>
> -void EhOutputSection<ELFT>::forEachInputSection(
> -    std::function<void(InputSectionBase<ELFT> *)> F) {
> -  for (EhInputSection<ELFT> *S : Sections)
> -    F(S);
> -}
> -
>  // Returns the first relocation that points to a region
>  // between Begin and Begin+Size.
>  template <class IntTy, class RelTy>
> @@ -1269,6 +1265,26 @@ template <class ELFT> void StringTableSe
>  }
>
>  template <class ELFT>
> +typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
> +  if (OutputSec)
> +    return OutputSec->getVA() + OffsetInSec;
> +  return InputSec->OutSec->getVA() + InputSec->getOffset(OffsetInSec);
> +}
> +
> +template <class ELFT>
> +typename ELFT::uint DynamicReloc<ELFT>::getAddend() const {
> +  if (UseSymVA)
> +    return Sym->getVA<ELFT>(Addend);
> +  return Addend;
> +}
> +
> +template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
> +  if (Sym && !UseSymVA)
> +    return Sym->DynsymIndex;
> +  return 0;
> +}
> +
> +template <class ELFT>
>  SymbolTableSection<ELFT>::SymbolTableSection(
>      StringTableSection<ELFT> &StrTabSec)
>      : OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Wed Jun 22 23:33:42 2016
> @@ -96,8 +96,7 @@ public:
>
>    virtual void finalize() {}
>    virtual void finalizePieces() {}
> -  virtual void
> -  forEachInputSection(std::function<void(InputSectionBase<ELFT> *)> F) {}
> +  virtual void assignOffsets() {}
>    virtual void writeTo(uint8_t *Buf) {}
>    virtual ~OutputSectionBase() = default;
>
> @@ -197,21 +196,35 @@ private:
>    std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
>  };
>
> -template <class ELFT> struct DynamicReloc {
> +template <class ELFT> class DynamicReloc {
>    typedef typename ELFT::uint uintX_t;
> +
> +public:
> +  DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec,
> +               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
> +               uintX_t Addend)
> +      : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
> +        UseSymVA(UseSymVA), Addend(Addend) {}
> +
> +  DynamicReloc(uint32_t Type, const OutputSectionBase<ELFT> *OutputSec,
> +               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
> +               uintX_t Addend)
> +      : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
> +        UseSymVA(UseSymVA), Addend(Addend) {}
> +
> +  uintX_t getOffset() const;
> +  uintX_t getAddend() const;
> +  uint32_t getSymIndex() const;
> +
>    uint32_t Type;
>
> +private:
>    SymbolBody *Sym;
> -  const OutputSectionBase<ELFT> *OffsetSec;
> +  const InputSectionBase<ELFT> *InputSec = nullptr;
> +  const OutputSectionBase<ELFT> *OutputSec = nullptr;
>    uintX_t OffsetInSec;
>    bool UseSymVA;
>    uintX_t Addend;
> -
> -  DynamicReloc(uint32_t Type, const OutputSectionBase<ELFT> *OffsetSec,
> -               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
> -               uintX_t Addend)
> -      : Type(Type), Sym(Sym), OffsetSec(OffsetSec), OffsetInSec(OffsetInSec),
> -        UseSymVA(UseSymVA), Addend(Addend) {}
>  };
>
>  template <class ELFT>
> @@ -343,8 +356,7 @@ public:
>    void sortCtorsDtors();
>    void writeTo(uint8_t *Buf) override;
>    void finalize() override;
> -  void
> -  forEachInputSection(std::function<void(InputSectionBase<ELFT> *)> F) override;
> +  void assignOffsets() override;
>    std::vector<InputSection<ELFT> *> Sections;
>  };
>
> @@ -385,8 +397,6 @@ public:
>    void writeTo(uint8_t *Buf) override;
>    void finalize() override;
>    bool empty() const { return Sections.empty(); }
> -  void
> -  forEachInputSection(std::function<void(InputSectionBase<ELFT> *)> F) override;
>
>    void addSection(InputSectionBase<ELFT> *S) override;
>
>
> Modified: lld/trunk/ELF/Relocations.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Relocations.cpp (original)
> +++ lld/trunk/ELF/Relocations.cpp Wed Jun 22 23:33:42 2016
> @@ -103,7 +103,7 @@ static unsigned handleTlsRelocation(uint
>            {Target->TlsDescRel, Out<ELFT>::Got, Off, false, &Body, 0});
>      }
>      if (Expr != R_HINT)
> -      C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
> +      C.Relocations.push_back({Expr, Type, &C, Offset, Addend, &Body});
>      return 1;
>    }
>
> @@ -111,21 +111,21 @@ static unsigned handleTlsRelocation(uint
>      // Local-Dynamic relocs can be relaxed to Local-Exec.
>      if (!Config->Shared) {
>        C.Relocations.push_back(
> -          {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body});
> +          {R_RELAX_TLS_LD_TO_LE, Type, &C, Offset, Addend, &Body});
>        return 2;
>      }
>      if (Out<ELFT>::Got->addTlsIndex())
>        Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, Out<ELFT>::Got,
>                                      Out<ELFT>::Got->getTlsIndexOff(), false,
>                                      nullptr, 0});
> -    C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
> +    C.Relocations.push_back({Expr, Type, &C, Offset, Addend, &Body});
>      return 1;
>    }
>
>    // Local-Dynamic relocs can be relaxed to Local-Exec.
>    if (Target->isTlsLocalDynamicRel(Type) && !Config->Shared) {
>      C.Relocations.push_back(
> -        {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body});
> +        {R_RELAX_TLS_LD_TO_LE, Type, &C, Offset, Addend, &Body});
>      return 1;
>    }
>
> @@ -144,7 +144,7 @@ static unsigned handleTlsRelocation(uint
>                                          Off + (uintX_t)sizeof(uintX_t), false,
>                                          &Body, 0});
>        }
> -      C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
> +      C.Relocations.push_back({Expr, Type, &C, Offset, Addend, &Body});
>        return 1;
>      }
>
> @@ -153,7 +153,7 @@ static unsigned handleTlsRelocation(uint
>      if (isPreemptible(Body, Type)) {
>        C.Relocations.push_back(
>            {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
> -           Offset, Addend, &Body});
> +           &C, Offset, Addend, &Body});
>        if (!Body.isInGot()) {
>          Out<ELFT>::Got->addEntry(Body);
>          Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, Out<ELFT>::Got,
> @@ -163,7 +163,7 @@ static unsigned handleTlsRelocation(uint
>        return Target->TlsGdRelaxSkip;
>      }
>      C.Relocations.push_back(
> -        {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
> +        {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type, &C,
>           Offset, Addend, &Body});
>      return Target->TlsGdRelaxSkip;
>    }
> @@ -173,7 +173,7 @@ static unsigned handleTlsRelocation(uint
>    if (Target->isTlsInitialExecRel(Type) && !Config->Shared &&
>        !isPreemptible(Body, Type)) {
>      C.Relocations.push_back(
> -        {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
> +        {R_RELAX_TLS_IE_TO_LE, Type, &C, Offset, Addend, &Body});
>      return 1;
>    }
>    return 0;
> @@ -497,8 +497,9 @@ static void scanRelocs(InputSectionBase<
>      if (HasError)
>        continue;
>
> -    uintX_t Offset = C.getOffset(RI.r_offset);
> -    if (Offset == (uintX_t)-1)
> +    // Skip a relocation that points to a dead piece
> +    // in a mergeable section.
> +    if (C.getOffset(RI.r_offset) == (uintX_t)-1)
>        continue;
>
>      // This relocation does not require got entry, but it is relative to got and
> @@ -508,8 +509,8 @@ static void scanRelocs(InputSectionBase<
>
>      uintX_t Addend = computeAddend(File, Buf, E, RI, Expr, Body);
>
> -    if (unsigned Processed =
> -            handleTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr)) {
> +    if (unsigned Processed = handleTlsRelocation<ELFT>(
> +            Type, Body, C, RI.r_offset, Addend, Expr)) {
>        I += (Processed - 1);
>        continue;
>      }
> @@ -529,17 +530,17 @@ static void scanRelocs(InputSectionBase<
>        // relocation. We can process some of it and and just ask the dynamic
>        // linker to add the load address.
>        if (!Constant)
> -        AddDyn({Target->RelativeRel, C.OutSec, Offset, true, &Body, Addend});
> +        AddDyn({Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
>
>        // If the produced value is a constant, we just remember to write it
>        // when outputting this section. We also have to do it if the format
>        // uses Elf_Rel, since in that case the written value is the addend.
>        if (Constant || !RelTy::IsRela)
> -        C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
> +        C.Relocations.push_back({Expr, Type, &C, RI.r_offset, Addend, &Body});
>      } else {
>        // We don't know anything about the finaly symbol. Just ask the dynamic
>        // linker to handle the relocation for us.
> -      AddDyn({Target->getDynRel(Type), C.OutSec, Offset, false, &Body, Addend});
> +      AddDyn({Target->getDynRel(Type), &C, RI.r_offset, false, &Body, Addend});
>        // MIPS ABI turns using of GOT and dynamic relocations inside out.
>        // While regular ABI uses dynamic relocations to fill up GOT entries
>        // MIPS ABI requires dynamic linker to fills up GOT entries using
>
> Modified: lld/trunk/ELF/Relocations.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Relocations.h (original)
> +++ lld/trunk/ELF/Relocations.h Wed Jun 22 23:33:42 2016
> @@ -60,9 +60,10 @@ enum RelExpr {
>    R_TLSLD_PC
>  };
>
> -struct Relocation {
> +template <class ELFT> struct Relocation {
>    RelExpr Expr;
>    uint32_t Type;
> +  InputSectionBase<ELFT> *InputSec;
>    uint64_t Offset;
>    uint64_t Addend;
>    SymbolBody *Sym;
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Wed Jun 22 23:33:42 2016
> @@ -793,24 +793,24 @@ template <class ELFT> void Writer<ELFT>:
>
>    // Scan relocations. This must be done after every symbol is declared so that
>    // we can correctly decide if a dynamic relocation is needed.
> -  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
> -    Sec->forEachInputSection([&](InputSectionBase<ELFT> *S) {
> -      if (auto *IS = dyn_cast<InputSection<ELFT>>(S)) {
> -        // Set OutSecOff so that scanRelocations can use it.
> -        uintX_t Off = alignTo(Sec->getSize(), S->Alignment);
> -        IS->OutSecOff = Off;
> -
> -        scanRelocations(*IS);
> -
> -        // Now that scan relocs possibly changed the size, update the offset.
> -        Sec->setSize(Off + S->getSize());
> -      } else if (auto *EH = dyn_cast<EhInputSection<ELFT>>(S)) {
> -        if (EH->RelocSection)
> -          scanRelocations(*EH, *EH->RelocSection);
> +  for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
> +       Symtab.getObjectFiles()) {
> +    for (InputSectionBase<ELFT> *C : F->getSections()) {
> +      if (isDiscarded(C))
> +        continue;
> +      if (auto *S = dyn_cast<InputSection<ELFT>>(C)) {
> +        scanRelocations(*S);
> +        continue;
>        }
> -    });
> +      if (auto *S = dyn_cast<EhInputSection<ELFT>>(C))
> +        if (S->RelocSection)
> +          scanRelocations(*S, *S->RelocSection);
> +    }
>    }
>
> +  for (OutputSectionBase<ELFT> *Sec : OutputSections)
> +    Sec->assignOffsets();
> +
>    // Now that we have defined all possible symbols including linker-
>    // synthesized ones. Visit all symbols to give the finishing touches.
>    std::vector<DefinedCommon *> CommonSymbols;
>
> Modified: lld/trunk/test/ELF/mips-npic-call-pic.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-npic-call-pic.s?rev=273532&r1=273531&r2=273532&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/mips-npic-call-pic.s (original)
> +++ lld/trunk/test/ELF/mips-npic-call-pic.s Wed Jun 22 23:33:42 2016
> @@ -1,3 +1,4 @@
> +# REQUIRES: mips
>  # Check LA25 stubs creation. This stub code is necessary when
>  # non-PIC code calls PIC function.
>
> @@ -7,8 +8,6 @@
>  # RUN: ld.lld %t-npic.o %t-pic.o %p/Inputs/mips-sto-pic.o -o %t.exe
>  # RUN: llvm-objdump -d %t.exe | FileCheck %s
>
> -# REQUIRES: mips
> -
>  # CHECK:     Disassembly of section .text:
>  # CHECK-NEXT: __start:
>  # CHECK-NEXT:    20000:       0c 00 80 0e     jal     131128 <foo1b+0x4>
> @@ -72,6 +71,68 @@
>  # CHECK-NEXT:    200a4:       08 00 80 20     j       131200 <fpic>
>  # CHECK-NEXT:    200a8:       27 39 00 80     addiu   $25, $25, 128
>
> +# Make sure tha thunks are created properly no matter how
> +# objects are laid out.
> +#
> +# RUN: ld.lld %t-pic.o %t-npic.o %p/Inputs/mips-sto-pic.o -o %t.exe
> +# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
> +
> +# REVERSE:      foo1a:
> +# REVERSE-NEXT:    20000:       00 00 00 00     nop
> +#
> +# REVERSE:      foo1b:
> +# REVERSE-NEXT:    20004:       00 00 00 00     nop
> +# REVERSE-NEXT:    20008:       3c 19 00 02     lui     $25, 2
> +# REVERSE-NEXT:    2000c:       08 00 80 00     j       131072 <foo1a>
> +# REVERSE-NEXT:    20010:       27 39 00 00     addiu   $25, $25, 0
> +# REVERSE-NEXT:    20014:       00 00 00 00     nop
> +# REVERSE-NEXT:    20018:       3c 19 00 02     lui     $25, 2
> +# REVERSE-NEXT:    2001c:       08 00 80 01     j       131076 <foo1b>
> +# REVERSE-NEXT:    20020:       27 39 00 04     addiu   $25, $25, 4
> +# REVERSE-NEXT:    20024:       00 00 00 00     nop
> +# REVERSE-NEXT:    20028:       00 00 00 00     nop
> +# REVERSE-NEXT:    2002c:       00 00 00 00     nop
> +#
> +# REVERSE:      foo2:
> +# REVERSE-NEXT:    20030:       00 00 00 00     nop
> +# REVERSE-NEXT:    20034:       3c 19 00 02     lui     $25, 2
> +# REVERSE-NEXT:    20038:       08 00 80 0c     j       131120 <foo2>
> +# REVERSE-NEXT:    2003c:       27 39 00 30     addiu   $25, $25, 48
> +# REVERSE-NEXT:    20040:       00 00 00 00     nop
> +# REVERSE-NEXT:    20044:       00 00 00 00     nop
> +# REVERSE-NEXT:    20048:       00 00 00 00     nop
> +# REVERSE-NEXT:    2004c:       00 00 00 00     nop
> +#
> +# REVERSE:      __start:
> +# REVERSE-NEXT:    20050:       0c 00 80 02     jal     131080 <foo1b+0x4>
> +# REVERSE-NEXT:    20054:       00 00 00 00     nop
> +# REVERSE-NEXT:    20058:       0c 00 80 0d     jal     131124 <foo2+0x4>
> +# REVERSE-NEXT:    2005c:       00 00 00 00     nop
> +# REVERSE-NEXT:    20060:       0c 00 80 06     jal     131096 <foo1b+0x14>
> +# REVERSE-NEXT:    20064:       00 00 00 00     nop
> +# REVERSE-NEXT:    20068:       0c 00 80 0d     jal     131124 <foo2+0x4>
> +# REVERSE-NEXT:    2006c:       00 00 00 00     nop
> +# REVERSE-NEXT:    20070:       0c 00 80 28     jal     131232 <fnpic+0x10>
> +# REVERSE-NEXT:    20074:       00 00 00 00     nop
> +# REVERSE-NEXT:    20078:       0c 00 80 24     jal     131216 <fnpic>
> +# REVERSE-NEXT:    2007c:       00 00 00 00     nop
> +#
> +# REVERSE:      fpic:
> +# REVERSE-NEXT:    20080:       00 00 00 00     nop
> +# REVERSE-NEXT:    20084:       00 00 00 00     nop
> +# REVERSE-NEXT:    20088:       00 00 00 00     nop
> +# REVERSE-NEXT:    2008c:       00 00 00 00     nop
> +#
> +# REVERSE:      fnpic:
> +# REVERSE-NEXT:    20090:       00 00 00 00     nop
> +# REVERSE-NEXT:    20094:       00 00 00 00     nop
> +# REVERSE-NEXT:    20098:       00 00 00 00     nop
> +# REVERSE-NEXT:    2009c:       00 00 00 00     nop
> +# REVERSE-NEXT:    200a0:       3c 19 00 02     lui     $25, 2
> +# REVERSE-NEXT:    200a4:       08 00 80 20     j       131200 <fpic>
> +# REVERSE-NEXT:    200a8:       27 39 00 80     addiu   $25, $25, 128
> +# REVERSE-NEXT:    200ac:       00 00 00 00     nop
> +
>    .text
>    .globl __start
>  __start:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: times
Type: application/octet-stream
Size: 673 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160629/c4846da5/attachment.obj>


More information about the llvm-commits mailing list