about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--include/klee/klee.h3
-rw-r--r--lib/Core/Executor.cpp52
-rw-r--r--lib/Core/Executor.h3
-rw-r--r--lib/Core/ExternalDispatcher.cpp19
-rw-r--r--lib/Core/ExternalDispatcher.h3
-rw-r--r--lib/Core/Memory.h1
-rw-r--r--lib/Core/SpecialFunctionHandler.cpp40
-rw-r--r--lib/Core/SpecialFunctionHandler.h1
-rw-r--r--runtime/POSIX/fd.c203
-rw-r--r--test/Runtime/POSIX/DirSeek.c12
-rw-r--r--test/Runtime/POSIX/Ioctl.c1
-rw-r--r--tools/klee/main.cpp2
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",