Browse Source

release v0.3

- Bugfixes in PAL and SHIM
- Improvement of migration scheme in SHIM, which largely speed up
  forking
- Upgrade glibc to 2.19
- FreeBSD port
- Support OpenJDK, python and R
Chia-Che Tsai 7 years ago
parent
commit
b5586bbfc6
100 changed files with 4704 additions and 2458 deletions
  1. 1 0
      LibOS/.packed/glibc.sha384
  2. BIN
      LibOS/.packed/glibc.tar.gz
  3. 8 8
      LibOS/Makefile
  4. 2 2
      LibOS/buildglibc.py
  5. 1845 0
      LibOS/glibc-2.19.patch
  6. 1 0
      LibOS/glibc-2.19/elf/syscallas.S
  7. 1 0
      LibOS/glibc-2.19/elf/syscalldb.c
  8. 56 0
      LibOS/glibc-2.19/libos/Makefile
  9. 15 0
      LibOS/glibc-2.19/libos/Versions
  10. 27 0
      LibOS/glibc-2.19/libos/benchmark.c
  11. 13 0
      LibOS/glibc-2.19/libos/checkpoint.c
  12. 13 0
      LibOS/glibc-2.19/libos/msgpersist.c
  13. 27 0
      LibOS/glibc-2.19/libos/sandbox.c
  14. 11 0
      LibOS/glibc-2.19/syscallas.S
  15. 10 0
      LibOS/glibc-2.19/syscalldb.c
  16. 15 0
      LibOS/glibc-2.19/syscalldb.h
  17. 1 0
      LibOS/glibc-2.19/sysdeps/unix/sysv/linux/x86_64/syscalldb.h
  18. 266 404
      LibOS/shim/include/shim_checkpoint.h
  19. 5 1
      LibOS/shim/include/shim_defs.h
  20. 35 25
      LibOS/shim/include/shim_fs.h
  21. 25 7
      LibOS/shim/include/shim_handle.h
  22. 38 17
      LibOS/shim/include/shim_signal.h
  23. 16 16
      LibOS/shim/include/shim_table.h
  24. 26 7
      LibOS/shim/include/shim_thread.h
  25. 195 23
      LibOS/shim/include/shim_types.h
  26. 9 0
      LibOS/shim/include/shim_unistd.h
  27. 1 1
      LibOS/shim/include/shim_utils.h
  28. 15 18
      LibOS/shim/include/shim_vma.h
  29. 0 0
      LibOS/shim/src/.packed/shim.sha384
  30. BIN
      LibOS/shim/src/.packed/shim.tar.gz
  31. 9 8
      LibOS/shim/src/Makefile
  32. 85 148
      LibOS/shim/src/bookkeep/shim_handle.c
  33. 28 54
      LibOS/shim/src/bookkeep/shim_signal.c
  34. 87 199
      LibOS/shim/src/bookkeep/shim_thread.c
  35. 261 200
      LibOS/shim/src/bookkeep/shim_vma.c
  36. 1 1
      LibOS/shim/src/elf/dl-machine-x86_64.h
  37. 67 173
      LibOS/shim/src/elf/shim_rtld.c
  38. 26 13
      LibOS/shim/src/fs/chroot/fs.c
  39. 5 1
      LibOS/shim/src/fs/dev/fs.c
  40. 9 5
      LibOS/shim/src/fs/pipe/fs.c
  41. 6 2
      LibOS/shim/src/fs/proc/fs.c
  42. 5 1
      LibOS/shim/src/fs/proc/info.c
  43. 6 1
      LibOS/shim/src/fs/proc/ipc-thread.c
  44. 5 1
      LibOS/shim/src/fs/proc/thread.c
  45. 79 10
      LibOS/shim/src/fs/shim_dcache.c
  46. 58 80
      LibOS/shim/src/fs/shim_fs.c
  47. 47 22
      LibOS/shim/src/fs/shim_namei.c
  48. 5 1
      LibOS/shim/src/fs/socket/fs.c
  49. 6 2
      LibOS/shim/src/fs/str/fs.c
  50. 44 67
      LibOS/shim/src/ipc/shim_ipc.c
  51. 28 4
      LibOS/shim/src/ipc/shim_ipc_child.c
  52. 1 1
      LibOS/shim/src/ipc/shim_ipc_helper.c
  53. 38 15
      LibOS/shim/src/shim.lds
  54. 1 1
      LibOS/shim/src/shim_async.c
  55. 519 383
      LibOS/shim/src/shim_checkpoint.c
  56. 38 29
      LibOS/shim/src/shim_debug.c
  57. 56 66
      LibOS/shim/src/shim_init.c
  58. 13 15
      LibOS/shim/src/shim_parser.c
  59. 12 11
      LibOS/shim/src/shim_syscalls.c
  60. 8 1
      LibOS/shim/src/start.S
  61. 1 1
      LibOS/shim/src/sys/shim_alarm.c
  62. 14 18
      LibOS/shim/src/sys/shim_brk.c
  63. 3 3
      LibOS/shim/src/sys/shim_clone.c
  64. 0 1
      LibOS/shim/src/sys/shim_dup.c
  65. 14 3
      LibOS/shim/src/sys/shim_epoll.c
  66. 129 59
      LibOS/shim/src/sys/shim_exec.c
  67. 5 1
      LibOS/shim/src/sys/shim_exit.c
  68. 4 3
      LibOS/shim/src/sys/shim_fcntl.c
  69. 19 36
      LibOS/shim/src/sys/shim_fork.c
  70. 3 1
      LibOS/shim/src/sys/shim_fs.c
  71. 3 1
      LibOS/shim/src/sys/shim_getcwd.c
  72. 75 112
      LibOS/shim/src/sys/shim_migrate.c
  73. 7 6
      LibOS/shim/src/sys/shim_open.c
  74. 6 1
      LibOS/shim/src/sys/shim_pipe.c
  75. 49 32
      LibOS/shim/src/sys/shim_poll.c
  76. 7 7
      LibOS/shim/src/sys/shim_sigaction.c
  77. 29 36
      LibOS/shim/src/sys/shim_socket.c
  78. 7 6
      LibOS/shim/src/sys/shim_time.c
  79. 1 0
      LibOS/shim/src/sys/shim_vfork.c
  80. 4 0
      LibOS/shim/src/sys/shim_wait.c
  81. 3 3
      LibOS/shim/test/Makefile
  82. 19 8
      LibOS/shim/test/apps/Makefile
  83. 17 16
      LibOS/shim/test/apps/apache/Makefile
  84. 2 2
      LibOS/shim/test/apps/bash/Makefile
  85. 10 12
      LibOS/shim/test/apps/bash/bash_test.sh
  86. 7 6
      LibOS/shim/test/apps/bash/unixbench.sh
  87. 3 3
      LibOS/shim/test/apps/busybox/Makefile
  88. 18 22
      LibOS/shim/test/apps/gcc/Makefile
  89. BIN
      LibOS/shim/test/apps/gcc/gcc-4.8.4.tar.bz2
  90. 4 4
      LibOS/shim/test/apps/gcc/gcc-local.manifest.template
  91. BIN
      LibOS/shim/test/apps/gcc/gmp-4.3.2.tar.bz2
  92. BIN
      LibOS/shim/test/apps/gcc/gmp-5.0.2.tar.bz2
  93. BIN
      LibOS/shim/test/apps/gcc/gmp-5.1.3.tar.bz2
  94. BIN
      LibOS/shim/test/apps/gcc/mpc-0.8.1.tar.gz
  95. BIN
      LibOS/shim/test/apps/gcc/mpc-1.0.1.tar.gz
  96. BIN
      LibOS/shim/test/apps/gcc/mpfr-2.4.2.tar.bz2
  97. BIN
      LibOS/shim/test/apps/gcc/mpfr-3.1.2.tar.bz2
  98. BIN
      LibOS/shim/test/apps/gcc/ppl-0.10.2.tar.gz
  99. BIN
      LibOS/shim/test/apps/gcc/ppl-1.1.tar.gz
  100. 11 11
      LibOS/shim/test/apps/lighttpd/Makefile

+ 1 - 0
LibOS/.packed/glibc.sha384

@@ -0,0 +1 @@
+build/crt1.o build/crti.o build/crtn.o build/ld-linux-x86-64.so.2 build/libc.so.6 build/libdl.so.2 build/liblibos.so.1 build/libm.so.6 build/libpthread.so.0 build/libutil.so.1

BIN
LibOS/.packed/glibc.tar.gz


+ 8 - 8
LibOS/Makefile

@@ -1,24 +1,24 @@
 SYS ?= $(shell gcc -dumpmachine)
 export SYS
 
-GLIBC_SRC = glibc-2.17
+GLIBC_SRC = glibc-2.19
 SHIM_DIR = shim
 BUILD_DIR = build
 GLIBC_TARGET = $(addprefix $(BUILD_DIR)/,libc.so.6 ld-linux-x86-64.so.2 libpthread.so.0 libm.so.6 libdl.so.2 libutil.so.1 crt1.o crti.o crtn.o liblibos.so.1)
 
 all: $(GLIBC_TARGET)
-	make -C $(SHIM_DIR) all
+	$(MAKE) -C $(SHIM_DIR) all
 
 debug: DEBUG=debug
 debug: $(GLIBC_TARGET)
-	make -C $(SHIM_DIR) debug
+	$(MAKE) -C $(SHIM_DIR) debug
 
 # nothing to install
 install:
 
 ifeq ($(SYS),x86_64-linux-gnu)
 $(GLIBC_TARGET): $(BUILD_DIR)/Makefile
-	cd $(BUILD_DIR) && make
+	cd $(BUILD_DIR) && $(MAKE)
 
 $(BUILD_DIR)/Makefile: $(GLIBC_SRC)/configure
 	./buildglibc.py --quiet $(DEBUG)
@@ -31,15 +31,15 @@ $(GLIBC_SRC)/configure:
 
 .PHONY: pack
 pack: $(GLIBC_TARGET)
-	tar -chzf .packed/glibc.tar.gz $^
-	make -C $(SHIM_DIR) pack
+	@../Scripts/pack_binaries.sh glibc $^
+	$(MAKE) -C $(SHIM_DIR) pack
 
 clean:
-	make -C $(SHIM_DIR) clean
+	$(MAKE) -C $(SHIM_DIR) clean
 	rm -rf $(BUILD_DIR)
 else
 $(GLIBC_TARGET): .packed/glibc.tar.gz
-	tar -xmozf $<
+	tar -xmozf $< $@
 
 clean:
 	rm -rf $(BUILD_DIR)

+ 2 - 2
LibOS/buildglibc.py

@@ -26,9 +26,9 @@ def appendText(filename, text) :
 
 try:
     home = os.getcwd()
-    glibc = "glibc-2.17"
+    glibc = "glibc-2.19"
     glibcParent = "" # glibc parent directory
-    glibcDir = ""    # glibc dir (ex. glibc-2.17)
+    glibcDir = ""    # glibc dir (ex. glibc-2.19)
     buildDir = "build"
     installDir = "/usr/local/graphene"
     commandStr = ""

+ 1845 - 0
LibOS/glibc-2.19.patch

