From c09306ffd894f95be195723327d5b17dca73ebd1 Mon Sep 17 00:00:00 2001 From: Felix Rath Date: Fri, 22 May 2020 14:09:10 +0200 Subject: Implemented support for C++ Exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We implement the Itanium ABI unwinding base-API, and leave the C++-specific parts to libcxxabi. Co-authored-by: Lukas Wölfer --- lib/Module/ModuleUtil.cpp | 64 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'lib/Module/ModuleUtil.cpp') diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp index f4cc3048..2316ef45 100644 --- a/lib/Module/ModuleUtil.cpp +++ b/lib/Module/ModuleUtil.cpp @@ -203,41 +203,69 @@ klee::linkModules(std::vector> &modules, return nullptr; } - while (true) { + auto containsUsedSymbols = [](const llvm::Module *module) { + GlobalValue *GV = + dyn_cast_or_null(module->getNamedValue("llvm.used")); + if (!GV) + return false; + KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Used attribute in " + << module->getModuleIdentifier() + << '\n'); + return true; + }; + + for (auto &module : modules) { + if (!module || !containsUsedSymbols(module.get())) + continue; + if (!linkTwoModules(composite.get(), std::move(module), errorMsg)) { + // Linking failed + errorMsg = "Linking module containing '__attribute__((used))'" + " symbols with composite failed:" + + errorMsg; + return nullptr; + } + module = nullptr; + } + + bool symbolsLinked = true; + while (symbolsLinked) { + symbolsLinked = false; std::set undefinedSymbols; GetAllUndefinedSymbols(composite.get(), undefinedSymbols); + auto hasRequiredDefinition = [&undefinedSymbols]( + const llvm::Module *module) { + for (auto symbol : undefinedSymbols) { + GlobalValue *GV = + dyn_cast_or_null(module->getNamedValue(symbol)); + if (GV && !GV->isDeclaration()) { + KLEE_DEBUG_WITH_TYPE("klee_linker", + dbgs() << "Found " << GV->getName() << " in " + << module->getModuleIdentifier() << "\n"); + return true; + } + } + return false; + }; // Stop in nothing is undefined if (undefinedSymbols.empty()) break; - bool merged = false; for (auto &module : modules) { if (!module) continue; - for (auto symbol : undefinedSymbols) { - GlobalValue *GV = - dyn_cast_or_null(module->getNamedValue(symbol)); - if (!GV || GV->isDeclaration()) - continue; + if (!hasRequiredDefinition(module.get())) + continue; - // Found symbol, therefore merge in module - KLEE_DEBUG_WITH_TYPE("klee_linker", - dbgs() << "Found " << GV->getName() << " in " - << module->getModuleIdentifier() << "\n"); - if (linkTwoModules(composite.get(), std::move(module), errorMsg)) { - module = nullptr; - merged = true; - break; - } + if (!linkTwoModules(composite.get(), std::move(module), errorMsg)) { // Linking failed errorMsg = "Linking archive module with composite failed:" + errorMsg; return nullptr; } + module = nullptr; + symbolsLinked = true; } - if (!merged) - break; } // Condense the module array -- cgit 1.4.1