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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lld/COFF/SymbolTable.h