@@ -0,0 +1,1845 @@
+diff --git a/Makeconfig b/Makeconfig
+index 1908f27..cf34ba1 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -775,7 +775,8 @@ endif	# $(+cflags) == ""
+ # current directory.
+ +includes = -I$(..)include $(if $(subdir),$(objpfx:%/=-I%)) \
+ 	    $(+sysdep-includes) $(includes) \
+-	    $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes)
++	    $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes) \
++	    -I$(common-objpfx)../shim/include
+ 
+ # Since libio has several internal header files, we use a -I instead
+ # of many little headers in the include directory.
+@@ -1033,7 +1034,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
+ 	      grp pwd posix io termios resource misc socket sysvipc gmon    \
+ 	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
+ 	      crypt localedata timezone rt conform debug		    \
+-	      $(add-on-subdirs) dlfcn elf
++	      $(add-on-subdirs) dlfcn elf libos
+ 
+ ifndef avoid-generated
+ # sysd-sorted itself will contain rules making the sysd-sorted target
+diff --git a/Makefile b/Makefile
+index 51d4690..d72c4b0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -177,6 +177,8 @@ $(inst_includedir)/gnu/stubs.h: $(+force)
+ install-others-nosubdir: $(installed-stubs)
+ endif
+ 
++# For Graphene
++CFLAGS-syscalldb.c = -fPIC
+ 
+ # Since stubs.h is never needed when building the library, we simplify the
+ # hairy installation process by producing it in place only as the last part
+diff --git a/Versions.def b/Versions.def
+index 759c754..e1a270e 100644
+--- a/Versions.def
++++ b/Versions.def
+@@ -41,6 +41,7 @@ libc {
+   GCC_3.0
+ %endif
+   GLIBC_PRIVATE
++  SHIM
+ }
+ libcrypt {
+   GLIBC_2.0
+@@ -50,6 +51,7 @@ libdl {
+   GLIBC_2.1
+   GLIBC_2.3.3
+   GLIBC_2.3.4
++  SHIM
+ }
+ libm {
+   GLIBC_2.0
+@@ -108,6 +110,7 @@ libpthread {
+   GLIBC_2.18
+   GLIBC_2.19
+   GLIBC_PRIVATE
++  SHIM
+ }
+ libresolv {
+   GLIBC_2.0
+@@ -135,6 +138,7 @@ ld {
+   GLIBC_2.3
+   GLIBC_2.4
+   GLIBC_PRIVATE
++  SHIM
+ }
+ libthread_db {
+   GLIBC_2.1.3
+@@ -148,3 +152,6 @@ libanl {
+ libcidn {
+   GLIBC_PRIVATE
+ }
++liblibos {
++  GLIBC_2.12
++}
+diff --git a/configure b/configure
+index fc023d0..b71c1f9 100755
+--- a/configure
++++ b/configure
+@@ -630,7 +630,8 @@ SED
+ MAKEINFO
+ MSGFMT
+ MAKE
+-LD
++LD_GOLD
++LD_BFD
+ AS
+ OBJCOPY
+ OBJDUMP
+@@ -4593,17 +4594,22 @@ if test $ac_verc_fail = yes; then
+   AS=: critic_missing="$critic_missing as"
+ fi
+ 
+-for ac_prog in $LD
++LD_BFD=
++LD_GOLD=
++ld_is_gold="`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"
++if test -z "$ld_is_gold"; then
++  LD_BFD=$LD
++  for ac_prog in $LD_BFD
+ do
+   # Extract the first word of "$ac_prog", so it can be a program name with args.
+ set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_LD+:} false; then :
++if ${ac_cv_prog_LD_BFD+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+-  if test -n "$LD"; then
+-  ac_cv_prog_LD="$LD" # Let the user override the test.
++  if test -n "$LD_BFD"; then
++  ac_cv_prog_LD_BFD="$LD_BFD" # Let the user override the test.
+ else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+@@ -4612,7 +4618,7 @@ do
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_LD="$ac_prog"
++    ac_cv_prog_LD_BFD="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -4622,26 +4628,26 @@ IFS=$as_save_IFS
+ 
+ fi
+ fi
+-LD=$ac_cv_prog_LD
+-if test -n "$LD"; then
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+-$as_echo "$LD" >&6; }
++LD_BFD=$ac_cv_prog_LD_BFD
++if test -n "$LD_BFD"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD_BFD" >&5
++$as_echo "$LD_BFD" >&6; }
+ else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ fi
+ 
+ 
+-  test -n "$LD" && break
++  test -n "$LD_BFD" && break
+ done
+ 
+-if test -z "$LD"; then
++if test -z "$LD_BFD"; then
+   ac_verc_fail=yes
+ else
+   # Found it, now check the version.
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5
+-$as_echo_n "checking version of $LD... " >&6; }
+-  ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD_BFD" >&5
++$as_echo_n "checking version of $LD_BFD... " >&6; }
++  ac_prog_version=`$LD_BFD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
+   case $ac_prog_version in
+     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+     2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*)
+@@ -4653,9 +4659,80 @@ $as_echo_n "checking version of $LD... " >&6; }
+ $as_echo "$ac_prog_version" >&6; }
+ fi
+ if test $ac_verc_fail = yes; then
+-  LD=: critic_missing="$critic_missing ld"
++  LD_BFD=:
+ fi
+ 
++else
++# Accept gold 1.11 or higher.
++  LD_GOLD=$LD
++  for ac_prog in $LD_GOLD
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_LD_GOLD+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$LD_GOLD"; then
++  ac_cv_prog_LD_GOLD="$LD_GOLD" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_LD_GOLD="$ac_prog"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++LD_GOLD=$ac_cv_prog_LD_GOLD
++if test -n "$LD_GOLD"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD_GOLD" >&5
++$as_echo "$LD_GOLD" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++  test -n "$LD_GOLD" && break
++done
++
++if test -z "$LD_GOLD"; then
++  ac_verc_fail=yes
++else
++  # Found it, now check the version.
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD_GOLD" >&5
++$as_echo_n "checking version of $LD_GOLD... " >&6; }
++  ac_prog_version=`$LD_GOLD --version 2>&1 | sed -n 's/^.*GNU gold.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
++  case $ac_prog_version in
++    '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
++    1.1[1-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*)
++       ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
++    *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
++
++  esac
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5
++$as_echo "$ac_prog_version" >&6; }
++fi
++if test $ac_verc_fail = yes; then
++  LD_GOLD=:
++fi
++
++fi
++# Neither ld nor gold are new enough.
++if test -z "$LD_BFD" && test -z "$LD_GOLD"; then
++  critic_missing="$critic_missing ld"
++fi
+ 
+ # These programs are version sensitive.
+ 
+@@ -6391,6 +6468,16 @@ $as_echo "$libc_cv_use_default_link" >&6; }
+   use_default_link=$libc_cv_use_default_link
+ fi
+ 
++# The gold linker has no builtin default linker script,
++# and the fallback of editing the builtin linker
++# script is not available. Therefore if use_default_link
++# is `no' then we can't use gold. This check is independent
++# of gold's version and is used to sanity check that the
++# linker continues to produce a useful shared link.
++if test "$ld_is_gold" && test "$use_default_link" = "no"; then
++  as_fn_error $? "$LD did not generate a useful shared link. Try using GNU ld.bfd?" "$LINENO" 5
++fi
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5
+ $as_echo_n "checking linker output format... " >&6; }
+ if ${libc_cv_output_format+:} false; then :
+@@ -6409,6 +6496,17 @@ fi
+ $as_echo "$libc_cv_output_format" >&6; }
+ 
+ 
++# The gold linker has no builtin default linker script,
++# and the fallback of parsing the builtin linker
++# script to determine the target is not available.
++# Therefore if libc_cv_output_format is `unknown' then
++# we can't use gold. This check is independent of gold's
++# version and is used to sanity check that the linker
++# continues to support --print-output-format.
++if test "$ld_is_gold" && test "$libc_cv_output_format" = "unknown"; then
++  as_fn_error $? "$LD did not support --print-output-format. Try using GNU ld.bfd?" "$LINENO" 5
++fi
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-toplevel-reorder -fno-section-anchors" >&5
+ $as_echo_n "checking for -fno-toplevel-reorder -fno-section-anchors... " >&6; }
+ if ${libc_cv_fno_toplevel_reorder+:} false; then :
+diff --git a/dlfcn/Versions b/dlfcn/Versions
+index 97902f0..c1874c1 100644
+--- a/dlfcn/Versions
++++ b/dlfcn/Versions
+@@ -14,4 +14,7 @@ libdl {
+   GLIBC_PRIVATE {
+     _dlfcn_hook;
+   }
++  SHIM {
++    syscalldb;
++  }
+ }
+diff --git a/elf/Makefile b/elf/Makefile
+index 4c58fc9..0ae2fa8 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -21,7 +21,7 @@ subdir		:= elf
+ 
+ include ../Makeconfig
+ 
+-headers		= elf.h bits/elfclass.h link.h bits/link.h
++headers		= elf.h bits/elfclass.h link.h bits/link.h syscalldb.h
+ routines	= $(dl-routines) dl-support dl-iteratephdr \
+ 		  dl-addr enbl-secure dl-profstub \
+ 		  dl-origin dl-libc dl-sym dl-tsd dl-sysdep
+@@ -31,7 +31,8 @@ routines	= $(dl-routines) dl-support dl-iteratephdr \
+ dl-routines	= $(addprefix dl-,load lookup object reloc deps hwcaps \
+ 				  runtime error init fini debug misc \
+ 				  version profile conflict tls origin scope \
+-				  execstack caller open close trampoline)
++				  execstack caller open close trampoline) \
++		  syscalldb syscallas
+ ifeq (yes,$(use-ldconfig))
+ dl-routines += dl-cache
+ endif
+diff --git a/elf/Versions b/elf/Versions
+index 2383992..03fbd38 100644
+--- a/elf/Versions
++++ b/elf/Versions
+@@ -24,14 +24,15 @@ libc {
+     _dl_sym; _dl_vsym;
+     __libc_dlclose; __libc_dlopen_mode; __libc_dlsym;
+   }
++  SHIM {
++    syscalldb;
++  }
+ }
+ 
+ ld {
+   GLIBC_2.0 {
+     # Function from libc.so which must be shared with libc.
+     __libc_memalign; calloc; free; malloc; realloc;
+-
+-    _r_debug;
+   }
+   GLIBC_2.1 {
+     # functions used in other libraries
+@@ -57,9 +58,12 @@ ld {
+     _rtld_global; _rtld_global_ro;
+ 
+     # Only here for gdb while a better method is developed.
+-    _dl_debug_state;
++    __libc_r_debug; __libc_dl_debug_state;
+ 
+     # Pointer protection.
+     __pointer_chk_guard;
+   }
++  SHIM {
++    syscalldb; glibc_vers_2_17; register_library;
++  }
+ }
+diff --git a/elf/circleload1.c b/elf/circleload1.c
+index 990ff84..ccf92d3 100644
+--- a/elf/circleload1.c
++++ b/elf/circleload1.c
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ static int
+ check_loaded_objects (const char **loaded)
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 5bf1de7..a887133 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -473,7 +473,7 @@ _dl_close_worker (struct link_map *map)
+   /* Notify the debugger we are about to remove some loaded objects.  */
+   struct r_debug *r = _dl_debug_initialize (0, nsid);
+   r->r_state = RT_DELETE;
+-  _dl_debug_state ();
++  __libc_dl_debug_state ();
+   LIBC_PROBE (unmap_start, 2, nsid, r);
+ 
+   if (unload_global)
+@@ -739,7 +739,7 @@ _dl_close_worker (struct link_map *map)
+ 
+   /* Notify the debugger those objects are finalized and gone.  */
+   r->r_state = RT_CONSISTENT;
+-  _dl_debug_state ();
++  __libc_dl_debug_state ();
+   LIBC_PROBE (unmap_complete, 2, nsid, r);
+ 
+   /* Recheck if we need to retry, release the lock.  */
+diff --git a/elf/dl-debug.c b/elf/dl-debug.c
+index 4e7c593..3e0bff4 100644
+--- a/elf/dl-debug.c
++++ b/elf/dl-debug.c
+@@ -34,7 +34,7 @@ extern const int verify_link_map_members[(VERIFY_MEMBER (l_addr)
+    normally finds it via the DT_DEBUG entry in the dynamic section, but in
+    a statically-linked program there is no dynamic section for the debugger
+    to examine and it looks for this particular symbol name.  */
+-struct r_debug _r_debug;
++struct r_debug __libc_r_debug __attribute__((weak));
+ 
+ 
+ /* Initialize _r_debug if it has not already been done.  The argument is
+@@ -48,7 +48,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
+   struct r_debug *r;
+ 
+   if (ns == LM_ID_BASE)
+-    r = &_r_debug;
++    r = &__libc_r_debug;
+   else
+     r = &GL(dl_ns)[ns]._ns_debug;
+ 
+@@ -56,9 +56,9 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
+     {
+       /* Tell the debugger where to find the map of loaded objects.  */
+       r->r_version = 1	/* R_DEBUG_VERSION XXX */;
+-      r->r_ldbase = ldbase ?: _r_debug.r_ldbase;
++      r->r_ldbase = ldbase ?: __libc_r_debug.r_ldbase;
+       r->r_map = (void *) GL(dl_ns)[ns]._ns_loaded;
+-      r->r_brk = (ElfW(Addr)) &_dl_debug_state;
++      r->r_brk = (ElfW(Addr)) &__libc_dl_debug_state;
+     }
+ 
+   return r;
+@@ -70,7 +70,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
+    examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks
+    for this particular symbol name in the PT_INTERP file.  */
+ void
+-_dl_debug_state (void)
++__libc_dl_debug_state (void)
+ {
+ }
+-rtld_hidden_def (_dl_debug_state)
++__attribute__((weak));
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 1be7a3c..c560ec1 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -39,6 +39,8 @@
+ 
+ #include <dl-dst.h>
+ 
++#include <glibc-version.h>
++
+ /* On some systems, no flag bits are given to specify file mapping.  */
+ #ifndef MAP_FILE
+ # define MAP_FILE	0
+@@ -902,7 +904,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
+   if (r != NULL)
+     {
+       r->r_state = RT_CONSISTENT;
+-      _dl_debug_state ();
++      __libc_dl_debug_state ();
+       LIBC_PROBE (map_failed, 2, nsid, r);
+     }
+ 
+@@ -1048,7 +1050,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
+ 	 call _dl_debug_initialize in a static program in case dynamic
+ 	 linking has not been used before.  */
+       r->r_state = RT_ADD;
+-      _dl_debug_state ();
++      __libc_dl_debug_state ();
+       LIBC_PROBE (map_start, 2, nsid, r);
+       make_consistent = true;
+     }
+@@ -1595,6 +1597,9 @@ cannot enable executable stack as shared object requires");
+   DL_AFTER_LOAD (l);
+ #endif
+ 
++  /* register the library to SHIM */
++  register_library(l->l_name, l->l_addr);
++
+   /* Now that the object is fully initialized add it to the object list.  */
+   _dl_add_to_namespace_list (l, nsid);
+ 
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index a9ca6b3..829d212 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -290,7 +290,7 @@ dl_open_worker (void *a)
+   /* Notify the debugger all new objects are now ready to go.  */
+   struct r_debug *r = _dl_debug_initialize (0, args->nsid);
+   r->r_state = RT_CONSISTENT;
+-  _dl_debug_state ();
++  __libc_dl_debug_state ();
+   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
+ 
+   /* Print scope information.  */
+diff --git a/elf/link.h b/elf/link.h
+index d5905d1..f4e108a 100644
+--- a/elf/link.h
++++ b/elf/link.h
+@@ -64,7 +64,7 @@ struct r_debug
+   };
+ 
+ /* This is the instance of that structure used by the dynamic linker.  */
+-extern struct r_debug _r_debug;
++extern struct r_debug __libc_r_debug;
+ 
+ /* This symbol refers to the "dynamic structure" in the `.dynamic' section
+    of whatever module refers to `_DYNAMIC'.  So, to find its own
+diff --git a/elf/loadtest.c b/elf/loadtest.c
+index 727469b..568ddef 100644
+--- a/elf/loadtest.c
++++ b/elf/loadtest.c
+@@ -70,7 +70,7 @@ static const struct
+ 
+ #include <include/link.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ #define OUT \
+   for (map = MAPS; map != NULL; map = map->l_next)		      \
+diff --git a/elf/neededtest.c b/elf/neededtest.c
+index 3cea499..e098d48 100644
+--- a/elf/neededtest.c
++++ b/elf/neededtest.c
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ static int
+ check_loaded_objects (const char **loaded)
+diff --git a/elf/neededtest2.c b/elf/neededtest2.c
+index 17c75f2..5a73a95 100644
+--- a/elf/neededtest2.c
++++ b/elf/neededtest2.c
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ static int
+ check_loaded_objects (const char **loaded)
+diff --git a/elf/neededtest3.c b/elf/neededtest3.c
+index 41970cf..5126615 100644
+--- a/elf/neededtest3.c
++++ b/elf/neededtest3.c
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ static int
+ check_loaded_objects (const char **loaded)
+diff --git a/elf/neededtest4.c b/elf/neededtest4.c
+index 0ae0b7f..f883910 100644
+--- a/elf/neededtest4.c
++++ b/elf/neededtest4.c
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ static int
+ check_loaded_objects (const char **loaded)
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 6dcbabc..431120a 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -356,6 +356,23 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
+   return start_addr;
+ }
+ 
++/* For graphene, check if glibc version match to the compatible SHIM
++   library. If not, tell the user to update glibc. */
++#include "glibc-version.h"
++
++volatile const int glibc_vers_2_17 __attribute__((weak)) = GLIBC_VERSION_2_17;
++
++static void __attribute__((noinline,optimize("-O0")))
++check_glibc_version (void)
++{
++  if (glibc_vers_2_17 != GLIBC_VERSION_2_17)
++    {
++      _dl_fatal_printf ("Warning from Graphene: "
++			"Glibc version is incorrect. Please rebuild Glibc.\n");
++      _exit (1);
++    }
++}
++
+ static ElfW(Addr) __attribute_used__ internal_function
+ _dl_start (void *arg)
+ {
+@@ -546,6 +563,9 @@ _dl_start (void *arg)
+      therefore need not test whether we have to allocate the array
+      for the relocation results (as done in dl-reloc.c).  */
+ 
++  /* For Graphene, check if the glibc version is correct. */
++  check_glibc_version();
++
+   /* Now life is sane; we can call functions and access global data.
+      Set up to use the operating system facilities, and find out from
+      the operating system's program loader where to find the program
+@@ -1233,9 +1253,20 @@ of this helper program; chances are you did not intend to run this program.\n\
+ 	    main_map->l_map_end = allocend;
+ 	  if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end)
+ 	    main_map->l_text_end = allocend;
++
++#if 0
++	  ElfW(Addr) mapend = (allocend + GLRO(dl_pagesize) - 1)
++		               & ~(GLRO(dl_pagesize) - 1);
++	  int prot = ((ph->p_flags & PF_R) ? PROT_READ  : 0)|
++	             ((ph->p_flags & PF_W) ? PROT_WRITE : 0)|
++	             ((ph->p_flags & PF_X) ? PROT_EXEC  : 0);
++	  __mmap ((void *) mapstart, mapend - mapstart,
++		  prot,
++		  MAP_ANON|MAP_PRIVATE|MAP_FIXED|0x20000000,
++		  -1, 0);
++#endif
+ 	}
+ 	break;
+-
+       case PT_TLS:
+ 	if (ph->p_memsz > 0)
+ 	  {
+@@ -1381,13 +1412,31 @@ of this helper program; chances are you did not intend to run this program.\n\
+   /* PT_GNU_RELRO is usually the last phdr.  */
+   size_t cnt = rtld_ehdr->e_phnum;
+   while (cnt-- > 0)
++  {
+     if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
+       {
+ 	GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr;
+ 	GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz;
+-	break;
+       }
+ 
++#if 0
++    if (rtld_phdr[cnt].p_type == PT_LOAD)
++      {
++	ElfW(Addr) mapstart = rtld_phdr[cnt].p_vaddr & ~(GLRO(dl_pagesize) - 1);
++	ElfW(Addr) mapend = (rtld_phdr[cnt].p_vaddr + rtld_phdr[cnt].p_memsz
++		             + GLRO(dl_pagesize) - 1)
++		             & ~(GLRO(dl_pagesize) - 1);
++	int prot = ((rtld_phdr[cnt].p_flags & PF_R) ? PROT_READ  : 0)|
++	           ((rtld_phdr[cnt].p_flags & PF_W) ? PROT_WRITE : 0)|
++	           ((rtld_phdr[cnt].p_flags & PF_X) ? PROT_EXEC  : 0);
++	__mmap ((void *) mapstart, mapend - mapstart,
++		prot,
++		MAP_ANON|MAP_PRIVATE|MAP_FIXED|0x20000000,
++		-1, 0);
++      }
++#endif
++  }
++
+   /* Add the dynamic linker to the TLS list if it also uses TLS.  */
+   if (GL(dl_rtld_map).l_tls_blocksize != 0)
+     /* Assign a module ID.  Do this before loading any audit modules.  */
+@@ -1588,7 +1637,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ 
+   /* We start adding objects.  */
+   r->r_state = RT_ADD;
+-  _dl_debug_state ();
++  __libc_dl_debug_state ();
+   LIBC_PROBE (init_start, 2, LM_ID_BASE, r);
+ 
+   /* Auditing checkpoint: we are ready to signal that the initial map
+@@ -2301,7 +2350,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+      the address since by now the variable might be in another object.  */
+   r = _dl_debug_initialize (0, LM_ID_BASE);
+   r->r_state = RT_CONSISTENT;
+-  _dl_debug_state ();
++  __libc_dl_debug_state ();
+   LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
+ 
+ #if defined USE_LDCONFIG && !defined MAP_COPY
+diff --git a/elf/unload.c b/elf/unload.c
+index 4566f22..73046de 100644
+--- a/elf/unload.c
++++ b/elf/unload.c
+@@ -9,7 +9,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ #define OUT \
+   for (map = MAPS; map != NULL; map = map->l_next)			      \
+diff --git a/elf/unload2.c b/elf/unload2.c
+index eef2bfd..a21d2ac 100644
+--- a/elf/unload2.c
++++ b/elf/unload2.c
+@@ -6,7 +6,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+-#define MAPS ((struct link_map *) _r_debug.r_map)
++#define MAPS ((struct link_map *) __libc_r_debug.r_map)
+ 
+ #define OUT \
+   for (map = MAPS; map != NULL; map = map->l_next)			      \
+diff --git a/nptl/Makefile b/nptl/Makefile
+index 57cc8c6..81f1bf4 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -20,7 +20,7 @@
+ #
+ subdir	:= nptl
+ 
+-headers := pthread.h semaphore.h bits/semaphore.h
++headers := pthread.h semaphore.h bits/semaphore.h syscalldb.h
+ 
+ extra-libs := libpthread
+ extra-libs-others := $(extra-libs)
+diff --git a/nptl/Versions b/nptl/Versions
+index bb11277..4480543 100644
+--- a/nptl/Versions
++++ b/nptl/Versions
+@@ -31,6 +31,9 @@ libc {
+     # Internal libc interface to libpthread
+     __libc_dl_error_tsd;
+   }
++  SHIM {
++    syscalldb;
++  }
+ }
+ 
+ libpthread {
+@@ -262,4 +265,8 @@ libpthread {
+     __pthread_clock_gettime; __pthread_clock_settime;
+     __pthread_unwind; __pthread_get_minstack;
+   }
++
++  SHIM {
++    syscalldb;
++  }
+ }
+diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
+index 9d7f52f..72d50ae 100644
+--- a/nptl/pthread_create.c
++++ b/nptl/pthread_create.c
+@@ -405,8 +405,11 @@ start_thread (void *arg)
+ # error "to do"
+ #endif
+   assert (freesize < pd->stackblock_size);
++  /* XXX: may not be necessary */
++#if 0
+   if (freesize > PTHREAD_STACK_MIN)
+     __madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
++#endif
+ 
+   /* If the thread is detached free the TCB.  */
+   if (IS_DETACHED (pd))
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+index 89fda5e..594dd72 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+@@ -111,7 +111,8 @@ ENTRY(__pthread_disable_asynccancel)
+ 	xorq	%r10, %r10
+ 	addq	$CANCELHANDLING, %rdi
+ 	LOAD_PRIVATE_FUTEX_WAIT (%esi)
+-	syscall
++	SYSCALL
++
+ 	movl	%fs:CANCELHANDLING, %eax
+ 	jmp	3b
+ END(__pthread_disable_asynccancel)
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c b/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
+index a036b92..40a1eaf 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
+@@ -21,10 +21,20 @@
+ #include <sysdep.h>
+ #include <tls.h>
+ 
+-
+-#define ARCH_FORK() \
++/* In Graphene, we prefer to call fork system call directly than clone */
++#if USE_clone_FOR_fork
++# define ARCH_FORK() \
+   INLINE_SYSCALL (clone, 4,						      \
+ 		  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+ 		  NULL, &THREAD_SELF->tid)
++#else
++# define ARCH_FORK() \
++ ({ unsigned long ret = INLINE_SYSCALL (fork, 0);	\
++    if (!ret) {						\
++	pid_t pid = INLINE_SYSCALL (getpid, 0);		\
++	THREAD_SETMEM (THREAD_SELF, pid, pid);		\
++	THREAD_SETMEM (THREAD_SELF, tid, pid);		\
++    } ret; })
++#endif
+ 
+ #include "../fork.c"
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+index f2dca07..e5b3f2f 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+@@ -90,7 +90,7 @@ __lll_lock_wait_private:
+ 
+ 1:	LIBC_PROBE (lll_lock_wait_private, 1, %rdi)
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 2:	movl	%edx, %eax
+ 	xchgl	%eax, (%rdi)	/* NB:	 lock is implied */
+@@ -130,7 +130,7 @@ __lll_lock_wait:
+ 
+ 1:	LIBC_PROBE (lll_lock_wait, 2, %rdi, %rsi)
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 2:	movl	%edx, %eax
+ 	xchgl	%eax, (%rdi)	/* NB:	 lock is implied */
+@@ -185,7 +185,7 @@ __lll_timedlock_wait:
+ 
+ 1:	movl	$SYS_futex, %eax
+ 	movl	$2, %edx
+-	syscall
++	SYSCALL
+ 
+ 2:	xchgl	%edx, (%rdi)	/* NB:   lock is implied */
+ 
+@@ -279,7 +279,7 @@ __lll_timedlock_wait:
+ 	LOAD_FUTEX_WAIT (%esi)
+ 	movq	%r12, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* NB: %edx == 2 */
+ 	xchgl	%edx, (%r12)
+@@ -336,7 +336,7 @@ __lll_unlock_wake_private:
+ 	LOAD_PRIVATE_FUTEX_WAKE (%esi)
+ 	movl	$1, %edx	/* Wake one thread.  */
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	popq	%rdx
+ 	cfi_adjust_cfa_offset(-8)
+@@ -366,7 +366,7 @@ __lll_unlock_wake:
+ 	LOAD_FUTEX_WAKE (%esi)
+ 	movl	$1, %edx	/* Wake one thread.  */
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	popq	%rdx
+ 	cfi_adjust_cfa_offset(-8)
+@@ -435,7 +435,7 @@ __lll_timedwait_tid:
+ #endif
+ 	movq	%r12, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	cmpl	$0, (%rdi)
+ 	jne	1f
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+index 0a26739..8aae14a 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+@@ -214,7 +214,7 @@ LLL_STUB_UNWIND_INFO_END
+     register const struct timespec *__to __asm ("r10") = timeout;	      \
+     int __status;							      \
+     register __typeof (val) _val __asm ("edx") = (val);			      \
+-    __asm __volatile ("syscall"						      \
++    __asm __volatile (SYSCALLDB						      \
+ 		      : "=a" (__status)					      \
+ 		      : "0" (SYS_futex), "D" (futex),			      \
+ 			"S" (__lll_private_flag (FUTEX_WAIT, private)),	      \
+@@ -229,7 +229,7 @@ LLL_STUB_UNWIND_INFO_END
+     int __status;							      \
+     register __typeof (nr) _nr __asm ("edx") = (nr);			      \
+     LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
+-    __asm __volatile ("syscall"						      \
++    __asm __volatile (SYSCALLDB						      \
+ 		      : "=a" (__status)					      \
+ 		      : "0" (SYS_futex), "D" (futex),			      \
+ 			"S" (__lll_private_flag (FUTEX_WAKE, private)),	      \
+@@ -540,7 +540,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count,
+     {									      \
+       int ignore;							      \
+       __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t"			      \
+-			"syscall"					      \
++			SYSCALLDB					      \
+ 			: "=m" (futex), "=a" (ignore)			      \
+ 			: "D" (&(futex)), "i" (FUTEX_OWNER_DIED),	      \
+ 			  "S" (__lll_private_flag (FUTEX_WAKE, private)),     \
+@@ -555,7 +555,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count,
+      register int __nr_move __asm ("r10") = nr_move;			      \
+      register void *__mutex __asm ("r8") = mutex;			      \
+      register int __val __asm ("r9") = val;				      \
+-     __asm __volatile ("syscall"					      \
++     __asm __volatile (SYSCALLDB					      \
+ 		       : "=a" (__res)					      \
+ 		       : "0" (__NR_futex), "D" ((void *) ftx),		      \
+ 			 "S" (__lll_private_flag (FUTEX_CMP_REQUEUE,	      \
+@@ -581,7 +581,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count,
+     if (_tid != 0)							      \
+       __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
+ 			"1:\tmovq %2, %%rax\n\t"			      \
+-			"syscall\n\t"					      \
++			SYSCALLDB					      \
+ 			"cmpl $0, (%%rdi)\n\t"				      \
+ 			"jne 1b"					      \
+ 			: "=&a" (__ignore)				      \
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+index 990b6f9..89dbe32 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+@@ -80,7 +80,7 @@ __lll_robust_lock_wait:
+ 	jnz	2f
+ 
+ 1:	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	movl	(%rdi), %eax
+ 
+@@ -145,7 +145,7 @@ __lll_robust_timedlock_wait:
+ 	jnz	6f
+ 
+ 5:	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	movl	%eax, %ecx
+ 
+ 	movl	(%rdi), %eax
+@@ -257,7 +257,7 @@ __lll_robust_timedlock_wait:
+ 	LOAD_FUTEX_WAIT (%esi)
+ 	movq	%r12, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	movq	%rax, %rcx
+ 
+ 	movl	(%r12), %eax
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+index eec17f2..4472960 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+@@ -62,7 +62,7 @@ pthread_barrier_wait:
+ #endif
+ 	xorq	%r10, %r10
+ 8:	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* Don't return on spurious wakeups.  The syscall does not change
+ 	   any register except %eax so there is no need to reload any of
+@@ -109,7 +109,7 @@ pthread_barrier_wait:
+ 	movl	$FUTEX_WAKE, %esi
+ 	orl	PRIVATE(%rdi), %esi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* Increment LEFT.  If this brings the count back to the
+ 	   initial count unlock the object.  */
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+index 985e0f1..f180ab1 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+@@ -90,7 +90,7 @@ __pthread_cond_broadcast:
+ 	movl	$SYS_futex, %eax
+ 	movl	$1, %edx
+ 	movl	$0x7fffffff, %r10d
+-	syscall
++	SYSCALL
+ 
+ 	/* For any kind of error, which mainly is EAGAIN, we try again
+ 	   with WAKE.  The general test also covers running on old
+@@ -106,7 +106,7 @@ __pthread_cond_broadcast:
+ 	movl	$SYS_futex, %eax
+ 	movl	$1, %edx
+ 	movl	$0x7fffffff, %r10d
+-	syscall
++	SYSCALL
+ 
+ 	/* For any kind of error, which mainly is EAGAIN, we try again
+ 	   with WAKE.  The general test also covers running on old
+@@ -172,7 +172,7 @@ __pthread_cond_broadcast:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	jmp	10b
+ 	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast
+ versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+index 53d65b6..8724325 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+@@ -82,7 +82,7 @@ __pthread_cond_signal:
+ 	addq	$cond_lock, %r8
+ #endif
+ 	movl	$FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
+-	syscall
++	SYSCALL
+ #if cond_lock != 0
+ 	subq	$cond_lock, %r8
+ #endif
+@@ -99,7 +99,7 @@ __pthread_cond_signal:
+ 	movq	%rcx, %r8
+ 	xorq	%r10, %r10
+ 	movl	(%rdi), %r9d	// XXX Can this be right?
+-	syscall
++	SYSCALL
+ 
+ 	leaq	-cond_futex(%rdi), %r8
+ 
+@@ -118,7 +118,7 @@ __pthread_cond_signal:
+ 	movl	$SYS_futex, %eax
+ 	/* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
+ 	movl	$1, %edx  */
+-	syscall
++	SYSCALL
+ 
+ 	/* Unlock.  */
+ 4:	LOCK
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+index 0dc2340..cac13bf 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+@@ -188,7 +188,7 @@ __pthread_cond_timedwait:
+ 	movq	%r12, %rdx
+ 	addq	$cond_futex, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	cmpl	$0, %eax
+ 	sete	%r15b
+@@ -234,7 +234,7 @@ __pthread_cond_timedwait:
+ 	movq	%r12, %rdx
+ 	addq	$cond_futex, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 62:	movq	%rax, %r14
+ 
+ 	movl	(%rsp), %edi
+@@ -321,7 +321,7 @@ __pthread_cond_timedwait:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	subq	$cond_nwaiters, %rdi
+ 
+ 55:	LOCK
+@@ -485,15 +485,8 @@ __pthread_cond_timedwait:
+ 	/* Only clocks 0 and 1 are allowed so far.  Both are handled in the
+ 	   kernel.  */
+ 	leaq	32(%rsp), %rsi
+-#  ifdef SHARED
+-	mov	__vdso_clock_gettime@GOTPCREL(%rip), %RAX_LP
+-	mov	(%rax), %RAX_LP
+-	PTR_DEMANGLE (%RAX_LP)
+-	call	*%rax
+-#  else
+ 	movl	$__NR_clock_gettime, %eax
+-	syscall
+-#  endif
++	SYSCALL
+ 
+ 	/* Compute relative timeout.  */
+ 	movq	(%r13), %rcx
+@@ -560,7 +553,7 @@ __pthread_cond_timedwait:
+ # endif
+ 	addq	$cond_futex, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	movq	%rax, %r14
+ 
+ 	movl	(%rsp), %edi
+@@ -732,7 +725,7 @@ __condvar_cleanup2:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	subq	$cond_nwaiters, %rdi
+ 	movl	$1, %r12d
+ 
+@@ -769,7 +762,7 @@ __condvar_cleanup2:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* Lock the mutex only if we don't own it already.  This only happens
+ 	   in case of PI mutexes, if we got cancelled after a successful
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+index 0e61d0a..60e104b 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+@@ -138,7 +138,7 @@ __pthread_cond_wait:
+ 
+ 	movl	$(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	cmpl	$0, %eax
+ 	sete	%r8b
+@@ -180,7 +180,7 @@ __pthread_cond_wait:
+ #endif
+ 60:	xorb	%r8b, %r8b
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 62:	movl	(%rsp), %edi
+ 	callq	__pthread_disable_asynccancel
+@@ -239,7 +239,7 @@ __pthread_cond_wait:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	subq	$cond_nwaiters, %rdi
+ 
+ 17:	LOCK
+@@ -455,7 +455,7 @@ __condvar_cleanup1:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	subq	$cond_nwaiters, %rdi
+ 	movl	$1, %ecx
+ 
+@@ -493,7 +493,7 @@ __condvar_cleanup1:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* Lock the mutex only if we don't own it already.  This only happens
+ 	   in case of PI mutexes, if we got cancelled after a successful
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+index 2cbe2fa..d4e229a 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+@@ -90,7 +90,7 @@ __pthread_once:
+ # endif
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	jmp	6b
+ 
+ 	/* Preserve the pointer to the control variable.  */
+@@ -123,7 +123,7 @@ __pthread_once:
+ 	orl	%fs:PRIVATE_FUTEX, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 4:	addq	$8, %rsp
+ 	cfi_adjust_cfa_offset(-8)
+@@ -152,7 +152,7 @@ clear_once_control:
+ 	orl	%fs:PRIVATE_FUTEX, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	movq	%r8, %rdi
+ .LcallUR:
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
+index 3bbb4c7..8ebf317 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
+@@ -82,7 +82,7 @@ __pthread_rwlock_rdlock:
+ #endif
+ 	addq	$READERS_WAKEUP, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	subq	$READERS_WAKEUP, %rdi
+ 
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+index 40bcc04..d6c9c82 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+@@ -109,7 +109,7 @@ pthread_rwlock_timedrdlock:
+ #endif
+ 21:	leaq	READERS_WAKEUP(%r12), %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	movq	%rax, %rdx
+ 
+ #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+index f57ef52..78a2655 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+@@ -106,7 +106,7 @@ pthread_rwlock_timedwrlock:
+ #endif
+ 21:	leaq	WRITERS_WAKEUP(%r12), %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 	movq	%rax, %rdx
+ 
+ #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+index d779f7b..4dec0c0 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+@@ -79,7 +79,7 @@ __pthread_rwlock_unlock:
+ #endif
+ 	movl	$SYS_futex, %eax
+ 	movq	%r10, %rdi
+-	syscall
++	SYSCALL
+ 
+ 	xorl	%eax, %eax
+ 	retq
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
+index e444def..ba31821 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
+@@ -80,7 +80,7 @@ __pthread_rwlock_wrlock:
+ #endif
+ 	addq	$WRITERS_WAKEUP, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALL
+ 
+ 	subq	$WRITERS_WAKEUP, %rdi
+ 
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+index 1c11600..d276efa 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+@@ -52,7 +52,7 @@ sem_post:
+ 	movl	$FUTEX_WAKE, %esi
+ 	orl	PRIVATE(%rdi), %esi
+ 	movl	$1, %edx
+-	syscall
++	SYSCALL
+ 
+ 	testq	%rax, %rax
+ 	js	1f
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+index 880610e..06fd57c 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+@@ -97,7 +97,7 @@ sem_timedwait:
+ 	orl	PRIVATE(%rdi), %esi
+ 	movl	$SYS_futex, %eax
+ 	xorl	%edx, %edx
+-	syscall
++	SYSCALL
+ 	movq	%rax, %r9
+ #if VALUE != 0
+ 	leaq	-VALUE(%rdi), %rdi
+@@ -233,7 +233,7 @@ sem_timedwait:
+ # endif
+ 	movl	$SYS_futex, %eax
+ 	xorl	%edx, %edx
+-	syscall
++	SYSCALL
+ 	movq	%rax, %r14
+ 
+ 	movl	16(%rsp), %edi
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+index 8f4d068..d9b49e4 100644
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
++++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+@@ -81,7 +81,7 @@ sem_wait:
+ 	orl	PRIVATE(%rdi), %esi
+ #endif
+ 	xorl	%edx, %edx
+-	syscall
++	SYSCALL
+ 	movq	%rax, %rcx
+ 
+ 	xchgq	%r8, %rdi
+diff --git a/nptl/sysdeps/x86_64/pthreaddef.h b/nptl/sysdeps/x86_64/pthreaddef.h
+index 18a15a1..ac3d6d3 100644
+--- a/nptl/sysdeps/x86_64/pthreaddef.h
++++ b/nptl/sysdeps/x86_64/pthreaddef.h
+@@ -48,4 +48,5 @@
+ 
+ /* While there is no such syscall.  */
+ #define __exit_thread_inline(val) \
+-  asm volatile ("syscall" :: "a" (__NR_exit), "D" (val))
++  asm volatile ("pushq %%rbx\n\tmovq syscalldb@GOTPCREL(%%rip), %%rbx\n\t" \
++		"call %%rbx\n\t" :: "a" (__NR_exit), "D" (val) : "bx" )
+diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
+index cbb5e9e..19b18ef 100644
+--- a/nptl/sysdeps/x86_64/tls.h
++++ b/nptl/sysdeps/x86_64/tls.h
+@@ -28,6 +28,7 @@
+ # include <sysdep.h>
+ # include <libc-internal.h>
+ # include <kernel-features.h>
++# include <shim_tls.h>
+ 
+ /* Replacement type for __m128 since this file is included by ld.so,
+    which is compiled with -mno-sse.  It must not change the alignment
+@@ -67,6 +68,10 @@ typedef struct
+ # else
+   int __glibc_reserved1;
+ # endif
++
++  shim_tcb_t shim_tcb;	/* For graphene, we allocate a shim_tcb
++			   in the real tcb. */
++
+   int rtld_must_xmm_save;
+   /* Reservation of some values for the TM ABI.  */
+   void *__private_tm[4];
+@@ -137,6 +142,12 @@ typedef struct
+ # define GET_DTV(descr) \
+   (((tcbhead_t *) (descr))->dtv)
+ 
++/* For Graphene */
++#define SYSCALLDB							      \
++	"pushq %%rbx\n\t"						      \
++	"movq syscalldb@GOTPCREL(%%rip), %%rbx\n\t"			      \
++	"callq *%%rbx\n\t"						      \
++	"popq %%rbx\n\t"
+ 
+ /* Code to initially initialize the thread pointer.  This might need
+    special attention since 'errno' is not yet available and if the
+@@ -154,7 +165,7 @@ typedef struct
+      _head->self = _thrdescr;						      \
+ 									      \
+      /* It is a simple syscall to set the %fs value for the thread.  */	      \
+-     asm volatile ("syscall"						      \
++     asm volatile (SYSCALLDB						      \
+ 		   : "=a" (_result)					      \
+ 		   : "0" ((unsigned long int) __NR_arch_prctl),		      \
+ 		     "D" ((unsigned long int) ARCH_SET_FS),		      \
+diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs
+index 55d537f..57bf12b 100755
+--- a/scripts/mkinstalldirs
++++ b/scripts/mkinstalldirs
+@@ -126,9 +126,9 @@ do
+     esac
+ 
+     if test ! -d "$pathcomp"; then
+-      echo "mkdir $pathcomp"
++      echo "mkdir -p $pathcomp"
+ 
+-      mkdir "$pathcomp" || lasterr=$?
++      mkdir -p "$pathcomp" || lasterr=$?
+ 
+       if test ! -d "$pathcomp"; then
+ 	errstatus=$lasterr
+diff --git a/shlib-versions b/shlib-versions
+index 78b0ad7..5c3dcf2 100644
+--- a/shlib-versions
++++ b/shlib-versions
+@@ -108,3 +108,5 @@ sparc64.*-.*-.*		libBrokenLocale=1	GLIBC_2.2
+ # This defines the libgcc soname version this glibc is to load for
+ # asynchronous cancellation to work correctly.
+ .*-.*-.*		libgcc_s=1
++
++.*-.*-.*		liblibos=1
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index ffeb093..7a9fbcb 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -881,8 +881,7 @@ extern void _dl_sort_fini (struct link_map **maps, size_t nmaps, char *used,
+    any shared object mappings.  The `r_state' member of `struct r_debug'
+    says what change is taking place.  This function's address is
+    the value of the `r_brk' member.  */
+-extern void _dl_debug_state (void);
+-rtld_hidden_proto (_dl_debug_state)
++extern void __libc_dl_debug_state (void) __attribute__((weak));
+ 
+ /* Initialize `struct r_debug' if it has not already been done.  The
+    argument is the run-time load address of the dynamic linker, to be put
+diff --git a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
+index 2468228..a9f1cd6 100644
+--- a/sysdeps/unix/sysv/linux/_exit.c
++++ b/sysdeps/unix/sysv/linux/_exit.c
+@@ -29,9 +29,9 @@ _exit (status)
+   while (1)
+     {
+ #ifdef __NR_exit_group
+-      INLINE_SYSCALL (exit_group, 1, status);
++      INLINE_SYSCALL_ASM (exit_group, 1, status);
+ #endif
+-      INLINE_SYSCALL (exit, 1, status);
++      INLINE_SYSCALL_ASM (exit, 1, status);
+ 
+ #ifdef ABORT_INSTRUCTION
+       ABORT_INSTRUCTION;
+diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+index 49f0384..ee59c00 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
++++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+@@ -84,7 +84,8 @@ ENTRY(____longjmp_chk)
+ 	xorl	%edi, %edi
+ 	lea	-sizeSS(%rsp), %RSI_LP
+ 	movl	$__NR_sigaltstack, %eax
+-	syscall
++	SYSCALL
++
+ 	/* Without working sigaltstack we cannot perform the test.  */
+ 	testl	%eax, %eax
+ 	jne	.Lok2
+diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+index f712110..f6bad14 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
++++ b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+@@ -1,5 +1,6 @@
+ #include "bits/libc-vdso.h"
+ 
++#if 0 /* in Graphene, disallow VDSO calls */
+ #ifdef SHARED
+ # define SYSCALL_GETTIME(id, tp) \
+   ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+@@ -16,5 +17,6 @@
+   PTR_DEMANGLE (f);							  \
+   f (id, tp); })
+ #endif
++#endif
+ 
+ #include "../clock_gettime.c"
+diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
+index 0508730..c011e7a 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
++++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
+@@ -59,11 +59,15 @@ ENTRY (__clone)
+ 	jz	SYSCALL_ERROR_LABEL
+ 
+ 	/* Insert the argument onto the new stack.  */
+-	subq	$16,%rsi
+-	movq	%rcx,8(%rsi)
++	subq	$24,%rsi
++	movq	%rcx,16(%rsi)
+ 
+ 	/* Save the function pointer.  It will be popped off in the
+ 	   child in the ebx frobbing below.  */
++	movq	%rdi,8(%rsi)
++
++	/* Push an additional pointer as return address into the stack */
++	leaq	L(clone_return)(%rip),%rdi
+ 	movq	%rdi,0(%rsi)
+ 
+ 	/* Do the system call.  */
+@@ -76,8 +80,9 @@ ENTRY (__clone)
+ 	/* End FDE now, because in the child the unwind info will be
+ 	   wrong.  */
+ 	cfi_endproc;
+-	syscall
++	SYSCALL
+ 
++L(clone_return):
+ 	testq	%rax,%rax
+ 	jl	SYSCALL_ERROR_LABEL
+ 	jz	L(thread_start)
+@@ -99,13 +104,14 @@ L(thread_start):
+ 	movl	$-1, %eax
+ 	jne	2f
+ 	movl	$SYS_ify(getpid), %eax
+-	syscall
++	SYSCALL
+ 2:	movl	%eax, %fs:PID
+ 	movl	%eax, %fs:TID
+ 1:
+ #endif
+ 
+ 	/* Set up arguments for the function call.  */
++	addq	$8,%rsp		/* Skip the return address */
+ 	popq	%rax		/* Function to call.  */
+ 	popq	%rdi		/* Argument.  */
+ 	call	*%rax
+diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+index 140db03..870fb02 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
++++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+@@ -75,7 +75,7 @@ ENTRY(__getcontext)
+ #endif
+ 	movl	$_NSIG8,%r10d
+ 	movl	$__NR_rt_sigprocmask, %eax
+-	syscall
++	SYSCALL
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+index 440ca7f..571125d 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
++++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+@@ -17,6 +17,7 @@
+ 
+ #include <sys/time.h>
+ 
++#if 0 /* In graphene, do not use vsyscall or VDSO call */
+ #ifdef SHARED
+ 
+ # include <dl-vdso.h>
+@@ -42,7 +43,8 @@ asm (".type __gettimeofday, %gnu_indirect_function");
+ asm (".globl __GI___gettimeofday\n"
+      "__GI___gettimeofday = __gettimeofday");
+ 
+-#else
++#endif
++#endif
+ 
+ # include <sysdep.h>
+ # include <errno.h>
+@@ -54,6 +56,5 @@ __gettimeofday (struct timeval *tv, struct timezone *tz)
+ }
+ libc_hidden_def (__gettimeofday)
+ 
+-#endif
+ weak_alias (__gettimeofday, gettimeofday)
+ libc_hidden_weak (gettimeofday)
+diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S
+index 0fd47f2..0247e2f 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S
++++ b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S
+@@ -30,6 +30,7 @@ ENTRY (sched_getcpu)
+ 	sub	$0x8, %rsp
+ 	cfi_adjust_cfa_offset(8)
+ 
++#if 0 /* for Graphene, never do VDSO calls */
+ 	movq	%rsp, %rdi
+ 	xorl	%esi, %esi
+ 	movl	$VGETCPU_CACHE_OFFSET, %edx
+@@ -39,16 +40,19 @@ ENTRY (sched_getcpu)
+ 	movq	__vdso_getcpu(%rip), %rax
+ 	PTR_DEMANGLE (%rax)
+ 	callq	*%rax
+-#else
+-# ifdef __NR_getcpu
++#endif
++#endif
++
++#ifdef __NR_getcpu
+ 	movl	$__NR_getcpu, %eax
+-	syscall
+-#  ifndef __ASSUME_GETCPU_SYSCALL
++	SYSCALL
++#endif
++
++#if 0 /* for Graphene, never do vsyscall */
++# ifndef __ASSUME_GETCPU_SYSCALL
+ 	cmpq	$-ENOSYS, %rax
+ 	jne	1f
+-#  endif
+-# endif
+-# ifndef __ASSUME_GETCPU_SYSCALL
++
+ 	movq	$VSYSCALL_ADDR_vgetcpu, %rax
+ 	callq	*%rax
+ 1:
+diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+index b726fa0..96bf0ec 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S
++++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+@@ -43,7 +43,7 @@ ENTRY(__setcontext)
+ 	movl	$SIG_SETMASK, %edi
+ 	movl	$_NSIG8,%r10d
+ 	movl	$__NR_rt_sigprocmask, %eax
+-	syscall
++	SYSCALL
+ 	popq	%rdi			/* Reload %rdi, adjust stack.  */
+ 	cfi_adjust_cfa_offset(-8)
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+index ab23985..39d0bdc 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
++++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+@@ -129,7 +129,8 @@ asm									\
+    "	.type __" #name ",@function\n"					\
+    "__" #name ":\n"							\
+    "	movq $" #syscall ", %rax\n"					\
+-   "	syscall\n"							\
++   "	movq syscalldb@GOTPCREL(%rip), %rbx\n"				\
++   "	call *%rbx\n"							\
+    ".LEND_" #name ":\n"							\
+    ".section .eh_frame,\"a\",@progbits\n"				\
+    ".LSTARTFRAME_" #name ":\n"						\
+diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+index b3854fa..fd42f66 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
++++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+@@ -75,7 +75,7 @@ ENTRY(__swapcontext)
+ 	movl	$SIG_SETMASK, %edi
+ 	movl	$_NSIG8,%r10d
+ 	movl	$__NR_rt_sigprocmask, %eax
+-	syscall
++	SYSCALL
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
+index 92c2f5b..7b7ee12 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/syscall.S
++++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S
+@@ -34,7 +34,7 @@ ENTRY (syscall)
+ 	movq %r8, %r10
+ 	movq %r9, %r8
+ 	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
+-	syscall			/* Do the system call.  */
++	SYSCALL			/* Do the system call.  */
+ 	cmpq $-4095, %rax	/* Check %rax for error.  */
+ 	jae SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 	ret			/* Return to caller.  */
+diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+index 4a9a9d9..3b7434d 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
++++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+@@ -21,6 +21,7 @@
+ /* There is some commonality.  */
+ #include <sysdeps/unix/x86_64/sysdep.h>
+ #include <tls.h>
++#include "syscalldb.h"
+ 
+ #ifdef IS_IN_rtld
+ # include <dl-sysdep.h>		/* Defines RTLD_PRIVATE_ERRNO.  */
+@@ -172,11 +173,18 @@
+ 
+     Syscalls of more than 6 arguments are not supported.  */
+ 
++# undef	SYSCALL
++# define SYSCALL				\
++    pushq %rbx;					\
++    movq syscalldb@GOTPCREL(%rip), %rbx;	\
++    call *%rbx;					\
++    popq %rbx;
++
+ # undef	DO_CALL
+ # define DO_CALL(syscall_name, args)		\
+     DOARGS_##args				\
+     movl $SYS_ify (syscall_name), %eax;		\
+-    syscall;
++    SYSCALL
+ 
+ # define DOARGS_0 /* nothing */
+ # define DOARGS_1 /* nothing */
+@@ -190,9 +198,20 @@
+ /* Define a macro which expands inline into the wrapper code for a system
+    call.  */
+ # undef INLINE_SYSCALL
+-# define INLINE_SYSCALL(name, nr, args...) \
++# define INLINE_SYSCALL(name, nr_args...) \
++  ({									      \
++    unsigned long int resultvar = INTERNAL_SYSCALL (name, , ##nr_args);	      \
++    if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))	      \
++      {									      \
++	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
++	resultvar = (unsigned long int) -1;				      \
++      }									      \
++    (long int) resultvar; })
++
++# undef INLINE_SYSCALL_ASM
++# define INLINE_SYSCALL_ASM(name, nr_args...) \
+   ({									      \
+-    unsigned long int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
++    unsigned long int resultvar = INTERNAL_SYSCALL_ASM (name, , ##nr_args);   \
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -204,9 +223,9 @@
+    into the wrapper code for a system call.  It should be used when size
+    of any argument > size of long int.  */
+ # undef INLINE_SYSCALL_TYPES
+-# define INLINE_SYSCALL_TYPES(name, nr, args...) \
++# define INLINE_SYSCALL_TYPES(name, nr_args...) \
+   ({									      \
+-    unsigned long int resultvar = INTERNAL_SYSCALL_TYPES (name, , nr, args);  \
++    unsigned long int resultvar = INTERNAL_SYSCALL_TYPES (name, , ##nr_args); \
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -223,13 +242,20 @@
+     LOAD_ARGS_##nr (args)						      \
+     LOAD_REGS_##nr							      \
+     asm volatile (							      \
+-    "syscall\n\t"							      \
++    "movq syscalldb@GOTPCREL(%%rip), %%rbx\n\t"				      \
++    "call *%%rbx\n\t"							      \
+     : "=a" (resultvar)							      \
+-    : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx");		      \
++    : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx", "bx");	      \
+     (long int) resultvar; })
++# define INTERNAL_SYSCALL_NCS_ASM INTERNAL_SYSCALL_NCS
++
+ # undef INTERNAL_SYSCALL
+-# define INTERNAL_SYSCALL(name, err, nr, args...) \
+-  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
++# define INTERNAL_SYSCALL(name, err, nr_args...) \
++  INTERNAL_SYSCALL_NCS (__NR_##name, err, ##nr_args)
++
++# undef INTERNAL_SYSCALL_ASM
++# define INTERNAL_SYSCALL_ASM(name, err, nr_args...) \
++  INTERNAL_SYSCALL_NCS_ASM (__NR_##name, err, ##nr_args)
+ 
+ # define INTERNAL_SYSCALL_NCS_TYPES(name, err, nr, args...) \
+   ({									      \
+@@ -237,9 +263,10 @@
+     LOAD_ARGS_TYPES_##nr (args)						      \
+     LOAD_REGS_TYPES_##nr (args)						      \
+     asm volatile (							      \
+-    "syscall\n\t"							      \
++    "movq syscalldb@GOTPCREL(%%rip), %%rbx\n\t"				      \
++    "call *%%rbx\n\t"							      \
+     : "=a" (resultvar)							      \
+-    : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx");		      \
++    : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx", "bx");	      \
+     (long int) resultvar; })
+ # undef INTERNAL_SYSCALL_TYPES
+ # define INTERNAL_SYSCALL_TYPES(name, err, nr, args...) \
+@@ -252,6 +279,7 @@
+ # undef INTERNAL_SYSCALL_ERRNO
+ # define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
+ 
++# if 0 /* for Graphene, never do vsyscall */
+ # ifdef SHARED
+ #  define INLINE_VSYSCALL(name, nr, args...) \
+   ({									      \
+@@ -300,12 +328,13 @@
+     v_ret;								      \
+   })
+ 
+-# else
+-#  define INLINE_VSYSCALL(name, nr, args...) \
+-  INLINE_SYSCALL (name, nr, ##args)
+-#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
+-  INTERNAL_SYSCALL (name, err, nr, ##args)
+ # endif
++# endif
++
++#  define INLINE_VSYSCALL(name, nr_args...) \
++  INLINE_SYSCALL (name, ##nr_args)
++#  define INTERNAL_VSYSCALL(name, err, nr_args...) \
++  INTERNAL_SYSCALL (name, err, ##nr_args)
+ 
+ # define LOAD_ARGS_0()
+ # define LOAD_REGS_0
+diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
+deleted file mode 100644
+index 79f1fab..0000000
+--- a/sysdeps/unix/sysv/linux/x86_64/time.c
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-#ifdef SHARED
+-/* Redefine time so that the compiler won't complain about the type
+-   mismatch with the IFUNC selector in strong_alias, below.  */
+-#undef time
+-#define time __redirect_time
+-#include <time.h>
+-
+-#include <dl-vdso.h>
+-
+-#define VSYSCALL_ADDR_vtime	0xffffffffff600400
+-
+-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+-   ifunc symbol properly.  */
+-extern __typeof (__redirect_time) __libc_time;
+-void *time_ifunc (void) __asm__ ("__libc_time");
+-
+-void *
+-time_ifunc (void)
+-{
+-  PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+-
+-  /* If the vDSO is not available we fall back on the old vsyscall.  */
+-  return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
+-}
+-__asm (".type __libc_time, %gnu_indirect_function");
+-
+-#undef time
+-strong_alias (__libc_time, time)
+-libc_hidden_ver (__libc_time, time)
+-
+-#else
+-
+-# include <time.h>
+-# include <sysdep.h>
+-
+-time_t
+-time (time_t *t)
+-{
+-  INTERNAL_SYSCALL_DECL (err);
+-  return INTERNAL_SYSCALL (time, err, 1, t);
+-}
+-
+-#endif
+diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+index d3b450a..76bda33 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
++++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+@@ -38,7 +38,7 @@ ENTRY (__vfork)
+ 
+ 	/* Stuff the syscall number in RAX and enter into the kernel.  */
+ 	movl	$SYS_ify (vfork), %eax
+-	syscall
++	SYSCALL
+ 
+ 	/* Push back the return PC.  */
+ 	pushq	%rdi
+diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+index 504c95f..dcfc259 100644
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -529,7 +529,8 @@ elf_machine_lazy_rel (struct link_map *map,
+ 	value = ((ElfW(Addr) (*) (void)) value) ();
+       *reloc_addr = value;
+     }
+-  else
++  /* for graphene, get around R_X86_64_NONE */
++  else if (__builtin_expect (r_type != R_X86_64_NONE, 1))
+     _dl_reloc_bad_type (map, r_type, 1);
+ }
+ 

+ 1 - 0
LibOS/glibc-2.19/elf/syscallas.S

@@ -0,0 +1 @@
+../syscallas.S

+ 1 - 0
LibOS/glibc-2.19/elf/syscalldb.c

@@ -0,0 +1 @@
+../syscalldb.c

+ 56 - 0
LibOS/glibc-2.19/libos/Makefile

@@ -0,0 +1,56 @@
+# Copyright (C) 1996-2001,2002,2003,2004,2005,2006
+#	Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# Makefile for the libos library.
+
+subdir		:= libos
+
+# Installed header files.
+headers		:= 
+
+# Internal header files.
+distribute	:= errno.h
+
+liblibos-routines := checkpoint sandbox msgpersist benchmark
+
+# Build the -llibos library.
+
+extra-libs	:= liblibos
+extra-libs-others = $(extra-libs)
+
+include ../Makeconfig
+
+ifeq ($(versioning),yes)
+liblibos-routines	+=
+liblibos-shared-only-routines :=
+endif
+
+tests =
+
+modules-names =
+
+extra-test-objs += $(modules-names:=.os)
+generated := $(modules-names:=.so)
+
+include ../Rules
+
+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
+# This ensures they will load libc.so for needed symbols if loaded by
+# a statically-linked program that hasn't already loaded it.
+$(objpfx)liblibos.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a

+ 15 - 0
LibOS/glibc-2.19/libos/Versions

@@ -0,0 +1,15 @@
+liblibos {
+  GLIBC_2.12 {
+    # checkpoint.c
+    checkpoint;
+
+    # sandbox.c
+    sandbox_create; sandbox_attach; sandbox_current;
+
+    # msgpersist.c
+    msgpersist;
+
+    # benchmark.c
+    benchmark_rpc; send_rpc; recv_rpc;
+  }
+}

+ 27 - 0
LibOS/glibc-2.19/libos/benchmark.c

@@ -0,0 +1,27 @@
+#include <errno.h>
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+#include <shim_unistd.h>
+
+#ifdef __NR_benchmark_rpc
+int benchmark_rpc(pid_t pid, int times, const void * buf, size_t size)
+{
+	return INLINE_SYSCALL (benchmark_rpc, 4, pid, times, buf, size);
+}
+#endif
+
+#ifdef __NR_send_rpc
+size_t send_rpc (pid_t pid, const void * buf, size_t size)
+{
+	return INLINE_SYSCALL (send_rpc, 3, pid, buf, size);
+}
+#endif
+
+#ifdef __NR_recv_rpc
+size_t recv_rpc (pid_t * pid, void * buf, size_t size)
+{
+	return INLINE_SYSCALL (recv_rpc, 3, pid, buf, size);
+}
+#endif

+ 13 - 0
LibOS/glibc-2.19/libos/checkpoint.c

@@ -0,0 +1,13 @@
+#include <errno.h>
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+#include <shim_unistd.h>
+
+#ifdef __NR_checkpoint
+int checkpoint (const char * filename)
+{
+	return INLINE_SYSCALL (checkpoint, 1, filename);
+}
+#endif

+ 13 - 0
LibOS/glibc-2.19/libos/msgpersist.c

@@ -0,0 +1,13 @@
+#include <errno.h>
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+#include <shim_unistd.h>
+
+#ifdef __NR_msgpersist
+int msgpersist (int msqid, int cmd)
+{
+	return INLINE_SYSCALL (msgpersist, 2, msqid, cmd);
+}
+#endif

+ 27 - 0
LibOS/glibc-2.19/libos/sandbox.c

@@ -0,0 +1,27 @@
+#include <errno.h>
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+#include <shim_unistd.h>
+
+#ifdef __NR_sandbox_create
+long sandbox_create(int flags, const char *fs_sb, struct net_sb *net_sb)
+{
+	return INLINE_SYSCALL (sandbox_create, 3, flags, fs_sb, net_sb);
+}
+#endif
+
+#ifdef __NR_sandbox_attach
+int sandbox_attach(unsigned int sbid)
+{
+	return INLINE_SYSCALL (sandbox_attach, 1, sbid);
+}
+#endif
+
+#ifdef __NR_sandbox_current
+long sandbox_current(void)
+{
+	return INLINE_SYSCALL (sandbox_current, 0);
+}
+#endif

+ 11 - 0
LibOS/glibc-2.19/syscallas.S

@@ -0,0 +1,11 @@
+#include <syscalldb.h>
+
+.weak syscalldb
+.type syscalldb,@function
+
+syscalldb:
+	.cfi_startproc
+	syscall
+	retq
+	.cfi_endproc
+	.size syscalldb,.-syscalldb

+ 10 - 0
LibOS/glibc-2.19/syscalldb.c

@@ -0,0 +1,10 @@
+#include "syscalldb.h"
+#include <stdarg.h>
+
+int register_library (const char * name, unsigned long load_address)
+	__attribute__((weak));
+
+int register_library (const char * name, unsigned long load_address)
+{
+	return 0;
+}

+ 15 - 0
LibOS/glibc-2.19/syscalldb.h

@@ -0,0 +1,15 @@
+#ifndef _SYSCALLDB_H_
+#define _SYSCALLDB_H_
+
+#ifdef __ASSEMBLER__
+.weak syscalldb
+.type syscalldb, @function
+
+#else /* !__ASSEMBLER__ */
+asm (
+".weak syscalldb\r\n"
+".type syscalldb, @function\r\n");
+
+#endif /* Assembler */
+
+#endif /* _SYSCALLDB_H */

+ 1 - 0
LibOS/glibc-2.19/sysdeps/unix/sysv/linux/x86_64/syscalldb.h

@@ -0,0 +1 @@
+../../../../../syscalldb.h

+ 266 - 404
LibOS/shim/include/shim_checkpoint.h

@@ -48,16 +48,16 @@ extern char __migratable;
 extern char __migratable_end;
 
 /* TSAI 7/11/2012:
-   The migration scheme we are expecting is to support an easy syntax to
+   The checkpoint scheme we are expecting is to support an easy syntax to
    implement migration procedure. A migration procedure can be written
    in teh following syntax:
 
-   BEGIN_MIGRATE_DEFINITION(exec)
+   BEGIN_CP_DEFINITION(exec)
    {
-       DEFINE_MIGRATE(thread, );
-       DEFINE_MIGRATE(handle_map, );
+       DEFINE_CP(thread, ...);
+       DEFINE_CP(handle_map, ...);
    }
-   void *checkpoint = DO_MIGRATE(exec);
+   void * checkpoint = DO_CHECKPOINT(exec);
 
    The structure of checkpoint data will be a counting-down stack-like
    memory segment, with enough space reserved below for 1. in case the
@@ -66,32 +66,14 @@ extern char __migratable_end;
 
    Below is the figure for our checkpoint structure:
 
-   (later added by PAL:  argc        program arguments
-                         argv[0]
-                         argv[1]
-                         ...
-                         envp[0]     env variables
-                         envp[1]
-                         ...
-                         NULL-end
-                         auxv[0]     aux vectors
-                         auxv[1]
-                         ...
-                         auxv[n]     AT_NULL
    Low Bytes -------------------------------------------------
-                checkpoint base (identified by a magic number)
-             -------------------------------------------------
                 checkpoint_entry[0]
+                data section for checkpoint 0
                 checkpoint_entry[1]
+                data section for checkpoint 1
                 checkpoint_entry[2]
                 ...
                 checkpoint_entry[n]  CP_NULL
-              ------------------------------------------------
-                data section for checkpoint 0
-                data section for checkpoint 1
-                data section for checkpoint 2
-                ...
-                data section for checkpoint n-1
    High Bytes ------------------------------------------------
 
 
@@ -107,457 +89,340 @@ struct shim_cp_entry
     } cp_un;
 };
 
-struct shim_gipc_entry {
-    struct shim_gipc_entry * next;
-    enum { ABS_ADDR, REL_ADDR, ANY_ADDR } addr_type;
+struct shim_mem_entry {
+    struct shim_mem_entry * prev;
     void * addr;
-    int npages;
+    int size;
+    void ** paddr;
     int prot;
-    struct shim_vma * vma;
+    void * data;
+};
+
+struct shim_gipc_entry {
+    struct shim_mem_entry mem;
 #if HASH_GIPC == 1
     unsigned long first_hash;
 #endif
 };
 
-#define SET_GIPC_REL_ADDR(gipc)                                             \
-    do {                                                                    \
-         (gipc)->addr_type = REL_ADDR;                                      \
-         (gipc)->addr = (void *) ((gipc)->addr - (void *) &__load_address); \
-    } while (0)
-
-struct shim_mem_entry {
-    void * addr;
-    int size;
-    int prot;
-    bool need_alloc, need_prot;
-    struct shim_vma * vma;
-    void * data;
+struct shim_palhdl_entry {
+    struct shim_palhdl_entry * prev;
+    PAL_HANDLE handle;
+    struct shim_qstr * uri;
+    PAL_HANDLE * phandle;
 };
 
 struct shim_cp_store {
-    void * cpaddr;
-    void * cpdata;
-    size_t cpsize;
-    void * addr_map;
-    bool use_gipc;
-    struct shim_gipc_entry * gipc_entries, * gipc_entries_tail;
-    int gipc_nentries;
-};
+    /* checkpoint data mapping */
+    void * cp_map;
+    struct shim_handle * cp_file;
 
-#define INIT_CP_STORE_GIPC(store)                       \
-    do {                                                \
-        (store)->use_gipc = false;                      \
-        (store)->gipc_entries = NULL;                   \
-        (store)->gipc_entries_tail = NULL;              \
-        (store)->gipc_nentries = 0;                     \
-    } while (0)
+    /* allocation method for check point area */
+    void * (*alloc) (struct shim_cp_store * store, void * mem, int size);
 
-#define INIT_CP_STORE(store)                            \
-    do {                                                \
-        (store)->cpaddr = NULL;                         \
-        (store)->cpdata = NULL;                         \
-        (store)->cpsize = 0;                            \
-        (store)->addr_map = create_addr_map();          \
-        INIT_CP_STORE_GIPC(store);                      \
-    } while (0)
+    /* check point area */
+    ptr_t base, offset, bound;
+
+    /* entries of gipc records */
+    bool use_gipc;
+    struct shim_gipc_entry * last_gipc_entry;
+    int gipc_nentries;
 
-#define MIGRATE_FUNC_ARGS                                                   \
-    struct shim_cp_store * store, struct shim_cp_entry ** ent, ptr_t base,  \
-    unsigned long * offset, void * obj, size_t size, void ** objp,          \
-    bool recursive, bool dry
+    /* entries of out-of-band data */
+    struct shim_mem_entry * last_mem_entry;
+    int mem_nentries;
+    int mem_size;
 
-#define MIGRATE_FUNC_RET size_t
+    /* entries of pal handles to send */
+    struct shim_palhdl_entry * last_palhdl_entry;
+    int palhdl_nentries;
+};
 
-#define RESUME_FUNC_ARGS                                                    \
-    struct shim_cp_entry ** ent, ptr_t base, size_t cpsize, long cprebase
+#define CP_FUNC_ARGS                                    \
+    struct shim_cp_store * store, void * obj, int size, void ** objp
 
-#define RESUME_FUNC_RET int
+#define RS_FUNC_ARGS                                    \
+    struct shim_cp_entry * entry, ptr_t base, ptr_t * offset, long rebase
 
-typedef MIGRATE_FUNC_RET (*migrate_func) (MIGRATE_FUNC_ARGS);
-typedef RESUME_FUNC_RET (*resume_func) (RESUME_FUNC_ARGS);
+#define DEFINE_CP_FUNC(name) int cp_##name (CP_FUNC_ARGS)
+#define DEFINE_RS_FUNC(name) int rs_##name (RS_FUNC_ARGS)
 
-extern const char *       __migrate_name;
-extern const migrate_func __migrate_func;
-extern const resume_func  __resume_func;
+typedef int (*cp_func) (CP_FUNC_ARGS);
+typedef int (*rs_func) (RS_FUNC_ARGS);
 
-#define CP_NULL   0
-#define CP_IGNORE 1
-#define CP_BASE   2
-#define CP_ADDR   3
-#define CP_SIZE   4
-#define CP_PID    5
-#define CP_UID    6
-#define CP_GID    7
-#define CP_FD     8
-#define CP_BOOL   9
-#define CP_PALHDL 10
+extern const char *  __cp_name;
+extern const cp_func __cp_func;
+extern const rs_func __rs_func;
 
-#define CP_FUNC_BASE   11
+enum {
+    CP_NULL = 0,
+    CP_IGNORE,
+    CP_OOB,
+    CP_ADDR,
+    CP_SIZE,
+    CP_FUNC_BASE,
+};
 
-#define CP_FUNC_INDEX(name)                                             \
-    ({  extern const migrate_func migrate_func_##name;                  \
-        &migrate_func_##name - &__migrate_func;  })
+#define CP_FUNC_INDEX(name)                                         \
+    ({ extern const cp_func cp_func_##name; &cp_func_##name - &__cp_func; })
 
 #define CP_FUNC(name)   CP_FUNC_BASE + CP_FUNC_INDEX(name)
-#define CP_FUNC_NAME(type)      (&__migrate_name)[(type) - CP_FUNC_BASE]
-
-#define ADD_ENTRY(type, value)                                      \
-    do {                                                            \
-        USED += sizeof(struct shim_cp_entry);                       \
-        if (!dry) {                                                 \
-            struct shim_cp_entry * tmp = (*ent)++;                  \
-            tmp->cp_type = CP_##type;                               \
-            tmp->cp_un.cp_val = (ptr_t) (value);                    \
+#define CP_FUNC_NAME(type)      (&__cp_name)[(type) - CP_FUNC_BASE]
+
+#define __ADD_CP_OFFSET(size)                                       \
+    ({                                                              \
+        ptr_t _off = store->offset;                                 \
+        if (store->offset + (size) > store->bound) {                \
+            int new_bound = store->bound * 2;                       \
+                                                                    \
+            while (store->offset + (size) > new_bound)              \
+                new_bound *= 2;                                     \
                                                                     \
-            if (DEBUG_CHECKPOINT)                                   \
-                debug("ADD CP_" #type "(%p) :%d\n",                 \
-                      tmp->cp_un.cp_val,                            \
-                      tmp - (struct shim_cp_entry *) base);         \
-        } else {                                                    \
-            if (DEBUG_CHECKPOINT)                                   \
-                debug("(dry) ADD CP_" #type "\n");                  \
+            void * buf = store->alloc(store,                        \
+                                      (void *) store->base + store->bound, \
+                                      new_bound - store->bound);    \
+            if (!buf)                                               \
+                return -ENOMEM;                                     \
+                                                                    \
+            store->bound = new_bound;                               \
         }                                                           \
-    } while(0)
+        store->offset += size;                                      \
+    _off;  })
 
-#define ADD_OFFSET(size)                                            \
+#define ADD_CP_ENTRY(type, value)                                   \
     ({                                                              \
-        int _size = ((size) + 7) & ~7;                              \
-        USED += _size;                                              \
-        if (!dry)                                                   \
-            *offset -= _size;                                       \
+        struct shim_cp_entry * tmp =                                \
+                (void *) base +                                     \
+                __ADD_CP_OFFSET(sizeof(struct shim_cp_entry));      \
+        tmp->cp_type = CP_##type;                                   \
+        tmp->cp_un.cp_val = (ptr_t) (value);                        \
         if (DEBUG_CHECKPOINT)                                       \
-            debug("%sADD OFFSET(%d)\n",                             \
-                  dry ? "(dry) " : "", _size);                      \
-        dry ? 0 : *offset;                                          \
-    })
-
-#define ADD_FUNC_ENTRY(value)                                       \
-    do {                                                            \
-        USED += sizeof(struct shim_cp_entry);                       \
-        if (!dry) {                                                 \
-            struct shim_cp_entry * tmp = (*ent)++;                  \
-            tmp->cp_type = CP_FUNC_TYPE;                            \
-            tmp->cp_un.cp_val = (ptr_t) value;                      \
-                                                                    \
-            if (DEBUG_CHECKPOINT)                                   \
-                debug("ADD CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,     \
-                      tmp->cp_un.cp_val,                            \
-                      tmp - (struct shim_cp_entry *) base);         \
-        } else {                                                    \
-            if (DEBUG_CHECKPOINT)                                   \
-                debug("(dry) ADD CP_FUNC_%s\n", CP_FUNC_NAME);      \
-        }                                                           \
-    } while(0)
+            debug("ADD CP_" #type "(%p) >%d\n", tmp->cp_un.cp_val,  \
+                  store->offset);                                   \
+    tmp; })
 
+#define ADD_CP_OFFSET(size)                                         \
+    ({                                                              \
+        int _size = ((size) + sizeof(void *) - 1) &                 \
+                    ~(sizeof(void *) - 1);                          \
+        struct shim_cp_entry * oob =                                \
+                (void *) base +                                     \
+                __ADD_CP_OFFSET(sizeof(struct shim_cp_entry));      \
+        oob->cp_type = CP_OOB;                                      \
+        oob->cp_un.cp_val = (ptr_t) _size;                          \
+        ptr_t _off = (ptr_t) __ADD_CP_OFFSET(_size);                \
+        if (DEBUG_CHECKPOINT)                                       \
+            debug("ADD OFFSET(%d) >%d\n", (size), store->offset);   \
+    _off; })
 
-#define GET_ENTRY(type)                                             \
-    ({  struct shim_cp_entry * tmp = (*ent)++;                      \
-                                                                    \
-        while (tmp->cp_type != CP_##type)                           \
-            tmp = (*ent)++;                                         \
-                                                                    \
-        /* debug("GET CP_" #type "(%p) :%d\n",                      \
-                 tmp->cp_un.cp_val,                                 \
-                 tmp - (struct shim_cp_entry *) base); */           \
-                                                                    \
-        tmp->cp_un.cp_val;                                          \
-     })
+#define ADD_CP_FUNC_ENTRY(value)                                    \
+    ({                                                              \
+        struct shim_cp_entry * tmp =                                \
+                (void *) base +                                     \
+                __ADD_CP_OFFSET(sizeof(struct shim_cp_entry));      \
+        tmp->cp_type = CP_FUNC_TYPE;                                \
+        tmp->cp_un.cp_val = (ptr_t) (value);                        \
+        if (DEBUG_CHECKPOINT)                                       \
+            debug("ADD %s(%p) >%d\n", CP_FUNC_NAME, (value),        \
+                  store->offset);                                   \
+    tmp; })
+
+#define NEXT_CP_ENTRY()                                             \
+    ({  struct shim_cp_entry * tmp;                                 \
+        while (1) {                                                 \
+            tmp = (void *) base + *offset;                          \
+            if (tmp->cp_type == CP_NULL) {                          \
+                tmp = NULL;                                         \
+                break;                                              \
+            }                                                       \
+            *offset += sizeof(struct shim_cp_entry);                \
+            if (tmp->cp_type == CP_OOB)                             \
+                *offset += tmp->cp_un.cp_val;                       \
+            else                                                    \
+                break;                                              \
+        }                                                           \
+    tmp; })
 
-#define GET_FUNC_ENTRY()                                            \
-    ({  struct shim_cp_entry * tmp = (*ent)++;                      \
-                                                                    \
-        while (tmp->cp_type != CP_FUNC_TYPE)                        \
-            tmp = (*ent)++;                                         \
-                                                                    \
-        /* debug("GET CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,          \
-                 tmp->cp_un.cp_val,                                 \
-                 tmp - (struct shim_cp_entry *) base); */           \
+#define GET_CP_ENTRY(type)                                          \
+    ({  struct shim_cp_entry * tmp = NEXT_CP_ENTRY();               \
                                                                     \
-        tmp->cp_un.cp_val;                                          \
-     })
-
-
-#define DEFINE_MIGRATE_FUNC(name)                                   \
-    const char * migrate_name_##name                                \
-        __attribute__((section(".migrate_name." #name))) = #name;   \
+        while (tmp->cp_type != CP_##type)                           \
+            tmp = NEXT_CP_ENTRY();                                  \
                                                                     \
-    extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);     \
-    const migrate_func migrate_func_##name                          \
-        __attribute__((section(".migrate." #name))) = &migrate_##name;\
+        /* debug("GET CP_" #type "(%p)\n",tmp->cp_un.cp_val); */    \
+    tmp->cp_un.cp_val; })
+
+#define GET_CP_FUNC_ENTRY()                                         \
+    ({  /* debug("GET CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,          \
+                 entry->cp_un.cp_val); */                           \
+    entry->cp_un.cp_val; })
+
+#define BEGIN_CP_FUNC(name)                                         \
+    const char * cp_name_##name                                     \
+            __attribute__((section(".cp_name." #name))) = #name;    \
+    extern DEFINE_CP_FUNC(name);                                    \
+    extern DEFINE_RS_FUNC(name);                                    \
+    const cp_func cp_func_##name                                    \
+            __attribute__((section(".cp_func." #name))) = &cp_##name; \
+    const rs_func rs_func_##name                                    \
+            __attribute__((section(".rs_func." #name))) = &rs_##name; \
                                                                     \
-    extern RESUME_FUNC_RET resume_##name (RESUME_FUNC_ARGS);        \
-    const resume_func resume_func_##name                            \
-        __attribute__((section(".resume." #name))) = &resume_##name;\
+    DEFINE_PROFILE_INTERVAL(cp_##name, checkpoint_func);            \
+    DEFINE_PROFILE_INTERVAL(rs_##name, resume_func);                \
                                                                     \
-    DEFINE_PROFILE_INTERVAL(migrate_##name, migrate_func);          \
-    DEFINE_PROFILE_INTERVAL(resume_##name,  resume_func);           \
-
-
-#define MIGRATE_FUNC_BODY(name)                                 \
-    MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS)         \
-    {                                                           \
-        int CP_FUNC_TYPE __attribute__((unused))                \
-                                    = CP_FUNC(name);            \
-        const char * CP_FUNC_NAME __attribute__((unused))       \
-                                    = #name;                    \
-        size_t USED = 0;                                        \
-        BEGIN_PROFILE_INTERVAL();                               \
-        ASSIGN_PROFILE_INTERVAL(migrate_##name);
-
-#define END_MIGRATE_FUNC                                        \
-        if (!dry) SAVE_PROFILE_INTERVAL_ASSIGNED();             \
-        return USED;                                            \
+    DEFINE_CP_FUNC(name)                                            \
+    {                                                               \
+        int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name);   \
+        const char * CP_FUNC_NAME __attribute__((unused)) = #name;  \
+        ptr_t base __attribute__((unused)) = store->base;           \
+        BEGIN_PROFILE_INTERVAL();                                   \
+        ASSIGN_PROFILE_INTERVAL(cp_##name);
+
+#define END_CP_FUNC(name)                                           \
+        SAVE_PROFILE_INTERVAL_ASSIGNED();                           \
+        return 0;                                                   \
     }
 
-
-#define RESUME_FUNC_BODY(name)                                  \
-    RESUME_FUNC_RET resume_##name (RESUME_FUNC_ARGS)            \
-    {                                                           \
-        int CP_FUNC_TYPE __attribute__((unused))                \
-                                    = CP_FUNC(name);            \
-        const char * CP_FUNC_NAME __attribute__((unused))       \
-                                    = #name;                    \
-        BEGIN_PROFILE_INTERVAL();                               \
-        ASSIGN_PROFILE_INTERVAL(resume_##name);
-
-#define END_RESUME_FUNC \
-        SAVE_PROFILE_INTERVAL_ASSIGNED();                       \
-        return 0;                                               \
+#define END_CP_FUNC_NO_RS(name)                                     \
+    END_CP_FUNC(name)                                               \
+    BEGIN_RS_FUNC(name) {} END_RS_FUNC(name)
+
+#define BEGIN_RS_FUNC(name)                                         \
+    DEFINE_RS_FUNC(name)                                            \
+    {                                                               \
+        int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name);   \
+        const char * CP_FUNC_NAME __attribute__((unused)) = #name;  \
+        BEGIN_PROFILE_INTERVAL();                                   \
+        ASSIGN_PROFILE_INTERVAL(rs_##name);
+
+#define END_RS_FUNC(name)                                           \
+        SAVE_PROFILE_INTERVAL_ASSIGNED();                           \
+        return 0;                                                   \
     }
 
-#define RESUME_REBASE(obj)                                      \
+#define CP_REBASE(obj)                                          \
     do {                                                        \
         void * _ptr = &(obj);                                   \
         size_t _size = sizeof(obj);                             \
         void ** _p;                                             \
         for (_p = _ptr ; _p < (void **)(_ptr + _size) ; _p++)   \
             if (*_p)                                            \
-                *_p += cprebase;                                \
+                *_p += rebase;                                  \
     } while (0)
 
-
-struct shim_addr_map {
-    ptr_t addr;
-    unsigned long offset;
-    size_t size;
-};
-
-void * create_addr_map (void);
-void destroy_addr_map (void * map);
-
-struct shim_addr_map *
-get_addr_map_entry (void * map, ptr_t addr, size_t size, bool create);
-
-#define DO_MIGRATE_SIZE(name, obj, size, objp, recur)                       \
-    do {                                                                    \
-        extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);         \
-                                                                            \
-        USED += migrate_##name (store, ent, base, offset,                   \
-                  obj, size, (void **) objp, recur, dry);                   \
+#define DO_CP_SIZE(name, obj, size, objp)                       \
+    do {                                                        \
+        extern DEFINE_CP_FUNC(name);                            \
+        int ret = cp_##name(store, obj, size, (void **) objp);  \
+        if (ret < 0) return ret;                                \
     } while (0)
 
 
-#define __DO_MIGRATE(name, obj, objp, recur)                                \
-    do {                                                                    \
-        extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);         \
-                                                                            \
-        USED += migrate_##name (store, ent, base, offset,                   \
-                  obj, sizeof(*(obj)), (void **) objp, recur, dry);         \
-    } while (0)
+#define DO_CP(name, obj, objp)                                  \
+        DO_CP_SIZE(name, obj, sizeof(*obj), objp)
 
-#define DO_MIGRATE_MEMBER(name, obj, newobj, member, recur)                 \
-    do {                                                                    \
-        typeof(obj->member) *(objp) = (newobj) ?                            \
-                                      &(newobj)->member : NULL;             \
-                                                                            \
-        DO_MIGRATE(name, (obj)->member, (objp), (recur));                   \
-    } while (0);
+#define DO_CP_MEMBER(name, obj, newobj, member)                 \
+        DO_CP(name, (obj)->member, &((newobj)->member));
 
-#define DO_MIGRATE(name, obj, objp, recur)                                  \
-    do {                                                                    \
-        if (!obj)                                                           \
-            break;                                                          \
-                                                                            \
-        struct shim_addr_map * _e = get_addr_map_entry (store->addr_map,    \
-                                (ptr_t) (obj), sizeof(*(obj)), 0);          \
-                                                                            \
-        if (_e && !ENTRY_JUST_CREATED(_e->offset) && !(recur))              \
-        {                                                                   \
-            if (!dry && objp)                                               \
-                *((typeof(obj) *) objp) = (typeof(obj))                     \
-                                          (base + _e->offset);              \
-            break;                                                          \
-        }                                                                   \
-                                                                            \
-        if (dry ? !_e || (recur) : _e != NULL)                              \
-            __DO_MIGRATE(name, (obj), (objp), (recur));                     \
-    } while (0)
+#define DO_CP_IN_MEMBER(name, obj, member)                      \
+        DO_CP(name, &((obj)->member), NULL)
 
-#define DO_MIGRATE_MEMBER_IF_RECURSIVE(name, obj, newobj, member, recur)    \
-    do {                                                                    \
-        typeof(obj->member) *(objp) = (newobj) ?                            \
-                                      &(newobj)->member : NULL;             \
-                                                                            \
-        DO_MIGRATE_IF_RECURSIVE(name, (obj)->member, (objp), (recur));      \
-    } while (0);
-
-#define DO_MIGRATE_IF_RECURSIVE(name, obj, objp, recur)                     \
-    do {                                                                    \
-        extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);         \
-        if (!obj)                                                           \
-            break;                                                          \
-                                                                            \
-        struct shim_addr_map * _e = get_addr_map_entry (store->addr_map,    \
-                                (ptr_t) (obj), sizeof(*(obj)), 0);          \
-                                                                            \
-        if (!_e && !recursive)                                              \
-        {                                                                   \
-            if (!dry && objp) *objp = NULL;                                 \
-            break;                                                          \
-        }                                                                   \
-                                                                            \
-        if (_e && !ENTRY_JUST_CREATED(_e->offset) && !(recur))              \
-        {                                                                   \
-            if (!dry && objp)                                               \
-                *((typeof(obj) *) objp) = (typeof(obj))                     \
-                                          (base + _e->offset);              \
-            break;                                                          \
-        }                                                                   \
-                                                                            \
-        /* 3 condition we need to run a recursive search                    \
-               _e && !recursive && dry && recur                             \
-               !_e && recursive && dry                                      \
-               _e && !dry               */                                  \
-        if (dry ?                                                           \
-            (_e ? !recursive && (recur) : recursive) : _e != NULL)          \
-                __DO_MIGRATE(name, (obj), (objp), (recur));                 \
-    } while (0)
-
-#define DO_MIGRATE_IN_MEMBER(name, obj, newobj, member, recur)              \
-    __DO_MIGRATE(name, dry ? &(obj)->member : &(newobj)->member,            \
-                 NULL, (recur))
+struct shim_cp_map_entry { void * addr; ptr_t off; };
 
-#define CHECKPOINT_ADDR (NULL)
+void * create_cp_map (void);
+void destroy_cp_map (void * map);
 
-#define MAP_UNALLOCATED 0x8000000000000000
-#define MAP_UNASSIGNED  0x4000000000000000
-#define MAP_UNUSABLE (MAP_UNALLOCATED|MAP_UNASSIGNED)
+struct shim_cp_map_entry *
+get_cp_map_entry (void * map, void * addr, bool create);
 
-#define ENTRY_JUST_CREATED(off) (off & MAP_UNUSABLE)
-
-static inline __attribute__((always_inline))
-ptr_t add_to_migrate_map (void * map, void * obj, ptr_t off,
-                          size_t size, bool dry)
-{
-    struct shim_addr_map * e = get_addr_map_entry(map,
-                    (ptr_t) obj, size, 1);
-
-    ptr_t result = e->offset;
-    if (dry) {
-        if (result & MAP_UNALLOCATED)
-            e->offset = MAP_UNASSIGNED;
-        else
-            result = 0;
-    } else {
-        if (result & MAP_UNUSABLE) {
-            assert(size);
-            assert(off >= size);
-            e->offset = off - size;
-            e->size = size;
-        }
-    }
+#define GET_FROM_CP_MAP(obj)                                    \
+    ({                                                          \
+        struct shim_cp_map_entry * e =                          \
+                get_cp_map_entry(store->cp_map, (obj), false);  \