diff options
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r-- | lld/ELF/Writer.cpp | 571 |
1 files changed, 4 insertions, 567 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index f2f66a0349f..5789484c8c5 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -11,13 +11,12 @@ #include "Config.h" #include "LinkerScript.h" #include "OutputSections.h" +#include "Relocations.h" #include "SymbolTable.h" #include "Target.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" @@ -25,7 +24,6 @@ using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; -using namespace llvm::support::endian; using namespace lld; using namespace lld::elf; @@ -270,523 +268,6 @@ template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> { }; } -// Returns the number of relocations processed. -template <class ELFT> -static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body, - InputSectionBase<ELFT> &C, - typename ELFT::uint Offset, - typename ELFT::uint Addend, RelExpr Expr) { - if (!(C.getSectionHdr()->sh_flags & SHF_ALLOC)) - return 0; - - if (!Body.isTls()) - return 0; - - typedef typename ELFT::uint uintX_t; - if (Expr == R_TLSLD_PC || Expr == R_TLSLD) { - // 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}); - 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}); - 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}); - return 1; - } - - if (Target->isTlsGlobalDynamicRel(Type)) { - if (Config->Shared) { - if (Out<ELFT>::Got->addDynTlsEntry(Body)) { - uintX_t Off = Out<ELFT>::Got->getGlobalDynOffset(Body); - Out<ELFT>::RelaDyn->addReloc( - {Target->TlsModuleIndexRel, Out<ELFT>::Got, Off, false, &Body, 0}); - Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Out<ELFT>::Got, - Off + (uintX_t)sizeof(uintX_t), false, - &Body, 0}); - } - C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); - return 1; - } - - // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec - // depending on the symbol being locally defined or not. - if (Body.isPreemptible()) { - C.Relocations.push_back( - {R_RELAX_TLS_GD_TO_IE, Type, Offset, Addend, &Body}); - if (!Body.isInGot()) { - Out<ELFT>::Got->addEntry(Body); - Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, Out<ELFT>::Got, - Body.getGotOffset<ELFT>(), false, &Body, - 0}); - } - return 2; - } - C.Relocations.push_back( - {R_RELAX_TLS_GD_TO_LE, Type, Offset, Addend, &Body}); - return Target->TlsGdToLeSkip; - } - - // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally - // defined. - if (Target->isTlsInitialExecRel(Type) && !Config->Shared && - !Body.isPreemptible()) { - C.Relocations.push_back( - {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body}); - return 1; - } - return 0; -} - -// Some targets might require creation of thunks for relocations. Now we -// support only MIPS which requires LA25 thunk to call PIC code from non-PIC -// one. Scan relocations to find each one requires thunk. -template <class ELFT, class RelTy> -static void scanRelocsForThunks(const elf::ObjectFile<ELFT> &File, - ArrayRef<RelTy> Rels) { - for (const RelTy &RI : Rels) { - uint32_t Type = RI.getType(Config->Mips64EL); - SymbolBody &Body = File.getRelocTargetSym(RI); - if (Body.hasThunk() || !Target->needsThunk(Type, File, Body)) - continue; - auto *D = cast<DefinedRegular<ELFT>>(&Body); - auto *S = cast<InputSection<ELFT>>(D->Section); - S->addThunk(Body); - } -} - -template <endianness E> static int16_t readSignedLo16(const uint8_t *Loc) { - return read32<E>(Loc) & 0xffff; -} - -template <class RelTy> -static uint32_t getMipsPairType(const RelTy *Rel, const SymbolBody &Sym) { - switch (Rel->getType(Config->Mips64EL)) { - case R_MIPS_HI16: - return R_MIPS_LO16; - case R_MIPS_GOT16: - return Sym.isLocal() ? R_MIPS_LO16 : R_MIPS_NONE; - case R_MIPS_PCHI16: - return R_MIPS_PCLO16; - case R_MICROMIPS_HI16: - return R_MICROMIPS_LO16; - default: - return R_MIPS_NONE; - } -} - -template <class ELFT, class RelTy> -static int32_t findMipsPairedAddend(const uint8_t *Buf, const uint8_t *BufLoc, - SymbolBody &Sym, const RelTy *Rel, - const RelTy *End) { - uint32_t SymIndex = Rel->getSymbol(Config->Mips64EL); - uint32_t Type = getMipsPairType(Rel, Sym); - - // Some MIPS relocations use addend calculated from addend of the relocation - // itself and addend of paired relocation. ABI requires to compute such - // combined addend in case of REL relocation record format only. - // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - if (RelTy::IsRela || Type == R_MIPS_NONE) - return 0; - - for (const RelTy *RI = Rel; RI != End; ++RI) { - if (RI->getType(Config->Mips64EL) != Type) - continue; - if (RI->getSymbol(Config->Mips64EL) != SymIndex) - continue; - const endianness E = ELFT::TargetEndianness; - return ((read32<E>(BufLoc) & 0xffff) << 16) + - readSignedLo16<E>(Buf + RI->r_offset); - } - unsigned OldType = Rel->getType(Config->Mips64EL); - StringRef OldName = getELFRelocationTypeName(Config->EMachine, OldType); - StringRef NewName = getELFRelocationTypeName(Config->EMachine, Type); - warning("can't find matching " + NewName + " relocation for " + OldName); - return 0; -} - -// True if non-preemptable symbol always has the same value regardless of where -// the DSO is loaded. -template <class ELFT> static bool isAbsolute(const SymbolBody &Body) { - if (Body.isUndefined()) - return !Body.isLocal() && Body.symbol()->isWeak(); - if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(&Body)) - return DR->Section == nullptr; // Absolute symbol. - return false; -} - -static bool needsPlt(RelExpr Expr) { - return Expr == R_PLT_PC || Expr == R_PPC_PLT_OPD || Expr == R_PLT; -} - -// True if this expression is of the form Sym - X, where X is a position in the -// file (PC, or GOT for example). -static bool isRelExpr(RelExpr Expr) { - return Expr == R_PC || Expr == R_GOTREL || Expr == R_PAGE_PC; -} - -template <class ELFT> -static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, - const SymbolBody &Body) { - // These expressions always compute a constant - if (E == R_SIZE || E == R_GOT_FROM_END || E == R_GOT_OFF || - E == R_MIPS_GOT_LOCAL || E == R_MIPS_GOT_LOCAL_PAGE || - E == R_GOT_PAGE_PC || E == R_GOT_PC || E == R_PLT_PC || E == R_TLSGD_PC || - E == R_TLSGD || E == R_PPC_PLT_OPD) - return true; - - // These never do, except if the entire file is position dependent or if - // only the low bits are used. - if (E == R_GOT || E == R_PLT) - return Target->usesOnlyLowPageBits(Type) || !Config->Pic; - - if (Body.isPreemptible()) - return false; - - if (!Config->Pic) - return true; - - bool AbsVal = isAbsolute<ELFT>(Body) || Body.isTls(); - bool RelE = isRelExpr(E); - if (AbsVal && !RelE) - return true; - if (!AbsVal && RelE) - return true; - - // Relative relocation to an absolute value. This is normally unrepresentable, - // but if the relocation refers to a weak undefined symbol, we allow it to - // resolve to the image base. This is a little strange, but it allows us to - // link function calls to such symbols. Normally such a call will be guarded - // with a comparison, which will load a zero from the GOT. - if (AbsVal && RelE) { - if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) - return true; - StringRef S = getELFRelocationTypeName(Config->EMachine, Type); - error("relocation " + S + " cannot refer to absolute symbol " + - Body.getName()); - return true; - } - - return Target->usesOnlyLowPageBits(Type); -} - -static RelExpr toPlt(RelExpr Expr) { - if (Expr == R_PPC_OPD) - return R_PPC_PLT_OPD; - if (Expr == R_PC) - return R_PLT_PC; - if (Expr == R_ABS) - return R_PLT; - return Expr; -} - -static RelExpr fromPlt(RelExpr Expr) { - // We decided not to use a plt. Optimize a reference to the plt to a - // reference to the symbol itself. - if (Expr == R_PLT_PC) - return R_PC; - if (Expr == R_PPC_PLT_OPD) - return R_PPC_OPD; - if (Expr == R_PLT) - return R_ABS; - return Expr; -} - -template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS); - -template <class ELFT> -static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, - bool IsWrite, RelExpr Expr, uint32_t Type) { - if (Target->needsThunk(Type, File, Body)) - return R_THUNK; - bool Preemptible = Body.isPreemptible(); - if (Body.isGnuIFunc()) - Expr = toPlt(Expr); - else if (needsPlt(Expr) && !Preemptible) - Expr = fromPlt(Expr); - - if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body)) - return Expr; - - // This relocation would require the dynamic linker to write a value to read - // only memory. We can hack around it if we are producing an executable and - // the refered symbol can be preemepted to refer to the executable. - if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) { - StringRef S = getELFRelocationTypeName(Config->EMachine, Type); - error("relocation " + S + " cannot be used when making a shared " - "object; recompile with -fPIC."); - return Expr; - } - if (Body.getVisibility() != STV_DEFAULT) { - error("Cannot preempt symbol"); - return Expr; - } - if (Body.isObject()) { - // Produce a copy relocation. - auto *B = cast<SharedSymbol<ELFT>>(&Body); - if (!B->needsCopy()) - addCopyRelSymbol(B); - return Expr; - } - if (Body.isFunc()) { - // This handles a non PIC program call to function in a shared library. In - // an ideal world, we could just report an error saying the relocation can - // overflow at runtime. In the real world with glibc, crt1.o has a - // R_X86_64_PC32 pointing to libc.so. - // - // The general idea on how to handle such cases is to create a PLT entry and - // use that as the function value. - // - // For the static linking part, we just return a plt expr and everything - // else will use the the PLT entry as the address. - // - // The remaining problem is making sure pointer equality still works. We - // need the help of the dynamic linker for that. We let it know that we have - // a direct reference to a so symbol by creating an undefined symbol with a - // non zero st_value. Seeing that, the dynamic linker resolves the symbol to - // the value of the symbol we created. This is true even for got entries, so - // pointer equality is maintained. To avoid an infinite loop, the only entry - // that points to the real function is a dedicated got entry used by the - // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, - // R_386_JMP_SLOT, etc). - Body.NeedsCopyOrPltAddr = true; - return toPlt(Expr); - } - error("Symbol is missing type"); - - return Expr; -} - -template <class ELFT, class RelTy> -static typename ELFT::uint computeAddend(const elf::ObjectFile<ELFT> &File, - const uint8_t *SectionData, - const RelTy *End, const RelTy &RI, - RelExpr Expr, SymbolBody &Body) { - typedef typename ELFT::uint uintX_t; - - uint32_t Type = RI.getType(Config->Mips64EL); - uintX_t Addend = getAddend<ELFT>(RI); - const uint8_t *BufLoc = SectionData + RI.r_offset; - if (!RelTy::IsRela) - Addend += Target->getImplicitAddend(BufLoc, Type); - if (Config->EMachine == EM_MIPS) { - Addend += findMipsPairedAddend<ELFT>(SectionData, BufLoc, Body, &RI, End); - if (Type == R_MIPS_LO16 && Expr == R_PC) - // R_MIPS_LO16 expression has R_PC type iif the target is _gp_disp - // symbol. In that case we should use the following formula for - // calculation "AHL + GP - P + 4". Let's add 4 right here. - // For details see p. 4-19 at - // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - Addend += 4; - if (Expr == R_GOT_OFF) - Addend -= MipsGPOffset; - if (Expr == R_GOTREL) { - Addend -= MipsGPOffset; - if (Body.isLocal()) - Addend += File.getMipsGp0(); - } - } - if (Config->Pic && Config->EMachine == EM_PPC64 && Type == R_PPC64_TOC) - Addend += getPPC64TocBase(); - return Addend; -} - -// The reason we have to do this early scan is as follows -// * To mmap the output file, we need to know the size -// * For that, we need to know how many dynamic relocs we will have. -// It might be possible to avoid this by outputting the file with write: -// * Write the allocated output sections, computing addresses. -// * Apply relocations, recording which ones require a dynamic reloc. -// * Write the dynamic relocations. -// * Write the rest of the file. -// This would have some drawbacks. For example, we would only know if .rela.dyn -// is needed after applying relocations. If it is, it will go after rw and rx -// sections. Given that it is ro, we will need an extra PT_LOAD. This -// complicates things for the dynamic linker and means we would have to reserve -// space for the extra PT_LOAD even if we end up not using it. -template <class ELFT, class RelTy> -void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { - typedef typename ELFT::uint uintX_t; - - uintX_t Flags = C.getSectionHdr()->sh_flags; - bool IsWrite = Flags & SHF_WRITE; - - auto AddDyn = [=](const DynamicReloc<ELFT> &Reloc) { - Out<ELFT>::RelaDyn->addReloc(Reloc); - }; - - const elf::ObjectFile<ELFT> &File = *C.getFile(); - ArrayRef<uint8_t> SectionData = C.getSectionData(); - const uint8_t *Buf = SectionData.begin(); - for (auto I = Rels.begin(), E = Rels.end(); I != E; ++I) { - const RelTy &RI = *I; - SymbolBody &Body = File.getRelocTargetSym(RI); - uint32_t Type = RI.getType(Config->Mips64EL); - - RelExpr Expr = Target->getRelExpr(Type, Body); - // Ignore "hint" relocation because it is for optional code optimization. - if (Expr == R_HINT) - continue; - - uintX_t Offset = C.getOffset(RI.r_offset); - if (Offset == (uintX_t)-1) - continue; - - bool Preemptible = Body.isPreemptible(); - Expr = adjustExpr(File, Body, IsWrite, Expr, Type); - if (HasError) - continue; - - // This relocation does not require got entry, but it is relative to got and - // needs it to be created. Here we request for that. - if (Expr == R_GOTONLY_PC || Expr == R_GOTREL || Expr == R_PPC_TOC) - Out<ELFT>::Got->HasGotOffRel = true; - - uintX_t Addend = computeAddend(File, Buf, E, RI, Expr, Body); - - if (unsigned Processed = - handleTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr)) { - I += (Processed - 1); - continue; - } - - if (needsPlt(Expr) || Expr == R_THUNK || refersToGotEntry(Expr) || - !Body.isPreemptible()) { - // If the relocation points to something in the file, we can process it. - bool Constant = isStaticLinkTimeConstant<ELFT>(Expr, Type, Body); - - // If the output being produced is position independent, the final value - // is still not known. In that case we still need some help from the - // dynamic linker. We can however do better than just copying the incoming - // 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}); - - // 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}); - } 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}); - // 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 - // specially sorted dynamic symbol table. This affects even dynamic - // relocations against symbols which do not require GOT entries - // creation explicitly, i.e. do not have any GOT-relocations. So if - // a preemptible symbol has a dynamic relocation we anyway have - // to create a GOT entry for it. - // If a non-preemptible symbol has a dynamic relocation against it, - // dynamic linker takes it st_value, adds offset and writes down - // result of the dynamic relocation. In case of preemptible symbol - // dynamic linker performs symbol resolution, writes the symbol value - // to the GOT entry and reads the GOT entry when it needs to perform - // a dynamic relocation. - // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 - if (Config->EMachine == EM_MIPS && !Body.isInGot()) - Out<ELFT>::Got->addEntry(Body); - continue; - } - - if (Expr == R_THUNK) - continue; - - // At this point we are done with the relocated position. Some relocations - // also require us to create a got or plt entry. - - // If a relocation needs PLT, we create a PLT and a GOT slot for the symbol. - if (needsPlt(Expr)) { - if (Body.isInPlt()) - continue; - Out<ELFT>::Plt->addEntry(Body); - - uint32_t Rel; - if (Body.isGnuIFunc() && !Preemptible) - Rel = Target->IRelativeRel; - else - Rel = Target->PltRel; - - Out<ELFT>::GotPlt->addEntry(Body); - Out<ELFT>::RelaPlt->addReloc({Rel, Out<ELFT>::GotPlt, - Body.getGotPltOffset<ELFT>(), !Preemptible, - &Body, 0}); - continue; - } - - if (refersToGotEntry(Expr)) { - if (Body.isInGot()) - continue; - Out<ELFT>::Got->addEntry(Body); - - if (Config->EMachine == EM_MIPS) - // MIPS ABI has special rules to process GOT entries - // and doesn't require relocation entries for them. - // See "Global Offset Table" in Chapter 5 in the following document - // for detailed description: - // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - continue; - - if (Preemptible || (Config->Pic && !isAbsolute<ELFT>(Body))) { - uint32_t DynType; - if (Body.isTls()) - DynType = Target->TlsGotRel; - else if (Preemptible) - DynType = Target->GotRel; - else - DynType = Target->RelativeRel; - AddDyn({DynType, Out<ELFT>::Got, Body.getGotOffset<ELFT>(), - !Preemptible, &Body, 0}); - } - continue; - } - } - - // Scan relocations for necessary thunks. - if (Config->EMachine == EM_MIPS) - scanRelocsForThunks<ELFT>(File, Rels); -} - -template <class ELFT> -static void scanRelocs(InputSectionBase<ELFT> &S, - const typename ELFT::Shdr &RelSec); - -template <class ELFT> static void scanRelocs(InputSection<ELFT> &C) { - typedef typename ELFT::Shdr Elf_Shdr; - - // Scan all relocations. Each relocation goes through a series - // of tests to determine if it needs special treatment, such as - // creating GOT, PLT, copy relocations, etc. - // Note that relocations for non-alloc sections are directly - // processed by InputSection::relocateNative. - if (C.getSectionHdr()->sh_flags & SHF_ALLOC) - for (const Elf_Shdr *RelSec : C.RelocSections) - scanRelocs(C, *RelSec); -} - -template <class ELFT> -static void scanRelocs(InputSectionBase<ELFT> &S, - const typename ELFT::Shdr &RelSec) { - ELFFile<ELFT> &EObj = S.getFile()->getObj(); - if (RelSec.sh_type == SHT_RELA) - scanRelocs(S, EObj.relas(&RelSec)); - else - scanRelocs(S, EObj.rels(&RelSec)); -} - template <class ELFT> static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) { if (!Config->NoUndefined) { @@ -1019,50 +500,6 @@ void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) { Out<ELFT>::Bss->setSize(Off); } -template <class ELFT> static uint32_t getAlignment(SharedSymbol<ELFT> *SS) { - typedef typename ELFT::uint uintX_t; - - uintX_t SecAlign = SS->File->getSection(SS->Sym)->sh_addralign; - uintX_t SymValue = SS->Sym.st_value; - int TrailingZeros = - std::min(countTrailingZeros(SecAlign), countTrailingZeros(SymValue)); - return 1 << TrailingZeros; -} - -// Reserve space in .bss for copy relocation. -template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) { - typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Sym Elf_Sym; - - // Copy relocation against zero-sized symbol doesn't make sense. - uintX_t SymSize = SS->template getSize<ELFT>(); - if (SymSize == 0) - fatal("cannot create a copy relocation for " + SS->getName()); - - uintX_t Align = getAlignment(SS); - uintX_t Off = alignTo(Out<ELFT>::Bss->getSize(), Align); - Out<ELFT>::Bss->setSize(Off + SymSize); - Out<ELFT>::Bss->updateAlign(Align); - uintX_t Shndx = SS->Sym.st_shndx; - uintX_t Value = SS->Sym.st_value; - // Look through the DSO's dynamic symbol table for aliases and create a - // dynamic symbol for each one. This causes the copy relocation to correctly - // interpose any aliases. - for (const Elf_Sym &S : SS->File->getElfSymbols(true)) { - if (S.st_shndx != Shndx || S.st_value != Value) - continue; - auto *Alias = dyn_cast_or_null<SharedSymbol<ELFT>>( - Symtab<ELFT>::X->find(check(S.getName(SS->File->getStringTable())))); - if (!Alias) - continue; - Alias->OffsetInBss = Off; - Alias->NeedsCopyOrPltAddr = true; - Alias->symbol()->IsUsedInRegularObj = true; - } - Out<ELFT>::RelaDyn->addReloc( - {Target->CopyRel, Out<ELFT>::Bss, SS->OffsetInBss, false, SS, 0}); -} - template <class ELFT> StringRef Writer<ELFT>::getOutputSectionName(InputSectionBase<ELFT> *S) const { StringRef Dest = Script<ELFT>::X->getOutputSection(S); @@ -1355,17 +792,17 @@ template <class ELFT> void Writer<ELFT>::createSections() { for (OutputSectionBase<ELFT> *Sec : OutputSections) { Sec->forEachInputSection([&](InputSectionBase<ELFT> *S) { if (auto *IS = dyn_cast<InputSection<ELFT>>(S)) { - // Set OutSecOff so that scanRelocs can use it. + // Set OutSecOff so that scanRelocations can use it. uintX_t Off = alignTo(Sec->getSize(), S->Align); IS->OutSecOff = Off; - scanRelocs(*IS); + 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) - scanRelocs(*EH, *EH->RelocSection); + scanRelocations(*EH, *EH->RelocSection); } }); } |