Lines Matching +full:partitions +full:- +full:table +full:- +full:offset
1 //===- Writer.cpp ---------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
101 if (p->p_type != PT_LOAD) in removeEmptyPTLoad()
103 if (!p->firstSec) in removeEmptyPTLoad()
105 uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr; in removeEmptyPTLoad()
113 if (removed.count(sec->ptLoad)) in removeEmptyPTLoad()
114 sec->ptLoad = nullptr; in removeEmptyPTLoad()
121 for (unsigned part = 2; part != partitions.size() + 1; ++part) { in copySectionsIntoPartitions()
123 if (!(s->flags & SHF_ALLOC) || !s->isLive() || s->type != SHT_NOTE) in copySectionsIntoPartitions()
126 copy->partition = part; in copySectionsIntoPartitions()
130 assert(ctx.ehInputSections[i]->isLive()); in copySectionsIntoPartitions()
132 copy->partition = part; in copySectionsIntoPartitions()
144 if (!s || s->isDefined() || s->isCommon()) in addOptionalRegular()
147 s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, stOther, in addOptionalRegular()
150 s->isUsedInRegularObj = true; in addOptionalRegular()
157 if (config->emachine == EM_MIPS) { in addReservedSymbols()
162 sym->isUsedInRegularObj = true; in addReservedSymbols()
167 // to GOT. Default offset is 0x7ff0. in addReservedSymbols()
169 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf in addReservedSymbols()
172 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between in addReservedSymbols()
178 // pointer. This symbol is used in the code generated by .cpload pseudo-op in addReservedSymbols()
179 // in case of using -mno-shared option. in addReservedSymbols()
180 // https://sourceware.org/ml/binutils/2004-12/msg00094.html in addReservedSymbols()
183 } else if (config->emachine == EM_PPC) { in addReservedSymbols()
187 } else if (config->emachine == EM_PPC64) { in addReservedSymbols()
191 // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which in addReservedSymbols()
194 // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to in addReservedSymbols()
195 // represent the TOC base which is offset by 0x8000 bytes from the start of in addReservedSymbols()
200 (config->emachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_"; in addReservedSymbols()
203 if (s->isDefined()) { in addReservedSymbols()
204 error(toString(s->file) + " cannot redefine linker defined symbol '" + in addReservedSymbols()
210 if (config->emachine == EM_PPC64) in addReservedSymbols()
213 s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN, in addReservedSymbols()
234 if (script->hasSectionsCommand) in addReservedSymbols()
242 ElfSym::end1 = add("end", -1); in addReservedSymbols()
243 ElfSym::end2 = add("_end", -1); in addReservedSymbols()
244 ElfSym::etext1 = add("etext", -1); in addReservedSymbols()
245 ElfSym::etext2 = add("_etext", -1); in addReservedSymbols()
246 ElfSym::edata1 = add("edata", -1); in addReservedSymbols()
247 ElfSym::edata2 = add("_edata", -1); in addReservedSymbols()
252 for (auto [i, sec] : llvm::enumerate(sym.file->getSections())) in demoteDefined()
260 // Eliminate from the symbol table, otherwise we would leave an undefined in demoteDefined()
268 // --no-allow-shlib-undefined diagnostics. Similarly, demote lazy symbols.
277 if (d->section && !d->section->isLive()) in demoteSymbolsAndComputeIsPreemptible()
278 demoteDefined(*d, sectionIndexMap[d->file]); in demoteSymbolsAndComputeIsPreemptible()
281 if (sym->isLazy() || (s && !cast<SharedFile>(s->file)->isNeeded)) { in demoteSymbolsAndComputeIsPreemptible()
282 uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK); in demoteSymbolsAndComputeIsPreemptible()
283 Undefined(ctx.internalFile, sym->getName(), binding, sym->stOther, in demoteSymbolsAndComputeIsPreemptible()
284 sym->type) in demoteSymbolsAndComputeIsPreemptible()
286 sym->versionId = VER_NDX_GLOBAL; in demoteSymbolsAndComputeIsPreemptible()
290 if (config->hasDynSymTab) in demoteSymbolsAndComputeIsPreemptible()
291 sym->isPreemptible = computeIsPreemptible(*sym); in demoteSymbolsAndComputeIsPreemptible()
296 for (SectionCommand *cmd : script->sectionCommands) in findSection()
298 if (osd->osec.name == name && osd->osec.partition == partition) in findSection()
299 return &osd->osec; in findSection()
307 // to the string table, and add entries to .got and .plt. in run()
312 // If --compressed-debug-sections is specified, compress .debug_* sections. in run()
315 sec->maybeCompress<ELFT>(); in run()
317 if (script->hasSectionsCommand) in run()
318 script->allocateHeaders(mainPart->phdrs); in run()
323 for (Partition &part : partitions) in run()
326 if (!config->oFormatBinary) in run()
331 for (Partition &part : partitions) in run()
334 // Handle --print-map(-M)/--Map and --cref. Dump them before checkSections() in run()
339 // Handle --print-memory-usage option. in run()
340 if (config->printMemoryUsage) in run()
341 script->printMemoryUsage(lld::outs()); in run()
343 if (config->checkSections) in run()
357 if (!config->oFormatBinary) { in run()
358 if (config->zSeparate != SeparateSegmentKind::None) in run()
366 // Backfill .note.gnu.build-id section content. This is done at last in run()
372 if (auto e = buffer->commit()) in run()
373 fatal("failed to write output '" + buffer->getPath() + in run()
376 if (!config->cmseOutputLib.empty()) in run()
385 Symbol &sym = file->getRelocTargetSym(rel); in markUsedLocalSymbolsImpl()
394 // With --gc-sections, the field is already filled. in markUsedLocalSymbols()
396 if (config->gcSections) in markUsedLocalSymbols()
400 for (InputSectionBase *s : f->getSections()) { in markUsedLocalSymbols()
404 if (isec->type == SHT_REL) { in markUsedLocalSymbols()
405 markUsedLocalSymbolsImpl(f, isec->getDataAs<typename ELFT::Rel>()); in markUsedLocalSymbols()
406 } else if (isec->type == SHT_RELA) { in markUsedLocalSymbols()
407 markUsedLocalSymbolsImpl(f, isec->getDataAs<typename ELFT::Rela>()); in markUsedLocalSymbols()
408 } else if (isec->type == SHT_CREL) { in markUsedLocalSymbols()
411 for (Elf_Crel_Impl<true> r : RelocsCrel<true>(isec->content_)) { in markUsedLocalSymbols()
412 Symbol &sym = file->getSymbol(r.r_symidx); in markUsedLocalSymbols()
425 // If --emit-reloc or -r is given, preserve symbols referenced by relocations in shouldKeepInSymtab()
427 if (sym.used && config->copyRelocs) in shouldKeepInSymtab()
434 // them to the symbol table from the beginning. in shouldKeepInSymtab()
435 if (config->emachine == EM_ARM && sym.section && in shouldKeepInSymtab()
436 sym.section->type == SHT_ARM_EXIDX) in shouldKeepInSymtab()
439 if (config->discard == DiscardPolicy::None) in shouldKeepInSymtab()
441 if (config->discard == DiscardPolicy::All) in shouldKeepInSymtab()
446 // * --discard-locals is used. in shouldKeepInSymtab()
450 (config->discard == DiscardPolicy::Locals || in shouldKeepInSymtab()
451 (sym.section && (sym.section->flags & SHF_MERGE)))) in shouldKeepInSymtab()
459 SectionBase *sec = d->section; in includeInSymtab()
462 assert(sec->isLive()); in includeInSymtab()
465 return s->getSectionPiece(d->value).live; in includeInSymtab()
468 return b.used || !config->gcSections; in includeInSymtab()
473 // - demote symbols defined relative to /DISCARD/ discarded input sections so
475 // - copy eligible symbols to .symTab
480 for (Symbol *b : file->getLocalSymbols()) { in demoteAndCopyLocalSymbols()
481 assert(b->isLocal() && "should have been caught in initializeSymbols()"); in demoteAndCopyLocalSymbols()
486 if (dr->section && !dr->section->isLive()) in demoteAndCopyLocalSymbols()
489 in.symTab->addSymbol(b); in demoteAndCopyLocalSymbols()
499 for (SectionCommand *cmd : script->sectionCommands) { in addSectionSymbols()
503 OutputSection &osec = osd->osec; in addSectionSymbols()
511 for (InputSectionBase *s : isd->sections) { in addSectionSymbols()
513 if (isStaticRelSecType(s->type)) in addSectionSymbols()
518 // pointing to its contents if -r or --emit-reloc is given. in addSectionSymbols()
519 if (isa<SyntheticSection>(s) && !(s->flags & SHF_MERGE)) in addSectionSymbols()
532 in.symTab->addSymbol(makeDefined(isec->file, "", STB_LOCAL, /*stOther=*/0, in addSectionSymbols()
538 // Today's loaders have a feature to make segments read-only after
545 if (!config->zRelro) in isRelroSection()
547 if (sec->relro) in isRelroSection()
550 uint64_t flags = sec->flags; in isRelroSection()
552 // Non-allocatable or non-writable sections don't need RELRO because in isRelroSection()
554 // RELRO is for sections that are essentially read-only but need to in isRelroSection()
561 // for a thread-local storage. For each new thread, runtime in isRelroSection()
573 uint32_t type = sec->type; in isRelroSection()
581 if (in.got && sec == in.got->getParent()) in isRelroSection()
584 // .toc is a GOT-ish section for PowerPC64. Their contents are accessed in isRelroSection()
589 if (sec->name == ".toc") in isRelroSection()
594 // However, if "-z now" is given, the lazy symbol resolution is in isRelroSection()
596 if (sec == in.gotPlt->getParent()) in isRelroSection()
597 return config->zNow; in isRelroSection()
599 if (in.relroPadding && sec == in.relroPadding->getParent()) in isRelroSection()
605 if (sec->name == ".dynamic") in isRelroSection()
612 StringRef s = sec->name; in isRelroSection()
620 config->osabi == ELFOSABI_OPENBSD && s == ".openbsd.randomdata"; in isRelroSection()
650 // We want to put section specified by -T option first, so we in getSectionRank()
652 if (config->sectionStartMap.count(osec.name)) in getSectionRank()
662 // order: R, RX, RXW, RW(RELRO), RW(non-RELRO). in getSectionRank()
664 // Read-only sections come first such that they go in the PT_LOAD covering the in getSectionRank()
677 // For -z lrodata-after-bss, place .lrodata after .lbss like GNU ld. This in getSectionRank()
679 // pressure for absolute relocations referencing small data from -fno-pic in getSectionRank()
681 if (osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64) in getSectionRank()
682 rank |= config->zLrodataAfterBss ? RF_LARGE_ALT : 0; in getSectionRank()
684 rank |= config->zLrodataAfterBss ? 0 : RF_LARGE; in getSectionRank()
693 // included in a truncate core file. In particular, .note.gnu.build-id, if in getSectionRank()
718 // For -z lrodata-after-bss, place .lbss/.lrodata/.ldata after .bss. in getSectionRank()
720 if (osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64) { in getSectionRank()
721 rank |= config->zLrodataAfterBss in getSectionRank()
727 // Within TLS sections, or within other RelRo sections, or within non-RelRo in getSectionRank()
728 // sections, place non-NOBITS sections first. in getSectionRank()
734 if (config->emachine == EM_PPC64) { in getSectionRank()
737 // their coverage by a single signed 16-bit offset from the TOC base in getSectionRank()
746 if (config->emachine == EM_MIPS) { in getSectionRank()
755 if (config->emachine == EM_RISCV) { in getSectionRank()
768 const OutputSection *a = &cast<OutputDesc>(aCmd)->osec; in compareSections()
769 const OutputSection *b = &cast<OutputDesc>(bCmd)->osec; in compareSections()
771 if (a->sortRank != b->sortRank) in compareSections()
772 return a->sortRank < b->sortRank; in compareSections()
774 if (!(a->sortRank & RF_NOT_ADDR_SET)) in compareSections()
775 return config->sectionStartMap.lookup(a->name) < in compareSections()
776 config->sectionStartMap.lookup(b->name); in compareSections()
784 p_align = std::max(p_align, sec->addralign); in add()
786 sec->ptLoad = this; in add()
789 // A statically linked position-dependent executable should only contain
795 if (config->isPic) in addRelIpltSymbols()
801 std::string name = config->isRela ? "__rela_iplt_start" : "__rel_iplt_start"; in addRelIpltSymbols()
804 name.replace(name.size() - 5, 5, "end"); in addRelIpltSymbols()
818 if (!target->gotBaseSymInGotPlt) in setReservedSymbolSections()
821 ElfSym::globalOffsetTable->section = sec; in setReservedSymbolSections()
825 if (ElfSym::relaIpltStart && mainPart->relaDyn->isNeeded()) { in setReservedSymbolSections()
826 ElfSym::relaIpltStart->section = mainPart->relaDyn.get(); in setReservedSymbolSections()
827 ElfSym::relaIpltEnd->section = mainPart->relaDyn.get(); in setReservedSymbolSections()
828 ElfSym::relaIpltEnd->value = mainPart->relaDyn->getSize(); in setReservedSymbolSections()
834 return config->emachine == EM_X86_64 && osec->flags & SHF_X86_64_LARGE; in setReservedSymbolSections()
836 for (Partition &part : partitions) { in setReservedSymbolSections()
838 if (p->p_type != PT_LOAD) in setReservedSymbolSections()
841 if (!(p->p_flags & PF_W) && p->lastSec && !isLarge(p->lastSec)) in setReservedSymbolSections()
842 lastRO = p->lastSec; in setReservedSymbolSections()
847 // _etext is the first location after the last read-only loadable segment in setReservedSymbolSections()
850 ElfSym::etext1->section = lastRO; in setReservedSymbolSections()
852 ElfSym::etext2->section = lastRO; in setReservedSymbolSections()
856 // _edata points to the end of the last non-large mapped initialized in setReservedSymbolSections()
860 if (os->type != SHT_NOBITS && !isLarge(os)) in setReservedSymbolSections()
862 if (os == last->lastSec) in setReservedSymbolSections()
867 ElfSym::edata1->section = edata; in setReservedSymbolSections()
869 ElfSym::edata2->section = edata; in setReservedSymbolSections()
873 ElfSym::end1->section = last->lastSec; in setReservedSymbolSections()
875 ElfSym::end2->section = last->lastSec; in setReservedSymbolSections()
879 // On RISC-V, set __bss_start to the start of .sbss if present. in setReservedSymbolSections()
881 config->emachine == EM_RISCV ? findSection(".sbss") : nullptr; in setReservedSymbolSections()
882 ElfSym::bss->section = sbss ? sbss : findSection(".bss"); in setReservedSymbolSections()
888 // Find GP-relative section with the lowest address in setReservedSymbolSections()
891 if (os->flags & SHF_MIPS_GPREL) { in setReservedSymbolSections()
892 ElfSym::mipsGp->section = os; in setReservedSymbolSections()
893 ElfSym::mipsGp->value = 0x7ff0; in setReservedSymbolSections()
906 return (osd && osd->osec.hasInputSections) in getRankProximity()
907 ? llvm::countl_zero(a->sortRank ^ osd->osec.sortRank) in getRankProximity()
908 : -1; in getRankProximity()
927 return assign->name != "."; in shouldSkip()
937 // Place non-alloc orphan sections at the end. This matches how we assign file in findOrphanPos()
938 // offsets to non-alloc sections. in findOrphanPos()
939 OutputSection *sec = &cast<OutputDesc>(*e)->osec; in findOrphanPos()
940 if (!(sec->flags & SHF_ALLOC)) in findOrphanPos()
945 if (in.relroPadding && sec == in.relroPadding->getParent()) { in findOrphanPos()
948 return assign->dataSegmentRelroEnd; in findOrphanPos()
956 // value in the range [-1, 32] where [0, 32] indicates potential anchors (0: in findOrphanPos()
957 // least similar; 32: identical). -1 means not an anchor. in findOrphanPos()
966 (p == maxP && cast<OutputDesc>(*j)->osec.sortRank <= sec->sortRank)) { in findOrphanPos()
976 return osd && osd->osec.hasInputSections; in findOrphanPos()
984 // making a read-only segment writable. If memory regions are defined, an in findOrphanPos()
987 bool mustAfter = script->hasPhdrsCommands() || !script->memoryRegions.empty(); in findOrphanPos()
988 if (cast<OutputDesc>(*i)->osec.sortRank <= sec->sortRank || mustAfter) { in findOrphanPos()
997 for (; i != b; --i) in findOrphanPos()
998 if (isOutputSecWithInputSections(i[-1])) in findOrphanPos()
1017 if (config->shuffleSections.empty()) in maybeShuffle()
1022 for (const auto &patAndSeed : config->shuffleSections) { in maybeShuffle()
1025 if (patAndSeed.first.match(sec->name)) in maybeShuffle()
1029 // If --shuffle-sections <section-glob>=-1, reverse the section order. The in maybeShuffle()
1040 if (patAndSeed.first.match(sec->name)) in maybeShuffle()
1053 // Builds section order for handling --symbol-ordering-file.
1056 // Use the rarely used option --call-graph-ordering-file to sort sections. in buildSectionOrder()
1057 if (!config->callGraphProfile.empty()) in buildSectionOrder()
1060 if (config->symbolOrderingFile.empty()) in buildSectionOrder()
1072 int priority = -config->symbolOrderingFile.size(); in buildSectionOrder()
1073 for (StringRef s : config->symbolOrderingFile) in buildSectionOrder()
1081 SymbolOrderEntry &ent = it->second; in buildSectionOrder()
1087 if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section)) { in buildSectionOrder()
1095 // symbol table and iterate the object files for the local ones. in buildSectionOrder()
1100 for (Symbol *sym : file->getLocalSymbols()) in buildSectionOrder()
1103 if (config->warnSymbolOrdering) in buildSectionOrder()
1121 for (InputSection *isec : isd->sections) { in sortISDBySectionOrder()
1123 totalSize += isec->getSize(); in sortISDBySectionOrder()
1127 unorderedSize += isec->getSize(); in sortISDBySectionOrder()
1130 orderedSections.push_back({isec, i->second}); in sortISDBySectionOrder()
1135 // section list. On targets with limited-range branches, this is the mid-point in sortISDBySectionOrder()
1149 // only the first 8-16MB of the cold code (depending on which hot function it in sortISDBySectionOrder()
1157 // both the last 8-16MB of the first block of cold code and the first 8-16MB in sortISDBySectionOrder()
1168 target->getThunkSectionSpacing() && in sortISDBySectionOrder()
1169 totalSize >= target->getThunkSectionSpacing()) { in sortISDBySectionOrder()
1172 unorderedPos += unorderedSections[insPt]->getSize(); in sortISDBySectionOrder()
1178 isd->sections.clear(); in sortISDBySectionOrder()
1180 isd->sections.push_back(isec); in sortISDBySectionOrder()
1182 isd->sections.push_back(p.first); in sortISDBySectionOrder()
1184 isd->sections.push_back(isec); in sortISDBySectionOrder()
1196 // --symbol-ordering-file or --shuffle-sections=. This is a least significant in sortSection()
1204 if (script->hasSectionsCommand) in sortSection()
1211 } else if (config->emachine == EM_PPC64 && name == ".toc") { in sortSection()
1212 // .toc is allocated just after .got and is accessed using GOT-relative in sortSection()
1214 // addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations. in sortSection()
1219 llvm::stable_sort(isd->sections, in sortSection()
1220 [](const InputSection *a, const InputSection *b) -> bool { in sortSection()
1221 return a->file->ppc64SmallCodeModelTocRelocs && in sortSection()
1222 !b->file->ppc64SmallCodeModelTocRelocs; in sortSection()
1228 // sorting for special input sections. This also handles --symbol-ordering-file.
1233 for (SectionCommand *cmd : script->sectionCommands) in sortInputSections()
1235 sortSection(osd->osec, order); in sortInputSections()
1241 // Don't sort if using -r. It is not necessary and we want to preserve the in sortSections()
1243 if (config->relocatable) { in sortSections()
1244 script->adjustOutputSections(); in sortSections()
1250 for (SectionCommand *cmd : script->sectionCommands) in sortSections()
1252 osd->osec.sortRank = getSectionRank(osd->osec); in sortSections()
1253 if (!script->hasSectionsCommand) { in sortSections()
1257 script->sectionCommands.begin(), script->sectionCommands.end(), in sortSections()
1259 std::stable_sort(script->sectionCommands.begin(), mid, compareSections); in sortSections()
1263 // point onwards the order of script->sectionCommands is fixed. in sortSections()
1264 script->processInsertCommands(); in sortSections()
1265 script->adjustOutputSections(); in sortSections()
1267 if (script->hasSectionsCommand) in sortSections()
1270 script->adjustSectionsAfterSorting(); in sortSections()
1313 auto i = script->sectionCommands.begin(); in sortOrphanSections()
1314 auto e = script->sectionCommands.end(); in sortOrphanSections()
1317 return osd->osec.sectionIndex == UINT32_MAX; in sortOrphanSections()
1337 OutputSection *orphan = &cast<OutputDesc>(*nonScriptI)->osec; in sortOrphanSections()
1341 unsigned rank = orphan->sortRank; in sortOrphanSections()
1343 return cast<OutputDesc>(cmd)->osec.sortRank != rank; in sortOrphanSections()
1351 InputSection *la = a->flags & SHF_LINK_ORDER ? a->getLinkOrderDep() : nullptr; in compareByFilePosition()
1352 InputSection *lb = b->flags & SHF_LINK_ORDER ? b->getLinkOrderDep() : nullptr; in compareByFilePosition()
1353 // SHF_LINK_ORDER sections with non-zero sh_link are ordered before in compareByFilePosition()
1354 // non-SHF_LINK_ORDER sections and SHF_LINK_ORDER sections with zero sh_link. in compareByFilePosition()
1357 OutputSection *aOut = la->getParent(); in compareByFilePosition()
1358 OutputSection *bOut = lb->getParent(); in compareByFilePosition()
1361 return la->outSecOff < lb->outSecOff; in compareByFilePosition()
1362 if (aOut->addr == bOut->addr) in compareByFilePosition()
1363 return aOut->sectionIndex < bOut->sectionIndex; in compareByFilePosition()
1364 return aOut->addr < bOut->addr; in compareByFilePosition()
1370 if (!(sec->flags & SHF_LINK_ORDER)) in resolveShfLinkOrder()
1375 if (!config->relocatable && config->emachine == EM_ARM && in resolveShfLinkOrder()
1376 sec->type == SHT_ARM_EXIDX) in resolveShfLinkOrder()
1383 for (SectionCommand *cmd : sec->commands) { in resolveShfLinkOrder()
1390 for (InputSection *&isec : isd->sections) { in resolveShfLinkOrder()
1391 if (isec->flags & SHF_LINK_ORDER) { in resolveShfLinkOrder()
1392 InputSection *link = isec->getLinkOrderDep(); in resolveShfLinkOrder()
1393 if (link && !link->getParent()) in resolveShfLinkOrder()
1411 if (sec && sec->isNeeded() && sec->getParent()) { in finalizeSynthetic()
1412 llvm::TimeTraceScope timeScope("Finalize synthetic sections", sec->name); in finalizeSynthetic()
1413 sec->finalizeContents(); in finalizeSynthetic()
1426 script->assignAddresses(); in finalizeAddressDependentContent()
1434 for (Partition &part : partitions) in finalizeAddressDependentContent()
1441 if (config->emachine == EM_HEXAGON) in finalizeAddressDependentContent()
1446 bool changed = target->needsThunks ? tc.createThunks(pass, outputSections) in finalizeAddressDependentContent()
1447 : target->relaxOnce(pass); in finalizeAddressDependentContent()
1448 bool spilled = script->spillSections(); in finalizeAddressDependentContent()
1455 error(target->needsThunks ? "thunk creation not converged" in finalizeAddressDependentContent()
1460 if (config->fixCortexA53Errata843419) { in finalizeAddressDependentContent()
1462 script->assignAddresses(); in finalizeAddressDependentContent()
1465 if (config->fixCortexA8) { in finalizeAddressDependentContent()
1467 script->assignAddresses(); in finalizeAddressDependentContent()
1473 in.mipsGot->updateAllocSize(); in finalizeAddressDependentContent()
1475 for (Partition &part : partitions) { in finalizeAddressDependentContent()
1484 part.relrAuthDyn->relocs, [&part](const RelativeReloc &elem) { in finalizeAddressDependentContent()
1485 const Relocation &reloc = elem.inputSec->relocs()[elem.relocIdx]; in finalizeAddressDependentContent()
1486 if (isInt<32>(reloc.sym->getVA(reloc.addend))) in finalizeAddressDependentContent()
1488 part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, elem.inputSec, in finalizeAddressDependentContent()
1489 reloc.offset, in finalizeAddressDependentContent()
1494 changed |= (it != part.relrAuthDyn->relocs.end()); in finalizeAddressDependentContent()
1495 part.relrAuthDyn->relocs.erase(it, part.relrAuthDyn->relocs.end()); in finalizeAddressDependentContent()
1498 changed |= part.relaDyn->updateAllocSize(); in finalizeAddressDependentContent()
1500 changed |= part.relrDyn->updateAllocSize(); in finalizeAddressDependentContent()
1502 changed |= part.relrAuthDyn->updateAllocSize(); in finalizeAddressDependentContent()
1504 changed |= part.memtagGlobalDescriptors->updateAllocSize(); in finalizeAddressDependentContent()
1508 script->assignAddresses(); in finalizeAddressDependentContent()
1517 errorOrWarn("address (0x" + Twine::utohexstr(changes.first->addr) + in finalizeAddressDependentContent()
1518 ") of section '" + changes.first->name + in finalizeAddressDependentContent()
1530 if (!config->relocatable) in finalizeAddressDependentContent()
1531 target->finalizeRelax(pass); in finalizeAddressDependentContent()
1533 if (config->relocatable) in finalizeAddressDependentContent()
1535 sec->addr = 0; in finalizeAddressDependentContent()
1538 // Warn because this is error-prone. in finalizeAddressDependentContent()
1539 for (SectionCommand *cmd : script->sectionCommands) in finalizeAddressDependentContent()
1541 OutputSection *osec = &osd->osec; in finalizeAddressDependentContent()
1542 if (osec->addr % osec->addralign != 0) in finalizeAddressDependentContent()
1543 warn("address (0x" + Twine::utohexstr(osec->addr) + ") of section " + in finalizeAddressDependentContent()
1544 osec->name + " is not a multiple of alignment (" + in finalizeAddressDependentContent()
1545 Twine(osec->addralign) + ")"); in finalizeAddressDependentContent()
1550 script->erasePotentialSpillSections(); in finalizeAddressDependentContent()
1559 parallelForEach(File->getSymbols(), [&](Symbol *Sym) { in fixSymbolsAfterShrinking()
1564 const SectionBase *sec = def->section; in fixSymbolsAfterShrinking()
1569 if (!inputSec || !inputSec->bytesDropped) in fixSymbolsAfterShrinking()
1572 const size_t OldSize = inputSec->content().size(); in fixSymbolsAfterShrinking()
1573 const size_t NewSize = OldSize - inputSec->bytesDropped; in fixSymbolsAfterShrinking()
1575 if (def->value > NewSize && def->value <= OldSize) { in fixSymbolsAfterShrinking()
1577 << "Moving symbol " << Sym->getName() << " from " in fixSymbolsAfterShrinking()
1578 << def->value << " to " in fixSymbolsAfterShrinking()
1579 << def->value - inputSec->bytesDropped << " bytes\n"); in fixSymbolsAfterShrinking()
1580 def->value -= inputSec->bytesDropped; in fixSymbolsAfterShrinking()
1584 if (def->value + def->size > NewSize && def->value <= OldSize && in fixSymbolsAfterShrinking()
1585 def->value + def->size <= OldSize) { in fixSymbolsAfterShrinking()
1587 << "Shrinking symbol " << Sym->getName() << " from " in fixSymbolsAfterShrinking()
1588 << def->size << " to " << def->size - inputSec->bytesDropped in fixSymbolsAfterShrinking()
1590 def->size -= inputSec->bytesDropped; in fixSymbolsAfterShrinking()
1598 // relaxation pass does that. It is only enabled when --optimize-bb-jumps
1601 assert(config->optimizeBBJumps); in optimizeBasicBlockJumps()
1604 script->assignAddresses(); in optimizeBasicBlockJumps()
1612 if (!(osec->flags & SHF_EXECINSTR)) in optimizeBasicBlockJumps()
1622 numDeleted += target->deleteFallThruJmpInsn(sec, sec.file, next); in optimizeBasicBlockJumps()
1625 script->assignAddresses(); in optimizeBasicBlockJumps()
1635 is->trim(); in optimizeBasicBlockJumps()
1638 // In order to allow users to manipulate linker-synthesized sections,
1653 // after a non-synthetic one which will be our starting point. in removeUnusedSyntheticSections()
1664 if (sec->getParent() && sec->isNeeded()) in removeUnusedSyntheticSections()
1670 if (config->emachine == EM_AARCH64 && config->relrPackDynRelocs) in removeUnusedSyntheticSections()
1672 if (relSec == mainPart->relaDyn.get()) in removeUnusedSyntheticSections()
1682 if (OutputSection *osec = cast<SyntheticSection>(sec)->getParent()) in removeUnusedSyntheticSections()
1683 for (SectionCommand *cmd : osec->commands) in removeUnusedSyntheticSections()
1685 llvm::erase_if(isd->sections, [&](InputSection *isec) { in removeUnusedSyntheticSections()
1688 llvm::erase_if(script->orphanSections, [&](const InputSectionBase *sec) { in removeUnusedSyntheticSections()
1695 if (!config->relocatable) { in finalizeSections()
1704 for (SectionCommand *cmd : script->sectionCommands) in finalizeSections()
1706 addStartStopSymbols(osd->osec); in finalizeSections()
1711 // https://sourceware.org/ml/binutils/2002-03/msg00360.html in finalizeSections()
1712 if (mainPart->dynamic->parent) { in finalizeSections()
1715 /*value=*/0, /*size=*/0, mainPart->dynamic.get()}); in finalizeSections()
1716 s->isUsedInRegularObj = true; in finalizeSections()
1722 // RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800. This symbol in finalizeSections()
1726 if (config->emachine == EM_RISCV) { in finalizeSections()
1728 if (!config->shared) { in finalizeSections()
1734 if (config->relaxGP) { in finalizeSections()
1736 if (s && s->isDefined()) in finalizeSections()
1742 if (config->emachine == EM_386 || config->emachine == EM_X86_64) { in finalizeSections()
1748 // 2) With LD->LE relaxation: _TLS_MODULE_BASE_@tpoff = 0 (lowest address in finalizeSections()
1755 if (s && s->isUndefined()) { in finalizeSections()
1756 s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, in finalizeSections()
1768 for (Partition &part : partitions) in finalizeSections()
1775 if (config->copyRelocs && config->discard != DiscardPolicy::None) in finalizeSections()
1779 if (config->copyRelocs) in finalizeSections()
1782 // Change values of linker-script-defined symbols from placeholders (assigned in finalizeSections()
1784 script->processSymbolAssignments(); in finalizeSections()
1786 if (!config->relocatable) { in finalizeSections()
1791 // a linker-script-defined symbol is absolute. in finalizeSections()
1797 if (in.plt && in.plt->isNeeded()) in finalizeSections()
1798 in.plt->addSymbols(); in finalizeSections()
1799 if (in.iplt && in.iplt->isNeeded()) in finalizeSections()
1800 in.iplt->addSymbols(); in finalizeSections()
1802 if (config->unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore) { in finalizeSections()
1804 config->unresolvedSymbolsInShlib == UnresolvedPolicy::ReportError in finalizeSections()
1822 llvm::all_of(file->dtNeeded, [&](StringRef needed) { in finalizeSections()
1827 for (Symbol *sym : file->requiredSymbols) { in finalizeSections()
1828 if (sym->dsoDefined) in finalizeSections()
1830 if (sym->isUndefined() && !sym->isWeak()) { in finalizeSections()
1833 " (disallowed by --no-allow-shlib-undefined)"); in finalizeSections()
1834 } else if (sym->isDefined() && sym->computeBinding() == STB_LOCAL) { in finalizeSections()
1835 diagnose("non-exported symbol '" + toString(*sym) + "' in '" + in finalizeSections()
1836 toString(sym->file) + "' is referenced by DSO '" + in finalizeSections()
1846 // Now that we have defined all possible global symbols including linker- in finalizeSections()
1849 if (!sym->isUsedInRegularObj || !includeInSymtab(*sym)) in finalizeSections()
1851 if (!config->relocatable) in finalizeSections()
1852 sym->binding = sym->computeBinding(); in finalizeSections()
1854 in.symTab->addSymbol(sym); in finalizeSections()
1856 if (sym->includeInDynsym()) { in finalizeSections()
1857 partitions[sym->partition - 1].dynSymTab->addSymbol(sym); in finalizeSections()
1858 if (auto *file = dyn_cast_or_null<SharedFile>(sym->file)) in finalizeSections()
1859 if (file->isNeeded && !sym->isUndefined()) in finalizeSections()
1865 // partitions and add any referenced symbols to the partition's dynsym. in finalizeSections()
1866 for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) { in finalizeSections()
1868 for (const SymbolTableEntry &e : part.dynSymTab->getSymbols()) in finalizeSections()
1870 for (DynamicReloc &reloc : part.relaDyn->relocs) in finalizeSections()
1873 part.dynSymTab->addSymbol(reloc.sym); in finalizeSections()
1878 in.mipsGot->build(); in finalizeSections()
1881 script->diagnoseOrphanHandling(); in finalizeSections()
1882 script->diagnoseMissingSGSectionAddress(); in finalizeSections()
1888 for (SectionCommand *cmd : script->sectionCommands) in finalizeSections()
1890 OutputSection *osec = &osd->osec; in finalizeSections()
1892 osec->sectionIndex = outputSections.size(); in finalizeSections()
1893 osec->shName = in.shStrTab->addString(osec->name); in finalizeSections()
1898 auto i = config->sectionStartMap.find(sec->name); in finalizeSections()
1899 if (i != config->sectionStartMap.end()) in finalizeSections()
1900 sec->addrExpr = [=] { return i->second; }; in finalizeSections()
1905 if (config->emachine == EM_HEXAGON && hexagonNeedsTLSSymbol(outputSections)) { in finalizeSections()
1909 sym->isPreemptible = true; in finalizeSections()
1910 partitions[0].dynSymTab->addSymbol(sym); in finalizeSections()
1916 Out::elfHeader->sectionIndex = 1; in finalizeSections()
1917 Out::elfHeader->size = sizeof(typename ELFT::Ehdr); in finalizeSections()
1922 if (!config->relocatable && !config->oFormatBinary) { in finalizeSections()
1923 for (Partition &part : partitions) { in finalizeSections()
1924 part.phdrs = script->hasPhdrsCommands() ? script->createPhdrs() in finalizeSections()
1926 if (config->emachine == EM_ARM) { in finalizeSections()
1930 if (config->emachine == EM_MIPS) { in finalizeSections()
1931 // Add separate segments for MIPS-specific sections. in finalizeSections()
1936 if (config->emachine == EM_RISCV) in finalizeSections()
1940 Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size(); in finalizeSections()
1946 for (PhdrEntry *p : mainPart->phdrs) in finalizeSections()
1947 if (p->p_type == PT_TLS) in finalizeSections()
1955 if (script->noCrossRefs.size()) { in finalizeSections()
1979 // symbol table section (dynSymTab) must be the first one. in finalizeSections()
1980 for (Partition &part : partitions) { in finalizeSections()
1982 part.relaDyn->mergeRels(); in finalizeSections()
1984 part.relaDyn->partitionRels(); in finalizeSections()
1988 part.relrDyn->mergeRels(); in finalizeSections()
1992 part.relrAuthDyn->mergeRels(); in finalizeSections()
2007 if (!script->hasSectionsCommand && !config->relocatable) in finalizeSections()
2013 // they cannot jump to arbitrary addresses in memory. For example, RISC-V in finalizeSections()
2014 // JAL instruction can target only +-1 MiB from PC. It is a linker's in finalizeSections()
2040 // static symbol table. in finalizeSections()
2047 // Relaxation to delete inter-basic block jumps created by basic block in finalizeSections()
2049 // can relax jump instructions based on symbol offset. in finalizeSections()
2050 if (config->optimizeBBJumps) in finalizeSections()
2053 // Fill other section headers. The dynamic table is finalized in finalizeSections()
2057 sec->finalize(); in finalizeSections()
2059 script->checkFinalScriptConditions(); in finalizeSections()
2061 if (config->emachine == EM_ARM && !config->isLE && config->armBe8) { in finalizeSections()
2068 // --execute-only is used. --execute-only make pages executable but not
2071 if (!config->executeOnly) in checkExecuteOnly()
2076 if (osec->flags & SHF_EXECINSTR) in checkExecuteOnly()
2078 if (!(isec->flags & SHF_EXECINSTR)) in checkExecuteOnly()
2080 toString(osec->name) + in checkExecuteOnly()
2081 ": --execute-only does not support intermingling data and code"); in checkExecuteOnly()
2096 Defined *stopSym = addOptionalRegular(end, os, -1); in addStartEndSymbols()
2098 os->usedInExpression = true; in addStartEndSymbols()
2126 config->zStartStopVisibility); in addStartStopSymbols()
2127 Defined *stopSym = addOptionalRegular(saver().save("__stop_" + s), &osec, -1, in addStartStopSymbols()
2128 config->zStartStopVisibility); in addStartStopSymbols()
2134 if (!(sec->flags & SHF_ALLOC)) in needsPtLoad()
2140 if ((sec->flags & SHF_TLS) && sec->type == SHT_NOBITS) in needsPtLoad()
2147 if (config->omagic) in computeFlags()
2149 if (config->executeOnly && (flags & PF_X)) in computeFlags()
2159 auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * { in createPhdrs()
2173 if (!config->nmagic && !config->omagic) { in createPhdrs()
2177 addHdr(PT_PHDR, PF_R)->add(Out::programHeaders); in createPhdrs()
2179 addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent()); in createPhdrs()
2183 addHdr(PT_INTERP, cmd->getPhdrFlags())->add(cmd); in createPhdrs()
2186 // In the other partitions the headers are ordinary sections, so they don't in createPhdrs()
2190 load->add(Out::elfHeader); in createPhdrs()
2191 load->add(Out::programHeaders); in createPhdrs()
2196 // read-only by dynamic linker after processing relocations. in createPhdrs()
2203 if (sec->partition != partNo || !needsPtLoad(sec)) in createPhdrs()
2208 relRo->add(sec); in createPhdrs()
2210 error("section: " + sec->name + " is not contiguous with other relro" + in createPhdrs()
2217 relRo->p_align = 1; in createPhdrs()
2223 // Normally, sections in partitions other than the current partition are in createPhdrs()
2228 // partitions. in createPhdrs()
2229 if (sec->partition != partNo) { in createPhdrs()
2230 if (isMain && sec->partition == 255) in createPhdrs()
2231 addHdr(PT_LOAD, computeFlags(sec->getPhdrFlags()))->add(sec); in createPhdrs()
2246 // not-NOBITS section after a NOBITS, we create a new LOAD for the latter in createPhdrs()
2248 // supposed-to-be-NOBITS section to the output file. (However, we cannot do in createPhdrs()
2251 uint64_t newFlags = computeFlags(sec->getPhdrFlags()); in createPhdrs()
2252 // When --no-rosegment is specified, RO and RX sections are compatible. in createPhdrs()
2254 if (config->singleRoRx && !(newFlags & PF_W)) in createPhdrs()
2260 load && !sec->lmaExpr && sec->lmaRegion == load->firstSec->lmaRegion; in createPhdrs()
2262 sec->memRegion == load->firstSec->memRegion && in createPhdrs()
2263 (sameLMARegion || load->lastSec == Out::programHeaders) && in createPhdrs()
2264 (script->hasSectionsCommand || sec->type == SHT_NOBITS || in createPhdrs()
2265 load->lastSec->type != SHT_NOBITS)) { in createPhdrs()
2266 load->p_flags |= newFlags; in createPhdrs()
2272 load->add(sec); in createPhdrs()
2278 if (sec->partition == partNo && sec->flags & SHF_TLS) in createPhdrs()
2279 tlsHdr->add(sec); in createPhdrs()
2280 if (tlsHdr->firstSec) in createPhdrs()
2284 if (OutputSection *sec = part.dynamic->getParent()) in createPhdrs()
2285 addHdr(PT_DYNAMIC, sec->getPhdrFlags())->add(sec); in createPhdrs()
2287 if (relRo->firstSec) in createPhdrs()
2291 if (part.ehFrame->isNeeded() && part.ehFrameHdr && in createPhdrs()
2292 part.ehFrame->getParent() && part.ehFrameHdr->getParent()) in createPhdrs()
2293 addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags()) in createPhdrs()
2294 ->add(part.ehFrameHdr->getParent()); in createPhdrs()
2296 if (config->osabi == ELFOSABI_OPENBSD) { in createPhdrs()
2300 addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd); in createPhdrs()
2305 addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd); in createPhdrs()
2310 addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd); in createPhdrs()
2313 if (config->zGnustack != GnuStackKind::None) { in createPhdrs()
2315 // pages for the stack non-executable. If you really want an executable in createPhdrs()
2316 // stack, you can pass -z execstack, but that's not recommended for in createPhdrs()
2319 if (config->zGnustack == GnuStackKind::Exec) in createPhdrs()
2321 addHdr(PT_GNU_STACK, perm)->p_memsz = config->zStackSize; in createPhdrs()
2324 // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable in createPhdrs()
2328 if (config->zWxneeded) in createPhdrs()
2332 addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd); in createPhdrs()
2338 if (sec->partition != partNo) in createPhdrs()
2340 if (sec->type == SHT_NOTE && (sec->flags & SHF_ALLOC)) { in createPhdrs()
2341 if (!note || sec->lmaExpr || note->lastSec->addralign != sec->addralign) in createPhdrs()
2343 note->add(sec); in createPhdrs()
2356 return cmd->partition == partNo && cmd->type == shType; in addPhdrForSection()
2362 entry->add(*i); in addPhdrForSection()
2372 OutputSection *cmd = p->firstSec; in fixSectionAlignments()
2375 cmd->alignExpr = [align = cmd->addralign]() { return align; }; in fixSectionAlignments()
2376 if (!cmd->addrExpr) { in fixSectionAlignments()
2380 // When -z separate-code is used we must not have any overlap in pages in fixSectionAlignments()
2381 // between an executable segment and a non-executable segment. We align to in fixSectionAlignments()
2383 // and non-executable segments. in fixSectionAlignments()
2390 if (config->zSeparate == SeparateSegmentKind::Loadable || in fixSectionAlignments()
2391 (config->zSeparate == SeparateSegmentKind::Code && prev && in fixSectionAlignments()
2392 (prev->p_flags & PF_X) != (p->p_flags & PF_X)) || in fixSectionAlignments()
2393 cmd->type == SHT_LLVM_PART_EHDR) in fixSectionAlignments()
2394 cmd->addrExpr = [] { in fixSectionAlignments()
2395 return alignToPowerOf2(script->getDot(), config->maxPageSize); in fixSectionAlignments()
2406 // x86-64) doesn't make runtime address congruent to p_vaddr modulo in fixSectionAlignments()
2410 else if (Out::tlsPhdr && Out::tlsPhdr->firstSec == p->firstSec) in fixSectionAlignments()
2411 cmd->addrExpr = [] { in fixSectionAlignments()
2412 return alignToPowerOf2(script->getDot(), config->maxPageSize) + in fixSectionAlignments()
2413 alignToPowerOf2(script->getDot() % config->maxPageSize, in fixSectionAlignments()
2414 Out::tlsPhdr->p_align); in fixSectionAlignments()
2417 cmd->addrExpr = [] { in fixSectionAlignments()
2418 return alignToPowerOf2(script->getDot(), config->maxPageSize) + in fixSectionAlignments()
2419 script->getDot() % config->maxPageSize; in fixSectionAlignments()
2424 for (Partition &part : partitions) { in fixSectionAlignments()
2427 if (p->p_type == PT_LOAD && p->firstSec) { in fixSectionAlignments()
2434 // Compute an in-file position for a given section. The file offset must be the
2438 // The first section in a PT_LOAD has to have congruent offset and address in computeFileOffset()
2440 if (os->ptLoad && os->ptLoad->firstSec == os) in computeFileOffset()
2441 return alignTo(off, os->ptLoad->p_align, os->addr); in computeFileOffset()
2446 if (os->type == SHT_NOBITS && in computeFileOffset()
2447 (!Out::tlsPhdr || Out::tlsPhdr->firstSec != os)) in computeFileOffset()
2451 if (!os->ptLoad) in computeFileOffset()
2452 return alignToPowerOf2(off, os->addralign); in computeFileOffset()
2454 // If two sections share the same PT_LOAD the file offset is calculated in computeFileOffset()
2455 // using this formula: Off2 = Off1 + (VA2 - VA1). in computeFileOffset()
2456 OutputSection *first = os->ptLoad->firstSec; in computeFileOffset()
2457 return first->offset + os->addr - first->addr; in computeFileOffset()
2461 // Compute the minimum LMA of all non-empty non-NOBITS sections as minAddr. in assignFileOffsetsBinary()
2468 sec->offset = sec->getLMA(); in assignFileOffsetsBinary()
2469 minAddr = std::min(minAddr, sec->offset); in assignFileOffsetsBinary()
2476 sec->offset -= minAddr; in assignFileOffsetsBinary()
2477 fileSize = std::max(fileSize, sec->offset + sec->size); in assignFileOffsetsBinary()
2482 return "[0x" + utohexstr(addr) + ", 0x" + utohexstr(addr + len - 1) + "]"; in rangeToString()
2487 Out::programHeaders->offset = Out::elfHeader->size; in assignFileOffsets()
2488 uint64_t off = Out::elfHeader->size + Out::programHeaders->size; in assignFileOffsets()
2491 for (Partition &part : partitions) in assignFileOffsets()
2493 if (p->p_type == PT_LOAD && (p->p_flags & PF_X)) in assignFileOffsets()
2496 // Layout SHF_ALLOC sections before non-SHF_ALLOC sections. A non-SHF_ALLOC in assignFileOffsets()
2499 if (!(sec->flags & SHF_ALLOC)) in assignFileOffsets()
2502 sec->offset = off; in assignFileOffsets()
2503 if (sec->type != SHT_NOBITS) in assignFileOffsets()
2504 off += sec->size; in assignFileOffsets()
2507 // segment is the last loadable segment, align the offset of the in assignFileOffsets()
2508 // following section to avoid loading non-segments parts of the file. in assignFileOffsets()
2509 if (config->zSeparate != SeparateSegmentKind::None && lastRX && in assignFileOffsets()
2510 lastRX->lastSec == sec) in assignFileOffsets()
2511 off = alignToPowerOf2(off, config->maxPageSize); in assignFileOffsets()
2514 if (osec->flags & SHF_ALLOC) in assignFileOffsets()
2516 osec->offset = alignToPowerOf2(off, osec->addralign); in assignFileOffsets()
2517 off = osec->offset + osec->size; in assignFileOffsets()
2520 sectionHeaderOff = alignToPowerOf2(off, config->wordsize); in assignFileOffsets()
2525 // offset overlaps or overflows. That should never happen with a valid script in assignFileOffsets()
2530 // perform non-critical checks for overlaps in checkSectionOverlap(), but here in assignFileOffsets()
2533 if (sec->type == SHT_NOBITS) in assignFileOffsets()
2535 if ((sec->offset > fileSize) || (sec->offset + sec->size > fileSize)) in assignFileOffsets()
2536 error("unable to place section " + sec->name + " at file offset " + in assignFileOffsets()
2537 rangeToString(sec->offset, sec->size) + in assignFileOffsets()
2546 OutputSection *first = p->firstSec; in setPhdrs()
2547 OutputSection *last = p->lastSec; in setPhdrs()
2552 if (part.armExidx && p->p_type == PT_ARM_EXIDX) { in setPhdrs()
2553 p->p_filesz = part.armExidx->getSize(); in setPhdrs()
2554 p->p_memsz = part.armExidx->getSize(); in setPhdrs()
2555 p->p_offset = first->offset + part.armExidx->outSecOff; in setPhdrs()
2556 p->p_vaddr = first->addr + part.armExidx->outSecOff; in setPhdrs()
2557 p->p_align = part.armExidx->addralign; in setPhdrs()
2559 p->p_offset -= part.elfHeader->getParent()->offset; in setPhdrs()
2561 if (!p->hasLMA) in setPhdrs()
2562 p->p_paddr = first->getLMA() + part.armExidx->outSecOff; in setPhdrs()
2567 p->p_filesz = last->offset - first->offset; in setPhdrs()
2568 if (last->type != SHT_NOBITS) in setPhdrs()
2569 p->p_filesz += last->size; in setPhdrs()
2571 p->p_memsz = last->addr + last->size - first->addr; in setPhdrs()
2572 p->p_offset = first->offset; in setPhdrs()
2573 p->p_vaddr = first->addr; in setPhdrs()
2575 // File offsets in partitions other than the main partition are relative in setPhdrs()
2576 // to the offset of the ELF headers. Perform that adjustment now. in setPhdrs()
2578 p->p_offset -= part.elfHeader->getParent()->offset; in setPhdrs()
2580 if (!p->hasLMA) in setPhdrs()
2581 p->p_paddr = first->getLMA(); in setPhdrs()
2590 uint64_t offset; member
2599 return a.offset < b.offset; in checkOverlap()
2605 SectionOffset a = sections[i - 1]; in checkOverlap()
2607 if (b.offset >= a.offset + a.sec->size) in checkOverlap()
2612 if (isVirtualAddr && a.sec->inOverlay && b.sec->inOverlay) in checkOverlap()
2615 errorOrWarn("section " + a.sec->name + " " + name + in checkOverlap()
2616 " range overlaps with " + b.sec->name + "\n>>> " + a.sec->name + in checkOverlap()
2617 " range is " + rangeToString(a.offset, a.sec->size) + "\n>>> " + in checkOverlap()
2618 b.sec->name + " range is " + in checkOverlap()
2619 rangeToString(b.offset, b.sec->size)); in checkOverlap()
2631 if ((os->addr + os->size < os->addr) || in checkSections()
2632 (!ELFT::Is64Bits && os->addr + os->size > uint64_t(UINT32_MAX) + 1)) in checkSections()
2633 errorOrWarn("section " + os->name + " at 0x" + utohexstr(os->addr) + in checkSections()
2634 " of size 0x" + utohexstr(os->size) + in checkSections()
2639 // the file so Sec->Offset + Sec->Size can overlap with others. If --oformat in checkSections()
2641 // file so we skip any non-allocated sections in that case. in checkSections()
2644 if (sec->size > 0 && sec->type != SHT_NOBITS && in checkSections()
2645 (!config->oFormatBinary || (sec->flags & SHF_ALLOC))) in checkSections()
2646 fileOffs.push_back({sec, sec->offset}); in checkSections()
2649 // When linking with -r there is no need to check for overlapping virtual/load in checkSections()
2652 if (config->relocatable) in checkSections()
2662 if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS)) in checkSections()
2663 vmas.push_back({sec, sec->addr}); in checkSections()
2671 if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS)) in checkSections()
2672 lmas.push_back({sec, sec->getLMA()}); in checkSections()
2678 // 1. the '-e' entry command-line option;
2685 if (Symbol *b = symtab.find(config->entry)) in getEntryAddr()
2686 return b->getVA(); in getEntryAddr()
2690 if (to_integer(config->entry, addr)) in getEntryAddr()
2694 if (config->warnMissingEntry) in getEntryAddr()
2695 warn("cannot find entry symbol " + config->entry + in getEntryAddr()
2701 if (config->isPic) in getELFType()
2703 if (config->relocatable) in getELFType()
2713 eHdr->e_type = getELFType(); in writeHeader()
2714 eHdr->e_entry = getEntryAddr(); in writeHeader()
2715 eHdr->e_shoff = sectionHeaderOff; in writeHeader()
2717 // Write the section header table. in writeHeader()
2726 auto *sHdrs = reinterpret_cast<Elf_Shdr *>(Out::bufferStart + eHdr->e_shoff); in writeHeader()
2729 sHdrs->sh_size = num; in writeHeader()
2731 eHdr->e_shnum = num; in writeHeader()
2733 uint32_t strTabIndex = in.shStrTab->getParent()->sectionIndex; in writeHeader()
2735 sHdrs->sh_link = strTabIndex; in writeHeader()
2736 eHdr->e_shstrndx = SHN_XINDEX; in writeHeader()
2738 eHdr->e_shstrndx = strTabIndex; in writeHeader()
2742 sec->writeHeaderTo<ELFT>(++sHdrs); in writeHeader()
2747 uint64_t maxSize = config->is64 ? INT64_MAX : UINT32_MAX; in openFile()
2754 s << os->name << ' ' << os->size << "\n"; in openFile()
2759 unlinkAsync(config->outputFile); in openFile()
2761 if (!config->relocatable) in openFile()
2763 if (!config->mmapOutputFile) in openFile()
2766 FileOutputBuffer::create(config->outputFile, fileSize, flags); in openFile()
2769 error("failed to open " + config->outputFile + ": " + in openFile()
2774 Out::bufferStart = buffer->getBufferStart(); in openFile()
2780 if (sec->flags & SHF_ALLOC) in writeSectionsBinary()
2781 sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg); in writeSectionsBinary()
2786 memcpy(i, &target->trapInstr, 4); in fillTrap()
2793 // We'll leave other pages in segments as-is because the rest will be
2796 for (Partition &part : partitions) { in writeTrapInstr()
2799 if (p->p_type == PT_LOAD && (p->p_flags & PF_X)) in writeTrapInstr()
2801 alignDown(p->firstSec->offset + p->p_filesz, 4), in writeTrapInstr()
2803 alignToPowerOf2(p->firstSec->offset + p->p_filesz, in writeTrapInstr()
2804 config->maxPageSize)); in writeTrapInstr()
2811 if (p->p_type == PT_LOAD) in writeTrapInstr()
2814 if (last && (last->p_flags & PF_X)) in writeTrapInstr()
2815 last->p_memsz = last->p_filesz = in writeTrapInstr()
2816 alignToPowerOf2(last->p_filesz, config->maxPageSize); in writeTrapInstr()
2825 // In -r or --emit-relocs mode, write the relocation sections first as in in writeSections()
2830 if (isStaticRelSecType(sec->type)) in writeSections()
2831 sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg); in writeSections()
2836 if (!isStaticRelSecType(sec->type)) in writeSections()
2837 sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg); in writeSections()
2841 if (config->checkDynamicRelocs && config->writeAddends) { in writeSections()
2843 if (isStaticRelSecType(sec->type)) in writeSections()
2844 sec->checkDynRelAddends(Out::bufferStart); in writeSections()
2870 if (!mainPart->buildId || !mainPart->buildId->getParent()) in writeBuildId()
2873 if (config->buildId == BuildIdKind::Hexstring) { in writeBuildId()
2874 for (Partition &part : partitions) in writeBuildId()
2875 part.buildId->writeBuildId(config->buildIdVector); in writeBuildId()
2880 size_t hashSize = mainPart->buildId->hashSize; in writeBuildId()
2888 // (second-)preimage and collision resistance. In practice people use 'md5' in writeBuildId()
2891 switch (config->buildId) { in writeBuildId()
2914 for (Partition &part : partitions) in writeBuildId()
2915 part.buildId->writeBuildId(output); in writeBuildId()