BasicBlock *Program::createBasicBlock(ByteAddr address) { if (BasicBlock *result = getBasicBlockStartingAt(address)) { return result; } else if (BasicBlock *basicBlock = getBasicBlockCovering(address)) { removeRange(basicBlock); std::size_t i = 0; for (std::size_t size = basicBlock->statements().size(); i < size; ++i) { if (basicBlock->statements()[i]->instruction()->addr() >= address) { break; } } BasicBlock *result = takeOwnership(basicBlock->split(i, address)); addRange(basicBlock); addRange(result); return result; } else { BasicBlock *result = takeOwnership(std::make_unique<BasicBlock>(address)); addRange(result); return result; } }
BasicBlock *Program::takeOwnership(std::unique_ptr<BasicBlock> basicBlock) { assert(basicBlock != NULL); BasicBlock *result = basicBlock.get(); basicBlocks_.push_back(std::move(basicBlock)); if (result->address()) { assert(getBasicBlockStartingAt(*result->address()) == NULL); start2basicBlock_[*result->address()] = result; } return result; }
BasicBlock *Program::getBasicBlockForInstruction(const arch::Instruction *instruction) { /* If there is a basic block that starts here, just take it. */ BasicBlock *result = getBasicBlockStartingAt(instruction->addr()); if (!result) { /* Maybe this instruction stands next to an existing basic block? */ result = getBasicBlockCovering(instruction->addr() - 1); /* No way? Create new block. */ if (!result) { result = createBasicBlock(instruction->addr()); } } removeRange(result); result->setSuccessorAddress(instruction->endAddr()); addRange(result); return result; }
BasicBlock *Program::createBasicBlock(ByteAddr address) { if (BasicBlock *result = getBasicBlockStartingAt(address)) { return result; } else if (BasicBlock *basicBlock = getBasicBlockCovering(address)) { removeRange(basicBlock); auto iterator = std::find_if(basicBlock->statements().begin(), basicBlock->statements().end(), [address](const Statement *statement) { return statement->instruction()->addr() >= address; }); BasicBlock *result = takeOwnership(basicBlock->split(iterator, address)); addRange(basicBlock); addRange(result); return result; } else { BasicBlock *result = takeOwnership(std::make_unique<BasicBlock>(address)); addRange(result); return result; } }