10b57cec5SDimitry Andric //===- InputFiles.h ---------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLD_ELF_INPUT_FILES_H 100b57cec5SDimitry Andric #define LLD_ELF_INPUT_FILES_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Config.h" 1381ad6265SDimitry Andric #include "Symbols.h" 140b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h" 150b57cec5SDimitry Andric #include "lld/Common/LLVM.h" 160b57cec5SDimitry Andric #include "lld/Common/Reproduce.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 1881ad6265SDimitry Andric #include "llvm/BinaryFormat/Magic.h" 190b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 2081ad6265SDimitry Andric #include "llvm/Support/MemoryBufferRef.h" 210b57cec5SDimitry Andric #include "llvm/Support/Threading.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace llvm { 24480093f4SDimitry Andric struct DILineInfo; 250b57cec5SDimitry Andric class TarWriter; 260b57cec5SDimitry Andric namespace lto { 270b57cec5SDimitry Andric class InputFile; 280b57cec5SDimitry Andric } 290b57cec5SDimitry Andric } // namespace llvm 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace lld { 32480093f4SDimitry Andric class DWARFCache; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Returns "<internal>", "foo.a(bar.o)" or "baz.o". 350b57cec5SDimitry Andric std::string toString(const elf::InputFile *f); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric namespace elf { 380b57cec5SDimitry Andric 390eae32dcSDimitry Andric class InputSection; 400b57cec5SDimitry Andric class Symbol; 410b57cec5SDimitry Andric 42349cc55cSDimitry Andric // If --reproduce is specified, all input files are written to this tar archive. 430b57cec5SDimitry Andric extern std::unique_ptr<llvm::TarWriter> tar; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric // Opens a given file. 46bdd1243dSDimitry Andric std::optional<MemoryBufferRef> readFile(StringRef path); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric // Add symbols in File to the symbol table. 490b57cec5SDimitry Andric void parseFile(InputFile *file); 500fca6ea1SDimitry Andric void parseFiles(const std::vector<InputFile *> &files, 510fca6ea1SDimitry Andric InputFile *armCmseImpLib); 5206c3fb27SDimitry Andric 530b57cec5SDimitry Andric // The root class of input files. 540b57cec5SDimitry Andric class InputFile { 550eae32dcSDimitry Andric protected: 56bdd1243dSDimitry Andric std::unique_ptr<Symbol *[]> symbols; 57bdd1243dSDimitry Andric uint32_t numSymbols = 0; 580eae32dcSDimitry Andric SmallVector<InputSectionBase *, 0> sections; 590eae32dcSDimitry Andric 600b57cec5SDimitry Andric public: 610eae32dcSDimitry Andric enum Kind : uint8_t { 620b57cec5SDimitry Andric ObjKind, 630b57cec5SDimitry Andric SharedKind, 640b57cec5SDimitry Andric BitcodeKind, 650b57cec5SDimitry Andric BinaryKind, 667a6dacacSDimitry Andric InternalKind, 670b57cec5SDimitry Andric }; 680b57cec5SDimitry Andric 697a6dacacSDimitry Andric InputFile(Kind k, MemoryBufferRef m); kind()700b57cec5SDimitry Andric Kind kind() const { return fileKind; } 710b57cec5SDimitry Andric isElf()720b57cec5SDimitry Andric bool isElf() const { 730b57cec5SDimitry Andric Kind k = kind(); 740b57cec5SDimitry Andric return k == ObjKind || k == SharedKind; 750b57cec5SDimitry Andric } isInternal()767a6dacacSDimitry Andric bool isInternal() const { return kind() == InternalKind; } 770b57cec5SDimitry Andric getName()780b57cec5SDimitry Andric StringRef getName() const { return mb.getBufferIdentifier(); } 790b57cec5SDimitry Andric MemoryBufferRef mb; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // Returns sections. It is a runtime error to call this function 820b57cec5SDimitry Andric // on files that don't have the notion of sections. getSections()830b57cec5SDimitry Andric ArrayRef<InputSectionBase *> getSections() const { 840b57cec5SDimitry Andric assert(fileKind == ObjKind || fileKind == BinaryKind); 850b57cec5SDimitry Andric return sections; 860b57cec5SDimitry Andric } cacheDecodedCrel(size_t i,InputSectionBase * s)87*52418fc2SDimitry Andric void cacheDecodedCrel(size_t i, InputSectionBase *s) { sections[i] = s; } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // Returns object file symbols. It is a runtime error to call this 900b57cec5SDimitry Andric // function on files of other types. getSymbols()910eae32dcSDimitry Andric ArrayRef<Symbol *> getSymbols() const { 920b57cec5SDimitry Andric assert(fileKind == BinaryKind || fileKind == ObjKind || 930b57cec5SDimitry Andric fileKind == BitcodeKind); 94bdd1243dSDimitry Andric return {symbols.get(), numSymbols}; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric getMutableSymbols()9706c3fb27SDimitry Andric MutableArrayRef<Symbol *> getMutableSymbols() { 9806c3fb27SDimitry Andric assert(fileKind == BinaryKind || fileKind == ObjKind || 9906c3fb27SDimitry Andric fileKind == BitcodeKind); 10006c3fb27SDimitry Andric return {symbols.get(), numSymbols}; 10106c3fb27SDimitry Andric } 10206c3fb27SDimitry Andric getSymbol(uint32_t symbolIndex)1030fca6ea1SDimitry Andric Symbol &getSymbol(uint32_t symbolIndex) const { 1040fca6ea1SDimitry Andric assert(fileKind == ObjKind); 1050fca6ea1SDimitry Andric if (symbolIndex >= numSymbols) 1060fca6ea1SDimitry Andric fatal(toString(this) + ": invalid symbol index"); 1070fca6ea1SDimitry Andric return *this->symbols[symbolIndex]; 1080fca6ea1SDimitry Andric } 1090fca6ea1SDimitry Andric getRelocTargetSym(const RelT & rel)1100fca6ea1SDimitry Andric template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const { 1110fca6ea1SDimitry Andric uint32_t symIndex = rel.getSymbol(config->isMips64EL); 1120fca6ea1SDimitry Andric return getSymbol(symIndex); 1130fca6ea1SDimitry Andric } 1140fca6ea1SDimitry Andric 115e8d8bef9SDimitry Andric // Get filename to use for linker script processing. 116e8d8bef9SDimitry Andric StringRef getNameForScript() const; 117e8d8bef9SDimitry Andric 1180eae32dcSDimitry Andric // Check if a non-common symbol should be extracted to override a common 1190eae32dcSDimitry Andric // definition. 1205f757f3fSDimitry Andric bool shouldExtractForCommon(StringRef name) const; 1210eae32dcSDimitry Andric 1220eae32dcSDimitry Andric // .got2 in the current file. This is used by PPC32 -fPIC/-fPIE to compute 1230eae32dcSDimitry Andric // offsets in PLT call stubs. 1240eae32dcSDimitry Andric InputSection *ppc32Got2 = nullptr; 1250eae32dcSDimitry Andric 1260eae32dcSDimitry Andric // Index of MIPS GOT built for this file. 1270eae32dcSDimitry Andric uint32_t mipsGotIndex = -1; 1280eae32dcSDimitry Andric 1290eae32dcSDimitry Andric // groupId is used for --warn-backrefs which is an optional error 1300eae32dcSDimitry Andric // checking feature. All files within the same --{start,end}-group or 1310eae32dcSDimitry Andric // --{start,end}-lib get the same group ID. Otherwise, each file gets a new 1320eae32dcSDimitry Andric // group ID. For more info, see checkDependency() in SymbolTable.cpp. 1330eae32dcSDimitry Andric uint32_t groupId; 1340eae32dcSDimitry Andric static bool isInGroup; 1350eae32dcSDimitry Andric static uint32_t nextGroupId; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric // If this is an architecture-specific file, the following members 1380b57cec5SDimitry Andric // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type. 1390b57cec5SDimitry Andric uint16_t emachine = llvm::ELF::EM_NONE; 1400eae32dcSDimitry Andric const Kind fileKind; 1410eae32dcSDimitry Andric ELFKind ekind = ELFNoneKind; 1420b57cec5SDimitry Andric uint8_t osabi = 0; 1430b57cec5SDimitry Andric uint8_t abiVersion = 0; 1440b57cec5SDimitry Andric 1457a6dacacSDimitry Andric // True if this is a relocatable object file/bitcode file in an ar archive 1467a6dacacSDimitry Andric // or between --start-lib and --end-lib. 1470eae32dcSDimitry Andric bool lazy = false; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric // True if this is an argument for --just-symbols. Usually false. 1500b57cec5SDimitry Andric bool justSymbols = false; 1510b57cec5SDimitry Andric 1525f757f3fSDimitry Andric std::string getSrcMsg(const Symbol &sym, const InputSectionBase &sec, 1530eae32dcSDimitry Andric uint64_t offset); 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric // On PPC64 we need to keep track of which files contain small code model 1560b57cec5SDimitry Andric // relocations that access the .toc section. To minimize the chance of a 1570b57cec5SDimitry Andric // relocation overflow, files that do contain said relocations should have 1580b57cec5SDimitry Andric // their .toc sections sorted closer to the .got section than files that do 1590b57cec5SDimitry Andric // not contain any small code model relocations. Thats because the toc-pointer 1600b57cec5SDimitry Andric // is defined to point at .got + 0x8000 and the instructions used with small 1610b57cec5SDimitry Andric // code model relocations support immediates in the range [-0x8000, 0x7FFC], 1620b57cec5SDimitry Andric // making the addressable range relative to the toc pointer 1630b57cec5SDimitry Andric // [.got, .got + 0xFFFC]. 1640b57cec5SDimitry Andric bool ppc64SmallCodeModelTocRelocs = false; 1650b57cec5SDimitry Andric 166e8d8bef9SDimitry Andric // True if the file has TLSGD/TLSLD GOT relocations without R_PPC64_TLSGD or 167e8d8bef9SDimitry Andric // R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation. 168e8d8bef9SDimitry Andric bool ppc64DisableTLSRelax = false; 169e8d8bef9SDimitry Andric 1701fd87a68SDimitry Andric public: 1711fd87a68SDimitry Andric // If not empty, this stores the name of the archive containing this file. 1721fd87a68SDimitry Andric // We use this string for creating error messages. 1731fd87a68SDimitry Andric SmallString<0> archiveName; 1741fd87a68SDimitry Andric // Cache for toString(). Only toString() should use this member. 1751fd87a68SDimitry Andric mutable SmallString<0> toStringCache; 1761fd87a68SDimitry Andric 1771fd87a68SDimitry Andric private: 1781fd87a68SDimitry Andric // Cache for getNameForScript(). 1791fd87a68SDimitry Andric mutable SmallString<0> nameForScriptCache; 1800b57cec5SDimitry Andric }; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric class ELFFileBase : public InputFile { 1830b57cec5SDimitry Andric public: 184bdd1243dSDimitry Andric ELFFileBase(Kind k, ELFKind ekind, MemoryBufferRef m); classof(const InputFile * f)1850b57cec5SDimitry Andric static bool classof(const InputFile *f) { return f->isElf(); } 1860b57cec5SDimitry Andric 187bdd1243dSDimitry Andric void init(); getObj()1880b57cec5SDimitry Andric template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const { 1890b57cec5SDimitry Andric return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer())); 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric getStringTable()1920b57cec5SDimitry Andric StringRef getStringTable() const { return stringTable; } 1930b57cec5SDimitry Andric getLocalSymbols()1944824e7fdSDimitry Andric ArrayRef<Symbol *> getLocalSymbols() { 195bdd1243dSDimitry Andric if (numSymbols == 0) 1964824e7fdSDimitry Andric return {}; 197bdd1243dSDimitry Andric return llvm::ArrayRef(symbols.get() + 1, firstGlobal - 1); 1984824e7fdSDimitry Andric } getGlobalSymbols()1994824e7fdSDimitry Andric ArrayRef<Symbol *> getGlobalSymbols() { 200bdd1243dSDimitry Andric return llvm::ArrayRef(symbols.get() + firstGlobal, 201bdd1243dSDimitry Andric numSymbols - firstGlobal); 2024824e7fdSDimitry Andric } getMutableGlobalSymbols()2030eae32dcSDimitry Andric MutableArrayRef<Symbol *> getMutableGlobalSymbols() { 204bdd1243dSDimitry Andric return llvm::MutableArrayRef(symbols.get() + firstGlobal, 205bdd1243dSDimitry Andric numSymbols - firstGlobal); 2060eae32dcSDimitry Andric } 2074824e7fdSDimitry Andric getELFShdrs()2080eae32dcSDimitry Andric template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const { 2090eae32dcSDimitry Andric return typename ELFT::ShdrRange( 2100eae32dcSDimitry Andric reinterpret_cast<const typename ELFT::Shdr *>(elfShdrs), numELFShdrs); 2110eae32dcSDimitry Andric } getELFSyms()2120b57cec5SDimitry Andric template <typename ELFT> typename ELFT::SymRange getELFSyms() const { 2130b57cec5SDimitry Andric return typename ELFT::SymRange( 2140b57cec5SDimitry Andric reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms); 2150b57cec5SDimitry Andric } getGlobalELFSyms()2160b57cec5SDimitry Andric template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const { 2170b57cec5SDimitry Andric return getELFSyms<ELFT>().slice(firstGlobal); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric protected: 2210b57cec5SDimitry Andric // Initializes this class's member variables. 222bdd1243dSDimitry Andric template <typename ELFT> void init(InputFile::Kind k); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric StringRef stringTable; 2250eae32dcSDimitry Andric const void *elfShdrs = nullptr; 2260eae32dcSDimitry Andric const void *elfSyms = nullptr; 2270eae32dcSDimitry Andric uint32_t numELFShdrs = 0; 2280eae32dcSDimitry Andric uint32_t numELFSyms = 0; 2290eae32dcSDimitry Andric uint32_t firstGlobal = 0; 2300eae32dcSDimitry Andric 2310eae32dcSDimitry Andric public: 2321fd87a68SDimitry Andric uint32_t andFeatures = 0; 2330eae32dcSDimitry Andric bool hasCommonSyms = false; 2340fca6ea1SDimitry Andric ArrayRef<uint8_t> aarch64PauthAbiCoreInfo; 2350b57cec5SDimitry Andric }; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric // .o file. 2380b57cec5SDimitry Andric template <class ELFT> class ObjFile : public ELFFileBase { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)239e8d8bef9SDimitry Andric LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric public: 2420b57cec5SDimitry Andric static bool classof(const InputFile *f) { return f->kind() == ObjKind; } 2430b57cec5SDimitry Andric getObj()2440b57cec5SDimitry Andric llvm::object::ELFFile<ELFT> getObj() const { 2450b57cec5SDimitry Andric return this->ELFFileBase::getObj<ELFT>(); 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric ObjFile(ELFKind ekind,MemoryBufferRef m,StringRef archiveName)248bdd1243dSDimitry Andric ObjFile(ELFKind ekind, MemoryBufferRef m, StringRef archiveName) 249bdd1243dSDimitry Andric : ELFFileBase(ObjKind, ekind, m) { 2500eae32dcSDimitry Andric this->archiveName = archiveName; 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric void parse(bool ignoreComdats = false); 2540eae32dcSDimitry Andric void parseLazy(); 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections, 2570b57cec5SDimitry Andric const Elf_Shdr &sec); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric uint32_t getSectionIndex(const Elf_Sym &sym) const; 2600b57cec5SDimitry Andric 2615f757f3fSDimitry Andric std::optional<llvm::DILineInfo> getDILineInfo(const InputSectionBase *, 2625f757f3fSDimitry Andric uint64_t); 263bdd1243dSDimitry Andric std::optional<std::pair<std::string, unsigned>> 264bdd1243dSDimitry Andric getVariableLoc(StringRef name); 2650b57cec5SDimitry Andric 2660eae32dcSDimitry Andric // Name of source file obtained from STT_FILE symbol value, 2670eae32dcSDimitry Andric // or empty string if there is no such symbol in object file 2680eae32dcSDimitry Andric // symbol table. 2690eae32dcSDimitry Andric StringRef sourceFile; 2700eae32dcSDimitry Andric 2710eae32dcSDimitry Andric // Pointer to this input file's .llvm_addrsig section, if it has one. 2720eae32dcSDimitry Andric const Elf_Shdr *addrsigSec = nullptr; 2730eae32dcSDimitry Andric 2740eae32dcSDimitry Andric // SHT_LLVM_CALL_GRAPH_PROFILE section index. 2750eae32dcSDimitry Andric uint32_t cgProfileSectionIndex = 0; 2760eae32dcSDimitry Andric 2770b57cec5SDimitry Andric // MIPS GP0 value defined by this file. This value represents the gp value 2780b57cec5SDimitry Andric // used to create the relocatable object and required to support 2790b57cec5SDimitry Andric // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. 2800b57cec5SDimitry Andric uint32_t mipsGp0 = 0; 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric // True if the file defines functions compiled with 2830b57cec5SDimitry Andric // -fsplit-stack. Usually false. 2840b57cec5SDimitry Andric bool splitStack = false; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // True if the file defines functions compiled with -fsplit-stack, 2870b57cec5SDimitry Andric // but had one or more functions with the no_split_stack attribute. 2880b57cec5SDimitry Andric bool someNoSplitStack = false; 2890b57cec5SDimitry Andric 2905ffd83dbSDimitry Andric // Get cached DWARF information. 2915ffd83dbSDimitry Andric DWARFCache *getDwarf(); 2925ffd83dbSDimitry Andric 293bdd1243dSDimitry Andric void initSectionsAndLocalSyms(bool ignoreComdats); 29481ad6265SDimitry Andric void postParse(); 29506c3fb27SDimitry Andric void importCmseSymbols(); 29681ad6265SDimitry Andric 2970b57cec5SDimitry Andric private: 2981fd87a68SDimitry Andric void initializeSections(bool ignoreComdats, 2991fd87a68SDimitry Andric const llvm::object::ELFFile<ELFT> &obj); 3001fd87a68SDimitry Andric void initializeSymbols(const llvm::object::ELFFile<ELFT> &obj); 3010b57cec5SDimitry Andric void initializeJustSymbols(); 3025ffd83dbSDimitry Andric 3030fca6ea1SDimitry Andric InputSectionBase *getRelocTarget(uint32_t idx, uint32_t info); 304349cc55cSDimitry Andric InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec, 3051fd87a68SDimitry Andric StringRef name); 3060b57cec5SDimitry Andric 30785868e8aSDimitry Andric bool shouldMerge(const Elf_Shdr &sec, StringRef name); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // Each ELF symbol contains a section index which the symbol belongs to. 3100b57cec5SDimitry Andric // However, because the number of bits dedicated for that is limited, a 3110b57cec5SDimitry Andric // symbol can directly point to a section only when the section index is 3120b57cec5SDimitry Andric // equal to or smaller than 65280. 3130b57cec5SDimitry Andric // 3140b57cec5SDimitry Andric // If an object file contains more than 65280 sections, the file must 3150b57cec5SDimitry Andric // contain .symtab_shndx section. The section contains an array of 3160b57cec5SDimitry Andric // 32-bit integers whose size is the same as the number of symbols. 3170b57cec5SDimitry Andric // Nth symbol's section index is in the Nth entry of .symtab_shndx. 3180b57cec5SDimitry Andric // 3190b57cec5SDimitry Andric // The following variable contains the contents of .symtab_shndx. 3200b57cec5SDimitry Andric // If the section does not exist (which is common), the array is empty. 3210b57cec5SDimitry Andric ArrayRef<Elf_Word> shndxTable; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric // Debugging information to retrieve source file and line for error 3240b57cec5SDimitry Andric // reporting. Linker may find reasonable number of errors in a 3250b57cec5SDimitry Andric // single object file, so we cache debugging information in order to 3260b57cec5SDimitry Andric // parse it only once for each object file we link. 3275ffd83dbSDimitry Andric std::unique_ptr<DWARFCache> dwarf; 3285ffd83dbSDimitry Andric llvm::once_flag initDwarf; 3290b57cec5SDimitry Andric }; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric class BitcodeFile : public InputFile { 3320b57cec5SDimitry Andric public: 3330b57cec5SDimitry Andric BitcodeFile(MemoryBufferRef m, StringRef archiveName, 3340eae32dcSDimitry Andric uint64_t offsetInArchive, bool lazy); classof(const InputFile * f)3350b57cec5SDimitry Andric static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } 336bdd1243dSDimitry Andric void parse(); 3370eae32dcSDimitry Andric void parseLazy(); 33881ad6265SDimitry Andric void postParse(); 3390b57cec5SDimitry Andric std::unique_ptr<llvm::lto::InputFile> obj; 34081ad6265SDimitry Andric std::vector<bool> keptComdats; 3410b57cec5SDimitry Andric }; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // .so file. 3440b57cec5SDimitry Andric class SharedFile : public ELFFileBase { 3450b57cec5SDimitry Andric public: 346bdd1243dSDimitry Andric SharedFile(MemoryBufferRef m, StringRef defaultSoName); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // This is actually a vector of Elf_Verdef pointers. 3490eae32dcSDimitry Andric SmallVector<const void *, 0> verdefs; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // If the output file needs Elf_Verneed data structures for this file, this is 3520b57cec5SDimitry Andric // a vector of Elf_Vernaux version identifiers that map onto the entries in 3530b57cec5SDimitry Andric // Verdefs, otherwise it is empty. 3540eae32dcSDimitry Andric SmallVector<uint32_t, 0> vernauxs; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric static unsigned vernauxNum; 3570b57cec5SDimitry Andric 3580eae32dcSDimitry Andric SmallVector<StringRef, 0> dtNeeded; 359349cc55cSDimitry Andric StringRef soName; 3600b57cec5SDimitry Andric classof(const InputFile * f)3610b57cec5SDimitry Andric static bool classof(const InputFile *f) { return f->kind() == SharedKind; } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric template <typename ELFT> void parse(); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // Used for --as-needed 3660b57cec5SDimitry Andric bool isNeeded; 3675ffd83dbSDimitry Andric 368fe6060f1SDimitry Andric // Non-weak undefined symbols which are not yet resolved when the SO is 369fe6060f1SDimitry Andric // parsed. Only filled for `--no-allow-shlib-undefined`. 3700eae32dcSDimitry Andric SmallVector<Symbol *, 0> requiredSymbols; 371fe6060f1SDimitry Andric 3725ffd83dbSDimitry Andric private: 3735ffd83dbSDimitry Andric template <typename ELFT> 3745ffd83dbSDimitry Andric std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj, 3755ffd83dbSDimitry Andric const typename ELFT::Shdr *sec); 3760b57cec5SDimitry Andric }; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric class BinaryFile : public InputFile { 3790b57cec5SDimitry Andric public: BinaryFile(MemoryBufferRef m)3800b57cec5SDimitry Andric explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {} classof(const InputFile * f)3810b57cec5SDimitry Andric static bool classof(const InputFile *f) { return f->kind() == BinaryKind; } 3820b57cec5SDimitry Andric void parse(); 3830b57cec5SDimitry Andric }; 3840b57cec5SDimitry Andric 3857a6dacacSDimitry Andric InputFile *createInternalFile(StringRef name); 386fcaf7f86SDimitry Andric ELFFileBase *createObjFile(MemoryBufferRef mb, StringRef archiveName = "", 387fcaf7f86SDimitry Andric bool lazy = false); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric std::string replaceThinLTOSuffix(StringRef path); 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric } // namespace elf 3920b57cec5SDimitry Andric } // namespace lld 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric #endif 395