[SandboxIR] Avoid repeated hash lookups (NFC) (#125337)
[llvm-project.git] / lld / COFF / SymbolTable.cpp
blob307bd4a0c94114f174a563815905a18b433d2d4d
1 //===- SymbolTable.cpp ----------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "SymbolTable.h"
10 #include "COFFLinkerContext.h"
11 #include "Config.h"
12 #include "Driver.h"
13 #include "LTO.h"
14 #include "PDB.h"
15 #include "Symbols.h"
16 #include "lld/Common/ErrorHandler.h"
17 #include "lld/Common/Memory.h"
18 #include "lld/Common/Timer.h"
19 #include "llvm/DebugInfo/DIContext.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/LTO/LTO.h"
23 #include "llvm/Object/COFFModuleDefinition.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/GlobPattern.h"
26 #include "llvm/Support/Parallel.h"
27 #include "llvm/Support/TimeProfiler.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include <utility>
31 using namespace llvm;
32 using namespace llvm::COFF;
33 using namespace llvm::object;
34 using namespace llvm::support;
36 namespace lld::coff {
38 StringRef ltrim1(StringRef s, const char *chars) {
39 if (!s.empty() && strchr(chars, s[0]))
40 return s.substr(1);
41 return s;
44 static COFFSyncStream errorOrWarn(COFFLinkerContext &ctx) {
45 return {ctx, ctx.config.forceUnresolved ? DiagLevel::Warn : DiagLevel::Err};
48 // Causes the file associated with a lazy symbol to be linked in.
49 static void forceLazy(Symbol *s) {
50 s->pendingArchiveLoad = true;
51 switch (s->kind()) {
52 case Symbol::Kind::LazyArchiveKind: {
53 auto *l = cast<LazyArchive>(s);
54 l->file->addMember(l->sym);
55 break;
57 case Symbol::Kind::LazyObjectKind: {
58 InputFile *file = cast<LazyObject>(s)->file;
59 // FIXME: Remove this once we resolve all defineds before all undefineds in
60 // ObjFile::initializeSymbols().
61 if (!file->lazy)
62 return;
63 file->lazy = false;
64 file->symtab.ctx.driver.addFile(file);
65 break;
67 case Symbol::Kind::LazyDLLSymbolKind: {
68 auto *l = cast<LazyDLLSymbol>(s);
69 l->file->makeImport(l->sym);
70 break;
72 default:
73 llvm_unreachable(
74 "symbol passed to forceLazy is not a LazyArchive or LazyObject");
78 // Returns the symbol in SC whose value is <= Addr that is closest to Addr.
79 // This is generally the global variable or function whose definition contains
80 // Addr.
81 static Symbol *getSymbol(SectionChunk *sc, uint32_t addr) {
82 DefinedRegular *candidate = nullptr;
84 for (Symbol *s : sc->file->getSymbols()) {
85 auto *d = dyn_cast_or_null<DefinedRegular>(s);
86 if (!d || !d->data || d->file != sc->file || d->getChunk() != sc ||
87 d->getValue() > addr ||
88 (candidate && d->getValue() < candidate->getValue()))
89 continue;
91 candidate = d;
94 return candidate;
97 static std::vector<std::string> getSymbolLocations(BitcodeFile *file) {
98 std::string res("\n>>> referenced by ");
99 StringRef source = file->obj->getSourceFileName();
100 if (!source.empty())
101 res += source.str() + "\n>>> ";
102 res += toString(file);
103 return {res};
106 static std::optional<std::pair<StringRef, uint32_t>>
107 getFileLineDwarf(const SectionChunk *c, uint32_t addr) {
108 std::optional<DILineInfo> optionalLineInfo =
109 c->file->getDILineInfo(addr, c->getSectionNumber() - 1);
110 if (!optionalLineInfo)
111 return std::nullopt;
112 const DILineInfo &lineInfo = *optionalLineInfo;
113 if (lineInfo.FileName == DILineInfo::BadString)
114 return std::nullopt;
115 return std::make_pair(saver().save(lineInfo.FileName), lineInfo.Line);
118 static std::optional<std::pair<StringRef, uint32_t>>
119 getFileLine(const SectionChunk *c, uint32_t addr) {
120 // MinGW can optionally use codeview, even if the default is dwarf.
121 std::optional<std::pair<StringRef, uint32_t>> fileLine =
122 getFileLineCodeView(c, addr);
123 // If codeview didn't yield any result, check dwarf in MinGW mode.
124 if (!fileLine && c->file->symtab.ctx.config.mingw)
125 fileLine = getFileLineDwarf(c, addr);
126 return fileLine;
129 // Given a file and the index of a symbol in that file, returns a description
130 // of all references to that symbol from that file. If no debug information is
131 // available, returns just the name of the file, else one string per actual
132 // reference as described in the debug info.
133 // Returns up to maxStrings string descriptions, along with the total number of
134 // locations found.
135 static std::pair<std::vector<std::string>, size_t>
136 getSymbolLocations(ObjFile *file, uint32_t symIndex, size_t maxStrings) {
137 struct Location {
138 Symbol *sym;
139 std::pair<StringRef, uint32_t> fileLine;
141 std::vector<Location> locations;
142 size_t numLocations = 0;
144 for (Chunk *c : file->getChunks()) {
145 auto *sc = dyn_cast<SectionChunk>(c);
146 if (!sc)
147 continue;
148 for (const coff_relocation &r : sc->getRelocs()) {
149 if (r.SymbolTableIndex != symIndex)
150 continue;
151 numLocations++;
152 if (locations.size() >= maxStrings)
153 continue;
155 std::optional<std::pair<StringRef, uint32_t>> fileLine =
156 getFileLine(sc, r.VirtualAddress);
157 Symbol *sym = getSymbol(sc, r.VirtualAddress);
158 if (fileLine)
159 locations.push_back({sym, *fileLine});
160 else if (sym)
161 locations.push_back({sym, {"", 0}});
165 if (maxStrings == 0)
166 return std::make_pair(std::vector<std::string>(), numLocations);
168 if (numLocations == 0)
169 return std::make_pair(
170 std::vector<std::string>{"\n>>> referenced by " + toString(file)}, 1);
172 std::vector<std::string> symbolLocations(locations.size());
173 size_t i = 0;
174 for (Location loc : locations) {
175 llvm::raw_string_ostream os(symbolLocations[i++]);
176 os << "\n>>> referenced by ";
177 if (!loc.fileLine.first.empty())
178 os << loc.fileLine.first << ":" << loc.fileLine.second
179 << "\n>>> ";
180 os << toString(file);
181 if (loc.sym)
182 os << ":(" << toString(file->symtab.ctx, *loc.sym) << ')';
184 return std::make_pair(symbolLocations, numLocations);
187 std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
188 return getSymbolLocations(file, symIndex, SIZE_MAX).first;
191 static std::pair<std::vector<std::string>, size_t>
192 getSymbolLocations(InputFile *file, uint32_t symIndex, size_t maxStrings) {
193 if (auto *o = dyn_cast<ObjFile>(file))
194 return getSymbolLocations(o, symIndex, maxStrings);
195 if (auto *b = dyn_cast<BitcodeFile>(file)) {
196 std::vector<std::string> symbolLocations = getSymbolLocations(b);
197 size_t numLocations = symbolLocations.size();
198 if (symbolLocations.size() > maxStrings)
199 symbolLocations.resize(maxStrings);
200 return std::make_pair(symbolLocations, numLocations);
202 llvm_unreachable("unsupported file type passed to getSymbolLocations");
203 return std::make_pair(std::vector<std::string>(), (size_t)0);
206 // For an undefined symbol, stores all files referencing it and the index of
207 // the undefined symbol in each file.
208 struct UndefinedDiag {
209 Symbol *sym;
210 struct File {
211 InputFile *file;
212 uint32_t symIndex;
214 std::vector<File> files;
217 static void reportUndefinedSymbol(COFFLinkerContext &ctx,
218 const UndefinedDiag &undefDiag) {
219 auto diag = errorOrWarn(ctx);
220 diag << "undefined symbol: " << undefDiag.sym;
222 const size_t maxUndefReferences = 3;
223 size_t numDisplayedRefs = 0, numRefs = 0;
224 for (const UndefinedDiag::File &ref : undefDiag.files) {
225 auto [symbolLocations, totalLocations] = getSymbolLocations(
226 ref.file, ref.symIndex, maxUndefReferences - numDisplayedRefs);
228 numRefs += totalLocations;
229 numDisplayedRefs += symbolLocations.size();
230 for (const std::string &s : symbolLocations)
231 diag << s;
233 if (numDisplayedRefs < numRefs)
234 diag << "\n>>> referenced " << numRefs - numDisplayedRefs << " more times";
237 void SymbolTable::loadMinGWSymbols() {
238 for (auto &i : symMap) {
239 Symbol *sym = i.second;
240 auto *undef = dyn_cast<Undefined>(sym);
241 if (!undef)
242 continue;
243 if (undef->getWeakAlias())
244 continue;
246 StringRef name = undef->getName();
248 if (machine == I386 && ctx.config.stdcallFixup) {
249 // Check if we can resolve an undefined decorated symbol by finding
250 // the intended target as an undecorated symbol (only with a leading
251 // underscore).
252 StringRef origName = name;
253 StringRef baseName = name;
254 // Trim down stdcall/fastcall/vectorcall symbols to the base name.
255 baseName = ltrim1(baseName, "_@");
256 baseName = baseName.substr(0, baseName.find('@'));
257 // Add a leading underscore, as it would be in cdecl form.
258 std::string newName = ("_" + baseName).str();
259 Symbol *l;
260 if (newName != origName && (l = find(newName)) != nullptr) {
261 // If we found a symbol and it is lazy; load it.
262 if (l->isLazy() && !l->pendingArchiveLoad) {
263 Log(ctx) << "Loading lazy " << l->getName() << " from "
264 << l->getFile()->getName() << " for stdcall fixup";
265 forceLazy(l);
267 // If it's lazy or already defined, hook it up as weak alias.
268 if (l->isLazy() || isa<Defined>(l)) {
269 if (ctx.config.warnStdcallFixup)
270 Warn(ctx) << "Resolving " << origName << " by linking to "
271 << newName;
272 else
273 Log(ctx) << "Resolving " << origName << " by linking to "
274 << newName;
275 undef->setWeakAlias(l);
276 continue;
281 if (ctx.config.autoImport) {
282 if (name.starts_with("__imp_"))
283 continue;
284 // If we have an undefined symbol, but we have a lazy symbol we could
285 // load, load it.
286 Symbol *l = find(("__imp_" + name).str());
287 if (!l || l->pendingArchiveLoad || !l->isLazy())
288 continue;
290 Log(ctx) << "Loading lazy " << l->getName() << " from "
291 << l->getFile()->getName() << " for automatic import";
292 forceLazy(l);
297 Defined *SymbolTable::impSymbol(StringRef name) {
298 if (name.starts_with("__imp_"))
299 return nullptr;
300 return dyn_cast_or_null<Defined>(find(("__imp_" + name).str()));
303 bool SymbolTable::handleMinGWAutomaticImport(Symbol *sym, StringRef name) {
304 Defined *imp = impSymbol(name);
305 if (!imp)
306 return false;
308 // Replace the reference directly to a variable with a reference
309 // to the import address table instead. This obviously isn't right,
310 // but we mark the symbol as isRuntimePseudoReloc, and a later pass
311 // will add runtime pseudo relocations for every relocation against
312 // this Symbol. The runtime pseudo relocation framework expects the
313 // reference itself to point at the IAT entry.
314 size_t impSize = 0;
315 if (isa<DefinedImportData>(imp)) {
316 Log(ctx) << "Automatically importing " << name << " from "
317 << cast<DefinedImportData>(imp)->getDLLName();
318 impSize = sizeof(DefinedImportData);
319 } else if (isa<DefinedRegular>(imp)) {
320 Log(ctx) << "Automatically importing " << name << " from "
321 << toString(cast<DefinedRegular>(imp)->file);
322 impSize = sizeof(DefinedRegular);
323 } else {
324 Warn(ctx) << "unable to automatically import " << name << " from "
325 << imp->getName() << " from " << cast<DefinedRegular>(imp)->file
326 << "; unexpected symbol type";
327 return false;
329 sym->replaceKeepingName(imp, impSize);
330 sym->isRuntimePseudoReloc = true;
332 // There may exist symbols named .refptr.<name> which only consist
333 // of a single pointer to <name>. If it turns out <name> is
334 // automatically imported, we don't need to keep the .refptr.<name>
335 // pointer at all, but redirect all accesses to it to the IAT entry
336 // for __imp_<name> instead, and drop the whole .refptr.<name> chunk.
337 DefinedRegular *refptr =
338 dyn_cast_or_null<DefinedRegular>(find((".refptr." + name).str()));
339 if (refptr && refptr->getChunk()->getSize() == ctx.config.wordsize) {
340 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(refptr->getChunk());
341 if (sc && sc->getRelocs().size() == 1 && *sc->symbols().begin() == sym) {
342 Log(ctx) << "Replacing .refptr." << name << " with " << imp->getName();
343 refptr->getChunk()->live = false;
344 refptr->replaceKeepingName(imp, impSize);
347 return true;
350 /// Helper function for reportUnresolvable and resolveRemainingUndefines.
351 /// This function emits an "undefined symbol" diagnostic for each symbol in
352 /// undefs. If localImports is not nullptr, it also emits a "locally
353 /// defined symbol imported" diagnostic for symbols in localImports.
354 /// objFiles and bitcodeFiles (if not nullptr) are used to report where
355 /// undefined symbols are referenced.
356 void SymbolTable::reportProblemSymbols(
357 const SmallPtrSetImpl<Symbol *> &undefs,
358 const DenseMap<Symbol *, Symbol *> *localImports, bool needBitcodeFiles) {
359 // Return early if there is nothing to report (which should be
360 // the common case).
361 if (undefs.empty() && (!localImports || localImports->empty()))
362 return;
364 for (Symbol *b : ctx.config.gcroot) {
365 if (undefs.count(b))
366 errorOrWarn(ctx) << "<root>: undefined symbol: " << b;
367 if (localImports)
368 if (Symbol *imp = localImports->lookup(b))
369 Warn(ctx) << "<root>: locally defined symbol imported: " << imp
370 << " (defined in " << toString(imp->getFile())
371 << ") [LNK4217]";
374 std::vector<UndefinedDiag> undefDiags;
375 DenseMap<Symbol *, int> firstDiag;
377 auto processFile = [&](InputFile *file, ArrayRef<Symbol *> symbols) {
378 uint32_t symIndex = (uint32_t)-1;
379 for (Symbol *sym : symbols) {
380 ++symIndex;
381 if (!sym)
382 continue;
383 if (undefs.count(sym)) {
384 auto [it, inserted] = firstDiag.try_emplace(sym, undefDiags.size());
385 if (inserted)
386 undefDiags.push_back({sym, {{file, symIndex}}});
387 else
388 undefDiags[it->second].files.push_back({file, symIndex});
390 if (localImports)
391 if (Symbol *imp = localImports->lookup(sym))
392 Warn(ctx) << file << ": locally defined symbol imported: " << imp
393 << " (defined in " << imp->getFile() << ") [LNK4217]";
397 for (ObjFile *file : ctx.objFileInstances)
398 processFile(file, file->getSymbols());
400 if (needBitcodeFiles)
401 for (BitcodeFile *file : bitcodeFileInstances)
402 processFile(file, file->getSymbols());
404 for (const UndefinedDiag &undefDiag : undefDiags)
405 reportUndefinedSymbol(ctx, undefDiag);
408 void SymbolTable::reportUnresolvable() {
409 SmallPtrSet<Symbol *, 8> undefs;
410 for (auto &i : symMap) {
411 Symbol *sym = i.second;
412 auto *undef = dyn_cast<Undefined>(sym);
413 if (!undef || sym->deferUndefined)
414 continue;
415 if (undef->getWeakAlias())
416 continue;
417 StringRef name = undef->getName();
418 if (name.starts_with("__imp_")) {
419 Symbol *imp = find(name.substr(strlen("__imp_")));
420 if (Defined *def = dyn_cast_or_null<Defined>(imp)) {
421 def->isUsedInRegularObj = true;
422 continue;
425 if (name.contains("_PchSym_"))
426 continue;
427 if (ctx.config.autoImport && impSymbol(name))
428 continue;
429 undefs.insert(sym);
432 reportProblemSymbols(undefs, /*localImports=*/nullptr, true);
435 bool SymbolTable::resolveRemainingUndefines() {
436 llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols");
437 SmallPtrSet<Symbol *, 8> undefs;
438 DenseMap<Symbol *, Symbol *> localImports;
439 bool foundLazy = false;
441 for (auto &i : symMap) {
442 Symbol *sym = i.second;
443 auto *undef = dyn_cast<Undefined>(sym);
444 if (!undef)
445 continue;
446 if (!sym->isUsedInRegularObj)
447 continue;
449 StringRef name = undef->getName();
451 // A weak alias may have been resolved, so check for that.
452 if (undef->resolveWeakAlias())
453 continue;
455 // If we can resolve a symbol by removing __imp_ prefix, do that.
456 // This odd rule is for compatibility with MSVC linker.
457 if (name.starts_with("__imp_")) {
458 auto findLocalSym = [&](StringRef n) {
459 Symbol *sym = find(n);
460 if (auto undef = dyn_cast_or_null<Undefined>(sym)) {
461 // The unprefixed symbol might come later in symMap, so handle it now
462 // if needed.
463 if (!undef->resolveWeakAlias())
464 sym = nullptr;
466 return sym;
469 StringRef impName = name.substr(strlen("__imp_"));
470 Symbol *imp = findLocalSym(impName);
471 if (!imp && isEC()) {
472 // Try to use the mangled symbol on ARM64EC.
473 std::optional<std::string> mangledName =
474 getArm64ECMangledFunctionName(impName);
475 if (mangledName)
476 imp = findLocalSym(*mangledName);
477 if (!imp && impName.consume_front("aux_")) {
478 // If it's a __imp_aux_ symbol, try skipping the aux_ prefix.
479 imp = findLocalSym(impName);
480 if (!imp && (mangledName = getArm64ECMangledFunctionName(impName)))
481 imp = findLocalSym(*mangledName);
484 if (imp && imp->isLazy()) {
485 forceLazy(imp);
486 foundLazy = true;
487 continue;
489 if (imp && isa<Defined>(imp)) {
490 auto *d = cast<Defined>(imp);
491 replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
492 localImportChunks.push_back(cast<DefinedLocalImport>(sym)->getChunk());
493 localImports[sym] = d;
494 continue;
498 // We don't want to report missing Microsoft precompiled headers symbols.
499 // A proper message will be emitted instead in PDBLinker::aquirePrecompObj
500 if (name.contains("_PchSym_"))
501 continue;
503 if (ctx.config.autoImport && handleMinGWAutomaticImport(sym, name))
504 continue;
506 // Remaining undefined symbols are not fatal if /force is specified.
507 // They are replaced with dummy defined symbols.
508 if (ctx.config.forceUnresolved)
509 replaceSymbol<DefinedAbsolute>(sym, ctx, name, 0);
510 undefs.insert(sym);
513 reportProblemSymbols(
514 undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr,
515 false);
516 return foundLazy;
519 std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {
520 bool inserted = false;
521 Symbol *&sym = symMap[CachedHashStringRef(name)];
522 if (!sym) {
523 sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
524 sym->isUsedInRegularObj = false;
525 sym->pendingArchiveLoad = false;
526 sym->canInline = true;
527 inserted = true;
529 if (isEC() && name.starts_with("EXP+"))
530 expSymbols.push_back(sym);
532 return {sym, inserted};
535 std::pair<Symbol *, bool> SymbolTable::insert(StringRef name, InputFile *file) {
536 std::pair<Symbol *, bool> result = insert(name);
537 if (!file || !isa<BitcodeFile>(file))
538 result.first->isUsedInRegularObj = true;
539 return result;
542 void SymbolTable::initializeLoadConfig() {
543 auto sym =
544 dyn_cast_or_null<DefinedRegular>(findUnderscore("_load_config_used"));
545 if (!sym) {
546 if (isEC()) {
547 Warn(ctx) << "EC version of '_load_config_used' is missing";
548 return;
550 if (ctx.hybridSymtab) {
551 Warn(ctx) << "native version of '_load_config_used' is missing for "
552 "ARM64X target";
553 return;
555 if (ctx.config.guardCF != GuardCFLevel::Off)
556 Warn(ctx)
557 << "Control Flow Guard is enabled but '_load_config_used' is missing";
558 if (ctx.config.dependentLoadFlags)
559 Warn(ctx) << "_load_config_used not found, /dependentloadflag will have "
560 "no effect";
561 return;
564 SectionChunk *sc = sym->getChunk();
565 if (!sc->hasData) {
566 Err(ctx) << "_load_config_used points to uninitialized data";
567 return;
569 uint64_t offsetInChunk = sym->getValue();
570 if (offsetInChunk + 4 > sc->getSize()) {
571 Err(ctx) << "_load_config_used section chunk is too small";
572 return;
575 ArrayRef<uint8_t> secContents = sc->getContents();
576 loadConfigSize =
577 *reinterpret_cast<const ulittle32_t *>(&secContents[offsetInChunk]);
578 if (offsetInChunk + loadConfigSize > sc->getSize()) {
579 Err(ctx) << "_load_config_used specifies a size larger than its containing "
580 "section chunk";
581 return;
584 uint32_t expectedAlign = ctx.config.is64() ? 8 : 4;
585 if (sc->getAlignment() < expectedAlign)
586 Warn(ctx) << "'_load_config_used' is misaligned (expected alignment to be "
587 << expectedAlign << " bytes, got " << sc->getAlignment()
588 << " instead)";
589 else if (!isAligned(Align(expectedAlign), offsetInChunk))
590 Warn(ctx) << "'_load_config_used' is misaligned (section offset is 0x"
591 << Twine::utohexstr(sym->getValue()) << " not aligned to "
592 << expectedAlign << " bytes)";
594 loadConfigSym = sym;
597 void SymbolTable::addEntryThunk(Symbol *from, Symbol *to) {
598 entryThunks.push_back({from, to});
601 void SymbolTable::addExitThunk(Symbol *from, Symbol *to) {
602 exitThunks[from] = to;
605 void SymbolTable::initializeECThunks() {
606 if (!isArm64EC(ctx.config.machine))
607 return;
609 for (auto it : entryThunks) {
610 auto *to = dyn_cast<Defined>(it.second);
611 if (!to)
612 continue;
613 auto *from = dyn_cast<DefinedRegular>(it.first);
614 // We need to be able to add padding to the function and fill it with an
615 // offset to its entry thunks. To ensure that padding the function is
616 // feasible, functions are required to be COMDAT symbols with no offset.
617 if (!from || !from->getChunk()->isCOMDAT() ||
618 cast<DefinedRegular>(from)->getValue()) {
619 Err(ctx) << "non COMDAT symbol '" << from->getName() << "' in hybrid map";
620 continue;
622 from->getChunk()->setEntryThunk(to);
625 for (ImportFile *file : ctx.importFileInstances) {
626 if (!file->impchkThunk)
627 continue;
629 Symbol *sym = exitThunks.lookup(file->thunkSym);
630 if (!sym)
631 sym = exitThunks.lookup(file->impECSym);
632 file->impchkThunk->exitThunk = dyn_cast_or_null<Defined>(sym);
635 // On ARM64EC, the __imp_ symbol references the auxiliary IAT, while the
636 // __imp_aux_ symbol references the regular IAT. However, x86_64 code expects
637 // both to reference the regular IAT, so adjust the symbol if necessary.
638 parallelForEach(ctx.objFileInstances, [&](ObjFile *file) {
639 if (file->getMachineType() != AMD64)
640 return;
641 for (auto &sym : file->getMutableSymbols()) {
642 auto impSym = dyn_cast_or_null<DefinedImportData>(sym);
643 if (impSym && impSym->file->impchkThunk && sym == impSym->file->impECSym)
644 sym = impSym->file->impSym;
649 Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f,
650 bool overrideLazy) {
651 auto [s, wasInserted] = insert(name, f);
652 if (wasInserted || (s->isLazy() && overrideLazy)) {
653 replaceSymbol<Undefined>(s, name);
654 return s;
656 if (s->isLazy())
657 forceLazy(s);
658 return s;
661 Symbol *SymbolTable::addGCRoot(StringRef name, bool aliasEC) {
662 Symbol *b = addUndefined(name);
663 if (!b->isGCRoot) {
664 b->isGCRoot = true;
665 ctx.config.gcroot.push_back(b);
668 // On ARM64EC, a symbol may be defined in either its mangled or demangled form
669 // (or both). Define an anti-dependency symbol that binds both forms, similar
670 // to how compiler-generated code references external functions.
671 if (aliasEC && isEC()) {
672 if (std::optional<std::string> mangledName =
673 getArm64ECMangledFunctionName(name)) {
674 auto u = dyn_cast<Undefined>(b);
675 if (u && !u->weakAlias) {
676 Symbol *t = addUndefined(saver().save(*mangledName));
677 u->setWeakAlias(t, true);
679 } else if (std::optional<std::string> demangledName =
680 getArm64ECDemangledFunctionName(name)) {
681 Symbol *us = addUndefined(saver().save(*demangledName));
682 auto u = dyn_cast<Undefined>(us);
683 if (u && !u->weakAlias)
684 u->setWeakAlias(b, true);
687 return b;
690 // On ARM64EC, a function symbol may appear in both mangled and demangled forms:
691 // - ARM64EC archives contain only the mangled name, while the demangled symbol
692 // is defined by the object file as an alias.
693 // - x86_64 archives contain only the demangled name (the mangled name is
694 // usually defined by an object referencing the symbol as an alias to a guess
695 // exit thunk).
696 // - ARM64EC import files contain both the mangled and demangled names for
697 // thunks.
698 // If more than one archive defines the same function, this could lead
699 // to different libraries being used for the same function depending on how they
700 // are referenced. Avoid this by checking if the paired symbol is already
701 // defined before adding a symbol to the table.
702 template <typename T>
703 bool checkLazyECPair(SymbolTable *symtab, StringRef name, InputFile *f) {
704 if (name.starts_with("__imp_"))
705 return true;
706 std::string pairName;
707 if (std::optional<std::string> mangledName =
708 getArm64ECMangledFunctionName(name))
709 pairName = std::move(*mangledName);
710 else if (std::optional<std::string> demangledName =
711 getArm64ECDemangledFunctionName(name))
712 pairName = std::move(*demangledName);
713 else
714 return true;
716 Symbol *sym = symtab->find(pairName);
717 if (!sym)
718 return true;
719 if (sym->pendingArchiveLoad)
720 return false;
721 if (auto u = dyn_cast<Undefined>(sym))
722 return !u->weakAlias || u->isAntiDep;
723 // If the symbol is lazy, allow it only if it originates from the same
724 // archive.
725 auto lazy = dyn_cast<T>(sym);
726 return lazy && lazy->file == f;
729 void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym) {
730 StringRef name = sym.getName();
731 if (isEC() && !checkLazyECPair<LazyArchive>(this, name, f))
732 return;
733 auto [s, wasInserted] = insert(name);
734 if (wasInserted) {
735 replaceSymbol<LazyArchive>(s, f, sym);
736 return;
738 auto *u = dyn_cast<Undefined>(s);
739 if (!u || (u->weakAlias && !u->isECAlias(machine)) || s->pendingArchiveLoad)
740 return;
741 s->pendingArchiveLoad = true;
742 f->addMember(sym);
745 void SymbolTable::addLazyObject(InputFile *f, StringRef n) {
746 assert(f->lazy);
747 if (isEC() && !checkLazyECPair<LazyObject>(this, n, f))
748 return;
749 auto [s, wasInserted] = insert(n, f);
750 if (wasInserted) {
751 replaceSymbol<LazyObject>(s, f, n);
752 return;
754 auto *u = dyn_cast<Undefined>(s);
755 if (!u || (u->weakAlias && !u->isECAlias(machine)) || s->pendingArchiveLoad)
756 return;
757 s->pendingArchiveLoad = true;
758 f->lazy = false;
759 ctx.driver.addFile(f);
762 void SymbolTable::addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym,
763 StringRef n) {
764 auto [s, wasInserted] = insert(n);
765 if (wasInserted) {
766 replaceSymbol<LazyDLLSymbol>(s, f, sym, n);
767 return;
769 auto *u = dyn_cast<Undefined>(s);
770 if (!u || u->weakAlias || s->pendingArchiveLoad)
771 return;
772 s->pendingArchiveLoad = true;
773 f->makeImport(sym);
776 static std::string getSourceLocationBitcode(BitcodeFile *file) {
777 std::string res("\n>>> defined at ");
778 StringRef source = file->obj->getSourceFileName();
779 if (!source.empty())
780 res += source.str() + "\n>>> ";
781 res += toString(file);
782 return res;
785 static std::string getSourceLocationObj(ObjFile *file, SectionChunk *sc,
786 uint32_t offset, StringRef name) {
787 std::optional<std::pair<StringRef, uint32_t>> fileLine;
788 if (sc)
789 fileLine = getFileLine(sc, offset);
790 if (!fileLine)
791 fileLine = file->getVariableLocation(name);
793 std::string res;
794 llvm::raw_string_ostream os(res);
795 os << "\n>>> defined at ";
796 if (fileLine)
797 os << fileLine->first << ":" << fileLine->second << "\n>>> ";
798 os << toString(file);
799 return res;
802 static std::string getSourceLocation(InputFile *file, SectionChunk *sc,
803 uint32_t offset, StringRef name) {
804 if (!file)
805 return "";
806 if (auto *o = dyn_cast<ObjFile>(file))
807 return getSourceLocationObj(o, sc, offset, name);
808 if (auto *b = dyn_cast<BitcodeFile>(file))
809 return getSourceLocationBitcode(b);
810 return "\n>>> defined at " + toString(file);
813 // Construct and print an error message in the form of:
815 // lld-link: error: duplicate symbol: foo
816 // >>> defined at bar.c:30
817 // >>> bar.o
818 // >>> defined at baz.c:563
819 // >>> baz.o
820 void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile,
821 SectionChunk *newSc,
822 uint32_t newSectionOffset) {
823 COFFSyncStream diag(ctx, ctx.config.forceMultiple ? DiagLevel::Warn
824 : DiagLevel::Err);
825 diag << "duplicate symbol: " << existing;
827 DefinedRegular *d = dyn_cast<DefinedRegular>(existing);
828 if (d && isa<ObjFile>(d->getFile())) {
829 diag << getSourceLocation(d->getFile(), d->getChunk(), d->getValue(),
830 existing->getName());
831 } else {
832 diag << getSourceLocation(existing->getFile(), nullptr, 0, "");
834 diag << getSourceLocation(newFile, newSc, newSectionOffset,
835 existing->getName());
838 Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) {
839 auto [s, wasInserted] = insert(n, nullptr);
840 s->isUsedInRegularObj = true;
841 if (wasInserted || isa<Undefined>(s) || s->isLazy())
842 replaceSymbol<DefinedAbsolute>(s, ctx, n, sym);
843 else if (auto *da = dyn_cast<DefinedAbsolute>(s)) {
844 if (da->getVA() != sym.getValue())
845 reportDuplicate(s, nullptr);
846 } else if (!isa<DefinedCOFF>(s))
847 reportDuplicate(s, nullptr);
848 return s;
851 Symbol *SymbolTable::addAbsolute(StringRef n, uint64_t va) {
852 auto [s, wasInserted] = insert(n, nullptr);
853 s->isUsedInRegularObj = true;
854 if (wasInserted || isa<Undefined>(s) || s->isLazy())
855 replaceSymbol<DefinedAbsolute>(s, ctx, n, va);
856 else if (auto *da = dyn_cast<DefinedAbsolute>(s)) {
857 if (da->getVA() != va)
858 reportDuplicate(s, nullptr);
859 } else if (!isa<DefinedCOFF>(s))
860 reportDuplicate(s, nullptr);
861 return s;
864 Symbol *SymbolTable::addSynthetic(StringRef n, Chunk *c) {
865 auto [s, wasInserted] = insert(n, nullptr);
866 s->isUsedInRegularObj = true;
867 if (wasInserted || isa<Undefined>(s) || s->isLazy())
868 replaceSymbol<DefinedSynthetic>(s, n, c);
869 else if (!isa<DefinedCOFF>(s))
870 reportDuplicate(s, nullptr);
871 return s;
874 Symbol *SymbolTable::addRegular(InputFile *f, StringRef n,
875 const coff_symbol_generic *sym, SectionChunk *c,
876 uint32_t sectionOffset, bool isWeak) {
877 auto [s, wasInserted] = insert(n, f);
878 if (wasInserted || !isa<DefinedRegular>(s) || s->isWeak)
879 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ false,
880 /*IsExternal*/ true, sym, c, isWeak);
881 else if (!isWeak)
882 reportDuplicate(s, f, c, sectionOffset);
883 return s;
886 std::pair<DefinedRegular *, bool>
887 SymbolTable::addComdat(InputFile *f, StringRef n,
888 const coff_symbol_generic *sym) {
889 auto [s, wasInserted] = insert(n, f);
890 if (wasInserted || !isa<DefinedRegular>(s)) {
891 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ true,
892 /*IsExternal*/ true, sym, nullptr);
893 return {cast<DefinedRegular>(s), true};
895 auto *existingSymbol = cast<DefinedRegular>(s);
896 if (!existingSymbol->isCOMDAT)
897 reportDuplicate(s, f);
898 return {existingSymbol, false};
901 Symbol *SymbolTable::addCommon(InputFile *f, StringRef n, uint64_t size,
902 const coff_symbol_generic *sym, CommonChunk *c) {
903 auto [s, wasInserted] = insert(n, f);
904 if (wasInserted || !isa<DefinedCOFF>(s))
905 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c);
906 else if (auto *dc = dyn_cast<DefinedCommon>(s))
907 if (size > dc->getSize())
908 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c);
909 return s;
912 DefinedImportData *SymbolTable::addImportData(StringRef n, ImportFile *f,
913 Chunk *&location) {
914 auto [s, wasInserted] = insert(n, nullptr);
915 s->isUsedInRegularObj = true;
916 if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
917 replaceSymbol<DefinedImportData>(s, n, f, location);
918 return cast<DefinedImportData>(s);
921 reportDuplicate(s, f);
922 return nullptr;
925 Defined *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
926 ImportThunkChunk *chunk) {
927 auto [s, wasInserted] = insert(name, nullptr);
928 s->isUsedInRegularObj = true;
929 if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
930 replaceSymbol<DefinedImportThunk>(s, ctx, name, id, chunk);
931 return cast<Defined>(s);
934 reportDuplicate(s, id->file);
935 return nullptr;
938 void SymbolTable::addLibcall(StringRef name) {
939 Symbol *sym = findUnderscore(name);
940 if (!sym)
941 return;
943 if (auto *l = dyn_cast<LazyArchive>(sym)) {
944 MemoryBufferRef mb = l->getMemberBuffer();
945 if (isBitcode(mb))
946 addUndefined(sym->getName());
947 } else if (LazyObject *o = dyn_cast<LazyObject>(sym)) {
948 if (isBitcode(o->file->mb))
949 addUndefined(sym->getName());
953 Symbol *SymbolTable::find(StringRef name) const {
954 return symMap.lookup(CachedHashStringRef(name));
957 Symbol *SymbolTable::findUnderscore(StringRef name) const {
958 if (machine == I386)
959 return find(("_" + name).str());
960 return find(name);
963 // Return all symbols that start with Prefix, possibly ignoring the first
964 // character of Prefix or the first character symbol.
965 std::vector<Symbol *> SymbolTable::getSymsWithPrefix(StringRef prefix) {
966 std::vector<Symbol *> syms;
967 for (auto pair : symMap) {
968 StringRef name = pair.first.val();
969 if (name.starts_with(prefix) || name.starts_with(prefix.drop_front()) ||
970 name.drop_front().starts_with(prefix) ||
971 name.drop_front().starts_with(prefix.drop_front())) {
972 syms.push_back(pair.second);
975 return syms;
978 Symbol *SymbolTable::findMangle(StringRef name) {
979 if (Symbol *sym = find(name)) {
980 if (auto *u = dyn_cast<Undefined>(sym)) {
981 // We're specifically looking for weak aliases that ultimately resolve to
982 // defined symbols, hence the call to getWeakAlias() instead of just using
983 // the weakAlias member variable. This matches link.exe's behavior.
984 if (Symbol *weakAlias = u->getWeakAlias())
985 return weakAlias;
986 } else {
987 return sym;
991 // Efficient fuzzy string lookup is impossible with a hash table, so iterate
992 // the symbol table once and collect all possibly matching symbols into this
993 // vector. Then compare each possibly matching symbol with each possible
994 // mangling.
995 std::vector<Symbol *> syms = getSymsWithPrefix(name);
996 auto findByPrefix = [&syms](const Twine &t) -> Symbol * {
997 std::string prefix = t.str();
998 for (auto *s : syms)
999 if (s->getName().starts_with(prefix))
1000 return s;
1001 return nullptr;
1004 // For non-x86, just look for C++ functions.
1005 if (machine != I386)
1006 return findByPrefix("?" + name + "@@Y");
1008 if (!name.starts_with("_"))
1009 return nullptr;
1010 // Search for x86 stdcall function.
1011 if (Symbol *s = findByPrefix(name + "@"))
1012 return s;
1013 // Search for x86 fastcall function.
1014 if (Symbol *s = findByPrefix("@" + name.substr(1) + "@"))
1015 return s;
1016 // Search for x86 vectorcall function.
1017 if (Symbol *s = findByPrefix(name.substr(1) + "@@"))
1018 return s;
1019 // Search for x86 C++ non-member function.
1020 return findByPrefix("?" + name.substr(1) + "@@Y");
1023 bool SymbolTable::findUnderscoreMangle(StringRef sym) {
1024 Symbol *s = findMangle(mangle(sym));
1025 return s && !isa<Undefined>(s);
1028 // Symbol names are mangled by prepending "_" on x86.
1029 StringRef SymbolTable::mangle(StringRef sym) {
1030 assert(machine != IMAGE_FILE_MACHINE_UNKNOWN);
1031 if (machine == I386)
1032 return saver().save("_" + sym);
1033 return sym;
1036 StringRef SymbolTable::mangleMaybe(Symbol *s) {
1037 // If the plain symbol name has already been resolved, do nothing.
1038 Undefined *unmangled = dyn_cast<Undefined>(s);
1039 if (!unmangled)
1040 return "";
1042 // Otherwise, see if a similar, mangled symbol exists in the symbol table.
1043 Symbol *mangled = findMangle(unmangled->getName());
1044 if (!mangled)
1045 return "";
1047 // If we find a similar mangled symbol, make this an alias to it and return
1048 // its name.
1049 Log(ctx) << unmangled->getName() << " aliased to " << mangled->getName();
1050 unmangled->setWeakAlias(addUndefined(mangled->getName()));
1051 return mangled->getName();
1054 // Windows specific -- find default entry point name.
1056 // There are four different entry point functions for Windows executables,
1057 // each of which corresponds to a user-defined "main" function. This function
1058 // infers an entry point from a user-defined "main" function.
1059 StringRef SymbolTable::findDefaultEntry() {
1060 assert(ctx.config.subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
1061 "must handle /subsystem before calling this");
1063 if (ctx.config.mingw)
1064 return mangle(ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
1065 ? "WinMainCRTStartup"
1066 : "mainCRTStartup");
1068 if (ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
1069 if (findUnderscoreMangle("wWinMain")) {
1070 if (!findUnderscoreMangle("WinMain"))
1071 return mangle("wWinMainCRTStartup");
1072 Warn(ctx) << "found both wWinMain and WinMain; using latter";
1074 return mangle("WinMainCRTStartup");
1076 if (findUnderscoreMangle("wmain")) {
1077 if (!findUnderscoreMangle("main"))
1078 return mangle("wmainCRTStartup");
1079 Warn(ctx) << "found both wmain and main; using latter";
1081 return mangle("mainCRTStartup");
1084 WindowsSubsystem SymbolTable::inferSubsystem() {
1085 if (ctx.config.dll)
1086 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
1087 if (ctx.config.mingw)
1088 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
1089 // Note that link.exe infers the subsystem from the presence of these
1090 // functions even if /entry: or /nodefaultlib are passed which causes them
1091 // to not be called.
1092 bool haveMain = findUnderscoreMangle("main");
1093 bool haveWMain = findUnderscoreMangle("wmain");
1094 bool haveWinMain = findUnderscoreMangle("WinMain");
1095 bool haveWWinMain = findUnderscoreMangle("wWinMain");
1096 if (haveMain || haveWMain) {
1097 if (haveWinMain || haveWWinMain) {
1098 Warn(ctx) << "found " << (haveMain ? "main" : "wmain") << " and "
1099 << (haveWinMain ? "WinMain" : "wWinMain")
1100 << "; defaulting to /subsystem:console";
1102 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
1104 if (haveWinMain || haveWWinMain)
1105 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
1106 return IMAGE_SUBSYSTEM_UNKNOWN;
1109 void SymbolTable::addUndefinedGlob(StringRef arg) {
1110 Expected<GlobPattern> pat = GlobPattern::create(arg);
1111 if (!pat) {
1112 Err(ctx) << "/includeglob: " << toString(pat.takeError());
1113 return;
1116 SmallVector<Symbol *, 0> syms;
1117 forEachSymbol([&syms, &pat](Symbol *sym) {
1118 if (pat->match(sym->getName())) {
1119 syms.push_back(sym);
1123 for (Symbol *sym : syms)
1124 addGCRoot(sym->getName());
1127 // Convert stdcall/fastcall style symbols into unsuffixed symbols,
1128 // with or without a leading underscore. (MinGW specific.)
1129 static StringRef killAt(StringRef sym, bool prefix) {
1130 if (sym.empty())
1131 return sym;
1132 // Strip any trailing stdcall suffix
1133 sym = sym.substr(0, sym.find('@', 1));
1134 if (!sym.starts_with("@")) {
1135 if (prefix && !sym.starts_with("_"))
1136 return saver().save("_" + sym);
1137 return sym;
1139 // For fastcall, remove the leading @ and replace it with an
1140 // underscore, if prefixes are used.
1141 sym = sym.substr(1);
1142 if (prefix)
1143 sym = saver().save("_" + sym);
1144 return sym;
1147 static StringRef exportSourceName(ExportSource s) {
1148 switch (s) {
1149 case ExportSource::Directives:
1150 return "source file (directives)";
1151 case ExportSource::Export:
1152 return "/export";
1153 case ExportSource::ModuleDefinition:
1154 return "/def";
1155 default:
1156 llvm_unreachable("unknown ExportSource");
1160 // Performs error checking on all /export arguments.
1161 // It also sets ordinals.
1162 void SymbolTable::fixupExports() {
1163 llvm::TimeTraceScope timeScope("Fixup exports");
1164 // Symbol ordinals must be unique.
1165 std::set<uint16_t> ords;
1166 for (Export &e : exports) {
1167 if (e.ordinal == 0)
1168 continue;
1169 if (!ords.insert(e.ordinal).second)
1170 Fatal(ctx) << "duplicate export ordinal: " << e.name;
1173 for (Export &e : exports) {
1174 if (!e.exportAs.empty()) {
1175 e.exportName = e.exportAs;
1176 continue;
1179 StringRef sym =
1180 !e.forwardTo.empty() || e.extName.empty() ? e.name : e.extName;
1181 if (machine == I386 && sym.starts_with("_")) {
1182 // In MSVC mode, a fully decorated stdcall function is exported
1183 // as-is with the leading underscore (with type IMPORT_NAME).
1184 // In MinGW mode, a decorated stdcall function gets the underscore
1185 // removed, just like normal cdecl functions.
1186 if (ctx.config.mingw || !sym.contains('@')) {
1187 e.exportName = sym.substr(1);
1188 continue;
1191 if (isEC() && !e.data && !e.constant) {
1192 if (std::optional<std::string> demangledName =
1193 getArm64ECDemangledFunctionName(sym)) {
1194 e.exportName = saver().save(*demangledName);
1195 continue;
1198 e.exportName = sym;
1201 if (ctx.config.killAt && machine == I386) {
1202 for (Export &e : exports) {
1203 e.name = killAt(e.name, true);
1204 e.exportName = killAt(e.exportName, false);
1205 e.extName = killAt(e.extName, true);
1206 e.symbolName = killAt(e.symbolName, true);
1210 // Uniquefy by name.
1211 DenseMap<StringRef, std::pair<Export *, unsigned>> map(exports.size());
1212 std::vector<Export> v;
1213 for (Export &e : exports) {
1214 auto pair = map.insert(std::make_pair(e.exportName, std::make_pair(&e, 0)));
1215 bool inserted = pair.second;
1216 if (inserted) {
1217 pair.first->second.second = v.size();
1218 v.push_back(e);
1219 continue;
1221 Export *existing = pair.first->second.first;
1222 if (e == *existing || e.name != existing->name)
1223 continue;
1224 // If the existing export comes from .OBJ directives, we are allowed to
1225 // overwrite it with /DEF: or /EXPORT without any warning, as MSVC link.exe
1226 // does.
1227 if (existing->source == ExportSource::Directives) {
1228 *existing = e;
1229 v[pair.first->second.second] = e;
1230 continue;
1232 if (existing->source == e.source) {
1233 Warn(ctx) << "duplicate " << exportSourceName(existing->source)
1234 << " option: " << e.name;
1235 } else {
1236 Warn(ctx) << "duplicate export: " << e.name << " first seen in "
1237 << exportSourceName(existing->source) << ", now in "
1238 << exportSourceName(e.source);
1241 exports = std::move(v);
1243 // Sort by name.
1244 llvm::sort(exports, [](const Export &a, const Export &b) {
1245 return a.exportName < b.exportName;
1249 void SymbolTable::assignExportOrdinals() {
1250 // Assign unique ordinals if default (= 0).
1251 uint32_t max = 0;
1252 for (Export &e : exports)
1253 max = std::max(max, (uint32_t)e.ordinal);
1254 for (Export &e : exports)
1255 if (e.ordinal == 0)
1256 e.ordinal = ++max;
1257 if (max > std::numeric_limits<uint16_t>::max())
1258 Fatal(ctx) << "too many exported symbols (got " << max << ", max "
1259 << Twine(std::numeric_limits<uint16_t>::max()) << ")";
1262 void SymbolTable::parseModuleDefs(StringRef path) {
1263 llvm::TimeTraceScope timeScope("Parse def file");
1264 std::unique_ptr<MemoryBuffer> mb =
1265 CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
1266 /*RequiresNullTerminator=*/false,
1267 /*IsVolatile=*/true),
1268 "could not open " + path);
1269 COFFModuleDefinition m = check(parseCOFFModuleDefinition(
1270 mb->getMemBufferRef(), machine, ctx.config.mingw));
1272 // Include in /reproduce: output if applicable.
1273 ctx.driver.takeBuffer(std::move(mb));
1275 if (ctx.config.outputFile.empty())
1276 ctx.config.outputFile = std::string(saver().save(m.OutputFile));
1277 ctx.config.importName = std::string(saver().save(m.ImportName));
1278 if (m.ImageBase)
1279 ctx.config.imageBase = m.ImageBase;
1280 if (m.StackReserve)
1281 ctx.config.stackReserve = m.StackReserve;
1282 if (m.StackCommit)
1283 ctx.config.stackCommit = m.StackCommit;
1284 if (m.HeapReserve)
1285 ctx.config.heapReserve = m.HeapReserve;
1286 if (m.HeapCommit)
1287 ctx.config.heapCommit = m.HeapCommit;
1288 if (m.MajorImageVersion)
1289 ctx.config.majorImageVersion = m.MajorImageVersion;
1290 if (m.MinorImageVersion)
1291 ctx.config.minorImageVersion = m.MinorImageVersion;
1292 if (m.MajorOSVersion)
1293 ctx.config.majorOSVersion = m.MajorOSVersion;
1294 if (m.MinorOSVersion)
1295 ctx.config.minorOSVersion = m.MinorOSVersion;
1297 for (COFFShortExport e1 : m.Exports) {
1298 Export e2;
1299 // Renamed exports are parsed and set as "ExtName = Name". If Name has
1300 // the form "OtherDll.Func", it shouldn't be a normal exported
1301 // function but a forward to another DLL instead. This is supported
1302 // by both MS and GNU linkers.
1303 if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
1304 StringRef(e1.Name).contains('.')) {
1305 e2.name = saver().save(e1.ExtName);
1306 e2.forwardTo = saver().save(e1.Name);
1307 } else {
1308 e2.name = saver().save(e1.Name);
1309 e2.extName = saver().save(e1.ExtName);
1311 e2.exportAs = saver().save(e1.ExportAs);
1312 e2.importName = saver().save(e1.ImportName);
1313 e2.ordinal = e1.Ordinal;
1314 e2.noname = e1.Noname;
1315 e2.data = e1.Data;
1316 e2.isPrivate = e1.Private;
1317 e2.constant = e1.Constant;
1318 e2.source = ExportSource::ModuleDefinition;
1319 exports.push_back(e2);
1323 Symbol *SymbolTable::addUndefined(StringRef name) {
1324 return addUndefined(name, nullptr, false);
1327 void SymbolTable::compileBitcodeFiles() {
1328 if (bitcodeFileInstances.empty())
1329 return;
1331 llvm::TimeTraceScope timeScope("Compile bitcode");
1332 ScopedTimer t(ctx.ltoTimer);
1333 lto.reset(new BitcodeCompiler(ctx));
1334 for (BitcodeFile *f : bitcodeFileInstances)
1335 lto->add(*f);
1336 for (InputFile *newObj : lto->compile()) {
1337 ObjFile *obj = cast<ObjFile>(newObj);
1338 obj->parse();
1339 ctx.objFileInstances.push_back(obj);
1343 } // namespace lld::coff