about summary refs log tree commit diff homepage
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/Intrinsic/Makefile20
-rw-r--r--runtime/Intrinsic/klee_div_zero_check.c15
-rw-r--r--runtime/Intrinsic/klee_int.c17
-rw-r--r--runtime/Intrinsic/klee_make_symbolic.c14
-rw-r--r--runtime/Intrinsic/klee_range.c33
-rw-r--r--runtime/Intrinsic/memcpy.c19
-rw-r--r--runtime/Intrinsic/memmove.c28
-rw-r--r--runtime/Intrinsic/mempcpy.c19
-rw-r--r--runtime/Intrinsic/memset.c17
-rwxr-xr-xruntime/Makefile26
-rw-r--r--runtime/POSIX/Makefile20
-rw-r--r--runtime/POSIX/fd.c1287
-rw-r--r--runtime/POSIX/fd.h90
-rw-r--r--runtime/POSIX/fd_32.c196
-rw-r--r--runtime/POSIX/fd_64.c90
-rw-r--r--runtime/POSIX/fd_init.c161
-rw-r--r--runtime/POSIX/illegal.c70
-rw-r--r--runtime/POSIX/klee_init_env.c181
-rw-r--r--runtime/POSIX/misc.c87
-rw-r--r--runtime/POSIX/selinux.c80
-rw-r--r--runtime/POSIX/stubs.c560
l---------runtime/POSIX/testing-dir/a1
l---------runtime/POSIX/testing-dir/b1
-rwxr-xr-xruntime/POSIX/testing-dir/c2
-rw-r--r--runtime/POSIX/testing-dir/d0
-rw-r--r--runtime/POSIX/testing-env27
-rw-r--r--runtime/Runtest/Makefile19
-rw-r--r--runtime/Runtest/intrinsics.c154
-rwxr-xr-xruntime/klee-libc/Makefile19
-rw-r--r--runtime/klee-libc/__cxa_atexit.c49
-rw-r--r--runtime/klee-libc/abort.c16
-rw-r--r--runtime/klee-libc/atexit.c16
-rw-r--r--runtime/klee-libc/atoi.c37
-rw-r--r--runtime/klee-libc/calloc.c46
-rw-r--r--runtime/klee-libc/htonl.c49
-rw-r--r--runtime/klee-libc/klee-choose.c20
-rw-r--r--runtime/klee-libc/memchr.c54
-rw-r--r--runtime/klee-libc/memcmp.c53
-rw-r--r--runtime/klee-libc/memcpy.c19
-rw-r--r--runtime/klee-libc/memmove.c28
-rw-r--r--runtime/klee-libc/mempcpy.c19
-rw-r--r--runtime/klee-libc/memset.c17
-rw-r--r--runtime/klee-libc/putchar.c17
-rw-r--r--runtime/klee-libc/stpcpy.c43
-rw-r--r--runtime/klee-libc/strcat.c47
-rw-r--r--runtime/klee-libc/strchr.c23
-rw-r--r--runtime/klee-libc/strcmp.c14
-rw-r--r--runtime/klee-libc/strcoll.c15
-rw-r--r--runtime/klee-libc/strcpy.c17
-rw-r--r--runtime/klee-libc/strlen.c17
-rw-r--r--runtime/klee-libc/strncmp.c49
-rw-r--r--runtime/klee-libc/strncpy.c58
-rw-r--r--runtime/klee-libc/strrchr.c21
-rw-r--r--runtime/klee-libc/strtol.c135
-rw-r--r--runtime/klee-libc/strtoul.c113
-rw-r--r--runtime/klee-libc/tolower.c14
-rw-r--r--runtime/klee-libc/toupper.c14
57 files changed, 4273 insertions, 0 deletions
diff --git a/runtime/Intrinsic/Makefile b/runtime/Intrinsic/Makefile
new file mode 100644
index 00000000..ce4a34ba
--- /dev/null
+++ b/runtime/Intrinsic/Makefile
@@ -0,0 +1,20 @@
+#===-- runtime/Intrinsic/Makefile --------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=intrinsic
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/Intrinsic/klee_div_zero_check.c b/runtime/Intrinsic/klee_div_zero_check.c
new file mode 100644
index 00000000..3fde1af5
--- /dev/null
+++ b/runtime/Intrinsic/klee_div_zero_check.c
@@ -0,0 +1,15 @@
+//===-- klee_div_zero_check.c ---------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <klee/klee.h>
+
+void klee_div_zero_check(long long z) {
+  if (z == 0)
+    klee_report_error(__FILE__, __LINE__, "divide by zero", "div.err");
+}
diff --git a/runtime/Intrinsic/klee_int.c b/runtime/Intrinsic/klee_int.c
new file mode 100644
index 00000000..88ec5026
--- /dev/null
+++ b/runtime/Intrinsic/klee_int.c
@@ -0,0 +1,17 @@
+//===-- klee_int.c --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <klee/klee.h>
+
+int klee_int(const char *name) {
+  int x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  return x;
+}
diff --git a/runtime/Intrinsic/klee_make_symbolic.c b/runtime/Intrinsic/klee_make_symbolic.c
new file mode 100644
index 00000000..b9dec2a7
--- /dev/null
+++ b/runtime/Intrinsic/klee_make_symbolic.c
@@ -0,0 +1,14 @@
+//===-- klee_make_symbolic.c ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <klee/klee.h>
+
+void klee_make_symbolic(void *addr, unsigned nbytes) {
+  klee_make_symbolic_name(addr, nbytes, "unnamed");
+}
diff --git a/runtime/Intrinsic/klee_range.c b/runtime/Intrinsic/klee_range.c
new file mode 100644
index 00000000..59d1a05e
--- /dev/null
+++ b/runtime/Intrinsic/klee_range.c
@@ -0,0 +1,33 @@
+//===-- klee_range.c ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <klee/klee.h>
+
+int klee_range(int start, int end, const char* name) {
+  int x;
+
+  assert(start < end);
+
+  if (start+1==end) {
+    return start;
+  } else {
+    klee_make_symbolic_name(&x, sizeof x, name); 
+
+    /* Make nicer constraint when simple... */
+    if (start==0) {
+      klee_assume((unsigned) x < (unsigned) end);
+    } else {
+      klee_assume(start <= x);
+      klee_assume(x < end);
+    }
+
+    return x;
+  }
+}
diff --git a/runtime/Intrinsic/memcpy.c b/runtime/Intrinsic/memcpy.c
new file mode 100644
index 00000000..14b98ce6
--- /dev/null
+++ b/runtime/Intrinsic/memcpy.c
@@ -0,0 +1,19 @@
+//===-- memcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return destaddr;
+}
diff --git a/runtime/Intrinsic/memmove.c b/runtime/Intrinsic/memmove.c
new file mode 100644
index 00000000..c6e1ada9
--- /dev/null
+++ b/runtime/Intrinsic/memmove.c
@@ -0,0 +1,28 @@
+//===-- memmove.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memmove(void *dst, const void *src, size_t count) {
+  char *a = dst;
+  const char *b = src;
+
+  if (src == dst)
+    return dst;
+
+  if (src>dst) {
+    while (count--) *a++ = *b++;
+  } else {
+    a+=count-1;
+    b+=count-1;
+    while (count--) *a-- = *b--;
+  }
+
+  return dst;
+}
diff --git a/runtime/Intrinsic/mempcpy.c b/runtime/Intrinsic/mempcpy.c
new file mode 100644
index 00000000..6327e748
--- /dev/null
+++ b/runtime/Intrinsic/mempcpy.c
@@ -0,0 +1,19 @@
+//===-- mempcpy.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *mempcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return dest;
+}
diff --git a/runtime/Intrinsic/memset.c b/runtime/Intrinsic/memset.c
new file mode 100644
index 00000000..ee9ecb87
--- /dev/null
+++ b/runtime/Intrinsic/memset.c
@@ -0,0 +1,17 @@
+//===-- memset.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memset(void * dst, int s, size_t count) {
+    char * a = dst;
+    while (count-- > 0)
+      *a++ = s;
+    return dst;
+}
diff --git a/runtime/Makefile b/runtime/Makefile
new file mode 100755
index 00000000..24824d08
--- /dev/null
+++ b/runtime/Makefile
@@ -0,0 +1,26 @@
+#===-- runtime/Makefile ------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+#
+# Relative path to the top of the source tree.
+#
+LEVEL=..
+
+#
+# List all of the subdirectories that we will compile.
+#
+PARALLEL_DIRS=Intrinsic klee-libc Runtest
+
+include $(LEVEL)/Makefile.config
+
+ifeq ($(ENABLE_POSIX_RUNTIME),1)
+PARALLEL_DIRS += POSIX
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/POSIX/Makefile b/runtime/POSIX/Makefile
new file mode 100644
index 00000000..9a42f5c0
--- /dev/null
+++ b/runtime/POSIX/Makefile
@@ -0,0 +1,20 @@
+#===-- runtime/POSIX/Makefile ------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeRuntimePOSIX
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/POSIX/fd.c b/runtime/POSIX/fd.c
new file mode 100644
index 00000000..367a8c4a
--- /dev/null
+++ b/runtime/POSIX/fd.c
@@ -0,0 +1,1287 @@
+//===-- fd.c --------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <termios.h>
+#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 is the pathname is symbolic */
+static exe_disk_file_t *__get_sym_file(const char *pathname) {
+  char c = pathname[0];
+  unsigned i;
+
+  if (c == 0 || pathname[1] != 0)
+    return NULL;
+
+  for (i=0; i<__exe_fs.n_sym_files; ++i) {
+    if (c == 'A' + (char) i) {
+      exe_disk_file_t *df = &__exe_fs.sym_files[i];
+      if (df->stat->st_ino == 0)
+        return NULL;
+      return df;
+    }
+  }
+  
+  return NULL;
+}
+
+static void *__concretize_ptr(const void *p);
+static size_t __concretize_size(size_t s);
+static const char *__concretize_string(const char *s);
+
+/* Returns pointer to the file entry for a valid fd */
+static exe_file_t *__get_file(int fd) {
+  if (fd>=0 && fd<MAX_FDS) {
+    exe_file_t *f = &__exe_env.fds[fd];
+    if (f->flags & eOpen)
+      return f;
+  }
+
+  return 0;
+}
+
+int access(const char *pathname, int mode) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  
+  if (dfile) {
+    /* 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;
+  } 
+}
+
+mode_t umask(mode_t mask) {  
+  mode_t r = __exe_env.umask;
+  __exe_env.umask = mask & 0777;
+  return r;
+}
+
+
+/* Returns 1 if the process has the access rights specified by 'flags'
+   to the file with stat 's'.  Returns 0 otherwise*/
+static int has_permission(int flags, struct stat64 *s) {
+  int write_access, read_access;
+  mode_t mode = s->st_mode;
+  
+  if (flags & O_RDONLY || flags & O_RDWR)
+    read_access = 1;
+  else read_access = 0;
+
+  if (flags & O_WRONLY || flags & O_RDWR)
+    write_access = 1;
+  else write_access = 0;
+
+  /* XXX: We don't worry about process uid and gid for now. 
+     We allow access if any user has access to the file. */
+#if 0
+  uid_t uid = s->st_uid;
+  uid_t euid = geteuid();
+  gid_t gid = s->st_gid;
+  gid_t egid = getegid();
+#endif  
+
+  if (read_access && ((mode & S_IRUSR) | (mode & S_IRGRP) | (mode & S_IROTH)))
+    return 0;
+
+  if (write_access && !((mode & S_IWUSR) | (mode & S_IWGRP) | (mode & S_IWOTH)))
+    return 0;
+
+  return 1;
+}
+
+
+int __fd_open(const char *pathname, int flags, mode_t mode) {
+  exe_disk_file_t *df;
+  exe_file_t *f;
+  int fd;
+
+  for (fd = 0; fd < MAX_FDS; ++fd)
+    if (!(__exe_env.fds[fd].flags & eOpen))
+      break;
+  if (fd == MAX_FDS) {
+    errno = EMFILE;
+    return -1;
+  }
+  
+  f = &__exe_env.fds[fd];
+
+  /* Should be the case if file was available, but just in case. */
+  memset(f, 0, sizeof *f);
+
+  df = __get_sym_file(pathname); 
+  if (df) {    
+    /* XXX Should check access against mode / stat / possible
+       deletion. */
+    f->dfile = df;
+    
+    if ((flags & O_CREAT) && (flags & O_EXCL)) {
+      errno = EEXIST;
+      return -1;
+    }
+    
+    if ((flags & O_TRUNC) && (flags & O_RDONLY)) {
+      /* The result of using O_TRUNC with O_RDONLY is undefined, so we
+	 return error */
+      fprintf(stderr, "Undefined call to open(): O_TRUNC | O_RDONLY\n");
+      errno = EACCES;
+      return -1;
+    }
+
+    if ((flags & O_EXCL) && !(flags & O_CREAT)) {
+      /* The result of using O_EXCL without O_CREAT is undefined, so
+	 we return error */
+      fprintf(stderr, "Undefined call to open(): O_EXCL w/o O_RDONLY\n");
+      errno = EACCES;
+      return -1;
+    }
+
+    if (!has_permission(flags, df->stat)) {
+	errno = EACCES;
+	return -1;
+    }
+    else
+      f->dfile->stat->st_mode = ((f->dfile->stat->st_mode & ~0777) |
+				 (mode & ~__exe_env.umask));
+  } else {    
+    int os_fd = syscall(__NR_open, __concretize_string(pathname), flags, mode);
+    if (os_fd == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+    f->fd = os_fd;
+  }
+  
+  f->flags = eOpen;
+  if ((flags & O_ACCMODE) == O_RDONLY) {
+    f->flags |= eReadable;
+  } else if ((flags & O_ACCMODE) == O_WRONLY) {
+    f->flags |= eWriteable;
+  } else { /* XXX What actually happens here if != O_RDWR. */
+    f->flags |= eReadable | eWriteable;
+  }
+  
+  return fd;
+}
+
+int close(int fd) {
+  static int n_calls = 0;
+  exe_file_t *f;
+  int r = 0;
+  
+  n_calls++;  
+
+  f = __get_file(fd);
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  } 
+
+  if (__exe_fs.max_failures && *__exe_fs.close_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+#if 0
+  if (!f->dfile) {
+    /* if a concrete fd */
+    r = syscall(__NR_close, f->fd);
+  }
+  else r = 0;
+#endif
+
+  memset(f, 0, sizeof *f);
+  
+  return r;
+}
+
+ssize_t read(int fd, void *buf, size_t count) {
+  static int n_calls = 0;
+  exe_file_t *f;
+
+  n_calls++;
+
+  if (count == 0) 
+    return 0;
+
+  if (buf == NULL) {
+    errno = EFAULT;
+    return -1;
+  }
+  
+  f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }  
+
+  if (__exe_fs.max_failures && *__exe_fs.read_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+  
+  if (!f->dfile) {
+    /* concrete file */
+    int r;
+    buf = __concretize_ptr(buf);
+    count = __concretize_size(count);
+    /* XXX In terms of looking for bugs we really should do this check
+       before concretization, at least once the routine has been fixed
+       to properly work with symbolics. */
+    klee_check_memory_access(buf, count);
+    if (f->fd == 0)
+      r = syscall(__NR_read, f->fd, buf, count);
+    else
+      r = syscall(__NR_pread64, f->fd, buf, count, (off64_t) f->off);
+
+    if (r == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+    
+    if (f->fd != 0)
+      f->off += r;
+    return r;
+  }
+  else {
+    assert(f->off >= 0);
+    if (f->dfile->size < f->off)
+      return 0;
+
+    /* symbolic file */
+    if (f->off + count > f->dfile->size) {
+      count = f->dfile->size - f->off;
+    }
+    
+    memcpy(buf, f->dfile->contents + f->off, count);
+    f->off += count;
+    
+    return count;
+  }
+}
+
+
+ssize_t write(int fd, const void *buf, size_t count) {
+  static int n_calls = 0;
+  exe_file_t *f;
+
+  n_calls++;
+
+  f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (__exe_fs.max_failures && *__exe_fs.write_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  if (!f->dfile) {
+    int r;
+
+    buf = __concretize_ptr(buf);
+    count = __concretize_size(count);
+    /* XXX In terms of looking for bugs we really should do this check
+       before concretization, at least once the routine has been fixed
+       to properly work with symbolics. */
+    klee_check_memory_access(buf, 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();
+      return -1;
+    }
+    
+    assert(r >= 0);
+    if (f->fd != 1 && f->fd != 2)
+      f->off += r;
+
+    return r;
+  }
+  else {
+    /* symbolic file */    
+    size_t actual_count = 0;
+    if (f->off + count <= f->dfile->size)
+      actual_count = count;
+    else {
+      if (__exe_env.save_all_writes)
+	assert(0);
+      else {
+	if (f->off < f->dfile->size)
+	  actual_count = f->dfile->size - f->off;	
+      }
+    }
+    
+    if (actual_count)
+      memcpy(f->dfile->contents + f->off, buf, actual_count);
+    
+    if (count != actual_count)
+      fprintf(stderr, "WARNING: write() ignores bytes.\n");
+
+    if (f->dfile == __exe_fs.sym_stdout)
+      __exe_fs.stdout_writes += actual_count;
+
+    f->off += count;
+    return count;
+  }
+}
+
+
+off64_t __fd_lseek(int fd, off64_t offset, int whence) {
+  off64_t new_off;
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (!f->dfile) {
+    /* We could always do SEEK_SET then whence, but this causes
+       troubles with directories since we play nasty tricks with the
+       offset, and the OS doesn't want us to randomly seek
+       directories. We could detect if it is a directory and correct
+       the offset, but really directories should only be SEEK_SET, so
+       this solves the problem. */
+    if (whence == SEEK_SET) {
+      new_off = syscall(__NR_lseek, f->fd, (int) offset, SEEK_SET);
+    } else {
+      new_off = syscall(__NR_lseek, f->fd, (int) f->off, SEEK_SET);
+
+      /* If we can't seek to start off, just return same error.
+         Probably ESPIPE. */
+      if (new_off != -1) {
+        assert(new_off == f->off);
+        new_off = syscall(__NR_lseek, f->fd, (int) offset, whence);
+      }
+    }
+
+    if (new_off == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+
+    f->off = new_off;
+    return new_off;
+  }
+  
+  switch (whence) {
+  case SEEK_SET: new_off = offset; break;
+  case SEEK_CUR: new_off = f->off + offset; break;
+  case SEEK_END: new_off = f->dfile->size + offset; break;
+  default: {
+    errno = EINVAL;
+    return (off64_t) -1;
+  }
+  }
+
+  if (new_off < 0) {
+    errno = EINVAL;
+    return (off64_t) -1;
+  }
+    
+  f->off = new_off;
+  return f->off;
+}
+
+int __fd_stat(const char *path, struct stat64 *buf) {  
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    memcpy(buf, dfile->stat, sizeof(*dfile->stat));
+    return 0;
+  } 
+
+  {
+    int r = syscall(__NR_stat64, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int __fd_lstat(const char *path, struct stat64 *buf) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    memcpy(buf, dfile->stat, sizeof(*dfile->stat));
+    return 0;
+  } 
+
+  {    
+    int r = syscall(__NR_lstat64, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int chdir(const char *path) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+
+  if (dfile) {
+    /* XXX incorrect */
+    klee_warning("symbolic file, ignoring (ENOENT)");
+    errno = ENOENT;
+    return -1;
+  }
+
+  {
+    int r = syscall(__NR_chdir, __concretize_string(path));
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fchdir(int fd) {
+  exe_file_t *f = __get_file(fd);
+  
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (f->dfile) {
+    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;
+  }
+}
+
+/* Sets mode and or errno and return appropriate result. */
+static int __df_chmod(exe_disk_file_t *df, mode_t mode) {
+  if (geteuid() == df->stat->st_uid) {
+    if (getgid() != df->stat->st_gid)
+      mode &= ~ S_ISGID;
+    df->stat->st_mode = ((df->stat->st_mode & ~07777) | 
+                         (mode & 07777));
+    return 0;
+  } else {
+    errno = EPERM;
+    return -1;
+  }
+}
+
+int chmod(const char *path, mode_t mode) {
+  static int n_calls = 0;
+
+  exe_disk_file_t *dfile = __get_sym_file(path);
+
+  n_calls++;
+  if (__exe_fs.max_failures && *__exe_fs.chmod_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  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;
+  }
+}
+
+int fchmod(int fd, mode_t mode) {
+  static int n_calls = 0;
+
+  exe_file_t *f = __get_file(fd);
+  
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  n_calls++;
+  if (__exe_fs.max_failures && *__exe_fs.fchmod_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  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;
+  }  
+}
+
+static int __df_chown(exe_disk_file_t *df, uid_t owner, gid_t group) {
+  klee_warning("symbolic file, ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int chown(const char *path, uid_t owner, gid_t group) {
+  exe_disk_file_t *df = __get_sym_file(path);
+
+  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;
+  }
+}
+
+int fchown(int fd, uid_t owner, gid_t group) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  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;
+  }
+}
+
+int lchown(const char *path, uid_t owner, gid_t group) {
+  /* XXX Ignores 'l' part */
+  exe_disk_file_t *df = __get_sym_file(path);
+
+  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;
+  }
+}
+
+int __fd_fstat(int fd, struct stat64 *buf) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (!f->dfile) {
+    int r = syscall(__NR_fstat64, f->fd, buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+  
+  memcpy(buf, f->dfile->stat, sizeof(*f->dfile->stat));
+  return 0;
+}
+
+int __fd_ftruncate(int fd, off64_t length) {
+  static int n_calls = 0;
+  exe_file_t *f = __get_file(fd);
+
+  n_calls++;
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (__exe_fs.max_failures && *__exe_fs.ftruncate_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (EIO)");
+    errno = EIO;
+    return -1;
+  } else {
+    int r = syscall(__NR_ftruncate64, f->fd, length);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }  
+}
+
+int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (EINVAL)");
+    errno = EINVAL;
+    return -1;
+  } else {
+    if ((unsigned) f->off < 4096u) {
+      /* Return our dirents */
+      unsigned i, pad, bytes=0;
+
+      /* What happens for bad offsets? */
+      i = f->off / sizeof(*dirp);
+      if ((i * sizeof(*dirp) != f->off) ||
+          i > __exe_fs.n_sym_files) {
+        errno = EINVAL;
+        return -1;
+      } 
+      for (; i<__exe_fs.n_sym_files; ++i) {
+        exe_disk_file_t *df = &__exe_fs.sym_files[i];
+        dirp->d_ino = df->stat->st_ino;
+        dirp->d_reclen = sizeof(*dirp);
+        dirp->d_type = IFTODT(df->stat->st_mode);
+        dirp->d_name[0] = 'A' + i;
+        dirp->d_name[1] = '\0';
+        dirp->d_off = (i+1) * sizeof(*dirp);
+        bytes += dirp->d_reclen;
+        ++dirp;
+      }
+      
+      /* Fake jump to OS records by a "deleted" file. */
+      pad = count>=4096 ? 4096 : count;
+      dirp->d_ino = 0;
+      dirp->d_reclen = pad - bytes;
+      dirp->d_type = DT_UNKNOWN;
+      dirp->d_name[0] = '\0';
+      dirp->d_off = 4096;
+      bytes += dirp->d_reclen;
+      f->off = pad;
+      return bytes;
+    } else {
+      unsigned os_pos = f->off - 4096;
+      int res, s;
+
+      /* For reasons which I really don't understand, if I don't
+         memset this then sometimes the kernel returns d_ino==0 for
+         some valid entries? Am I crazy? Can writeback possibly be
+         failing? 
+      
+         Even more bizarre, interchanging the memset and the seek also
+         case strange behavior. Really should be debugged properly. */
+      memset(dirp, 0, count);
+      s = syscall(__NR_lseek, f->fd, (int) 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 {
+        int pos = 0;
+
+        f->off = syscall(__NR_lseek, f->fd, 0, SEEK_CUR) + 4096;
+
+        /* Patch offsets */
+        
+        while (pos < res) {
+          struct dirent64 *dp = (struct dirent64*) ((char*) dirp + pos);
+          dp->d_off += 4096;
+          pos += dp->d_reclen;
+        }
+      }
+      return res;
+    }
+  }
+}
+
+int ioctl(int fd, unsigned long request, ...) {
+  exe_file_t *f = __get_file(fd);
+  va_list ap;
+  void *buf;
+
+#if 0
+  printf("In ioctl(%d, ...)\n", fd);
+#endif
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  va_start(ap, request);
+  buf = va_arg(ap, void*);
+  va_end(ap);
+  
+  if (f->dfile) {
+    struct stat *stat = (struct stat*) f->dfile->stat;
+
+    switch (request) {
+    case TCGETS: {      
+      struct termios *ts = buf;
+
+      klee_warning_once("(TCGETS) symbolic file, incomplete model");
+
+      /* XXX need more data, this is ok but still not good enough */
+      if (S_ISCHR(stat->st_mode)) {
+        /* Just copied from my system, munged to match what fields
+           uclibc thinks are there. */
+        ts->c_iflag = 27906;
+        ts->c_oflag = 5;
+        ts->c_cflag = 1215;
+        ts->c_lflag = 35287;
+        ts->c_line = 0;
+        ts->c_cc[0] = '\x03';
+        ts->c_cc[1] = '\x1c';
+        ts->c_cc[2] = '\x7f';
+        ts->c_cc[3] = '\x15';
+        ts->c_cc[4] = '\x04';
+        ts->c_cc[5] = '\x00';
+        ts->c_cc[6] = '\x01';
+        ts->c_cc[7] = '\xff';
+        ts->c_cc[8] = '\x11';
+        ts->c_cc[9] = '\x13';
+        ts->c_cc[10] = '\x1a';
+        ts->c_cc[11] = '\xff';
+        ts->c_cc[12] = '\x12';
+        ts->c_cc[13] = '\x0f';
+        ts->c_cc[14] = '\x17';
+        ts->c_cc[15] = '\x16';
+        ts->c_cc[16] = '\xff';
+        ts->c_cc[17] = '\x0';
+        ts->c_cc[18] = '\x0';
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETS: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETS) symbolic file, silently ignoring");
+      if (S_ISCHR(stat->st_mode)) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETSW: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETSW) symbolic file, silently ignoring");
+      if (fd==0) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETSF: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETSF) symbolic file, silently ignoring");
+      if (S_ISCHR(stat->st_mode)) {        
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TIOCGWINSZ: {
+      struct winsize *ws = buf;
+      ws->ws_row = 24;
+      ws->ws_col = 80;
+      klee_warning_once("(TIOCGWINSZ) symbolic file, incomplete model");
+      if (S_ISCHR(stat->st_mode)) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TIOCSWINSZ: {
+      /* const struct winsize *ws = buf; */
+      klee_warning_once("(TIOCSWINSZ) symbolic file, ignoring (EINVAL)");
+      if (S_ISCHR(stat->st_mode)) {
+        errno = EINVAL;
+        return -1;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case FIONREAD: {
+      int *res = buf;
+      klee_warning_once("(FIONREAD) symbolic file, incomplete model");
+      if (S_ISCHR(stat->st_mode)) {
+        if (f->off < f->dfile->size) {
+          *res = f->dfile->size - f->off;
+        } else {
+          *res = 0;
+        }
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case MTIOCGET: {
+      klee_warning("(MTIOCGET) symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+    default:
+      klee_warning("symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_ioctl, f->fd, request, buf );
+    if (r == -1) 
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fcntl(int fd, int cmd, ...) {
+  exe_file_t *f = __get_file(fd);
+  va_list ap;
+  unsigned arg; /* 32 bit assumption (int/ptr) */
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (cmd==F_GETFD || cmd==F_GETFL || cmd==F_GETOWN || cmd==F_GETSIG ||
+      cmd==F_GETLEASE || cmd==F_NOTIFY) {
+    arg = 0;
+  } else {
+    va_start(ap, cmd);
+    arg = va_arg(ap, int);
+    va_end(ap);
+  }
+
+  if (f->dfile) {
+    switch(cmd) {
+    case F_GETFD: {
+      int flags = 0;
+      if (f->flags & eCloseOnExec)
+        flags |= FD_CLOEXEC;
+      return flags;
+    } 
+    case F_SETFD: {
+      f->flags &= ~eCloseOnExec;
+      if (arg & FD_CLOEXEC)
+        f->flags |= eCloseOnExec;
+      return 0;
+    }
+    case F_GETFL: {
+      /* XXX (CrC): This should return the status flags: O_APPEND,
+	 O_ASYNC, O_DIRECT, O_NOATIME, O_NONBLOCK.  As of now, we
+	 discard these flags during open().  We should save them and
+	 return them here.  These same flags can be set by F_SETFL,
+	 which we could also handle properly. 
+      */
+      return 0;
+    }
+    default:
+      klee_warning("symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_fcntl, f->fd, cmd, arg );
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int __fd_statfs(const char *path, struct statfs *buf) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    /* XXX incorrect */
+    klee_warning("symbolic file, ignoring (ENOENT)");
+    errno = ENOENT;
+    return -1;
+  }
+
+  {
+    int r = syscall(__NR_statfs, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fstatfs(int fd, struct statfs *buf) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    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;
+  }
+}
+
+int fsync(int fd) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    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;
+  }
+}
+
+int dup2(int oldfd, int newfd) {
+  exe_file_t *f = __get_file(oldfd);
+
+  if (!f || !(newfd>=0 && newfd<MAX_FDS)) {
+    errno = EBADF;
+    return -1;
+  } else {
+    exe_file_t *f2 = &__exe_env.fds[newfd];
+    if (f2->flags & eOpen) close(newfd);
+
+    /* XXX Incorrect, really we need another data structure for open
+       files */
+    *f2 = *f;
+
+    f2->flags &= ~eCloseOnExec;
+      
+    /* I'm not sure it is wise, but we can get away with not dup'ng
+       the OS fd, since actually that will in many cases effect the
+       sharing of the open file (and the process should never have
+       access to it). */
+
+    return newfd;
+  }
+}
+
+int dup(int oldfd) {
+  exe_file_t *f = __get_file(oldfd);
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  } else {
+    int fd;
+    for (fd = 0; fd < MAX_FDS; ++fd)
+      if (!(__exe_env.fds[fd].flags & eOpen))
+        break;
+    if (fd == MAX_FDS) {
+      errno = EMFILE;
+      return -1;
+    } else {
+      return dup2(oldfd, fd);
+    }
+  }
+}
+
+int rmdir(const char *pathname) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  if (dfile) {
+    /* XXX check access */ 
+    if (S_ISDIR(dfile->stat->st_mode)) {
+      dfile->stat->st_ino = 0;
+      return 0;
+    } else {
+      errno = ENOTDIR;
+      return -1;
+    }
+  }
+
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int unlink(const char *pathname) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  if (dfile) {
+    /* XXX check access */ 
+    if (S_ISREG(dfile->stat->st_mode)) {
+      dfile->stat->st_ino = 0;
+      return 0;
+    } else if (S_ISDIR(dfile->stat->st_mode)) {
+      errno = EISDIR;
+      return -1;
+    } else {
+      errno = EPERM;
+      return -1;
+    }
+  }
+
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+ssize_t readlink(const char *path, char *buf, size_t bufsize) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    /* XXX We need to get the sym file name really, but since we don't
+       handle paths anyway... */
+    if (S_ISLNK(dfile->stat->st_mode)) {
+      buf[0] = path[0];
+      if (bufsize>1) buf[1] = '.';
+      if (bufsize>2) buf[2] = 'l';
+      if (bufsize>3) buf[3] = 'n';
+      if (bufsize>4) buf[4] = 'k';
+      return (bufsize>5) ? 5 : bufsize;
+    } else {
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_readlink, path, buf, bufsize);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+#undef FD_SET
+#undef FD_CLR
+#undef FD_ISSET
+#undef FD_ZERO
+#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)	memset((char *)(p), '\0', sizeof(*(p)))
+int select(int nfds, fd_set *read, fd_set *write,
+           fd_set *except, struct timeval *timeout) {
+  fd_set in_read, in_write, in_except, os_read, os_write, os_except;
+  int i, count = 0, os_nfds = 0;
+
+  if (read) {
+    in_read = *read;
+    FD_ZERO(read);
+  } else {
+    FD_ZERO(&in_read);
+  }
+
+  if (write) {
+    in_write = *write;
+    FD_ZERO(write);
+  } else {
+    FD_ZERO(&in_write);
+  }
+   
+  if (except) {
+    in_except = *except;
+    FD_ZERO(except);
+  } else {
+    FD_ZERO(&in_except);
+  }
+
+  FD_ZERO(&os_read);
+  FD_ZERO(&os_write);
+  FD_ZERO(&os_except);
+
+  /* Check for symbolic stuff */
+  for (i=0; i<nfds; i++) {    
+    if (FD_ISSET(i, &in_read) || FD_ISSET(i, &in_write) || FD_ISSET(i, &in_except)) {
+      exe_file_t *f = __get_file(i);
+      if (!f) {
+        errno = EBADF;
+        return -1;
+      } else if (f->dfile) {
+        /* Operations on this fd will never block... */
+        if (FD_ISSET(i, &in_read)) FD_SET(i, read);
+        if (FD_ISSET(i, &in_write)) FD_SET(i, write);
+        if (FD_ISSET(i, &in_except)) FD_SET(i, except);
+        ++count;
+      } else {
+        if (FD_ISSET(i, &in_read)) FD_SET(f->fd, &os_read);
+        if (FD_ISSET(i, &in_write)) FD_SET(f->fd, &os_write);
+        if (FD_ISSET(i, &in_except)) FD_SET(f->fd, &os_except);
+        if (f->fd >= os_nfds) os_nfds = f->fd + 1;
+      }
+    }
+  }
+
+  if (os_nfds > 0) {
+    /* Never allow blocking select. This is broken but what else can
+       we do. */
+    struct timeval tv = { 0, 0 };    
+    int r = syscall(__NR_select, os_nfds, 
+                    &os_read, &os_write, &os_except, &tv);
+    
+    if (r == -1) {
+      /* If no symbolic results, return error. Otherwise we will
+         silently ignore the OS error. */
+      if (!count) {
+        errno = klee_get_errno();
+        return -1;
+      }
+    } else {
+      count += r;
+
+      /* Translate resulting sets back */
+      for (i=0; i<nfds; i++) {
+        exe_file_t *f = __get_file(i);
+        if (f && !f->dfile) {
+          if (read && FD_ISSET(f->fd, &os_read)) FD_SET(i, read);
+          if (write && FD_ISSET(f->fd, &os_write)) FD_SET(i, write);
+          if (except && FD_ISSET(f->fd, &os_except)) FD_SET(i, except);
+        }
+      }
+    }
+  }
+
+  return count;
+}
+
+/*** Library functions ***/
+
+char *getcwd(char *buf, size_t size) {
+  static int n_calls = 0;
+  int r;
+
+  n_calls++;
+
+  if (__exe_fs.max_failures && *__exe_fs.getcwd_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = ERANGE;
+    return NULL;
+  }
+
+  if (!buf) {
+    if (!size)
+      size = 1024;
+    buf = malloc(size);
+  }
+  
+  buf = __concretize_ptr(buf);
+  size = __concretize_size(size);
+  /* XXX In terms of looking for bugs we really should do this check
+     before concretization, at least once the routine has been fixed
+     to properly work with symbolics. */
+  klee_check_memory_access(buf, size);
+  r = syscall(__NR_getcwd, buf, size);
+  if (r == -1) {
+    errno = klee_get_errno();
+    return NULL;
+  }
+    
+  return buf;
+}
+
+/*** Helper functions ***/
+
+static void *__concretize_ptr(const void *p) {
+  /* XXX 32-bit assumption */
+  char *pc = (char*) klee_get_value((unsigned) (long) p);
+  klee_assume(pc == p);
+  return pc;
+}
+
+static size_t __concretize_size(size_t s) {
+  size_t sc = klee_get_value(s);
+  klee_assume(sc == s);
+  return sc;
+}
+
+static const char *__concretize_string(const char *s) {
+  char *sc = __concretize_ptr(s);
+  unsigned i;
+
+  for (i=0; ; ++i) {
+    char c = *sc;
+    if (!(i&(i-1))) {
+      if (!c) {
+        *sc++ = 0;
+        break;
+      } else if (c=='/') {
+        *sc++ = '/';
+      } 
+    } else {
+      char cc = (char) klee_get_value(c);
+      klee_assume(cc == c);
+      *sc++ = cc;
+      if (!cc) break;
+    }
+  }
+
+  return s;
+}
+
+
+
+/* Trivial model:
+   if path is "/" (basically no change) accept, otherwise reject
+*/
+int chroot(const char *path) {
+  if (path[0] == '\0') {
+    errno = ENOENT;
+    return -1;
+  }
+    
+  if (path[0] == '/' && path[1] == '\0') {
+    return 0;
+  }
+  
+  klee_warning("ignoring (ENOENT)");
+  errno = ENOENT;
+  return -1;
+}
diff --git a/runtime/POSIX/fd.h b/runtime/POSIX/fd.h
new file mode 100644
index 00000000..f2780143
--- /dev/null
+++ b/runtime/POSIX/fd.h
@@ -0,0 +1,90 @@
+//===-- fd.h ---------------------------------------------------*- C++ -*--===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __EXE_FD__
+#define __EXE_FD__
+
+#ifndef _LARGEFILE64_SOURCE
+#error "_LARGEFILE64_SOURCE should be defined"
+#endif
+#include <sys/types.h>
+#include <sys/statfs.h>
+#include <dirent.h>
+
+typedef struct {  
+  unsigned size;  /* in bytes */
+  char* contents;
+  struct stat64* stat;
+} exe_disk_file_t;
+
+typedef enum {
+  eOpen         = (1 << 0),
+  eCloseOnExec  = (1 << 1),
+  eReadable     = (1 << 2),
+  eWriteable    = (1 << 3)
+} exe_file_flag_t;
+
+typedef struct {      
+  int fd;                   /* actual fd if not symbolic */
+  unsigned flags;           /* set of exe_file_flag_t values. fields
+                               are only defined when flags at least
+                               has eOpen. */
+  off64_t off;              /* offset */
+  exe_disk_file_t* dfile;   /* ptr to file on disk, if symbolic */
+} exe_file_t;
+
+typedef struct {
+  unsigned n_sym_files; /* number of symbolic input files, excluding stdin */
+  exe_disk_file_t *sym_stdin, *sym_stdout;
+  unsigned stdout_writes; /* how many chars were written to stdout */
+  exe_disk_file_t *sym_files;
+  /* --- */
+  /* the maximum number of failures on one path; gets decremented after each failure */
+  unsigned max_failures; 
+
+  /* Which read, write etc. call should fail */
+  int *read_fail, *write_fail, *close_fail, *ftruncate_fail, *getcwd_fail;
+  int *chmod_fail, *fchmod_fail;
+} exe_file_system_t;
+
+#define MAX_FDS 32
+
+/* Note, if you change this structure be sure to update the
+   initialization code if necessary. New fields should almost
+   certainly be at the end. */
+typedef struct {
+  exe_file_t fds[MAX_FDS];
+  mode_t umask; /* process umask */
+  unsigned version;
+  /* If set, writes execute as expected.  Otherwise, writes extending
+     the file size only change the contents up to the initial
+     size. The file offset is always incremented correctly. */
+  int save_all_writes; 
+} exe_sym_env_t;
+
+extern exe_file_system_t __exe_fs;
+extern exe_sym_env_t __exe_env;
+
+void klee_init_fds(unsigned n_files, unsigned file_length, 
+		   int sym_stdout_flag, int do_all_writes_flag, 
+		   unsigned max_failures);
+void klee_init_env(int *argcPtr, char ***argvPtr);
+
+/* *** */
+
+int __fd_open(const char *pathname, int flags, mode_t mode);
+off64_t __fd_lseek(int fd, off64_t offset, int whence);
+int __fd_stat(const char *path, struct stat64 *buf);
+int __fd_lstat(const char *path, struct stat64 *buf);
+int __fd_fstat(int fd, struct stat64 *buf);
+int __fd_ftruncate(int fd, off64_t length);
+int __fd_statfs(const char *path, struct statfs *buf);
+int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count);
+
+#endif /* __EXE_FD__ */
diff --git a/runtime/POSIX/fd_32.c b/runtime/POSIX/fd_32.c
new file mode 100644
index 00000000..4eea1805
--- /dev/null
+++ b/runtime/POSIX/fd_32.c
@@ -0,0 +1,196 @@
+//===-- fd_32.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/vfs.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/***/
+
+static void __stat64_to_stat(struct stat64 *a, struct stat *b) {
+  b->st_dev = a->st_dev;
+  b->st_ino = a->st_ino;
+  b->st_mode = a->st_mode;
+  b->st_nlink = a->st_nlink;
+  b->st_uid = a->st_uid;
+  b->st_gid = a->st_gid;
+  b->st_rdev = a->st_rdev;
+  b->st_size = a->st_size;
+  b->st_atime = a->st_atime;
+  b->st_mtime = a->st_mtime;
+  b->st_ctime = a->st_ctime;
+  b->st_blksize = a->st_blksize;
+  b->st_blocks = a->st_blocks;
+}
+
+/***/
+
+int open(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off_t lseek(int fd, off_t off, int whence) {
+  return (off_t) __fd_lseek(fd, off, whence);
+}
+
+int __xstat(int vers, const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_stat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int stat(const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_stat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int __lxstat(int vers, const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_lstat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int lstat(const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_lstat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int __fxstat(int vers, int fd, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_fstat(fd, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int fstat(int fd, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_fstat(fd, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int ftruncate(int fd, off_t length) {
+  return __fd_ftruncate(fd, length);
+}
+
+int statfs(const char *path, struct statfs *buf32) {
+#if 0
+    struct statfs64 buf;
+
+    if (__fd_statfs(path, &buf) < 0)
+	return -1;
+
+    buf32->f_type = buf.f_type;
+    buf32->f_bsize = buf.f_bsize;
+    buf32->f_blocks = buf.f_blocks;
+    buf32->f_bfree = buf.f_bfree;
+    buf32->f_bavail = buf.f_bavail;
+    buf32->f_files = buf.f_files;
+    buf32->f_ffree = buf.f_ffree;
+    buf32->f_fsid = buf.f_fsid;
+    buf32->f_namelen = buf.f_namelen;
+
+    return 0;
+#else
+    return __fd_statfs(path, buf32);
+#endif
+}
+
+/* Based on uclibc version. We use getdents64 and then rewrite the
+   results over themselves, as dirent32s. */
+ssize_t getdents(int fd, struct dirent *dirp, size_t nbytes) {
+  struct dirent64 *dp64 = (struct dirent64*) dirp;
+  ssize_t res = __fd_getdents(fd, dp64, nbytes);
+
+  if (res>0) {
+    struct dirent64 *end = (struct dirent64*) ((char*) dp64 + res);
+    while (dp64 < end) {
+      struct dirent *dp = (struct dirent *) dp64;
+      unsigned name_len = (dp64->d_reclen - 
+                           (unsigned) &((struct dirent64*) 0)->d_name);
+      dp->d_ino = dp64->d_ino;
+      dp->d_off = dp64->d_off;
+      dp->d_reclen = dp64->d_reclen;
+      dp->d_type = dp64->d_type;
+      memmove(dp->d_name, dp64->d_name, name_len);
+      dp64 = (struct dirent64*) ((char*) dp64 + dp->d_reclen);
+    }
+  }
+
+  return res;
+}
+int __getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
+     __attribute__((alias("getdents")));
+
+/* Forward to 64 versions (uclibc expects versions w/o asm specifier) */
+
+int open64(const char *pathname, int flags, ...) __attribute__((weak));
+int open64(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off64_t lseek64(int fd, off64_t off, int whence) __attribute__((weak));
+off64_t lseek64(int fd, off64_t off, int whence) {
+  return __fd_lseek(fd, off, whence);
+}
+
+int stat64(const char *path, struct stat64 *buf) __attribute__((weak));
+int stat64(const char *path, struct stat64 *buf) {
+  return __fd_stat(path, buf);
+}
+
+int lstat64(const char *path, struct stat64 *buf) __attribute__((weak));
+int lstat64(const char *path, struct stat64 *buf) {
+  return __fd_lstat(path, buf);
+}
+
+int fstat64(int fd, struct stat64 *buf) __attribute__((weak));
+int fstat64(int fd, struct stat64 *buf) {
+  return __fd_fstat(fd, buf);
+}
diff --git a/runtime/POSIX/fd_64.c b/runtime/POSIX/fd_64.c
new file mode 100644
index 00000000..d0710caf
--- /dev/null
+++ b/runtime/POSIX/fd_64.c
@@ -0,0 +1,90 @@
+//===-- fd_64.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <termios.h>
+#include <sys/select.h>
+#include <klee/klee.h>
+
+/*** Forward to actual implementations ***/
+
+int open(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+  
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off64_t lseek(int fd, off64_t offset, int whence) {
+  return __fd_lseek(fd, offset, whence);
+}
+
+int __xstat(int vers, const char *path, struct stat *buf) {
+  return __fd_stat(path, (struct stat64*) buf);
+}
+
+int stat(const char *path, struct stat *buf) {
+  return __fd_stat(path, (struct stat64*) buf);
+}
+
+int __lxstat(int vers, const char *path, struct stat *buf) {
+  return __fd_lstat(path, (struct stat64*) buf);
+}
+
+int lstat(const char *path, struct stat *buf) {
+  return __fd_lstat(path, (struct stat64*) buf);
+}
+
+int __fxstat(int vers, int fd, struct stat *buf) {
+  return __fd_fstat(fd, (struct stat64*) buf);
+}
+
+int fstat(int fd, struct stat *buf) {
+  return __fd_fstat(fd, (struct stat64*) buf);
+}
+
+int ftruncate64(int fd, off64_t length) {
+  return __fd_ftruncate(fd, length);
+}
+
+int statfs(const char *path, struct statfs *buf) __attribute__((weak));
+int statfs(const char *path, struct statfs *buf) {
+  return __fd_statfs(path, buf);
+}
+
+int getdents64(unsigned int fd, struct dirent *dirp, unsigned int count) {
+  return __fd_getdents(fd, (struct dirent64*) dirp, count);
+}
+int __getdents64(unsigned int fd, struct dirent *dirp, unsigned int count)
+     __attribute__((alias("getdents64")));
diff --git a/runtime/POSIX/fd_init.c b/runtime/POSIX/fd_init.c
new file mode 100644
index 00000000..61e49893
--- /dev/null
+++ b/runtime/POSIX/fd_init.c
@@ -0,0 +1,161 @@
+//===-- fd_init.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+#include "fd.h"
+#include <klee/klee.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+
+exe_file_system_t __exe_fs;
+
+/* NOTE: It is important that these are statically initialized
+   correctly, since things that run before main may hit them given the
+   current way things are linked. */
+
+/* XXX Technically these flags are initialized w.o.r. to the
+   environment we are actually running in. We could patch them in
+   klee_init_fds, but we still have the problem that uclibc calls
+   prior to main will get the wrong data. Not such a big deal since we
+   mostly care about sym case anyway. */
+
+
+exe_sym_env_t __exe_env = { 
+  {{ 0, eOpen | eReadable, 0, 0}, 
+   { 1, eOpen | eWriteable, 0, 0}, 
+   { 2, eOpen | eWriteable, 0, 0}},
+  022,
+  0,
+  0
+};
+
+static void __create_new_dfile(exe_disk_file_t *dfile, unsigned size, 
+                               const char *name, struct stat64 *defaults) {
+  struct stat64 *s = malloc(sizeof(*s));
+  const char *sp;
+  char sname[64];
+  for (sp=name; *sp; ++sp)
+    sname[sp-name] = *sp;
+  memcpy(&sname[sp-name], "-stat", 6);
+
+  assert(size);
+
+  dfile->size = size;
+  dfile->contents = malloc(dfile->size);
+  klee_make_symbolic_name(dfile->contents, dfile->size, name);
+  
+  klee_make_symbolic_name(s, sizeof(*s), sname);
+
+  /* For broken tests */
+  if (!klee_is_symbolic(s->st_ino) && 
+      (s->st_ino & 0x7FFFFFFF) == 0)
+    s->st_ino = defaults->st_ino;
+  
+  /* Important since we copy this out through getdents, and readdir
+     will otherwise skip this entry. For same reason need to make sure
+     it fits in low bits. */
+  klee_assume((s->st_ino & 0x7FFFFFFF) != 0);
+
+  /* uclibc opendir uses this as its buffer size, try to keep
+     reasonable. */
+  klee_assume((s->st_blksize & ~0xFFFF) == 0);
+
+  klee_prefer_cex(s, !(s->st_mode & ~(S_IFMT | 0777)));
+  klee_prefer_cex(s, s->st_dev == defaults->st_dev);
+  klee_prefer_cex(s, s->st_rdev == defaults->st_rdev);
+  klee_prefer_cex(s, (s->st_mode&0700) == 0600);
+  klee_prefer_cex(s, (s->st_mode&0070) == 0020);
+  klee_prefer_cex(s, (s->st_mode&0007) == 0002);
+  klee_prefer_cex(s, (s->st_mode&S_IFMT) == S_IFREG);
+  klee_prefer_cex(s, s->st_nlink == 1);
+  klee_prefer_cex(s, s->st_uid == defaults->st_uid);
+  klee_prefer_cex(s, s->st_gid == defaults->st_gid);
+  klee_prefer_cex(s, s->st_blksize == 4096);
+  klee_prefer_cex(s, s->st_atime == defaults->st_atime);
+  klee_prefer_cex(s, s->st_mtime == defaults->st_mtime);
+  klee_prefer_cex(s, s->st_ctime == defaults->st_ctime);
+
+  s->st_size = dfile->size;
+  s->st_blocks = 8;
+  dfile->stat = s;
+}
+
+static unsigned __sym_uint32(const char *name) {
+  unsigned x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  return x;
+}
+
+/* n_files: number of symbolic input files, excluding stdin
+   file_length: size in bytes of each symbolic file, including stdin
+   sym_stdout_flag: 1 if stdout should be symbolic, 0 otherwise
+   save_all_writes_flag: 1 if all writes are executed as expected, 0 if 
+                         writes past the initial file size are discarded 
+			 (file offset is always incremented)
+   max_failures: maximum number of system call failures */
+void klee_init_fds(unsigned n_files, unsigned file_length, 
+		   int sym_stdout_flag, int save_all_writes_flag,
+		   unsigned max_failures) {
+  unsigned k;
+  char name[7] = "?-data";
+  struct stat64 s;
+
+  stat64(".", &s);
+
+  __exe_fs.n_sym_files = n_files;
+  __exe_fs.sym_files = malloc(sizeof(*__exe_fs.sym_files) * n_files);
+  for (k=0; k < n_files; k++) {
+    name[0] = 'A' + k;
+    __create_new_dfile(&__exe_fs.sym_files[k], file_length, name, &s);
+  }
+  
+  /* setting symbolic stdin */
+  if (file_length) {
+    __exe_fs.sym_stdin = malloc(sizeof(*__exe_fs.sym_stdin));
+    __create_new_dfile(__exe_fs.sym_stdin, file_length, "stdin", &s);
+    __exe_env.fds[0].dfile = __exe_fs.sym_stdin;
+  }
+  else __exe_fs.sym_stdin = NULL;
+
+  __exe_fs.max_failures = max_failures;
+  if (__exe_fs.max_failures) {
+    __exe_fs.read_fail = malloc(sizeof(*__exe_fs.read_fail));
+    __exe_fs.write_fail = malloc(sizeof(*__exe_fs.write_fail));
+    __exe_fs.close_fail = malloc(sizeof(*__exe_fs.close_fail));
+    __exe_fs.ftruncate_fail = malloc(sizeof(*__exe_fs.ftruncate_fail));
+    __exe_fs.getcwd_fail = malloc(sizeof(*__exe_fs.getcwd_fail));
+
+    klee_make_symbolic_name(__exe_fs.read_fail, sizeof(*__exe_fs.read_fail), "read_fail");
+    klee_make_symbolic_name(__exe_fs.write_fail, sizeof(*__exe_fs.write_fail), "write_fail");
+    klee_make_symbolic_name(__exe_fs.close_fail, sizeof(*__exe_fs.close_fail), "close_fail");
+    klee_make_symbolic_name(__exe_fs.ftruncate_fail, sizeof(*__exe_fs.ftruncate_fail), "ftruncate_fail");
+    klee_make_symbolic_name(__exe_fs.getcwd_fail, sizeof(*__exe_fs.getcwd_fail), "getcwd_fail");
+  }
+
+  /* setting symbolic stdout */
+  if (sym_stdout_flag) {
+    __exe_fs.sym_stdout = malloc(sizeof(*__exe_fs.sym_stdout));
+    __create_new_dfile(__exe_fs.sym_stdout, 1024, "stdout", &s);
+    __exe_env.fds[1].dfile = __exe_fs.sym_stdout;
+    __exe_fs.stdout_writes = 0;
+  }
+  else __exe_fs.sym_stdout = NULL;
+  
+  __exe_env.save_all_writes = save_all_writes_flag;
+  __exe_env.version = __sym_uint32("model_version");
+  klee_assume(__exe_env.version == 1);
+}
diff --git a/runtime/POSIX/illegal.c b/runtime/POSIX/illegal.c
new file mode 100644
index 00000000..469ea623
--- /dev/null
+++ b/runtime/POSIX/illegal.c
@@ -0,0 +1,70 @@
+//===-- illegal.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/types.h>
+
+#include <klee/klee.h>
+
+void klee_warning(const char*);
+void klee_warning_once(const char*);
+
+int kill(pid_t pid, int sig) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int _setjmp (struct __jmp_buf_tag __env[1]) __attribute__((weak));
+int _setjmp (struct __jmp_buf_tag __env[1]) {
+  klee_warning_once("ignoring");
+  return 0;
+}
+
+void longjmp(jmp_buf env, int val) {
+  klee_report_error(__FILE__, __LINE__, "longjmp unsupported", "xxx.err");
+}
+
+/* Macro so function name from klee_warning comes out correct. */
+#define __bad_exec() \
+  (klee_warning("ignoring (EACCES)"),\
+   errno = EACCES,\
+   -1)
+
+/* This need to be weak because uclibc wants to define them as well,
+   but we will want to make sure a definition is around in case we
+   don't link with it. */
+
+int execl(const char *path, const char *arg, ...) __attribute__((weak));
+int execlp(const char *file, const char *arg, ...) __attribute__((weak));
+int execle(const char *path, const char *arg, ...) __attribute__((weak));
+int execv(const char *path, char *const argv[]) __attribute__((weak));
+int execvp(const char *file, char *const argv[]) __attribute__((weak));
+int execve(const char *file, char *const argv[], char *const envp[]) __attribute__((weak));
+
+int execl(const char *path, const char *arg, ...) { return __bad_exec(); }
+int execlp(const char *file, const char *arg, ...) { return __bad_exec(); }
+int execle(const char *path, const char *arg, ...)  { return __bad_exec(); }
+int execv(const char *path, char *const argv[]) { return __bad_exec(); }
+int execvp(const char *file, char *const argv[]) { return __bad_exec(); }
+int execve(const char *file, char *const argv[], char *const envp[]) { return __bad_exec(); }
+
+pid_t fork(void) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return -1;
+}
+
+pid_t vfork(void) {
+  return fork();
+}
diff --git a/runtime/POSIX/klee_init_env.c b/runtime/POSIX/klee_init_env.c
new file mode 100644
index 00000000..83e9fde6
--- /dev/null
+++ b/runtime/POSIX/klee_init_env.c
@@ -0,0 +1,181 @@
+//===-- klee_init_env.c ---------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static void __emit_error(const char *msg) {
+  klee_report_error(__FILE__, __LINE__, msg, "user.err");
+}
+
+/* Helper function that converts a string to an integer, and
+   terminates the program with an error message is the string is not a
+   proper number */   
+static long int __str_to_int(char *s, const char *error_msg) {
+  long int res = 0;
+  char c;
+
+  if (!*s) __emit_error(error_msg);
+
+  while ((c = *s++)) {
+    if (c == '\0') {
+      break;
+    } else if (c>='0' && c<='9') {
+      res = res*10 + (c - '0');
+    } else {
+      __emit_error(error_msg);
+    }
+  }
+  return res;
+}
+
+static int __isprint(const char c) {
+  /* Assume ASCII */
+  return (32 <= c && c <= 126);
+}
+
+static int __streq(const char *a, const char *b) {
+  while (*a == *b) {
+    if (!*a)
+      return 1;
+    a++;
+    b++;
+  }
+  return 0;
+}
+
+static char *__get_sym_str(int numChars, char *name) {
+  int i;
+  char *s = malloc(numChars+1);
+  klee_mark_global(s);
+  klee_make_symbolic_name(s, numChars+1, name);
+
+  for (i=0; i<numChars; i++)
+    klee_prefer_cex(s, __isprint(s[i]));
+  
+  s[numChars] = '\0';
+  return s;
+}
+
+static void __add_arg(int *argc, char **argv, char *arg, int argcMax) {
+  if (*argc==argcMax) {
+    __emit_error("too many arguments for klee_init_env");
+  } else {
+    argv[*argc] = arg;
+    (*argc)++;
+  }
+}
+
+void klee_init_env(int* argcPtr, char*** argvPtr) {
+  int argc = *argcPtr;
+  char** argv = *argvPtr;
+
+  int new_argc = 0, n_args;
+  char* new_argv[1024];
+  unsigned max_len, min_argvs, max_argvs;
+  unsigned sym_files = 0, sym_file_len = 0;
+  int sym_stdout_flag = 0;
+  int save_all_writes_flag = 0;
+  int fd_fail = 0;
+  char** final_argv;
+  char sym_arg_name[5] = "arg";
+  unsigned sym_arg_num = 0;
+  int k=0, i;
+
+  sym_arg_name[4] = '\0';
+
+  while (k < argc) {
+    if (__streq(argv[k], "--sym-arg") || __streq(argv[k], "-sym-arg")) {
+      const char *msg = "--sym-arg expects an integer argument <max-len>";
+      if (++k == argc)        
+	__emit_error(msg);
+		
+      max_len = __str_to_int(argv[k++], msg);
+      sym_arg_name[3] = '0' + sym_arg_num++;
+      __add_arg(&new_argc, new_argv, 
+                __get_sym_str(max_len, sym_arg_name),
+                1024);
+    }
+    else if (__streq(argv[k], "--sym-args") || __streq(argv[k], "-sym-args")) {
+      const char *msg = 
+        "--sym-args expects three integer arguments <min-argvs> <max-argvs> <max-len>";
+
+      if (k+3 >= argc)
+	__emit_error(msg);
+      
+      k++;
+      min_argvs = __str_to_int(argv[k++], msg);
+      max_argvs = __str_to_int(argv[k++], msg);
+      max_len = __str_to_int(argv[k++], msg);
+
+      n_args = klee_range(min_argvs, max_argvs+1, "n_args");
+      for (i=0; i < n_args; i++) {
+        sym_arg_name[3] = '0' + sym_arg_num++;
+        __add_arg(&new_argc, new_argv, 
+                  __get_sym_str(max_len, sym_arg_name),
+                  1024);
+      }
+    }
+    else if (__streq(argv[k], "--sym-files") || __streq(argv[k], "-sym-files")) {
+      const char* msg = "--sym-files expects two integer arguments <no-sym-files> <sym-file-len>";      
+
+      if (k+2 >= argc)
+	__emit_error(msg);
+      
+      k++;
+      sym_files = __str_to_int(argv[k++], msg);
+      sym_file_len = __str_to_int(argv[k++], msg);
+
+    }
+    else if (__streq(argv[k], "--sym-stdout") || __streq(argv[k], "-sym-stdout")) {
+      sym_stdout_flag = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--save-all-writes") || __streq(argv[k], "-save-all-writes")) {
+      save_all_writes_flag = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--fd-fail") || __streq(argv[k], "-fd-fail")) {
+      fd_fail = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--max-fail") || __streq(argv[k], "-max-fail")) {
+      const char *msg = "--max-fail expects an integer argument <max-failures>";
+      if (++k == argc)
+	__emit_error(msg);
+		
+      fd_fail = __str_to_int(argv[k++], msg);
+    }
+    else {
+      /* simply copy arguments */
+      __add_arg(&new_argc, new_argv, argv[k++], 1024);
+    }
+  }
+
+  final_argv = (char**) malloc((new_argc+1) * sizeof(*final_argv));
+  klee_mark_global(final_argv);
+  memcpy(final_argv, new_argv, new_argc * sizeof(*final_argv));
+  final_argv[new_argc] = 0;
+
+  *argcPtr = new_argc;
+  *argvPtr = final_argv;
+
+  klee_init_fds(sym_files, sym_file_len, 
+		sym_stdout_flag, save_all_writes_flag, 
+		fd_fail);
+}
+
diff --git a/runtime/POSIX/misc.c b/runtime/POSIX/misc.c
new file mode 100644
index 00000000..12ff2f58
--- /dev/null
+++ b/runtime/POSIX/misc.c
@@ -0,0 +1,87 @@
+//===-- misc.c ------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <klee/klee.h>
+#include <string.h>
+
+#if 0
+#define MAX_SYM_ENV_SIZE 32
+typedef struct {
+  char name[MAX_SYM_ENV_SIZE];
+  char *value;
+} sym_env_var;
+
+static sym_env_var *__klee_sym_env = 0;
+static unsigned __klee_sym_env_count = 0;
+static unsigned __klee_sym_env_nvars = 0;
+static unsigned __klee_sym_env_var_size = 0;
+void __klee_init_environ(unsigned nvars, 
+                         unsigned var_size) {
+  assert(var_size);
+  __klee_sym_env = malloc(sizeof(*__klee_sym_env) * nvars);
+  assert(__klee_sym_env);
+
+  __klee_sym_env_nvars = nvars;
+  __klee_sym_env_var_size = var_size;  
+}
+
+static unsigned __strlen(const char *s) {
+  const char *s2 = s;
+  while (*s2) ++s2;
+  return s2-s;
+}
+
+extern char *__getenv(const char *name);
+char *getenv(const char *name) {
+  char *res = __getenv(name);
+
+  if (!__klee_sym_env_nvars)
+    return res;
+
+  /* If it exists in the system environment fork and return the actual
+     result or 0. */
+  if (res) {
+    return klee_range(0, 2, name) ? res : 0;
+  } else {
+    unsigned i, len = __strlen(name);
+
+    if (len>=MAX_SYM_ENV_SIZE) {
+      /* Don't deal with strings to large to fit in our name. */
+      return 0;
+    } else {
+      /* Check for existing entry */
+      for (i=0; i<__klee_sym_env_count; ++i)
+        if (memcmp(__klee_sym_env[i].name, name, len+1)==0)
+          return __klee_sym_env[i].value;
+      
+      /* Otherwise create if room and we choose to */
+      if (__klee_sym_env_count < __klee_sym_env_nvars) {
+        if (klee_range(0, 2, name)) {
+          char *s = malloc(__klee_sym_env_var_size+1);
+          klee_make_symbolic(s, __klee_sym_env_var_size+1);
+          s[__klee_sym_env_var_size] = '\0';
+          
+          memcpy(__klee_sym_env[__klee_sym_env_count].name, name, len+1);
+          __klee_sym_env[__klee_sym_env_count].value = s;
+          ++__klee_sym_env_count;
+          
+          return s;
+        }
+      }
+      
+      return 0;
+    }
+  }
+}
+#endif
diff --git a/runtime/POSIX/selinux.c b/runtime/POSIX/selinux.c
new file mode 100644
index 00000000..38acba6c
--- /dev/null
+++ b/runtime/POSIX/selinux.c
@@ -0,0 +1,80 @@
+//===-- selinux.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/* Very basic SELinux support */
+
+#include "klee/Config/config.h"
+
+#ifdef HAVE_SELINUX_SELINUX_H
+
+#include "klee/klee.h"
+
+#include <selinux/selinux.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/* for now, assume we run on an SELinux machine */
+int exe_selinux = 1;
+
+/* NULL is the default policy behavior */
+security_context_t create_con = NULL;
+
+
+int is_selinux_enabled() {
+  return exe_selinux;
+}
+
+
+/***/
+
+int getfscreatecon(security_context_t *context) {
+  *context = create_con;
+  return 0;
+}
+
+
+int setfscreatecon(security_context_t context) {
+  if (context == NULL) {
+    create_con = context;
+    return 0;
+  }
+
+  /* on my machine, setfscreatecon seems to incorrectly accept one
+     char strings.. Also, make sure mcstrans > 0.2.8 for replay 
+     (important bug fixed) */
+  if (context[0] != '\0' && context[1] == '\0')
+    klee_silent_exit(1);
+
+  return -1;
+}
+
+/***/
+
+int setfilecon(const char *path, security_context_t con) {
+  if (con)
+    return 0;
+  
+  errno = ENOSPC;
+  return -1;  
+}
+
+int lsetfilecon(const char *path, security_context_t con) {
+  return setfilecon(path, con);
+}
+
+int fsetfilecon(int fd, security_context_t con) {
+  return setfilecon("", con);
+}
+
+/***/
+
+void freecon(security_context_t con) {}
+void freeconary(security_context_t *con) {}
+
+#endif
diff --git a/runtime/POSIX/stubs.c b/runtime/POSIX/stubs.c
new file mode 100644
index 00000000..cf64f26b
--- /dev/null
+++ b/runtime/POSIX/stubs.c
@@ -0,0 +1,560 @@
+//===-- stubs.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <utime.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "klee/Config/config.h"
+
+void klee_warning(const char*);
+void klee_warning_once(const char*);
+
+/* Silent ignore */
+
+int __syscall_rt_sigaction(int signum, const struct sigaction *act, 
+                           struct sigaction *oldact, size_t _something)
+     __attribute__((weak));
+
+int __syscall_rt_sigaction(int signum, const struct sigaction *act, 
+                           struct sigaction *oldact, size_t _something) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+int sigaction(int signum, const struct sigaction *act, 
+              struct sigaction *oldact) __attribute__((weak));
+
+int sigaction(int signum, const struct sigaction *act, 
+              struct sigaction *oldact) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
+     __attribute__((weak));
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+/* Not even worth warning about these */
+int fdatasync(int fd) __attribute__((weak));
+int fdatasync(int fd) {
+  return 0;
+}
+
+/* Not even worth warning about this */
+void sync(void) __attribute__((weak));
+void sync(void) {
+}
+
+/* Error ignore */
+
+extern int __fgetc_unlocked(FILE *f);
+extern int __fputc_unlocked(int c, FILE *f);
+
+int __socketcall(int type, int *args) __attribute__((weak));
+int __socketcall(int type, int *args) {
+  klee_warning("ignoring (EAFNOSUPPORT)");
+  errno = EAFNOSUPPORT;
+  return -1;
+}
+
+int _IO_getc(FILE *f) __attribute__((weak));
+int _IO_getc(FILE *f) {
+  return __fgetc_unlocked(f);
+}
+
+int _IO_putc(int c, FILE *f) __attribute__((weak));
+int _IO_putc(int c, FILE *f) {
+  return __fputc_unlocked(c, f);
+}
+
+int mkdir(const char *pathname, mode_t mode) __attribute__((weak));
+int mkdir(const char *pathname, mode_t mode) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int mkfifo(const char *pathname, mode_t mode) __attribute__((weak));
+int mkfifo(const char *pathname, mode_t mode) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int mknod(const char *pathname, mode_t mode, dev_t dev) __attribute__((weak));
+int mknod(const char *pathname, mode_t mode, dev_t dev) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int pipe(int filedes[2]) __attribute__((weak));
+int pipe(int filedes[2]) {
+  klee_warning("ignoring (ENFILE)");
+  errno = ENFILE;
+  return -1;
+}
+
+int link(const char *oldpath, const char *newpath) __attribute__((weak));
+int link(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int symlink(const char *oldpath, const char *newpath) __attribute__((weak));
+int symlink(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int rename(const char *oldpath, const char *newpath) __attribute__((weak));
+int rename(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int nanosleep(const struct timespec *req, struct timespec *rem) __attribute__((weak));
+int nanosleep(const struct timespec *req, struct timespec *rem) {
+  return 0;
+}
+
+/* XXX why can't I call this internally? */
+int clock_gettime(clockid_t clk_id, struct timespec *res) __attribute__((weak));
+int clock_gettime(clockid_t clk_id, struct timespec *res) {
+  /* Fake */
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  res->tv_sec = tv.tv_sec;
+  res->tv_nsec = tv.tv_usec * 1000;
+  return 0;
+}
+
+int clock_settime(clockid_t clk_id, const struct timespec *res) __attribute__((weak));
+int clock_settime(clockid_t clk_id, const struct timespec *res) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+time_t time(time_t *t) {
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  if (t)
+    *t = tv.tv_sec;
+  return tv.tv_sec;
+}
+
+clock_t times(struct tms *buf) {
+  /* Fake */
+  buf->tms_utime = 0;
+  buf->tms_stime = 0;
+  buf->tms_cutime = 0;
+  buf->tms_cstime = 0;
+  return 0;
+}
+
+struct utmpx *getutxent(void) __attribute__((weak));
+struct utmpx *getutxent(void) {
+  return (struct utmpx*) getutent();
+}
+
+void setutxent(void) __attribute__((weak));
+void setutxent(void) {
+  setutent();
+}
+
+void endutxent(void) __attribute__((weak));
+void endutxent(void) {
+  endutent();
+}
+
+int utmpxname(const char *file) __attribute__((weak));
+int utmpxname(const char *file) {
+  utmpname(file);
+  return 0;
+}
+
+int euidaccess(const char *pathname, int mode) __attribute__((weak));
+int euidaccess(const char *pathname, int mode) {
+  return access(pathname, mode);
+}
+
+int eaccess(const char *pathname, int mode) __attribute__((weak));
+int eaccess(const char *pathname, int mode) {
+  return euidaccess(pathname, mode);
+}
+
+int group_member (gid_t __gid) __attribute__((weak));
+int group_member (gid_t __gid) {
+  return ((__gid == getgid ()) || (__gid == getegid ()));
+}
+
+int utime(const char *filename, const struct utimbuf *buf) __attribute__((weak));
+int utime(const char *filename, const struct utimbuf *buf) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int utimes(const char *filename, const struct timeval times[2]) __attribute__((weak));
+int utimes(const char *filename, const struct timeval times[2]) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int futimes(int fd, const struct timeval times[2]) __attribute__((weak));
+int futimes(int fd, const struct timeval times[2]) {
+  klee_warning("ignoring (EBADF)");
+  errno = EBADF;
+  return -1;
+}
+
+int strverscmp (__const char *__s1, __const char *__s2) {
+  return strcmp(__s1, __s2); /* XXX no doubt this is bad */
+}
+
+unsigned int gnu_dev_major(unsigned long long int __dev) __attribute__((weak));
+unsigned int gnu_dev_major(unsigned long long int __dev) {
+  return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
+}
+
+unsigned int gnu_dev_minor(unsigned long long int __dev) __attribute__((weak));
+unsigned int gnu_dev_minor(unsigned long long int __dev) {
+  return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
+}
+
+unsigned long long int gnu_dev_makedev(unsigned int __major, unsigned int __minor) __attribute__((weak));
+unsigned long long int gnu_dev_makedev(unsigned int __major, unsigned int __minor) {
+  return ((__minor & 0xff) | ((__major & 0xfff) << 8)
+	  | (((unsigned long long int) (__minor & ~0xff)) << 12)
+	  | (((unsigned long long int) (__major & ~0xfff)) << 32));
+}
+
+char *canonicalize_file_name (const char *name) __attribute__((weak));
+char *canonicalize_file_name (const char *name) {
+  char *res = malloc(PATH_MAX);
+  char *rp_res = realpath(name, res);
+  if (!rp_res)
+    free(res);
+  return rp_res;
+}
+
+int getloadavg(double loadavg[], int nelem) __attribute__((weak));
+int getloadavg(double loadavg[], int nelem) {
+  klee_warning("ignoring (-1 result)");
+  return -1;
+}
+
+pid_t wait(int *status) __attribute__((weak));
+pid_t wait(int *status) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t wait3(int *status, int options, struct rusage *rusage) __attribute__((weak));
+pid_t wait3(int *status, int options, struct rusage *rusage) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) __attribute__((weak));
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t waitpid(pid_t pid, int *status, int options) __attribute__((weak));
+pid_t waitpid(pid_t pid, int *status, int options) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) __attribute__((weak));
+pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+/* ACL */
+
+/* FIXME: We need autoconf magic for this. */
+
+#ifdef HAVE_SYS_ACL_H
+
+#include <sys/acl.h>
+
+int acl_delete_def_file(const char *path_p) __attribute__((weak));
+int acl_delete_def_file(const char *path_p) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_extended_file(const char path_p) __attribute__((weak));
+int acl_extended_file(const char path_p) {
+  klee_warning("ignoring (ENOENT)");
+  errno = ENOENT;
+  return -1;
+}
+
+int acl_entries(acl_t acl) __attribute__((weak));
+int acl_entries(acl_t acl) {
+  klee_warning("ignoring (EINVAL)");
+  errno = EINVAL;
+  return -1;
+}
+
+acl_t acl_from_mode(mode_t mode) __attribute__((weak));
+acl_t acl_from_mode(mode_t mode) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+acl_t acl_get_fd(int fd) __attribute__((weak));
+acl_t acl_get_fd(int fd) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+acl_t acl_get_file(const char *pathname, acl_type_t type) __attribute__((weak));
+acl_t acl_get_file(const char *pathname, acl_type_t type) {
+  klee_warning("ignoring (ENONMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+int acl_set_fd(int fd, acl_t acl) __attribute__((weak));
+int acl_set_fd(int fd, acl_t acl) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) __attribute__((weak));
+int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_free(void *obj_p) __attribute__((weak));
+int acl_free(void *obj_p) {
+  klee_warning("ignoring (EINVAL)");
+  errno = EINVAL;
+  return -1;
+}
+
+#endif
+
+int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) __attribute__((weak));
+int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int umount(const char *target) __attribute__((weak));
+int umount(const char *target) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int umount2(const char *target, int flags) __attribute__((weak));
+int umount2(const char *target, int flags) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int swapon(const char *path, int swapflags) __attribute__((weak));
+int swapon(const char *path, int swapflags) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int swapoff(const char *path) __attribute__((weak));
+int swapoff(const char *path) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setgid(gid_t gid) __attribute__((weak));
+int setgid(gid_t gid) {
+  klee_warning("silently ignoring (returning 0)");
+  return 0;
+}
+
+int setgroups(size_t size, const gid_t *list) __attribute__((weak));
+int setgroups(size_t size, const gid_t *list) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int sethostname(const char *name, size_t len) __attribute__((weak));
+int sethostname(const char *name, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpgid(pid_t pid, pid_t pgid) __attribute__((weak));
+int setpgid(pid_t pid, pid_t pgid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpgrp(void) __attribute__((weak));
+int setpgrp(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpriority(__priority_which_t which, id_t who, int prio) __attribute__((weak));
+int setpriority(__priority_which_t which, id_t who, int prio) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid) __attribute__((weak));
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid) __attribute__((weak));
+int setresuid(uid_t ruid, uid_t euid, uid_t suid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) __attribute__((weak));
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) __attribute__((weak));
+int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+pid_t setsid(void) __attribute__((weak));
+pid_t setsid(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz) __attribute__((weak));
+int settimeofday(const struct timeval *tv, const struct timezone *tz) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setuid(uid_t uid) __attribute__((weak));
+int setuid(uid_t uid) {
+  klee_warning("silently ignoring (returning 0)");
+  return 0;
+}
+
+int reboot(int flag) __attribute__((weak));
+int reboot(int flag) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int mlock(const void *addr, size_t len) __attribute__((weak));
+int mlock(const void *addr, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int munlock(const void *addr, size_t len) __attribute__((weak));
+int munlock(const void *addr, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int pause(void) __attribute__((weak));
+int pause(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+ssize_t readahead(int fd, off64_t *offset, size_t count) __attribute__((weak));
+ssize_t readahead(int fd, off64_t *offset, size_t count) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) __attribute__((weak));
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return (void*) -1;
+}
+
+void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) __attribute__((weak));
+void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return (void*) -1;
+}
+
+int munmap(void*start, size_t length) __attribute__((weak));
+int munmap(void*start, size_t length) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
diff --git a/runtime/POSIX/testing-dir/a b/runtime/POSIX/testing-dir/a
new file mode 120000
index 00000000..dc1dc0cd
--- /dev/null
+++ b/runtime/POSIX/testing-dir/a
@@ -0,0 +1 @@
+/dev/null
\ No newline at end of file
diff --git a/runtime/POSIX/testing-dir/b b/runtime/POSIX/testing-dir/b
new file mode 120000
index 00000000..b9251ec6
--- /dev/null
+++ b/runtime/POSIX/testing-dir/b
@@ -0,0 +1 @@
+/dev/random
\ No newline at end of file
diff --git a/runtime/POSIX/testing-dir/c b/runtime/POSIX/testing-dir/c
new file mode 100755
index 00000000..2b45f6a5
--- /dev/null
+++ b/runtime/POSIX/testing-dir/c
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Hello world!"
diff --git a/runtime/POSIX/testing-dir/d b/runtime/POSIX/testing-dir/d
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/runtime/POSIX/testing-dir/d
diff --git a/runtime/POSIX/testing-env b/runtime/POSIX/testing-env
new file mode 100644
index 00000000..5a6e8eb8
--- /dev/null
+++ b/runtime/POSIX/testing-env
@@ -0,0 +1,27 @@
+# This file is sourced prior to running the testing environment, make
+# sure to quote things.
+
+export TERM="xterm"
+export SHELL="/bin/bash"
+export LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:"
+export PATH="/usr/local/bin:/usr/bin:/bin"
+export COLORTERM="gnome-terminal"
+export LC_ALL=C
+export TABSIZE=8
+export COLUMNS=80
+
+#       1 BLOCK_SIZE
+#       2 COLUMNS
+#       1 DF_BLOCK_SIZE
+#       1 DU_BLOCK_SIZE
+#       1 HOME
+#       1 LS_BLOCK_SIZE
+#       1 LS_COLORS
+#      11 POSIXLY_CORRECT
+#       1 QUOTING_STYLE
+#       3 SHELL
+#       4 SIMPLE_BACKUP_SUFFIX
+#       1 TABSIZE
+#       2 TERM
+#       2 TIME_STYLE
+#       4 TMPDIR
diff --git a/runtime/Runtest/Makefile b/runtime/Runtest/Makefile
new file mode 100644
index 00000000..dd21c4a9
--- /dev/null
+++ b/runtime/Runtest/Makefile
@@ -0,0 +1,19 @@
+#===-- runtime/Runtest/Makefile ----------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+USEDLIBS=kleeBasic.a
+LIBRARYNAME=kleeRuntest
+SHARED_LIBRARY=1
+LINK_LIBS_IN_SHARED = 1
+DONT_BUILD_RELINKED = 1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/Runtest/intrinsics.c b/runtime/Runtest/intrinsics.c
new file mode 100644
index 00000000..1a2fd030
--- /dev/null
+++ b/runtime/Runtest/intrinsics.c
@@ -0,0 +1,154 @@
+//===-- intrinsics.c ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/* Straight C for linking simplicity */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "klee/klee.h"
+
+#include "klee/Internal/ADT/BOut.h"
+
+static BOut *testData = 0;
+static unsigned testPosition = 0;
+
+static unsigned char rand_byte(void) {
+  unsigned x = rand();
+  x ^= x>>16;
+  x ^= x>>8;
+  return x & 0xFF;
+}
+
+void klee_make_symbolic_name(void *array, unsigned nbytes, const char *name) {
+  static int rand_init = -1;
+
+  if (rand_init == -1) {
+    if (getenv("KLEE_RANDOM")) {
+      struct timeval tv;
+      gettimeofday(&tv, 0);
+      rand_init = 1;
+      srand(tv.tv_sec ^ tv.tv_usec);
+    } else {
+      rand_init = 0;
+    }
+  }
+
+  if (rand_init) {
+    if (!strcmp(name,"syscall_a0")) {
+      unsigned long long *v = array;
+      assert(nbytes == 8);
+      *v = rand() % 69;
+    } else {
+      char *c = array;
+      unsigned i;
+      for (i=0; i<nbytes; i++)
+        c[i] = rand_byte();
+    }
+    return;
+  }
+
+  if (!testData) {
+    char tmp[256];
+    char *name = getenv("KLEE_RUNTEST");
+
+    if (!name) {
+      fprintf(stdout, "KLEE-RUNTIME: KLEE_RUNTEST not set, please enter .bout path: ");
+      fflush(stdout);
+      name = tmp;
+      if (!fgets(tmp, sizeof tmp, stdin) || !strlen(tmp)) {
+        fprintf(stderr, "KLEE-RUNTIME: cannot replay, no KLEE_RUNTEST or user input\n");
+        exit(1);
+      }
+      tmp[strlen(tmp)-1] = '\0'; /* kill newline */
+    }
+    testData = bOut_fromFile(name);
+    if (!testData) {
+      fprintf(stderr, "KLEE-RUNTIME: unable to open .bout file\n");
+      exit(1);
+    }
+  }
+
+  if (testPosition >= testData->numObjects) {
+    fprintf(stderr, "ERROR: out of inputs, using zero\n");
+    memset(array, 0, nbytes);
+  } else {
+    BOutObject *o = &testData->objects[testPosition++];
+    memcpy(array, o->bytes, nbytes<o->numBytes ? nbytes : o->numBytes);
+    if (nbytes != o->numBytes) {
+      fprintf(stderr, "ERROR: object sizes differ\n");
+      if (o->numBytes < nbytes) 
+        memset((char*) array + o->numBytes, 0, nbytes - o->numBytes);
+    }
+  }
+}
+
+void klee_make_symbolic(void *array, unsigned nbytes) {
+  klee_make_symbolic_name(array, nbytes, "unnamed");
+}
+
+void *klee_malloc_n(unsigned nelems, unsigned size, unsigned alignment) {
+#if 1
+  return mmap((void*) 0x90000000, nelems*size, PROT_READ|PROT_WRITE, 
+              MAP_PRIVATE
+#ifdef MAP_ANONYMOUS
+              |MAP_ANONYMOUS
+#endif
+              , 0, 0);
+#else
+  char *buffer = malloc(nelems*size + alignment - 1);
+  buffer += (alignment - (long)buffer % alignment);
+  return buffer;
+#endif
+}
+
+void klee_silent_exit(int x) {
+  exit(x);
+}
+
+unsigned klee_choose(unsigned n) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if(x >= n)
+    fprintf(stderr, "ERROR: max = %d, got = %d\n", n, x);
+  assert(x < n);
+  return x;
+}
+
+void klee_assume(unsigned x) {
+  if (!x) {
+    fprintf(stderr, "ERROR: invalid klee_assume\n");
+  }
+}
+
+unsigned klee_get_value(unsigned x) {
+  return x;
+}
+
+int klee_range_name(int begin, int end, const char* name) {
+  int x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  if (x<begin || x>=end) {
+    fprintf(stderr, 
+            "KLEE: ERROR: invalid klee_range(%u,%u,%s) value, got: %u\n", 
+            begin, end, name, x);
+    abort();
+  }
+  return x;
+}
+
+/* not sure we should even define.  is for debugging. */
+void klee_print_expr(const char *msg, ...) { }
+
+void klee_set_forking(unsigned enable) { }
diff --git a/runtime/klee-libc/Makefile b/runtime/klee-libc/Makefile
new file mode 100755
index 00000000..bcd61f73
--- /dev/null
+++ b/runtime/klee-libc/Makefile
@@ -0,0 +1,19 @@
+#===-- runtime/klee-libc/Makefile --------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=klee-libc
+DONT_BUILD_RELINKED=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/klee-libc/__cxa_atexit.c b/runtime/klee-libc/__cxa_atexit.c
new file mode 100644
index 00000000..e7982848
--- /dev/null
+++ b/runtime/klee-libc/__cxa_atexit.c
@@ -0,0 +1,49 @@
+//===-- __cxa_atexit.c ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+
+#define MAX_ATEXIT 128
+
+static struct {
+  void (*fn)(void*);
+  void *arg;
+  void *dso_handle;
+} AtExit[MAX_ATEXIT];
+static unsigned NumAtExit = 0;
+
+static void RunAtExit(void) __attribute__((destructor));
+static void RunAtExit(void) {
+  unsigned i;
+
+  for (i=0; i<NumAtExit; ++i)
+    AtExit[i].fn(AtExit[i].arg);
+}
+
+int __cxa_atexit(void (*fn)(void*),
+                 void *arg,
+                 void *dso_handle) {
+  klee_warning_once("FIXME: __cxa_atexit being ignored");
+  
+  /* Better to just report an error here than return 1 (the defined
+   * semantics).
+   */
+  if (NumAtExit == MAX_ATEXIT)
+    klee_report_error(__FILE__,
+                      __LINE__,
+                      "__cxa_atexit: no room in array!",
+                      "exec");
+  
+  AtExit[NumAtExit].fn = fn;
+  AtExit[NumAtExit].arg = arg;
+  ++NumAtExit;
+  
+  return 0;
+}
+
diff --git a/runtime/klee-libc/abort.c b/runtime/klee-libc/abort.c
new file mode 100644
index 00000000..0332d095
--- /dev/null
+++ b/runtime/klee-libc/abort.c
@@ -0,0 +1,16 @@
+//===-- abort.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#include "klee/klee.h"
+
+void abort(void) {
+  klee_abort();
+}
diff --git a/runtime/klee-libc/atexit.c b/runtime/klee-libc/atexit.c
new file mode 100644
index 00000000..c71b2cd6
--- /dev/null
+++ b/runtime/klee-libc/atexit.c
@@ -0,0 +1,16 @@
+//===-- atexit.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int __cxa_atexit(void (*fn)(void*),
+                 void *arg,
+                 void *dso_handle);
+
+int atexit(void (*fn)(void)) {
+  return __cxa_atexit((void(*)(void*)) fn, 0, 0);
+}
diff --git a/runtime/klee-libc/atoi.c b/runtime/klee-libc/atoi.c
new file mode 100644
index 00000000..ab97bfbb
--- /dev/null
+++ b/runtime/klee-libc/atoi.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdlib.h>
+
+int atoi(const char *str) {
+  return (int)strtol(str, (char **)NULL, 10);
+}
diff --git a/runtime/klee-libc/calloc.c b/runtime/klee-libc/calloc.c
new file mode 100644
index 00000000..30b88b30
--- /dev/null
+++ b/runtime/klee-libc/calloc.c
@@ -0,0 +1,46 @@
+//===-- calloc.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+#include <string.h>
+
+// DWD - I prefer to be internal
+#if 0
+void *calloc(size_t nmemb, size_t size) {
+	unsigned nbytes = nmemb * size;
+	void *addr = malloc(nbytes);
+	if(addr)
+		memset(addr, 0, nbytes);
+	return addr;
+}
+// Always reallocate.
+void *realloc(void *ptr, size_t nbytes) {
+	if(!ptr)
+		return malloc(nbytes);
+
+	if(!nbytes) {
+		free(ptr);
+		return 0;
+	}
+
+        unsigned copy_nbytes = klee_get_obj_size(ptr);
+	//printf("REALLOC: current object = %d bytes!\n", copy_nbytes);
+
+	void *addr = malloc(nbytes);
+	if(addr) {
+		// shrinking
+		if(copy_nbytes > nbytes)
+			copy_nbytes = nbytes;
+		//printf("REALLOC: copying = %d bytes!\n", copy_nbytes);
+		memcpy(addr, ptr, copy_nbytes);
+		free(ptr);
+	} 
+	return addr;
+}
+#endif
diff --git a/runtime/klee-libc/htonl.c b/runtime/klee-libc/htonl.c
new file mode 100644
index 00000000..cec2d0f5
--- /dev/null
+++ b/runtime/klee-libc/htonl.c
@@ -0,0 +1,49 @@
+//===-- htonl.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdint.h>
+
+#undef htons
+#undef htonl
+#undef ntohs
+#undef ntohl
+
+// Make sure we can recognize the endianness.
+#if (!defined(BYTE_ORDER) || !defined(BIG_ENDIAN) || !defined(LITTLE_ENDIAN))
+#error "Unknown platform endianness!"
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+uint16_t htons(uint16_t v) {
+  return (v >> 8) | (v << 8);
+}
+uint32_t htonl(uint32_t v) {
+  return htons(v >> 16) | (htons((uint16_t) v) << 16);
+}
+
+#else
+
+uint16_t htons(uint16_t v) {
+  return v;
+}
+uint32_t htonl(uint32_t v) {
+  return v;
+}
+
+#endif
+
+uint16_t ntohs(uint32_t v) {
+  return htons(v);
+}
+uint32_t ntohl(uint32_t v) {
+  return htonl(v);
+}
diff --git a/runtime/klee-libc/klee-choose.c b/runtime/klee-libc/klee-choose.c
new file mode 100644
index 00000000..106b4f89
--- /dev/null
+++ b/runtime/klee-libc/klee-choose.c
@@ -0,0 +1,20 @@
+//===-- klee-choose.c -----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+
+unsigned klee_choose(unsigned n) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+
+  // NB: this will *not* work if they don't compare to n values.
+  if(x >= n)
+    klee_silent_exit(0);
+  return x;
+}
diff --git a/runtime/klee-libc/memchr.c b/runtime/klee-libc/memchr.c
new file mode 100644
index 00000000..fe0670a7
--- /dev/null
+++ b/runtime/klee-libc/memchr.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+void *
+memchr(s, c, n)
+	const void *s;
+	int c;
+	size_t n;
+{
+	if (n != 0) {
+		const unsigned char *p = s;
+
+		do {
+			if (*p++ == c)
+				return ((void *)(p - 1));
+		} while (--n != 0);
+	}
+	return (NULL);
+}
diff --git a/runtime/klee-libc/memcmp.c b/runtime/klee-libc/memcmp.c
new file mode 100644
index 00000000..7562f4f7
--- /dev/null
+++ b/runtime/klee-libc/memcmp.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/*
+ * Compare memory regions.
+ */
+int memcmp(const void *s1, const void *s2, size_t n) {
+  if (n != 0) {
+    const unsigned char *p1 = s1, *p2 = s2;
+    
+    do {
+      if (*p1++ != *p2++) {
+        return (*--p1 - *--p2);
+      }
+    } while (--n != 0);
+  }
+  return (0);
+}
diff --git a/runtime/klee-libc/memcpy.c b/runtime/klee-libc/memcpy.c
new file mode 100644
index 00000000..14b98ce6
--- /dev/null
+++ b/runtime/klee-libc/memcpy.c
@@ -0,0 +1,19 @@
+//===-- memcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return destaddr;
+}
diff --git a/runtime/klee-libc/memmove.c b/runtime/klee-libc/memmove.c
new file mode 100644
index 00000000..c6e1ada9
--- /dev/null
+++ b/runtime/klee-libc/memmove.c
@@ -0,0 +1,28 @@
+//===-- memmove.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memmove(void *dst, const void *src, size_t count) {
+  char *a = dst;
+  const char *b = src;
+
+  if (src == dst)
+    return dst;
+
+  if (src>dst) {
+    while (count--) *a++ = *b++;
+  } else {
+    a+=count-1;
+    b+=count-1;
+    while (count--) *a-- = *b--;
+  }
+
+  return dst;
+}
diff --git a/runtime/klee-libc/mempcpy.c b/runtime/klee-libc/mempcpy.c
new file mode 100644
index 00000000..6327e748
--- /dev/null
+++ b/runtime/klee-libc/mempcpy.c
@@ -0,0 +1,19 @@
+//===-- mempcpy.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *mempcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return dest;
+}
diff --git a/runtime/klee-libc/memset.c b/runtime/klee-libc/memset.c
new file mode 100644
index 00000000..ee9ecb87
--- /dev/null
+++ b/runtime/klee-libc/memset.c
@@ -0,0 +1,17 @@
+//===-- memset.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memset(void * dst, int s, size_t count) {
+    char * a = dst;
+    while (count-- > 0)
+      *a++ = s;
+    return dst;
+}
diff --git a/runtime/klee-libc/putchar.c b/runtime/klee-libc/putchar.c
new file mode 100644
index 00000000..f3fcf01d
--- /dev/null
+++ b/runtime/klee-libc/putchar.c
@@ -0,0 +1,17 @@
+//===-- putchar.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <unistd.h>
+
+int putchar(int c) {
+  char x = c;
+  write(1, &x, 1);
+  return 1;
+}
diff --git a/runtime/klee-libc/stpcpy.c b/runtime/klee-libc/stpcpy.c
new file mode 100644
index 00000000..1f774f3d
--- /dev/null
+++ b/runtime/klee-libc/stpcpy.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999
+ *	David E. O'Brien
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/* Defeat object checking stuff. */
+#undef stpcpy
+
+char *
+stpcpy(char * to, const char * from)
+{
+
+	for (; (*to = *from); ++from, ++to);
+	return(to);
+}
diff --git a/runtime/klee-libc/strcat.c b/runtime/klee-libc/strcat.c
new file mode 100644
index 00000000..195e9460
--- /dev/null
+++ b/runtime/klee-libc/strcat.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/* Defeat object checking stuff. */
+#undef strcat
+
+char * strcat(char * s, const char * append) {
+	char *save = s;
+
+	for (; *s; ++s)
+		;
+	while ((*s++ = *append++))
+		;
+	return(save);
+}
diff --git a/runtime/klee-libc/strchr.c b/runtime/klee-libc/strchr.c
new file mode 100644
index 00000000..33f97bea
--- /dev/null
+++ b/runtime/klee-libc/strchr.c
@@ -0,0 +1,23 @@
+//===-- strchr.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+char *strchr(const char *p, int ch) {
+  char c;
+
+  c = ch;
+  for (;; ++p) {
+    if (*p == c) {
+      return ((char *)p);
+    } else if (*p == '\0') {
+      return 0;
+    }
+  }
+  /* NOTREACHED */  
+  return 0;
+}
diff --git a/runtime/klee-libc/strcmp.c b/runtime/klee-libc/strcmp.c
new file mode 100644
index 00000000..6b8c4e85
--- /dev/null
+++ b/runtime/klee-libc/strcmp.c
@@ -0,0 +1,14 @@
+//===-- strcmp.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int strcmp(const char *a, const char *b) {
+  while (*a && *a == *b)
+    ++a, ++b;
+  return *a - *b;
+}
diff --git a/runtime/klee-libc/strcoll.c b/runtime/klee-libc/strcoll.c
new file mode 100644
index 00000000..73d59f89
--- /dev/null
+++ b/runtime/klee-libc/strcoll.c
@@ -0,0 +1,15 @@
+//===-- strcoll.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+// according to the manpage, this is equiv in the POSIX/C locale.
+int strcoll(const char *s1, const char *s2) {
+  return strcmp(s1,s2);
+}
diff --git a/runtime/klee-libc/strcpy.c b/runtime/klee-libc/strcpy.c
new file mode 100644
index 00000000..0fbaf9a7
--- /dev/null
+++ b/runtime/klee-libc/strcpy.c
@@ -0,0 +1,17 @@
+//===-- strcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+char *strcpy(char *to, const char *from) {
+  char *start = to;
+
+  while ((*to = *from))
+    ++to, ++from;
+
+  return start;
+}
diff --git a/runtime/klee-libc/strlen.c b/runtime/klee-libc/strlen.c
new file mode 100644
index 00000000..e298410c
--- /dev/null
+++ b/runtime/klee-libc/strlen.c
@@ -0,0 +1,17 @@
+//===-- strlen.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+size_t strlen(const char *str) {
+  const char *s = str;
+  while (*s)
+    ++s;
+  return s - str;
+}
diff --git a/runtime/klee-libc/strncmp.c b/runtime/klee-libc/strncmp.c
new file mode 100644
index 00000000..a8dc3749
--- /dev/null
+++ b/runtime/klee-libc/strncmp.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+
+	if (n == 0)
+		return (0);
+	do {
+		if (*s1 != *s2++)
+			return (*(unsigned char *)s1 -
+				*(unsigned char *)(s2 - 1));
+		if (*s1++ == 0)
+			break;
+	} while (--n != 0);
+	return (0);
+}
diff --git a/runtime/klee-libc/strncpy.c b/runtime/klee-libc/strncpy.c
new file mode 100644
index 00000000..62ab7993
--- /dev/null
+++ b/runtime/klee-libc/strncpy.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+char * strncpy(char * dst, const char * src, size_t n)
+{
+	if (n != 0) {
+		char *d = dst;
+		const char *s = src;
+
+		do {
+			if ((*d++ = *s++) == 0) {
+				/* NUL pad the remaining n-1 bytes */
+				while (--n != 0)
+					*d++ = 0;
+				break;
+			}
+		} while (--n != 0);
+	}
+	return (dst);
+}
diff --git a/runtime/klee-libc/strrchr.c b/runtime/klee-libc/strrchr.c
new file mode 100644
index 00000000..01128b48
--- /dev/null
+++ b/runtime/klee-libc/strrchr.c
@@ -0,0 +1,21 @@
+//===-- strrchr.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+char *strrchr(const char *t, int c) {
+  char ch;
+  const char *l=0;
+
+  ch = c;
+  for (;;) {
+    if (*t == ch) l=t; if (!*t) return (char*)l; ++t;
+  }
+  return (char*)l;
+}
diff --git a/runtime/klee-libc/strtol.c b/runtime/klee-libc/strtol.c
new file mode 100644
index 00000000..3be7fff3
--- /dev/null
+++ b/runtime/klee-libc/strtol.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(const char * nptr, char ** endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+	if (base < 2 || base > 36)
+		goto noconv;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set 'any' if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
+	    : LONG_MAX;
+	cutlim = cutoff % base;
+	cutoff /= base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LONG_MIN : LONG_MAX;
+		errno = ERANGE;
+	} else if (!any) {
+noconv:
+		errno = EINVAL;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/runtime/klee-libc/strtoul.c b/runtime/klee-libc/strtoul.c
new file mode 100644
index 00000000..f23d5b54
--- /dev/null
+++ b/runtime/klee-libc/strtoul.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(const char * nptr, char ** endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+	if (base < 2 || base > 36)
+		goto noconv;
+
+	cutoff = ULONG_MAX / base;
+	cutlim = ULONG_MAX % base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULONG_MAX;
+		errno = ERANGE;
+	} else if (!any) {
+noconv:
+		errno = EINVAL;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/runtime/klee-libc/tolower.c b/runtime/klee-libc/tolower.c
new file mode 100644
index 00000000..265f5deb
--- /dev/null
+++ b/runtime/klee-libc/tolower.c
@@ -0,0 +1,14 @@
+//===-- tolower.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int tolower(int ch) {
+  if ( (unsigned int)(ch - 'A') < 26u )
+    ch -= 'A' - 'a';
+  return ch;
+}
diff --git a/runtime/klee-libc/toupper.c b/runtime/klee-libc/toupper.c
new file mode 100644
index 00000000..37e5f9d6
--- /dev/null
+++ b/runtime/klee-libc/toupper.c
@@ -0,0 +1,14 @@
+//===-- toupper.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int toupper(int ch) {
+  if ( (unsigned int)(ch - 'a') < 26u )
+    ch += 'A' - 'a';
+  return ch;
+}