Skip to content
Relocations.cpp 41.1 KiB
Newer Older
  // 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 *Base : OutputSections) {
    auto *OS = dyn_cast<OutputSection>(Base);
    if (OS == nullptr)
      continue;
    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)) {
          bool IsNew;
          std::tie(T, IsNew) = GetThunk(Body, Rel.Type);
          if (IsNew) {
            // Find or create a ThunkSection for the new Thunk
            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 scanRelocations<ELF32LE>(InputSectionBase &);
template void scanRelocations<ELF32BE>(InputSectionBase &);
template void scanRelocations<ELF64LE>(InputSectionBase &);
template void scanRelocations<ELF64BE>(InputSectionBase &);
template bool createThunks<ELF32LE>(ArrayRef<OutputSection *>);
template bool createThunks<ELF32BE>(ArrayRef<OutputSection *>);
template bool createThunks<ELF64LE>(ArrayRef<OutputSection *>);
template bool createThunks<ELF64BE>(ArrayRef<OutputSection *>);