void AndroidBitcodeLinker::GetAllSymbols(Module *M, std::set<std::string> &UndefinedSymbols, std::set<std::string> &DefinedSymbols) { UndefinedSymbols.clear(); DefinedSymbols.clear(); Function *Main = M->getFunction("main"); if (Main == 0 || Main->isDeclaration()) UndefinedSymbols.insert("main"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::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()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) if (DefinedSymbols.count(*I)) UndefinedSymbols.erase(I++); else ++I; }
/// 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 ***\n"); for (Module::iterator I = M->begin(), E = M->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::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::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.count(*I)) { 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"); } // Remove KLEE intrinsics from set of undefined symbols for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(), se = SpecialFunctionHandler::end(); sf != se; ++sf) { if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end()) continue; SymbolsToRemove.push_back(sf->name); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "KLEE intrinsic " << sf->name << " has will be removed from undefined symbols"<< "\n"); } // Now remove the symbols from undefined set. for (size_t i = 0, j = SymbolsToRemove.size(); i < j; ++i ) UndefinedSymbols.erase(SymbolsToRemove[i]); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Finished computing undefined symbols ***\n"); }