Browse Source

[Glibc] Update Glibc version to 2.23 and 2.27

Previously, Graphene supported Glibc version 2.19 only. This commit
adds support for Glibc v2.23 (default in Ubuntu 16.04) and Glibc
v2.27 (default in Ubuntu 18.04). The exact version can be chosen by
specifying GLIBC_VERSION during Graphene build. The default version
to be built is v2.27.

Note that for the best GDB experience it is advised to build Graphene
with the same Glibc version as installed on the host OS.
Chia-Che Tsai 5 years ago
parent
commit
dc8b63ce62

+ 6 - 0
Jenkinsfiles/Linux

@@ -6,6 +6,12 @@ pipeline {
                 stage('Build') {
                     steps {
                         sh '''
+                            cd LibOS
+                            make -j 8 glibc-build/Build.success GLIBC_VERSION=2.19
+                            rm -r glibc-build
+                            make -j 8 glibc-build/Build.success GLIBC_VERSION=2.23
+                            rm -r glibc-build
+                            cd ..
                             make -j 8 WERROR=1
                             make -j 8 WERROR=1 test
                             cd Pal/ipc/linux

+ 1 - 0
Jenkinsfiles/ubuntu-16.04.dockerfile

@@ -8,6 +8,7 @@ RUN apt-get update \
        autoconf \
        build-essential \
        gawk \
+       bison \
        gettext \
        git \
        libexpat1 \

+ 1 - 0
Jenkinsfiles/ubuntu-18.04.dockerfile

@@ -7,6 +7,7 @@ RUN apt-get update && apt-get install -y \
     autoconf \
     build-essential \
     gawk \
+    bison \
     gettext \
     git \
     libexpat1 \

+ 33 - 16
LibOS/Makefile

@@ -3,9 +3,9 @@ export SYS
 
 export DEBUG
 
-# GLIBC_DISABLE_VDSO = true
-GLIBC_SRC = glibc-2.19
-GLIBC_CHECKSUM = 18ad6db70724699d264add80b1f813630d0141cf3a3558b4e1a7c15f6beac796
+GLIBC_VERSION ?= 2.27
+GLIBC_SRC = glibc-$(GLIBC_VERSION)
+GLIBC_CHECKSUM = $(firstword $(shell grep $(GLIBC_SRC).tar.gz glibc-checksums))
 SHIM_DIR = shim
 BUILD_DIR = glibc-build
 RUNTIME_DIR = $(CURDIR)/../Runtime
@@ -45,15 +45,14 @@ ifeq ($(findstring x86_64,$(SYS))$(findstring linux,$(SYS)),x86_64linux)
 $(BUILD_DIR)/Build.success: $(BUILD_DIR)/Makefile
 	@echo "Building glibc, may take a while to finish. Warning messages may show up. If this process terminates with failures, see \"$(BUILD_DIR)/build.log\" for more information."
 	($(MAKE) PARALLELMFLAGS='-j `nproc`' -C $(BUILD_DIR) 2>&1 >> build.log) && touch $@
-#  2>&1 | tee -a build.log)
 
 $(GLIBC_TARGET): $(BUILD_DIR)/Build.success
 
 $(BUILD_DIR)/Makefile: $(GLIBC_SRC)/configure
 ifeq ($(DEBUG),1)
-	./buildglibc.py --quiet --debug
+	./buildglibc.py --src $(GLIBC_SRC) --quiet --debug
 else
-	./buildglibc.py --quiet
+	./buildglibc.py --src $(GLIBC_SRC) --quiet
 endif
 
 define LN_SF_TO_RUNTIME_DIR_template =
@@ -67,23 +66,42 @@ GLIBC_MIRRORS ?= https://ftp.gnu.org/gnu/ \
 		https://mirrors.kernel.org/gnu/ \
 		https://mirrors.ocf.berkeley.edu/gnu/
 
-ifeq ($(shell git ls-files $(GLIBC_SRC)/configure),)
 GLIBC_PATCHES = \
-	$(GLIBC_SRC).patch \
-	glibc-syscalldb-api.patch \
-	glibc-fix-warning.patch \
-	glibc-no-pie.patch \
-	glibc-liblibos.patch
+	glibc-patches/$(GLIBC_SRC).patch \
+	glibc-patches/syscalldb-api.patch \
+	glibc-patches/liblibos.patch \
+	glibc-patches/malloc-arena-size.patch
+
+GLIBC_PATCHES_2.19 = \
+	glibc-patches/fix-make-warnings.patch \
+	glibc-patches/no-pie.patch \
+	glibc-patches/liblibos-2.19.patch \
+	glibc-patches/hp-timing-2.19.patch
+
+GLIBC_PATCHES_2.23 = \
+	glibc-patches/liblibos-2.23+.patch \
+	glibc-patches/hp-timing-2.23+.patch \
+	glibc-patches/dangling-else.patch \
+	glibc-patches/cvs-common-symbols.patch \
+	glibc-patches/rpc-format-overflow.patch \
+	glibc-patches/ieee754-boolean-context.patch \
+	glibc-patches/nis-bogus-conditional.patch
+
+GLIBC_PATCHES_2.27 = \
+	glibc-patches/liblibos-2.23+.patch \
+	glibc-patches/hp-timing-2.23+.patch
 
 ifeq ($(GLIBC_DISABLE_VDSO),true)
-GLIBC_PATCHES += \
-	glibc-2.19-remove-vdso.patch
+GLIBC_PATCHES_2.19 += \
+	glibc-patches/glibc-2.19-remove-vdso.patch
 endif
 
 ifneq ($(filter %.gold,$(shell readlink -f /usr/bin/ld)),)
-GLIBC_PATCHES += glibc-ld.gold.patch
+GLIBC_PATCHES += glibc-patches/ld-gold.patch
 endif
 
+GLIBC_PATCHES += $(GLIBC_PATCHES_$(GLIBC_VERSION))
+
 $(GLIBC_SRC)/configure: $(GLIBC_PATCHES) $(GLIBC_SRC).tar.gz
 	[ "`sha256sum $(GLIBC_SRC).tar.gz`" = "$(GLIBC_CHECKSUM)  $(GLIBC_SRC).tar.gz" ] || \
 		(echo "*** $(GLIBC_SRC).tar.gz has a wrong checksum ***"; exit 255)
@@ -95,7 +113,6 @@ $(GLIBC_SRC)/configure: $(GLIBC_PATCHES) $(GLIBC_SRC).tar.gz
 		patch -p1 < ../$$p || exit 255; \
 	done
 	touch $@
-endif
 
 $(GLIBC_SRC).tar.gz:
 	for MIRROR in $(GLIBC_MIRRORS); do \

+ 11 - 1
LibOS/buildglibc.py

@@ -4,6 +4,7 @@ import os
 import shutil
 import subprocess
 import sys
+from pkg_resources import parse_version
 
 def prependText(filename, text) :
     data = ""
@@ -29,12 +30,18 @@ commandOutput = ""
 quiet = False
 debug_flags = ""
 
+index = 0
 for arg in sys.argv[1:]:
+    index += 1
+    if (arg == '--src' or arg == '-s') and index + 1 < len(sys.argv):
+        glibc = sys.argv[index + 1]
     if arg == '--quiet' or arg == '-q':
         quiet = True
     if arg == '--debug':
         debug_flags = "-g"
 
+version = parse_version(glibc.replace("glibc-", ""))
+
 if True:
 
     #########################################
@@ -99,7 +106,10 @@ if True:
     cflags = '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector -Wno-unused-value'.format(debug_flags)
     extra_defs = ''
     disabled_features = { 'nscd' }
-    extra_flags = '--with-tls --enable-add-ons=nptl --without-selinux --disable-test {0}'.format(' '.join(['--disable-' + f for f in disabled_features]))
+    extra_flags = '--with-tls --without-selinux --disable-test {0}'.format(' '.join(['--disable-' + f for f in disabled_features]))
+
+    if version <= parse_version('2.21'):
+        extra_flags += ' --enable-add-ons=nptl'
 
     ##    configure
     commandStr = r'CFLAGS="{2}" {3} {0}/configure --prefix={1} {4} | tee configure.out'.format(glibc, installDir, cflags, extra_defs, extra_flags)

+ 3 - 0
LibOS/glibc-checksums

@@ -0,0 +1,3 @@
+18ad6db70724699d264add80b1f813630d0141cf3a3558b4e1a7c15f6beac796  glibc-2.19.tar.gz
+2bd08abb24811cda62e17e61e9972f091f02a697df550e2e44ddcfb2255269d2  glibc-2.23.tar.gz
+881ca905e6b5eec724de7948f14d66a07d97bdee8013e1b2a7d021ff5d540522  glibc-2.27.tar.gz

+ 24 - 0
LibOS/glibc-patches/cvs-common-symbols.patch

@@ -0,0 +1,24 @@
+diff --git a/misc/regexp.c b/misc/regexp.c
+index 19d76c0c37..eaea7c3b89 100644
+--- a/misc/regexp.c
++++ b/misc/regexp.c
+@@ -29,14 +29,15 @@
+
+ #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_23)
+
+-/* Define the variables used for the interface.  */
+-char *loc1;
+-char *loc2;
++/* Define the variables used for the interface.  Avoid .symver on common
++   symbol, which just creates a new common symbol, not an alias.  */
++char *loc1 __attribute__ ((nocommon));
++char *loc2 __attribute__ ((nocommon));
+ compat_symbol (libc, loc1, loc1, GLIBC_2_0);
+ compat_symbol (libc, loc2, loc2, GLIBC_2_0);
+
+ /* Although we do not support the use we define this variable as well.  */
+-char *locs;
++char *locs __attribute__ ((nocommon));
+ compat_symbol (libc, locs, locs, GLIBC_2_0);
+
+

+ 42 - 0
LibOS/glibc-patches/dangling-else.patch

@@ -0,0 +1,42 @@
+diff -ruNp old/stdlib/setenv.c new/stdlib/setenv.c
+--- old/stdlib/setenv.c
++++ new/stdlib/setenv.c
+@@ -276,7 +276,7 @@ unsetenv (const char *name)
+   LOCK;
+ 
+   ep = __environ;
+-  if (ep != NULL)
++  if (ep != NULL) {
+     while (*ep != NULL)
+       if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
+ 	{
+@@ -288,8 +288,9 @@ unsetenv (const char *name)
+ 	  while (*dp++);
+ 	  /* Continue the loop in case NAME appears again.  */
+ 	}
+       else
+ 	++ep;
++  }
+ 
+   UNLOCK;
+ 
+diff -ruNp old/nis/nis_call.c new/nis/nis_call.c
+--- old/nis/nis_call.c
++++ new/nis/nis_call.c
+@@ -679,7 +679,7 @@ nis_server_cache_add (const_nis_name nam
+ 
+   /* Choose which entry should be evicted from the cache.  */
+   loc = &nis_server_cache[0];
+-  if (*loc != NULL)
++  if (*loc != NULL) {
+     for (i = 1; i < 16; ++i)
+       if (nis_server_cache[i] == NULL)
+ 	{
+@@ -690,6 +690,7 @@ nis_server_cache_add (const_nis_name nam
+ 	       || ((*loc)->uses == nis_server_cache[i]->uses
+ 		   && (*loc)->expires > nis_server_cache[i]->expires))
+ 	loc = &nis_server_cache[i];
++  }
+   old = *loc;
+   *loc = new;
+ 

+ 0 - 0
LibOS/glibc-fix-warning.patch → LibOS/glibc-patches/fix-make-warnings.patch


+ 0 - 0
LibOS/glibc-2.19-remove-vdso.patch → LibOS/glibc-patches/glibc-2.19-remove-vdso.patch


+ 6 - 248
LibOS/glibc-2.19.patch → LibOS/glibc-patches/glibc-2.19.patch

@@ -29,30 +29,6 @@ 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
@@ -61,18 +37,6 @@ index 759c754..e1a270e 100644
  }
  libthread_db {
    GLIBC_2.1.3
-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
@@ -100,16 +64,6 @@ diff --git a/elf/Versions b/elf/Versions
 index 2383992..98687f6 100644
 --- a/elf/Versions
 +++ b/elf/Versions
-@@ -24,6 +24,9 @@ libc {
-     _dl_sym; _dl_vsym;
-     __libc_dlclose; __libc_dlopen_mode; __libc_dlsym;
-   }
-+  SHIM {
-+    syscalldb; glibc_option;
-+  }
- }
- 
- ld {
 @@ -62,4 +65,7 @@ ld {
      # Pointer protection.
      __pointer_chk_guard;
@@ -118,39 +72,6 @@ index 2383992..98687f6 100644
 +    syscalldb; glibc_version; glibc_option; register_library;
 +  }
  }
-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
-    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;
- 
- 
- /* Initialize _r_debug if it has not already been done.  The argument is
-@@ -48,7 +48,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase,
-   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,
-     {
-       /* 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;
-     }
- 
-   return r;
 diff --git a/elf/dl-load.c b/elf/dl-load.c
 index 1be7a3c..c560ec1 100644
 --- a/elf/dl-load.c
@@ -174,18 +95,6 @@ index 1be7a3c..c560ec1 100644
    /* Now that the object is fully initialized add it to the object list.  */
    _dl_add_to_namespace_list (l, nsid);
  
-diff --git a/elf/link.h b/elf/link.h
-index d5905d1..f4e108a 100644
---- a/elf/link.h
-+++ b/elf/link.h
-@@ -65,6 +65,7 @@ struct r_debug
- 
- /* This is the instance of that structure used by the dynamic linker.  */
- extern struct r_debug _r_debug;
-+asm (".symver _r_debug, __libc_r_debug@GLIBC_PRIVATE");
- 
- /* 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/rtld.c b/elf/rtld.c
 index 6dcbabc..c87c773 100644
 --- a/elf/rtld.c
@@ -198,7 +107,7 @@ index 6dcbabc..c87c773 100644
 +   library. If not, tell the user to update glibc. */
 +#include "glibc-version.h"
 +
-+volatile const int glibc_version __attribute__((weak)) = GLIBC_VERSION;
++const unsigned int glibc_version __attribute__((weak)) = GLIBC_VERSION;
 +
 +static void __attribute__((noinline,optimize("-O0")))
 +check_glibc_version (void)
@@ -224,112 +133,18 @@ index 6dcbabc..c87c773 100644
    /* 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
-diff --git a/malloc/arena.c b/malloc/arena.c
-index 5088a25..33a3879 100644
---- a/malloc/arena.c
-+++ b/malloc/arena.c
-@@ -21,6 +21,27 @@
- 
- /* Compile-time constants.  */
- 
-+#ifndef HEAP_MAX_SIZE
-+# ifdef DEFAULT_MMAP_THRESHOLD_MAX
-+#  define DEFAULT_HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX)
-+# else
-+#  define DEFAULT_HEAP_MAX_SIZE (1024 * 1024) /* must be a power of two */
-+# endif
-+# include <sysdep.h>
-+static long int heap_max_size = 0;
-+# define HEAP_MAX_SIZE								\
-+	({									\
-+		if (!heap_max_size) {						\
-+			long int size = glibc_option("heap_size");		\
-+			if (size > 0)						\
-+				heap_max_size = size;				\
-+			else							\
-+				heap_max_size = DEFAULT_HEAP_MAX_SIZE;		\
-+		}								\
-+		heap_max_size;							\
-+	})
-+#endif
-+
- #define HEAP_MIN_SIZE (32 * 1024)
- #ifndef HEAP_MAX_SIZE
- # ifdef DEFAULT_MMAP_THRESHOLD_MAX
-@@ -545,17 +566,6 @@ new_heap (size_t size, size_t top_pad)
-      mapping (on Linux, this is the case for all non-writable mappings
-      anyway). */
-   p2 = MAP_FAILED;
--  if (aligned_heap_area)
--    {
--      p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
--                          MAP_NORESERVE);
--      aligned_heap_area = NULL;
--      if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)))
--        {
--          __munmap (p2, HEAP_MAX_SIZE);
--          p2 = MAP_FAILED;
--        }
--    }
-   if (p2 == MAP_FAILED)
-     {
-       p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE);
-@@ -566,8 +576,6 @@ new_heap (size_t size, size_t top_pad)
-           ul = p2 - p1;
-           if (ul)
-             __munmap (p1, ul);
--          else
--            aligned_heap_area = p2 + HEAP_MAX_SIZE;
-           __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
-         }
-       else
-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..354149a 100644
---- a/nptl/Versions
-+++ b/nptl/Versions
-@@ -31,6 +31,9 @@ libc {
-     # Internal libc interface to libpthread
-     __libc_dl_error_tsd;
-   }
-+  SHIM {
-+    syscalldb; glibc_option;
-+  }
- }
- 
- libpthread {
-@@ -262,4 +265,8 @@ libpthread {
-     __pthread_clock_gettime; __pthread_clock_settime;
-     __pthread_unwind; __pthread_get_minstack;
-   }
-+
-+  SHIM {
-+    syscalldb; glibc_option;
-+  }
- }
 diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
 index 89fda5e..f6963f6 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)
+@@ -111,7 +111,7 @@ ENTRY(__pthread_disable_asynccancel)
  	xorq	%r10, %r10
  	addq	$CANCELHANDLING, %rdi
  	LOAD_PRIVATE_FUTEX_WAIT (%esi)
 -	syscall
 +	SYSCALLDB
-+
  	movl	%fs:CANCELHANDLING, %eax
  	jmp	3b
  END(__pthread_disable_asynccancel)
@@ -595,7 +410,8 @@ index 0dc2340..8aff242 100644
  	subq	$cond_nwaiters, %rdi
  
  55:	LOCK
-@@ -493,6 +488,6 @@
+@@ -492,7 +492,7 @@ __pthread_cond_timedwait:
+ 	call	*%rax
  #  else
  	movl	$__NR_clock_gettime, %eax
 -	syscall
@@ -857,14 +673,6 @@ index cbb5e9e..9b87e25 100644
    int rtld_must_xmm_save;
    /* Reservation of some values for the TM ABI.  */
    void *__private_tm[4];
-@@ -137,7 +143,6 @@ typedef struct
- # define GET_DTV(descr) \
-   (((tcbhead_t *) (descr))->dtv)
- 
--
- /* Code to initially initialize the thread pointer.  This might need
-    special attention since 'errno' is not yet available and if the
-    operation can cause a failure 'errno' must not be touched.
 @@ -154,7 +159,7 @@ typedef struct
       _head->self = _thrdescr;						      \
  									      \
@@ -874,22 +682,6 @@ index cbb5e9e..9b87e25 100644
  		   : "=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/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
 index 2468228..a9f1cd6 100644
 --- a/sysdeps/unix/sysv/linux/_exit.c
@@ -1012,12 +804,7 @@ diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/
 index 92c2f5b..e32ebb2 100644
 --- a/sysdeps/unix/sysv/linux/x86_64/syscall.S
 +++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S
-@@ -31,10 +31,12 @@
- 	movq %rsi, %rdi		/* shift arg1 - arg5.  */
- 	movq %rdx, %rsi
- 	movq %rcx, %rdx
-+	/* DEP 8/17/17: Keep kernel calling
-+	 * 	convention and fix in libOS */
+@@ -34,7 +34,7 @@
  	movq %r8, %r10
  	movq %r9, %r8
  	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
@@ -1043,7 +830,7 @@ index 4a9a9d9..dc452ed 100644
      DOARGS_##args				\
      movl $SYS_ify (syscall_name), %eax;		\
 -    syscall;
-+    SYSCALLDB
++    SYSCALLDB;
  
  # define DOARGS_0 /* nothing */
  # define DOARGS_1 /* nothing */
@@ -1141,32 +928,3 @@ index 504c95f..dcfc259 100644
      _dl_reloc_bad_type (map, r_type, 1);
  }
  
-diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h
-index d88206c..886c500 100644
---- a/sysdeps/x86_64/hp-timing.h
-+++ b/sysdeps/x86_64/hp-timing.h
-@@ -18,23 +18,6 @@
- 
- #ifndef _HP_TIMING_H
- 
--/* We can use some of the i686 implementation without changes.  */
--# include <sysdeps/i386/i686/hp-timing.h>
--
--/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode.  */
--# undef HP_TIMING_NOW
--# define HP_TIMING_NOW(Var) \
--  ({ unsigned int _hi, _lo; \
--     asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
--     (Var) = ((unsigned long long int) _hi << 32) | _lo; })
--
--/* The funny business for 32-bit mode is not required here.  */
--# undef HP_TIMING_ACCUM
--# define HP_TIMING_ACCUM(Sum, Diff)					      \
--  do {									      \
--    hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead);		      \
--    __asm__ __volatile__ ("lock; addq %1, %0"				      \
--			  : "=m" (Sum) : "r" (__diff), "m" (Sum));	      \
--  } while (0)
-+# include <sysdeps/generic/hp-timing.h>
- 
- #endif /* hp-timing.h */

+ 641 - 0
LibOS/glibc-patches/glibc-2.23.patch

@@ -0,0 +1,641 @@
+diff -ruNp a/elf/dl-load.c b/elf/dl-load.c
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -45,6 +45,7 @@
+ #include <dl-machine-reject-phdr.h>
+ #include <dl-sysdep-open.h>
+ 
++#include <glibc-version.h>
+ 
+ #include <endian.h>
+ #if BYTE_ORDER == BIG_ENDIAN
+@@ -1415,6 +1416,9 @@ cannot enable executable stack as shared
+   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 -ruNp a/elf/Makefile b/elf/Makefile
+--- 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	= $(all-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	= $(all-dl-routines) dl-support
+ 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 -ruNp a/elf/rtld.c b/elf/rtld.c
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -332,6 +332,23 @@ _dl_start_final (void *arg, struct dl_st
+   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"
++
++const unsigned int glibc_version __attribute__((weak)) = GLIBC_VERSION;
++
++static void __attribute__((noinline,optimize("-O0")))
++check_glibc_version (void)
++{
++  if (glibc_version != GLIBC_VERSION)
++    {
++      _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)
+ {
+@@ -402,6 +419,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
+diff -ruNp a/elf/Versions b/elf/Versions
+--- a/elf/Versions
++++ b/elf/Versions
+@@ -65,4 +68,7 @@ ld {
+     # Pointer protection.
+     __pointer_chk_guard;
+   }
++  SHIM {
++    syscalldb; glibc_version; glibc_option; register_library;
++  }
+ }
+diff -ruNp a/Makeconfig b/Makeconfig
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -841,7 +841,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.
+diff -ruNp a/Makefile b/Makefile
+--- a/Makefile
++++ b/Makefile
+@@ -178,6 +178,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 -ruNp a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
+--- a/sysdeps/unix/sysv/linux/_exit.c
++++ b/sysdeps/unix/sysv/linux/_exit.c
+@@ -28,9 +28,9 @@ _exit (int 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+--- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S
++++ b/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+@@ -111,7 +111,7 @@ ENTRY(__pthread_disable_asynccancel)
+ 	xorq	%r10, %r10
+ 	addq	$CANCELHANDLING, %rdi
+ 	LOAD_PRIVATE_FUTEX_WAIT (%esi)
+-	syscall
++	SYSCALLDB
+ 	movl	%fs:CANCELHANDLING, %eax
+ 	jmp	3b
+ END(__pthread_disable_asynccancel)
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
+--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
++++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
+@@ -76,7 +76,7 @@ ENTRY (__clone)
+ 	/* End FDE now, because in the child the unwind info will be
+ 	   wrong.  */
+ 	cfi_endproc;
+-	syscall
++	SYSCALLDB
+ 
+ 	testq	%rax,%rax
+ 	jl	SYSCALL_ERROR_LABEL
+@@ -98,7 +98,7 @@ L(thread_start):
+ 	movl	$-1, %eax
+ 	jne	2f
+ 	movl	$SYS_ify(getpid), %eax
+-	syscall
++	SYSCALLDB
+ 2:	movl	%eax, %fs:PID
+ 	movl	%eax, %fs:TID
+ 1:
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+--- 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
++	SYSCALLDB
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+--- 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
++	SYSCALLDB
++
+ 	/* Without working sigaltstack we cannot perform the test.  */
+ 	testl	%eax, %eax
+ 	jne	.Lok2
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+--- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
++++ b/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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 	/* 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
++	SYSCALLDB
+ 
+ 	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
++	SYSCALLDB
+ 
+ 	popq	%rdx
+ 	cfi_adjust_cfa_offset(-8)
+@@ -436,7 +436,7 @@ __lll_timedwait_tid:
+ #endif
+ 	movq	%r12, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	cmpl	$0, (%rdi)
+ 	jne	1f
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+--- a/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
++++ b/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+@@ -80,7 +80,7 @@ __lll_robust_lock_wait:
+ 	jnz	2f
+ 
+ 1:	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	movl	(%rdi), %eax
+ 
+@@ -145,7 +145,7 @@ __lll_robust_timedlock_wait:
+ 	jnz	6f
+ 
+ 5:	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 	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
++	SYSCALLDB
+ 	movq	%rax, %rcx
+ 
+ 	movl	(%r12), %eax
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+--- a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
++++ b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+@@ -87,7 +87,7 @@ ENTRY(__pthread_cond_broadcast)
+ 	movl	$SYS_futex, %eax
+ 	movl	$1, %edx
+ 	movl	$0x7fffffff, %r10d
+-	syscall
++	SYSCALLDB
+ 
+ 	/* For any kind of error, which mainly is EAGAIN, we try again
+ 	   with WAKE.  The general test also covers running on old
+@@ -103,7 +103,7 @@ ENTRY(__pthread_cond_broadcast)
+ 	movl	$SYS_futex, %eax
+ 	movl	$1, %edx
+ 	movl	$0x7fffffff, %r10d
+-	syscall
++	SYSCALLDB
+ 
+ 	/* For any kind of error, which mainly is EAGAIN, we try again
+ 	   with WAKE.  The general test also covers running on old
+@@ -169,7 +169,7 @@ ENTRY(__pthread_cond_broadcast)
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 	jmp	10b
+ END(__pthread_cond_broadcast)
+ 
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+--- a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
++++ b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+@@ -78,7 +78,7 @@ ENTRY(__pthread_cond_signal)
+ 	addq	$cond_lock, %r8
+ #endif
+ 	movl	$FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
+-	syscall
++	SYSCALLDB
+ #if cond_lock != 0
+ 	subq	$cond_lock, %r8
+ #endif
+@@ -95,7 +95,7 @@ ENTRY(__pthread_cond_signal)
+ 	movq	%rcx, %r8
+ 	xorq	%r10, %r10
+ 	movl	(%rdi), %r9d	// XXX Can this be right?
+-	syscall
++	SYSCALLDB
+ 
+ 	leaq	-cond_futex(%rdi), %r8
+ 
+@@ -114,7 +114,7 @@ ENTRY(__pthread_cond_signal)
+ 	movl	$SYS_futex, %eax
+ 	/* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
+ 	movl	$1, %edx  */
+-	syscall
++	SYSCALLDB
+ 
+ 	/* Unlock.  */
+ 4:	LOCK
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+--- a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
++++ b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+@@ -175,7 +175,7 @@ __pthread_cond_timedwait:
+ 	movq	%r12, %rdx
+ 	addq	$cond_futex, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	cmpl	$0, %eax
+ 	sete	%r15b
+@@ -221,7 +221,7 @@ __pthread_cond_timedwait:
+ 	movq	%r12, %rdx
+ 	addq	$cond_futex, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 62:	movq	%rax, %r14
+ 
+ 	movl	(%rsp), %edi
+@@ -308,7 +308,7 @@ __pthread_cond_timedwait:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 	subq	$cond_nwaiters, %rdi
+ 
+ 55:	LOCK
+@@ -521,7 +521,7 @@ __condvar_cleanup2:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 	subq	$cond_nwaiters, %rdi
+ 	movl	$1, %r12d
+ 
+@@ -558,7 +558,7 @@ __condvar_cleanup2:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	/* 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+--- a/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
++++ b/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
++	SYSCALLDB
+ 
+ 	cmpl	$0, %eax
+ 	sete	%r8b
+@@ -180,7 +180,7 @@ __pthread_cond_wait:
+ #endif
+ 60:	xorb	%r8b, %r8b
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 	subq	$cond_nwaiters, %rdi
+ 
+ 17:	LOCK
+@@ -455,7 +455,7 @@ __condvar_cleanup1:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 	subq	$cond_nwaiters, %rdi
+ 	movl	$1, %ecx
+ 
+@@ -493,7 +493,7 @@ __condvar_cleanup1:
+ 	orl	$FUTEX_WAKE, %esi
+ #endif
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	/* 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+--- 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
++	SYSCALLDB
+ 	popq	%rdi			/* Reload %rdi, adjust stack.  */
+ 	cfi_adjust_cfa_offset(-8)
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
++++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+@@ -120,7 +120,7 @@ asm									\
+    "	.type __" #name ",@function\n"					\
+    "__" #name ":\n"							\
+    "	movq $" #syscall ", %rax\n"					\
+-   "	syscall\n"							\
++   SYSCALLDB_ASM							\
+    ".LEND_" #name ":\n"							\
+    ".section .eh_frame,\"a\",@progbits\n"				\
+    ".LSTARTFRAME_" #name ":\n"						\
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+--- 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
++	SYSCALLDB
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
+--- 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.  */
++	SYSCALLDB			/* 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
++++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+@@ -22,6 +22,7 @@
+ #include <sysdeps/unix/sysv/linux/sysdep.h>
+ #include <sysdeps/unix/x86_64/sysdep.h>
+ #include <tls.h>
++#include "syscalldb.h"
+ 
+ #if IS_IN (rtld)
+ # include <dl-sysdep.h>		/* Defines RTLD_PRIVATE_ERRNO.  */
+@@ -177,7 +178,7 @@
+ # define DO_CALL(syscall_name, args)		\
+     DOARGS_##args				\
+     movl $SYS_ify (syscall_name), %eax;		\
+-    syscall;
++    SYSCALLDB;
+ 
+ # define DOARGS_0 /* nothing */
+ # define DOARGS_1 /* nothing */
+@@ -191,9 +192,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);	      \
++    unsigned long int resultvar = INTERNAL_SYSCALL (name, , ##nr_args);	      \
++    if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
++      {									      \
++	__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_ASM (name, , ##nr_args);   \
+     if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -205,9 +217,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 (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -227,13 +239,19 @@
+     LOAD_ARGS_##nr (args)						      \
+     LOAD_REGS_##nr							      \
+     asm volatile (							      \
+-    "syscall\n\t"							      \
++    SYSCALLDB								      \
+     : "=a" (resultvar)							      \
+     : "0" (name) ASM_ARGS_##nr : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);   \
+     (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...) \
+   ({									      \
+@@ -241,7 +259,7 @@
+     LOAD_ARGS_TYPES_##nr (args)						      \
+     LOAD_REGS_TYPES_##nr (args)						      \
+     asm volatile (							      \
+-    "syscall\n\t"							      \
++    SYSCALLDB								      \
+     : "=a" (resultvar)							      \
+     : "0" (name) ASM_ARGS_##nr : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);   \
+     (long int) resultvar; })
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
++++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+@@ -46,7 +46,7 @@ ENTRY (__vfork)
+ 
+ 	/* Stuff the syscall number in RAX and enter into the kernel.  */
+ 	movl	$SYS_ify (vfork), %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	/* Push back the return PC.  */
+ 	pushq	%rdi
+diff -ruNp a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -554,7 +554,8 @@ elf_machine_lazy_rel (struct link_map *m
+ 	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);
+ }
+ 
+diff -ruNp a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
+--- a/sysdeps/x86_64/nptl/tls.h
++++ b/sysdeps/x86_64/nptl/tls.h
+@@ -28,6 +28,8 @@
+ # include <sysdep.h>
+ # include <libc-internal.h>
+ # include <kernel-features.h>
++# include <shim_tls.h>
++# include <syscalldb.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 +69,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 __glibc_unused1;
+   /* Reservation of some values for the TM ABI.  */
+   void *__private_tm[4];
+@@ -138,7 +144,6 @@ typedef struct
+ # define GET_DTV(descr) \
+   (((tcbhead_t *) (descr))->dtv)
+ 
+-
+ /* Code to initially initialize the thread pointer.  This might need
+    special attention since 'errno' is not yet available and if the
+    operation can cause a failure 'errno' must not be touched.
+@@ -155,7 +160,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),		      \

+ 489 - 0
LibOS/glibc-patches/glibc-2.27.patch

@@ -0,0 +1,489 @@
+diff -ruNp a/elf/dl-load.c b/elf/dl-load.c
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -46,6 +46,7 @@
+ #include <dl-machine-reject-phdr.h>
+ #include <dl-sysdep-open.h>
+ 
++#include <glibc-version.h>
+ 
+ #include <endian.h>
+ #if BYTE_ORDER == BIG_ENDIAN
+@@ -1318,6 +1319,9 @@ cannot enable executable stack as shared
+   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 -ruNp a/elf/Makefile b/elf/Makefile
+--- 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	= $(all-dl-routines) dl-support dl-iteratephdr \
+ 		  dl-addr dl-addr-obj enbl-secure dl-profstub \
+ 		  dl-origin dl-libc dl-sym dl-sysdep dl-error \
+@@ -33,7 +33,8 @@ dl-routines	= $(addprefix dl-,load looku
+ 				  runtime init fini debug misc \
+ 				  version profile tls origin scope \
+ 				  execstack caller open close trampoline \
+-				  exception sort-maps)
++				  exception sort-maps) \
++		  syscalldb syscallas
+ ifeq (yes,$(use-ldconfig))
+ dl-routines += dl-cache
+ endif
+diff -ruNp a/elf/rtld.c b/elf/rtld.c
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -439,6 +439,23 @@ _dl_start_final (void *arg, struct dl_st
+   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"
++
++const unsigned int glibc_version __attribute__((weak)) = GLIBC_VERSION;
++
++static void __attribute__((noinline,optimize("-O0")))
++check_glibc_version (void)
++{
++  if (glibc_version != GLIBC_VERSION)
++    {
++      _dl_fatal_printf ("Warning from Graphene: "
++                        "Glibc version is incorrect. Please rebuild Glibc.\n");
++      _exit (1);
++    }
++}
++
+ static ElfW(Addr) __attribute_used__
+ _dl_start (void *arg)
+ {
+@@ -510,6 +527,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
+diff -ruNp a/elf/Versions b/elf/Versions
+--- a/elf/Versions
++++ b/elf/Versions
+@@ -79,4 +82,7 @@ ld {
+     # Set value of a tunable.
+     __tunable_get_val;
+   }
++  SHIM {
++    syscalldb; glibc_version; glibc_option; register_library;
++  }
+ }
+diff -ruNp a/Makeconfig b/Makeconfig
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -916,7 +916,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.
+diff -ruNp a/Makefile b/Makefile
+--- a/Makefile
++++ b/Makefile
+@@ -179,6 +179,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 -ruNp a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
+--- a/sysdeps/unix/sysv/linux/_exit.c	2018-02-01 10:17:18.000000000 -0600
++++ b/sysdeps/unix/sysv/linux/_exit.c	2019-05-27 17:26:39.209526816 -0500
+@@ -28,9 +28,9 @@ _exit (int 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+--- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S
++++ b/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+@@ -109,7 +109,7 @@ ENTRY(__pthread_disable_asynccancel)
+ 	xorq	%r10, %r10
+ 	addq	$CANCELHANDLING, %rdi
+ 	LOAD_PRIVATE_FUTEX_WAIT (%esi)
+-	syscall
++	SYSCALLDB
+ 	movl	%fs:CANCELHANDLING, %eax
+ 	jmp	3b
+ END(__pthread_disable_asynccancel)
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
+--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
++++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
+@@ -73,7 +73,7 @@ ENTRY (__clone)
+ 	/* End FDE now, because in the child the unwind info will be
+ 	   wrong.  */
+ 	cfi_endproc;
+-	syscall
++	SYSCALLDB
+ 
+ 	testq	%rax,%rax
+ 	jl	SYSCALL_ERROR_LABEL
+@@ -96,7 +96,7 @@ L(thread_start):
+ 	/* Call exit with return value from function call. */
+ 	movq	%rax, %rdi
+ 	movl	$SYS_ify(exit), %eax
+-	syscall
++	SYSCALLDB
+ 	cfi_endproc;
+ 
+ 	cfi_startproc;
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+--- 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
++	SYSCALLDB
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
++++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+@@ -84,7 +84,7 @@ ENTRY(____longjmp_chk)
+ 	xorl	%edi, %edi
+ 	lea	-sizeSS(%rsp), %RSI_LP
+ 	movl	$__NR_sigaltstack, %eax
+-	syscall
++	SYSCALLDB
+ 	/* Without working sigaltstack we cannot perform the test.  */
+ 	testl	%eax, %eax
+ 	jne	.Lok2
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+--- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
++++ b/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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 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
++	SYSCALLDB
+ 
+ 	/* 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
++	SYSCALLDB
+ 
+ 	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
++	SYSCALLDB
+ 
+ 	popq	%rdx
+ 	cfi_adjust_cfa_offset(-8)
+@@ -436,7 +436,7 @@ __lll_timedwait_tid:
+ #endif
+ 	movq	%r12, %rdi
+ 	movl	$SYS_futex, %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	cmpl	$0, (%rdi)
+ 	jne	1f
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+--- 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
++	SYSCALLDB
+ 	popq	%rdi			/* Reload %rdi, adjust stack.  */
+ 	cfi_adjust_cfa_offset(-8)
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
++++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+@@ -120,7 +120,7 @@ asm									\
+    "	.type __" #name ",@function\n"					\
+    "__" #name ":\n"							\
+    "	movq $" #syscall ", %rax\n"					\
+-   "	syscall\n"							\
++   SYSCALLDB_ASM							\
+    ".LEND_" #name ":\n"							\
+    ".section .eh_frame,\"a\",@progbits\n"				\
+    ".LSTARTFRAME_" #name ":\n"						\
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+--- 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
++	SYSCALLDB
+ 	cmpq	$-4095, %rax		/* Check %rax for error.  */
+ 	jae	SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
+ 
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
+--- 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.  */
++	SYSCALLDB		/* 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
++++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+@@ -22,6 +22,7 @@
+ #include <sysdeps/unix/sysv/linux/sysdep.h>
+ #include <sysdeps/unix/x86_64/sysdep.h>
+ #include <tls.h>
++#include "syscalldb.h"
+ 
+ #if IS_IN (rtld)
+ # include <dl-sysdep.h>		/* Defines RTLD_PRIVATE_ERRNO.  */
+@@ -177,7 +178,7 @@
+ # define DO_CALL(syscall_name, args)		\
+     DOARGS_##args				\
+     movl $SYS_ify (syscall_name), %eax;		\
+-    syscall;
++    SYSCALLDB;
+ 
+ # define DOARGS_0 /* nothing */
+ # define DOARGS_1 /* nothing */
+@@ -191,9 +192,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);	      \
++    unsigned long int resultvar = INTERNAL_SYSCALL (name, , ##nr_args);	      \
++    if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
++      {									      \
++	__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_ASM (name, , ##nr_args);   \
+     if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -205,9 +217,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 (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
+       {									      \
+ 	__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));		      \
+@@ -236,12 +248,19 @@
+ #define INTERNAL_SYSCALL_NCS(number, err, nr, args...)			\
+ 	internal_syscall##nr (number, err, args)
+ 
++#undef INTERNAL_SYSCALL_ASM
++#define INTERNAL_SYSCALL_ASM(name, err, nr, args...)			\
++	INTERNAL_SYSCALL_NCS_ASM (SYS_ify (name), err, nr, args)
++
++#undef INTERNAL_SYSCALL_NCS_ASM
++#define INTERNAL_SYSCALL_NCS_ASM INTERNAL_SYSCALL_NCS
++
+ #undef internal_syscall0
+ #define internal_syscall0(number, err, dummy...)			\
+ ({									\
+     unsigned long int resultvar;					\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number)							\
+     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
+@@ -255,7 +270,7 @@
+     TYPEFY (arg1, __arg1) = ARGIFY (arg1);			 	\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1)						\
+     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
+@@ -271,7 +286,7 @@
+     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1), "r" (_a2)				\
+     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
+@@ -289,7 +304,7 @@
+     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3)			\
+     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
+@@ -309,7 +324,7 @@
+     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4)		\
+     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);			\
+@@ -331,7 +346,7 @@
+     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),		\
+       "r" (_a5)								\
+@@ -356,7 +371,7 @@
+     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;			\
+     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;			\
+     asm volatile (							\
+-    "syscall\n\t"							\
++    SYSCALLDB								\
+     : "=a" (resultvar)							\
+     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),		\
+       "r" (_a5), "r" (_a6)						\
+diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
++++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
+@@ -36,7 +36,7 @@ ENTRY (__vfork)
+ 
+ 	/* Stuff the syscall number in RAX and enter into the kernel.  */
+ 	movl	$SYS_ify (vfork), %eax
+-	syscall
++	SYSCALLDB
+ 
+ 	/* Push back the return PC.  */
+ 	pushq	%rdi
+diff -ruNp a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -577,7 +577,8 @@ elf_machine_lazy_rel (struct link_map *m
+ 	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);
+ }
+ 
+diff -ruNp a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
+--- a/sysdeps/x86_64/nptl/tls.h
++++ b/sysdeps/x86_64/nptl/tls.h
+@@ -29,6 +29,8 @@
+ # include <libc-pointer-arith.h> /* For cast_to_integer.  */
+ # include <kernel-features.h>
+ # include <dl-dtv.h>
++# include <shim_tls.h>
++# include <syscalldb.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
+@@ -56,6 +58,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 __glibc_unused1;
+   /* Reservation of some values for the TM ABI.  */
+   void *__private_tm[4];
+@@ -144,7 +149,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),		      \

+ 29 - 0
LibOS/glibc-patches/hp-timing-2.19.patch

@@ -0,0 +1,29 @@
+diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h
+index d88206c..886c500 100644
+--- a/sysdeps/x86_64/hp-timing.h
++++ b/sysdeps/x86_64/hp-timing.h
+@@ -18,23 +18,6 @@
+ 
+ #ifndef _HP_TIMING_H
+ 
+-/* We can use some of the i686 implementation without changes.  */
+-# include <sysdeps/i386/i686/hp-timing.h>
+-
+-/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode.  */
+-# undef HP_TIMING_NOW
+-# define HP_TIMING_NOW(Var) \
+-  ({ unsigned int _hi, _lo; \
+-     asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
+-     (Var) = ((unsigned long long int) _hi << 32) | _lo; })
+-
+-/* The funny business for 32-bit mode is not required here.  */
+-# undef HP_TIMING_ACCUM
+-# define HP_TIMING_ACCUM(Sum, Diff)					      \
+-  do {									      \
+-    hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead);		      \
+-    __asm__ __volatile__ ("lock; addq %1, %0"				      \
+-			  : "=m" (Sum) : "r" (__diff), "m" (Sum));	      \
+-  } while (0)
++#include <sysdeps/generic/hp-timing.h>
+ 
+ #endif /* hp-timing.h */

+ 29 - 0
LibOS/glibc-patches/hp-timing-2.23+.patch

@@ -0,0 +1,29 @@
+diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h
+index d88206c..886c500 100644
+--- a/sysdeps/x86_64/hp-timing.h
++++ b/sysdeps/x86_64/hp-timing.h
+@@ -19,22 +19,5 @@
+ #ifndef _HP_TIMING_H
+-#define _HP_TIMING_H	1
+-
+-/* We always assume having the timestamp register.  */
+-#define HP_TIMING_AVAIL		(1)
+-#define HP_SMALL_TIMING_AVAIL	(1)
+-
+-/* We indeed have inlined functions.  */
+-#define HP_TIMING_INLINE	(1)
+-
+-/* We use 64bit values for the times.  */
+-typedef unsigned long long int hp_timing_t;
+-
+-/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode.  */
+-#define HP_TIMING_NOW(Var) \
+-  ({ unsigned int _hi, _lo; \
+-     asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
+-     (Var) = ((unsigned long long int) _hi << 32) | _lo; })
+-
+-#include <hp-timing-common.h>
++
++#include <sysdeps/generic/hp-timing.h>
+ 
+ #endif /* hp-timing.h */

+ 24 - 0
LibOS/glibc-patches/ieee754-boolean-context.patch

@@ -0,0 +1,24 @@
+diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
+index 663fa39..bd758b5 100644
+--- a/sysdeps/ieee754/dbl-64/e_pow.c
++++ b/sysdeps/ieee754/dbl-64/e_pow.c
+@@ -466,15 +466,15 @@  checkint (double x)
+     return (n & 1) ? -1 : 1;	/* odd or even */
+   if (k > 20)
+     {
+-      if (n << (k - 20))
++      if (n << (k - 20) != 0)
+ 	return 0;		/* if not integer */
+-      return (n << (k - 21)) ? -1 : 1;
++      return (n << (k - 21) != 0) ? -1 : 1;
+     }
+   if (n)
+     return 0;			/*if  not integer */
+   if (k == 20)
+     return (m & 1) ? -1 : 1;
+-  if (m << (k + 12))
++  if (m << (k + 12) != 0)
+     return 0;
+-  return (m << (k + 11)) ? -1 : 1;
++  return (m << (k + 11) != 0) ? -1 : 1;
+ }

+ 0 - 0
LibOS/glibc-ld.gold.patch → LibOS/glibc-patches/ld-gold.patch


+ 25 - 0
LibOS/glibc-patches/liblibos-2.19.patch

@@ -0,0 +1,25 @@
+diff --git a/Versions.def b/Versions.def
+index 759c754..e1a270e 100644
+--- a/Versions.def
++++ b/Versions.def
+@@ -148,3 +152,6 @@ libanl {
+ libcidn {
+   GLIBC_PRIVATE
+ }
++liblibos {
++  GLIBC_2.19
++}
+diff --git a/shlib-versions b/shlib-versions
+index 78b0ad7..5c3dcf2 100644
+--- a/shlib-versions
++++ b/shlib-versions
+@@ -64,6 +64,9 @@ sh.*-.*-linux.*		ld=ld-linux.so.2	GLIBC_
+ # The -ldl interface (see <dlfcn.h>) is the same on all platforms.
+ .*-.*-.*		libdl=2
+ 
++# Interface for Graphene
++.*-.*-.*		liblibos=1
++
+ # So far the -lutil interface is the same on all platforms, except for the
+ # `struct utmp' format, which depends on libc.
+ .*-.*-.*		libutil=1

+ 14 - 0
LibOS/glibc-patches/liblibos-2.23+.patch

@@ -0,0 +1,14 @@
+diff --git a/shlib-versions b/shlib-versions
+index 78b0ad7..5c3dcf2 100644
+--- a/shlib-versions
++++ b/shlib-versions
+@@ -64,6 +64,9 @@ sh.*-.*-linux.*		ld=ld-linux.so.2	GLIBC_
+ # The -ldl interface (see <dlfcn.h>) is the same on all platforms.
+ libdl=2
+ 
++# Interface for Graphene
++liblibos=1
++
+ # So far the -lutil interface is the same on all platforms, except for the
+ # `struct utmp' format, which depends on libc.
+ libutil=1

+ 6 - 28
LibOS/glibc-liblibos.patch → LibOS/glibc-patches/liblibos.patch

@@ -2,36 +2,14 @@ diff --git a/Makeconfig b/Makeconfig
 index 1908f27..cf34ba1 100644
 --- a/Makeconfig
 +++ b/Makeconfig
-@@ -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
+@@ -1100,4 +1100,7 @@ all-subdirs = csu assert ctype locale in
+ 	      $(add-on-subdirs) dlfcn elf
  
++# Add libos for Graphene
++all-subdirs += libos
++
  ifndef avoid-generated
  # sysd-sorted itself will contain rules making the sysd-sorted target
-diff --git a/Versions.def b/Versions.def
-index 759c754..e1a270e 100644
---- a/Versions.def
-+++ b/Versions.def
-@@ -148,3 +152,6 @@ libanl {
- libcidn {
-   GLIBC_PRIVATE
- }
-+liblibos {
-+  GLIBC_2.12
-+}
-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/libos/Makefile b/libos/Makefile
 new file mode 100644
 index 0000000..7e0027d
@@ -101,7 +79,7 @@ index 0000000..3211637
 +++ b/libos/Versions
 @@ -0,0 +1,7 @@
 +liblibos {
-+  GLIBC_2.12 {
++  GLIBC_2.19 {
 +    checkpoint;
 +    msgpersist;
 +    benchmark_rpc; send_rpc; recv_rpc;

+ 59 - 0
LibOS/glibc-patches/malloc-arena-size.patch

@@ -0,0 +1,59 @@
+diff -ruNp a/malloc/arena.c b/malloc/arena.c
+--- a/malloc/arena.c
++++ b/malloc/arena.c
+@@ -21,6 +21,27 @@
+ 
+ /* Compile-time constants.  */
+ 
++#ifndef HEAP_MAX_SIZE
++# ifdef DEFAULT_MMAP_THRESHOLD_MAX
++#  define DEFAULT_HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX)
++# else
++#  define DEFAULT_HEAP_MAX_SIZE (1024 * 1024) /* must be a power of two */
++# endif
++# include <sysdep.h>
++static long int heap_max_size = 0;
++# define HEAP_MAX_SIZE								\
++	({									\
++		if (!heap_max_size) {						\
++			long int size = glibc_option("heap_size");		\
++			if (size > 0)						\
++				heap_max_size = size;				\
++			else							\
++				heap_max_size = DEFAULT_HEAP_MAX_SIZE;		\
++		}								\
++		heap_max_size;							\
++	})
++#endif
++
+ #define HEAP_MIN_SIZE (32 * 1024)
+ #ifndef HEAP_MAX_SIZE
+ # ifdef DEFAULT_MMAP_THRESHOLD_MAX
+@@ -556,17 +577,6 @@ new_heap (size_t size, size_t top_pad)
+      mapping (on Linux, this is the case for all non-writable mappings
+      anyway). */
+   p2 = MAP_FAILED;
+-  if (aligned_heap_area)
+-    {
+-      p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
+-                          MAP_NORESERVE);
+-      aligned_heap_area = NULL;
+-      if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)))
+-        {
+-          __munmap (p2, HEAP_MAX_SIZE);
+-          p2 = MAP_FAILED;
+-        }
+-    }
+   if (p2 == MAP_FAILED)
+     {
+       p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE);
+@@ -577,8 +587,6 @@ new_heap (size_t size, size_t top_pad)
+           ul = p2 - p1;
+           if (ul)
+             __munmap (p1, ul);
+-          else
+-            aligned_heap_area = p2 + HEAP_MAX_SIZE;
+           __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
+         }
+       else
+

+ 64 - 0
LibOS/glibc-patches/nis-bogus-conditional.patch

@@ -0,0 +1,64 @@
+commit f88759ea9bd3c8d8fef28f123ba9767cb0e421a3
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Dec 21 23:44:01 2016 +0000
+
+    Fix nss_nisplus build with mainline GCC (bug 20978).
+    
+    glibc build with current mainline GCC fails because
+    nis/nss_nisplus/nisplus-alias.c contains code
+    
+      if (name != NULL)
+        {
+          *errnop = EINVAL;
+          return NSS_STATUS_UNAVAIL;
+        }
+    
+      char buf[strlen (name) + 9 + tablename_len];
+    
+    producing an error about strlen being called on a pointer that is
+    always NULL (and a subsequent use of that pointer with a %s format in
+    snprintf).
+    
+    As Andreas noted, the bogus conditional comes from a 1997 change:
+    
+    -  if (name == NULL || strlen(name) > 8)
+    -    return NSS_STATUS_NOTFOUND;
+    -  else
+    +  if (name != NULL || strlen(name) <= 8)
+    
+    So the intention is clearly to return an error for NULL name.
+    
+    This patch duly inverts the sense of the conditional.  It fixes the
+    build with GCC mainline, and passes usual glibc testsuite testing for
+    x86_64.  However, I have not tried any actual substantive nisplus
+    testing, do not have an environment for such testing, and do not know
+    whether it is possible that strlen (name) or tablename_len might be
+    large so that the VLA for buf is actually a security issue.  However,
+    if it is a security issue, there are plenty of other similar instances
+    in the nisplus code (that haven't been hidden by a bogus comparison
+    with NULL) - and nis_table.c:__create_ib_request uses strdupa on the
+    string passed to nis_list, so a local fix in the caller wouldn't
+    suffice anyway (see bug 20987).  (Calls to strdupa and other such
+    macros that use alloca must be considered equally questionable
+    regarding stack overflow issues as direct calls to alloca and VLA
+    declarations.)
+    
+            [BZ #20978]
+            * nis/nss_nisplus/nisplus-alias.c (_nss_nisplus_getaliasbyname_r):
+            Compare name == NULL, not name != NULL.
+
+---
+ nis/nss_nisplus/nisplus-alias.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/nis/nss_nisplus/nisplus-alias.c
++++ b/nis/nss_nisplus/nisplus-alias.c
+@@ -291,7 +291,7 @@
+ 	return status;
+     }
+ 
+-  if (name != NULL)
++  if (name == NULL)
+     {
+       *errnop = EINVAL;
+       return NSS_STATUS_UNAVAIL;

+ 0 - 0
LibOS/glibc-no-pie.patch → LibOS/glibc-patches/no-pie.patch


+ 8 - 0
LibOS/glibc-patches/rpc-format-overflow.patch

@@ -0,0 +1,8 @@
+--- a/sunrpc/rpc_parse.c
++++ b/sunrpc/rpc_parse.c
+@@ -521,7 +521,7 @@ static void
+ get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
+ {
+   token tok;
+-  char name[10];		/* argument name */
++  char name[MAXLINESIZE];		/* argument name */

+ 0 - 0
LibOS/glibc-syscalldb-api.patch → LibOS/glibc-patches/syscalldb-api.patch


+ 1 - 1
README.md

@@ -47,7 +47,7 @@ contact us with a detailed bug report.
 
 Run the following command on Ubuntu to install dependencies for Graphene:
 
-    sudo apt-get install -y build-essential autoconf gawk
+    sudo apt-get install -y build-essential autoconf gawk bison
 
 
 For building Graphene for SGX, run the following command in addition: