Skip to content
Relocations.cpp 41.3 KiB
Newer Older
// finalized. If any Thunks are added to an OutputSection the output section
// offsets of the InputSections will change.
//
// FIXME: All Thunks are assumed to be in range of the relocation. Range
// extension Thunks are not yet supported.
template <class ELFT>
bool ThunkCreator<ELFT>::createThunks(
    ArrayRef<OutputSection *> OutputSections) {
  // Create all the Thunks and insert them into synthetic ThunkSections. The
  // ThunkSections are later inserted back into the OutputSection.

  // We separate the creation of ThunkSections from the insertion of the
  // ThunkSections back into the OutputSection as ThunkSections are not always
  // inserted into the same OutputSection as the caller.
  for (OutputSection *OS : OutputSections) {
    ThunkSection *OSTS = nullptr;
    for (InputSection *IS : OS->Sections) {
      for (Relocation &Rel : IS->Relocations) {
        SymbolBody &Body = *Rel.Sym;
        if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
          continue;
        Thunk *T;
        bool IsNew;
        std::tie(T, IsNew) = getThunk(Body, Rel.Type);
        if (IsNew) {
          // Find or create a ThunkSection for the new Thunk
          ThunkSection *TS;
          if (auto *TIS = T->getTargetInputSection())
            TS = getISThunkSec(TIS, OS);
          else
            TS = getOSThunkSec(OSTS, OS);
          TS->addThunk(T);
        // Redirect relocation to Thunk, we never go via the PLT to a Thunk
        Rel.Sym = T->ThunkSym;
        Rel.Expr = fromPlt(Rel.Expr);

  // Merge all created synthetic ThunkSections back into OutputSection
  for (auto &KV : ThunkSections)
    mergeThunks(KV.first, KV.second);
  return !ThunkSections.empty();
template void elf::scanRelocations<ELF32LE>(InputSectionBase &);
template void elf::scanRelocations<ELF32BE>(InputSectionBase &);
template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
template class elf::ThunkCreator<ELF32LE>;
template class elf::ThunkCreator<ELF32BE>;
template class elf::ThunkCreator<ELF64LE>;
template class elf::ThunkCreator<ELF64BE>;