void AddressSanitizer::instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB, Value *Addr, uint32_t TypeSize, bool IsWrite) { Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); Type *ShadowTy = IntegerType::get( *C, std::max(8U, TypeSize >> MappingScale)); Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); Value *ShadowPtr = memToShadow(AddrLong, IRB); Value *CmpVal = Constant::getNullValue(ShadowTy); Value *ShadowValue = IRB.CreateLoad( IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); Instruction *CheckTerm = splitBlockAndInsertIfThen( cast<Instruction>(Cmp)->getNextNode(), Cmp); IRBuilder<> IRB2(CheckTerm); size_t Granularity = 1 << MappingScale; if (TypeSize < 8 * Granularity) { // Addr & (Granularity - 1) Value *Lower3Bits = IRB2.CreateAnd( AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); // (Addr & (Granularity - 1)) + size - 1 Value *LastAccessedByte = IRB2.CreateAdd( Lower3Bits, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); // (uint8_t) ((Addr & (Granularity-1)) + size - 1) LastAccessedByte = IRB2.CreateIntCast( LastAccessedByte, IRB.getInt8Ty(), false); // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue Value *Cmp2 = IRB2.CreateICmpSGE(LastAccessedByte, ShadowValue); CheckTerm = splitBlockAndInsertIfThen(CheckTerm, Cmp2); } IRBuilder<> IRB1(CheckTerm); Instruction *Crash = generateCrashCode(IRB1, AddrLong, IsWrite, TypeSize); Crash->setDebugLoc(OrigIns->getDebugLoc()); ReplaceInstWithInst(CheckTerm, new UnreachableInst(*C)); }
void AddressSanitizer::instrumentAddress(AsanFunctionContext &AFC, Instruction *OrigIns, IRBuilder<> &IRB, Value *Addr, uint32_t TypeSize, bool IsWrite) { Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); Type *ShadowTy = IntegerType::get( *C, std::max(8U, TypeSize >> MappingScale)); Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); Value *ShadowPtr = memToShadow(AddrLong, IRB); Value *CmpVal = Constant::getNullValue(ShadowTy); Value *ShadowValue = IRB.CreateLoad( IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); size_t Granularity = 1 << MappingScale; TerminatorInst *CrashTerm = 0; if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { TerminatorInst *CheckTerm = splitBlockAndInsertIfThen(Cmp, false); assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional()); BasicBlock *NextBB = CheckTerm->getSuccessor(0); IRB.SetInsertPoint(CheckTerm); Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); BasicBlock *CrashBlock = BasicBlock::Create(*C, "", &AFC.F, NextBB); CrashTerm = new UnreachableInst(*C, CrashBlock); BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); ReplaceInstWithInst(CheckTerm, NewTerm); } else { CrashTerm = splitBlockAndInsertIfThen(Cmp, true); } Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite, AccessSizeIndex); Crash->setDebugLoc(OrigIns->getDebugLoc()); }