Lines Matching +full:riscv +full:- +full:v +full:- +full:spec

1 //===- Relocations.cpp ----------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains platform-independent functions to process relocations.
28 // - create GOT/PLT entries
29 // - create new relocations in .dynsym to let the dynamic linker resolve
31 // relocations can be resolved at link-time)
32 // - create COPY relocs and reserve space in .bss
33 // - replace expensive relocs (in terms of runtime cost) with cheap ones
34 // - error out infeasible combinations such as PIC and non-relative relocs
41 //===----------------------------------------------------------------------===//
69 for (SectionCommand *cmd : script->sectionCommands) in getLinkerScriptLocation()
71 if (assign->sym == &sym) in getLinkerScriptLocation()
72 return assign->location; in getLinkerScriptLocation()
99 void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v, in reportRangeError() argument
104 if (!rel.sym->isSection()) in reportRangeError()
107 hint = ("; references section '" + d->section->name + "'").str(); in reportRangeError()
109 if (config->emachine == EM_X86_64 && rel.type == R_X86_64_PC32 && in reportRangeError()
110 rel.sym->getOutputSection() && in reportRangeError()
111 (rel.sym->getOutputSection()->flags & SHF_X86_64_LARGE)) { in reportRangeError()
118 if (rel.sym && !rel.sym->isSection()) in reportRangeError()
121 if (errPlace.isec && errPlace.isec->name.starts_with(".debug")) in reportRangeError()
122 hint += "; consider recompiling with -fdebug-types-section to reduce size " in reportRangeError()
126 " out of range: " + v.str() + " is not in [" + Twine(min).str() + in reportRangeError()
130 void elf::reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, in reportRangeError() argument
137 errorOrWarn(errPlace.loc + msg + " is out of range: " + Twine(v) + in reportRangeError()
154 // 64-bit mask. Then we decide which mask to test depending on the value of
155 // expr and use a simple shift and bitwise-and to test for membership.
158 "RelExpr is too large for 128-bit mask!"); in oneof()
161 return (uint64_t(1) << (expr - 64)) & buildMask((Exprs - 64)...); in oneof()
190 // True if non-preemptable symbol always has the same value regardless of where
196 return dr->section == nullptr; // Absolute symbol. in isAbsolute()
218 // True if this expression is of the form Sym - X, where X is a position in the
266 // Returns true if a given shared symbol is in a read-only segment in a DSO.
270 // Determine if the symbol is read-only by scanning the DSO's program headers. in isReadOnly()
304 // non-default version symbols. If ss has a non-default version, ret won't in getSymbolsAt()
305 // contain ss. Just add ss unconditionally. If a non-default version alias is in getSymbolsAt()
338 // but if you violate that implicit ABI, that can cause very counter-
341 // So, what is the copy relocation? It's for linking non-position
344 // are compiled as non-PIC, all data references are direct. There is no
350 // to a specified address (which is usually in .bss) at load-time. If the
366 // variable of type T. It is an ABI-breaking change to add new members at
372 // debug. What's a solution? Instead of exporting a variable V from a DSO,
375 // Copy relocation against zero-sized symbol doesn't make sense. in addCopyRelSymbol()
380 // See if this symbol is in a read-only segment. If so, preserve the symbol's in addCopyRelSymbol()
385 OutputSection *osec = (isRO ? in.bssRelRo : in.bss)->getParent(); in addCopyRelSymbol()
389 if (osec->commands.empty() || in addCopyRelSymbol()
390 !isa<InputSectionDescription>(osec->commands.back())) in addCopyRelSymbol()
391 osec->commands.push_back(make<InputSectionDescription>("")); in addCopyRelSymbol()
392 auto *isd = cast<InputSectionDescription>(osec->commands.back()); in addCopyRelSymbol()
393 isd->sections.push_back(sec); in addCopyRelSymbol()
394 osec->commitSection(sec); in addCopyRelSymbol()
400 replaceWithDefined(*sym, *sec, 0, sym->size); in addCopyRelSymbol()
402 mainPart->relaDyn->addSymbolReloc(target->copyRel, *sec, 0, ss); in addCopyRelSymbol()
422 cies = eh->cies; in OffsetGetter()
423 fdes = eh->fdes; in OffsetGetter()
436 while (j != fdes.end() && j->inputOff <= off) in get()
439 if (j == fdes.begin() || j[-1].inputOff + j[-1].size <= off) { in get()
440 while (i != cies.end() && i->inputOff <= off) in get()
442 if (i == cies.begin() || i[-1].inputOff + i[-1].size <= off) in get()
447 // Offset -1 means that the piece is dead (i.e. garbage collected). in get()
448 if (it[-1].outputOff == -1) in get()
449 return -1; in get()
450 return it[-1].outputOff + (off - it[-1].inputOff); in get()
493 return sec->getFile<ELFT>()->mipsGp0; in computeMipsAddend()
496 // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf in computeMipsAddend()
501 RelType type = rel.getType(config->isMips64EL); in computeMipsAddend()
506 const uint8_t *buf = sec->content().data(); in computeMipsAddend()
507 uint32_t symIndex = rel.getSymbol(config->isMips64EL); in computeMipsAddend()
512 if (ri->getType(config->isMips64EL) == pairTy && in computeMipsAddend()
513 ri->getSymbol(config->isMips64EL) == symIndex) in computeMipsAddend()
514 return target->getImplicitAddend(buf + ri->r_offset, pairTy); in computeMipsAddend()
528 file->template getELFShdrs<ELFT>(); in maybeReportDiscarded()
534 file->getObj().getSectionName(objSections[sym.discardedSecIdx]), file); in maybeReportDiscarded()
541 Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1]; in maybeReportDiscarded()
546 StringRef signature = file->getShtGroupSignature(objSections, elfSec); in maybeReportDiscarded()
553 "binding and the symbol in a non-prevailing group had STB_GLOBAL " in maybeReportDiscarded()
601 if (sym.file && sym.file->kind() == InputFile::ObjKind) { in getAlternativeSpelling()
606 file->getSections()[sym.discardedSecIdx] == &InputSection::discarded) in getAlternativeSpelling()
610 for (const Symbol *s : sym.file->getSymbols()) in getAlternativeSpelling()
611 if (s->isLocal() && s->isDefined() && !s->getName().empty()) in getAlternativeSpelling()
612 map.try_emplace(s->getName(), s); in getAlternativeSpelling()
615 auto suggest = [&](StringRef newName) -> const Symbol * { in getAlternativeSpelling()
622 if (!s->isUndefined()) in getAlternativeSpelling()
629 // correction candidates and suggests the one that exists as a non-undefined in getAlternativeSpelling()
671 if (!sym->isUndefined() && name.equals_insensitive(sym->getName())) in getAlternativeSpelling()
697 if (canSuggestExternCForCXX(name, sym->getName())) { in getAlternativeSpelling()
715 auto visibility = [&]() -> std::string { in reportUndefinedSymbol()
729 switch (config->ekind) { in reportUndefinedSymbol()
768 msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times") in reportUndefinedSymbol()
776 if (corrected->file) in reportUndefinedSymbol()
777 msg += "\n>>> defined in: " + toString(corrected->file); in reportUndefinedSymbol()
785 if (config->gcSections && config->zStartStopGC && in reportUndefinedSymbol()
788 "--gc-sections properly; consider -z nostart-stop-gc " in reportUndefinedSymbol()
789 "(see https://lld.llvm.org/ELF/start-stop-gc)"; in reportUndefinedSymbol()
805 canon->locs.push_back(undef.locs[0]); in reportUndefinedSymbols()
833 if (config->unresolvedSymbols == UnresolvedPolicy::Ignore && canBeExternal) in maybeReportUndefined()
836 // clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc in maybeReportUndefined()
839 // spec says references from outside the group to a STB_LOCAL symbol are not in maybeReportUndefined()
843 // because .LC0-.LTOC is not representable if the two labels are in different in maybeReportUndefined()
849 (config->unresolvedSymbols == UnresolvedPolicy::Warn && canBeExternal) || in maybeReportUndefined()
850 config->noinhibitExec; in maybeReportUndefined()
859 // theirs types into the single bit-set.
863 uint64_t offset = rel->r_offset; in getMipsN32RelType()
866 while (rel != static_cast<const RelTy *>(end) && rel->r_offset == offset) in getMipsN32RelType()
867 type |= (rel++)->getType(config->isMips64EL) << (8 * n++); in getMipsN32RelType()
879 part.relaDyn->addRelativeReloc(target->relativeRel, isec, offsetInSec, sym, in addRelativeReloc()
881 // With MTE globals, we always want to derive the address tag by `ldg`-ing in addRelativeReloc()
884 // puts the result of the RELATIVE relocation out-of-bounds of the symbol in addRelativeReloc()
888 …// https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended- in addRelativeReloc()
903 part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back( in addRelativeReloc()
904 {&isec, isec.relocs().size() - 1}); in addRelativeReloc()
906 part.relrDyn->relocs.push_back({&isec, isec.relocs().size() - 1}); in addRelativeReloc()
909 part.relaDyn->addRelativeReloc<shard>(target->relativeRel, isec, offsetInSec, in addRelativeReloc()
925 in.got->addEntry(sym); in addGotEntry()
930 mainPart->relaDyn->addReloc({target->gotRel, in.got.get(), off, in addGotEntry()
935 // Otherwise, the value is either a link-time constant or the load base in addGotEntry()
937 if (!config->isPic || isAbsolute(sym)) in addGotEntry()
938 in.got->addConstant({R_ABS, target->symbolicRel, off, 0, &sym}); in addGotEntry()
940 addRelativeReloc(*in.got, off, sym, 0, R_ABS, target->symbolicRel); in addGotEntry()
944 in.got->addEntry(sym); in addTpOffsetGotEntry()
946 if (!sym.isPreemptible && !config->shared) { in addTpOffsetGotEntry()
947 in.got->addConstant({R_TPREL, target->symbolicRel, off, 0, &sym}); in addTpOffsetGotEntry()
950 mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible( in addTpOffsetGotEntry()
951 target->tlsGotRel, *in.got, off, sym, target->symbolicRel); in addTpOffsetGotEntry()
969 return ((sym.isFunc() && config->ignoreFunctionAddressEquality) || in canDefineSymbolInExecutable()
970 (sym.isObject() && config->ignoreDataAddressEquality)); in canDefineSymbolInExecutable()
973 // Returns true if a given relocation can be computed at link-time.
977 // link-time if the relocation is PC-relative and refers a
978 // non-interposable function in the same executable. This function
982 // dynamic relocation so that the relocation will be fixed at load-time.
999 return target->usesOnlyLowPageBits(type) || !config->isPic; in isStaticLinkTimeConstant()
1004 if (!config->isPic) in isStaticLinkTimeConstant()
1007 // Constant when referencing a non-preemptible symbol. in isStaticLinkTimeConstant()
1020 return target->usesOnlyLowPageBits(type); in isStaticLinkTimeConstant()
1057 // If non-ifunc non-preemptible, change PLT to direct call and optimize GOT in processAux()
1060 if (!sym.isPreemptible && (!isIfunc || config->zIfuncNoplt)) { in processAux()
1064 if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL) in processAux()
1067 // call __tls_get_addr even if the symbol is non-preemptible. in processAux()
1068 if (!(config->emachine == EM_HEXAGON && in processAux()
1075 target->adjustGotPcExpr(type, addend, sec->content().data() + offset); in processAux()
1079 in.got->hasGotOffRel.store(true, std::memory_order_relaxed); in processAux()
1085 if (LLVM_UNLIKELY(isIfunc) && config->zIfuncNoplt) { in processAux()
1088 mainPart->relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type); in processAux()
1093 if (config->emachine == EM_MIPS) { in processAux()
1100 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf in processAux()
1101 in.mipsGot->addEntry(*sec->file, sym, addend, expr); in processAux()
1102 } else if (!sym.isTls() || config->emachine != EM_LOONGARCH) { in processAux()
1113 // If the relocation is known to be a link-time constant, we know no dynamic in processAux()
1118 // non-link-time constants, we resolve relocations statically (let in processAux()
1119 // relocate{,Non}Alloc() resolve them) for -no-pie and try producing dynamic in processAux()
1120 // relocations for -pie and -shared. in processAux()
1122 // The general expectation of -no-pie static linking is that there is no in processAux()
1124 // -shared matches the spirit of its -z undefs default. -pie has freedom on in processAux()
1126 // handling of GOT-generating relocations. in processAux()
1128 (!config->isPic && sym.isUndefWeak())) { in processAux()
1129 sec->addReloc({expr, type, offset, addend, &sym}); in processAux()
1133 // Use a simple -z notext rule that treats all sections except .eh_frame as in processAux()
1139 bool canWrite = (sec->flags & SHF_WRITE) || in processAux()
1140 !(config->zText || in processAux()
1141 (isa<EhInputSection>(sec) && config->emachine != EM_MIPS)); in processAux()
1143 RelType rel = target->getDynRel(type); in processAux()
1145 (rel == target->symbolicRel && !sym.isPreemptible)) { in processAux()
1150 if (config->emachine == EM_MIPS && rel == target->symbolicRel) in processAux()
1151 rel = target->relativeRel; in processAux()
1153 Partition &part = sec->getPartition(); in processAux()
1154 if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) { in processAux()
1156 // undefined symbol, we can't compute offset at link-time and use a in processAux()
1159 part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type); in processAux()
1160 } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0) { in processAux()
1164 sec->addReloc({expr, type, offset, addend, &sym}); in processAux()
1165 part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1}); in processAux()
1167 part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, in processAux()
1173 part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type); in processAux()
1180 // creation explicitly, i.e. do not have any GOT-relocations. So if in processAux()
1183 // If a non-preemptible symbol has a dynamic relocation against it, in processAux()
1189 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 in processAux()
1190 if (config->emachine == EM_MIPS) in processAux()
1191 in.mipsGot->addEntry(*sec->file, sym, addend, expr); in processAux()
1200 if (!config->shared && sym.isShared() && in processAux()
1201 !(config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) { in processAux()
1211 if (!config->zCopyreloc) in processAux()
1214 "'; recompile with -fPIC or remove '-z nocopyreloc'" + in processAux()
1218 sec->addReloc({expr, type, offset, addend, &sym}); in processAux()
1246 // compiled without -fPIE/-fPIC and doesn't maintain ebx. in processAux()
1250 if (config->pie && config->emachine == EM_386) in processAux()
1252 "' cannot be preempted; recompile with -fPIE" + in processAux()
1255 sec->addReloc({expr, type, offset, addend, &sym}); in processAux()
1263 "; recompile with -fPIC" + getLocation(*sec, sym, offset)); in processAux()
1276 in.mipsGot->addTlsIndex(*c.file); in handleMipsTlsRelocation()
1281 in.mipsGot->addDynTlsEntry(*c.file, sym); in handleMipsTlsRelocation()
1291 // Index (Used to find pointer to TLS block at run-time) GOT[e1] Offset of
1299 if (config->shared) { in handleTlsRelocation()
1301 " cannot be used with -shared" + getLocation(c, sym, offset)); in handleTlsRelocation()
1307 if (config->emachine == EM_MIPS) in handleTlsRelocation()
1312 if (config->emachine == EM_LOONGARCH && in handleTlsRelocation()
1322 bool isRISCV = config->emachine == EM_RISCV; in handleTlsRelocation()
1326 config->shared) { in handleTlsRelocation()
1337 // ARM, Hexagon, LoongArch and RISC-V do not support GD/LD to IE/LE in handleTlsRelocation()
1339 // RISC-V supports TLSDESC to IE/LE optimizations. in handleTlsRelocation()
1343 !config->shared && config->emachine != EM_ARM && in handleTlsRelocation()
1344 config->emachine != EM_HEXAGON && config->emachine != EM_LOONGARCH && in handleTlsRelocation()
1346 !c.file->ppc64DisableTLSRelax; in handleTlsRelocation()
1348 // If we are producing an executable and the symbol is non-preemptable, it in handleTlsRelocation()
1349 // must be defined and the code sequence can be optimized to use Local-Exec. in handleTlsRelocation()
1351 // ARM and RISC-V do not support any relaxations for TLS relocations, however, in handleTlsRelocation()
1355 bool isLocalInExecutable = !sym.isPreemptible && !config->shared; in handleTlsRelocation()
1362 // Local-Dynamic relocs can be optimized to Local-Exec. in handleTlsRelocation()
1364 c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE), type, in handleTlsRelocation()
1366 return target->getTlsGdRelaxSkip(type); in handleTlsRelocation()
1375 // Local-Dynamic relocs can be optimized to Local-Exec. in handleTlsRelocation()
1378 expr = target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE); in handleTlsRelocation()
1383 // Local-Dynamic sequence where offset of tls variable relative to dynamic in handleTlsRelocation()
1385 // Local-Exec. in handleTlsRelocation()
1401 // Global-Dynamic/TLSDESC can be optimized to Initial-Exec or Local-Exec in handleTlsRelocation()
1404 // R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a non-preemptible in handleTlsRelocation()
1406 // the categorization in RISCV::relocateAlloc. in handleTlsRelocation()
1409 c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type, in handleTlsRelocation()
1412 c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE), type, in handleTlsRelocation()
1415 return target->getTlsGdRelaxSkip(type); in handleTlsRelocation()
1421 // Initial-Exec relocs can be optimized to Local-Exec if the symbol is in handleTlsRelocation()
1423 if (execOptimize && isLocalInExecutable && config->emachine != EM_S390) { in handleTlsRelocation()
1428 if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type)) in handleTlsRelocation()
1442 uint32_t symIndex = rel.getSymbol(config->isMips64EL); in scanOne()
1443 Symbol &sym = sec->getFile<ELFT>()->getSymbol(symIndex); in scanOne()
1446 type = rel.getType(config->isMips64EL); in scanOne()
1450 if (config->mipsN32Abi) { in scanOne()
1453 type = rel.getType(config->isMips64EL); in scanOne()
1459 if (offset == uint64_t(-1)) in scanOne()
1462 RelExpr expr = target->getRelExpr(type, sym, sec->content().data() + offset); in scanOne()
1465 : target->getImplicitAddend( in scanOne()
1466 sec->content().data() + rel.r_offset, type); in scanOne()
1467 if (LLVM_UNLIKELY(config->emachine == EM_MIPS)) in scanOne()
1469 else if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC) in scanOne()
1482 if (config->emachine == EM_PPC64) { in scanOne()
1488 // have got-based small code model relocs. The .toc sections get placed in scanOne()
1492 sec->file->ppc64SmallCodeModelTocRelocs = true; in scanOne()
1497 cast<Defined>(sym).section->name == ".toc") in scanOne()
1512 // Offset the 4-byte aligned R_PPC64_TLSGD by one byte in the NOTOC in scanOne()
1513 // case, so we can discern it later from the toc-case. in scanOne()
1514 if (i->getType(/*isMips64EL=*/false) == R_PPC64_REL24_NOTOC) in scanOne()
1522 // The 5 types that relative GOTPLT are all x86 and x86-64 specific. in scanOne()
1525 in.gotPlt->hasGotPltOffRel.store(true, std::memory_order_relaxed); in scanOne()
1528 in.got->hasGotOffRel.store(true, std::memory_order_relaxed); in scanOne()
1534 // Some RISCV TLSDESC relocations reference a local NOTYPE symbol, in scanOne()
1539 i += processed - 1; in scanOne()
1555 if (!sec.file || sec.file->ppc64DisableTLSRelax) in checkPPC64TLSRelax()
1577 sec.file->ppc64DisableTLSRelax = true; in checkPPC64TLSRelax()
1586 // Not all relocations end up in Sec->Relocations, but a lot do. in scan()
1587 sec->relocations.reserve(rels.size()); in scan()
1589 if (config->emachine == EM_PPC64) in scan()
1596 // relaxation to be handled correctly - see SystemZ::getTlsGdRelaxSkip. in scan()
1598 if (isa<EhInputSection>(sec) || config->emachine == EM_S390) in scan()
1605 // The non-CREL code path has additional check for PPC64 TLS. in scan()
1613 if (config->emachine == EM_RISCV || in scan()
1614 (config->emachine == EM_PPC64 && sec->name == ".toc")) in scan()
1615 llvm::stable_sort(sec->relocs(), in scan()
1637 // copy relocations, etc. Note that relocations for non-alloc sections are in scanRelocations()
1641 // for -z nocombreloc. MIPS and PPC64 use global states which are not suitable in scanRelocations()
1643 bool serial = !config->zCombreloc || config->emachine == EM_MIPS || in scanRelocations()
1644 config->emachine == EM_PPC64; in scanRelocations()
1650 for (InputSectionBase *s : f->getSections()) { in scanRelocations()
1651 if (s && s->kind() == SectionBase::Regular && s->isLive() && in scanRelocations()
1652 (s->flags & SHF_ALLOC) && in scanRelocations()
1653 !(s->type == SHT_ARM_EXIDX && config->emachine == EM_ARM)) in scanRelocations()
1665 for (EhInputSection *sec : part.ehFrame->sections) in scanRelocations()
1667 if (part.armExidx && part.armExidx->isLive()) in scanRelocations()
1668 for (InputSection *sec : part.armExidx->exidxSections) in scanRelocations()
1669 if (sec->isLive()) in scanRelocations()
1687 // Handle a reference to a non-preemptible ifunc. These are special in a in handleNonPreemptibleIfunc()
1690 // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have in handleNonPreemptibleIfunc()
1692 // GOT-generating or PLT-generating, the handling of an ifunc is in handleNonPreemptibleIfunc()
1699 // - Despite the fact that an ifunc does not have a fixed value, compilers in handleNonPreemptibleIfunc()
1700 // that are not passed -fPIC will assume that they do, and will emit in handleNonPreemptibleIfunc()
1701 // direct (non-GOT-generating, non-PLT-generating) relocations to the in handleNonPreemptibleIfunc()
1711 // the value computed using a direct relocation, a non-preemptible ifunc in handleNonPreemptibleIfunc()
1715 // GOT-generating relocations. in handleNonPreemptibleIfunc()
1717 // - The fact that these symbols do not have a fixed value makes them an in handleNonPreemptibleIfunc()
1722 // linker-defined symbols __rela?_iplt_{start,end}. in handleNonPreemptibleIfunc()
1723 if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt) in handleNonPreemptibleIfunc()
1725 // Skip unreferenced non-preemptible ifunc. in handleNonPreemptibleIfunc()
1732 // original section/value pairs. For non-GOT non-PLT relocation case below, we in handleNonPreemptibleIfunc()
1736 // Prior to Android V, there was a bug that caused RELR relocations to be in handleNonPreemptibleIfunc()
1740 // --pack-relative-relocs=android+relr is enabled. Work around this by placing in handleNonPreemptibleIfunc()
1743 directSym->allocateAux(); in handleNonPreemptibleIfunc()
1744 auto &dyn = config->androidPackDynRelocs ? *in.relaPlt : *mainPart->relaDyn; in handleNonPreemptibleIfunc()
1745 addPltEntry(*in.iplt, *in.igotPlt, dyn, target->iRelativeRel, *directSym); in handleNonPreemptibleIfunc()
1747 symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx; in handleNonPreemptibleIfunc()
1753 d.value = d.getPltIdx() * target->ipltEntrySize; in handleNonPreemptibleIfunc()
1775 mainPart->memtagGlobalDescriptors->addSymbol(sym); in postScanRelocations()
1784 addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym); in postScanRelocations()
1795 target->pltHeaderSize + in postScanRelocations()
1796 target->pltEntrySize * sym.getPltIdx(), in postScanRelocations()
1799 if (config->emachine == EM_PPC) { in postScanRelocations()
1801 cast<Defined>(sym).value = in.plt->headerSize; in postScanRelocations()
1802 in.plt->headerSize += 16; in postScanRelocations()
1811 bool isLocalInExecutable = !sym.isPreemptible && !config->shared; in postScanRelocations()
1815 got->addTlsDescEntry(sym); in postScanRelocations()
1816 mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible( in postScanRelocations()
1817 target->tlsDescRel, *got, got->getTlsDescOffset(sym), sym, in postScanRelocations()
1818 target->tlsDescRel); in postScanRelocations()
1821 got->addDynTlsEntry(sym); in postScanRelocations()
1822 uint64_t off = got->getGlobalDynOffset(sym); in postScanRelocations()
1825 got->addConstant({R_ADDEND, target->symbolicRel, off, 1, &sym}); in postScanRelocations()
1827 mainPart->relaDyn->addSymbolReloc(target->tlsModuleIndexRel, *got, off, in postScanRelocations()
1832 uint64_t offsetOff = off + config->wordsize; in postScanRelocations()
1834 mainPart->relaDyn->addSymbolReloc(target->tlsOffsetRel, *got, offsetOff, in postScanRelocations()
1837 got->addConstant({R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym}); in postScanRelocations()
1840 got->addEntry(sym); in postScanRelocations()
1841 mainPart->relaDyn->addSymbolReloc(target->tlsGotRel, *got, in postScanRelocations()
1845 got->addEntry(sym); in postScanRelocations()
1846 got->addConstant( in postScanRelocations()
1847 {R_ABS, target->tlsOffsetRel, sym.getGotOffset(), 0, &sym}); in postScanRelocations()
1855 if (ctx.needsTlsLd.load(std::memory_order_relaxed) && got->addTlsIndex()) { in postScanRelocations()
1857 if (config->shared) in postScanRelocations()
1858 mainPart->relaDyn->addReloc( in postScanRelocations()
1859 {target->tlsModuleIndexRel, got, got->getTlsIndexOff()}); in postScanRelocations()
1861 got->addConstant( in postScanRelocations()
1862 {R_ADDEND, target->symbolicRel, got->getTlsIndexOff(), 1, &dummy}); in postScanRelocations()
1869 // Local symbols may need the aforementioned non-preemptible ifunc and GOT in postScanRelocations()
1872 for (Symbol *sym : file->getLocalSymbols()) in postScanRelocations()
1878 if (a->outSecOff < b->outSecOff) in mergeCmp()
1881 // FIXME dyn_cast<ThunkSection> is non-null for any SyntheticSection. in mergeCmp()
1882 if (a->outSecOff == b->outSecOff && a != b) { in mergeCmp()
1888 if (ta && ta->getTargetInputSection() == b) in mergeCmp()
1892 // non-Thunk Sections. in mergeCmp()
1893 if (ta && !tb && !ta->getTargetInputSection()) in mergeCmp()
1906 if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) in forEachInputSectionDescription()
1908 for (SectionCommand *bc : os->commands) in forEachInputSectionDescription()
1959 // - Maximize reuse of thunks by multiple callers
1960 // - Minimize number of ThunkSections to simplify insertion
1961 // - Handle impact of already added Thunks on addresses
1962 // - Simple to understand and implement
1964 // In lld for the first pass, we pre-create one or more ThunkSections per
1982 // be placed in a pre-created ThunkSection; when this happens we create a new
1993 // pre-created ThunkSections is that in rare cases calls to Thunks that were in
2008 if (isd->thunkSections.empty()) in mergeThunks()
2012 llvm::erase_if(isd->thunkSections, in mergeThunks()
2014 return ts.first->getSize() == 0; in mergeThunks()
2017 // ISD->ThunkSections contains all created ThunkSections, including in mergeThunks()
2021 for (std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections) in mergeThunks()
2026 return a->outSecOff < b->outSecOff; in mergeThunks()
2031 tmp.reserve(isd->sections.size() + newThunks.size()); in mergeThunks()
2033 std::merge(isd->sections.begin(), isd->sections.end(), in mergeThunks()
2037 isd->sections = std::move(tmp); in mergeThunks()
2042 if (config->emachine != EM_ARM) in getPCBias()
2062 // See the comment in getThunk for -pcBias below. in getISDThunkSec()
2064 for (std::pair<ThunkSection *, uint32_t> tp : isd->thunkSections) { in getISDThunkSec()
2066 uint64_t tsBase = os->addr + ts->outSecOff - pcBias; in getISDThunkSec()
2067 uint64_t tsLimit = tsBase + ts->getSize(); in getISDThunkSec()
2068 if (target->inBranchRange(rel.type, src, in getISDThunkSec()
2078 uint64_t thunkSecOff = isec->outSecOff; in getISDThunkSec()
2079 if (!target->inBranchRange(rel.type, src, in getISDThunkSec()
2080 os->addr + thunkSecOff + rel.addend)) { in getISDThunkSec()
2081 thunkSecOff = isec->outSecOff + isec->getSize(); in getISDThunkSec()
2082 if (!target->inBranchRange(rel.type, src, in getISDThunkSec()
2083 os->addr + thunkSecOff + rel.addend)) in getISDThunkSec()
2085 isec->getObjMsg(src - (os->addr + isec->outSecOff))); in getISDThunkSec()
2099 OutputSection *tos = isec->getParent(); in getISThunkSec()
2100 for (SectionCommand *bc : tos->commands) { in getISThunkSec()
2102 if (!isd || isd->sections.empty()) in getISThunkSec()
2105 InputSection *first = isd->sections.front(); in getISThunkSec()
2106 InputSection *last = isd->sections.back(); in getISThunkSec()
2108 if (isec->outSecOff < first->outSecOff || last->outSecOff < isec->outSecOff) in getISThunkSec()
2111 ts = addThunkSection(tos, isd, isec->outSecOff); in getISThunkSec()
2122 // - Within range of the maximum number of callers
2123 // - Minimise the number of ThunkSections
2137 uint32_t thunkSectionSpacing = target->getThunkSectionSpacing(); in createInitialThunkSections()
2141 if (isd->sections.empty()) in createInitialThunkSections()
2144 uint32_t isdBegin = isd->sections.front()->outSecOff; in createInitialThunkSections()
2146 isd->sections.back()->outSecOff + isd->sections.back()->getSize(); in createInitialThunkSections()
2147 uint32_t lastThunkLowerBound = -1; in createInitialThunkSections()
2148 if (isdEnd - isdBegin > thunkSectionSpacing * 2) in createInitialThunkSections()
2149 lastThunkLowerBound = isdEnd - thunkSectionSpacing; in createInitialThunkSections()
2155 for (const InputSection *isec : isd->sections) { in createInitialThunkSections()
2156 isecLimit = isec->outSecOff + isec->getSize(); in createInitialThunkSections()
2173 ts->partition = os->partition; in addThunkSection()
2174 if ((config->fixCortexA53Errata843419 || config->fixCortexA8) && in addThunkSection()
2175 !isd->sections.empty()) { in addThunkSection()
2187 // Rounding up the size to 4KiB has consequences for code-size and can in addThunkSection()
2199 uint64_t isdSize = isd->sections.back()->outSecOff + in addThunkSection()
2200 isd->sections.back()->getSize() - in addThunkSection()
2201 isd->sections.front()->outSecOff; in addThunkSection()
2202 if (os->size > target->getThunkSectionSpacing() && isdSize > 4096) in addThunkSection()
2203 ts->roundUpSizeForErrata = true; in addThunkSection()
2205 isd->thunkSections.push_back({ts, pass}); in addThunkSection()
2213 if (source->partition != target->partition) in isThunkSectionCompatible()
2214 return target->partition == 1; in isThunkSectionCompatible()
2232 // non-Thunk target, so we cannot fold offset + addend. in getThunk()
2234 if (!d->isInPlt() && d->section) in getThunk()
2235 thunkVec = &thunkedSymbolsBySectionAndAddend[{{d->section, d->value}, in getThunk()
2242 if (isThunkSectionCompatible(isec, t->getThunkTargetSym()->section) && in getThunk()
2243 t->isCompatibleWith(*isec, rel) && in getThunk()
2244 target->inBranchRange(rel.type, src, in getThunk()
2245 t->getThunkTargetSym()->getVA(-pcBias))) in getThunk()
2250 thunkVec->push_back(t); in getThunk()
2257 // relocation back to its original non-Thunk target.
2260 if (target->inBranchRange(rel.type, src, rel.sym->getVA(rel.addend))) in normalizeExistingThunk()
2262 rel.sym = &t->destination; in normalizeExistingThunk()
2263 rel.addend = t->addend; in normalizeExistingThunk()
2264 if (rel.sym->isInPlt()) in normalizeExistingThunk()
2297 this->pass = pass; in createThunks()
2300 if (pass == 0 && target->getThunkSectionSpacing()) in createThunks()
2310 for (InputSection *isec : isd->sections) in createThunks()
2311 for (Relocation &rel : isec->relocs()) { in createThunks()
2312 uint64_t src = isec->getVA(rel.offset); in createThunks()
2320 if (!target->needsThunk(rel.expr, rel.type, isec->file, src, in createThunks()
2331 if (auto *tis = t->getTargetInputSection()) in createThunks()
2335 ts->addThunk(t); in createThunks()
2336 thunks[t->getThunkTargetSym()] = t; in createThunks()
2340 rel.sym = t->getThunkTargetSym(); in createThunks()
2344 // STT_SECTION + non-zero addend, clear the addend after in createThunks()
2346 if (config->emachine != EM_MIPS) in createThunks()
2347 rel.addend = -getPCBias(rel.type); in createThunks()
2350 for (auto &p : isd->thunkSections) in createThunks()
2351 addressesChanged |= p.first->assignOffsets(); in createThunks()
2355 addressesChanged |= p.second->assignOffsets(); in createThunks()
2370 for (InputSection *isec : isd->sections) in hexagonNeedsTLSSymbol()
2371 for (Relocation &rel : isec->relocs()) in hexagonNeedsTLSSymbol()
2372 if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) { in hexagonNeedsTLSSymbol()
2387 for (InputSection *isec : isd->sections) in hexagonTLSSymbolUpdate()
2388 for (Relocation &rel : isec->relocs()) in hexagonTLSSymbolUpdate()
2389 if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) { in hexagonTLSSymbolUpdate()
2391 sym->allocateAux(); in hexagonTLSSymbolUpdate()
2392 addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, in hexagonTLSSymbolUpdate()
2411 Symbol &sym = sec->file->getSymbol(r.getSymbol(config->isMips64EL)); in scanCrossRefs()
2412 // A legal cross-reference is when the destination output section is in scanCrossRefs()
2413 // nullptr, osec for a self-reference, or a section that is described by the in scanCrossRefs()
2416 if (!dstOsec || dstOsec == osec || !matchesRefTo(cmd, dstOsec->name)) in scanCrossRefs()
2423 toSymName = d->section->name; in scanCrossRefs()
2424 errorOrWarn(sec->getLocation(r.r_offset) + in scanCrossRefs()
2425 ": prohibited cross reference from '" + osec->name + "' to '" + in scanCrossRefs()
2426 toSymName + "' in '" + dstOsec->name + "'"); in scanCrossRefs()
2434 for (const NoCrossRefCommand &noxref : script->noCrossRefs) { in checkNoCrossRefs()
2435 if (!llvm::is_contained(noxref.outputSections, osec->name) || in checkNoCrossRefs()
2436 (noxref.toFirst && noxref.outputSections[0] == osec->name)) in checkNoCrossRefs()
2438 for (SectionCommand *cmd : osec->commands) { in checkNoCrossRefs()
2442 parallelForEach(isd->sections, [&](InputSection *sec) { in checkNoCrossRefs()