lib/range-analysis/src/OverflowDetect/OverflowDetect.cpp
/*
 * Inserts global variable and function declarations, needed during the instrumentation.
 */
Inserts global variable and function declarations, needed during the instrumentation.
Inserts global variable and function declarations needed during the instrumentation .
void OverflowDetect::InsertGlobalDeclarations(){
	Constant* stringConstant = llvm::ConstantDataArray::getString(*context, "Overflow occurred in %s, line %d.\n", true);
	GlobalVariable* messageStr = new GlobalVariable(*module, stringConstant->getType(), true,
	                                                llvm::GlobalValue::InternalLinkage,
	                                                stringConstant, "OverflowMessage");
    constZero = ConstantInt::get(Type::getInt32Ty(*context), 0);
	Constant* constArray = ConstantExpr::getInBoundsGetElementPtr(messageStr, constZero);
	overflowMessagePtr = ConstantExpr::getBitCast(constArray, PointerType::getUnqual(Type::getInt8Ty(*context)));
	stringConstant = llvm::ConstantDataArray::getString(*context, "Truncation with data loss occurred in %s, line %d.\n", true);
	messageStr = new GlobalVariable(*module, stringConstant->getType(), true,
	                                                llvm::GlobalValue::InternalLinkage,
	                                                stringConstant, "TruncErrorMessage");
	constArray = ConstantExpr::getInBoundsGetElementPtr(messageStr, constZero);
	truncErrorMessagePtr = ConstantExpr::getBitCast(constArray, PointerType::getUnqual(Type::getInt8Ty(*context)));
	Type* IO_FILE_PTR_ty;
	GVstderr = module->getGlobalVariable("stderr");
	if (GVstderr == NULL) {
		StructType* IO_FILE_ty = StructType::create(*context, "struct._IO_FILE");
		IO_FILE_PTR_ty = PointerType::getUnqual(IO_FILE_ty);
		StructType* IO_marker_ty = StructType::create(*context, "struct._IO_marker");
		PointerType* IO_marker_ptr_ty = PointerType::getUnqual(IO_marker_ty);
		std::vector<Type*> Elements;
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(IO_marker_ptr_ty);
		Elements.push_back(IO_FILE_PTR_ty);
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(Type::getInt16Ty(*context));
		Elements.push_back(Type::getInt8Ty(*context));
		Elements.push_back(ArrayType::get(Type::getInt8Ty(*context), 1));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt64Ty(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt8PtrTy(*context));
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(Type::getInt32Ty(*context));
		Elements.push_back(ArrayType::get(Type::getInt8Ty(*context), 40));
		IO_FILE_ty->setBody(Elements, false);
		std::vector<Type*> Elements2;
		Elements2.push_back(IO_marker_ptr_ty);
		Elements2.push_back(IO_FILE_PTR_ty);
		Elements2.push_back(Type::getInt32Ty(*context));;
		IO_marker_ty->setBody(Elements2, false);
		GVstderr = new GlobalVariable(*module,IO_FILE_PTR_ty,false,GlobalValue::ExternalLinkage, NULL, "stderr");
	} else {
		IO_FILE_PTR_ty = GVstderr->getType();
		IO_FILE_PTR_ty = IO_FILE_PTR_ty->getContainedType(0);
	}
    std::vector<Type*> Params;
    Params.push_back(IO_FILE_PTR_ty);										
    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(*context)));	
    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(*context)));	
    Params.push_back(Type::getInt32Ty(*context));							
    FPrintF = module->getOrInsertFunction("fprintf",FunctionType::get(Type::getVoidTy(*context), Params, true));
    if (InsertAborts){
		FunctionType *AbortFTy = FunctionType::get(Type::getVoidTy(*context), false);
		Module::iterator Fit, Fend;
		bool alreadyDeclared = false;
		for (Fit = module->begin(), Fend =  module->end(); Fit != Fend; ++Fit){
			if (Fit->getName().equals("abort")) {
					alreadyDeclared = true;
					AbortF = Fit;
					break;
			}
		}
		if (!alreadyDeclared) {
				AbortF = Function::Create(AbortFTy, GlobalValue::ExternalLinkage, "abort", module);
		}
    }
}
void OverflowDetect :: InsertGlobalDeclarations ( ) { Constant * stringConstant = llvm :: ConstantDataArray :: getString ( * context , " \n " , true ) ; GlobalVariable * messageStr = new GlobalVariable ( * module , stringConstant -> getType ( ) , true , llvm :: GlobalValue :: InternalLinkage , stringConstant , " " ) ; constZero = ConstantInt :: get ( Type :: getInt32Ty ( * context ) , 0 ) ; Constant * constArray = ConstantExpr :: getInBoundsGetElementPtr ( messageStr , constZero ) ; overflowMessagePtr = ConstantExpr :: getBitCast ( constArray , PointerType :: getUnqual ( Type :: getInt8Ty ( * context ) ) ) ; stringConstant = llvm :: ConstantDataArray :: getString ( * context , " \n " , true ) ; messageStr = new GlobalVariable ( * module , stringConstant -> getType ( ) , true , llvm :: GlobalValue :: InternalLinkage , stringConstant , " " ) ; constArray = ConstantExpr :: getInBoundsGetElementPtr ( messageStr , constZero ) ; truncErrorMessagePtr = ConstantExpr :: getBitCast ( constArray , PointerType :: getUnqual ( Type :: getInt8Ty ( * context ) ) ) ; Type * IO_FILE_PTR_ty ; GVstderr = module -> getGlobalVariable ( " " ) ; if ( GVstderr == NULL ) { StructType * IO_FILE_ty = StructType :: create ( * context , " " ) ; IO_FILE_PTR_ty = PointerType :: getUnqual ( IO_FILE_ty ) ; StructType * IO_marker_ty = StructType :: create ( * context , " " ) ; PointerType * IO_marker_ptr_ty = PointerType :: getUnqual ( IO_marker_ty ) ; std :: vector < Type * > Elements ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( IO_marker_ptr_ty ) ; Elements . push_back ( IO_FILE_PTR_ty ) ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( Type :: getInt16Ty ( * context ) ) ; Elements . push_back ( Type :: getInt8Ty ( * context ) ) ; Elements . push_back ( ArrayType :: get ( Type :: getInt8Ty ( * context ) , 1 ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt64Ty ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt8PtrTy ( * context ) ) ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( Type :: getInt32Ty ( * context ) ) ; Elements . push_back ( ArrayType :: get ( Type :: getInt8Ty ( * context ) , 40 ) ) ; IO_FILE_ty -> setBody ( Elements , false ) ; std :: vector < Type * > Elements2 ; Elements2 . push_back ( IO_marker_ptr_ty ) ; Elements2 . push_back ( IO_FILE_PTR_ty ) ; Elements2 . push_back ( Type :: getInt32Ty ( * context ) ) ; ; IO_marker_ty -> setBody ( Elements2 , false ) ; GVstderr = new GlobalVariable ( * module , IO_FILE_PTR_ty , false , GlobalValue :: ExternalLinkage , NULL , " " ) ; } else { IO_FILE_PTR_ty = GVstderr -> getType ( ) ; IO_FILE_PTR_ty = IO_FILE_PTR_ty -> getContainedType ( 0 ) ; } std :: vector < Type * > Params ; Params . push_back ( IO_FILE_PTR_ty ) ; Params . push_back ( PointerType :: getUnqual ( Type :: getInt8Ty ( * context ) ) ) ; Params . push_back ( PointerType :: getUnqual ( Type :: getInt8Ty ( * context ) ) ) ; Params . push_back ( Type :: getInt32Ty ( * context ) ) ; FPrintF = module -> getOrInsertFunction ( " " , FunctionType :: get ( Type :: getVoidTy ( * context ) , Params , true ) ) ; if ( InsertAborts ) { FunctionType * AbortFTy = FunctionType :: get ( Type :: getVoidTy ( * context ) , false ) ; Module :: iterator Fit , Fend ; bool alreadyDeclared = false ; for ( Fit = module -> begin ( ) , Fend = module -> end ( ) ; Fit != Fend ; ++ Fit ) { if ( Fit -> getName ( ) . equals ( " " ) ) { alreadyDeclared = true ; AbortF = Fit ; break ; } } if ( ! alreadyDeclared ) { AbortF = Function :: Create ( AbortFTy , GlobalValue :: ExternalLinkage , " " , module ) ; } } }
Inserts global variable and function declarations, needed during the instrumentation.
Inserts global variable and function declarations needed during the instrumentation .
//Create a global variable with the fprintf Message //Get the int8ptr to our message //Get the int8ptr to our message //Insert the declaration of the stderr global external variable //Create the types to get the stderr //Get the type of the stderr //Get the type of the dereference of stderr //Create list of our fprintf argument types //stderr //message //file name //line number // Get the fprintf() function (takes an IO_FILE* and an i8* followed by variadic parameters) // Get void function type /*
		 *      Initialization of 'abort' function
		 */ // Before declaring the abort function, we need to check whether it is already declared or not