13#include "klee/Support/Debug.h"
16#include "llvm/Analysis/ValueTracking.h"
17#include "llvm/BinaryFormat/Magic.h"
18#include "llvm/Bitcode/BitcodeReader.h"
19#include "llvm/IR/AssemblyAnnotationWriter.h"
20#include "llvm/IR/DiagnosticInfo.h"
21#include "llvm/IR/DiagnosticPrinter.h"
22#include "llvm/IR/Function.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/IR/IntrinsicInst.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
27#include "llvm/IR/ValueSymbolTable.h"
28#include "llvm/IRReader/IRReader.h"
29#include "llvm/Linker/Linker.h"
30#include "llvm/Object/Archive.h"
31#include "llvm/Object/Error.h"
32#include "llvm/Object/ObjectFile.h"
33#include "llvm/Support/FileSystem.h"
34#include "llvm/Support/MemoryBuffer.h"
35#include "llvm/Support/Path.h"
36#include "llvm/Support/raw_ostream.h"
37#include "llvm/Support/SourceMgr.h"
66 static const std::string llvmIntrinsicPrefix=
"llvm.";
67 std::set<std::string> DefinedSymbols;
68 UndefinedSymbols.clear();
69 KLEE_DEBUG_WITH_TYPE(
"klee_linker",
70 dbgs() <<
"*** Computing undefined symbols for "
71 << M->getModuleIdentifier() <<
" ***\n");
73 for (
auto const &Function : *M) {
74 if (Function.hasName()) {
75 if (Function.isDeclaration())
76 UndefinedSymbols.insert(Function.getName().str());
77 else if (!Function.hasLocalLinkage()) {
78 assert(!Function.hasDLLImportStorageClass() &&
79 "Found dllimported non-external symbol!");
80 DefinedSymbols.insert(Function.getName().str());
85 for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
88 if (I->isDeclaration())
89 UndefinedSymbols.insert(I->getName().str());
90 else if (!I->hasLocalLinkage()) {
91 assert(!I->hasDLLImportStorageClass() &&
"Found dllimported non-external symbol!");
92 DefinedSymbols.insert(I->getName().str());
96 for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
99 DefinedSymbols.insert(I->getName().str());
103 std::vector<std::string> SymbolsToRemove;
104 for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
105 I != UndefinedSymbols.end(); ++I )
107 if (DefinedSymbols.find(*I) != DefinedSymbols.end()) {
108 SymbolsToRemove.push_back(*I);
113 if ( (I->size() >= llvmIntrinsicPrefix.size() ) &&
114 (I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) )
116 KLEE_DEBUG_WITH_TYPE(
"klee_linker", dbgs() <<
"LLVM intrinsic " << *I <<
117 " has will be removed from undefined symbols"<<
"\n");
118 SymbolsToRemove.push_back(*I);
123 KLEE_DEBUG_WITH_TYPE(
"klee_linker",
124 dbgs() <<
"Symbol " << *I <<
" is undefined.\n");
128 for (
auto const &symbol : SymbolsToRemove)
129 UndefinedSymbols.erase(symbol);
131 KLEE_DEBUG_WITH_TYPE(
"klee_linker",
132 dbgs() <<
"*** Finished computing undefined symbols ***\n");
136 std::unique_ptr<llvm::Module> Src,
137 std::string &errorMsg) {
139 errorMsg =
"Linking module " + Src->getModuleIdentifier() +
" failed";
145std::unique_ptr<llvm::Module>
147 llvm::StringRef entryFunction, std::string &errorMsg) {
148 assert(!modules.empty() &&
"modules list should not be empty");
150 if (entryFunction.empty()) {
152 std::unique_ptr<llvm::Module> composite = std::move(modules.back());
156 for (
auto &module : modules) {
161 errorMsg =
"Linking archive module with composite failed:" + errorMsg;
175 std::unique_ptr<llvm::Module> composite;
176 for (
auto &module : modules) {
177 if (!module || !module->getNamedValue(entryFunction))
181 "Function " + entryFunction.str() +
182 " defined in different modules (" + module->getModuleIdentifier() +
183 " already defined in: " + composite->getModuleIdentifier() +
")";
186 composite = std::move(module);
192 "Entry function '" + entryFunction.str() +
"' not found in module.";
196 auto containsUsedSymbols = [](
const llvm::Module *module) {
198 dyn_cast_or_null<GlobalValue>(module->getNamedValue(
"llvm.used"));
201 KLEE_DEBUG_WITH_TYPE(
"klee_linker", dbgs() <<
"Used attribute in "
202 << module->getModuleIdentifier()
207 for (
auto &module : modules) {
208 if (!module || !containsUsedSymbols(module.get()))
210 if (!
linkTwoModules(composite.get(), std::move(module), errorMsg)) {
212 errorMsg =
"Linking module containing '__attribute__((used))'"
213 " symbols with composite failed:" +
220 bool symbolsLinked =
true;
221 while (symbolsLinked) {
222 symbolsLinked =
false;
223 std::set<std::string> undefinedSymbols;
225 auto hasRequiredDefinition = [&undefinedSymbols](
226 const llvm::Module *module) {
227 for (
auto symbol : undefinedSymbols) {
229 dyn_cast_or_null<GlobalValue>(module->getNamedValue(symbol));
230 if (GV && !GV->isDeclaration()) {
231 KLEE_DEBUG_WITH_TYPE(
"klee_linker",
232 dbgs() <<
"Found " << GV->getName() <<
" in "
233 << module->getModuleIdentifier() <<
"\n");
241 if (undefinedSymbols.empty())
244 for (
auto &module : modules) {
248 if (!hasRequiredDefinition(module.get()))
251 if (!
linkTwoModules(composite.get(), std::move(module), errorMsg)) {
253 errorMsg =
"Linking archive module with composite failed:" + errorMsg;
257 symbolsLinked =
true;
262 std::vector<std::unique_ptr<llvm::Module>> LeftoverModules;
263 for (
auto &module : modules) {
265 LeftoverModules.emplace_back(std::move(module));
268 modules.swap(LeftoverModules);
278 bool moduleIsFullyLinked) {
279#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
280 Value *v = cs.getCalledOperand();
282 Value *v = cs.getCalledValue();
284 bool viaConstantExpr =
false;
288 if (isa<llvm::GlobalVariable>(v)) {
290 viaConstantExpr =
false;
295 }
else if (Function *f = dyn_cast<Function>(v)) {
297 }
else if (llvm::GlobalAlias *ga = dyn_cast<GlobalAlias>(v)) {
298 if (moduleIsFullyLinked || !(ga->isInterposable())) {
299 v = ga->getAliasee();
303 }
else if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(v)) {
304 viaConstantExpr =
true;
305 v = ce->getOperand(0)->stripPointerCasts();
309 }
while (v !=
nullptr);
313 (void) viaConstantExpr;
314 assert((!viaConstantExpr) &&
315 "FIXME: Unresolved direct target for a constant expression");
320 for (
auto user : v->users()) {
321#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
323 if (
const auto *cs_ptr = dyn_cast<CallBase>(user)) {
324 const CallBase &cs = *cs_ptr;
326 if (
const auto *instr = dyn_cast<Instruction>(user)) {
328 const CallSite cs(
const_cast<Instruction *
>(instr));
329 if (!cs)
return false;
333 if (cs.hasArgument(v))
335 }
else if (
const auto *ce = dyn_cast<ConstantExpr>(user)) {
336 if (ce->getOpcode() == Instruction::BitCast)
340 }
else if (
const auto *ga = dyn_cast<GlobalAlias>(user)) {
343 }
else if (isa<BlockAddress>(user)) {
358bool klee::loadFile(
const std::string &fileName, LLVMContext &context,
359 std::vector<std::unique_ptr<llvm::Module>> &modules,
360 std::string &errorMsg) {
361 KLEE_DEBUG_WITH_TYPE(
"klee_loader", dbgs()
362 <<
"Load file " << fileName <<
"\n");
364 ErrorOr<std::unique_ptr<MemoryBuffer>> bufferErr =
365 MemoryBuffer::getFileOrSTDIN(fileName);
366 std::error_code ec = bufferErr.getError();
368 klee_error(
"Loading file %s failed: %s", fileName.c_str(),
369 ec.message().c_str());
372 MemoryBufferRef Buffer = bufferErr.get()->getMemBufferRef();
373 file_magic magic = identify_magic(Buffer.getBuffer());
375 if (magic == file_magic::bitcode) {
377 std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context));
379 klee_error(
"Loading file %s failed: %s", fileName.c_str(),
380 Err.getMessage().str().c_str());
382 modules.push_back(std::move(module));
386 if (magic == file_magic::archive) {
387 Expected<std::unique_ptr<object::Binary> > archOwner =
388 object::createBinary(Buffer, &context);
390 ec = errorToErrorCode(archOwner.takeError());
391 llvm::object::Binary *arch = archOwner.get().get();
393 klee_error(
"Loading file %s failed: %s", fileName.c_str(),
394 ec.message().c_str());
396 if (
auto archive = dyn_cast<object::Archive>(arch)) {
398 auto Err = Error::success();
399 for (
auto AI = archive->child_begin(Err), AE = archive->child_end();
403 StringRef memberName;
405 ErrorOr<object::Archive::Child> childOrErr = *AI;
406 ec = childOrErr.getError();
408 errorMsg = ec.message();
411 auto memberNameErr = childOrErr->getName();
412 ec = memberNameErr ? std::error_code() :
413 errorToErrorCode(memberNameErr.takeError());
415 memberName = memberNameErr.get();
416 KLEE_DEBUG_WITH_TYPE(
"klee_linker", dbgs()
417 <<
"Loading archive member "
418 << memberName <<
"\n");
420 errorMsg =
"Archive member does not have a name!\n";
424 Expected<std::unique_ptr<llvm::object::Binary> > child =
425 childOrErr->getAsBinary();
427 ec = errorToErrorCode(child.takeError());
430 auto buff = childOrErr->getMemoryBufferRef();
431 ec = buff ? std::error_code() : errorToErrorCode(buff.takeError());
433 errorMsg =
"Failed to get MemoryBuffer: " + ec.message();
442 std::unique_ptr<llvm::Module> module =
443 parseIR(buff.get(), Err, context);
445 klee_error(
"Loading file %s failed: %s", fileName.c_str(),
446 Err.getMessage().str().c_str());
449 modules.push_back(std::move(module));
451 errorMsg =
"Buffer was NULL!";
455 }
else if (child.get()->isObject()) {
456 errorMsg =
"Object file " + child.get()->getFileName().str() +
457 " in archive is not supported";
460 errorMsg =
"Loading archive child with error " + ec.message();
465 errorMsg =
"Cannot iterate over archive";
472 if (magic.is_object()) {
473 errorMsg =
"Loading file " + fileName +
474 " Object file as input is currently not supported";
479 std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context));
481 klee_error(
"Loading file %s failed: Unrecognized file type.",
484 modules.push_back(std::move(module));
static bool linkTwoModules(llvm::Module *Dest, std::unique_ptr< llvm::Module > Src, std::string &errorMsg)
static bool valueIsOnlyCalled(const Value *v)
static void GetAllUndefinedSymbols(Module *M, std::set< std::string > &UndefinedSymbols)
#define LLVM_VERSION_CODE
#define LLVM_VERSION(major, minor)
std::unique_ptr< llvm::Module > linkModules(std::vector< std::unique_ptr< llvm::Module > > &modules, llvm::StringRef entryFunction, std::string &errorMsg)
bool loadFile(const std::string &libraryName, llvm::LLVMContext &context, std::vector< std::unique_ptr< llvm::Module > > &modules, std::string &errorMsg)
bool functionEscapes(const llvm::Function *f)
llvm::Function * getDirectCallTarget(const llvm::CallBase &cb, bool moduleIsFullyLinked)
void klee_error(const char *msg,...) __attribute__((format(printf