Path: blob/main/contrib/llvm-project/lld/ELF/InputFiles.h
34869 views
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//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#ifndef LLD_ELF_INPUT_FILES_H9#define LLD_ELF_INPUT_FILES_H1011#include "Config.h"12#include "Symbols.h"13#include "lld/Common/ErrorHandler.h"14#include "lld/Common/LLVM.h"15#include "lld/Common/Reproduce.h"16#include "llvm/ADT/DenseSet.h"17#include "llvm/BinaryFormat/Magic.h"18#include "llvm/Object/ELF.h"19#include "llvm/Support/MemoryBufferRef.h"20#include "llvm/Support/Threading.h"2122namespace llvm {23struct DILineInfo;24class TarWriter;25namespace lto {26class InputFile;27}28} // namespace llvm2930namespace lld {31class DWARFCache;3233// Returns "<internal>", "foo.a(bar.o)" or "baz.o".34std::string toString(const elf::InputFile *f);3536namespace elf {3738class InputSection;39class Symbol;4041// If --reproduce is specified, all input files are written to this tar archive.42extern std::unique_ptr<llvm::TarWriter> tar;4344// Opens a given file.45std::optional<MemoryBufferRef> readFile(StringRef path);4647// Add symbols in File to the symbol table.48void parseFile(InputFile *file);49void parseFiles(const std::vector<InputFile *> &files,50InputFile *armCmseImpLib);5152// The root class of input files.53class InputFile {54protected:55std::unique_ptr<Symbol *[]> symbols;56uint32_t numSymbols = 0;57SmallVector<InputSectionBase *, 0> sections;5859public:60enum Kind : uint8_t {61ObjKind,62SharedKind,63BitcodeKind,64BinaryKind,65InternalKind,66};6768InputFile(Kind k, MemoryBufferRef m);69Kind kind() const { return fileKind; }7071bool isElf() const {72Kind k = kind();73return k == ObjKind || k == SharedKind;74}75bool isInternal() const { return kind() == InternalKind; }7677StringRef getName() const { return mb.getBufferIdentifier(); }78MemoryBufferRef mb;7980// Returns sections. It is a runtime error to call this function81// on files that don't have the notion of sections.82ArrayRef<InputSectionBase *> getSections() const {83assert(fileKind == ObjKind || fileKind == BinaryKind);84return sections;85}86void cacheDecodedCrel(size_t i, InputSectionBase *s) { sections[i] = s; }8788// Returns object file symbols. It is a runtime error to call this89// function on files of other types.90ArrayRef<Symbol *> getSymbols() const {91assert(fileKind == BinaryKind || fileKind == ObjKind ||92fileKind == BitcodeKind);93return {symbols.get(), numSymbols};94}9596MutableArrayRef<Symbol *> getMutableSymbols() {97assert(fileKind == BinaryKind || fileKind == ObjKind ||98fileKind == BitcodeKind);99return {symbols.get(), numSymbols};100}101102Symbol &getSymbol(uint32_t symbolIndex) const {103assert(fileKind == ObjKind);104if (symbolIndex >= numSymbols)105fatal(toString(this) + ": invalid symbol index");106return *this->symbols[symbolIndex];107}108109template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {110uint32_t symIndex = rel.getSymbol(config->isMips64EL);111return getSymbol(symIndex);112}113114// Get filename to use for linker script processing.115StringRef getNameForScript() const;116117// Check if a non-common symbol should be extracted to override a common118// definition.119bool shouldExtractForCommon(StringRef name) const;120121// .got2 in the current file. This is used by PPC32 -fPIC/-fPIE to compute122// offsets in PLT call stubs.123InputSection *ppc32Got2 = nullptr;124125// Index of MIPS GOT built for this file.126uint32_t mipsGotIndex = -1;127128// groupId is used for --warn-backrefs which is an optional error129// checking feature. All files within the same --{start,end}-group or130// --{start,end}-lib get the same group ID. Otherwise, each file gets a new131// group ID. For more info, see checkDependency() in SymbolTable.cpp.132uint32_t groupId;133static bool isInGroup;134static uint32_t nextGroupId;135136// If this is an architecture-specific file, the following members137// have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.138uint16_t emachine = llvm::ELF::EM_NONE;139const Kind fileKind;140ELFKind ekind = ELFNoneKind;141uint8_t osabi = 0;142uint8_t abiVersion = 0;143144// True if this is a relocatable object file/bitcode file in an ar archive145// or between --start-lib and --end-lib.146bool lazy = false;147148// True if this is an argument for --just-symbols. Usually false.149bool justSymbols = false;150151std::string getSrcMsg(const Symbol &sym, const InputSectionBase &sec,152uint64_t offset);153154// On PPC64 we need to keep track of which files contain small code model155// relocations that access the .toc section. To minimize the chance of a156// relocation overflow, files that do contain said relocations should have157// their .toc sections sorted closer to the .got section than files that do158// not contain any small code model relocations. Thats because the toc-pointer159// is defined to point at .got + 0x8000 and the instructions used with small160// code model relocations support immediates in the range [-0x8000, 0x7FFC],161// making the addressable range relative to the toc pointer162// [.got, .got + 0xFFFC].163bool ppc64SmallCodeModelTocRelocs = false;164165// True if the file has TLSGD/TLSLD GOT relocations without R_PPC64_TLSGD or166// R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation.167bool ppc64DisableTLSRelax = false;168169public:170// If not empty, this stores the name of the archive containing this file.171// We use this string for creating error messages.172SmallString<0> archiveName;173// Cache for toString(). Only toString() should use this member.174mutable SmallString<0> toStringCache;175176private:177// Cache for getNameForScript().178mutable SmallString<0> nameForScriptCache;179};180181class ELFFileBase : public InputFile {182public:183ELFFileBase(Kind k, ELFKind ekind, MemoryBufferRef m);184static bool classof(const InputFile *f) { return f->isElf(); }185186void init();187template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {188return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer()));189}190191StringRef getStringTable() const { return stringTable; }192193ArrayRef<Symbol *> getLocalSymbols() {194if (numSymbols == 0)195return {};196return llvm::ArrayRef(symbols.get() + 1, firstGlobal - 1);197}198ArrayRef<Symbol *> getGlobalSymbols() {199return llvm::ArrayRef(symbols.get() + firstGlobal,200numSymbols - firstGlobal);201}202MutableArrayRef<Symbol *> getMutableGlobalSymbols() {203return llvm::MutableArrayRef(symbols.get() + firstGlobal,204numSymbols - firstGlobal);205}206207template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {208return typename ELFT::ShdrRange(209reinterpret_cast<const typename ELFT::Shdr *>(elfShdrs), numELFShdrs);210}211template <typename ELFT> typename ELFT::SymRange getELFSyms() const {212return typename ELFT::SymRange(213reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);214}215template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {216return getELFSyms<ELFT>().slice(firstGlobal);217}218219protected:220// Initializes this class's member variables.221template <typename ELFT> void init(InputFile::Kind k);222223StringRef stringTable;224const void *elfShdrs = nullptr;225const void *elfSyms = nullptr;226uint32_t numELFShdrs = 0;227uint32_t numELFSyms = 0;228uint32_t firstGlobal = 0;229230public:231uint32_t andFeatures = 0;232bool hasCommonSyms = false;233ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;234};235236// .o file.237template <class ELFT> class ObjFile : public ELFFileBase {238LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)239240public:241static bool classof(const InputFile *f) { return f->kind() == ObjKind; }242243llvm::object::ELFFile<ELFT> getObj() const {244return this->ELFFileBase::getObj<ELFT>();245}246247ObjFile(ELFKind ekind, MemoryBufferRef m, StringRef archiveName)248: ELFFileBase(ObjKind, ekind, m) {249this->archiveName = archiveName;250}251252void parse(bool ignoreComdats = false);253void parseLazy();254255StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections,256const Elf_Shdr &sec);257258uint32_t getSectionIndex(const Elf_Sym &sym) const;259260std::optional<llvm::DILineInfo> getDILineInfo(const InputSectionBase *,261uint64_t);262std::optional<std::pair<std::string, unsigned>>263getVariableLoc(StringRef name);264265// Name of source file obtained from STT_FILE symbol value,266// or empty string if there is no such symbol in object file267// symbol table.268StringRef sourceFile;269270// Pointer to this input file's .llvm_addrsig section, if it has one.271const Elf_Shdr *addrsigSec = nullptr;272273// SHT_LLVM_CALL_GRAPH_PROFILE section index.274uint32_t cgProfileSectionIndex = 0;275276// MIPS GP0 value defined by this file. This value represents the gp value277// used to create the relocatable object and required to support278// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.279uint32_t mipsGp0 = 0;280281// True if the file defines functions compiled with282// -fsplit-stack. Usually false.283bool splitStack = false;284285// True if the file defines functions compiled with -fsplit-stack,286// but had one or more functions with the no_split_stack attribute.287bool someNoSplitStack = false;288289// Get cached DWARF information.290DWARFCache *getDwarf();291292void initSectionsAndLocalSyms(bool ignoreComdats);293void postParse();294void importCmseSymbols();295296private:297void initializeSections(bool ignoreComdats,298const llvm::object::ELFFile<ELFT> &obj);299void initializeSymbols(const llvm::object::ELFFile<ELFT> &obj);300void initializeJustSymbols();301302InputSectionBase *getRelocTarget(uint32_t idx, uint32_t info);303InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec,304StringRef name);305306bool shouldMerge(const Elf_Shdr &sec, StringRef name);307308// Each ELF symbol contains a section index which the symbol belongs to.309// However, because the number of bits dedicated for that is limited, a310// symbol can directly point to a section only when the section index is311// equal to or smaller than 65280.312//313// If an object file contains more than 65280 sections, the file must314// contain .symtab_shndx section. The section contains an array of315// 32-bit integers whose size is the same as the number of symbols.316// Nth symbol's section index is in the Nth entry of .symtab_shndx.317//318// The following variable contains the contents of .symtab_shndx.319// If the section does not exist (which is common), the array is empty.320ArrayRef<Elf_Word> shndxTable;321322// Debugging information to retrieve source file and line for error323// reporting. Linker may find reasonable number of errors in a324// single object file, so we cache debugging information in order to325// parse it only once for each object file we link.326std::unique_ptr<DWARFCache> dwarf;327llvm::once_flag initDwarf;328};329330class BitcodeFile : public InputFile {331public:332BitcodeFile(MemoryBufferRef m, StringRef archiveName,333uint64_t offsetInArchive, bool lazy);334static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }335void parse();336void parseLazy();337void postParse();338std::unique_ptr<llvm::lto::InputFile> obj;339std::vector<bool> keptComdats;340};341342// .so file.343class SharedFile : public ELFFileBase {344public:345SharedFile(MemoryBufferRef m, StringRef defaultSoName);346347// This is actually a vector of Elf_Verdef pointers.348SmallVector<const void *, 0> verdefs;349350// If the output file needs Elf_Verneed data structures for this file, this is351// a vector of Elf_Vernaux version identifiers that map onto the entries in352// Verdefs, otherwise it is empty.353SmallVector<uint32_t, 0> vernauxs;354355static unsigned vernauxNum;356357SmallVector<StringRef, 0> dtNeeded;358StringRef soName;359360static bool classof(const InputFile *f) { return f->kind() == SharedKind; }361362template <typename ELFT> void parse();363364// Used for --as-needed365bool isNeeded;366367// Non-weak undefined symbols which are not yet resolved when the SO is368// parsed. Only filled for `--no-allow-shlib-undefined`.369SmallVector<Symbol *, 0> requiredSymbols;370371private:372template <typename ELFT>373std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj,374const typename ELFT::Shdr *sec);375};376377class BinaryFile : public InputFile {378public:379explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {}380static bool classof(const InputFile *f) { return f->kind() == BinaryKind; }381void parse();382};383384InputFile *createInternalFile(StringRef name);385ELFFileBase *createObjFile(MemoryBufferRef mb, StringRef archiveName = "",386bool lazy = false);387388std::string replaceThinLTOSuffix(StringRef path);389390} // namespace elf391} // namespace lld392393#endif394395396