void CheckModule::check_pthread_join(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *pthread_join = M->getFunction("pthread_join"); if(pthread_join){ if(!pthread_join->getReturnType()->isIntegerTy()){ err << "pthread_join returns non-integer type: " << *pthread_join->getReturnType(); throw CheckModuleError(err.str()); } if(pthread_join->getArgumentList().size() != 2){ err << "pthread_join takes wrong number of arguments (" << pthread_join->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } llvm::Type *arg0_ty, *arg1_ty; { auto it = pthread_join->arg_begin(); arg0_ty = it->getType(); arg1_ty = (++it)->getType(); } if(!arg0_ty->isIntegerTy()){ err << "First argument of pthread_join is non-integer type: " << *arg0_ty; throw CheckModuleError(err.str()); } llvm::Type *arg1_ty_expected = llvm::Type::getInt8PtrTy(M->getContext())->getPointerTo(); if(arg1_ty != arg1_ty_expected){ err << "Second argument of pthread_join has wrong type: " << *arg1_ty << ", should be " << *arg1_ty_expected; throw CheckModuleError(err.str()); } } }
void CheckModule::check_pthread_cond_wait(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction("pthread_cond_wait"); if(F){ if(!F->getReturnType()->isIntegerTy()){ err << "pthread_cond_wait returns non-integer type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } if(F->getArgumentList().size() != 2){ err << "pthread_cond_wait takes wrong number of arguments (" << F->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } llvm::Type *arg0ty, *arg1ty; { auto it = F->arg_begin(); arg0ty = it->getType(); arg1ty = (++it)->getType(); } if(!arg0ty->isPointerTy()){ err << "First argument of pthread_cond_wait has non-pointer type: " << *arg0ty; throw CheckModuleError(err.str()); } if(!arg1ty->isPointerTy()){ err << "Second argument of pthread_cond_wait has non-pointer type: " << *arg1ty; throw CheckModuleError(err.str()); } } }
void CheckModule::check_pthread_self(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *pthread_self = M->getFunction("pthread_self"); if(pthread_self){ if(!pthread_self->getReturnType()->isIntegerTy()){ err << "pthread_self returns non-integer type: " << *pthread_self->getReturnType(); throw CheckModuleError(err.str()); } if(pthread_self->getArgumentList().size()){ err << "pthread_self takes arguments. Should not take any."; throw CheckModuleError(err.str()); } } }
static void check_nondet_int(const llvm::Module *M, const std::string &name){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction(name); if(F){ if(!F->getReturnType()->isIntegerTy()){ err << name << " returns non-integer type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } } }
void CheckModule::check_malloc(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction("malloc"); if(F){ if(!F->getReturnType()->isPointerTy()){ err << "malloc returns non-pointer type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } } }
static void check_assume(const llvm::Module *M, const std::string &name){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction(name); if(F){ if(!F->getReturnType()->isVoidTy()){ err << name << " has non-void return type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } if(F->getArgumentList().size() != 1){ err << name << " takes wrong number of arguments (" << F->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } if(!F->arg_begin()->getType()->isIntegerTy()){ err << "First argument of " << name << " has non-integer type: " << *F->arg_begin()->getType(); throw CheckModuleError(err.str()); } } }
void CheckModule::check_pthread_mutex_destroy(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction("pthread_mutex_destroy"); if(F){ if(!F->getReturnType()->isIntegerTy()){ err << "pthread_mutex_destroy returns non-integer type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } if(F->getArgumentList().size() != 1){ err << "pthread_mutex_destroy takes wrong number of arguments (" << F->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } llvm::Type *arg0ty = F->arg_begin()->getType(); if(!arg0ty->isPointerTy()){ err << "First argument of pthread_mutex_destroy has non-pointer type: " << *arg0ty; throw CheckModuleError(err.str()); } } }
void CheckModule::check_malloc(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *F = M->getFunction("malloc"); if(F){ if(!F->getReturnType()->isPointerTy()){ err << "malloc returns non-pointer type: " << *F->getReturnType(); throw CheckModuleError(err.str()); } if(F->arg_size() != 1){ err << "malloc takes wrong number of arguments (" << F->arg_size() << ")"; throw CheckModuleError(err.str()); } llvm::Type *arg0ty = F->arg_begin()->getType(); if(!arg0ty->isIntegerTy()){ err << "Argument of malloc has non-integer type: " << *arg0ty; throw CheckModuleError(err.str()); } } }
void CheckModule::check_pthread_exit(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *pthread_exit = M->getFunction("pthread_exit"); if(pthread_exit){ if(!pthread_exit->getReturnType()->isVoidTy()){ err << "pthread_exit returns non-void type: " << *pthread_exit->getReturnType(); throw CheckModuleError(err.str()); } if(pthread_exit->getArgumentList().size() != 1){ err << "pthread_exit takes wrong number of arguments (" << pthread_exit->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } llvm::Type *ty = pthread_exit->arg_begin()->getType(), *ty_expected = llvm::Type::getInt8PtrTy(M->getContext()); if(ty != ty_expected){ err << "Argument of pthread_exit has wrong type: " << *ty << ", should be " << *ty_expected; throw CheckModuleError(err.str()); } } }
void CheckModule::check_pthread_create(const llvm::Module *M){ std::string _err; llvm::raw_string_ostream err(_err); llvm::Function *pthread_create = M->getFunction("pthread_create"); if(pthread_create){ if(!pthread_create->getReturnType()->isIntegerTy()){ err << "pthread_create returns non-integer type: " << *pthread_create->getReturnType(); throw CheckModuleError(err.str()); } if(pthread_create->getArgumentList().size() != 4){ err << "pthread_create takes wrong number of arguments (" << pthread_create->getArgumentList().size() << ")"; throw CheckModuleError(err.str()); } if(!pthread_create->arg_begin()->getType()->isPointerTy()){ err << "First argument of pthread_create is non-pointer type: " << *pthread_create->arg_begin()->getType(); throw CheckModuleError(err.str()); } llvm::Type *ty0e = static_cast<llvm::PointerType*>(pthread_create->arg_begin()->getType())->getElementType(); if(!ty0e->isIntegerTy()){ err << "First argument of pthread_create is pointer to non-integer type: " << *ty0e; throw CheckModuleError(err.str()); } llvm::Type *vpty = llvm::Type::getInt8PtrTy(M->getContext()); llvm::Type *fty = llvm::FunctionType::get(vpty,{vpty},false)->getPointerTo(); llvm::Type *arg2_ty, *arg3_ty; { auto it = pthread_create->arg_begin(); arg2_ty = (++++it)->getType(); arg3_ty = (++it)->getType(); } if(arg2_ty != fty){ err << "Third argument of pthread_create has wrong type: " << *arg2_ty << ", should be " << *fty; throw CheckModuleError(err.str()); } if(arg3_ty != vpty){ err << "Fourth argument of pthread_create has wrong type: " << *arg3_ty << ", should be " << *vpty; throw CheckModuleError(err.str()); } } }