diff options
Diffstat (limited to 'lld/COFF/SymbolTable.cpp')
-rw-r--r-- | lld/COFF/SymbolTable.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 189e75d..de04cdf 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -452,7 +452,7 @@ void SymbolTable::reportUnresolvable() { reportProblemSymbols(undefs, /*localImports=*/nullptr, true); } -void SymbolTable::resolveRemainingUndefines() { +void SymbolTable::resolveRemainingUndefines(std::vector<Undefined *> &aliases) { llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols"); SmallPtrSet<Symbol *, 8> undefs; DenseMap<Symbol *, Symbol *> localImports; @@ -468,8 +468,10 @@ void SymbolTable::resolveRemainingUndefines() { StringRef name = undef->getName(); // A weak alias may have been resolved, so check for that. - if (undef->resolveWeakAlias()) + if (undef->getWeakAlias()) { + aliases.push_back(undef); continue; + } // If we can resolve a symbol by removing __imp_ prefix, do that. // This odd rule is for compatibility with MSVC linker. @@ -620,10 +622,10 @@ void SymbolTable::initializeECThunks() { return; for (auto it : entryThunks) { - auto *to = dyn_cast<Defined>(it.second); + Defined *to = it.second->getDefined(); if (!to) continue; - auto *from = dyn_cast<DefinedRegular>(it.first); + auto *from = dyn_cast_or_null<DefinedRegular>(it.first->getDefined()); // We need to be able to add padding to the function and fill it with an // offset to its entry thunks. To ensure that padding the function is // feasible, functions are required to be COMDAT symbols with no offset. @@ -642,7 +644,8 @@ void SymbolTable::initializeECThunks() { Symbol *sym = exitThunks.lookup(file->thunkSym); if (!sym) sym = exitThunks.lookup(file->impECSym); - file->impchkThunk->exitThunk = dyn_cast_or_null<Defined>(sym); + if (sym) + file->impchkThunk->exitThunk = sym->getDefined(); } // On ARM64EC, the __imp_ symbol references the auxiliary IAT, while the @@ -659,6 +662,35 @@ void SymbolTable::initializeECThunks() { }); } +void SymbolTable::initializeSameAddressThunks() { + for (auto iter : ctx.config.sameAddresses) { + auto sym = dyn_cast_or_null<DefinedRegular>(iter.first->getDefined()); + if (!sym || !sym->isLive()) + continue; + auto nativeSym = + dyn_cast_or_null<DefinedRegular>(iter.second->getDefined()); + if (!nativeSym || !nativeSym->isLive()) + continue; + Defined *entryThunk = sym->getChunk()->getEntryThunk(); + if (!entryThunk) + continue; + + // Replace symbols with symbols referencing the thunk. Store the original + // symbol as equivalent DefinedSynthetic instances for use in the thunk + // itself. + auto symClone = make<DefinedSynthetic>(sym->getName(), sym->getChunk(), + sym->getValue()); + auto nativeSymClone = make<DefinedSynthetic>( + nativeSym->getName(), nativeSym->getChunk(), nativeSym->getValue()); + SameAddressThunkARM64EC *thunk = + make<SameAddressThunkARM64EC>(nativeSymClone, symClone, entryThunk); + sameAddressThunks.push_back(thunk); + + replaceSymbol<DefinedSynthetic>(sym, sym->getName(), thunk); + replaceSymbol<DefinedSynthetic>(nativeSym, nativeSym->getName(), thunk); + } +} + Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f, bool overrideLazy) { auto [s, wasInserted] = insert(name, f); |