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/ADT/SmallPtrSet.h"
18#include "llvm/Support/raw_ostream.h"
19
20namespace llvm {
21struct LTOCodeGenerator;
22}
23
24namespace lld::coff {
25
26class Chunk;
27class CommonChunk;
28class COFFLinkerContext;
29class Defined;
30class DefinedAbsolute;
31class DefinedRegular;
32class ImportThunkChunk;
33class LazyArchive;
34class SameAddressThunkARM64EC;
35class SectionChunk;
36class Symbol;
37
38// This data structure is instantiated for each -wrap option.
39struct WrappedSymbol {
40 Symbol *sym;
41 Symbol *real;
42 Symbol *wrap;
43};
44
45struct UndefinedDiag;
46
47// SymbolTable is a bucket of all known symbols, including defined,
48// undefined, or lazy symbols (the last one is symbols in archive
49// files whose archive members are not yet loaded).
50//
51// We put all symbols of all files to a SymbolTable, and the
52// SymbolTable selects the "best" symbols if there are name
53// conflicts. For example, obviously, a defined symbol is better than
54// an undefined symbol. Or, if there's a conflict between a lazy and a
55// undefined, it'll read an archive member to read a real definition
56// to replace the lazy symbol. The logic is implemented in the
57// add*() functions, which are called by input files as they are parsed.
58// There is one add* function per symbol type.
59class SymbolTable {
60public:
61 SymbolTable(COFFLinkerContext &c,
62 llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN)
63 : ctx(c), machine(machine) {}
64
65 // Emit errors for symbols that cannot be resolved.
66 void reportUnresolvable();
67
68 // Try to resolve any undefined symbols and update the symbol table
69 // accordingly, then print an error message for any remaining undefined
70 // symbols and warn about imported local symbols.
71 void resolveRemainingUndefines(std::vector<Undefined *> &aliases);
72
73 // Try to resolve undefined symbols with alternate names.
74 void resolveAlternateNames();
75
76 // Load lazy objects that are needed for MinGW automatic import and for
77 // doing stdcall fixups.
78 void loadMinGWSymbols();
79 bool handleMinGWAutomaticImport(Symbol *sym, StringRef name);
80
81 // Returns a symbol for a given name. Returns a nullptr if not found.
82 Symbol *find(StringRef name) const;
83 Symbol *findUnderscore(StringRef name) const;
84
85 void addUndefinedGlob(StringRef arg);
86
87 // Occasionally we have to resolve an undefined symbol to its
88 // mangled symbol. This function tries to find a mangled name
89 // for U from the symbol table, and if found, set the symbol as
90 // a weak alias for U.
91 Symbol *findMangle(StringRef name);
92 StringRef mangleMaybe(Symbol *s);
93
94 // Symbol names are mangled by prepending "_" on x86.
95 StringRef mangle(StringRef sym);
96
97 // Windows specific -- "main" is not the only main function in Windows.
98 // You can choose one from these four -- {w,}{WinMain,main}.
99 // There are four different entry point functions for them,
100 // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to
101 // choose the right one depending on which "main" function is defined.
102 // This function looks up the symbol table and resolve corresponding
103 // entry point name.
104 StringRef findDefaultEntry();
105 WindowsSubsystem inferSubsystem();
106
107 // Build a set of COFF objects representing the combined contents of
108 // BitcodeFiles and add them to the symbol table. Called after all files are
109 // added and before the writer writes results to a file.
110 void compileBitcodeFiles();
111
112 void waitForLTOCleanup();
113
114 // Creates an Undefined symbol and marks it as live.
115 Symbol *addGCRoot(StringRef sym, bool aliasEC = false);
116
117 // Creates an Undefined symbol for a given name.
118 Symbol *addUndefined(StringRef name);
119
120 Symbol *addSynthetic(StringRef n, Chunk *c);
121 Symbol *addAbsolute(StringRef n, uint64_t va);
122
123 Symbol *addUndefined(StringRef name, InputFile *f, bool overrideLazy);
124 void addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym);
125 void addLazyObject(InputFile *f, StringRef n);
126 void addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym, StringRef n);
127 Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
128 Symbol *addRegular(InputFile *f, StringRef n,
129 const llvm::object::coff_symbol_generic *s = nullptr,
130 SectionChunk *c = nullptr, uint32_t sectionOffset = 0,
131 bool isWeak = false);
132 std::pair<DefinedRegular *, bool>
133 addComdat(InputFile *f, StringRef n,
134 const llvm::object::coff_symbol_generic *s = nullptr);
135 Symbol *addCommon(InputFile *f, StringRef n, uint64_t size,
136 const llvm::object::coff_symbol_generic *s = nullptr,
137 CommonChunk *c = nullptr);
138 DefinedImportData *addImportData(StringRef n, ImportFile *f,
139 Chunk *&location);
140 Defined *addImportThunk(StringRef name, DefinedImportData *s,
141 ImportThunkChunk *chunk);
142 void addLibcall(StringRef name);
143 void addEntryThunk(Symbol *from, Symbol *to);
144 void addExitThunk(Symbol *from, Symbol *to);
145 void initializeECThunks();
146 void initializeSameAddressThunks();
147
148 void reportDuplicate(Symbol *existing, InputFile *newFile,
149 SectionChunk *newSc = nullptr,
150 uint32_t newSectionOffset = 0);
151
152 COFFLinkerContext &ctx;
153 llvm::COFF::MachineTypes machine;
154
155 bool isEC() const { return machine == ARM64EC; }
156
157 // An entry point symbol.
158 Symbol *entry = nullptr;
159
160 // A list of chunks which to be added to .rdata.
161 std::vector<Chunk *> localImportChunks;
162
163 // A list of EC EXP+ symbols.
164 std::vector<Symbol *> expSymbols;
165
166 std::vector<SameAddressThunkARM64EC *> sameAddressThunks;
167
168 // A list of DLL exports.
169 std::vector<Export> exports;
170 llvm::DenseSet<StringRef> directivesExports;
171 bool hadExplicitExports;
172
173 Chunk *edataStart = nullptr;
174 Chunk *edataEnd = nullptr;
175
176 Symbol *delayLoadHelper = nullptr;
177 Chunk *tailMergeUnwindInfoChunk = nullptr;
178
179 // A list of wrapped symbols.
180 std::vector<WrappedSymbol> wrapped;
181
182 // Used for /alternatename.
183 std::map<StringRef, StringRef> alternateNames;
184
185 // Used for /aligncomm.
186 std::map<std::string, int> alignComm;
187
188 void fixupExports();
189 void assignExportOrdinals();
190 void parseModuleDefs(StringRef path);
191 void parseAlternateName(StringRef);
192 void parseAligncomm(StringRef);
193
194 // Iterates symbols in non-determinstic hash table order.
195 template <typename T> void forEachSymbol(T callback) {
196 for (auto &pair : symMap)
197 callback(pair.second);
198 }
199
200 std::vector<BitcodeFile *> bitcodeFileInstances;
201
202 DefinedRegular *loadConfigSym = nullptr;
203 uint32_t loadConfigSize = 0;
204 void initializeLoadConfig();
205
206 std::string printSymbol(Symbol *sym) const;
207
208private:
209 /// Given a name without "__imp_" prefix, returns a defined symbol
210 /// with the "__imp_" prefix, if it exists.
211 Defined *impSymbol(StringRef name);
212 /// Inserts symbol if not already present.
213 std::pair<Symbol *, bool> insert(StringRef name);
214 /// Same as insert(Name), but also sets isUsedInRegularObj.
215 std::pair<Symbol *, bool> insert(StringRef name, InputFile *f);
216
217 bool findUnderscoreMangle(StringRef sym);
218 std::vector<Symbol *> getSymsWithPrefix(StringRef prefix);
219
220 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> symMap;
221 std::unique_ptr<BitcodeCompiler> lto;
222 std::vector<std::pair<Symbol *, Symbol *>> entryThunks;
223 llvm::DenseMap<Symbol *, Symbol *> exitThunks;
224
225 void
226 reportProblemSymbols(const llvm::SmallPtrSetImpl<Symbol *> &undefs,
227 const llvm::DenseMap<Symbol *, Symbol *> *localImports,
228 bool needBitcodeFiles);
229 void reportUndefinedSymbol(const UndefinedDiag &undefDiag);
230};
231
232std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);
233
234StringRef ltrim1(StringRef s, const char *chars);
235
236} // namespace lld::coff
237
238#endif
239