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