bool X86IntelAsmPrinter::doInitialization(Module &M) { bool Result = AsmPrinter::doInitialization(M); Mang->markCharUnacceptable('.'); O << "\t.686\n\t.model flat\n\n"; // Emit declarations for external functions. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (I->isDeclaration()) { std::string Name = Mang->getValueName(I); decorateName(Name, I); O << "\textern " ; if (I->hasDLLImportLinkage()) { O << "__imp_"; } O << Name << ":near\n"; } // Emit declarations for external globals. Note that VC++ always declares // external globals to have type byte, and if that's good enough for VC++... for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->isDeclaration()) { std::string Name = Mang->getValueName(I); O << "\textern " ; if (I->hasDLLImportLinkage()) { O << "__imp_"; } O << Name << ":byte\n"; } } return Result; }
/// Based on GetAllUndefinedSymbols() from LLVM3.2 /// /// GetAllUndefinedSymbols - calculates the set of undefined symbols that still /// exist in an LLVM module. This is a bit tricky because there may be two /// symbols with the same name but different LLVM types that will be resolved to /// each other but aren't currently (thus we need to treat it as resolved). /// /// Inputs: /// M - The module in which to find undefined symbols. /// /// Outputs: /// UndefinedSymbols - A set of C++ strings containing the name of all /// undefined symbols. /// static void GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) { static const std::string llvmIntrinsicPrefix="llvm."; std::set<std::string> DefinedSymbols; UndefinedSymbols.clear(); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Computing undefined symbols for " << M->getModuleIdentifier() << " ***\n"); for (auto const &Function : *M) { if (Function.hasName()) { if (Function.isDeclaration()) UndefinedSymbols.insert(Function.getName()); else if (!Function.hasLocalLinkage()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!Function.hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!Function.hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif DefinedSymbols.insert(Function.getName()); } } } for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif DefinedSymbols.insert(I->getName()); } } for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); // Prune out any defined symbols from the undefined symbols set // and other symbols we don't want to treat as an undefined symbol std::vector<std::string> SymbolsToRemove; for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ++I ) { if (DefinedSymbols.find(*I) != DefinedSymbols.end()) { SymbolsToRemove.push_back(*I); continue; } // Strip out llvm intrinsics if ( (I->size() >= llvmIntrinsicPrefix.size() ) && (I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) ) { KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I << " has will be removed from undefined symbols"<< "\n"); SymbolsToRemove.push_back(*I); continue; } // Symbol really is undefined KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Symbol " << *I << " is undefined.\n"); } // Now remove the symbols from undefined set. for (auto const &symbol : SymbolsToRemove) UndefinedSymbols.erase(symbol); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Finished computing undefined symbols ***\n"); }