Path: blob/main/contrib/llvm-project/lld/ELF/InputFiles.cpp
34869 views
//===- InputFiles.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//===----------------------------------------------------------------------===//78#include "InputFiles.h"9#include "Config.h"10#include "DWARF.h"11#include "Driver.h"12#include "InputSection.h"13#include "LinkerScript.h"14#include "SymbolTable.h"15#include "Symbols.h"16#include "SyntheticSections.h"17#include "Target.h"18#include "lld/Common/CommonLinkerContext.h"19#include "lld/Common/DWARF.h"20#include "llvm/ADT/CachedHashString.h"21#include "llvm/ADT/STLExtras.h"22#include "llvm/LTO/LTO.h"23#include "llvm/Object/IRObjectFile.h"24#include "llvm/Support/ARMAttributeParser.h"25#include "llvm/Support/ARMBuildAttributes.h"26#include "llvm/Support/Endian.h"27#include "llvm/Support/FileSystem.h"28#include "llvm/Support/Path.h"29#include "llvm/Support/RISCVAttributeParser.h"30#include "llvm/Support/TarWriter.h"31#include "llvm/Support/TimeProfiler.h"32#include "llvm/Support/raw_ostream.h"33#include <optional>3435using namespace llvm;36using namespace llvm::ELF;37using namespace llvm::object;38using namespace llvm::sys;39using namespace llvm::sys::fs;40using namespace llvm::support::endian;41using namespace lld;42using namespace lld::elf;4344// This function is explicitly instantiated in ARM.cpp, don't do it here to45// avoid warnings with MSVC.46extern template void ObjFile<ELF32LE>::importCmseSymbols();47extern template void ObjFile<ELF32BE>::importCmseSymbols();48extern template void ObjFile<ELF64LE>::importCmseSymbols();49extern template void ObjFile<ELF64BE>::importCmseSymbols();5051bool InputFile::isInGroup;52uint32_t InputFile::nextGroupId;5354std::unique_ptr<TarWriter> elf::tar;5556// Returns "<internal>", "foo.a(bar.o)" or "baz.o".57std::string lld::toString(const InputFile *f) {58static std::mutex mu;59if (!f)60return "<internal>";6162{63std::lock_guard<std::mutex> lock(mu);64if (f->toStringCache.empty()) {65if (f->archiveName.empty())66f->toStringCache = f->getName();67else68(f->archiveName + "(" + f->getName() + ")").toVector(f->toStringCache);69}70}71return std::string(f->toStringCache);72}7374static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {75unsigned char size;76unsigned char endian;77std::tie(size, endian) = getElfArchType(mb.getBuffer());7879auto report = [&](StringRef msg) {80StringRef filename = mb.getBufferIdentifier();81if (archiveName.empty())82fatal(filename + ": " + msg);83else84fatal(archiveName + "(" + filename + "): " + msg);85};8687if (!mb.getBuffer().starts_with(ElfMagic))88report("not an ELF file");89if (endian != ELFDATA2LSB && endian != ELFDATA2MSB)90report("corrupted ELF file: invalid data encoding");91if (size != ELFCLASS32 && size != ELFCLASS64)92report("corrupted ELF file: invalid file class");9394size_t bufSize = mb.getBuffer().size();95if ((size == ELFCLASS32 && bufSize < sizeof(Elf32_Ehdr)) ||96(size == ELFCLASS64 && bufSize < sizeof(Elf64_Ehdr)))97report("corrupted ELF file: file is too short");9899if (size == ELFCLASS32)100return (endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;101return (endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;102}103104// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD105// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how106// the input objects have been compiled.107static void updateARMVFPArgs(const ARMAttributeParser &attributes,108const InputFile *f) {109std::optional<unsigned> attr =110attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);111if (!attr)112// If an ABI tag isn't present then it is implicitly given the value of 0113// which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,114// including some in glibc that don't use FP args (and should have value 3)115// don't have the attribute so we do not consider an implicit value of 0116// as a clash.117return;118119unsigned vfpArgs = *attr;120ARMVFPArgKind arg;121switch (vfpArgs) {122case ARMBuildAttrs::BaseAAPCS:123arg = ARMVFPArgKind::Base;124break;125case ARMBuildAttrs::HardFPAAPCS:126arg = ARMVFPArgKind::VFP;127break;128case ARMBuildAttrs::ToolChainFPPCS:129// Tool chain specific convention that conforms to neither AAPCS variant.130arg = ARMVFPArgKind::ToolChain;131break;132case ARMBuildAttrs::CompatibleFPAAPCS:133// Object compatible with all conventions.134return;135default:136error(toString(f) + ": unknown Tag_ABI_VFP_args value: " + Twine(vfpArgs));137return;138}139// Follow ld.bfd and error if there is a mix of calling conventions.140if (config->armVFPArgs != arg && config->armVFPArgs != ARMVFPArgKind::Default)141error(toString(f) + ": incompatible Tag_ABI_VFP_args");142else143config->armVFPArgs = arg;144}145146// The ARM support in lld makes some use of instructions that are not available147// on all ARM architectures. Namely:148// - Use of BLX instruction for interworking between ARM and Thumb state.149// - Use of the extended Thumb branch encoding in relocation.150// - Use of the MOVT/MOVW instructions in Thumb Thunks.151// The ARM Attributes section contains information about the architecture chosen152// at compile time. We follow the convention that if at least one input object153// is compiled with an architecture that supports these features then lld is154// permitted to use them.155static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {156std::optional<unsigned> attr =157attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);158if (!attr)159return;160auto arch = *attr;161switch (arch) {162case ARMBuildAttrs::Pre_v4:163case ARMBuildAttrs::v4:164case ARMBuildAttrs::v4T:165// Architectures prior to v5 do not support BLX instruction166break;167case ARMBuildAttrs::v5T:168case ARMBuildAttrs::v5TE:169case ARMBuildAttrs::v5TEJ:170case ARMBuildAttrs::v6:171case ARMBuildAttrs::v6KZ:172case ARMBuildAttrs::v6K:173config->armHasBlx = true;174// Architectures used in pre-Cortex processors do not support175// The J1 = 1 J2 = 1 Thumb branch range extension, with the exception176// of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do.177break;178default:179// All other Architectures have BLX and extended branch encoding180config->armHasBlx = true;181config->armJ1J2BranchEncoding = true;182if (arch != ARMBuildAttrs::v6_M && arch != ARMBuildAttrs::v6S_M)183// All Architectures used in Cortex processors with the exception184// of v6-M and v6S-M have the MOVT and MOVW instructions.185config->armHasMovtMovw = true;186break;187}188189// Only ARMv8-M or later architectures have CMSE support.190std::optional<unsigned> profile =191attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);192if (!profile)193return;194if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base &&195profile == ARMBuildAttrs::MicroControllerProfile)196config->armCMSESupport = true;197198// The thumb PLT entries require Thumb2 which can be used on multiple archs.199// For now, let's limit it to ones where ARM isn't available and we know have200// Thumb2.201std::optional<unsigned> armISA =202attributes.getAttributeValue(ARMBuildAttrs::ARM_ISA_use);203std::optional<unsigned> thumb =204attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);205config->armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed;206config->armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;207}208209InputFile::InputFile(Kind k, MemoryBufferRef m)210: mb(m), groupId(nextGroupId), fileKind(k) {211// All files within the same --{start,end}-group get the same group ID.212// Otherwise, a new file will get a new group ID.213if (!isInGroup)214++nextGroupId;215}216217std::optional<MemoryBufferRef> elf::readFile(StringRef path) {218llvm::TimeTraceScope timeScope("Load input files", path);219220// The --chroot option changes our virtual root directory.221// This is useful when you are dealing with files created by --reproduce.222if (!config->chroot.empty() && path.starts_with("/"))223path = saver().save(config->chroot + path);224225bool remapped = false;226auto it = config->remapInputs.find(path);227if (it != config->remapInputs.end()) {228path = it->second;229remapped = true;230} else {231for (const auto &[pat, toFile] : config->remapInputsWildcards) {232if (pat.match(path)) {233path = toFile;234remapped = true;235break;236}237}238}239if (remapped) {240// Use /dev/null to indicate an input file that should be ignored. Change241// the path to NUL on Windows.242#ifdef _WIN32243if (path == "/dev/null")244path = "NUL";245#endif246}247248log(path);249config->dependencyFiles.insert(llvm::CachedHashString(path));250251auto mbOrErr = MemoryBuffer::getFile(path, /*IsText=*/false,252/*RequiresNullTerminator=*/false);253if (auto ec = mbOrErr.getError()) {254error("cannot open " + path + ": " + ec.message());255return std::nullopt;256}257258MemoryBufferRef mbref = (*mbOrErr)->getMemBufferRef();259ctx.memoryBuffers.push_back(std::move(*mbOrErr)); // take MB ownership260261if (tar)262tar->append(relativeToRoot(path), mbref.getBuffer());263return mbref;264}265266// All input object files must be for the same architecture267// (e.g. it does not make sense to link x86 object files with268// MIPS object files.) This function checks for that error.269static bool isCompatible(InputFile *file) {270if (!file->isElf() && !isa<BitcodeFile>(file))271return true;272273if (file->ekind == config->ekind && file->emachine == config->emachine) {274if (config->emachine != EM_MIPS)275return true;276if (isMipsN32Abi(file) == config->mipsN32Abi)277return true;278}279280StringRef target =281!config->bfdname.empty() ? config->bfdname : config->emulation;282if (!target.empty()) {283error(toString(file) + " is incompatible with " + target);284return false;285}286287InputFile *existing = nullptr;288if (!ctx.objectFiles.empty())289existing = ctx.objectFiles[0];290else if (!ctx.sharedFiles.empty())291existing = ctx.sharedFiles[0];292else if (!ctx.bitcodeFiles.empty())293existing = ctx.bitcodeFiles[0];294std::string with;295if (existing)296with = " with " + toString(existing);297error(toString(file) + " is incompatible" + with);298return false;299}300301template <class ELFT> static void doParseFile(InputFile *file) {302if (!isCompatible(file))303return;304305// Lazy object file306if (file->lazy) {307if (auto *f = dyn_cast<BitcodeFile>(file)) {308ctx.lazyBitcodeFiles.push_back(f);309f->parseLazy();310} else {311cast<ObjFile<ELFT>>(file)->parseLazy();312}313return;314}315316if (config->trace)317message(toString(file));318319if (file->kind() == InputFile::ObjKind) {320ctx.objectFiles.push_back(cast<ELFFileBase>(file));321cast<ObjFile<ELFT>>(file)->parse();322} else if (auto *f = dyn_cast<SharedFile>(file)) {323f->parse<ELFT>();324} else if (auto *f = dyn_cast<BitcodeFile>(file)) {325ctx.bitcodeFiles.push_back(f);326f->parse();327} else {328ctx.binaryFiles.push_back(cast<BinaryFile>(file));329cast<BinaryFile>(file)->parse();330}331}332333// Add symbols in File to the symbol table.334void elf::parseFile(InputFile *file) { invokeELFT(doParseFile, file); }335336// This function is explicitly instantiated in ARM.cpp. Mark it extern here,337// to avoid warnings when building with MSVC.338extern template void ObjFile<ELF32LE>::importCmseSymbols();339extern template void ObjFile<ELF32BE>::importCmseSymbols();340extern template void ObjFile<ELF64LE>::importCmseSymbols();341extern template void ObjFile<ELF64BE>::importCmseSymbols();342343template <class ELFT>344static void doParseFiles(const std::vector<InputFile *> &files,345InputFile *armCmseImpLib) {346// Add all files to the symbol table. This will add almost all symbols that we347// need to the symbol table. This process might add files to the link due to348// addDependentLibrary.349for (size_t i = 0; i < files.size(); ++i) {350llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName());351doParseFile<ELFT>(files[i]);352}353if (armCmseImpLib)354cast<ObjFile<ELFT>>(*armCmseImpLib).importCmseSymbols();355}356357void elf::parseFiles(const std::vector<InputFile *> &files,358InputFile *armCmseImpLib) {359llvm::TimeTraceScope timeScope("Parse input files");360invokeELFT(doParseFiles, files, armCmseImpLib);361}362363// Concatenates arguments to construct a string representing an error location.364static std::string createFileLineMsg(StringRef path, unsigned line) {365std::string filename = std::string(path::filename(path));366std::string lineno = ":" + std::to_string(line);367if (filename == path)368return filename + lineno;369return filename + lineno + " (" + path.str() + lineno + ")";370}371372template <class ELFT>373static std::string getSrcMsgAux(ObjFile<ELFT> &file, const Symbol &sym,374const InputSectionBase &sec, uint64_t offset) {375// In DWARF, functions and variables are stored to different places.376// First, look up a function for a given offset.377if (std::optional<DILineInfo> info = file.getDILineInfo(&sec, offset))378return createFileLineMsg(info->FileName, info->Line);379380// If it failed, look up again as a variable.381if (std::optional<std::pair<std::string, unsigned>> fileLine =382file.getVariableLoc(sym.getName()))383return createFileLineMsg(fileLine->first, fileLine->second);384385// File.sourceFile contains STT_FILE symbol, and that is a last resort.386return std::string(file.sourceFile);387}388389std::string InputFile::getSrcMsg(const Symbol &sym, const InputSectionBase &sec,390uint64_t offset) {391if (kind() != ObjKind)392return "";393switch (ekind) {394default:395llvm_unreachable("Invalid kind");396case ELF32LEKind:397return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), sym, sec, offset);398case ELF32BEKind:399return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), sym, sec, offset);400case ELF64LEKind:401return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), sym, sec, offset);402case ELF64BEKind:403return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset);404}405}406407StringRef InputFile::getNameForScript() const {408if (archiveName.empty())409return getName();410411if (nameForScriptCache.empty())412nameForScriptCache = (archiveName + Twine(':') + getName()).str();413414return nameForScriptCache;415}416417// An ELF object file may contain a `.deplibs` section. If it exists, the418// section contains a list of library specifiers such as `m` for libm. This419// function resolves a given name by finding the first matching library checking420// the various ways that a library can be specified to LLD. This ELF extension421// is a form of autolinking and is called `dependent libraries`. It is currently422// unique to LLVM and lld.423static void addDependentLibrary(StringRef specifier, const InputFile *f) {424if (!config->dependentLibraries)425return;426if (std::optional<std::string> s = searchLibraryBaseName(specifier))427ctx.driver.addFile(saver().save(*s), /*withLOption=*/true);428else if (std::optional<std::string> s = findFromSearchPaths(specifier))429ctx.driver.addFile(saver().save(*s), /*withLOption=*/true);430else if (fs::exists(specifier))431ctx.driver.addFile(specifier, /*withLOption=*/false);432else433error(toString(f) +434": unable to find library from dependent library specifier: " +435specifier);436}437438// Record the membership of a section group so that in the garbage collection439// pass, section group members are kept or discarded as a unit.440template <class ELFT>441static void handleSectionGroup(ArrayRef<InputSectionBase *> sections,442ArrayRef<typename ELFT::Word> entries) {443bool hasAlloc = false;444for (uint32_t index : entries.slice(1)) {445if (index >= sections.size())446return;447if (InputSectionBase *s = sections[index])448if (s != &InputSection::discarded && s->flags & SHF_ALLOC)449hasAlloc = true;450}451452// If any member has the SHF_ALLOC flag, the whole group is subject to garbage453// collection. See the comment in markLive(). This rule retains .debug_types454// and .rela.debug_types.455if (!hasAlloc)456return;457458// Connect the members in a circular doubly-linked list via459// nextInSectionGroup.460InputSectionBase *head;461InputSectionBase *prev = nullptr;462for (uint32_t index : entries.slice(1)) {463InputSectionBase *s = sections[index];464if (!s || s == &InputSection::discarded)465continue;466if (prev)467prev->nextInSectionGroup = s;468else469head = s;470prev = s;471}472if (prev)473prev->nextInSectionGroup = head;474}475476template <class ELFT> DWARFCache *ObjFile<ELFT>::getDwarf() {477llvm::call_once(initDwarf, [this]() {478dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(479std::make_unique<LLDDwarfObj<ELFT>>(this), "",480[&](Error err) { warn(getName() + ": " + toString(std::move(err))); },481[&](Error warning) {482warn(getName() + ": " + toString(std::move(warning)));483}));484});485486return dwarf.get();487}488489// Returns the pair of file name and line number describing location of data490// object (variable, array, etc) definition.491template <class ELFT>492std::optional<std::pair<std::string, unsigned>>493ObjFile<ELFT>::getVariableLoc(StringRef name) {494return getDwarf()->getVariableLoc(name);495}496497// Returns source line information for a given offset498// using DWARF debug info.499template <class ELFT>500std::optional<DILineInfo>501ObjFile<ELFT>::getDILineInfo(const InputSectionBase *s, uint64_t offset) {502// Detect SectionIndex for specified section.503uint64_t sectionIndex = object::SectionedAddress::UndefSection;504ArrayRef<InputSectionBase *> sections = s->file->getSections();505for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) {506if (s == sections[curIndex]) {507sectionIndex = curIndex;508break;509}510}511512return getDwarf()->getDILineInfo(offset, sectionIndex);513}514515ELFFileBase::ELFFileBase(Kind k, ELFKind ekind, MemoryBufferRef mb)516: InputFile(k, mb) {517this->ekind = ekind;518}519520template <typename Elf_Shdr>521static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> sections, uint32_t type) {522for (const Elf_Shdr &sec : sections)523if (sec.sh_type == type)524return &sec;525return nullptr;526}527528void ELFFileBase::init() {529switch (ekind) {530case ELF32LEKind:531init<ELF32LE>(fileKind);532break;533case ELF32BEKind:534init<ELF32BE>(fileKind);535break;536case ELF64LEKind:537init<ELF64LE>(fileKind);538break;539case ELF64BEKind:540init<ELF64BE>(fileKind);541break;542default:543llvm_unreachable("getELFKind");544}545}546547template <class ELFT> void ELFFileBase::init(InputFile::Kind k) {548using Elf_Shdr = typename ELFT::Shdr;549using Elf_Sym = typename ELFT::Sym;550551// Initialize trivial attributes.552const ELFFile<ELFT> &obj = getObj<ELFT>();553emachine = obj.getHeader().e_machine;554osabi = obj.getHeader().e_ident[llvm::ELF::EI_OSABI];555abiVersion = obj.getHeader().e_ident[llvm::ELF::EI_ABIVERSION];556557ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);558elfShdrs = sections.data();559numELFShdrs = sections.size();560561// Find a symbol table.562const Elf_Shdr *symtabSec =563findSection(sections, k == SharedKind ? SHT_DYNSYM : SHT_SYMTAB);564565if (!symtabSec)566return;567568// Initialize members corresponding to a symbol table.569firstGlobal = symtabSec->sh_info;570571ArrayRef<Elf_Sym> eSyms = CHECK(obj.symbols(symtabSec), this);572if (firstGlobal == 0 || firstGlobal > eSyms.size())573fatal(toString(this) + ": invalid sh_info in symbol table");574575elfSyms = reinterpret_cast<const void *>(eSyms.data());576numELFSyms = uint32_t(eSyms.size());577stringTable = CHECK(obj.getStringTableForSymtab(*symtabSec, sections), this);578}579580template <class ELFT>581uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {582return CHECK(583this->getObj().getSectionIndex(sym, getELFSyms<ELFT>(), shndxTable),584this);585}586587template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {588object::ELFFile<ELFT> obj = this->getObj();589// Read a section table. justSymbols is usually false.590if (this->justSymbols) {591initializeJustSymbols();592initializeSymbols(obj);593return;594}595596// Handle dependent libraries and selection of section groups as these are not597// done in parallel.598ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>();599StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this);600uint64_t size = objSections.size();601sections.resize(size);602for (size_t i = 0; i != size; ++i) {603const Elf_Shdr &sec = objSections[i];604if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !config->relocatable) {605StringRef name = check(obj.getSectionName(sec, shstrtab));606ArrayRef<char> data = CHECK(607this->getObj().template getSectionContentsAsArray<char>(sec), this);608if (!data.empty() && data.back() != '\0') {609error(610toString(this) +611": corrupted dependent libraries section (unterminated string): " +612name);613} else {614for (const char *d = data.begin(), *e = data.end(); d < e;) {615StringRef s(d);616addDependentLibrary(s, this);617d += s.size() + 1;618}619}620this->sections[i] = &InputSection::discarded;621continue;622}623624if (sec.sh_type == SHT_ARM_ATTRIBUTES && config->emachine == EM_ARM) {625ARMAttributeParser attributes;626ArrayRef<uint8_t> contents =627check(this->getObj().getSectionContents(sec));628StringRef name = check(obj.getSectionName(sec, shstrtab));629this->sections[i] = &InputSection::discarded;630if (Error e = attributes.parse(contents, ekind == ELF32LEKind631? llvm::endianness::little632: llvm::endianness::big)) {633InputSection isec(*this, sec, name);634warn(toString(&isec) + ": " + llvm::toString(std::move(e)));635} else {636updateSupportedARMFeatures(attributes);637updateARMVFPArgs(attributes, this);638639// FIXME: Retain the first attribute section we see. The eglibc ARM640// dynamic loaders require the presence of an attribute section for641// dlopen to work. In a full implementation we would merge all attribute642// sections.643if (in.attributes == nullptr) {644in.attributes = std::make_unique<InputSection>(*this, sec, name);645this->sections[i] = in.attributes.get();646}647}648}649650// Producing a static binary with MTE globals is not currently supported,651// remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused652// medatada, and we don't want them to end up in the output file for static653// executables.654if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&655!canHaveMemtagGlobals()) {656this->sections[i] = &InputSection::discarded;657continue;658}659660if (sec.sh_type != SHT_GROUP)661continue;662StringRef signature = getShtGroupSignature(objSections, sec);663ArrayRef<Elf_Word> entries =664CHECK(obj.template getSectionContentsAsArray<Elf_Word>(sec), this);665if (entries.empty())666fatal(toString(this) + ": empty SHT_GROUP");667668Elf_Word flag = entries[0];669if (flag && flag != GRP_COMDAT)670fatal(toString(this) + ": unsupported SHT_GROUP format");671672bool keepGroup =673(flag & GRP_COMDAT) == 0 || ignoreComdats ||674symtab.comdatGroups.try_emplace(CachedHashStringRef(signature), this)675.second;676if (keepGroup) {677if (!config->resolveGroups)678this->sections[i] = createInputSection(679i, sec, check(obj.getSectionName(sec, shstrtab)));680continue;681}682683// Otherwise, discard group members.684for (uint32_t secIndex : entries.slice(1)) {685if (secIndex >= size)686fatal(toString(this) +687": invalid section index in group: " + Twine(secIndex));688this->sections[secIndex] = &InputSection::discarded;689}690}691692// Read a symbol table.693initializeSymbols(obj);694}695696// Sections with SHT_GROUP and comdat bits define comdat section groups.697// They are identified and deduplicated by group name. This function698// returns a group name.699template <class ELFT>700StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> sections,701const Elf_Shdr &sec) {702typename ELFT::SymRange symbols = this->getELFSyms<ELFT>();703if (sec.sh_info >= symbols.size())704fatal(toString(this) + ": invalid symbol index");705const typename ELFT::Sym &sym = symbols[sec.sh_info];706return CHECK(sym.getName(this->stringTable), this);707}708709template <class ELFT>710bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) {711// On a regular link we don't merge sections if -O0 (default is -O1). This712// sometimes makes the linker significantly faster, although the output will713// be bigger.714//715// Doing the same for -r would create a problem as it would combine sections716// with different sh_entsize. One option would be to just copy every SHF_MERGE717// section as is to the output. While this would produce a valid ELF file with718// usable SHF_MERGE sections, tools like (llvm-)?dwarfdump get confused when719// they see two .debug_str. We could have separate logic for combining720// SHF_MERGE sections based both on their name and sh_entsize, but that seems721// to be more trouble than it is worth. Instead, we just use the regular (-O1)722// logic for -r.723if (config->optimize == 0 && !config->relocatable)724return false;725726// A mergeable section with size 0 is useless because they don't have727// any data to merge. A mergeable string section with size 0 can be728// argued as invalid because it doesn't end with a null character.729// We'll avoid a mess by handling them as if they were non-mergeable.730if (sec.sh_size == 0)731return false;732733// Check for sh_entsize. The ELF spec is not clear about the zero734// sh_entsize. It says that "the member [sh_entsize] contains 0 if735// the section does not hold a table of fixed-size entries". We know736// that Rust 1.13 produces a string mergeable section with a zero737// sh_entsize. Here we just accept it rather than being picky about it.738uint64_t entSize = sec.sh_entsize;739if (entSize == 0)740return false;741if (sec.sh_size % entSize)742fatal(toString(this) + ":(" + name + "): SHF_MERGE section size (" +743Twine(sec.sh_size) + ") must be a multiple of sh_entsize (" +744Twine(entSize) + ")");745746if (sec.sh_flags & SHF_WRITE)747fatal(toString(this) + ":(" + name +748"): writable SHF_MERGE section is not supported");749750return true;751}752753// This is for --just-symbols.754//755// --just-symbols is a very minor feature that allows you to link your756// output against other existing program, so that if you load both your757// program and the other program into memory, your output can refer the758// other program's symbols.759//760// When the option is given, we link "just symbols". The section table is761// initialized with null pointers.762template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {763sections.resize(numELFShdrs);764}765766static bool isKnownSpecificSectionType(uint32_t t, uint32_t flags) {767if (SHT_LOUSER <= t && t <= SHT_HIUSER && !(flags & SHF_ALLOC))768return true;769if (SHT_LOOS <= t && t <= SHT_HIOS && !(flags & SHF_OS_NONCONFORMING))770return true;771// Allow all processor-specific types. This is different from GNU ld.772return SHT_LOPROC <= t && t <= SHT_HIPROC;773}774775template <class ELFT>776void ObjFile<ELFT>::initializeSections(bool ignoreComdats,777const llvm::object::ELFFile<ELFT> &obj) {778ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>();779StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this);780uint64_t size = objSections.size();781SmallVector<ArrayRef<Elf_Word>, 0> selectedGroups;782for (size_t i = 0; i != size; ++i) {783if (this->sections[i] == &InputSection::discarded)784continue;785const Elf_Shdr &sec = objSections[i];786const uint32_t type = sec.sh_type;787788// SHF_EXCLUDE'ed sections are discarded by the linker. However,789// if -r is given, we'll let the final link discard such sections.790// This is compatible with GNU.791if ((sec.sh_flags & SHF_EXCLUDE) && !config->relocatable) {792if (type == SHT_LLVM_CALL_GRAPH_PROFILE)793cgProfileSectionIndex = i;794if (type == SHT_LLVM_ADDRSIG) {795// We ignore the address-significance table if we know that the object796// file was created by objcopy or ld -r. This is because these tools797// will reorder the symbols in the symbol table, invalidating the data798// in the address-significance table, which refers to symbols by index.799if (sec.sh_link != 0)800this->addrsigSec = &sec;801else if (config->icf == ICFLevel::Safe)802warn(toString(this) +803": --icf=safe conservatively ignores "804"SHT_LLVM_ADDRSIG [index " +805Twine(i) +806"] with sh_link=0 "807"(likely created using objcopy or ld -r)");808}809this->sections[i] = &InputSection::discarded;810continue;811}812813switch (type) {814case SHT_GROUP: {815if (!config->relocatable)816sections[i] = &InputSection::discarded;817StringRef signature =818cantFail(this->getELFSyms<ELFT>()[sec.sh_info].getName(stringTable));819ArrayRef<Elf_Word> entries =820cantFail(obj.template getSectionContentsAsArray<Elf_Word>(sec));821if ((entries[0] & GRP_COMDAT) == 0 || ignoreComdats ||822symtab.comdatGroups.find(CachedHashStringRef(signature))->second ==823this)824selectedGroups.push_back(entries);825break;826}827case SHT_SYMTAB_SHNDX:828shndxTable = CHECK(obj.getSHNDXTable(sec, objSections), this);829break;830case SHT_SYMTAB:831case SHT_STRTAB:832case SHT_REL:833case SHT_RELA:834case SHT_CREL:835case SHT_NULL:836break;837case SHT_PROGBITS:838case SHT_NOTE:839case SHT_NOBITS:840case SHT_INIT_ARRAY:841case SHT_FINI_ARRAY:842case SHT_PREINIT_ARRAY:843this->sections[i] =844createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));845break;846case SHT_LLVM_LTO:847// Discard .llvm.lto in a relocatable link that does not use the bitcode.848// The concatenated output does not properly reflect the linking849// semantics. In addition, since we do not use the bitcode wrapper format,850// the concatenated raw bitcode would be invalid.851if (config->relocatable && !config->fatLTOObjects) {852sections[i] = &InputSection::discarded;853break;854}855[[fallthrough]];856default:857this->sections[i] =858createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));859if (type == SHT_LLVM_SYMPART)860ctx.hasSympart.store(true, std::memory_order_relaxed);861else if (config->rejectMismatch &&862!isKnownSpecificSectionType(type, sec.sh_flags))863errorOrWarn(toString(this->sections[i]) + ": unknown section type 0x" +864Twine::utohexstr(type));865break;866}867}868869// We have a second loop. It is used to:870// 1) handle SHF_LINK_ORDER sections.871// 2) create relocation sections. In some cases the section header index of a872// relocation section may be smaller than that of the relocated section. In873// such cases, the relocation section would attempt to reference a target874// section that has not yet been created. For simplicity, delay creation of875// relocation sections until now.876for (size_t i = 0; i != size; ++i) {877if (this->sections[i] == &InputSection::discarded)878continue;879const Elf_Shdr &sec = objSections[i];880881if (isStaticRelSecType(sec.sh_type)) {882// Find a relocation target section and associate this section with that.883// Target may have been discarded if it is in a different section group884// and the group is discarded, even though it's a violation of the spec.885// We handle that situation gracefully by discarding dangling relocation886// sections.887const uint32_t info = sec.sh_info;888InputSectionBase *s = getRelocTarget(i, info);889if (!s)890continue;891892// ELF spec allows mergeable sections with relocations, but they are rare,893// and it is in practice hard to merge such sections by contents, because894// applying relocations at end of linking changes section contents. So, we895// simply handle such sections as non-mergeable ones. Degrading like this896// is acceptable because section merging is optional.897if (auto *ms = dyn_cast<MergeInputSection>(s)) {898s = makeThreadLocal<InputSection>(899ms->file, ms->flags, ms->type, ms->addralign,900ms->contentMaybeDecompress(), ms->name);901sections[info] = s;902}903904if (s->relSecIdx != 0)905error(906toString(s) +907": multiple relocation sections to one section are not supported");908s->relSecIdx = i;909910// Relocation sections are usually removed from the output, so return911// `nullptr` for the normal case. However, if -r or --emit-relocs is912// specified, we need to copy them to the output. (Some post link analysis913// tools specify --emit-relocs to obtain the information.)914if (config->copyRelocs) {915auto *isec = makeThreadLocal<InputSection>(916*this, sec, check(obj.getSectionName(sec, shstrtab)));917// If the relocated section is discarded (due to /DISCARD/ or918// --gc-sections), the relocation section should be discarded as well.919s->dependentSections.push_back(isec);920sections[i] = isec;921}922continue;923}924925// A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have926// the flag.927if (!sec.sh_link || !(sec.sh_flags & SHF_LINK_ORDER))928continue;929930InputSectionBase *linkSec = nullptr;931if (sec.sh_link < size)932linkSec = this->sections[sec.sh_link];933if (!linkSec)934fatal(toString(this) + ": invalid sh_link index: " + Twine(sec.sh_link));935936// A SHF_LINK_ORDER section is discarded if its linked-to section is937// discarded.938InputSection *isec = cast<InputSection>(this->sections[i]);939linkSec->dependentSections.push_back(isec);940if (!isa<InputSection>(linkSec))941error("a section " + isec->name +942" with SHF_LINK_ORDER should not refer a non-regular section: " +943toString(linkSec));944}945946for (ArrayRef<Elf_Word> entries : selectedGroups)947handleSectionGroup<ELFT>(this->sections, entries);948}949950// Read the following info from the .note.gnu.property section and write it to951// the corresponding fields in `ObjFile`:952// - Feature flags (32 bits) representing x86 or AArch64 features for953// hardware-assisted call flow control;954// - AArch64 PAuth ABI core info (16 bytes).955template <class ELFT>956void readGnuProperty(const InputSection &sec, ObjFile<ELFT> &f) {957using Elf_Nhdr = typename ELFT::Nhdr;958using Elf_Note = typename ELFT::Note;959960ArrayRef<uint8_t> data = sec.content();961auto reportFatal = [&](const uint8_t *place, const Twine &msg) {962fatal(toString(sec.file) + ":(" + sec.name + "+0x" +963Twine::utohexstr(place - sec.content().data()) + "): " + msg);964};965while (!data.empty()) {966// Read one NOTE record.967auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());968if (data.size() < sizeof(Elf_Nhdr) ||969data.size() < nhdr->getSize(sec.addralign))970reportFatal(data.data(), "data is too short");971972Elf_Note note(*nhdr);973if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {974data = data.slice(nhdr->getSize(sec.addralign));975continue;976}977978uint32_t featureAndType = config->emachine == EM_AARCH64979? GNU_PROPERTY_AARCH64_FEATURE_1_AND980: GNU_PROPERTY_X86_FEATURE_1_AND;981982// Read a body of a NOTE record, which consists of type-length-value fields.983ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);984while (!desc.empty()) {985const uint8_t *place = desc.data();986if (desc.size() < 8)987reportFatal(place, "program property is too short");988uint32_t type = read32<ELFT::Endianness>(desc.data());989uint32_t size = read32<ELFT::Endianness>(desc.data() + 4);990desc = desc.slice(8);991if (desc.size() < size)992reportFatal(place, "program property is too short");993994if (type == featureAndType) {995// We found a FEATURE_1_AND field. There may be more than one of these996// in a .note.gnu.property section, for a relocatable object we997// accumulate the bits set.998if (size < 4)999reportFatal(place, "FEATURE_1_AND entry is too short");1000f.andFeatures |= read32<ELFT::Endianness>(desc.data());1001} else if (config->emachine == EM_AARCH64 &&1002type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {1003if (!f.aarch64PauthAbiCoreInfo.empty()) {1004reportFatal(data.data(),1005"multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "1006"not supported");1007} else if (size != 16) {1008reportFatal(data.data(), "GNU_PROPERTY_AARCH64_FEATURE_PAUTH entry "1009"is invalid: expected 16 bytes, but got " +1010Twine(size));1011}1012f.aarch64PauthAbiCoreInfo = desc;1013}10141015// Padding is present in the note descriptor, if necessary.1016desc = desc.slice(alignTo<(ELFT::Is64Bits ? 8 : 4)>(size));1017}10181019// Go to next NOTE record to look for more FEATURE_1_AND descriptions.1020data = data.slice(nhdr->getSize(sec.addralign));1021}1022}10231024template <class ELFT>1025InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, uint32_t info) {1026if (info < this->sections.size()) {1027InputSectionBase *target = this->sections[info];10281029// Strictly speaking, a relocation section must be included in the1030// group of the section it relocates. However, LLVM 3.3 and earlier1031// would fail to do so, so we gracefully handle that case.1032if (target == &InputSection::discarded)1033return nullptr;10341035if (target != nullptr)1036return target;1037}10381039error(toString(this) + Twine(": relocation section (index ") + Twine(idx) +1040") has invalid sh_info (" + Twine(info) + ")");1041return nullptr;1042}10431044// The function may be called concurrently for different input files. For1045// allocation, prefer makeThreadLocal which does not require holding a lock.1046template <class ELFT>1047InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,1048const Elf_Shdr &sec,1049StringRef name) {1050if (name.starts_with(".n")) {1051// The GNU linker uses .note.GNU-stack section as a marker indicating1052// that the code in the object file does not expect that the stack is1053// executable (in terms of NX bit). If all input files have the marker,1054// the GNU linker adds a PT_GNU_STACK segment to tells the loader to1055// make the stack non-executable. Most object files have this section as1056// of 2017.1057//1058// But making the stack non-executable is a norm today for security1059// reasons. Failure to do so may result in a serious security issue.1060// Therefore, we make LLD always add PT_GNU_STACK unless it is1061// explicitly told to do otherwise (by -z execstack). Because the stack1062// executable-ness is controlled solely by command line options,1063// .note.GNU-stack sections are simply ignored.1064if (name == ".note.GNU-stack")1065return &InputSection::discarded;10661067// Object files that use processor features such as Intel Control-Flow1068// Enforcement (CET) or AArch64 Branch Target Identification BTI, use a1069// .note.gnu.property section containing a bitfield of feature bits like the1070// GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag.1071//1072// Since we merge bitmaps from multiple object files to create a new1073// .note.gnu.property containing a single AND'ed bitmap, we discard an input1074// file's .note.gnu.property section.1075if (name == ".note.gnu.property") {1076readGnuProperty<ELFT>(InputSection(*this, sec, name), *this);1077return &InputSection::discarded;1078}10791080// Split stacks is a feature to support a discontiguous stack,1081// commonly used in the programming language Go. For the details,1082// see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled1083// for split stack will include a .note.GNU-split-stack section.1084if (name == ".note.GNU-split-stack") {1085if (config->relocatable) {1086error(1087"cannot mix split-stack and non-split-stack in a relocatable link");1088return &InputSection::discarded;1089}1090this->splitStack = true;1091return &InputSection::discarded;1092}10931094// An object file compiled for split stack, but where some of the1095// functions were compiled with the no_split_stack_attribute will1096// include a .note.GNU-no-split-stack section.1097if (name == ".note.GNU-no-split-stack") {1098this->someNoSplitStack = true;1099return &InputSection::discarded;1100}11011102// Strip existing .note.gnu.build-id sections so that the output won't have1103// more than one build-id. This is not usually a problem because input1104// object files normally don't have .build-id sections, but you can create1105// such files by "ld.{bfd,gold,lld} -r --build-id", and we want to guard1106// against it.1107if (name == ".note.gnu.build-id")1108return &InputSection::discarded;1109}11101111// The linker merges EH (exception handling) frames and creates a1112// .eh_frame_hdr section for runtime. So we handle them with a special1113// class. For relocatable outputs, they are just passed through.1114if (name == ".eh_frame" && !config->relocatable)1115return makeThreadLocal<EhInputSection>(*this, sec, name);11161117if ((sec.sh_flags & SHF_MERGE) && shouldMerge(sec, name))1118return makeThreadLocal<MergeInputSection>(*this, sec, name);1119return makeThreadLocal<InputSection>(*this, sec, name);1120}11211122// Initialize symbols. symbols is a parallel array to the corresponding ELF1123// symbol table.1124template <class ELFT>1125void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {1126ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();1127if (numSymbols == 0) {1128numSymbols = eSyms.size();1129symbols = std::make_unique<Symbol *[]>(numSymbols);1130}11311132// Some entries have been filled by LazyObjFile.1133for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)1134if (!symbols[i])1135symbols[i] = symtab.insert(CHECK(eSyms[i].getName(stringTable), this));11361137// Perform symbol resolution on non-local symbols.1138SmallVector<unsigned, 32> undefineds;1139for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {1140const Elf_Sym &eSym = eSyms[i];1141uint32_t secIdx = eSym.st_shndx;1142if (secIdx == SHN_UNDEF) {1143undefineds.push_back(i);1144continue;1145}11461147uint8_t binding = eSym.getBinding();1148uint8_t stOther = eSym.st_other;1149uint8_t type = eSym.getType();1150uint64_t value = eSym.st_value;1151uint64_t size = eSym.st_size;11521153Symbol *sym = symbols[i];1154sym->isUsedInRegularObj = true;1155if (LLVM_UNLIKELY(eSym.st_shndx == SHN_COMMON)) {1156if (value == 0 || value >= UINT32_MAX)1157fatal(toString(this) + ": common symbol '" + sym->getName() +1158"' has invalid alignment: " + Twine(value));1159hasCommonSyms = true;1160sym->resolve(1161CommonSymbol{this, StringRef(), binding, stOther, type, value, size});1162continue;1163}11641165// Handle global defined symbols. Defined::section will be set in postParse.1166sym->resolve(Defined{this, StringRef(), binding, stOther, type, value, size,1167nullptr});1168}11691170// Undefined symbols (excluding those defined relative to non-prevailing1171// sections) can trigger recursive extract. Process defined symbols first so1172// that the relative order between a defined symbol and an undefined symbol1173// does not change the symbol resolution behavior. In addition, a set of1174// interconnected symbols will all be resolved to the same file, instead of1175// being resolved to different files.1176for (unsigned i : undefineds) {1177const Elf_Sym &eSym = eSyms[i];1178Symbol *sym = symbols[i];1179sym->resolve(Undefined{this, StringRef(), eSym.getBinding(), eSym.st_other,1180eSym.getType()});1181sym->isUsedInRegularObj = true;1182sym->referenced = true;1183}1184}11851186template <class ELFT>1187void ObjFile<ELFT>::initSectionsAndLocalSyms(bool ignoreComdats) {1188if (!justSymbols)1189initializeSections(ignoreComdats, getObj());11901191if (!firstGlobal)1192return;1193SymbolUnion *locals = makeThreadLocalN<SymbolUnion>(firstGlobal);1194memset(locals, 0, sizeof(SymbolUnion) * firstGlobal);11951196ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();1197for (size_t i = 0, end = firstGlobal; i != end; ++i) {1198const Elf_Sym &eSym = eSyms[i];1199uint32_t secIdx = eSym.st_shndx;1200if (LLVM_UNLIKELY(secIdx == SHN_XINDEX))1201secIdx = check(getExtendedSymbolTableIndex<ELFT>(eSym, i, shndxTable));1202else if (secIdx >= SHN_LORESERVE)1203secIdx = 0;1204if (LLVM_UNLIKELY(secIdx >= sections.size()))1205fatal(toString(this) + ": invalid section index: " + Twine(secIdx));1206if (LLVM_UNLIKELY(eSym.getBinding() != STB_LOCAL))1207error(toString(this) + ": non-local symbol (" + Twine(i) +1208") found at index < .symtab's sh_info (" + Twine(end) + ")");12091210InputSectionBase *sec = sections[secIdx];1211uint8_t type = eSym.getType();1212if (type == STT_FILE)1213sourceFile = CHECK(eSym.getName(stringTable), this);1214if (LLVM_UNLIKELY(stringTable.size() <= eSym.st_name))1215fatal(toString(this) + ": invalid symbol name offset");1216StringRef name(stringTable.data() + eSym.st_name);12171218symbols[i] = reinterpret_cast<Symbol *>(locals + i);1219if (eSym.st_shndx == SHN_UNDEF || sec == &InputSection::discarded)1220new (symbols[i]) Undefined(this, name, STB_LOCAL, eSym.st_other, type,1221/*discardedSecIdx=*/secIdx);1222else1223new (symbols[i]) Defined(this, name, STB_LOCAL, eSym.st_other, type,1224eSym.st_value, eSym.st_size, sec);1225symbols[i]->partition = 1;1226symbols[i]->isUsedInRegularObj = true;1227}1228}12291230// Called after all ObjFile::parse is called for all ObjFiles. This checks1231// duplicate symbols and may do symbol property merge in the future.1232template <class ELFT> void ObjFile<ELFT>::postParse() {1233static std::mutex mu;1234ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();1235for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {1236const Elf_Sym &eSym = eSyms[i];1237Symbol &sym = *symbols[i];1238uint32_t secIdx = eSym.st_shndx;1239uint8_t binding = eSym.getBinding();1240if (LLVM_UNLIKELY(binding != STB_GLOBAL && binding != STB_WEAK &&1241binding != STB_GNU_UNIQUE))1242errorOrWarn(toString(this) + ": symbol (" + Twine(i) +1243") has invalid binding: " + Twine((int)binding));12441245// st_value of STT_TLS represents the assigned offset, not the actual1246// address which is used by STT_FUNC and STT_OBJECT. STT_TLS symbols can1247// only be referenced by special TLS relocations. It is usually an error if1248// a STT_TLS symbol is replaced by a non-STT_TLS symbol, vice versa.1249if (LLVM_UNLIKELY(sym.isTls()) && eSym.getType() != STT_TLS &&1250eSym.getType() != STT_NOTYPE)1251errorOrWarn("TLS attribute mismatch: " + toString(sym) + "\n>>> in " +1252toString(sym.file) + "\n>>> in " + toString(this));12531254// Handle non-COMMON defined symbol below. !sym.file allows a symbol1255// assignment to redefine a symbol without an error.1256if (!sym.file || !sym.isDefined() || secIdx == SHN_UNDEF ||1257secIdx == SHN_COMMON)1258continue;12591260if (LLVM_UNLIKELY(secIdx == SHN_XINDEX))1261secIdx = check(getExtendedSymbolTableIndex<ELFT>(eSym, i, shndxTable));1262else if (secIdx >= SHN_LORESERVE)1263secIdx = 0;1264if (LLVM_UNLIKELY(secIdx >= sections.size()))1265fatal(toString(this) + ": invalid section index: " + Twine(secIdx));1266InputSectionBase *sec = sections[secIdx];1267if (sec == &InputSection::discarded) {1268if (sym.traced) {1269printTraceSymbol(Undefined{this, sym.getName(), sym.binding,1270sym.stOther, sym.type, secIdx},1271sym.getName());1272}1273if (sym.file == this) {1274std::lock_guard<std::mutex> lock(mu);1275ctx.nonPrevailingSyms.emplace_back(&sym, secIdx);1276}1277continue;1278}12791280if (sym.file == this) {1281cast<Defined>(sym).section = sec;1282continue;1283}12841285if (sym.binding == STB_WEAK || binding == STB_WEAK)1286continue;1287std::lock_guard<std::mutex> lock(mu);1288ctx.duplicates.push_back({&sym, this, sec, eSym.st_value});1289}1290}12911292// The handling of tentative definitions (COMMON symbols) in archives is murky.1293// A tentative definition will be promoted to a global definition if there are1294// no non-tentative definitions to dominate it. When we hold a tentative1295// definition to a symbol and are inspecting archive members for inclusion1296// there are 2 ways we can proceed:1297//1298// 1) Consider the tentative definition a 'real' definition (ie promotion from1299// tentative to real definition has already happened) and not inspect1300// archive members for Global/Weak definitions to replace the tentative1301// definition. An archive member would only be included if it satisfies some1302// other undefined symbol. This is the behavior Gold uses.1303//1304// 2) Consider the tentative definition as still undefined (ie the promotion to1305// a real definition happens only after all symbol resolution is done).1306// The linker searches archive members for STB_GLOBAL definitions to1307// replace the tentative definition with. This is the behavior used by1308// GNU ld.1309//1310// The second behavior is inherited from SysVR4, which based it on the FORTRAN1311// COMMON BLOCK model. This behavior is needed for proper initialization in old1312// (pre F90) FORTRAN code that is packaged into an archive.1313//1314// The following functions search archive members for definitions to replace1315// tentative definitions (implementing behavior 2).1316static bool isBitcodeNonCommonDef(MemoryBufferRef mb, StringRef symName,1317StringRef archiveName) {1318IRSymtabFile symtabFile = check(readIRSymtab(mb));1319for (const irsymtab::Reader::SymbolRef &sym :1320symtabFile.TheReader.symbols()) {1321if (sym.isGlobal() && sym.getName() == symName)1322return !sym.isUndefined() && !sym.isWeak() && !sym.isCommon();1323}1324return false;1325}13261327template <class ELFT>1328static bool isNonCommonDef(ELFKind ekind, MemoryBufferRef mb, StringRef symName,1329StringRef archiveName) {1330ObjFile<ELFT> *obj = make<ObjFile<ELFT>>(ekind, mb, archiveName);1331obj->init();1332StringRef stringtable = obj->getStringTable();13331334for (auto sym : obj->template getGlobalELFSyms<ELFT>()) {1335Expected<StringRef> name = sym.getName(stringtable);1336if (name && name.get() == symName)1337return sym.isDefined() && sym.getBinding() == STB_GLOBAL &&1338!sym.isCommon();1339}1340return false;1341}13421343static bool isNonCommonDef(MemoryBufferRef mb, StringRef symName,1344StringRef archiveName) {1345switch (getELFKind(mb, archiveName)) {1346case ELF32LEKind:1347return isNonCommonDef<ELF32LE>(ELF32LEKind, mb, symName, archiveName);1348case ELF32BEKind:1349return isNonCommonDef<ELF32BE>(ELF32BEKind, mb, symName, archiveName);1350case ELF64LEKind:1351return isNonCommonDef<ELF64LE>(ELF64LEKind, mb, symName, archiveName);1352case ELF64BEKind:1353return isNonCommonDef<ELF64BE>(ELF64BEKind, mb, symName, archiveName);1354default:1355llvm_unreachable("getELFKind");1356}1357}13581359unsigned SharedFile::vernauxNum;13601361SharedFile::SharedFile(MemoryBufferRef m, StringRef defaultSoName)1362: ELFFileBase(SharedKind, getELFKind(m, ""), m), soName(defaultSoName),1363isNeeded(!config->asNeeded) {}13641365// Parse the version definitions in the object file if present, and return a1366// vector whose nth element contains a pointer to the Elf_Verdef for version1367// identifier n. Version identifiers that are not definitions map to nullptr.1368template <typename ELFT>1369static SmallVector<const void *, 0>1370parseVerdefs(const uint8_t *base, const typename ELFT::Shdr *sec) {1371if (!sec)1372return {};13731374// Build the Verdefs array by following the chain of Elf_Verdef objects1375// from the start of the .gnu.version_d section.1376SmallVector<const void *, 0> verdefs;1377const uint8_t *verdef = base + sec->sh_offset;1378for (unsigned i = 0, e = sec->sh_info; i != e; ++i) {1379auto *curVerdef = reinterpret_cast<const typename ELFT::Verdef *>(verdef);1380verdef += curVerdef->vd_next;1381unsigned verdefIndex = curVerdef->vd_ndx;1382if (verdefIndex >= verdefs.size())1383verdefs.resize(verdefIndex + 1);1384verdefs[verdefIndex] = curVerdef;1385}1386return verdefs;1387}13881389// Parse SHT_GNU_verneed to properly set the name of a versioned undefined1390// symbol. We detect fatal issues which would cause vulnerabilities, but do not1391// implement sophisticated error checking like in llvm-readobj because the value1392// of such diagnostics is low.1393template <typename ELFT>1394std::vector<uint32_t> SharedFile::parseVerneed(const ELFFile<ELFT> &obj,1395const typename ELFT::Shdr *sec) {1396if (!sec)1397return {};1398std::vector<uint32_t> verneeds;1399ArrayRef<uint8_t> data = CHECK(obj.getSectionContents(*sec), this);1400const uint8_t *verneedBuf = data.begin();1401for (unsigned i = 0; i != sec->sh_info; ++i) {1402if (verneedBuf + sizeof(typename ELFT::Verneed) > data.end())1403fatal(toString(this) + " has an invalid Verneed");1404auto *vn = reinterpret_cast<const typename ELFT::Verneed *>(verneedBuf);1405const uint8_t *vernauxBuf = verneedBuf + vn->vn_aux;1406for (unsigned j = 0; j != vn->vn_cnt; ++j) {1407if (vernauxBuf + sizeof(typename ELFT::Vernaux) > data.end())1408fatal(toString(this) + " has an invalid Vernaux");1409auto *aux = reinterpret_cast<const typename ELFT::Vernaux *>(vernauxBuf);1410if (aux->vna_name >= this->stringTable.size())1411fatal(toString(this) + " has a Vernaux with an invalid vna_name");1412uint16_t version = aux->vna_other & VERSYM_VERSION;1413if (version >= verneeds.size())1414verneeds.resize(version + 1);1415verneeds[version] = aux->vna_name;1416vernauxBuf += aux->vna_next;1417}1418verneedBuf += vn->vn_next;1419}1420return verneeds;1421}14221423// We do not usually care about alignments of data in shared object1424// files because the loader takes care of it. However, if we promote a1425// DSO symbol to point to .bss due to copy relocation, we need to keep1426// the original alignment requirements. We infer it in this function.1427template <typename ELFT>1428static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> sections,1429const typename ELFT::Sym &sym) {1430uint64_t ret = UINT64_MAX;1431if (sym.st_value)1432ret = 1ULL << llvm::countr_zero((uint64_t)sym.st_value);1433if (0 < sym.st_shndx && sym.st_shndx < sections.size())1434ret = std::min<uint64_t>(ret, sections[sym.st_shndx].sh_addralign);1435return (ret > UINT32_MAX) ? 0 : ret;1436}14371438// Fully parse the shared object file.1439//1440// This function parses symbol versions. If a DSO has version information,1441// the file has a ".gnu.version_d" section which contains symbol version1442// definitions. Each symbol is associated to one version through a table in1443// ".gnu.version" section. That table is a parallel array for the symbol1444// table, and each table entry contains an index in ".gnu.version_d".1445//1446// The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for1447// VER_NDX_GLOBAL. There's no table entry for these special versions in1448// ".gnu.version_d".1449//1450// The file format for symbol versioning is perhaps a bit more complicated1451// than necessary, but you can easily understand the code if you wrap your1452// head around the data structure described above.1453template <class ELFT> void SharedFile::parse() {1454using Elf_Dyn = typename ELFT::Dyn;1455using Elf_Shdr = typename ELFT::Shdr;1456using Elf_Sym = typename ELFT::Sym;1457using Elf_Verdef = typename ELFT::Verdef;1458using Elf_Versym = typename ELFT::Versym;14591460ArrayRef<Elf_Dyn> dynamicTags;1461const ELFFile<ELFT> obj = this->getObj<ELFT>();1462ArrayRef<Elf_Shdr> sections = getELFShdrs<ELFT>();14631464const Elf_Shdr *versymSec = nullptr;1465const Elf_Shdr *verdefSec = nullptr;1466const Elf_Shdr *verneedSec = nullptr;14671468// Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.1469for (const Elf_Shdr &sec : sections) {1470switch (sec.sh_type) {1471default:1472continue;1473case SHT_DYNAMIC:1474dynamicTags =1475CHECK(obj.template getSectionContentsAsArray<Elf_Dyn>(sec), this);1476break;1477case SHT_GNU_versym:1478versymSec = &sec;1479break;1480case SHT_GNU_verdef:1481verdefSec = &sec;1482break;1483case SHT_GNU_verneed:1484verneedSec = &sec;1485break;1486}1487}14881489if (versymSec && numELFSyms == 0) {1490error("SHT_GNU_versym should be associated with symbol table");1491return;1492}14931494// Search for a DT_SONAME tag to initialize this->soName.1495for (const Elf_Dyn &dyn : dynamicTags) {1496if (dyn.d_tag == DT_NEEDED) {1497uint64_t val = dyn.getVal();1498if (val >= this->stringTable.size())1499fatal(toString(this) + ": invalid DT_NEEDED entry");1500dtNeeded.push_back(this->stringTable.data() + val);1501} else if (dyn.d_tag == DT_SONAME) {1502uint64_t val = dyn.getVal();1503if (val >= this->stringTable.size())1504fatal(toString(this) + ": invalid DT_SONAME entry");1505soName = this->stringTable.data() + val;1506}1507}15081509// DSOs are uniquified not by filename but by soname.1510DenseMap<CachedHashStringRef, SharedFile *>::iterator it;1511bool wasInserted;1512std::tie(it, wasInserted) =1513symtab.soNames.try_emplace(CachedHashStringRef(soName), this);15141515// If a DSO appears more than once on the command line with and without1516// --as-needed, --no-as-needed takes precedence over --as-needed because a1517// user can add an extra DSO with --no-as-needed to force it to be added to1518// the dependency list.1519it->second->isNeeded |= isNeeded;1520if (!wasInserted)1521return;15221523ctx.sharedFiles.push_back(this);15241525verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec);1526std::vector<uint32_t> verneeds = parseVerneed<ELFT>(obj, verneedSec);15271528// Parse ".gnu.version" section which is a parallel array for the symbol1529// table. If a given file doesn't have a ".gnu.version" section, we use1530// VER_NDX_GLOBAL.1531size_t size = numELFSyms - firstGlobal;1532std::vector<uint16_t> versyms(size, VER_NDX_GLOBAL);1533if (versymSec) {1534ArrayRef<Elf_Versym> versym =1535CHECK(obj.template getSectionContentsAsArray<Elf_Versym>(*versymSec),1536this)1537.slice(firstGlobal);1538for (size_t i = 0; i < size; ++i)1539versyms[i] = versym[i].vs_index;1540}15411542// System libraries can have a lot of symbols with versions. Using a1543// fixed buffer for computing the versions name (foo@ver) can save a1544// lot of allocations.1545SmallString<0> versionedNameBuffer;15461547// Add symbols to the symbol table.1548ArrayRef<Elf_Sym> syms = this->getGlobalELFSyms<ELFT>();1549for (size_t i = 0, e = syms.size(); i != e; ++i) {1550const Elf_Sym &sym = syms[i];15511552// ELF spec requires that all local symbols precede weak or global1553// symbols in each symbol table, and the index of first non-local symbol1554// is stored to sh_info. If a local symbol appears after some non-local1555// symbol, that's a violation of the spec.1556StringRef name = CHECK(sym.getName(stringTable), this);1557if (sym.getBinding() == STB_LOCAL) {1558errorOrWarn(toString(this) + ": invalid local symbol '" + name +1559"' in global part of symbol table");1560continue;1561}15621563const uint16_t ver = versyms[i], idx = ver & ~VERSYM_HIDDEN;1564if (sym.isUndefined()) {1565// For unversioned undefined symbols, VER_NDX_GLOBAL makes more sense but1566// as of binutils 2.34, GNU ld produces VER_NDX_LOCAL.1567if (ver != VER_NDX_LOCAL && ver != VER_NDX_GLOBAL) {1568if (idx >= verneeds.size()) {1569error("corrupt input file: version need index " + Twine(idx) +1570" for symbol " + name + " is out of bounds\n>>> defined in " +1571toString(this));1572continue;1573}1574StringRef verName = stringTable.data() + verneeds[idx];1575versionedNameBuffer.clear();1576name = saver().save(1577(name + "@" + verName).toStringRef(versionedNameBuffer));1578}1579Symbol *s = symtab.addSymbol(1580Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});1581s->exportDynamic = true;1582if (sym.getBinding() != STB_WEAK &&1583config->unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)1584requiredSymbols.push_back(s);1585continue;1586}15871588if (ver == VER_NDX_LOCAL ||1589(ver != VER_NDX_GLOBAL && idx >= verdefs.size())) {1590// In GNU ld < 2.31 (before 3be08ea4728b56d35e136af4e6fd3086ade17764), the1591// MIPS port puts _gp_disp symbol into DSO files and incorrectly assigns1592// VER_NDX_LOCAL. Workaround this bug.1593if (config->emachine == EM_MIPS && name == "_gp_disp")1594continue;1595error("corrupt input file: version definition index " + Twine(idx) +1596" for symbol " + name + " is out of bounds\n>>> defined in " +1597toString(this));1598continue;1599}16001601uint32_t alignment = getAlignment<ELFT>(sections, sym);1602if (ver == idx) {1603auto *s = symtab.addSymbol(1604SharedSymbol{*this, name, sym.getBinding(), sym.st_other,1605sym.getType(), sym.st_value, sym.st_size, alignment});1606s->dsoDefined = true;1607if (s->file == this)1608s->versionId = ver;1609}16101611// Also add the symbol with the versioned name to handle undefined symbols1612// with explicit versions.1613if (ver == VER_NDX_GLOBAL)1614continue;16151616StringRef verName =1617stringTable.data() +1618reinterpret_cast<const Elf_Verdef *>(verdefs[idx])->getAux()->vda_name;1619versionedNameBuffer.clear();1620name = (name + "@" + verName).toStringRef(versionedNameBuffer);1621auto *s = symtab.addSymbol(1622SharedSymbol{*this, saver().save(name), sym.getBinding(), sym.st_other,1623sym.getType(), sym.st_value, sym.st_size, alignment});1624s->dsoDefined = true;1625if (s->file == this)1626s->versionId = idx;1627}1628}16291630static ELFKind getBitcodeELFKind(const Triple &t) {1631if (t.isLittleEndian())1632return t.isArch64Bit() ? ELF64LEKind : ELF32LEKind;1633return t.isArch64Bit() ? ELF64BEKind : ELF32BEKind;1634}16351636static uint16_t getBitcodeMachineKind(StringRef path, const Triple &t) {1637switch (t.getArch()) {1638case Triple::aarch64:1639case Triple::aarch64_be:1640return EM_AARCH64;1641case Triple::amdgcn:1642case Triple::r600:1643return EM_AMDGPU;1644case Triple::arm:1645case Triple::armeb:1646case Triple::thumb:1647case Triple::thumbeb:1648return EM_ARM;1649case Triple::avr:1650return EM_AVR;1651case Triple::hexagon:1652return EM_HEXAGON;1653case Triple::loongarch32:1654case Triple::loongarch64:1655return EM_LOONGARCH;1656case Triple::mips:1657case Triple::mipsel:1658case Triple::mips64:1659case Triple::mips64el:1660return EM_MIPS;1661case Triple::msp430:1662return EM_MSP430;1663case Triple::ppc:1664case Triple::ppcle:1665return EM_PPC;1666case Triple::ppc64:1667case Triple::ppc64le:1668return EM_PPC64;1669case Triple::riscv32:1670case Triple::riscv64:1671return EM_RISCV;1672case Triple::sparcv9:1673return EM_SPARCV9;1674case Triple::systemz:1675return EM_S390;1676case Triple::x86:1677return t.isOSIAMCU() ? EM_IAMCU : EM_386;1678case Triple::x86_64:1679return EM_X86_64;1680default:1681error(path + ": could not infer e_machine from bitcode target triple " +1682t.str());1683return EM_NONE;1684}1685}16861687static uint8_t getOsAbi(const Triple &t) {1688switch (t.getOS()) {1689case Triple::AMDHSA:1690return ELF::ELFOSABI_AMDGPU_HSA;1691case Triple::AMDPAL:1692return ELF::ELFOSABI_AMDGPU_PAL;1693case Triple::Mesa3D:1694return ELF::ELFOSABI_AMDGPU_MESA3D;1695default:1696return ELF::ELFOSABI_NONE;1697}1698}16991700BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,1701uint64_t offsetInArchive, bool lazy)1702: InputFile(BitcodeKind, mb) {1703this->archiveName = archiveName;1704this->lazy = lazy;17051706std::string path = mb.getBufferIdentifier().str();1707if (config->thinLTOIndexOnly)1708path = replaceThinLTOSuffix(mb.getBufferIdentifier());17091710// ThinLTO assumes that all MemoryBufferRefs given to it have a unique1711// name. If two archives define two members with the same name, this1712// causes a collision which result in only one of the objects being taken1713// into consideration at LTO time (which very likely causes undefined1714// symbols later in the link stage). So we append file offset to make1715// filename unique.1716StringRef name = archiveName.empty()1717? saver().save(path)1718: saver().save(archiveName + "(" + path::filename(path) +1719" at " + utostr(offsetInArchive) + ")");1720MemoryBufferRef mbref(mb.getBuffer(), name);17211722obj = CHECK(lto::InputFile::create(mbref), this);17231724Triple t(obj->getTargetTriple());1725ekind = getBitcodeELFKind(t);1726emachine = getBitcodeMachineKind(mb.getBufferIdentifier(), t);1727osabi = getOsAbi(t);1728}17291730static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {1731switch (gvVisibility) {1732case GlobalValue::DefaultVisibility:1733return STV_DEFAULT;1734case GlobalValue::HiddenVisibility:1735return STV_HIDDEN;1736case GlobalValue::ProtectedVisibility:1737return STV_PROTECTED;1738}1739llvm_unreachable("unknown visibility");1740}17411742static void1743createBitcodeSymbol(Symbol *&sym, const std::vector<bool> &keptComdats,1744const lto::InputFile::Symbol &objSym, BitcodeFile &f) {1745uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;1746uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;1747uint8_t visibility = mapVisibility(objSym.getVisibility());17481749if (!sym)1750sym = symtab.insert(saver().save(objSym.getName()));17511752int c = objSym.getComdatIndex();1753if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {1754Undefined newSym(&f, StringRef(), binding, visibility, type);1755sym->resolve(newSym);1756sym->referenced = true;1757return;1758}17591760if (objSym.isCommon()) {1761sym->resolve(CommonSymbol{&f, StringRef(), binding, visibility, STT_OBJECT,1762objSym.getCommonAlignment(),1763objSym.getCommonSize()});1764} else {1765Defined newSym(&f, StringRef(), binding, visibility, type, 0, 0, nullptr);1766if (objSym.canBeOmittedFromSymbolTable())1767newSym.exportDynamic = false;1768sym->resolve(newSym);1769}1770}17711772void BitcodeFile::parse() {1773for (std::pair<StringRef, Comdat::SelectionKind> s : obj->getComdatTable()) {1774keptComdats.push_back(1775s.second == Comdat::NoDeduplicate ||1776symtab.comdatGroups.try_emplace(CachedHashStringRef(s.first), this)1777.second);1778}17791780if (numSymbols == 0) {1781numSymbols = obj->symbols().size();1782symbols = std::make_unique<Symbol *[]>(numSymbols);1783}1784// Process defined symbols first. See the comment in1785// ObjFile<ELFT>::initializeSymbols.1786for (auto [i, irSym] : llvm::enumerate(obj->symbols()))1787if (!irSym.isUndefined())1788createBitcodeSymbol(symbols[i], keptComdats, irSym, *this);1789for (auto [i, irSym] : llvm::enumerate(obj->symbols()))1790if (irSym.isUndefined())1791createBitcodeSymbol(symbols[i], keptComdats, irSym, *this);17921793for (auto l : obj->getDependentLibraries())1794addDependentLibrary(l, this);1795}17961797void BitcodeFile::parseLazy() {1798numSymbols = obj->symbols().size();1799symbols = std::make_unique<Symbol *[]>(numSymbols);1800for (auto [i, irSym] : llvm::enumerate(obj->symbols()))1801if (!irSym.isUndefined()) {1802auto *sym = symtab.insert(saver().save(irSym.getName()));1803sym->resolve(LazySymbol{*this});1804symbols[i] = sym;1805}1806}18071808void BitcodeFile::postParse() {1809for (auto [i, irSym] : llvm::enumerate(obj->symbols())) {1810const Symbol &sym = *symbols[i];1811if (sym.file == this || !sym.isDefined() || irSym.isUndefined() ||1812irSym.isCommon() || irSym.isWeak())1813continue;1814int c = irSym.getComdatIndex();1815if (c != -1 && !keptComdats[c])1816continue;1817reportDuplicate(sym, this, nullptr, 0);1818}1819}18201821void BinaryFile::parse() {1822ArrayRef<uint8_t> data = arrayRefFromStringRef(mb.getBuffer());1823auto *section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,18248, data, ".data");1825sections.push_back(section);18261827// For each input file foo that is embedded to a result as a binary1828// blob, we define _binary_foo_{start,end,size} symbols, so that1829// user programs can access blobs by name. Non-alphanumeric1830// characters in a filename are replaced with underscore.1831std::string s = "_binary_" + mb.getBufferIdentifier().str();1832for (char &c : s)1833if (!isAlnum(c))1834c = '_';18351836llvm::StringSaver &saver = lld::saver();18371838symtab.addAndCheckDuplicate(Defined{this, saver.save(s + "_start"),1839STB_GLOBAL, STV_DEFAULT, STT_OBJECT, 0, 0,1840section});1841symtab.addAndCheckDuplicate(Defined{this, saver.save(s + "_end"), STB_GLOBAL,1842STV_DEFAULT, STT_OBJECT, data.size(), 0,1843section});1844symtab.addAndCheckDuplicate(Defined{this, saver.save(s + "_size"), STB_GLOBAL,1845STV_DEFAULT, STT_OBJECT, data.size(), 0,1846nullptr});1847}18481849InputFile *elf::createInternalFile(StringRef name) {1850auto *file =1851make<InputFile>(InputFile::InternalKind, MemoryBufferRef("", name));1852// References from an internal file do not lead to --warn-backrefs1853// diagnostics.1854file->groupId = 0;1855return file;1856}18571858ELFFileBase *elf::createObjFile(MemoryBufferRef mb, StringRef archiveName,1859bool lazy) {1860ELFFileBase *f;1861switch (getELFKind(mb, archiveName)) {1862case ELF32LEKind:1863f = make<ObjFile<ELF32LE>>(ELF32LEKind, mb, archiveName);1864break;1865case ELF32BEKind:1866f = make<ObjFile<ELF32BE>>(ELF32BEKind, mb, archiveName);1867break;1868case ELF64LEKind:1869f = make<ObjFile<ELF64LE>>(ELF64LEKind, mb, archiveName);1870break;1871case ELF64BEKind:1872f = make<ObjFile<ELF64BE>>(ELF64BEKind, mb, archiveName);1873break;1874default:1875llvm_unreachable("getELFKind");1876}1877f->init();1878f->lazy = lazy;1879return f;1880}18811882template <class ELFT> void ObjFile<ELFT>::parseLazy() {1883const ArrayRef<typename ELFT::Sym> eSyms = this->getELFSyms<ELFT>();1884numSymbols = eSyms.size();1885symbols = std::make_unique<Symbol *[]>(numSymbols);18861887// resolve() may trigger this->extract() if an existing symbol is an undefined1888// symbol. If that happens, this function has served its purpose, and we can1889// exit from the loop early.1890for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {1891if (eSyms[i].st_shndx == SHN_UNDEF)1892continue;1893symbols[i] = symtab.insert(CHECK(eSyms[i].getName(stringTable), this));1894symbols[i]->resolve(LazySymbol{*this});1895if (!lazy)1896break;1897}1898}18991900bool InputFile::shouldExtractForCommon(StringRef name) const {1901if (isa<BitcodeFile>(this))1902return isBitcodeNonCommonDef(mb, name, archiveName);19031904return isNonCommonDef(mb, name, archiveName);1905}19061907std::string elf::replaceThinLTOSuffix(StringRef path) {1908auto [suffix, repl] = config->thinLTOObjectSuffixReplace;1909if (path.consume_back(suffix))1910return (path + repl).str();1911return std::string(path);1912}19131914template class elf::ObjFile<ELF32LE>;1915template class elf::ObjFile<ELF32BE>;1916template class elf::ObjFile<ELF64LE>;1917template class elf::ObjFile<ELF64BE>;19181919template void SharedFile::parse<ELF32LE>();1920template void SharedFile::parse<ELF32BE>();1921template void SharedFile::parse<ELF64LE>();1922template void SharedFile::parse<ELF64BE>();192319241925