diff --git a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h index 07502e3b0..d8d72912c 100644 --- a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h @@ -55,7 +55,8 @@ class SymbolTableBuilder void buildMemModel(SVFModule* svfModule); /// Return size of this object based on LLVM value - u32_t getObjSize(const Type* type); + u32_t getNumOfElements(const Type* ety); + protected: @@ -93,6 +94,9 @@ class SymbolTableBuilder /// Analyse types of heap and static objects void analyzeStaticObjType(ObjTypeInfo* typeinfo, const Value* val); + /// Analyze byte size of heap alloc function (e.g. malloc/calloc/...) + u32_t analyzeHeapAllocByteSize(const Value* val); + ///Get a reference to the components of struct_info. /// Number of flattened elements of an array or struct u32_t getNumOfFlattenElements(const Type* T); diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index 563c420ba..6fa8a17b3 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -669,6 +669,65 @@ void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val) typeinfo->setFlag(ObjTypeInfo::HASPTR_OBJ); } +/*! + * Analyze byte size of heap alloc function (e.g. malloc/calloc/...) + * 1) __attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) + void* safe_malloc(unsigned long size). + Byte Size is the size(Arg0) + 2)__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) + char* safecalloc(int a, int b) + Byte Size is a(Arg0) * b(Arg1) + 3)__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) + void* __sysv_signal(int a, void *b) + Byte Size is Unknown + If all required arg values are constant, byte Size is also constant, + otherwise return ByteSize 0 + */ +u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val) { + if (const llvm::CallInst* callInst = llvm::dyn_cast(val)) + { + if (const llvm::Function* calledFunction = callInst->getCalledFunction()) + { + const SVFFunction* svfFunction = + LLVMModuleSet::getLLVMModuleSet()->getSVFFunction( + calledFunction); + std::vector args; + for (const std::string& annot : svfFunction->getAnnotations()) + { + if (annot == "UNKNOWN") + { + return 0; + } + if (annot.rfind("Arg", 0) == 0) + { + u32_t argIndex; + std::istringstream(annot.substr(3)) >> argIndex; + if (argIndex < callInst->getNumOperands() - 1) + { + args.push_back(callInst->getArgOperand(argIndex)); + } + } + } + u64_t product = 1; + for (const llvm::Value* arg : args) + { + if (const llvm::ConstantInt* constIntArg = + llvm::dyn_cast(arg)) + { + product *= constIntArg->getZExtValue(); + } + else + { + return 0; + } + } + return product; + } + } + // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size + return 0; +} + /*! * Analyse types of heap and static objects */ @@ -714,14 +773,20 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, const Type* objTy) { - u32_t objSize = 1; + u32_t elemNum = 1; + // init byteSize = 0, If byteSize is changed in the following process, + // it means that ObjTypeInfo has a Constant Byte Size + u32_t byteSize = 0; // Global variable + // if val is Function Obj, byteSize is not set if (SVFUtil::isa(val)) { typeinfo->setFlag(ObjTypeInfo::FUNCTION_OBJ); analyzeObjType(typeinfo,val); - objSize = getObjSize(objTy); + elemNum = getNumOfElements(objTy); } + /// if val is AllocaInst, byteSize is Type's LLVM ByteSize * ArraySize + /// e.g. alloc i32, 10. byteSize is 4 (i32's size) * 10 (ArraySize) = 40 else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast(val)) { typeinfo->setFlag(ObjTypeInfo::STACK_OBJ); @@ -729,18 +794,29 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, /// This is for `alloca `. For example, `alloca i64 3` allocates 3 i64 on the stack (objSize=3) /// In most cases, `NumElements` is not specified in the instruction, which means there is only one element (objSize=1). if(const ConstantInt* sz = SVFUtil::dyn_cast(allocaInst->getArraySize())) - objSize = sz->getZExtValue() * getObjSize(objTy); + { + elemNum = sz->getZExtValue() * getNumOfElements(objTy); + byteSize = sz->getZExtValue() * typeinfo->getType()->getLLVMByteSize(); + } + /// if ArraySize is not constant, byteSize is not static determined. else - objSize = getObjSize(objTy); + { + elemNum = getNumOfElements(objTy); + byteSize = 0; + } } + /// if val is GlobalVar, byteSize is Type's LLVM ByteSize + /// All GlobalVariable must have constant size else if(SVFUtil::isa(val)) { typeinfo->setFlag(ObjTypeInfo::GLOBVAR_OBJ); if(isConstantObjSym(val)) typeinfo->setFlag(ObjTypeInfo::CONST_GLOBAL_OBJ); analyzeObjType(typeinfo,val); - objSize = getObjSize(objTy); + elemNum = getNumOfElements(objTy); + byteSize = typeinfo->getType()->getLLVMByteSize(); } + /// if val is heap alloc else if (SVFUtil::isa(val) && isHeapAllocExtCall( LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction( @@ -748,18 +824,25 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, { analyzeHeapObjType(typeinfo,val); // Heap object, label its field as infinite here - objSize = typeinfo->getMaxFieldOffsetLimit(); + elemNum = typeinfo->getMaxFieldOffsetLimit(); + // analyze heap alloc like (malloc/calloc/...), the alloc functions have + // annotation like "AllocSize:Arg1". Please refer to extapi.c. + // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1", + // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40 + byteSize = analyzeHeapAllocByteSize(val); } else if(ArgInProgEntryFunction(val)) { analyzeStaticObjType(typeinfo,val); // user input data, label its field as infinite here - objSize = typeinfo->getMaxFieldOffsetLimit(); + elemNum = typeinfo->getMaxFieldOffsetLimit(); + byteSize = typeinfo->getType()->getLLVMByteSize(); } else if(LLVMUtil::isConstDataOrAggData(val)) { typeinfo->setFlag(ObjTypeInfo::CONST_DATA); - objSize = getNumOfFlattenElements(val->getType()); + elemNum = getNumOfFlattenElements(val->getType()); + byteSize = typeinfo->getType()->getLLVMByteSize(); } else { @@ -768,14 +851,20 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, } // Reset maxOffsetLimit if it is over the total fieldNum of this object - if(typeinfo->getMaxFieldOffsetLimit() > objSize) - typeinfo->setNumOfElements(objSize); + if(typeinfo->getMaxFieldOffsetLimit() > elemNum) + typeinfo->setNumOfElements(elemNum); + + // set ByteSize. If ByteSize > 0, this typeinfo has constant type. + // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size + // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize; + byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit(); + typeinfo->setByteSizeOfObj(byteSize); } /*! * Return size of this Object */ -u32_t SymbolTableBuilder::getObjSize(const Type* ety) +u32_t SymbolTableBuilder::getNumOfElements(const Type* ety) { assert(ety && "type is null?"); u32_t numOfFields = 1; diff --git a/svf-llvm/lib/extapi.c b/svf-llvm/lib/extapi.c index 3280d8e95..4094b27ca 100644 --- a/svf-llvm/lib/extapi.c +++ b/svf-llvm/lib/extapi.c @@ -14,541 +14,541 @@ MEMCPY, // memset() operations OVERWRITE, // svf function overwrite app function */ -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) void *malloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *fopen(const char *voidname, const char *mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *fopen64(const char *voidname, const char *mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *fdopen(int fd, const char *mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) struct dirent64 *readdir64(void *dirp) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *tmpvoid64(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) void *calloc(unsigned long nitems, unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *zmalloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *gzdopen(int fd, const char *mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *iconv_open(const char *tocode, const char *fromcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *lalloc(unsigned long size, int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *lalloc_clear(unsigned long size, int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) long *nhalloc(unsigned int a, const char *b, int c) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *oballoc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *popen(const char *command, const char *type) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *pthread_getspecific(const char *a, const char *b) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) struct dirent *readdir(void *dirp) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) void* safe_calloc(unsigned nelem, unsigned elsize) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void* safe_malloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) char* safecalloc(int a, int b) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) char* safemalloc(int a, int b) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *setmntent(const char *voidname, const char *type) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *shmat(int shmid, const void *shmaddr, int shmflg) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void* __sysv_signal(int a, void *b) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void (*signal(int sig, void (*func)(int)))(int) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *tempnam(const char *dir, const char *pfx) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *tmpvoid(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"), annotate("Arg1"))) void* xcalloc(unsigned long size1, unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void* xmalloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_Znam(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_Znaj(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_Znwj(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *__cxa_allocate_exception(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg1"))) void* aligned_alloc(unsigned long size1, unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg1"))) void* memalign(unsigned long size1, unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *valloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg1"))) void *mmap64(void *addr, unsigned long len, int prot, int flags, int fildes, long off) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *XSetLocaleModifiers(char *a) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char * __strdup(const char * string) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *crypt(const char *key, const char *salt) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *ctime(const void *timer) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *dlerror(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *dlopen(const char *voidname, int flags) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char *gai_strerror(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char *gcry_cipher_algo_name(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char *svfgcry_md_algo_name_(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *getenv(const char *name) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *getlogin(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *getpass(const char *prompt) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char * gnutls_strerror(int error) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char *gpg_strerror(unsigned int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) const char * gzerror(void* file, int * errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *inet_ntoa(unsigned int in) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *initscr(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void* llvm_stacksave() { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg1"))) void *mmap(void *addr, unsigned long len, int prot, int flags, int fildes, long off) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *newwin(int nlines, int ncols, int begin_y, int begin_x) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *nl_langinfo(int item) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *opendir(const char *name) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) void *sbrk(long increment) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *strdup(const char *s) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *strerror(int errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *strsignal(int errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *textdomain(const char * domainname) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *tgetstr(char *id, char **area) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *tigetstr(char *capname) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *tmpnam(char *s) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("UNKNOWN"))) char *ttyname(int fd) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("UNKNOWN"))) char *getcwd(char *buf, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("Arg1"))) char *mem_realloc(void *ptr, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("Arg1"))) char *realloc(void *ptr, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("Arg1"))) void* safe_realloc(void *p, unsigned long n) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("Arg1"), annotate("Arg2"))) void* saferealloc(void *p, unsigned long n1, unsigned long n2) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("UNKNOWN"))) void* safexrealloc() { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("UNKNOWN"))) char *strtok(char *str, const char *delim) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("UNKNOWN"))) char *strtok_r(char *str, const char *delim, char **saveptr) { return NULL; } -__attribute__((annotate("REALLOC_RET"))) +__attribute__((annotate("REALLOC_RET"), annotate("Arg1"))) void *xrealloc(void *ptr, unsigned long bytes) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_Znwm(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_ZnwmRKSt9nothrow_t(unsigned long size, void *) { return NULL; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) void *_ZnamRKSt9nothrow_t(unsigned long size, void *) { return NULL; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int asprintf(char **restrict strp, const char *restrict fmt, ...) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int vasprintf(char **strp, const char *fmt, void* ap) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int db_create(void **dbp, void *dbenv, unsigned int flags) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int gnutls_pkcs12_bag_init(void *a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int gnutls_pkcs12_init(void *a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int gnutls_x509_crt_init(void *a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("UNKNOWN"))) int gnutls_x509_privkey_init(void *a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"))) +__attribute__((annotate("ALLOC_ARG0"), annotate("Arg2"))) int posix_memalign(void **a, unsigned long b, unsigned long c) { return 0; } -__attribute__((annotate("ALLOC_ARG1"))) +__attribute__((annotate("ALLOC_ARG1"), annotate("UNKNOWN"))) int scandir(const char *restrict dirp, struct dirent ***restrict namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) { return 0; } -__attribute__((annotate("ALLOC_ARG2"))) +__attribute__((annotate("ALLOC_ARG2"), annotate("UNKNOWN"))) int XmbTextPropertyToTextList(void *a, void *b, char ***c, int *d) { return 0; @@ -664,7 +664,7 @@ void* _ZNSt5arrayIPK1ALm2EE4backEv(void *arg) return ptr2; } -__attribute__((annotate("ALLOC_RET"))) +__attribute__((annotate("ALLOC_RET"), annotate("Arg0"))) __attribute__((annotate("OVERWRITE"))) void *SyGetmem(unsigned long size) { diff --git a/svf/include/SVFIR/SymbolTableInfo.h b/svf/include/SVFIR/SymbolTableInfo.h index 7fdfad0af..5719897bc 100644 --- a/svf/include/SVFIR/SymbolTableInfo.h +++ b/svf/include/SVFIR/SymbolTableInfo.h @@ -438,6 +438,13 @@ class MemObj /// Whether it is a black hole object bool isBlackHoleObj() const; + /// Get the byte size of this object + u32_t getByteSizeOfObj() const; + + /// Check if byte size is a const value + bool isConstantByteSize() const; + + /// object attributes methods //@{ bool isFunction() const; @@ -505,6 +512,9 @@ class ObjTypeInfo /// Size of the object or number of elements u32_t elemNum; + /// Byte size of object + u32_t byteSize; + void resetTypeForHeapStaticObj(const SVFType* type); public: @@ -547,6 +557,22 @@ class ObjTypeInfo return elemNum; } + /// Get the byte size of this object + inline u32_t getByteSizeOfObj() const { + assert(isConstantByteSize() && "This Obj's byte size is not constant."); + return byteSize; + } + + /// Set the byte size of this object + inline void setByteSizeOfObj(u32_t size) { + byteSize = size; + } + + /// Check if byte size is a const value + inline bool isConstantByteSize() const { + return byteSize != 0; + } + /// Flag for this object type //@{ inline void setFlag(MEMTYPE mask) diff --git a/svf/lib/SVFIR/SymbolTableInfo.cpp b/svf/lib/SVFIR/SymbolTableInfo.cpp index df1946293..63394eaa2 100644 --- a/svf/lib/SVFIR/SymbolTableInfo.cpp +++ b/svf/lib/SVFIR/SymbolTableInfo.cpp @@ -429,6 +429,19 @@ u32_t MemObj::getNumOfElements() const return typeInfo->getNumOfElements(); } +/// Get the byte size of this object +u32_t MemObj::getByteSizeOfObj() const +{ + return typeInfo->getByteSizeOfObj(); +} + +/// Check if byte size is static determined +bool MemObj::isConstantByteSize() const +{ + return typeInfo->isConstantByteSize(); +} + + /// Set the number of elements of this object void MemObj::setNumOfElements(u32_t num) {