diff --git a/lib/BC/Util.cpp b/lib/BC/Util.cpp index a64644705..d902d6150 100644 --- a/lib/BC/Util.cpp +++ b/lib/BC/Util.cpp @@ -788,6 +788,9 @@ static llvm::Function *DeclareFunctionInModule(llvm::Function *func, static llvm::GlobalVariable *DeclareVarInModule(llvm::GlobalVariable *var, llvm::Module *dest_module); +static llvm::GlobalAlias *DeclareAliasInModule(llvm::GlobalAlias *var, + llvm::Module *dest_module); + template static void ClearMetaData(T *value) { llvm::SmallVector, 4> mds; @@ -808,7 +811,11 @@ static llvm::Constant *MoveConstantIntoModule(llvm::Constant *c, type = ::remill::RecontextualizeType(type, dest_context); } else { #if LLVM_VERSION_NUMBER > LLVM_VERSION(3, 8) - if (!c->needsRelocation()) { + if (!llvm::isa(c) && + !llvm::isa(c) && + !llvm::isa(c) && + !c->needsRelocation()) { + LOG(ERROR) << "Not moving: " << LLVMThingToString(c); return c; } #endif @@ -817,6 +824,9 @@ static llvm::Constant *MoveConstantIntoModule(llvm::Constant *c, if (auto gv = llvm::dyn_cast(c); gv) { return DeclareVarInModule(gv, dest_module); + } else if (auto ga = llvm::dyn_cast(c); ga) { + return DeclareAliasInModule(ga, dest_module); + } else if (auto func = llvm::dyn_cast(c); func) { return DeclareFunctionInModule(func, dest_module); @@ -1078,23 +1088,23 @@ static llvm::Constant *MoveConstantIntoModule(llvm::Constant *c, } else if (in_same_context) { LOG(ERROR) << "Unsupported CA when moving across module boundaries: " - << LLVMThingToString(ce); - return ca; + << LLVMThingToString(c); + return c; } else { LOG(FATAL) << "Unsupported CA when moving across context boundaries: " - << LLVMThingToString(ce); + << LLVMThingToString(c); return nullptr; } } else if (in_same_context) { LOG(ERROR) << "Unsupported constant when moving across module boundaries: " - << LLVMThingToString(ce); + << LLVMThingToString(c); return c; } else { LOG(FATAL) << "Unsupported constant when moving across context boundaries: " - << LLVMThingToString(ce); + << LLVMThingToString(c); return nullptr; } } @@ -1126,6 +1136,24 @@ llvm::GlobalVariable *DeclareVarInModule(llvm::GlobalVariable *var, return dest_var; } + +llvm::GlobalAlias *DeclareAliasInModule(llvm::GlobalAlias *var, + llvm::Module *dest_module) { + for (auto &alias : dest_module->aliases()) { + if (alias.getName() == var->getName()) { + return &alias; + } + } + + auto type = var->getType()->getElementType(); + auto dest_var = llvm::GlobalAlias::create( + type, var->getType()->getAddressSpace(), var->getLinkage(), + var->getName(), MoveConstantIntoModule(var->getAliasee(), dest_module), + dest_module); + + return dest_var; +} + } // namespace // Clone function `source_func` into `dest_func`, using `value_map` to map over @@ -1351,6 +1379,18 @@ void MoveFunctionIntoModule(llvm::Function *func, llvm::Module *dest_module) { op.set(MoveConstantIntoModule(c, dest_module)); } } + + if (auto ci = llvm::dyn_cast(&inst); ci) { + if (auto callee = ci->getCalledFunction(); + callee && callee->getParent() != dest_module) { + ci->setCalledOperand(DeclareFunctionInModule(callee, dest_module)); + } + } else if (auto ii = llvm::dyn_cast(&inst); ii) { + if (auto callee = ii->getCalledFunction(); + callee && callee->getParent() != dest_module) { + ii->setCalledOperand(DeclareFunctionInModule(callee, dest_module)); + } + } } } }