1ece8a530Spatrick //===- SymbolTable.h --------------------------------------------*- C++ -*-===// 2ece8a530Spatrick // 3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information. 5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ece8a530Spatrick // 7ece8a530Spatrick //===----------------------------------------------------------------------===// 8ece8a530Spatrick 9ece8a530Spatrick #ifndef LLD_COFF_SYMBOL_TABLE_H 10ece8a530Spatrick #define LLD_COFF_SYMBOL_TABLE_H 11ece8a530Spatrick 12ece8a530Spatrick #include "InputFiles.h" 13ece8a530Spatrick #include "LTO.h" 14ece8a530Spatrick #include "llvm/ADT/CachedHashString.h" 15ece8a530Spatrick #include "llvm/ADT/DenseMap.h" 16ece8a530Spatrick #include "llvm/ADT/DenseMapInfo.h" 17ece8a530Spatrick #include "llvm/Support/raw_ostream.h" 18ece8a530Spatrick 19ece8a530Spatrick namespace llvm { 20ece8a530Spatrick struct LTOCodeGenerator; 21ece8a530Spatrick } 22ece8a530Spatrick 23*dfe94b16Srobert namespace lld::coff { 24ece8a530Spatrick 25ece8a530Spatrick class Chunk; 26ece8a530Spatrick class CommonChunk; 27*dfe94b16Srobert class COFFLinkerContext; 28ece8a530Spatrick class Defined; 29ece8a530Spatrick class DefinedAbsolute; 30ece8a530Spatrick class DefinedRegular; 31ece8a530Spatrick class DefinedRelative; 32ece8a530Spatrick class LazyArchive; 33ece8a530Spatrick class SectionChunk; 34ece8a530Spatrick class Symbol; 35ece8a530Spatrick 36ece8a530Spatrick // SymbolTable is a bucket of all known symbols, including defined, 37ece8a530Spatrick // undefined, or lazy symbols (the last one is symbols in archive 38ece8a530Spatrick // files whose archive members are not yet loaded). 39ece8a530Spatrick // 40ece8a530Spatrick // We put all symbols of all files to a SymbolTable, and the 41ece8a530Spatrick // SymbolTable selects the "best" symbols if there are name 42ece8a530Spatrick // conflicts. For example, obviously, a defined symbol is better than 43ece8a530Spatrick // an undefined symbol. Or, if there's a conflict between a lazy and a 44ece8a530Spatrick // undefined, it'll read an archive member to read a real definition 45ece8a530Spatrick // to replace the lazy symbol. The logic is implemented in the 46ece8a530Spatrick // add*() functions, which are called by input files as they are parsed. 47ece8a530Spatrick // There is one add* function per symbol type. 48ece8a530Spatrick class SymbolTable { 49ece8a530Spatrick public: SymbolTable(COFFLinkerContext & c)50*dfe94b16Srobert SymbolTable(COFFLinkerContext &c) : ctx(c) {} 51*dfe94b16Srobert 52ece8a530Spatrick void addFile(InputFile *file); 53ece8a530Spatrick 54ece8a530Spatrick // Emit errors for symbols that cannot be resolved. 55ece8a530Spatrick void reportUnresolvable(); 56ece8a530Spatrick 57ece8a530Spatrick // Try to resolve any undefined symbols and update the symbol table 58ece8a530Spatrick // accordingly, then print an error message for any remaining undefined 59ece8a530Spatrick // symbols and warn about imported local symbols. 60ece8a530Spatrick void resolveRemainingUndefines(); 61ece8a530Spatrick 621cf9926bSpatrick // Load lazy objects that are needed for MinGW automatic import and for 631cf9926bSpatrick // doing stdcall fixups. 641cf9926bSpatrick void loadMinGWSymbols(); 65ece8a530Spatrick bool handleMinGWAutomaticImport(Symbol *sym, StringRef name); 66ece8a530Spatrick 67ece8a530Spatrick // Returns a list of chunks of selected symbols. 68*dfe94b16Srobert std::vector<Chunk *> getChunks() const; 69ece8a530Spatrick 70ece8a530Spatrick // Returns a symbol for a given name. Returns a nullptr if not found. 71*dfe94b16Srobert Symbol *find(StringRef name) const; 72*dfe94b16Srobert Symbol *findUnderscore(StringRef name) const; 73ece8a530Spatrick 74ece8a530Spatrick // Occasionally we have to resolve an undefined symbol to its 75ece8a530Spatrick // mangled symbol. This function tries to find a mangled name 76ece8a530Spatrick // for U from the symbol table, and if found, set the symbol as 77ece8a530Spatrick // a weak alias for U. 78ece8a530Spatrick Symbol *findMangle(StringRef name); 79ece8a530Spatrick 80ece8a530Spatrick // Build a set of COFF objects representing the combined contents of 81ece8a530Spatrick // BitcodeFiles and add them to the symbol table. Called after all files are 82ece8a530Spatrick // added and before the writer writes results to a file. 83*dfe94b16Srobert void compileBitcodeFiles(); 84ece8a530Spatrick 85ece8a530Spatrick // Creates an Undefined symbol for a given name. 86ece8a530Spatrick Symbol *addUndefined(StringRef name); 87ece8a530Spatrick 88ece8a530Spatrick Symbol *addSynthetic(StringRef n, Chunk *c); 89ece8a530Spatrick Symbol *addAbsolute(StringRef n, uint64_t va); 90ece8a530Spatrick 91ece8a530Spatrick Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias); 92ece8a530Spatrick void addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym); 93*dfe94b16Srobert void addLazyObject(InputFile *f, StringRef n); 941cf9926bSpatrick void addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym, StringRef n); 95ece8a530Spatrick Symbol *addAbsolute(StringRef n, COFFSymbolRef s); 96ece8a530Spatrick Symbol *addRegular(InputFile *f, StringRef n, 97ece8a530Spatrick const llvm::object::coff_symbol_generic *s = nullptr, 98*dfe94b16Srobert SectionChunk *c = nullptr, uint32_t sectionOffset = 0, 99*dfe94b16Srobert bool isWeak = false); 100ece8a530Spatrick std::pair<DefinedRegular *, bool> 101ece8a530Spatrick addComdat(InputFile *f, StringRef n, 102ece8a530Spatrick const llvm::object::coff_symbol_generic *s = nullptr); 103ece8a530Spatrick Symbol *addCommon(InputFile *f, StringRef n, uint64_t size, 104ece8a530Spatrick const llvm::object::coff_symbol_generic *s = nullptr, 105ece8a530Spatrick CommonChunk *c = nullptr); 106ece8a530Spatrick Symbol *addImportData(StringRef n, ImportFile *f); 107ece8a530Spatrick Symbol *addImportThunk(StringRef name, DefinedImportData *s, 108ece8a530Spatrick uint16_t machine); 109ece8a530Spatrick void addLibcall(StringRef name); 110ece8a530Spatrick 111ece8a530Spatrick void reportDuplicate(Symbol *existing, InputFile *newFile, 112ece8a530Spatrick SectionChunk *newSc = nullptr, 113ece8a530Spatrick uint32_t newSectionOffset = 0); 114ece8a530Spatrick 115ece8a530Spatrick // A list of chunks which to be added to .rdata. 116ece8a530Spatrick std::vector<Chunk *> localImportChunks; 117ece8a530Spatrick 118ece8a530Spatrick // Iterates symbols in non-determinstic hash table order. forEachSymbol(T callback)119ece8a530Spatrick template <typename T> void forEachSymbol(T callback) { 120ece8a530Spatrick for (auto &pair : symMap) 121ece8a530Spatrick callback(pair.second); 122ece8a530Spatrick } 123ece8a530Spatrick 124ece8a530Spatrick private: 125ece8a530Spatrick /// Given a name without "__imp_" prefix, returns a defined symbol 126ece8a530Spatrick /// with the "__imp_" prefix, if it exists. 127ece8a530Spatrick Defined *impSymbol(StringRef name); 128ece8a530Spatrick /// Inserts symbol if not already present. 129ece8a530Spatrick std::pair<Symbol *, bool> insert(StringRef name); 130ece8a530Spatrick /// Same as insert(Name), but also sets isUsedInRegularObj. 131ece8a530Spatrick std::pair<Symbol *, bool> insert(StringRef name, InputFile *f); 132ece8a530Spatrick 133ece8a530Spatrick std::vector<Symbol *> getSymsWithPrefix(StringRef prefix); 134ece8a530Spatrick 135ece8a530Spatrick llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> symMap; 136ece8a530Spatrick std::unique_ptr<BitcodeCompiler> lto; 137ece8a530Spatrick 138*dfe94b16Srobert COFFLinkerContext &ctx; 139*dfe94b16Srobert }; 140ece8a530Spatrick 141ece8a530Spatrick std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex); 142ece8a530Spatrick 1431cf9926bSpatrick StringRef ltrim1(StringRef s, const char *chars); 1441cf9926bSpatrick 145*dfe94b16Srobert } // namespace lld::coff 146ece8a530Spatrick 147ece8a530Spatrick #endif 148