diff options
-rw-r--r-- | include/klee/klee.h | 3 | ||||
-rw-r--r-- | lib/Core/Executor.cpp | 52 | ||||
-rw-r--r-- | lib/Core/Executor.h | 3 | ||||
-rw-r--r-- | lib/Core/ExternalDispatcher.cpp | 19 | ||||
-rw-r--r-- | lib/Core/ExternalDispatcher.h | 3 | ||||
-rw-r--r-- | lib/Core/Memory.h | 1 | ||||
-rw-r--r-- | lib/Core/SpecialFunctionHandler.cpp | 40 | ||||
-rw-r--r-- | lib/Core/SpecialFunctionHandler.h | 1 | ||||
-rw-r--r-- | runtime/POSIX/fd.c | 203 | ||||
-rw-r--r-- | test/Runtime/POSIX/DirSeek.c | 12 | ||||
-rw-r--r-- | test/Runtime/POSIX/Ioctl.c | 1 | ||||
-rw-r--r-- | tools/klee/main.cpp | 2 |
12 files changed, 174 insertions, 166 deletions
diff --git a/include/klee/klee.h b/include/klee/klee.h index 644c498e..8b9cd2e2 100644 --- a/include/klee/klee.h +++ b/include/klee/klee.h @@ -157,6 +157,9 @@ extern "C" { /* Merge all paths of the state that went through klee_open_merge */ void klee_close_merge(); + + /* Get errno value of the current state */ + int klee_get_errno(void); #ifdef __cplusplus } #endif diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 81b9ec3c..7b054e5b 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -524,14 +524,18 @@ void Executor::initializeGlobals(ExecutionState &state) { globalAddresses.insert(std::make_pair(f, addr)); } +#ifndef WINDOWS + int *errno_addr = getErrnoLocation(state); + MemoryObject *errnoObj = + addExternalObject(state, (void *)errno_addr, sizeof *errno_addr, false); + // Copy values from and to program space explicitly + errnoObj->isUserSpecified = true; +#endif + // Disabled, we don't want to promote use of live externals. #ifdef HAVE_CTYPE_EXTERNALS #ifndef WINDOWS #ifndef DARWIN - /* From /usr/include/errno.h: it [errno] is a per-thread variable. */ - int *errno_addr = __errno_location(); - addExternalObject(state, (void *)errno_addr, sizeof *errno_addr, false); - /* from /usr/include/ctype.h: These point into arrays of 384, so they can be indexed by any `unsigned char' value [0,255]; by EOF (-1); or by any `signed char' value @@ -3035,7 +3039,28 @@ void Executor::callExternalFunction(ExecutionState &state, } } + // Prepare external memory for invoking the function state.addressSpace.copyOutConcretes(); +#ifndef WINDOWS + // Update external errno state with local state value + int *errno_addr = getErrnoLocation(state); + ObjectPair result; + bool resolved = state.addressSpace.resolveOne( + ConstantExpr::create((uint64_t)errno_addr, Expr::Int64), result); + if (!resolved) + klee_error("Could not resolve memory object for errno"); + ref<Expr> errValueExpr = result.second->read(0, sizeof(*errno_addr) * 8); + ConstantExpr *errnoValue = dyn_cast<ConstantExpr>(errValueExpr); + if (!errnoValue) { + terminateStateOnExecError(state, + "external call with errno value symbolic: " + + function->getName()); + return; + } + + externalDispatcher->setLastErrno( + errnoValue->getZExtValue(sizeof(*errno_addr) * 8)); +#endif if (!SuppressExternalWarnings) { @@ -3055,6 +3080,7 @@ void Executor::callExternalFunction(ExecutionState &state, else klee_warning_once(function, "%s", os.str().c_str()); } + bool success = externalDispatcher->executeCall(function, target->inst, args); if (!success) { terminateStateOnError(state, "failed external call: " + function->getName(), @@ -3068,6 +3094,13 @@ void Executor::callExternalFunction(ExecutionState &state, return; } +#ifndef WINDOWS + // Update errno memory object with the errno value from the call + int error = externalDispatcher->getLastErrno(); + state.addressSpace.copyInConcrete(result.first, result.second, + (uint64_t)&error); +#endif + Type *resultType = target->inst->getType(); if (resultType != Type::getVoidTy(function->getContext())) { ref<Expr> e = ConstantExpr::fromMemory((void*) args, @@ -3814,6 +3847,17 @@ void Executor::prepareForEarlyExit() { statsTracker->done(); } } + +/// Returns the errno location in memory +int *Executor::getErrnoLocation(const ExecutionState &state) const { +#ifndef __APPLE__ + /* From /usr/include/errno.h: it [errno] is a per-thread variable. */ + return __errno_location(); +#else + return __error(); +#endif +} + /// Interpreter *Interpreter::create(LLVMContext &ctx, const InterpreterOptions &opts, diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h index 71b1f5f7..1bc91be0 100644 --- a/lib/Core/Executor.h +++ b/lib/Core/Executor.h @@ -525,6 +525,9 @@ public: Expr::Width getWidthForLLVMType(llvm::Type *type) const; size_t getAllocationAlignment(const llvm::Value *allocSite) const; + + /// Returns the errno location in memory of the state + int *getErrnoLocation(const ExecutionState &state) const; }; } // End klee namespace diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp index 6c54d34b..70c14050 100644 --- a/lib/Core/ExternalDispatcher.cpp +++ b/lib/Core/ExternalDispatcher.cpp @@ -65,6 +65,7 @@ private: llvm::Module *singleDispatchModule; std::vector<std::string> moduleIDs; std::string &getFreshModuleID(); + int lastErrno; public: ExternalDispatcherImpl(llvm::LLVMContext &ctx); @@ -72,6 +73,8 @@ public: bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args); void *resolveSymbol(const std::string &name); + int getLastErrno(); + void setLastErrno(int newErrno); }; std::string &ExternalDispatcherImpl::getFreshModuleID() { @@ -114,7 +117,8 @@ void *ExternalDispatcherImpl::resolveSymbol(const std::string &name) { return addr; } -ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx) : ctx(ctx) { +ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx) + : ctx(ctx), lastErrno(0) { std::string error; singleDispatchModule = new Module(getFreshModuleID(), ctx); #if LLVM_VERSION_CODE < LLVM_VERSION(3, 6) @@ -252,7 +256,10 @@ bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) { if (setjmp(escapeCallJmpBuf)) { res = false; } else { + errno = lastErrno; executionEngine->runFunction(f, gvArgs); + // Explicitly acquire errno information + lastErrno = errno; res = true; } @@ -346,6 +353,11 @@ Function *ExternalDispatcherImpl::createDispatcher(Function *target, return dispatcher; } +int ExternalDispatcherImpl::getLastErrno() { return lastErrno; } +void ExternalDispatcherImpl::setLastErrno(int newErrno) { + lastErrno = newErrno; +} + ExternalDispatcher::ExternalDispatcher(llvm::LLVMContext &ctx) : impl(new ExternalDispatcherImpl(ctx)) {} @@ -359,4 +371,9 @@ bool ExternalDispatcher::executeCall(llvm::Function *function, void *ExternalDispatcher::resolveSymbol(const std::string &name) { return impl->resolveSymbol(name); } + +int ExternalDispatcher::getLastErrno() { return impl->getLastErrno(); } +void ExternalDispatcher::setLastErrno(int newErrno) { + impl->setLastErrno(newErrno); +} } diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h index c64dc7d8..7c3a1d79 100644 --- a/lib/Core/ExternalDispatcher.h +++ b/lib/Core/ExternalDispatcher.h @@ -40,6 +40,9 @@ public: bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args); void *resolveSymbol(const std::string &name); + + int getLastErrno(); + void setLastErrno(int newErrno); }; } diff --git a/lib/Core/Memory.h b/lib/Core/Memory.h index 3084cf32..e854502c 100644 --- a/lib/Core/Memory.h +++ b/lib/Core/Memory.h @@ -154,6 +154,7 @@ private: const MemoryObject *object; uint8_t *concreteStore; + // XXX cleanup name of flushMask (its backwards or something) BitArray *concreteMask; diff --git a/lib/Core/SpecialFunctionHandler.cpp b/lib/Core/SpecialFunctionHandler.cpp index 6587c30b..75456856 100644 --- a/lib/Core/SpecialFunctionHandler.cpp +++ b/lib/Core/SpecialFunctionHandler.cpp @@ -91,6 +91,11 @@ static SpecialFunctionHandler::HandlerInfo handlerInfo[] = { add("klee_define_fixed_object", handleDefineFixedObject, false), add("klee_get_obj_size", handleGetObjSize, true), add("klee_get_errno", handleGetErrno, true), +#ifndef __APPLE__ + add("__errno_location", handleErrnoLocation, true), +#else + add("__error", handleErrnoLocation, true), +#endif add("klee_is_symbolic", handleIsSymbolic, true), add("klee_make_symbolic", handleMakeSymbolic, false), add("klee_mark_global", handleMarkGlobal, false), @@ -578,10 +583,41 @@ void SpecialFunctionHandler::handleGetErrno(ExecutionState &state, // XXX should type check args assert(arguments.size()==0 && "invalid number of arguments to klee_get_errno"); - executor.bindLocal(target, state, - ConstantExpr::create(errno, Expr::Int32)); +#ifndef WINDOWS + int *errno_addr = executor.getErrnoLocation(state); +#else + int *errno_addr = nullptr; +#endif + + // Retrieve the memory object of the errno variable + ObjectPair result; + bool resolved = state.addressSpace.resolveOne( + ConstantExpr::create((uint64_t)errno_addr, Expr::Int64), result); + if (!resolved) + executor.terminateStateOnError(state, "Could not resolve address for errno", + Executor::User); + executor.bindLocal(target, state, result.second->read(0, Expr::Int32)); } +void SpecialFunctionHandler::handleErrnoLocation( + ExecutionState &state, KInstruction *target, + std::vector<ref<Expr> > &arguments) { + // Returns the address of the errno variable + assert(arguments.size() == 0 && + "invalid number of arguments to __errno_location/__error"); + +#ifndef WINDOWS + int *errno_addr = executor.getErrnoLocation(state); +#else + int *errno_addr = nullptr; +#endif + + executor.bindLocal( + target, state, + ConstantExpr::create((uint64_t)errno_addr, + executor.kmodule->targetData->getTypeSizeInBits( + target->inst->getType()))); +} void SpecialFunctionHandler::handleCalloc(ExecutionState &state, KInstruction *target, std::vector<ref<Expr> > &arguments) { diff --git a/lib/Core/SpecialFunctionHandler.h b/lib/Core/SpecialFunctionHandler.h index 7e58018f..b11a4974 100644 --- a/lib/Core/SpecialFunctionHandler.h +++ b/lib/Core/SpecialFunctionHandler.h @@ -107,6 +107,7 @@ namespace klee { HANDLER(handleDelete); HANDLER(handleDeleteArray); HANDLER(handleExit); + HANDLER(handleErrnoLocation); HANDLER(handleAliasFunction); HANDLER(handleFree); HANDLER(handleGetErrno); diff --git a/runtime/POSIX/fd.c b/runtime/POSIX/fd.c index 6f78c747..e0e87604 100644 --- a/runtime/POSIX/fd.c +++ b/runtime/POSIX/fd.c @@ -29,12 +29,6 @@ #include <sys/select.h> #include <klee/klee.h> -/* #define DEBUG */ - -void klee_warning(const char*); -void klee_warning_once(const char*); -int klee_get_errno(void); - /* Returns pointer to the symbolic file structure fs the pathname is symbolic */ static exe_disk_file_t *__get_sym_file(const char *pathname) { if (!pathname) @@ -80,12 +74,8 @@ int access(const char *pathname, int mode) { /* XXX we should check against stat values but we also need to enforce in open and friends then. */ return 0; - } else { - int r = syscall(__NR_access, __concretize_string(pathname), mode); - if (r == -1) - errno = klee_get_errno(); - return r; - } + } + return syscall(__NR_access, __concretize_string(pathname), mode); } mode_t umask(mode_t mask) { @@ -182,10 +172,8 @@ int __fd_open(const char *pathname, int flags, mode_t mode) { (mode & ~__exe_env.umask)); } else { int os_fd = syscall(__NR_open, __concretize_string(pathname), flags, mode); - if (os_fd == -1) { - errno = klee_get_errno(); + if (os_fd == -1) return -1; - } f->fd = os_fd; } @@ -237,10 +225,8 @@ int __fd_openat(int basefd, const char *pathname, int flags, mode_t mode) { memset(f, 0, sizeof *f); int os_fd = syscall(__NR_openat, (long)basefd, __concretize_string(pathname), (long)flags, mode); - if (os_fd == -1) { - errno = klee_get_errno(); + if (os_fd == -1) return -1; - } f->fd = os_fd; f->flags = eOpen; @@ -269,11 +255,7 @@ int utimes(const char *path, const struct timeval times[2]) { #endif return 0; } - int r = syscall(__NR_utimes, __concretize_string(path), times); - if (r == -1) - errno = klee_get_errno(); - - return r; + return syscall(__NR_utimes, __concretize_string(path), times); } @@ -295,12 +277,8 @@ int futimesat(int fd, const char* path, const struct timeval times[2]) { return utimes(path, times); } - int r = syscall(__NR_futimesat, (long)fd, - (path ? __concretize_string(path) : NULL), - times); - if (r == -1) - errno = klee_get_errno(); - return r; + return syscall(__NR_futimesat, (long)fd, + (path ? __concretize_string(path) : NULL), times); } int close(int fd) { @@ -376,10 +354,8 @@ ssize_t read(int fd, void *buf, size_t count) { else r = syscall(__NR_pread64, f->fd, buf, count, (off64_t) f->off); - if (r == -1) { - errno = klee_get_errno(); + if (r == -1) return -1; - } if (f->fd != 0) f->off += r; @@ -434,11 +410,9 @@ ssize_t write(int fd, const void *buf, size_t count) { if (f->fd == 1 || f->fd == 2) r = syscall(__NR_write, f->fd, buf, count); else r = syscall(__NR_pwrite64, f->fd, buf, count, (off64_t) f->off); - - if (r == -1) { - errno = klee_get_errno(); + + if (r == -1) return -1; - } assert(r >= 0); if (f->fd != 1 && f->fd != 2) @@ -504,10 +478,8 @@ off64_t __fd_lseek(int fd, off64_t offset, int whence) { } } - if (new_off == -1) { - errno = klee_get_errno(); + if (new_off == -1) return -1; - } f->off = new_off; return new_off; @@ -541,13 +513,10 @@ int __fd_stat(const char *path, struct stat64 *buf) { { #if __WORDSIZE == 64 - int r = syscall(__NR_stat, __concretize_string(path), buf); + return syscall(__NR_stat, __concretize_string(path), buf); #else - int r = syscall(__NR_stat64, __concretize_string(path), buf); + return syscall(__NR_stat64, __concretize_string(path), buf); #endif - if (r == -1) - errno = klee_get_errno(); - return r; } } @@ -572,18 +541,12 @@ int fstatat(int fd, const char *path, struct stat *buf, int flags) { } #if (defined __NR_newfstatat) && (__NR_newfstatat != 0) - int r = syscall(__NR_newfstatat, (long)fd, - (path ? __concretize_string(path) : NULL), - buf, (long)flags); + return syscall(__NR_newfstatat, (long)fd, + (path ? __concretize_string(path) : NULL), buf, (long)flags); #else - int r = syscall(__NR_fstatat64, (long)fd, - (path ? __concretize_string(path) : NULL), - buf, (long)flags); + return syscall(__NR_fstatat64, (long)fd, + (path ? __concretize_string(path) : NULL), buf, (long)flags); #endif - - if (r == -1) - errno = klee_get_errno(); - return r; } @@ -596,13 +559,10 @@ int __fd_lstat(const char *path, struct stat64 *buf) { { #if __WORDSIZE == 64 - int r = syscall(__NR_lstat, __concretize_string(path), buf); + return syscall(__NR_lstat, __concretize_string(path), buf); #else - int r = syscall(__NR_lstat64, __concretize_string(path), buf); + return syscall(__NR_lstat64, __concretize_string(path), buf); #endif - if (r == -1) - errno = klee_get_errno(); - return r; } } @@ -616,12 +576,7 @@ int chdir(const char *path) { return -1; } - { - int r = syscall(__NR_chdir, __concretize_string(path)); - if (r == -1) - errno = klee_get_errno(); - return r; - } + return syscall(__NR_chdir, __concretize_string(path)); } int fchdir(int fd) { @@ -636,12 +591,9 @@ int fchdir(int fd) { klee_warning("symbolic file, ignoring (ENOENT)"); errno = ENOENT; return -1; - } else { - int r = syscall(__NR_fchdir, f->fd); - if (r == -1) - errno = klee_get_errno(); - return r; } + + return syscall(__NR_fchdir, f->fd); } /* Sets mode and or errno and return appropriate result. */ @@ -672,12 +624,9 @@ int chmod(const char *path, mode_t mode) { if (dfile) { return __df_chmod(dfile, mode); - } else { - int r = syscall(__NR_chmod, __concretize_string(path), mode); - if (r == -1) - errno = klee_get_errno(); - return r; } + + return syscall(__NR_chmod, __concretize_string(path), mode); } int fchmod(int fd, mode_t mode) { @@ -699,12 +648,9 @@ int fchmod(int fd, mode_t mode) { if (f->dfile) { return __df_chmod(f->dfile, mode); - } else { - int r = syscall(__NR_fchmod, f->fd, mode); - if (r == -1) - errno = klee_get_errno(); - return r; - } + } + + return syscall(__NR_fchmod, f->fd, mode); } static int __df_chown(exe_disk_file_t *df, uid_t owner, gid_t group) { @@ -718,12 +664,9 @@ int chown(const char *path, uid_t owner, gid_t group) { if (df) { return __df_chown(df, owner, group); - } else { - int r = syscall(__NR_chown, __concretize_string(path), owner, group); - if (r == -1) - errno = klee_get_errno(); - return r; } + + return syscall(__NR_chown, __concretize_string(path), owner, group); } int fchown(int fd, uid_t owner, gid_t group) { @@ -736,12 +679,9 @@ int fchown(int fd, uid_t owner, gid_t group) { if (f->dfile) { return __df_chown(f->dfile, owner, group); - } else { - int r = syscall(__NR_fchown, fd, owner, group); - if (r == -1) - errno = klee_get_errno(); - return r; } + + return syscall(__NR_fchown, fd, owner, group); } int lchown(const char *path, uid_t owner, gid_t group) { @@ -750,12 +690,9 @@ int lchown(const char *path, uid_t owner, gid_t group) { if (df) { return __df_chown(df, owner, group); - } else { - int r = syscall(__NR_chown, __concretize_string(path), owner, group); - if (r == -1) - errno = klee_get_errno(); - return r; } + + return syscall(__NR_chown, __concretize_string(path), owner, group); } int __fd_fstat(int fd, struct stat64 *buf) { @@ -768,13 +705,10 @@ int __fd_fstat(int fd, struct stat64 *buf) { if (!f->dfile) { #if __WORDSIZE == 64 - int r = syscall(__NR_fstat, f->fd, buf); + return syscall(__NR_fstat, f->fd, buf); #else - int r = syscall(__NR_fstat64, f->fd, buf); + return syscall(__NR_fstat64, f->fd, buf); #endif - if (r == -1) - errno = klee_get_errno(); - return r; } memcpy(buf, f->dfile->stat, sizeof(*f->dfile->stat)); @@ -802,16 +736,12 @@ int __fd_ftruncate(int fd, off64_t length) { klee_warning("symbolic file, ignoring (EIO)"); errno = EIO; return -1; - } else { + } #if __WORDSIZE == 64 - int r = syscall(__NR_ftruncate, f->fd, length); + return syscall(__NR_ftruncate, f->fd, length); #else - int r = syscall(__NR_ftruncate64, f->fd, length); + return syscall(__NR_ftruncate64, f->fd, length); #endif - if (r == -1) - errno = klee_get_errno(); - return r; - } } int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count) { @@ -877,19 +807,17 @@ int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count) { s = syscall(__NR_lseek, f->fd, os_pos, SEEK_SET); assert(s != (off64_t) -1); res = syscall(__NR_getdents64, f->fd, dirp, count); - if (res == -1) { - errno = klee_get_errno(); - } else { + if (res > -1) { int pos = 0; - f->off = syscall(__NR_lseek, f->fd, 0, SEEK_CUR) + 4096; + f->off = syscall(__NR_lseek, f->fd, 0, SEEK_CUR); + assert(f->off != (off64_t)-1); + f->off += 4096; /* Patch offsets */ - while (pos < res) { struct dirent64 *dp = (struct dirent64*) ((char*) dirp + pos); dp->d_off += 4096; pos += dp->d_reclen; - } } return res; @@ -918,7 +846,6 @@ int ioctl(int fd, unsigned long request, ...) { va_start(ap, request); buf = va_arg(ap, void*); va_end(ap); - if (f->dfile) { struct stat *stat = (struct stat*) f->dfile->stat; @@ -1040,12 +967,8 @@ int ioctl(int fd, unsigned long request, ...) { errno = EINVAL; return -1; } - } else { - int r = syscall(__NR_ioctl, f->fd, request, buf ); - if (r == -1) - errno = klee_get_errno(); - return r; } + return syscall(__NR_ioctl, f->fd, request, buf); } int fcntl(int fd, int cmd, ...) { @@ -1095,12 +1018,8 @@ int fcntl(int fd, int cmd, ...) { errno = EINVAL; return -1; } - } else { - int r = syscall(__NR_fcntl, f->fd, cmd, arg ); - if (r == -1) - errno = klee_get_errno(); - return r; } + return syscall(__NR_fcntl, f->fd, cmd, arg); } int __fd_statfs(const char *path, struct statfs *buf) { @@ -1112,12 +1031,7 @@ int __fd_statfs(const char *path, struct statfs *buf) { return -1; } - { - int r = syscall(__NR_statfs, __concretize_string(path), buf); - if (r == -1) - errno = klee_get_errno(); - return r; - } + return syscall(__NR_statfs, __concretize_string(path), buf); } int fstatfs(int fd, struct statfs *buf) { @@ -1132,12 +1046,8 @@ int fstatfs(int fd, struct statfs *buf) { klee_warning("symbolic file, ignoring (EBADF)"); errno = EBADF; return -1; - } else { - int r = syscall(__NR_fstatfs, f->fd, buf); - if (r == -1) - errno = klee_get_errno(); - return r; } + return syscall(__NR_fstatfs, f->fd, buf); } int fsync(int fd) { @@ -1148,12 +1058,8 @@ int fsync(int fd) { return -1; } else if (f->dfile) { return 0; - } else { - int r = syscall(__NR_fsync, f->fd); - if (r == -1) - errno = klee_get_errno(); - return r; } + return syscall(__NR_fsync, f->fd); } int dup2(int oldfd, int newfd) { @@ -1278,12 +1184,8 @@ ssize_t readlink(const char *path, char *buf, size_t bufsize) { errno = EINVAL; return -1; } - } else { - int r = syscall(__NR_readlink, path, buf, bufsize); - if (r == -1) - errno = klee_get_errno(); - return r; } + return syscall(__NR_readlink, path, buf, bufsize); } #undef FD_SET @@ -1356,10 +1258,8 @@ int select(int nfds, fd_set *read, fd_set *write, if (r == -1) { /* If no symbolic results, return error. Otherwise we will silently ignore the OS error. */ - if (!count) { - errno = klee_get_errno(); + if (!count) return -1; - } } else { count += r; @@ -1405,11 +1305,8 @@ char *getcwd(char *buf, size_t size) { to properly work with symbolics. */ klee_check_memory_access(buf, size); r = syscall(__NR_getcwd, buf, size); - if (r == -1) { - errno = klee_get_errno(); + if (r == -1) return NULL; - } - return buf; } diff --git a/test/Runtime/POSIX/DirSeek.c b/test/Runtime/POSIX/DirSeek.c index 3908b4e2..4c68a30c 100644 --- a/test/Runtime/POSIX/DirSeek.c +++ b/test/Runtime/POSIX/DirSeek.c @@ -1,4 +1,4 @@ -// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc +// RUN: %llvmgcc %s -emit-llvm -O0 -c -g -o %t2.bc // RUN: rm -rf %t.klee-out %t.klee-out-tmp // RUN: %gentmp %t.klee-out-tmp // RUN: %klee --output-dir=%t.klee-out --run-in=%t.klee-out-tmp --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 2 2 @@ -11,8 +11,8 @@ // For this test really to work as intended it needs to be run in a // directory large enough to cause uclibc to do multiple getdents -// calls (otherwise uclibc will handle the seeks itself). We should -// create a bunch of files or something. +// calls (otherwise uclibc will handle the seeks itself). +// Therefore gentmp generates a directory with a specific amount of entries #include <assert.h> #include <stdio.h> @@ -29,7 +29,6 @@ int main(int argc, char **argv) { assert(de); strcpy(first, de->d_name); off_t pos = telldir(d); - printf("pos: %ld\n", telldir(d)); de = readdir(d); assert(de); strcpy(second, de->d_name); @@ -41,9 +40,10 @@ int main(int argc, char **argv) { assert(strcmp(de->d_name, second) == 0); // Go to end, then back to 2nd - while (de) + while (de) { de = readdir(d); - assert(!errno); + assert(!errno); + } seekdir(d, pos); assert(telldir(d) == pos); de = readdir(d); diff --git a/test/Runtime/POSIX/Ioctl.c b/test/Runtime/POSIX/Ioctl.c index e8220276..f1caaf77 100644 --- a/test/Runtime/POSIX/Ioctl.c +++ b/test/Runtime/POSIX/Ioctl.c @@ -5,6 +5,7 @@ #include <assert.h> #include <fcntl.h> #include <sys/stat.h> +#include <sys/ioctl.h> #include <termios.h> #include <asm/ioctls.h> #include <errno.h> diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index ec951609..44bc5407 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -698,6 +698,8 @@ static const char *modelledExternals[] = { "_assert", "__assert_fail", "__assert_rtn", + "__errno_location", + "__error", "calloc", "_exit", "exit", |