void Lint::visitIndirectBrInst(IndirectBrInst &I) { visitMemoryReference(I, I.getAddress(), MemoryLocation::UnknownSize, 0, nullptr, MemRef::Branchee); Assert(I.getNumDestinations() != 0, "Undefined behavior: indirectbr with no destinations", &I); }
void LLVM_General_GetIndirectBrDests( LLVMValueRef v, LLVMBasicBlockRef *dests ) { IndirectBrInst *ib = unwrap<IndirectBrInst>(v); for(unsigned i=0; i != ib->getNumDestinations(); ++i, ++dests) *dests = wrap(ib->getDestination(i)); }
void Lint::visitIndirectBrInst(IndirectBrInst &I) { visitMemoryReference(I, I.getAddress(), ~0u, 0, 0, MemRef::Branchee); }
void Lint::visitIndirectBrInst(IndirectBrInst &I) { visitMemoryReference(I, I.getAddress(), 0, 0); }
bool runOnFunction(Function &Func) override { if (Func.isDeclaration()) { return false; } vector<BranchInst *> BIs; for (inst_iterator I = inst_begin(Func); I != inst_end(Func); I++) { Instruction *Inst = &(*I); if (BranchInst *BI = dyn_cast<BranchInst>(Inst)) { BIs.push_back(BI); } } // Finish collecting branching conditions Value *zero = ConstantInt::get(Type::getInt32Ty(Func.getParent()->getContext()), 0); for (BranchInst *BI : BIs) { IRBuilder<> IRB(BI); vector<BasicBlock *> BBs; // We use the condition's evaluation result to generate the GEP // instruction False evaluates to 0 while true evaluates to 1. So here // we insert the false block first if (BI->isConditional()) { BBs.push_back(BI->getSuccessor(1)); } BBs.push_back(BI->getSuccessor(0)); ArrayType *AT = ArrayType::get( Type::getInt8PtrTy(Func.getParent()->getContext()), BBs.size()); vector<Constant *> BlockAddresses; for (unsigned i = 0; i < BBs.size(); i++) { BlockAddresses.push_back(BlockAddress::get(BBs[i])); } GlobalVariable *LoadFrom = NULL; if (BI->isConditional() || indexmap.find(BI->getSuccessor(0))==indexmap.end()) { // Create a new GV Constant *BlockAddressArray = ConstantArray::get(AT, ArrayRef<Constant *>(BlockAddresses)); LoadFrom = new GlobalVariable(*Func.getParent(), AT, false, GlobalValue::LinkageTypes::PrivateLinkage, BlockAddressArray); } else { LoadFrom = Func.getParent()->getGlobalVariable("IndirectBranchingGlobalTable",true); } Value *index = NULL; if (BI->isConditional()) { Value *condition = BI->getCondition(); index = IRB.CreateZExt( condition, Type::getInt32Ty(Func.getParent()->getContext())); } else { index = ConstantInt::get(Type::getInt32Ty(Func.getParent()->getContext()), indexmap[BI->getSuccessor(0)]); } Value *GEP = IRB.CreateGEP(LoadFrom, {zero, index}); LoadInst *LI = IRB.CreateLoad(GEP, "IndirectBranchingTargetAddress"); IndirectBrInst *indirBr = IndirectBrInst::Create(LI, BBs.size()); for (BasicBlock *BB : BBs) { indirBr->addDestination(BB); } ReplaceInstWithInst(BI, indirBr); } return true; }