Path: blob/main/contrib/llvm-project/lld/ELF/Relocations.cpp
34878 views
//===- Relocations.cpp ----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains platform-independent functions to process relocations.9// I'll describe the overview of this file here.10//11// Simple relocations are easy to handle for the linker. For example,12// for R_X86_64_PC64 relocs, the linker just has to fix up locations13// with the relative offsets to the target symbols. It would just be14// reading records from relocation sections and applying them to output.15//16// But not all relocations are that easy to handle. For example, for17// R_386_GOTOFF relocs, the linker has to create new GOT entries for18// symbols if they don't exist, and fix up locations with GOT entry19// offsets from the beginning of GOT section. So there is more than20// fixing addresses in relocation processing.21//22// ELF defines a large number of complex relocations.23//24// The functions in this file analyze relocations and do whatever needs25// to be done. It includes, but not limited to, the following.26//27// - create GOT/PLT entries28// - create new relocations in .dynsym to let the dynamic linker resolve29// them at runtime (since ELF supports dynamic linking, not all30// relocations can be resolved at link-time)31// - create COPY relocs and reserve space in .bss32// - replace expensive relocs (in terms of runtime cost) with cheap ones33// - error out infeasible combinations such as PIC and non-relative relocs34//35// Note that the functions in this file don't actually apply relocations36// because it doesn't know about the output file nor the output file buffer.37// It instead stores Relocation objects to InputSection's Relocations38// vector to let it apply later in InputSection::writeTo.39//40//===----------------------------------------------------------------------===//4142#include "Relocations.h"43#include "Config.h"44#include "InputFiles.h"45#include "LinkerScript.h"46#include "OutputSections.h"47#include "SymbolTable.h"48#include "Symbols.h"49#include "SyntheticSections.h"50#include "Target.h"51#include "Thunks.h"52#include "lld/Common/ErrorHandler.h"53#include "lld/Common/Memory.h"54#include "llvm/ADT/SmallSet.h"55#include "llvm/BinaryFormat/ELF.h"56#include "llvm/Demangle/Demangle.h"57#include "llvm/Support/Endian.h"58#include <algorithm>5960using namespace llvm;61using namespace llvm::ELF;62using namespace llvm::object;63using namespace llvm::support::endian;64using namespace lld;65using namespace lld::elf;6667static std::optional<std::string> getLinkerScriptLocation(const Symbol &sym) {68for (SectionCommand *cmd : script->sectionCommands)69if (auto *assign = dyn_cast<SymbolAssignment>(cmd))70if (assign->sym == &sym)71return assign->location;72return std::nullopt;73}7475static std::string getDefinedLocation(const Symbol &sym) {76const char msg[] = "\n>>> defined in ";77if (sym.file)78return msg + toString(sym.file);79if (std::optional<std::string> loc = getLinkerScriptLocation(sym))80return msg + *loc;81return "";82}8384// Construct a message in the following format.85//86// >>> defined in /home/alice/src/foo.o87// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)88// >>> /home/alice/src/bar.o:(.text+0x1)89static std::string getLocation(InputSectionBase &s, const Symbol &sym,90uint64_t off) {91std::string msg = getDefinedLocation(sym) + "\n>>> referenced by ";92std::string src = s.getSrcMsg(sym, off);93if (!src.empty())94msg += src + "\n>>> ";95return msg + s.getObjMsg(off);96}9798void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,99int64_t min, uint64_t max) {100ErrorPlace errPlace = getErrorPlace(loc);101std::string hint;102if (rel.sym) {103if (!rel.sym->isSection())104hint = "; references '" + lld::toString(*rel.sym) + '\'';105else if (auto *d = dyn_cast<Defined>(rel.sym))106hint = ("; references section '" + d->section->name + "'").str();107108if (config->emachine == EM_X86_64 && rel.type == R_X86_64_PC32 &&109rel.sym->getOutputSection() &&110(rel.sym->getOutputSection()->flags & SHF_X86_64_LARGE)) {111hint += "; R_X86_64_PC32 should not reference a section marked "112"SHF_X86_64_LARGE";113}114}115if (!errPlace.srcLoc.empty())116hint += "\n>>> referenced by " + errPlace.srcLoc;117if (rel.sym && !rel.sym->isSection())118hint += getDefinedLocation(*rel.sym);119120if (errPlace.isec && errPlace.isec->name.starts_with(".debug"))121hint += "; consider recompiling with -fdebug-types-section to reduce size "122"of debug sections";123124errorOrWarn(errPlace.loc + "relocation " + lld::toString(rel.type) +125" out of range: " + v.str() + " is not in [" + Twine(min).str() +126", " + Twine(max).str() + "]" + hint);127}128129void elf::reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym,130const Twine &msg) {131ErrorPlace errPlace = getErrorPlace(loc);132std::string hint;133if (!sym.getName().empty())134hint =135"; references '" + lld::toString(sym) + '\'' + getDefinedLocation(sym);136errorOrWarn(errPlace.loc + msg + " is out of range: " + Twine(v) +137" is not in [" + Twine(llvm::minIntN(n)) + ", " +138Twine(llvm::maxIntN(n)) + "]" + hint);139}140141// Build a bitmask with one bit set for each 64 subset of RelExpr.142static constexpr uint64_t buildMask() { return 0; }143144template <typename... Tails>145static constexpr uint64_t buildMask(int head, Tails... tails) {146return (0 <= head && head < 64 ? uint64_t(1) << head : 0) |147buildMask(tails...);148}149150// Return true if `Expr` is one of `Exprs`.151// There are more than 64 but less than 128 RelExprs, so we divide the set of152// exprs into [0, 64) and [64, 128) and represent each range as a constant153// 64-bit mask. Then we decide which mask to test depending on the value of154// expr and use a simple shift and bitwise-and to test for membership.155template <RelExpr... Exprs> static bool oneof(RelExpr expr) {156assert(0 <= expr && (int)expr < 128 &&157"RelExpr is too large for 128-bit mask!");158159if (expr >= 64)160return (uint64_t(1) << (expr - 64)) & buildMask((Exprs - 64)...);161return (uint64_t(1) << expr) & buildMask(Exprs...);162}163164static RelType getMipsPairType(RelType type, bool isLocal) {165switch (type) {166case R_MIPS_HI16:167return R_MIPS_LO16;168case R_MIPS_GOT16:169// In case of global symbol, the R_MIPS_GOT16 relocation does not170// have a pair. Each global symbol has a unique entry in the GOT171// and a corresponding instruction with help of the R_MIPS_GOT16172// relocation loads an address of the symbol. In case of local173// symbol, the R_MIPS_GOT16 relocation creates a GOT entry to hold174// the high 16 bits of the symbol's value. A paired R_MIPS_LO16175// relocations handle low 16 bits of the address. That allows176// to allocate only one GOT entry for every 64 KBytes of local data.177return isLocal ? R_MIPS_LO16 : R_MIPS_NONE;178case R_MICROMIPS_GOT16:179return isLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;180case R_MIPS_PCHI16:181return R_MIPS_PCLO16;182case R_MICROMIPS_HI16:183return R_MICROMIPS_LO16;184default:185return R_MIPS_NONE;186}187}188189// True if non-preemptable symbol always has the same value regardless of where190// the DSO is loaded.191static bool isAbsolute(const Symbol &sym) {192if (sym.isUndefWeak())193return true;194if (const auto *dr = dyn_cast<Defined>(&sym))195return dr->section == nullptr; // Absolute symbol.196return false;197}198199static bool isAbsoluteValue(const Symbol &sym) {200return isAbsolute(sym) || sym.isTls();201}202203// Returns true if Expr refers a PLT entry.204static bool needsPlt(RelExpr expr) {205return oneof<R_PLT, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT, R_GOTPLT_GOTREL,206R_GOTPLT_PC, R_LOONGARCH_PLT_PAGE_PC, R_PPC32_PLTREL,207R_PPC64_CALL_PLT>(expr);208}209210bool lld::elf::needsGot(RelExpr expr) {211return oneof<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,212R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,213R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(214expr);215}216217// True if this expression is of the form Sym - X, where X is a position in the218// file (PC, or GOT for example).219static bool isRelExpr(RelExpr expr) {220return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_ARM_PCA, R_MIPS_GOTREL,221R_PPC64_CALL, R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC,222R_RELAX_GOT_PC, R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC,223R_LOONGARCH_PAGE_PC>(expr);224}225226static RelExpr toPlt(RelExpr expr) {227switch (expr) {228case R_LOONGARCH_PAGE_PC:229return R_LOONGARCH_PLT_PAGE_PC;230case R_PPC64_CALL:231return R_PPC64_CALL_PLT;232case R_PC:233return R_PLT_PC;234case R_ABS:235return R_PLT;236case R_GOTREL:237return R_PLT_GOTREL;238default:239return expr;240}241}242243static RelExpr fromPlt(RelExpr expr) {244// We decided not to use a plt. Optimize a reference to the plt to a245// reference to the symbol itself.246switch (expr) {247case R_PLT_PC:248case R_PPC32_PLTREL:249return R_PC;250case R_LOONGARCH_PLT_PAGE_PC:251return R_LOONGARCH_PAGE_PC;252case R_PPC64_CALL_PLT:253return R_PPC64_CALL;254case R_PLT:255return R_ABS;256case R_PLT_GOTPLT:257return R_GOTPLTREL;258case R_PLT_GOTREL:259return R_GOTREL;260default:261return expr;262}263}264265// Returns true if a given shared symbol is in a read-only segment in a DSO.266template <class ELFT> static bool isReadOnly(SharedSymbol &ss) {267using Elf_Phdr = typename ELFT::Phdr;268269// Determine if the symbol is read-only by scanning the DSO's program headers.270const auto &file = cast<SharedFile>(*ss.file);271for (const Elf_Phdr &phdr :272check(file.template getObj<ELFT>().program_headers()))273if ((phdr.p_type == ELF::PT_LOAD || phdr.p_type == ELF::PT_GNU_RELRO) &&274!(phdr.p_flags & ELF::PF_W) && ss.value >= phdr.p_vaddr &&275ss.value < phdr.p_vaddr + phdr.p_memsz)276return true;277return false;278}279280// Returns symbols at the same offset as a given symbol, including SS itself.281//282// If two or more symbols are at the same offset, and at least one of283// them are copied by a copy relocation, all of them need to be copied.284// Otherwise, they would refer to different places at runtime.285template <class ELFT>286static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &ss) {287using Elf_Sym = typename ELFT::Sym;288289const auto &file = cast<SharedFile>(*ss.file);290291SmallSet<SharedSymbol *, 4> ret;292for (const Elf_Sym &s : file.template getGlobalELFSyms<ELFT>()) {293if (s.st_shndx == SHN_UNDEF || s.st_shndx == SHN_ABS ||294s.getType() == STT_TLS || s.st_value != ss.value)295continue;296StringRef name = check(s.getName(file.getStringTable()));297Symbol *sym = symtab.find(name);298if (auto *alias = dyn_cast_or_null<SharedSymbol>(sym))299ret.insert(alias);300}301302// The loop does not check SHT_GNU_verneed, so ret does not contain303// non-default version symbols. If ss has a non-default version, ret won't304// contain ss. Just add ss unconditionally. If a non-default version alias is305// separately copy relocated, it and ss will have different addresses.306// Fortunately this case is impractical and fails with GNU ld as well.307ret.insert(&ss);308return ret;309}310311// When a symbol is copy relocated or we create a canonical plt entry, it is312// effectively a defined symbol. In the case of copy relocation the symbol is313// in .bss and in the case of a canonical plt entry it is in .plt. This function314// replaces the existing symbol with a Defined pointing to the appropriate315// location.316static void replaceWithDefined(Symbol &sym, SectionBase &sec, uint64_t value,317uint64_t size) {318Symbol old = sym;319Defined(sym.file, StringRef(), sym.binding, sym.stOther, sym.type, value,320size, &sec)321.overwrite(sym);322323sym.versionId = old.versionId;324sym.exportDynamic = true;325sym.isUsedInRegularObj = true;326// A copy relocated alias may need a GOT entry.327sym.flags.store(old.flags.load(std::memory_order_relaxed) & NEEDS_GOT,328std::memory_order_relaxed);329}330331// Reserve space in .bss or .bss.rel.ro for copy relocation.332//333// The copy relocation is pretty much a hack. If you use a copy relocation334// in your program, not only the symbol name but the symbol's size, RW/RO335// bit and alignment become part of the ABI. In addition to that, if the336// symbol has aliases, the aliases become part of the ABI. That's subtle,337// but if you violate that implicit ABI, that can cause very counter-338// intuitive consequences.339//340// So, what is the copy relocation? It's for linking non-position341// independent code to DSOs. In an ideal world, all references to data342// exported by DSOs should go indirectly through GOT. But if object files343// are compiled as non-PIC, all data references are direct. There is no344// way for the linker to transform the code to use GOT, as machine345// instructions are already set in stone in object files. This is where346// the copy relocation takes a role.347//348// A copy relocation instructs the dynamic linker to copy data from a DSO349// to a specified address (which is usually in .bss) at load-time. If the350// static linker (that's us) finds a direct data reference to a DSO351// symbol, it creates a copy relocation, so that the symbol can be352// resolved as if it were in .bss rather than in a DSO.353//354// As you can see in this function, we create a copy relocation for the355// dynamic linker, and the relocation contains not only symbol name but356// various other information about the symbol. So, such attributes become a357// part of the ABI.358//359// Note for application developers: I can give you a piece of advice if360// you are writing a shared library. You probably should export only361// functions from your library. You shouldn't export variables.362//363// As an example what can happen when you export variables without knowing364// the semantics of copy relocations, assume that you have an exported365// variable of type T. It is an ABI-breaking change to add new members at366// end of T even though doing that doesn't change the layout of the367// existing members. That's because the space for the new members are not368// reserved in .bss unless you recompile the main program. That means they369// are likely to overlap with other data that happens to be laid out next370// to the variable in .bss. This kind of issue is sometimes very hard to371// debug. What's a solution? Instead of exporting a variable V from a DSO,372// define an accessor getV().373template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {374// Copy relocation against zero-sized symbol doesn't make sense.375uint64_t symSize = ss.getSize();376if (symSize == 0 || ss.alignment == 0)377fatal("cannot create a copy relocation for symbol " + toString(ss));378379// See if this symbol is in a read-only segment. If so, preserve the symbol's380// memory protection by reserving space in the .bss.rel.ro section.381bool isRO = isReadOnly<ELFT>(ss);382BssSection *sec =383make<BssSection>(isRO ? ".bss.rel.ro" : ".bss", symSize, ss.alignment);384OutputSection *osec = (isRO ? in.bssRelRo : in.bss)->getParent();385386// At this point, sectionBases has been migrated to sections. Append sec to387// sections.388if (osec->commands.empty() ||389!isa<InputSectionDescription>(osec->commands.back()))390osec->commands.push_back(make<InputSectionDescription>(""));391auto *isd = cast<InputSectionDescription>(osec->commands.back());392isd->sections.push_back(sec);393osec->commitSection(sec);394395// Look through the DSO's dynamic symbol table for aliases and create a396// dynamic symbol for each one. This causes the copy relocation to correctly397// interpose any aliases.398for (SharedSymbol *sym : getSymbolsAt<ELFT>(ss))399replaceWithDefined(*sym, *sec, 0, sym->size);400401mainPart->relaDyn->addSymbolReloc(target->copyRel, *sec, 0, ss);402}403404// .eh_frame sections are mergeable input sections, so their input405// offsets are not linearly mapped to output section. For each input406// offset, we need to find a section piece containing the offset and407// add the piece's base address to the input offset to compute the408// output offset. That isn't cheap.409//410// This class is to speed up the offset computation. When we process411// relocations, we access offsets in the monotonically increasing412// order. So we can optimize for that access pattern.413//414// For sections other than .eh_frame, this class doesn't do anything.415namespace {416class OffsetGetter {417public:418OffsetGetter() = default;419explicit OffsetGetter(InputSectionBase &sec) {420if (auto *eh = dyn_cast<EhInputSection>(&sec)) {421cies = eh->cies;422fdes = eh->fdes;423i = cies.begin();424j = fdes.begin();425}426}427428// Translates offsets in input sections to offsets in output sections.429// Given offset must increase monotonically. We assume that Piece is430// sorted by inputOff.431uint64_t get(uint64_t off) {432if (cies.empty())433return off;434435while (j != fdes.end() && j->inputOff <= off)436++j;437auto it = j;438if (j == fdes.begin() || j[-1].inputOff + j[-1].size <= off) {439while (i != cies.end() && i->inputOff <= off)440++i;441if (i == cies.begin() || i[-1].inputOff + i[-1].size <= off)442fatal(".eh_frame: relocation is not in any piece");443it = i;444}445446// Offset -1 means that the piece is dead (i.e. garbage collected).447if (it[-1].outputOff == -1)448return -1;449return it[-1].outputOff + (off - it[-1].inputOff);450}451452private:453ArrayRef<EhSectionPiece> cies, fdes;454ArrayRef<EhSectionPiece>::iterator i, j;455};456457// This class encapsulates states needed to scan relocations for one458// InputSectionBase.459class RelocationScanner {460public:461template <class ELFT>462void scanSection(InputSectionBase &s, bool isEH = false);463464private:465InputSectionBase *sec;466OffsetGetter getter;467468// End of relocations, used by Mips/PPC64.469const void *end = nullptr;470471template <class RelTy> RelType getMipsN32RelType(RelTy *&rel) const;472template <class ELFT, class RelTy>473int64_t computeMipsAddend(const RelTy &rel, RelExpr expr, bool isLocal) const;474bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym,475uint64_t relOff) const;476void processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym,477int64_t addend) const;478template <class ELFT, class RelTy>479void scanOne(typename Relocs<RelTy>::const_iterator &i);480template <class ELFT, class RelTy> void scan(Relocs<RelTy> rels);481};482} // namespace483484// MIPS has an odd notion of "paired" relocations to calculate addends.485// For example, if a relocation is of R_MIPS_HI16, there must be a486// R_MIPS_LO16 relocation after that, and an addend is calculated using487// the two relocations.488template <class ELFT, class RelTy>489int64_t RelocationScanner::computeMipsAddend(const RelTy &rel, RelExpr expr,490bool isLocal) const {491if (expr == R_MIPS_GOTREL && isLocal)492return sec->getFile<ELFT>()->mipsGp0;493494// The ABI says that the paired relocation is used only for REL.495// See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf496// This generalises to relocation types with implicit addends.497if (RelTy::HasAddend)498return 0;499500RelType type = rel.getType(config->isMips64EL);501uint32_t pairTy = getMipsPairType(type, isLocal);502if (pairTy == R_MIPS_NONE)503return 0;504505const uint8_t *buf = sec->content().data();506uint32_t symIndex = rel.getSymbol(config->isMips64EL);507508// To make things worse, paired relocations might not be contiguous in509// the relocation table, so we need to do linear search. *sigh*510for (const RelTy *ri = &rel; ri != static_cast<const RelTy *>(end); ++ri)511if (ri->getType(config->isMips64EL) == pairTy &&512ri->getSymbol(config->isMips64EL) == symIndex)513return target->getImplicitAddend(buf + ri->r_offset, pairTy);514515warn("can't find matching " + toString(pairTy) + " relocation for " +516toString(type));517return 0;518}519520// Custom error message if Sym is defined in a discarded section.521template <class ELFT>522static std::string maybeReportDiscarded(Undefined &sym) {523auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file);524if (!file || !sym.discardedSecIdx)525return "";526ArrayRef<typename ELFT::Shdr> objSections =527file->template getELFShdrs<ELFT>();528529std::string msg;530if (sym.type == ELF::STT_SECTION) {531msg = "relocation refers to a discarded section: ";532msg += CHECK(533file->getObj().getSectionName(objSections[sym.discardedSecIdx]), file);534} else {535msg = "relocation refers to a symbol in a discarded section: " +536toString(sym);537}538msg += "\n>>> defined in " + toString(file);539540Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1];541if (elfSec.sh_type != SHT_GROUP)542return msg;543544// If the discarded section is a COMDAT.545StringRef signature = file->getShtGroupSignature(objSections, elfSec);546if (const InputFile *prevailing =547symtab.comdatGroups.lookup(CachedHashStringRef(signature))) {548msg += "\n>>> section group signature: " + signature.str() +549"\n>>> prevailing definition is in " + toString(prevailing);550if (sym.nonPrevailing) {551msg += "\n>>> or the symbol in the prevailing group had STB_WEAK "552"binding and the symbol in a non-prevailing group had STB_GLOBAL "553"binding. Mixing groups with STB_WEAK and STB_GLOBAL binding "554"signature is not supported";555}556}557return msg;558}559560namespace {561// Undefined diagnostics are collected in a vector and emitted once all of562// them are known, so that some postprocessing on the list of undefined symbols563// can happen before lld emits diagnostics.564struct UndefinedDiag {565Undefined *sym;566struct Loc {567InputSectionBase *sec;568uint64_t offset;569};570std::vector<Loc> locs;571bool isWarning;572};573574std::vector<UndefinedDiag> undefs;575std::mutex relocMutex;576}577578// Check whether the definition name def is a mangled function name that matches579// the reference name ref.580static bool canSuggestExternCForCXX(StringRef ref, StringRef def) {581llvm::ItaniumPartialDemangler d;582std::string name = def.str();583if (d.partialDemangle(name.c_str()))584return false;585char *buf = d.getFunctionName(nullptr, nullptr);586if (!buf)587return false;588bool ret = ref == buf;589free(buf);590return ret;591}592593// Suggest an alternative spelling of an "undefined symbol" diagnostic. Returns594// the suggested symbol, which is either in the symbol table, or in the same595// file of sym.596static const Symbol *getAlternativeSpelling(const Undefined &sym,597std::string &pre_hint,598std::string &post_hint) {599DenseMap<StringRef, const Symbol *> map;600if (sym.file && sym.file->kind() == InputFile::ObjKind) {601auto *file = cast<ELFFileBase>(sym.file);602// If sym is a symbol defined in a discarded section, maybeReportDiscarded()603// will give an error. Don't suggest an alternative spelling.604if (file && sym.discardedSecIdx != 0 &&605file->getSections()[sym.discardedSecIdx] == &InputSection::discarded)606return nullptr;607608// Build a map of local defined symbols.609for (const Symbol *s : sym.file->getSymbols())610if (s->isLocal() && s->isDefined() && !s->getName().empty())611map.try_emplace(s->getName(), s);612}613614auto suggest = [&](StringRef newName) -> const Symbol * {615// If defined locally.616if (const Symbol *s = map.lookup(newName))617return s;618619// If in the symbol table and not undefined.620if (const Symbol *s = symtab.find(newName))621if (!s->isUndefined())622return s;623624return nullptr;625};626627// This loop enumerates all strings of Levenshtein distance 1 as typo628// correction candidates and suggests the one that exists as a non-undefined629// symbol.630StringRef name = sym.getName();631for (size_t i = 0, e = name.size(); i != e + 1; ++i) {632// Insert a character before name[i].633std::string newName = (name.substr(0, i) + "0" + name.substr(i)).str();634for (char c = '0'; c <= 'z'; ++c) {635newName[i] = c;636if (const Symbol *s = suggest(newName))637return s;638}639if (i == e)640break;641642// Substitute name[i].643newName = std::string(name);644for (char c = '0'; c <= 'z'; ++c) {645newName[i] = c;646if (const Symbol *s = suggest(newName))647return s;648}649650// Transpose name[i] and name[i+1]. This is of edit distance 2 but it is651// common.652if (i + 1 < e) {653newName[i] = name[i + 1];654newName[i + 1] = name[i];655if (const Symbol *s = suggest(newName))656return s;657}658659// Delete name[i].660newName = (name.substr(0, i) + name.substr(i + 1)).str();661if (const Symbol *s = suggest(newName))662return s;663}664665// Case mismatch, e.g. Foo vs FOO.666for (auto &it : map)667if (name.equals_insensitive(it.first))668return it.second;669for (Symbol *sym : symtab.getSymbols())670if (!sym->isUndefined() && name.equals_insensitive(sym->getName()))671return sym;672673// The reference may be a mangled name while the definition is not. Suggest a674// missing extern "C".675if (name.starts_with("_Z")) {676std::string buf = name.str();677llvm::ItaniumPartialDemangler d;678if (!d.partialDemangle(buf.c_str()))679if (char *buf = d.getFunctionName(nullptr, nullptr)) {680const Symbol *s = suggest(buf);681free(buf);682if (s) {683pre_hint = ": extern \"C\" ";684return s;685}686}687} else {688const Symbol *s = nullptr;689for (auto &it : map)690if (canSuggestExternCForCXX(name, it.first)) {691s = it.second;692break;693}694if (!s)695for (Symbol *sym : symtab.getSymbols())696if (canSuggestExternCForCXX(name, sym->getName())) {697s = sym;698break;699}700if (s) {701pre_hint = " to declare ";702post_hint = " as extern \"C\"?";703return s;704}705}706707return nullptr;708}709710static void reportUndefinedSymbol(const UndefinedDiag &undef,711bool correctSpelling) {712Undefined &sym = *undef.sym;713714auto visibility = [&]() -> std::string {715switch (sym.visibility()) {716case STV_INTERNAL:717return "internal ";718case STV_HIDDEN:719return "hidden ";720case STV_PROTECTED:721return "protected ";722default:723return "";724}725};726727std::string msg;728switch (config->ekind) {729case ELF32LEKind:730msg = maybeReportDiscarded<ELF32LE>(sym);731break;732case ELF32BEKind:733msg = maybeReportDiscarded<ELF32BE>(sym);734break;735case ELF64LEKind:736msg = maybeReportDiscarded<ELF64LE>(sym);737break;738case ELF64BEKind:739msg = maybeReportDiscarded<ELF64BE>(sym);740break;741default:742llvm_unreachable("");743}744if (msg.empty())745msg = "undefined " + visibility() + "symbol: " + toString(sym);746747const size_t maxUndefReferences = 3;748size_t i = 0;749for (UndefinedDiag::Loc l : undef.locs) {750if (i >= maxUndefReferences)751break;752InputSectionBase &sec = *l.sec;753uint64_t offset = l.offset;754755msg += "\n>>> referenced by ";756// In the absence of line number information, utilize DW_TAG_variable (if757// present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).758Symbol *enclosing = sec.getEnclosingSymbol(offset);759std::string src = sec.getSrcMsg(enclosing ? *enclosing : sym, offset);760if (!src.empty())761msg += src + "\n>>> ";762msg += sec.getObjMsg(offset);763i++;764}765766if (i < undef.locs.size())767msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")768.str();769770if (correctSpelling) {771std::string pre_hint = ": ", post_hint;772if (const Symbol *corrected =773getAlternativeSpelling(sym, pre_hint, post_hint)) {774msg += "\n>>> did you mean" + pre_hint + toString(*corrected) + post_hint;775if (corrected->file)776msg += "\n>>> defined in: " + toString(corrected->file);777}778}779780if (sym.getName().starts_with("_ZTV"))781msg +=782"\n>>> the vtable symbol may be undefined because the class is missing "783"its key function (see https://lld.llvm.org/missingkeyfunction)";784if (config->gcSections && config->zStartStopGC &&785sym.getName().starts_with("__start_")) {786msg += "\n>>> the encapsulation symbol needs to be retained under "787"--gc-sections properly; consider -z nostart-stop-gc "788"(see https://lld.llvm.org/ELF/start-stop-gc)";789}790791if (undef.isWarning)792warn(msg);793else794error(msg, ErrorTag::SymbolNotFound, {sym.getName()});795}796797void elf::reportUndefinedSymbols() {798// Find the first "undefined symbol" diagnostic for each diagnostic, and799// collect all "referenced from" lines at the first diagnostic.800DenseMap<Symbol *, UndefinedDiag *> firstRef;801for (UndefinedDiag &undef : undefs) {802assert(undef.locs.size() == 1);803if (UndefinedDiag *canon = firstRef.lookup(undef.sym)) {804canon->locs.push_back(undef.locs[0]);805undef.locs.clear();806} else807firstRef[undef.sym] = &undef;808}809810// Enable spell corrector for the first 2 diagnostics.811for (const auto &[i, undef] : llvm::enumerate(undefs))812if (!undef.locs.empty())813reportUndefinedSymbol(undef, i < 2);814undefs.clear();815}816817// Report an undefined symbol if necessary.818// Returns true if the undefined symbol will produce an error message.819static bool maybeReportUndefined(Undefined &sym, InputSectionBase &sec,820uint64_t offset) {821std::lock_guard<std::mutex> lock(relocMutex);822// If versioned, issue an error (even if the symbol is weak) because we don't823// know the defining filename which is required to construct a Verneed entry.824if (sym.hasVersionSuffix) {825undefs.push_back({&sym, {{&sec, offset}}, false});826return true;827}828if (sym.isWeak())829return false;830831bool canBeExternal = !sym.isLocal() && sym.visibility() == STV_DEFAULT;832if (config->unresolvedSymbols == UnresolvedPolicy::Ignore && canBeExternal)833return false;834835// clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc836// which references a switch table in a discarded .rodata/.text section. The837// .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF838// spec says references from outside the group to a STB_LOCAL symbol are not839// allowed. Work around the bug.840//841// PPC32 .got2 is similar but cannot be fixed. Multiple .got2 is infeasible842// because .LC0-.LTOC is not representable if the two labels are in different843// .got2844if (sym.discardedSecIdx != 0 && (sec.name == ".got2" || sec.name == ".toc"))845return false;846847bool isWarning =848(config->unresolvedSymbols == UnresolvedPolicy::Warn && canBeExternal) ||849config->noinhibitExec;850undefs.push_back({&sym, {{&sec, offset}}, isWarning});851return !isWarning;852}853854// MIPS N32 ABI treats series of successive relocations with the same offset855// as a single relocation. The similar approach used by N64 ABI, but this ABI856// packs all relocations into the single relocation record. Here we emulate857// this for the N32 ABI. Iterate over relocation with the same offset and put858// theirs types into the single bit-set.859template <class RelTy>860RelType RelocationScanner::getMipsN32RelType(RelTy *&rel) const {861RelType type = 0;862uint64_t offset = rel->r_offset;863864int n = 0;865while (rel != static_cast<const RelTy *>(end) && rel->r_offset == offset)866type |= (rel++)->getType(config->isMips64EL) << (8 * n++);867return type;868}869870template <bool shard = false>871static void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec,872Symbol &sym, int64_t addend, RelExpr expr,873RelType type) {874Partition &part = isec.getPartition();875876if (sym.isTagged()) {877std::lock_guard<std::mutex> lock(relocMutex);878part.relaDyn->addRelativeReloc(target->relativeRel, isec, offsetInSec, sym,879addend, type, expr);880// With MTE globals, we always want to derive the address tag by `ldg`-ing881// the symbol. When we have a RELATIVE relocation though, we no longer have882// a reference to the symbol. Because of this, when we have an addend that883// puts the result of the RELATIVE relocation out-of-bounds of the symbol884// (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI885// says we should store the offset to the start of the symbol in the target886// field. This is described in further detail in:887// https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative888if (addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize())889isec.relocations.push_back({expr, type, offsetInSec, addend, &sym});890return;891}892893// Add a relative relocation. If relrDyn section is enabled, and the894// relocation offset is guaranteed to be even, add the relocation to895// the relrDyn section, otherwise add it to the relaDyn section.896// relrDyn sections don't support odd offsets. Also, relrDyn sections897// don't store the addend values, so we must write it to the relocated898// address.899if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) {900isec.addReloc({expr, type, offsetInSec, addend, &sym});901if (shard)902part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back(903{&isec, isec.relocs().size() - 1});904else905part.relrDyn->relocs.push_back({&isec, isec.relocs().size() - 1});906return;907}908part.relaDyn->addRelativeReloc<shard>(target->relativeRel, isec, offsetInSec,909sym, addend, type, expr);910}911912template <class PltSection, class GotPltSection>913static void addPltEntry(PltSection &plt, GotPltSection &gotPlt,914RelocationBaseSection &rel, RelType type, Symbol &sym) {915plt.addEntry(sym);916gotPlt.addEntry(sym);917rel.addReloc({type, &gotPlt, sym.getGotPltOffset(),918sym.isPreemptible ? DynamicReloc::AgainstSymbol919: DynamicReloc::AddendOnlyWithTargetVA,920sym, 0, R_ABS});921}922923void elf::addGotEntry(Symbol &sym) {924in.got->addEntry(sym);925uint64_t off = sym.getGotOffset();926927// If preemptible, emit a GLOB_DAT relocation.928if (sym.isPreemptible) {929mainPart->relaDyn->addReloc({target->gotRel, in.got.get(), off,930DynamicReloc::AgainstSymbol, sym, 0, R_ABS});931return;932}933934// Otherwise, the value is either a link-time constant or the load base935// plus a constant.936if (!config->isPic || isAbsolute(sym))937in.got->addConstant({R_ABS, target->symbolicRel, off, 0, &sym});938else939addRelativeReloc(*in.got, off, sym, 0, R_ABS, target->symbolicRel);940}941942static void addTpOffsetGotEntry(Symbol &sym) {943in.got->addEntry(sym);944uint64_t off = sym.getGotOffset();945if (!sym.isPreemptible && !config->shared) {946in.got->addConstant({R_TPREL, target->symbolicRel, off, 0, &sym});947return;948}949mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(950target->tlsGotRel, *in.got, off, sym, target->symbolicRel);951}952953// Return true if we can define a symbol in the executable that954// contains the value/function of a symbol defined in a shared955// library.956static bool canDefineSymbolInExecutable(Symbol &sym) {957// If the symbol has default visibility the symbol defined in the958// executable will preempt it.959// Note that we want the visibility of the shared symbol itself, not960// the visibility of the symbol in the output file we are producing.961if (!sym.dsoProtected)962return true;963964// If we are allowed to break address equality of functions, defining965// a plt entry will allow the program to call the function in the966// .so, but the .so and the executable will no agree on the address967// of the function. Similar logic for objects.968return ((sym.isFunc() && config->ignoreFunctionAddressEquality) ||969(sym.isObject() && config->ignoreDataAddressEquality));970}971972// Returns true if a given relocation can be computed at link-time.973// This only handles relocation types expected in processAux.974//975// For instance, we know the offset from a relocation to its target at976// link-time if the relocation is PC-relative and refers a977// non-interposable function in the same executable. This function978// will return true for such relocation.979//980// If this function returns false, that means we need to emit a981// dynamic relocation so that the relocation will be fixed at load-time.982bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,983const Symbol &sym,984uint64_t relOff) const {985// These expressions always compute a constant986if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, R_MIPS_GOT_LOCAL_PAGE,987R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,988R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,989R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT, R_GOTPLT_GOTREL, R_GOTPLT_PC,990R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD,991R_AARCH64_GOT_PAGE, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,992R_LOONGARCH_GOT_PAGE_PC>(e))993return true;994995// These never do, except if the entire file is position dependent or if996// only the low bits are used.997if (e == R_GOT || e == R_PLT)998return target->usesOnlyLowPageBits(type) || !config->isPic;9991000// R_AARCH64_AUTH_ABS64 requires a dynamic relocation.1001if (sym.isPreemptible || e == R_AARCH64_AUTH)1002return false;1003if (!config->isPic)1004return true;10051006// Constant when referencing a non-preemptible symbol.1007if (e == R_SIZE || e == R_RISCV_LEB128)1008return true;10091010// For the target and the relocation, we want to know if they are1011// absolute or relative.1012bool absVal = isAbsoluteValue(sym);1013bool relE = isRelExpr(e);1014if (absVal && !relE)1015return true;1016if (!absVal && relE)1017return true;1018if (!absVal && !relE)1019return target->usesOnlyLowPageBits(type);10201021assert(absVal && relE);10221023// Allow R_PLT_PC (optimized to R_PC here) to a hidden undefined weak symbol1024// in PIC mode. This is a little strange, but it allows us to link function1025// calls to such symbols (e.g. glibc/stdlib/exit.c:__run_exit_handlers).1026// Normally such a call will be guarded with a comparison, which will load a1027// zero from the GOT.1028if (sym.isUndefWeak())1029return true;10301031// We set the final symbols values for linker script defined symbols later.1032// They always can be computed as a link time constant.1033if (sym.scriptDefined)1034return true;10351036error("relocation " + toString(type) + " cannot refer to absolute symbol: " +1037toString(sym) + getLocation(*sec, sym, relOff));1038return true;1039}10401041// The reason we have to do this early scan is as follows1042// * To mmap the output file, we need to know the size1043// * For that, we need to know how many dynamic relocs we will have.1044// It might be possible to avoid this by outputting the file with write:1045// * Write the allocated output sections, computing addresses.1046// * Apply relocations, recording which ones require a dynamic reloc.1047// * Write the dynamic relocations.1048// * Write the rest of the file.1049// This would have some drawbacks. For example, we would only know if .rela.dyn1050// is needed after applying relocations. If it is, it will go after rw and rx1051// sections. Given that it is ro, we will need an extra PT_LOAD. This1052// complicates things for the dynamic linker and means we would have to reserve1053// space for the extra PT_LOAD even if we end up not using it.1054void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,1055Symbol &sym, int64_t addend) const {1056// If non-ifunc non-preemptible, change PLT to direct call and optimize GOT1057// indirection.1058const bool isIfunc = sym.isGnuIFunc();1059if (!sym.isPreemptible && (!isIfunc || config->zIfuncNoplt)) {1060if (expr != R_GOT_PC) {1061// The 0x8000 bit of r_addend of R_PPC_PLTREL24 is used to choose call1062// stub type. It should be ignored if optimized to R_PC.1063if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)1064addend &= ~0x8000;1065// R_HEX_GD_PLT_B22_PCREL (call a@GDPLT) is transformed into1066// call __tls_get_addr even if the symbol is non-preemptible.1067if (!(config->emachine == EM_HEXAGON &&1068(type == R_HEX_GD_PLT_B22_PCREL ||1069type == R_HEX_GD_PLT_B22_PCREL_X ||1070type == R_HEX_GD_PLT_B32_PCREL_X)))1071expr = fromPlt(expr);1072} else if (!isAbsoluteValue(sym)) {1073expr =1074target->adjustGotPcExpr(type, addend, sec->content().data() + offset);1075// If the target adjusted the expression to R_RELAX_GOT_PC, we may end up1076// needing the GOT if we can't relax everything.1077if (expr == R_RELAX_GOT_PC)1078in.got->hasGotOffRel.store(true, std::memory_order_relaxed);1079}1080}10811082// We were asked not to generate PLT entries for ifuncs. Instead, pass the1083// direct relocation on through.1084if (LLVM_UNLIKELY(isIfunc) && config->zIfuncNoplt) {1085std::lock_guard<std::mutex> lock(relocMutex);1086sym.exportDynamic = true;1087mainPart->relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);1088return;1089}10901091if (needsGot(expr)) {1092if (config->emachine == EM_MIPS) {1093// MIPS ABI has special rules to process GOT entries and doesn't1094// require relocation entries for them. A special case is TLS1095// relocations. In that case dynamic loader applies dynamic1096// relocations to initialize TLS GOT entries.1097// See "Global Offset Table" in Chapter 5 in the following document1098// for detailed description:1099// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf1100in.mipsGot->addEntry(*sec->file, sym, addend, expr);1101} else if (!sym.isTls() || config->emachine != EM_LOONGARCH) {1102// Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which1103// case the NEEDS_GOT flag shouldn't get set.1104sym.setFlags(NEEDS_GOT);1105}1106} else if (needsPlt(expr)) {1107sym.setFlags(NEEDS_PLT);1108} else if (LLVM_UNLIKELY(isIfunc)) {1109sym.setFlags(HAS_DIRECT_RELOC);1110}11111112// If the relocation is known to be a link-time constant, we know no dynamic1113// relocation will be created, pass the control to relocateAlloc() or1114// relocateNonAlloc() to resolve it.1115//1116// The behavior of an undefined weak reference is implementation defined. For1117// non-link-time constants, we resolve relocations statically (let1118// relocate{,Non}Alloc() resolve them) for -no-pie and try producing dynamic1119// relocations for -pie and -shared.1120//1121// The general expectation of -no-pie static linking is that there is no1122// dynamic relocation (except IRELATIVE). Emitting dynamic relocations for1123// -shared matches the spirit of its -z undefs default. -pie has freedom on1124// choices, and we choose dynamic relocations to be consistent with the1125// handling of GOT-generating relocations.1126if (isStaticLinkTimeConstant(expr, type, sym, offset) ||1127(!config->isPic && sym.isUndefWeak())) {1128sec->addReloc({expr, type, offset, addend, &sym});1129return;1130}11311132// Use a simple -z notext rule that treats all sections except .eh_frame as1133// writable. GNU ld does not produce dynamic relocations in .eh_frame (and our1134// SectionBase::getOffset would incorrectly adjust the offset).1135//1136// For MIPS, we don't implement GNU ld's DW_EH_PE_absptr to DW_EH_PE_pcrel1137// conversion. We still emit a dynamic relocation.1138bool canWrite = (sec->flags & SHF_WRITE) ||1139!(config->zText ||1140(isa<EhInputSection>(sec) && config->emachine != EM_MIPS));1141if (canWrite) {1142RelType rel = target->getDynRel(type);1143if (oneof<R_GOT, R_LOONGARCH_GOT>(expr) ||1144(rel == target->symbolicRel && !sym.isPreemptible)) {1145addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);1146return;1147}1148if (rel != 0) {1149if (config->emachine == EM_MIPS && rel == target->symbolicRel)1150rel = target->relativeRel;1151std::lock_guard<std::mutex> lock(relocMutex);1152Partition &part = sec->getPartition();1153if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {1154// For a preemptible symbol, we can't use a relative relocation. For an1155// undefined symbol, we can't compute offset at link-time and use a1156// relative relocation. Use a symbolic relocation instead.1157if (sym.isPreemptible) {1158part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);1159} else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0) {1160// When symbol values are determined in1161// finalizeAddressDependentContent, some .relr.auth.dyn relocations1162// may be moved to .rela.dyn.1163sec->addReloc({expr, type, offset, addend, &sym});1164part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1});1165} else {1166part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,1167DynamicReloc::AddendOnlyWithTargetVA, sym,1168addend, R_ABS});1169}1170return;1171}1172part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type);11731174// MIPS ABI turns using of GOT and dynamic relocations inside out.1175// While regular ABI uses dynamic relocations to fill up GOT entries1176// MIPS ABI requires dynamic linker to fills up GOT entries using1177// specially sorted dynamic symbol table. This affects even dynamic1178// relocations against symbols which do not require GOT entries1179// creation explicitly, i.e. do not have any GOT-relocations. So if1180// a preemptible symbol has a dynamic relocation we anyway have1181// to create a GOT entry for it.1182// If a non-preemptible symbol has a dynamic relocation against it,1183// dynamic linker takes it st_value, adds offset and writes down1184// result of the dynamic relocation. In case of preemptible symbol1185// dynamic linker performs symbol resolution, writes the symbol value1186// to the GOT entry and reads the GOT entry when it needs to perform1187// a dynamic relocation.1188// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-191189if (config->emachine == EM_MIPS)1190in.mipsGot->addEntry(*sec->file, sym, addend, expr);1191return;1192}1193}11941195// When producing an executable, we can perform copy relocations (for1196// STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.1197// Copy relocations/canonical PLT entries are unsupported for1198// R_AARCH64_AUTH_ABS64.1199if (!config->shared && sym.isShared() &&1200!(config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {1201if (!canDefineSymbolInExecutable(sym)) {1202errorOrWarn("cannot preempt symbol: " + toString(sym) +1203getLocation(*sec, sym, offset));1204return;1205}12061207if (sym.isObject()) {1208// Produce a copy relocation.1209if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {1210if (!config->zCopyreloc)1211error("unresolvable relocation " + toString(type) +1212" against symbol '" + toString(*ss) +1213"'; recompile with -fPIC or remove '-z nocopyreloc'" +1214getLocation(*sec, sym, offset));1215sym.setFlags(NEEDS_COPY);1216}1217sec->addReloc({expr, type, offset, addend, &sym});1218return;1219}12201221// This handles a non PIC program call to function in a shared library. In1222// an ideal world, we could just report an error saying the relocation can1223// overflow at runtime. In the real world with glibc, crt1.o has a1224// R_X86_64_PC32 pointing to libc.so.1225//1226// The general idea on how to handle such cases is to create a PLT entry and1227// use that as the function value.1228//1229// For the static linking part, we just return a plt expr and everything1230// else will use the PLT entry as the address.1231//1232// The remaining problem is making sure pointer equality still works. We1233// need the help of the dynamic linker for that. We let it know that we have1234// a direct reference to a so symbol by creating an undefined symbol with a1235// non zero st_value. Seeing that, the dynamic linker resolves the symbol to1236// the value of the symbol we created. This is true even for got entries, so1237// pointer equality is maintained. To avoid an infinite loop, the only entry1238// that points to the real function is a dedicated got entry used by the1239// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,1240// R_386_JMP_SLOT, etc).12411242// For position independent executable on i386, the plt entry requires ebx1243// to be set. This causes two problems:1244// * If some code has a direct reference to a function, it was probably1245// compiled without -fPIE/-fPIC and doesn't maintain ebx.1246// * If a library definition gets preempted to the executable, it will have1247// the wrong ebx value.1248if (sym.isFunc()) {1249if (config->pie && config->emachine == EM_386)1250errorOrWarn("symbol '" + toString(sym) +1251"' cannot be preempted; recompile with -fPIE" +1252getLocation(*sec, sym, offset));1253sym.setFlags(NEEDS_COPY | NEEDS_PLT);1254sec->addReloc({expr, type, offset, addend, &sym});1255return;1256}1257}12581259errorOrWarn("relocation " + toString(type) + " cannot be used against " +1260(sym.getName().empty() ? "local symbol"1261: "symbol '" + toString(sym) + "'") +1262"; recompile with -fPIC" + getLocation(*sec, sym, offset));1263}12641265// This function is similar to the `handleTlsRelocation`. MIPS does not1266// support any relaxations for TLS relocations so by factoring out MIPS1267// handling in to the separate function we can simplify the code and do not1268// pollute other `handleTlsRelocation` by MIPS `ifs` statements.1269// Mips has a custom MipsGotSection that handles the writing of GOT entries1270// without dynamic relocations.1271static unsigned handleMipsTlsRelocation(RelType type, Symbol &sym,1272InputSectionBase &c, uint64_t offset,1273int64_t addend, RelExpr expr) {1274if (expr == R_MIPS_TLSLD) {1275in.mipsGot->addTlsIndex(*c.file);1276c.addReloc({expr, type, offset, addend, &sym});1277return 1;1278}1279if (expr == R_MIPS_TLSGD) {1280in.mipsGot->addDynTlsEntry(*c.file, sym);1281c.addReloc({expr, type, offset, addend, &sym});1282return 1;1283}1284return 0;1285}12861287// Notes about General Dynamic and Local Dynamic TLS models below. They may1288// require the generation of a pair of GOT entries that have associated dynamic1289// relocations. The pair of GOT entries created are of the form GOT[e0] Module1290// Index (Used to find pointer to TLS block at run-time) GOT[e1] Offset of1291// symbol in TLS block.1292//1293// Returns the number of relocations processed.1294static unsigned handleTlsRelocation(RelType type, Symbol &sym,1295InputSectionBase &c, uint64_t offset,1296int64_t addend, RelExpr expr) {1297if (expr == R_TPREL || expr == R_TPREL_NEG) {1298if (config->shared) {1299errorOrWarn("relocation " + toString(type) + " against " + toString(sym) +1300" cannot be used with -shared" + getLocation(c, sym, offset));1301return 1;1302}1303return 0;1304}13051306if (config->emachine == EM_MIPS)1307return handleMipsTlsRelocation(type, sym, c, offset, addend, expr);13081309// LoongArch does not yet implement transition from TLSDESC to LE/IE, so1310// generate TLSDESC dynamic relocation for the dynamic linker to handle.1311if (config->emachine == EM_LOONGARCH &&1312oneof<R_LOONGARCH_TLSDESC_PAGE_PC, R_TLSDESC, R_TLSDESC_PC,1313R_TLSDESC_CALL>(expr)) {1314if (expr != R_TLSDESC_CALL) {1315sym.setFlags(NEEDS_TLSDESC);1316c.addReloc({expr, type, offset, addend, &sym});1317}1318return 1;1319}13201321bool isRISCV = config->emachine == EM_RISCV;13221323if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,1324R_TLSDESC_GOTPLT>(expr) &&1325config->shared) {1326// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a label. Do not1327// set NEEDS_TLSDESC on the label.1328if (expr != R_TLSDESC_CALL) {1329if (!isRISCV || type == R_RISCV_TLSDESC_HI20)1330sym.setFlags(NEEDS_TLSDESC);1331c.addReloc({expr, type, offset, addend, &sym});1332}1333return 1;1334}13351336// ARM, Hexagon, LoongArch and RISC-V do not support GD/LD to IE/LE1337// optimizations.1338// RISC-V supports TLSDESC to IE/LE optimizations.1339// For PPC64, if the file has missing R_PPC64_TLSGD/R_PPC64_TLSLD, disable1340// optimization as well.1341bool execOptimize =1342!config->shared && config->emachine != EM_ARM &&1343config->emachine != EM_HEXAGON && config->emachine != EM_LOONGARCH &&1344!(isRISCV && expr != R_TLSDESC_PC && expr != R_TLSDESC_CALL) &&1345!c.file->ppc64DisableTLSRelax;13461347// If we are producing an executable and the symbol is non-preemptable, it1348// must be defined and the code sequence can be optimized to use Local-Exec.1349//1350// ARM and RISC-V do not support any relaxations for TLS relocations, however,1351// we can omit the DTPMOD dynamic relocations and resolve them at link time1352// because them are always 1. This may be necessary for static linking as1353// DTPMOD may not be expected at load time.1354bool isLocalInExecutable = !sym.isPreemptible && !config->shared;13551356// Local Dynamic is for access to module local TLS variables, while still1357// being suitable for being dynamically loaded via dlopen. GOT[e0] is the1358// module index, with a special value of 0 for the current module. GOT[e1] is1359// unused. There only needs to be one module index entry.1360if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(expr)) {1361// Local-Dynamic relocs can be optimized to Local-Exec.1362if (execOptimize) {1363c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE), type,1364offset, addend, &sym});1365return target->getTlsGdRelaxSkip(type);1366}1367if (expr == R_TLSLD_HINT)1368return 1;1369ctx.needsTlsLd.store(true, std::memory_order_relaxed);1370c.addReloc({expr, type, offset, addend, &sym});1371return 1;1372}13731374// Local-Dynamic relocs can be optimized to Local-Exec.1375if (expr == R_DTPREL) {1376if (execOptimize)1377expr = target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE);1378c.addReloc({expr, type, offset, addend, &sym});1379return 1;1380}13811382// Local-Dynamic sequence where offset of tls variable relative to dynamic1383// thread pointer is stored in the got. This cannot be optimized to1384// Local-Exec.1385if (expr == R_TLSLD_GOT_OFF) {1386sym.setFlags(NEEDS_GOT_DTPREL);1387c.addReloc({expr, type, offset, addend, &sym});1388return 1;1389}13901391if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,1392R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC,1393R_LOONGARCH_TLSGD_PAGE_PC>(expr)) {1394if (!execOptimize) {1395sym.setFlags(NEEDS_TLSGD);1396c.addReloc({expr, type, offset, addend, &sym});1397return 1;1398}13991400// Global-Dynamic/TLSDESC can be optimized to Initial-Exec or Local-Exec1401// depending on the symbol being locally defined or not.1402//1403// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a non-preemptible1404// label, so TLSDESC=>IE will be categorized as R_RELAX_TLS_GD_TO_LE. We fix1405// the categorization in RISCV::relocateAlloc.1406if (sym.isPreemptible) {1407sym.setFlags(NEEDS_TLSGD_TO_IE);1408c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type,1409offset, addend, &sym});1410} else {1411c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE), type,1412offset, addend, &sym});1413}1414return target->getTlsGdRelaxSkip(type);1415}14161417if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC,1418R_LOONGARCH_GOT_PAGE_PC, R_GOT_OFF, R_TLSIE_HINT>(expr)) {1419ctx.hasTlsIe.store(true, std::memory_order_relaxed);1420// Initial-Exec relocs can be optimized to Local-Exec if the symbol is1421// locally defined. This is not supported on SystemZ.1422if (execOptimize && isLocalInExecutable && config->emachine != EM_S390) {1423c.addReloc({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});1424} else if (expr != R_TLSIE_HINT) {1425sym.setFlags(NEEDS_TLSIE);1426// R_GOT needs a relative relocation for PIC on i386 and Hexagon.1427if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type))1428addRelativeReloc<true>(c, offset, sym, addend, expr, type);1429else1430c.addReloc({expr, type, offset, addend, &sym});1431}1432return 1;1433}14341435return 0;1436}14371438template <class ELFT, class RelTy>1439void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {1440const RelTy &rel = *i;1441uint32_t symIndex = rel.getSymbol(config->isMips64EL);1442Symbol &sym = sec->getFile<ELFT>()->getSymbol(symIndex);1443RelType type;1444if constexpr (ELFT::Is64Bits || RelTy::IsCrel) {1445type = rel.getType(config->isMips64EL);1446++i;1447} else {1448// CREL is unsupported for MIPS N32.1449if (config->mipsN32Abi) {1450type = getMipsN32RelType(i);1451} else {1452type = rel.getType(config->isMips64EL);1453++i;1454}1455}1456// Get an offset in an output section this relocation is applied to.1457uint64_t offset = getter.get(rel.r_offset);1458if (offset == uint64_t(-1))1459return;14601461RelExpr expr = target->getRelExpr(type, sym, sec->content().data() + offset);1462int64_t addend = RelTy::HasAddend1463? getAddend<ELFT>(rel)1464: target->getImplicitAddend(1465sec->content().data() + rel.r_offset, type);1466if (LLVM_UNLIKELY(config->emachine == EM_MIPS))1467addend += computeMipsAddend<ELFT>(rel, expr, sym.isLocal());1468else if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC)1469addend += getPPC64TocBase();14701471// Ignore R_*_NONE and other marker relocations.1472if (expr == R_NONE)1473return;14741475// Error if the target symbol is undefined. Symbol index 0 may be used by1476// marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them.1477if (sym.isUndefined() && symIndex != 0 &&1478maybeReportUndefined(cast<Undefined>(sym), *sec, offset))1479return;14801481if (config->emachine == EM_PPC64) {1482// We can separate the small code model relocations into 2 categories:1483// 1) Those that access the compiler generated .toc sections.1484// 2) Those that access the linker allocated got entries.1485// lld allocates got entries to symbols on demand. Since we don't try to1486// sort the got entries in any way, we don't have to track which objects1487// have got-based small code model relocs. The .toc sections get placed1488// after the end of the linker allocated .got section and we do sort those1489// so sections addressed with small code model relocations come first.1490if (type == R_PPC64_TOC16 || type == R_PPC64_TOC16_DS)1491sec->file->ppc64SmallCodeModelTocRelocs = true;14921493// Record the TOC entry (.toc + addend) as not relaxable. See the comment in1494// InputSectionBase::relocateAlloc().1495if (type == R_PPC64_TOC16_LO && sym.isSection() && isa<Defined>(sym) &&1496cast<Defined>(sym).section->name == ".toc")1497ppc64noTocRelax.insert({&sym, addend});14981499if ((type == R_PPC64_TLSGD && expr == R_TLSDESC_CALL) ||1500(type == R_PPC64_TLSLD && expr == R_TLSLD_HINT)) {1501// Skip the error check for CREL, which does not set `end`.1502if constexpr (!RelTy::IsCrel) {1503if (i == end) {1504errorOrWarn("R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "1505"relocation" +1506getLocation(*sec, sym, offset));1507return;1508}1509}15101511// Offset the 4-byte aligned R_PPC64_TLSGD by one byte in the NOTOC1512// case, so we can discern it later from the toc-case.1513if (i->getType(/*isMips64EL=*/false) == R_PPC64_REL24_NOTOC)1514++offset;1515}1516}15171518// If the relocation does not emit a GOT or GOTPLT entry but its computation1519// uses their addresses, we need GOT or GOTPLT to be created.1520//1521// The 5 types that relative GOTPLT are all x86 and x86-64 specific.1522if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_PLT_GOTPLT,1523R_TLSDESC_GOTPLT, R_TLSGD_GOTPLT>(expr)) {1524in.gotPlt->hasGotPltOffRel.store(true, std::memory_order_relaxed);1525} else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC32_PLTREL, R_PPC64_TOCBASE,1526R_PPC64_RELAX_TOC>(expr)) {1527in.got->hasGotOffRel.store(true, std::memory_order_relaxed);1528}15291530// Process TLS relocations, including TLS optimizations. Note that1531// R_TPREL and R_TPREL_NEG relocations are resolved in processAux.1532//1533// Some RISCV TLSDESC relocations reference a local NOTYPE symbol,1534// but we need to process them in handleTlsRelocation.1535if (sym.isTls() || oneof<R_TLSDESC_PC, R_TLSDESC_CALL>(expr)) {1536if (unsigned processed =1537handleTlsRelocation(type, sym, *sec, offset, addend, expr)) {1538i += processed - 1;1539return;1540}1541}15421543processAux(expr, type, offset, sym, addend);1544}15451546// R_PPC64_TLSGD/R_PPC64_TLSLD is required to mark `bl __tls_get_addr` for1547// General Dynamic/Local Dynamic code sequences. If a GD/LD GOT relocation is1548// found but no R_PPC64_TLSGD/R_PPC64_TLSLD is seen, we assume that the1549// instructions are generated by very old IBM XL compilers. Work around the1550// issue by disabling GD/LD to IE/LE relaxation.1551template <class RelTy>1552static void checkPPC64TLSRelax(InputSectionBase &sec, Relocs<RelTy> rels) {1553// Skip if sec is synthetic (sec.file is null) or if sec has been marked.1554if (!sec.file || sec.file->ppc64DisableTLSRelax)1555return;1556bool hasGDLD = false;1557for (const RelTy &rel : rels) {1558RelType type = rel.getType(false);1559switch (type) {1560case R_PPC64_TLSGD:1561case R_PPC64_TLSLD:1562return; // Found a marker1563case R_PPC64_GOT_TLSGD16:1564case R_PPC64_GOT_TLSGD16_HA:1565case R_PPC64_GOT_TLSGD16_HI:1566case R_PPC64_GOT_TLSGD16_LO:1567case R_PPC64_GOT_TLSLD16:1568case R_PPC64_GOT_TLSLD16_HA:1569case R_PPC64_GOT_TLSLD16_HI:1570case R_PPC64_GOT_TLSLD16_LO:1571hasGDLD = true;1572break;1573}1574}1575if (hasGDLD) {1576sec.file->ppc64DisableTLSRelax = true;1577warn(toString(sec.file) +1578": disable TLS relaxation due to R_PPC64_GOT_TLS* relocations without "1579"R_PPC64_TLSGD/R_PPC64_TLSLD relocations");1580}1581}15821583template <class ELFT, class RelTy>1584void RelocationScanner::scan(Relocs<RelTy> rels) {1585// Not all relocations end up in Sec->Relocations, but a lot do.1586sec->relocations.reserve(rels.size());15871588if (config->emachine == EM_PPC64)1589checkPPC64TLSRelax<RelTy>(*sec, rels);15901591// For EhInputSection, OffsetGetter expects the relocations to be sorted by1592// r_offset. In rare cases (.eh_frame pieces are reordered by a linker1593// script), the relocations may be unordered.1594// On SystemZ, all sections need to be sorted by r_offset, to allow TLS1595// relaxation to be handled correctly - see SystemZ::getTlsGdRelaxSkip.1596SmallVector<RelTy, 0> storage;1597if (isa<EhInputSection>(sec) || config->emachine == EM_S390)1598rels = sortRels(rels, storage);15991600if constexpr (RelTy::IsCrel) {1601for (auto i = rels.begin(); i != rels.end();)1602scanOne<ELFT, RelTy>(i);1603} else {1604// The non-CREL code path has additional check for PPC64 TLS.1605end = static_cast<const void *>(rels.end());1606for (auto i = rels.begin(); i != end;)1607scanOne<ELFT, RelTy>(i);1608}16091610// Sort relocations by offset for more efficient searching for1611// R_RISCV_PCREL_HI20 and R_PPC64_ADDR64.1612if (config->emachine == EM_RISCV ||1613(config->emachine == EM_PPC64 && sec->name == ".toc"))1614llvm::stable_sort(sec->relocs(),1615[](const Relocation &lhs, const Relocation &rhs) {1616return lhs.offset < rhs.offset;1617});1618}16191620template <class ELFT>1621void RelocationScanner::scanSection(InputSectionBase &s, bool isEH) {1622sec = &s;1623getter = OffsetGetter(s);1624const RelsOrRelas<ELFT> rels = s.template relsOrRelas<ELFT>(!isEH);1625if (rels.areRelocsCrel())1626scan<ELFT>(rels.crels);1627else if (rels.areRelocsRel())1628scan<ELFT>(rels.rels);1629else1630scan<ELFT>(rels.relas);1631}16321633template <class ELFT> void elf::scanRelocations() {1634// Scan all relocations. Each relocation goes through a series of tests to1635// determine if it needs special treatment, such as creating GOT, PLT,1636// copy relocations, etc. Note that relocations for non-alloc sections are1637// directly processed by InputSection::relocateNonAlloc.16381639// Deterministic parallellism needs sorting relocations which is unsuitable1640// for -z nocombreloc. MIPS and PPC64 use global states which are not suitable1641// for parallelism.1642bool serial = !config->zCombreloc || config->emachine == EM_MIPS ||1643config->emachine == EM_PPC64;1644parallel::TaskGroup tg;1645auto outerFn = [&]() {1646for (ELFFileBase *f : ctx.objectFiles) {1647auto fn = [f]() {1648RelocationScanner scanner;1649for (InputSectionBase *s : f->getSections()) {1650if (s && s->kind() == SectionBase::Regular && s->isLive() &&1651(s->flags & SHF_ALLOC) &&1652!(s->type == SHT_ARM_EXIDX && config->emachine == EM_ARM))1653scanner.template scanSection<ELFT>(*s);1654}1655};1656if (serial)1657fn();1658else1659tg.spawn(fn);1660}1661auto scanEH = [] {1662RelocationScanner scanner;1663for (Partition &part : partitions) {1664for (EhInputSection *sec : part.ehFrame->sections)1665scanner.template scanSection<ELFT>(*sec);1666if (part.armExidx && part.armExidx->isLive())1667for (InputSection *sec : part.armExidx->exidxSections)1668if (sec->isLive())1669scanner.template scanSection<ELFT>(*sec);1670}1671};1672if (serial)1673scanEH();1674else1675tg.spawn(scanEH);1676};1677// If `serial` is true, call `spawn` to ensure that `scanner` runs in a thread1678// with valid getThreadIndex().1679if (serial)1680tg.spawn(outerFn);1681else1682outerFn();1683}16841685static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {1686// Handle a reference to a non-preemptible ifunc. These are special in a1687// few ways:1688//1689// - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have1690// a fixed value. But assuming that all references to the ifunc are1691// GOT-generating or PLT-generating, the handling of an ifunc is1692// relatively straightforward. We create a PLT entry in Iplt, which is1693// usually at the end of .plt, which makes an indirect call using a1694// matching GOT entry in igotPlt, which is usually at the end of .got.plt.1695// The GOT entry is relocated using an IRELATIVE relocation in relaDyn,1696// which is usually at the end of .rela.dyn.1697//1698// - Despite the fact that an ifunc does not have a fixed value, compilers1699// that are not passed -fPIC will assume that they do, and will emit1700// direct (non-GOT-generating, non-PLT-generating) relocations to the1701// symbol. This means that if a direct relocation to the symbol is1702// seen, the linker must set a value for the symbol, and this value must1703// be consistent no matter what type of reference is made to the symbol.1704// This can be done by creating a PLT entry for the symbol in the way1705// described above and making it canonical, that is, making all references1706// point to the PLT entry instead of the resolver. In lld we also store1707// the address of the PLT entry in the dynamic symbol table, which means1708// that the symbol will also have the same value in other modules.1709// Because the value loaded from the GOT needs to be consistent with1710// the value computed using a direct relocation, a non-preemptible ifunc1711// may end up with two GOT entries, one in .got.plt that points to the1712// address returned by the resolver and is used only by the PLT entry,1713// and another in .got that points to the PLT entry and is used by1714// GOT-generating relocations.1715//1716// - The fact that these symbols do not have a fixed value makes them an1717// exception to the general rule that a statically linked executable does1718// not require any form of dynamic relocation. To handle these relocations1719// correctly, the IRELATIVE relocations are stored in an array which a1720// statically linked executable's startup code must enumerate using the1721// linker-defined symbols __rela?_iplt_{start,end}.1722if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt)1723return false;1724// Skip unreferenced non-preemptible ifunc.1725if (!(flags & (NEEDS_GOT | NEEDS_PLT | HAS_DIRECT_RELOC)))1726return true;17271728sym.isInIplt = true;17291730// Create an Iplt and the associated IRELATIVE relocation pointing to the1731// original section/value pairs. For non-GOT non-PLT relocation case below, we1732// may alter section/value, so create a copy of the symbol to make1733// section/value fixed.1734//1735// Prior to Android V, there was a bug that caused RELR relocations to be1736// applied after packed relocations. This meant that resolvers referenced by1737// IRELATIVE relocations in the packed relocation section would read1738// unrelocated globals with RELR relocations when1739// --pack-relative-relocs=android+relr is enabled. Work around this by placing1740// IRELATIVE in .rela.plt.1741auto *directSym = makeDefined(cast<Defined>(sym));1742directSym->allocateAux();1743auto &dyn = config->androidPackDynRelocs ? *in.relaPlt : *mainPart->relaDyn;1744addPltEntry(*in.iplt, *in.igotPlt, dyn, target->iRelativeRel, *directSym);1745sym.allocateAux();1746symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx;17471748if (flags & HAS_DIRECT_RELOC) {1749// Change the value to the IPLT and redirect all references to it.1750auto &d = cast<Defined>(sym);1751d.section = in.iplt.get();1752d.value = d.getPltIdx() * target->ipltEntrySize;1753d.size = 0;1754// It's important to set the symbol type here so that dynamic loaders1755// don't try to call the PLT as if it were an ifunc resolver.1756d.type = STT_FUNC;17571758if (flags & NEEDS_GOT)1759addGotEntry(sym);1760} else if (flags & NEEDS_GOT) {1761// Redirect GOT accesses to point to the Igot.1762sym.gotInIgot = true;1763}1764return true;1765}17661767void elf::postScanRelocations() {1768auto fn = [](Symbol &sym) {1769auto flags = sym.flags.load(std::memory_order_relaxed);1770if (handleNonPreemptibleIfunc(sym, flags))1771return;17721773if (sym.isTagged() && sym.isDefined())1774mainPart->memtagGlobalDescriptors->addSymbol(sym);17751776if (!sym.needsDynReloc())1777return;1778sym.allocateAux();17791780if (flags & NEEDS_GOT)1781addGotEntry(sym);1782if (flags & NEEDS_PLT)1783addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym);1784if (flags & NEEDS_COPY) {1785if (sym.isObject()) {1786invokeELFT(addCopyRelSymbol, cast<SharedSymbol>(sym));1787// NEEDS_COPY is cleared for sym and its aliases so that in1788// later iterations aliases won't cause redundant copies.1789assert(!sym.hasFlag(NEEDS_COPY));1790} else {1791assert(sym.isFunc() && sym.hasFlag(NEEDS_PLT));1792if (!sym.isDefined()) {1793replaceWithDefined(sym, *in.plt,1794target->pltHeaderSize +1795target->pltEntrySize * sym.getPltIdx(),17960);1797sym.setFlags(NEEDS_COPY);1798if (config->emachine == EM_PPC) {1799// PPC32 canonical PLT entries are at the beginning of .glink1800cast<Defined>(sym).value = in.plt->headerSize;1801in.plt->headerSize += 16;1802cast<PPC32GlinkSection>(*in.plt).canonical_plts.push_back(&sym);1803}1804}1805}1806}18071808if (!sym.isTls())1809return;1810bool isLocalInExecutable = !sym.isPreemptible && !config->shared;1811GotSection *got = in.got.get();18121813if (flags & NEEDS_TLSDESC) {1814got->addTlsDescEntry(sym);1815mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(1816target->tlsDescRel, *got, got->getTlsDescOffset(sym), sym,1817target->tlsDescRel);1818}1819if (flags & NEEDS_TLSGD) {1820got->addDynTlsEntry(sym);1821uint64_t off = got->getGlobalDynOffset(sym);1822if (isLocalInExecutable)1823// Write one to the GOT slot.1824got->addConstant({R_ADDEND, target->symbolicRel, off, 1, &sym});1825else1826mainPart->relaDyn->addSymbolReloc(target->tlsModuleIndexRel, *got, off,1827sym);18281829// If the symbol is preemptible we need the dynamic linker to write1830// the offset too.1831uint64_t offsetOff = off + config->wordsize;1832if (sym.isPreemptible)1833mainPart->relaDyn->addSymbolReloc(target->tlsOffsetRel, *got, offsetOff,1834sym);1835else1836got->addConstant({R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});1837}1838if (flags & NEEDS_TLSGD_TO_IE) {1839got->addEntry(sym);1840mainPart->relaDyn->addSymbolReloc(target->tlsGotRel, *got,1841sym.getGotOffset(), sym);1842}1843if (flags & NEEDS_GOT_DTPREL) {1844got->addEntry(sym);1845got->addConstant(1846{R_ABS, target->tlsOffsetRel, sym.getGotOffset(), 0, &sym});1847}18481849if ((flags & NEEDS_TLSIE) && !(flags & NEEDS_TLSGD_TO_IE))1850addTpOffsetGotEntry(sym);1851};18521853GotSection *got = in.got.get();1854if (ctx.needsTlsLd.load(std::memory_order_relaxed) && got->addTlsIndex()) {1855static Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);1856if (config->shared)1857mainPart->relaDyn->addReloc(1858{target->tlsModuleIndexRel, got, got->getTlsIndexOff()});1859else1860got->addConstant(1861{R_ADDEND, target->symbolicRel, got->getTlsIndexOff(), 1, &dummy});1862}18631864assert(symAux.size() == 1);1865for (Symbol *sym : symtab.getSymbols())1866fn(*sym);18671868// Local symbols may need the aforementioned non-preemptible ifunc and GOT1869// handling. They don't need regular PLT.1870for (ELFFileBase *file : ctx.objectFiles)1871for (Symbol *sym : file->getLocalSymbols())1872fn(*sym);1873}18741875static bool mergeCmp(const InputSection *a, const InputSection *b) {1876// std::merge requires a strict weak ordering.1877if (a->outSecOff < b->outSecOff)1878return true;18791880// FIXME dyn_cast<ThunkSection> is non-null for any SyntheticSection.1881if (a->outSecOff == b->outSecOff && a != b) {1882auto *ta = dyn_cast<ThunkSection>(a);1883auto *tb = dyn_cast<ThunkSection>(b);18841885// Check if Thunk is immediately before any specific Target1886// InputSection for example Mips LA25 Thunks.1887if (ta && ta->getTargetInputSection() == b)1888return true;18891890// Place Thunk Sections without specific targets before1891// non-Thunk Sections.1892if (ta && !tb && !ta->getTargetInputSection())1893return true;1894}18951896return false;1897}18981899// Call Fn on every executable InputSection accessed via the linker script1900// InputSectionDescription::Sections.1901static void forEachInputSectionDescription(1902ArrayRef<OutputSection *> outputSections,1903llvm::function_ref<void(OutputSection *, InputSectionDescription *)> fn) {1904for (OutputSection *os : outputSections) {1905if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))1906continue;1907for (SectionCommand *bc : os->commands)1908if (auto *isd = dyn_cast<InputSectionDescription>(bc))1909fn(os, isd);1910}1911}19121913// Thunk Implementation1914//1915// Thunks (sometimes called stubs, veneers or branch islands) are small pieces1916// of code that the linker inserts inbetween a caller and a callee. The thunks1917// are added at link time rather than compile time as the decision on whether1918// a thunk is needed, such as the caller and callee being out of range, can only1919// be made at link time.1920//1921// It is straightforward to tell given the current state of the program when a1922// thunk is needed for a particular call. The more difficult part is that1923// the thunk needs to be placed in the program such that the caller can reach1924// the thunk and the thunk can reach the callee; furthermore, adding thunks to1925// the program alters addresses, which can mean more thunks etc.1926//1927// In lld we have a synthetic ThunkSection that can hold many Thunks.1928// The decision to have a ThunkSection act as a container means that we can1929// more easily handle the most common case of a single block of contiguous1930// Thunks by inserting just a single ThunkSection.1931//1932// The implementation of Thunks in lld is split across these areas1933// Relocations.cpp : Framework for creating and placing thunks1934// Thunks.cpp : The code generated for each supported thunk1935// Target.cpp : Target specific hooks that the framework uses to decide when1936// a thunk is used1937// Synthetic.cpp : Implementation of ThunkSection1938// Writer.cpp : Iteratively call framework until no more Thunks added1939//1940// Thunk placement requirements:1941// Mips LA25 thunks. These must be placed immediately before the callee section1942// We can assume that the caller is in range of the Thunk. These are modelled1943// by Thunks that return the section they must precede with1944// getTargetInputSection().1945//1946// ARM interworking and range extension thunks. These thunks must be placed1947// within range of the caller. All implemented ARM thunks can always reach the1948// callee as they use an indirect jump via a register that has no range1949// restrictions.1950//1951// Thunk placement algorithm:1952// For Mips LA25 ThunkSections; the placement is explicit, it has to be before1953// getTargetInputSection().1954//1955// For thunks that must be placed within range of the caller there are many1956// possible choices given that the maximum range from the caller is usually1957// much larger than the average InputSection size. Desirable properties include:1958// - Maximize reuse of thunks by multiple callers1959// - Minimize number of ThunkSections to simplify insertion1960// - Handle impact of already added Thunks on addresses1961// - Simple to understand and implement1962//1963// In lld for the first pass, we pre-create one or more ThunkSections per1964// InputSectionDescription at Target specific intervals. A ThunkSection is1965// placed so that the estimated end of the ThunkSection is within range of the1966// start of the InputSectionDescription or the previous ThunkSection. For1967// example:1968// InputSectionDescription1969// Section 01970// ...1971// Section N1972// ThunkSection 01973// Section N + 11974// ...1975// Section N + K1976// Thunk Section 11977//1978// The intention is that we can add a Thunk to a ThunkSection that is well1979// spaced enough to service a number of callers without having to do a lot1980// of work. An important principle is that it is not an error if a Thunk cannot1981// be placed in a pre-created ThunkSection; when this happens we create a new1982// ThunkSection placed next to the caller. This allows us to handle the vast1983// majority of thunks simply, but also handle rare cases where the branch range1984// is smaller than the target specific spacing.1985//1986// The algorithm is expected to create all the thunks that are needed in a1987// single pass, with a small number of programs needing a second pass due to1988// the insertion of thunks in the first pass increasing the offset between1989// callers and callees that were only just in range.1990//1991// A consequence of allowing new ThunkSections to be created outside of the1992// pre-created ThunkSections is that in rare cases calls to Thunks that were in1993// range in pass K, are out of range in some pass > K due to the insertion of1994// more Thunks in between the caller and callee. When this happens we retarget1995// the relocation back to the original target and create another Thunk.19961997// Remove ThunkSections that are empty, this should only be the initial set1998// precreated on pass 0.19992000// Insert the Thunks for OutputSection OS into their designated place2001// in the Sections vector, and recalculate the InputSection output section2002// offsets.2003// This may invalidate any output section offsets stored outside of InputSection2004void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {2005forEachInputSectionDescription(2006outputSections, [&](OutputSection *os, InputSectionDescription *isd) {2007if (isd->thunkSections.empty())2008return;20092010// Remove any zero sized precreated Thunks.2011llvm::erase_if(isd->thunkSections,2012[](const std::pair<ThunkSection *, uint32_t> &ts) {2013return ts.first->getSize() == 0;2014});20152016// ISD->ThunkSections contains all created ThunkSections, including2017// those inserted in previous passes. Extract the Thunks created this2018// pass and order them in ascending outSecOff.2019std::vector<ThunkSection *> newThunks;2020for (std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections)2021if (ts.second == pass)2022newThunks.push_back(ts.first);2023llvm::stable_sort(newThunks,2024[](const ThunkSection *a, const ThunkSection *b) {2025return a->outSecOff < b->outSecOff;2026});20272028// Merge sorted vectors of Thunks and InputSections by outSecOff2029SmallVector<InputSection *, 0> tmp;2030tmp.reserve(isd->sections.size() + newThunks.size());20312032std::merge(isd->sections.begin(), isd->sections.end(),2033newThunks.begin(), newThunks.end(), std::back_inserter(tmp),2034mergeCmp);20352036isd->sections = std::move(tmp);2037});2038}20392040static int64_t getPCBias(RelType type) {2041if (config->emachine != EM_ARM)2042return 0;2043switch (type) {2044case R_ARM_THM_JUMP19:2045case R_ARM_THM_JUMP24:2046case R_ARM_THM_CALL:2047return 4;2048default:2049return 8;2050}2051}20522053// Find or create a ThunkSection within the InputSectionDescription (ISD) that2054// is in range of Src. An ISD maps to a range of InputSections described by a2055// linker script section pattern such as { .text .text.* }.2056ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os,2057InputSection *isec,2058InputSectionDescription *isd,2059const Relocation &rel,2060uint64_t src) {2061// See the comment in getThunk for -pcBias below.2062const int64_t pcBias = getPCBias(rel.type);2063for (std::pair<ThunkSection *, uint32_t> tp : isd->thunkSections) {2064ThunkSection *ts = tp.first;2065uint64_t tsBase = os->addr + ts->outSecOff - pcBias;2066uint64_t tsLimit = tsBase + ts->getSize();2067if (target->inBranchRange(rel.type, src,2068(src > tsLimit) ? tsBase : tsLimit))2069return ts;2070}20712072// No suitable ThunkSection exists. This can happen when there is a branch2073// with lower range than the ThunkSection spacing or when there are too2074// many Thunks. Create a new ThunkSection as close to the InputSection as2075// possible. Error if InputSection is so large we cannot place ThunkSection2076// anywhere in Range.2077uint64_t thunkSecOff = isec->outSecOff;2078if (!target->inBranchRange(rel.type, src,2079os->addr + thunkSecOff + rel.addend)) {2080thunkSecOff = isec->outSecOff + isec->getSize();2081if (!target->inBranchRange(rel.type, src,2082os->addr + thunkSecOff + rel.addend))2083fatal("InputSection too large for range extension thunk " +2084isec->getObjMsg(src - (os->addr + isec->outSecOff)));2085}2086return addThunkSection(os, isd, thunkSecOff);2087}20882089// Add a Thunk that needs to be placed in a ThunkSection that immediately2090// precedes its Target.2091ThunkSection *ThunkCreator::getISThunkSec(InputSection *isec) {2092ThunkSection *ts = thunkedSections.lookup(isec);2093if (ts)2094return ts;20952096// Find InputSectionRange within Target Output Section (TOS) that the2097// InputSection (IS) that we need to precede is in.2098OutputSection *tos = isec->getParent();2099for (SectionCommand *bc : tos->commands) {2100auto *isd = dyn_cast<InputSectionDescription>(bc);2101if (!isd || isd->sections.empty())2102continue;21032104InputSection *first = isd->sections.front();2105InputSection *last = isd->sections.back();21062107if (isec->outSecOff < first->outSecOff || last->outSecOff < isec->outSecOff)2108continue;21092110ts = addThunkSection(tos, isd, isec->outSecOff);2111thunkedSections[isec] = ts;2112return ts;2113}21142115return nullptr;2116}21172118// Create one or more ThunkSections per OS that can be used to place Thunks.2119// We attempt to place the ThunkSections using the following desirable2120// properties:2121// - Within range of the maximum number of callers2122// - Minimise the number of ThunkSections2123//2124// We follow a simple but conservative heuristic to place ThunkSections at2125// offsets that are multiples of a Target specific branch range.2126// For an InputSectionDescription that is smaller than the range, a single2127// ThunkSection at the end of the range will do.2128//2129// For an InputSectionDescription that is more than twice the size of the range,2130// we place the last ThunkSection at range bytes from the end of the2131// InputSectionDescription in order to increase the likelihood that the2132// distance from a thunk to its target will be sufficiently small to2133// allow for the creation of a short thunk.2134void ThunkCreator::createInitialThunkSections(2135ArrayRef<OutputSection *> outputSections) {2136uint32_t thunkSectionSpacing = target->getThunkSectionSpacing();21372138forEachInputSectionDescription(2139outputSections, [&](OutputSection *os, InputSectionDescription *isd) {2140if (isd->sections.empty())2141return;21422143uint32_t isdBegin = isd->sections.front()->outSecOff;2144uint32_t isdEnd =2145isd->sections.back()->outSecOff + isd->sections.back()->getSize();2146uint32_t lastThunkLowerBound = -1;2147if (isdEnd - isdBegin > thunkSectionSpacing * 2)2148lastThunkLowerBound = isdEnd - thunkSectionSpacing;21492150uint32_t isecLimit;2151uint32_t prevIsecLimit = isdBegin;2152uint32_t thunkUpperBound = isdBegin + thunkSectionSpacing;21532154for (const InputSection *isec : isd->sections) {2155isecLimit = isec->outSecOff + isec->getSize();2156if (isecLimit > thunkUpperBound) {2157addThunkSection(os, isd, prevIsecLimit);2158thunkUpperBound = prevIsecLimit + thunkSectionSpacing;2159}2160if (isecLimit > lastThunkLowerBound)2161break;2162prevIsecLimit = isecLimit;2163}2164addThunkSection(os, isd, isecLimit);2165});2166}21672168ThunkSection *ThunkCreator::addThunkSection(OutputSection *os,2169InputSectionDescription *isd,2170uint64_t off) {2171auto *ts = make<ThunkSection>(os, off);2172ts->partition = os->partition;2173if ((config->fixCortexA53Errata843419 || config->fixCortexA8) &&2174!isd->sections.empty()) {2175// The errata fixes are sensitive to addresses modulo 4 KiB. When we add2176// thunks we disturb the base addresses of sections placed after the thunks2177// this makes patches we have generated redundant, and may cause us to2178// generate more patches as different instructions are now in sensitive2179// locations. When we generate more patches we may force more branches to2180// go out of range, causing more thunks to be generated. In pathological2181// cases this can cause the address dependent content pass not to converge.2182// We fix this by rounding up the size of the ThunkSection to 4KiB, this2183// limits the insertion of a ThunkSection on the addresses modulo 4 KiB,2184// which means that adding Thunks to the section does not invalidate2185// errata patches for following code.2186// Rounding up the size to 4KiB has consequences for code-size and can2187// trip up linker script defined assertions. For example the linux kernel2188// has an assertion that what LLD represents as an InputSectionDescription2189// does not exceed 4 KiB even if the overall OutputSection is > 128 Mib.2190// We use the heuristic of rounding up the size when both of the following2191// conditions are true:2192// 1.) The OutputSection is larger than the ThunkSectionSpacing. This2193// accounts for the case where no single InputSectionDescription is2194// larger than the OutputSection size. This is conservative but simple.2195// 2.) The InputSectionDescription is larger than 4 KiB. This will prevent2196// any assertion failures that an InputSectionDescription is < 4 KiB2197// in size.2198uint64_t isdSize = isd->sections.back()->outSecOff +2199isd->sections.back()->getSize() -2200isd->sections.front()->outSecOff;2201if (os->size > target->getThunkSectionSpacing() && isdSize > 4096)2202ts->roundUpSizeForErrata = true;2203}2204isd->thunkSections.push_back({ts, pass});2205return ts;2206}22072208static bool isThunkSectionCompatible(InputSection *source,2209SectionBase *target) {2210// We can't reuse thunks in different loadable partitions because they might2211// not be loaded. But partition 1 (the main partition) will always be loaded.2212if (source->partition != target->partition)2213return target->partition == 1;2214return true;2215}22162217std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,2218Relocation &rel, uint64_t src) {2219std::vector<Thunk *> *thunkVec = nullptr;2220// Arm and Thumb have a PC Bias of 8 and 4 respectively, this is cancelled2221// out in the relocation addend. We compensate for the PC bias so that2222// an Arm and Thumb relocation to the same destination get the same keyAddend,2223// which is usually 0.2224const int64_t pcBias = getPCBias(rel.type);2225const int64_t keyAddend = rel.addend + pcBias;22262227// We use a ((section, offset), addend) pair to find the thunk position if2228// possible so that we create only one thunk for aliased symbols or ICFed2229// sections. There may be multiple relocations sharing the same (section,2230// offset + addend) pair. We may revert the relocation back to its original2231// non-Thunk target, so we cannot fold offset + addend.2232if (auto *d = dyn_cast<Defined>(rel.sym))2233if (!d->isInPlt() && d->section)2234thunkVec = &thunkedSymbolsBySectionAndAddend[{{d->section, d->value},2235keyAddend}];2236if (!thunkVec)2237thunkVec = &thunkedSymbols[{rel.sym, keyAddend}];22382239// Check existing Thunks for Sym to see if they can be reused2240for (Thunk *t : *thunkVec)2241if (isThunkSectionCompatible(isec, t->getThunkTargetSym()->section) &&2242t->isCompatibleWith(*isec, rel) &&2243target->inBranchRange(rel.type, src,2244t->getThunkTargetSym()->getVA(-pcBias)))2245return std::make_pair(t, false);22462247// No existing compatible Thunk in range, create a new one2248Thunk *t = addThunk(*isec, rel);2249thunkVec->push_back(t);2250return std::make_pair(t, true);2251}22522253// Return true if the relocation target is an in range Thunk.2254// Return false if the relocation is not to a Thunk. If the relocation target2255// was originally to a Thunk, but is no longer in range we revert the2256// relocation back to its original non-Thunk target.2257bool ThunkCreator::normalizeExistingThunk(Relocation &rel, uint64_t src) {2258if (Thunk *t = thunks.lookup(rel.sym)) {2259if (target->inBranchRange(rel.type, src, rel.sym->getVA(rel.addend)))2260return true;2261rel.sym = &t->destination;2262rel.addend = t->addend;2263if (rel.sym->isInPlt())2264rel.expr = toPlt(rel.expr);2265}2266return false;2267}22682269// Process all relocations from the InputSections that have been assigned2270// to InputSectionDescriptions and redirect through Thunks if needed. The2271// function should be called iteratively until it returns false.2272//2273// PreConditions:2274// All InputSections that may need a Thunk are reachable from2275// OutputSectionCommands.2276//2277// All OutputSections have an address and all InputSections have an offset2278// within the OutputSection.2279//2280// The offsets between caller (relocation place) and callee2281// (relocation target) will not be modified outside of createThunks().2282//2283// PostConditions:2284// If return value is true then ThunkSections have been inserted into2285// OutputSections. All relocations that needed a Thunk based on the information2286// available to createThunks() on entry have been redirected to a Thunk. Note2287// that adding Thunks changes offsets between caller and callee so more Thunks2288// may be required.2289//2290// If return value is false then no more Thunks are needed, and createThunks has2291// made no changes. If the target requires range extension thunks, currently2292// ARM, then any future change in offset between caller and callee risks a2293// relocation out of range error.2294bool ThunkCreator::createThunks(uint32_t pass,2295ArrayRef<OutputSection *> outputSections) {2296this->pass = pass;2297bool addressesChanged = false;22982299if (pass == 0 && target->getThunkSectionSpacing())2300createInitialThunkSections(outputSections);23012302// Create all the Thunks and insert them into synthetic ThunkSections. The2303// ThunkSections are later inserted back into InputSectionDescriptions.2304// We separate the creation of ThunkSections from the insertion of the2305// ThunkSections as ThunkSections are not always inserted into the same2306// InputSectionDescription as the caller.2307forEachInputSectionDescription(2308outputSections, [&](OutputSection *os, InputSectionDescription *isd) {2309for (InputSection *isec : isd->sections)2310for (Relocation &rel : isec->relocs()) {2311uint64_t src = isec->getVA(rel.offset);23122313// If we are a relocation to an existing Thunk, check if it is2314// still in range. If not then Rel will be altered to point to its2315// original target so another Thunk can be generated.2316if (pass > 0 && normalizeExistingThunk(rel, src))2317continue;23182319if (!target->needsThunk(rel.expr, rel.type, isec->file, src,2320*rel.sym, rel.addend))2321continue;23222323Thunk *t;2324bool isNew;2325std::tie(t, isNew) = getThunk(isec, rel, src);23262327if (isNew) {2328// Find or create a ThunkSection for the new Thunk2329ThunkSection *ts;2330if (auto *tis = t->getTargetInputSection())2331ts = getISThunkSec(tis);2332else2333ts = getISDThunkSec(os, isec, isd, rel, src);2334ts->addThunk(t);2335thunks[t->getThunkTargetSym()] = t;2336}23372338// Redirect relocation to Thunk, we never go via the PLT to a Thunk2339rel.sym = t->getThunkTargetSym();2340rel.expr = fromPlt(rel.expr);23412342// On AArch64 and PPC, a jump/call relocation may be encoded as2343// STT_SECTION + non-zero addend, clear the addend after2344// redirection.2345if (config->emachine != EM_MIPS)2346rel.addend = -getPCBias(rel.type);2347}23482349for (auto &p : isd->thunkSections)2350addressesChanged |= p.first->assignOffsets();2351});23522353for (auto &p : thunkedSections)2354addressesChanged |= p.second->assignOffsets();23552356// Merge all created synthetic ThunkSections back into OutputSection2357mergeThunks(outputSections);2358return addressesChanged;2359}23602361// The following aid in the conversion of call x@GDPLT to call __tls_get_addr2362// hexagonNeedsTLSSymbol scans for relocations would require a call to2363// __tls_get_addr.2364// hexagonTLSSymbolUpdate rebinds the relocation to __tls_get_addr.2365bool elf::hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections) {2366bool needTlsSymbol = false;2367forEachInputSectionDescription(2368outputSections, [&](OutputSection *os, InputSectionDescription *isd) {2369for (InputSection *isec : isd->sections)2370for (Relocation &rel : isec->relocs())2371if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {2372needTlsSymbol = true;2373return;2374}2375});2376return needTlsSymbol;2377}23782379void elf::hexagonTLSSymbolUpdate(ArrayRef<OutputSection *> outputSections) {2380Symbol *sym = symtab.find("__tls_get_addr");2381if (!sym)2382return;2383bool needEntry = true;2384forEachInputSectionDescription(2385outputSections, [&](OutputSection *os, InputSectionDescription *isd) {2386for (InputSection *isec : isd->sections)2387for (Relocation &rel : isec->relocs())2388if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {2389if (needEntry) {2390sym->allocateAux();2391addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel,2392*sym);2393needEntry = false;2394}2395rel.sym = sym;2396}2397});2398}23992400static bool matchesRefTo(const NoCrossRefCommand &cmd, StringRef osec) {2401if (cmd.toFirst)2402return cmd.outputSections[0] == osec;2403return llvm::is_contained(cmd.outputSections, osec);2404}24052406template <class ELFT, class Rels>2407static void scanCrossRefs(const NoCrossRefCommand &cmd, OutputSection *osec,2408InputSection *sec, Rels rels) {2409for (const auto &r : rels) {2410Symbol &sym = sec->file->getSymbol(r.getSymbol(config->isMips64EL));2411// A legal cross-reference is when the destination output section is2412// nullptr, osec for a self-reference, or a section that is described by the2413// NOCROSSREFS/NOCROSSREFS_TO command.2414auto *dstOsec = sym.getOutputSection();2415if (!dstOsec || dstOsec == osec || !matchesRefTo(cmd, dstOsec->name))2416continue;24172418std::string toSymName;2419if (!sym.isSection())2420toSymName = toString(sym);2421else if (auto *d = dyn_cast<Defined>(&sym))2422toSymName = d->section->name;2423errorOrWarn(sec->getLocation(r.r_offset) +2424": prohibited cross reference from '" + osec->name + "' to '" +2425toSymName + "' in '" + dstOsec->name + "'");2426}2427}24282429// For each output section described by at least one NOCROSSREFS(_TO) command,2430// scan relocations from its input sections for prohibited cross references.2431template <class ELFT> void elf::checkNoCrossRefs() {2432for (OutputSection *osec : outputSections) {2433for (const NoCrossRefCommand &noxref : script->noCrossRefs) {2434if (!llvm::is_contained(noxref.outputSections, osec->name) ||2435(noxref.toFirst && noxref.outputSections[0] == osec->name))2436continue;2437for (SectionCommand *cmd : osec->commands) {2438auto *isd = dyn_cast<InputSectionDescription>(cmd);2439if (!isd)2440continue;2441parallelForEach(isd->sections, [&](InputSection *sec) {2442invokeOnRelocs(*sec, scanCrossRefs<ELFT>, noxref, osec, sec);2443});2444}2445}2446}2447}24482449template void elf::scanRelocations<ELF32LE>();2450template void elf::scanRelocations<ELF32BE>();2451template void elf::scanRelocations<ELF64LE>();2452template void elf::scanRelocations<ELF64BE>();24532454template void elf::checkNoCrossRefs<ELF32LE>();2455template void elf::checkNoCrossRefs<ELF32BE>();2456template void elf::checkNoCrossRefs<ELF64LE>();2457template void elf::checkNoCrossRefs<ELF64BE>();245824592460