Browse Source

apply multiple patches

Chia-Che Tsai 9 years ago
parent
commit
5eaaf9abfb
73 changed files with 973 additions and 628 deletions
  1. 2 1
      LibOS/buildglibc.py
  2. 14 48
      LibOS/glibc-2.17.patch
  3. 3 7
      LibOS/glibc-2.17/syscallas.S
  4. 0 10
      LibOS/glibc-2.17/syscalldb.h
  5. 2 0
      LibOS/shim/include/shim_internal.h
  6. 0 14
      LibOS/shim/include/shim_thread.h
  7. 1 1
      LibOS/shim/include/shim_tls.h
  8. 2 0
      LibOS/shim/include/shim_vma.h
  9. 1 1
      LibOS/shim/src/Makefile
  10. 1 0
      LibOS/shim/src/bookkeep/shim_thread.c
  11. 73 6
      LibOS/shim/src/bookkeep/shim_vma.c
  12. 9 24
      LibOS/shim/src/elf/shim_rtld.c
  13. 32 9
      LibOS/shim/src/fs/chroot/fs.c
  14. 98 0
      LibOS/shim/src/fs/proc/thread.c
  15. 1 1
      LibOS/shim/src/ipc/shim_ipc_nsimpl.h
  16. 2 4
      LibOS/shim/src/shim.map
  17. 7 6
      LibOS/shim/src/shim_checkpoint.c
  18. 13 160
      LibOS/shim/src/shim_debug.c
  19. 24 2
      LibOS/shim/src/shim_init.c
  20. 2 5
      LibOS/shim/src/shim_malloc.c
  21. 51 5
      LibOS/shim/src/shim_parser.c
  22. 13 4
      LibOS/shim/src/sys/shim_brk.c
  23. 147 70
      LibOS/shim/src/sys/shim_clone.c
  24. 1 2
      LibOS/shim/src/sys/shim_exec.c
  25. 4 6
      LibOS/shim/src/sys/shim_fork.c
  26. 126 20
      LibOS/shim/src/sys/shim_futex.c
  27. 1 1
      LibOS/shim/src/sys/shim_mmap.c
  28. 4 7
      LibOS/shim/src/sys/shim_sigaction.c
  29. 19 22
      LibOS/shim/src/syscallas.S
  30. 4 5
      LibOS/shim/test/Makefile
  31. 3 5
      LibOS/shim/test/apps/Makefile
  32. 1 1
      LibOS/shim/test/apps/apache/httpd.manifest.template
  33. 1 1
      LibOS/shim/test/apps/bash/bash-local.manifest.template
  34. 1 1
      LibOS/shim/test/apps/bash/bash.manifest.template
  35. 1 1
      LibOS/shim/test/apps/busybox/busybox.manifest.template
  36. 1 1
      LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template
  37. 1 1
      LibOS/shim/test/apps/gcc/g++-huge.manifest.template
  38. 1 1
      LibOS/shim/test/apps/gcc/g++-local.manifest.template
  39. 1 1
      LibOS/shim/test/apps/gcc/g++.manifest.template
  40. 1 1
      LibOS/shim/test/apps/gcc/gcc-huge.manifest.template
  41. 1 1
      LibOS/shim/test/apps/gcc/gcc-local.manifest.template
  42. 1 1
      LibOS/shim/test/apps/gcc/gcc.manifest.template
  43. 1 1
      LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template
  44. 1 1
      LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template
  45. 15 9
      LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c
  46. 1 1
      LibOS/shim/test/apps/lmbench/manifest.template
  47. 1 1
      LibOS/shim/test/apps/make/make-huge.manifest.template
  48. 1 1
      LibOS/shim/test/apps/make/make-local.manifest.template
  49. 1 1
      LibOS/shim/test/apps/make/make.manifest.template
  50. 1 1
      LibOS/shim/test/apps/python/python.manifest.template
  51. 2 2
      LibOS/shim/test/inline/Makefile
  52. 2 2
      LibOS/shim/test/native/Makefile
  53. 4 0
      LibOS/shim/test/native/manifest.template
  54. 0 1
      LibOS/shim/test/native/start.c
  55. 12 0
      LibOS/shim/test/native/system.c
  56. 1 1
      Pal/ipc/linux/graphene-ipc.c
  57. 26 11
      Pal/src/Makefile
  58. 78 65
      Pal/src/db_rtld.c
  59. 4 4
      Pal/src/dynamic_link.h
  60. 2 1
      Pal/src/host/Linux/Makefile
  61. 7 0
      Pal/src/host/Linux/Makefile.am
  62. 8 32
      Pal/src/host/Linux/db_main.c
  63. 2 2
      Pal/src/host/Linux/db_misc.c
  64. 1 1
      Pal/src/host/Linux/db_pipes.c
  65. 2 2
      Pal/src/host/Linux/db_process.c
  66. 106 23
      Pal/src/host/Linux/db_rtld.c
  67. 0 0
      Pal/src/host/Linux/pal.lds
  68. 1 2
      Pal/src/host/Linux/pal.map
  69. 3 0
      Pal/src/host/Linux/pal_linux.h
  70. 3 0
      Pal/src/pal_debug.h
  71. 1 5
      Pal/src/pal_internal.h
  72. 15 0
      Pal/src/pal_rtld.h
  73. 0 1
      Pal/src/security/Linux/Makefile

+ 2 - 1
LibOS/buildglibc.py

@@ -86,7 +86,7 @@ try:
 
 
     os.chdir(buildDir)
     os.chdir(buildDir)
 
 
-    cflags= '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector'.format(debug_flags)
+    cflags = '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector'.format(debug_flags)
     disabled_features = { 'nscd' }
     disabled_features = { 'nscd' }
     extra_flags = '--with-tls --enable-add-ons=nptl --without-selinux {0}'.format(' '.join(['--disable-' + f for f in disabled_features]))
     extra_flags = '--with-tls --enable-add-ons=nptl --without-selinux {0}'.format(' '.join(['--disable-' + f for f in disabled_features]))
 
 
@@ -108,6 +108,7 @@ try:
                       ( 'nptl',   'libpthread.so.0' ),
                       ( 'nptl',   'libpthread.so.0' ),
                       ( 'nptl_db','libthread_db.so.1' ),
                       ( 'nptl_db','libthread_db.so.1' ),
                       ( 'dlfcn',  'libdl.so.2' ),
                       ( 'dlfcn',  'libdl.so.2' ),
+                      ( 'math',   'libm.so.6' ),
                       ( 'csu',    'crt1.o' ),
                       ( 'csu',    'crt1.o' ),
                       ( 'csu',    'crti.o' ),
                       ( 'csu',    'crti.o' ),
                       ( 'csu',    'crtn.o' ),
                       ( 'csu',    'crtn.o' ),

+ 14 - 48
LibOS/glibc-2.17.patch

@@ -926,10 +926,10 @@ index dc95421..a772f66 100644
  	cmpl	$0, (%rdi)
  	cmpl	$0, (%rdi)
  	jne	1f
  	jne	1f
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
-index 5a80ddd..bcc8d57 100644
+index 5a80ddd..f7319ca 100644
 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
 +++ b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
 +++ b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
-@@ -214,12 +214,12 @@ LLL_STUB_UNWIND_INFO_END
+@@ -214,7 +214,7 @@ LLL_STUB_UNWIND_INFO_END
      register const struct timespec *__to __asm ("r10") = timeout;	      \
      register const struct timespec *__to __asm ("r10") = timeout;	      \
      int __status;							      \
      int __status;							      \
      register __typeof (val) _val __asm ("edx") = (val);			      \
      register __typeof (val) _val __asm ("edx") = (val);			      \
@@ -938,13 +938,7 @@ index 5a80ddd..bcc8d57 100644
  		      : "=a" (__status)					      \
  		      : "=a" (__status)					      \
  		      : "0" (SYS_futex), "D" (futex),			      \
  		      : "0" (SYS_futex), "D" (futex),			      \
  			"S" (__lll_private_flag (FUTEX_WAIT, private)),	      \
  			"S" (__lll_private_flag (FUTEX_WAIT, private)),	      \
- 			"d" (_val), "r" (__to)				      \
--		      : "memory", "cc", "r11", "cx");			      \
-+		      : "memory", "cc", "r11", "cx", "bx");		      \
-     __status;								      \
-   })
- 
-@@ -229,12 +229,12 @@ LLL_STUB_UNWIND_INFO_END
+@@ -229,7 +229,7 @@ LLL_STUB_UNWIND_INFO_END
      int __ignore;							      \
      int __ignore;							      \
      register __typeof (nr) _nr __asm ("edx") = (nr);			      \
      register __typeof (nr) _nr __asm ("edx") = (nr);			      \
      LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
      LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
@@ -953,13 +947,7 @@ index 5a80ddd..bcc8d57 100644
  		      : "=a" (__ignore)					      \
  		      : "=a" (__ignore)					      \
  		      : "0" (SYS_futex), "D" (futex),			      \
  		      : "0" (SYS_futex), "D" (futex),			      \
  			"S" (__lll_private_flag (FUTEX_WAKE, private)),	      \
  			"S" (__lll_private_flag (FUTEX_WAKE, private)),	      \
- 			"d" (_nr)					      \
--		      : "memory", "cc", "r10", "r11", "cx");		      \
-+		      : "memory", "cc", "r10", "r11", "cx", "bx");	      \
-   } while (0)
- 
- 
-@@ -532,12 +532,12 @@ LLL_STUB_UNWIND_INFO_END
+@@ -532,7 +532,7 @@ LLL_STUB_UNWIND_INFO_END
      {									      \
      {									      \
        int ignore;							      \
        int ignore;							      \
        __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t"			      \
        __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t"			      \
@@ -968,13 +956,7 @@ index 5a80ddd..bcc8d57 100644
  			: "=m" (futex), "=a" (ignore)			      \
  			: "=m" (futex), "=a" (ignore)			      \
  			: "D" (&(futex)), "i" (FUTEX_OWNER_DIED),	      \
  			: "D" (&(futex)), "i" (FUTEX_OWNER_DIED),	      \
  			  "S" (__lll_private_flag (FUTEX_WAKE, private)),     \
  			  "S" (__lll_private_flag (FUTEX_WAKE, private)),     \
- 			  "1" (__NR_futex), "d" (1)			      \
--			: "cx", "r11", "cc", "memory");			      \
-+			: "cx", "bx", "r11", "cc", "memory");		      \
-     }									      \
-   while (0)
- 
-@@ -547,13 +547,13 @@ LLL_STUB_UNWIND_INFO_END
+@@ -547,7 +547,7 @@ LLL_STUB_UNWIND_INFO_END
       register int __nr_move __asm ("r10") = nr_move;			      \
       register int __nr_move __asm ("r10") = nr_move;			      \
       register void *__mutex __asm ("r8") = mutex;			      \
       register void *__mutex __asm ("r8") = mutex;			      \
       register int __val __asm ("r9") = val;				      \
       register int __val __asm ("r9") = val;				      \
@@ -983,14 +965,7 @@ index 5a80ddd..bcc8d57 100644
  		       : "=a" (__res)					      \
  		       : "=a" (__res)					      \
  		       : "0" (__NR_futex), "D" ((void *) ftx),		      \
  		       : "0" (__NR_futex), "D" ((void *) ftx),		      \
  			 "S" (__lll_private_flag (FUTEX_CMP_REQUEUE,	      \
  			 "S" (__lll_private_flag (FUTEX_CMP_REQUEUE,	      \
- 						  private)), "d" (nr_wake),   \
- 			 "r" (__nr_move), "r" (__mutex), "r" (__val)	      \
--		       : "cx", "r11", "cc", "memory");			      \
-+		       : "cx", "bx", "r11", "cc", "memory");		      \
-      __res < 0; })
- 
- #define lll_islocked(futex) \
-@@ -573,13 +573,13 @@ LLL_STUB_UNWIND_INFO_END
+@@ -573,7 +573,7 @@ LLL_STUB_UNWIND_INFO_END
      if (_tid != 0)							      \
      if (_tid != 0)							      \
        __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
        __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
  			"1:\tmovq %2, %%rax\n\t"			      \
  			"1:\tmovq %2, %%rax\n\t"			      \
@@ -999,13 +974,6 @@ index 5a80ddd..bcc8d57 100644
  			"cmpl $0, (%%rdi)\n\t"				      \
  			"cmpl $0, (%%rdi)\n\t"				      \
  			"jne 1b"					      \
  			"jne 1b"					      \
  			: "=&a" (__ignore)				      \
  			: "=&a" (__ignore)				      \
- 			: "S" (FUTEX_WAIT), "i" (SYS_futex), "D" (&tid),      \
- 			  "d" (_tid)					      \
--			: "memory", "cc", "r10", "r11", "cx");		      \
-+			: "memory", "cc", "r10", "r11", "cx", "bx");	      \
-   } while (0)
- 
- extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
 index 0b4ef71..36c5572 100644
 index 0b4ef71..36c5572 100644
 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
@@ -1401,7 +1369,7 @@ index 50587b8..374b553 100644
 +  asm volatile ("pushq %%rbx\n\tmovq syscalldb@GOTPCREL(%%rip), %%rbx\n\t" \
 +  asm volatile ("pushq %%rbx\n\tmovq syscalldb@GOTPCREL(%%rip), %%rbx\n\t" \
 +		"call %%rbx\n\t" :: "a" (__NR_exit), "D" (val) : "bx" )
 +		"call %%rbx\n\t" :: "a" (__NR_exit), "D" (val) : "bx" )
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
 diff --git a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
-index f3b7649..b466cb1 100644
+index f3b7649..433b8c9 100644
 --- a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
 --- a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
 +++ b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
 +++ b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h
 @@ -28,6 +28,7 @@
 @@ -28,6 +28,7 @@
@@ -1423,16 +1391,20 @@ index f3b7649..b466cb1 100644
    int rtld_must_xmm_save;
    int rtld_must_xmm_save;
    /* Reservation of some values for the TM ABI.  */
    /* Reservation of some values for the TM ABI.  */
    void *__private_tm[5];
    void *__private_tm[5];
-@@ -135,6 +140,8 @@ typedef struct
+@@ -135,6 +140,12 @@ typedef struct
  # define GET_DTV(descr) \
  # define GET_DTV(descr) \
    (((tcbhead_t *) (descr))->dtv)
    (((tcbhead_t *) (descr))->dtv)
  
  
 +/* For Graphene */
 +/* For Graphene */
-+#define SYSCALLDB "movq syscalldb@GOTPCREL(%%rip), %%rbx\n\tcall %%rbx\n\t"
++#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
  /* Code to initially initialize the thread pointer.  This might need
     special attention since 'errno' is not yet available and if the
     special attention since 'errno' is not yet available and if the
-@@ -152,12 +159,12 @@ typedef struct
+@@ -152,7 +163,7 @@ typedef struct
       _head->self = _thrdescr;						      \
       _head->self = _thrdescr;						      \
  									      \
  									      \
       /* It is a simple syscall to set the %fs value for the thread.  */	      \
       /* It is a simple syscall to set the %fs value for the thread.  */	      \
@@ -1441,12 +1413,6 @@ index f3b7649..b466cb1 100644
  		   : "=a" (_result)					      \
  		   : "=a" (_result)					      \
  		   : "0" ((unsigned long int) __NR_arch_prctl),		      \
  		   : "0" ((unsigned long int) __NR_arch_prctl),		      \
  		     "D" ((unsigned long int) ARCH_SET_FS),		      \
  		     "D" ((unsigned long int) ARCH_SET_FS),		      \
- 		     "S" (_thrdescr)					      \
--		   : "memory", "cc", "r11", "cx");			      \
-+		   : "memory", "cc", "r11", "cx", "bx");		      \
- 									      \
-     _result ? "cannot set %fs base address for thread-local storage" : 0;     \
-   })
 diff --git a/LibOS/glibc-2.17/scripts/mkinstalldirs b/LibOS/glibc-2.17/scripts/mkinstalldirs
 diff --git a/LibOS/glibc-2.17/scripts/mkinstalldirs b/LibOS/glibc-2.17/scripts/mkinstalldirs
 index f945dbf..3c0e48c 100755
 index f945dbf..3c0e48c 100755
 --- a/LibOS/glibc-2.17/scripts/mkinstalldirs
 --- a/LibOS/glibc-2.17/scripts/mkinstalldirs

+ 3 - 7
LibOS/glibc-2.17/syscallas.S

@@ -1,15 +1,11 @@
 #include <syscalldb.h>
 #include <syscalldb.h>
 
 
-#ifdef WEAK_SYSCALLDB
 .weak syscalldb
 .weak syscalldb
-#else
-.global syscalldb
-#endif
 .type syscalldb,@function
 .type syscalldb,@function
 
 
 syscalldb:
 syscalldb:
 	.cfi_startproc
 	.cfi_startproc
 	syscall
 	syscall
-	ret
-.cfi_endproc
-.size syscalldb,.-syscalldb
+	retq
+	.cfi_endproc
+	.size syscalldb,.-syscalldb

+ 0 - 10
LibOS/glibc-2.17/syscalldb.h

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

+ 2 - 0
LibOS/shim/include/shim_internal.h

@@ -742,6 +742,8 @@ extern const char ** initial_envp;
         _stack;                                                     \
         _stack;                                                     \
     })
     })
 
 
+void get_brk_region (void ** start, void ** end, void ** current);
+
 int init_randgen (void);
 int init_randgen (void);
 int init_brk (void);
 int init_brk (void);
 int init_heap (void);
 int init_heap (void);

+ 0 - 14
LibOS/shim/include/shim_thread.h

@@ -265,21 +265,7 @@ void set_handle_map (struct shim_thread * thread,
 int thread_exit (struct shim_thread * self, bool send_ipc);
 int thread_exit (struct shim_thread * self, bool send_ipc);
 int try_process_exit (int error_code);
 int try_process_exit (int error_code);
 
 
-/* thread cloning helpers */
-struct clone_args {
-    PAL_HANDLE create_event;
-    PAL_HANDLE initialize_event;
-    struct shim_thread * thread;
-    void * stack;
-    void * return_pc;
-};
-
-int clone_implementation_wrapper(struct clone_args * arg);
-
-int clean_held_locks (struct shim_thread * self);
-
 void * allocate_stack (size_t size, size_t protect_size, bool user);
 void * allocate_stack (size_t size, size_t protect_size, bool user);
-
 int populate_user_stack (void * stack, size_t stack_size,
 int populate_user_stack (void * stack, size_t stack_size,
                          int nauxv, elf_auxv_t ** auxpp,
                          int nauxv, elf_auxv_t ** auxpp,
                          const char *** argvp, const char *** envpp);
                          const char *** argvp, const char *** envpp);

+ 1 - 1
LibOS/shim/include/shim_tls.h

@@ -32,13 +32,13 @@ struct shim_regs {
     unsigned long           r15;
     unsigned long           r15;
     unsigned long           r14;
     unsigned long           r14;
     unsigned long           r13;
     unsigned long           r13;
+    unsigned long           r12;
     unsigned long           r9;
     unsigned long           r9;
     unsigned long           r8;
     unsigned long           r8;
     unsigned long           rcx;
     unsigned long           rcx;
     unsigned long           rdx;
     unsigned long           rdx;
     unsigned long           rsi;
     unsigned long           rsi;
     unsigned long           rdi;
     unsigned long           rdi;
-    unsigned long           r12;
     unsigned long           rbx;
     unsigned long           rbx;
     unsigned long           rbp;
     unsigned long           rbp;
 };
 };

+ 2 - 0
LibOS/shim/include/shim_vma.h

@@ -87,6 +87,8 @@ struct shim_vma * next_vma (struct shim_vma * vma);
 
 
 void * get_unmapped_vma (size_t len, int flags);
 void * get_unmapped_vma (size_t len, int flags);
 
 
+int dump_all_vmas (struct shim_thread * thread, char * buf, size_t size);
+
 void unmap_all_vmas (void);
 void unmap_all_vmas (void);
 
 
 /* Debugging */
 /* Debugging */

+ 1 - 1
LibOS/shim/src/Makefile

@@ -64,7 +64,7 @@ libsysdb.so: $(addsuffix .o,$(objs)) $(filter %.map %.lds,$(LDFLAGS)) \
 	$(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) -soname $@ \
 	$(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) -soname $@ \
 		-e shim_start
 		-e shim_start
 
 
-libsysdb_debug.so: $(addsuffix .o,$(objs)) \
+libsysdb_debug.so: $(addsuffix .o,$(filter-out syscallas,$(objs))) \
 		   $(filter %.map %.lds,$($LDFLAGS-debug)) \
 		   $(filter %.map %.lds,$($LDFLAGS-debug)) \
 		   $(graphene_lib) $(pal_lib)
 		   $(graphene_lib) $(pal_lib)
 	@echo [ $@ ]
 	@echo [ $@ ]

+ 1 - 0
LibOS/shim/src/bookkeep/shim_thread.c

@@ -231,6 +231,7 @@ struct shim_thread * get_new_thread (IDTYPE new_tid)
         thread->parent      = cur_thread;
         thread->parent      = cur_thread;
         thread->stack       = cur_thread->stack;
         thread->stack       = cur_thread->stack;
         thread->stack_top   = cur_thread->stack_top;
         thread->stack_top   = cur_thread->stack_top;
+        thread->stack_red   = cur_thread->stack_red;
         thread->cwd         = cur_thread->cwd;
         thread->cwd         = cur_thread->cwd;
         thread->root        = cur_thread->root;
         thread->root        = cur_thread->root;
         thread->umask       = cur_thread->umask;
         thread->umask       = cur_thread->umask;

+ 73 - 6
LibOS/shim/src/bookkeep/shim_vma.c

@@ -282,6 +282,7 @@ static int __bkeep_mmap (void * addr, size_t length,
                     prev->length = addr - prev->addr;
                     prev->length = addr - prev->addr;
                 }
                 }
 
 
+                assert(prev->addr + prev->length <= addr);
                 cont = prev;
                 cont = prev;
                 pos = &prev->list;
                 pos = &prev->list;
             } else { /* has no precendent vma */
             } else { /* has no precendent vma */
@@ -584,9 +585,12 @@ static int __bkeep_mprotect (void * addr, size_t length, int prot,
                 /* no more vmas, protect the whole area */
                 /* no more vmas, protect the whole area */
                 ret = __bkeep_mmap((void *) addr, length, prot,
                 ret = __bkeep_mmap((void *) addr, length, prot,
                                    VMA_UNMAPPED|(flags ? *flags : 0),
                                    VMA_UNMAPPED|(flags ? *flags : 0),
-                                   NULL, 0, "bkeep");
+                                   NULL, 0, NULL);
                 if (ret < 0)
                 if (ret < 0)
                     return ret;
                     return ret;
+
+                candidate = __lookup_vma((void *) addr, length);
+                assert(candidate);
             }
             }
 
 
             length -= candidate->addr - addr;
             length -= candidate->addr - addr;
@@ -801,6 +805,73 @@ struct shim_vma * next_vma (struct shim_vma * vma)
     return tmp;
     return tmp;
 }
 }
 
 
+int dump_all_vmas (struct shim_thread * thread, char * buf, size_t size)
+{
+    lock(vma_list_lock);
+
+    struct shim_vma * vma;
+    int cnt = 0;
+
+    list_for_each_entry(vma, &vma_list, list) {
+        void * start = vma->addr, * end = vma->addr + vma->length;
+
+        if ((vma->flags & (VMA_INTERNAL|VMA_UNMAPPED)) && !vma->comment[0])
+            continue;
+
+        char prot[3] = {'-', '-', '-'};
+        if (vma->prot & PROT_READ)
+            prot[0] = 'r';
+        if (vma->prot & PROT_WRITE)
+            prot[1] = 'w';
+        if (vma->prot & PROT_EXEC)
+            prot[2] = 'x';
+
+        if (vma->file) {
+            int dev_major = 0, dev_minor = 0;
+            unsigned long ino = vma->file->dentry ? vma->file->dentry->ino : 0;
+            const char * name = "[unknown]";
+
+            if (!qstrempty(&vma->file->path))
+                name = qstrgetstr(&vma->file->path);
+
+            cnt += snprintf(buf + cnt, size - cnt,
+                            start > (void *) 0xffffffff ? "%lx" : "%08x", start);
+
+            cnt += snprintf(buf + cnt, size - cnt,
+                            end > (void *) 0xffffffff ? "-%lx" : "-%08x", end);
+
+            cnt += snprintf(buf + cnt, size - cnt,
+                            " %c%c%cp %08x %02d:%02d %u %s\n",
+                            prot[0], prot[1], prot[2],
+                            vma->offset, dev_major, dev_minor, ino,
+                            name);
+        } else {
+            cnt += snprintf(buf + cnt, size - cnt,
+                            start > (void *) 0xffffffff ? "%lx" : "%08x", start);
+
+            cnt += snprintf(buf + cnt, size - cnt,
+                            end > (void *) 0xffffffff ? "-%lx" : "-%08x", end);
+
+            if (vma->comment[0])
+                cnt += snprintf(buf + cnt, size - cnt,
+                                " %c%c%cp 00000000 00:00 0 [%s]\n",
+                                prot[0], prot[1], prot[2], vma->comment[0]);
+            else
+                cnt += snprintf(buf + cnt, size - cnt,
+                                " %c%c%cp 00000000 00:00 0\n",
+                                prot[0], prot[1], prot[2]);
+        }
+
+        if (cnt >= size) {
+            cnt = -EOVERFLOW;
+            break;
+        }
+    }
+
+    unlock(vma_list_lock);
+    return cnt;
+}
+
 void unmap_all_vmas (void)
 void unmap_all_vmas (void)
 {
 {
     struct shim_thread * cur_thread = get_cur_thread();
     struct shim_thread * cur_thread = get_cur_thread();
@@ -1085,12 +1156,10 @@ RESUME_FUNC_BODY(all_vmas)
 }
 }
 END_RESUME_FUNC
 END_RESUME_FUNC
 
 
-void debug_print_vma_list ()
+void debug_print_vma_list (void)
 {
 {
     sys_printf("vma bookkeeping:\n");
     sys_printf("vma bookkeeping:\n");
 
 
-    lock(vma_list_lock);
-
     struct shim_vma * vma;
     struct shim_vma * vma;
     list_for_each_entry(vma, &vma_list, list) {
     list_for_each_entry(vma, &vma_list, list) {
         const char * type = "", * name = "";
         const char * type = "", * name = "";
@@ -1116,8 +1185,6 @@ void debug_print_vma_list ()
                    vma->comment[0] ? " comment=" : "",
                    vma->comment[0] ? " comment=" : "",
                    vma->comment[0] ? vma->comment : "");
                    vma->comment[0] ? vma->comment : "");
     }
     }
-
-    unlock(vma_list_lock);
 }
 }
 
 
 void print_vma_hash (struct shim_vma * vma, void * addr, int len,
 void print_vma_hash (struct shim_vma * vma, void * addr, int len,

+ 9 - 24
LibOS/shim/src/elf/shim_rtld.c

@@ -339,23 +339,6 @@ void setup_elf_hash (struct link_map * map)
     map->l_chain = hash;
     map->l_chain = hash;
 }
 }
 
 
-static const char * __obj_type_str (int type, struct link_map * remap)
-{
-    switch (type) {
-        case OBJECT_INTERNAL:
-            return "elf-internal";
-        case OBJECT_LOAD:
-            return "elf-load";
-        case OBJECT_MAPPED:
-            return "elf-mapped";
-        case OBJECT_REMAP:
-            return __obj_type_str(remap->l_type, NULL);
-        case OBJECT_USER:
-            return "elf-user";
-    }
-    return NULL;
-}
-
 /* Map in the shared object NAME, actually located in REALNAME, and already
 /* Map in the shared object NAME, actually located in REALNAME, and already
    opened on FD */
    opened on FD */
 static struct link_map *
 static struct link_map *
@@ -376,7 +359,6 @@ __map_elf_object (struct shim_handle * file,
     if (file && (!read || !mmap || !seek))
     if (file && (!read || !mmap || !seek))
         return NULL;
         return NULL;
 
 
-    const char * obj_type = __obj_type_str(type, remap);
     struct link_map * l = remap ? :
     struct link_map * l = remap ? :
                           new_elf_object(file ? (!qstrempty(&file->path) ?
                           new_elf_object(file ? (!qstrempty(&file->path) ?
                                          qstrgetstr(&file->path) :
                                          qstrgetstr(&file->path) :
@@ -404,6 +386,7 @@ call_lose:
 
 
     /* Extract the remaining details we need from the ELF header
     /* Extract the remaining details we need from the ELF header
        and then read in the program header table.  */
        and then read in the program header table.  */
+    l->l_addr = (ElfW(Addr)) addr;
     l->l_entry = header->e_entry;
     l->l_entry = header->e_entry;
     int e_type = header->e_type;
     int e_type = header->e_type;
     l->l_phnum = header->e_phnum;
     l->l_phnum = header->e_phnum;
@@ -438,7 +421,7 @@ call_lose:
                 break;
                 break;
 
 
             case PT_INTERP:
             case PT_INTERP:
-                l->l_interp_libname = ((const char *) l->l_addr + ph->p_vaddr);
+                l->l_interp_libname = (const char *) ph->p_vaddr;
                 break;
                 break;
 
 
             case PT_PHDR:
             case PT_PHDR:
@@ -559,7 +542,7 @@ map_error:
             bkeep_mmap((void *) mappref, ALIGN_UP(maplength), c->prot,
             bkeep_mmap((void *) mappref, ALIGN_UP(maplength), c->prot,
                        c->flags|MAP_PRIVATE|
                        c->flags|MAP_PRIVATE|
                        (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0),
                        (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0),
-                       file, c->mapoff, obj_type);
+                       file, c->mapoff, NULL);
 
 
         l->l_addr = l->l_map_start - c->mapstart;
         l->l_addr = l->l_map_start - c->mapstart;
 
 
@@ -593,6 +576,7 @@ map_error:
     }
     }
 
 
     /* Remember which part of the address space this object uses.  */
     /* Remember which part of the address space this object uses.  */
+    l->l_addr = 0;
     l->l_map_start = c->mapstart;
     l->l_map_start = c->mapstart;
     l->l_map_end = l->l_map_start + maplength;
     l->l_map_end = l->l_map_start + maplength;
 
 
@@ -615,7 +599,7 @@ do_remap:
                     bkeep_mmap(mapaddr, c->mapend - c->mapstart, c->prot,
                     bkeep_mmap(mapaddr, c->mapend - c->mapstart, c->prot,
                                c->flags|MAP_FIXED|MAP_PRIVATE|
                                c->flags|MAP_FIXED|MAP_PRIVATE|
                                (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0),
                                (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0),
-                               file, c->mapoff, obj_type);
+                               file, c->mapoff, NULL);
         }
         }
 
 
 postmap:
 postmap:
@@ -1143,12 +1127,12 @@ static int __load_elf_object (struct shim_handle * file, void * addr,
         add_link_map(map);
         add_link_map(map);
     }
     }
 
 
-    if ((type == OBJECT_LOAD || type == OBJECT_REMAP) &&
+    if ((type == OBJECT_LOAD || type == OBJECT_REMAP || type == OBJECT_USER) &&
         map->l_file && !qstrempty(&map->l_file->uri)) {
         map->l_file && !qstrempty(&map->l_file->uri)) {
         if (type == OBJECT_REMAP)
         if (type == OBJECT_REMAP)
             remove_r_debug((void *) map->l_addr);
             remove_r_debug((void *) map->l_addr);
 
 
-        append_r_debug(qstrgetstr(&map->l_file->uri), (void *) map->l_addr,
+        append_r_debug(qstrgetstr(&map->l_file->uri), (void *) map->l_map_start,
                        (void *) map->l_real_ld);
                        (void *) map->l_real_ld);
     }
     }
 
 
@@ -1440,7 +1424,8 @@ int free_elf_interp (void)
 
 
 static int __load_interp_object (struct link_map * exec_map)
 static int __load_interp_object (struct link_map * exec_map)
 {
 {
-    const char * interp_name = exec_map->l_interp_libname;
+    const char * interp_name = (const char *) exec_map->l_interp_libname +
+                               (long) exec_map->l_addr;
     int len = strlen(interp_name);
     int len = strlen(interp_name);
     const char * filename = interp_name + len - 1;
     const char * filename = interp_name + len - 1;
     while (filename > interp_name && *filename != '/')
     while (filename > interp_name && *filename != '/')

+ 32 - 9
LibOS/shim/src/fs/chroot/fs.c

@@ -595,7 +595,7 @@ static inline int __map_buffer (struct shim_handle * hdl, int size)
         return -PAL_ERRNO;
         return -PAL_ERRNO;
 
 
     bkeep_mmap(mapbuf, maplen, prot, MAP_FILE|MAP_SHARED|VMA_INTERNAL,
     bkeep_mmap(mapbuf, maplen, prot, MAP_FILE|MAP_SHARED|VMA_INTERNAL,
-               hdl, mapoff, "chroot-buffer");
+               hdl, mapoff, NULL);
 
 
     file->mapbuf    = mapbuf;
     file->mapbuf    = mapbuf;
     file->mapoffset = mapoff;
     file->mapoffset = mapoff;
@@ -706,14 +706,26 @@ static int chroot_read (struct shim_handle * hdl, void * buf,
         goto out;
         goto out;
     }
     }
 
 
-    if (hdl->info.file.buf_type == FILEBUF_MAP) {
+    struct shim_file_handle * file = &hdl->info.file;
+
+    if (file->buf_type == FILEBUF_MAP) {
         ret = map_read(hdl, buf, count);
         ret = map_read(hdl, buf, count);
-        goto out;
+        if (ret != -EACCES)
+            goto out;
+
+        lock(hdl->lock);
+        file->buf_type = FILEBUF_NONE;
+    } else {
+        lock(hdl->lock);
     }
     }
 
 
-    ret = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0) ? :
+    ret = DkStreamRead(hdl->pal_handle, file->marker, count, buf, NULL, 0) ? :
            (PAL_NATIVE_ERRNO == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO);
            (PAL_NATIVE_ERRNO == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO);
 
 
+    if (ret > 0)
+        file->marker += ret;
+
+    unlock(hdl->lock);
 out:
 out:
     return ret;
     return ret;
 }
 }
@@ -730,13 +742,26 @@ static int chroot_write (struct shim_handle * hdl, const void * buf,
         goto out;
         goto out;
     }
     }
 
 
+    struct shim_file_handle * file = &hdl->info.file;
+
     if (hdl->info.file.buf_type == FILEBUF_MAP) {
     if (hdl->info.file.buf_type == FILEBUF_MAP) {
         ret = map_write(hdl, buf, count);
         ret = map_write(hdl, buf, count);
+        if (ret != -EACCES)
+            goto out;
+
+        lock(hdl->lock);
+        file->buf_type = FILEBUF_NONE;
     } else {
     } else {
-        ret =  DkStreamWrite(hdl->pal_handle, 0, count, buf, NULL) ? :
-            -PAL_ERRNO;
+        lock(hdl->lock);
     }
     }
 
 
+    ret = DkStreamWrite(hdl->pal_handle, file->marker, count, buf, NULL) ? :
+          -PAL_ERRNO;
+
+    if (ret > 0)
+        file->marker += ret;
+
+    unlock(hdl->lock);
 out:
 out:
     return ret;
     return ret;
 
 
@@ -804,9 +829,7 @@ static int chroot_seek (struct shim_handle * hdl, off_t offset, int wence)
             break;
             break;
 
 
         case SEEK_END:
         case SEEK_END:
-            if (offset < 0)
-                goto out;
-            marker = size - offset;
+            marker = size + offset;
             break;
             break;
     }
     }
 
 

+ 98 - 0
LibOS/shim/src/fs/proc/thread.c

@@ -11,11 +11,14 @@
 #include <pal.h>
 #include <pal.h>
 #include <pal_error.h>
 #include <pal_error.h>
 
 
+#include <asm/fcntl.h>
 #include <asm/mman.h>
 #include <asm/mman.h>
 #include <asm/unistd.h>
 #include <asm/unistd.h>
 #include <asm/prctl.h>
 #include <asm/prctl.h>
 #include <errno.h>
 #include <errno.h>
 
 
+#define DEFAULT_BUFFER_SIZE 256
+
 static int parse_thread_name (const char * name,
 static int parse_thread_name (const char * name,
                               const char ** next, int * next_len,
                               const char ** next, int * next_len,
                               const char ** nextnext)
                               const char ** nextnext)
@@ -461,6 +464,100 @@ static const struct proc_dir dir_fd = { .size = 1, .ent = { {
             .nm_ops = &nm_thread_each_fd, .fs_ops = &fs_thread_each_fd,
             .nm_ops = &nm_thread_each_fd, .fs_ops = &fs_thread_each_fd,
         }, }, };
         }, }, };
 
 
+static int proc_thread_maps_open (struct shim_handle * hdl,
+                                  const char * name, int flags)
+{
+    if (flags & (O_WRONLY|O_RDWR))
+        return -EACCES;
+
+    const char * next;
+    int next_len;
+    int pid = parse_thread_name(name, &next, &next_len, NULL);
+
+    if (pid < 0)
+        return pid;
+
+    struct shim_thread * thread = lookup_thread(pid);
+
+    if (!thread)
+        return -ENOENT;
+
+    int size = DEFAULT_BUFFER_SIZE;
+    char * strbuf = malloc(size);
+    int ret = 0, len = 0;
+
+    if (!strbuf) {
+        ret = -ENOMEM;
+        goto out;
+    }
+
+retry:
+    ret = dump_all_vmas(thread, strbuf, size);
+
+    if (ret == -EOVERFLOW) {
+        char * newbuf = malloc(size * 2);
+        if (!newbuf) {
+            ret = -ENOMEM;
+            goto err;
+        }
+        free(strbuf);
+        strbuf = newbuf;
+        size *= 2;
+        goto retry;
+    }
+
+    if (ret < 0)
+        goto err;
+
+    len = ret;
+
+    struct shim_str_data * data = malloc(sizeof(struct shim_str_data));
+    if (!data) {
+        ret = -ENOMEM;
+        goto err;
+    }
+
+    memset(data, 0, sizeof(struct shim_str_data));
+    data->str = strbuf;
+    data->len = len;
+    hdl->type = TYPE_STR;
+    hdl->flags = flags & ~O_RDONLY;
+    hdl->acc_mode = MAY_READ;
+    hdl->info.str.data = data;
+    ret = 0;
+out:
+    put_thread(thread);
+    return ret;
+err:
+    free(strbuf);
+    goto out;
+}
+
+static int proc_thread_maps_mode (const char * name, mode_t * mode)
+{
+    *mode = 0400;
+    return 0;
+}
+
+static int proc_thread_maps_stat (const char * name, struct stat * buf)
+{
+    memset(buf, 0, sizeof(struct stat));
+
+    buf->st_dev = buf->st_ino = 1;
+    buf->st_mode = 0400|S_IFREG;
+    buf->st_uid = 0;
+    buf->st_gid = 0;
+    buf->st_size = 0;
+
+    return 0;
+}
+
+static const struct proc_fs_ops fs_thread_maps = {
+            .open           = &proc_thread_maps_open,
+            .mode           = &proc_thread_maps_mode,
+            .stat           = &proc_thread_maps_stat,
+        };
+
 static int proc_thread_dir_mode (const char * name, mode_t * mode)
 static int proc_thread_dir_mode (const char * name, mode_t * mode)
 {
 {
     const char * next;
     const char * next;
@@ -570,4 +667,5 @@ const struct proc_dir dir_thread = { .size = 5, .ent = {
         { .name = "exe", .fs_ops = &fs_thread_link, },
         { .name = "exe", .fs_ops = &fs_thread_link, },
         { .name = "root", .fs_ops = &fs_thread_link, },
         { .name = "root", .fs_ops = &fs_thread_link, },
         { .name = "fd", .dir = &dir_fd, .fs_ops = &fs_thread_fd, },
         { .name = "fd", .dir = &dir_fd, .fs_ops = &fs_thread_fd, },
+        { .name = "maps", .fs_ops = &fs_thread_maps, },
     }, };
     }, };

+ 1 - 1
LibOS/shim/src/ipc/shim_ipc_nsimpl.h

@@ -639,7 +639,7 @@ IDTYPE CONCAT2(allocate, NS) (IDTYPE min, IDTYPE max)
                 for ( ; j < BITS ; f <<= 1, j++)
                 for ( ; j < BITS ; f <<= 1, j++)
                     if (!(map & f)) {
                     if (!(map & f)) {
                         (*m) |= f;
                         (*m) |= f;
-                        idx = base + i * RANGE_SIZE + j;
+                        idx = base + i * BITS + j;
                         debug("allocated " NS_STR ": %u\n", idx);
                         debug("allocated " NS_STR ": %u\n", idx);
                         goto out;
                         goto out;
                     }
                     }

+ 2 - 4
LibOS/shim/src/shim.map

@@ -1,8 +1,6 @@
 SHIM {
 SHIM {
     global:
     global:
-        syscalldb;
-        __libc_r_debug; __libc_dl_debug_state;
-        glibc_vers_2_17;
-        register_library;
+        syscalldb; register_library;
+        glibc_vers_*;
     local: *;
     local: *;
 };
 };

+ 7 - 6
LibOS/shim/src/shim_checkpoint.c

@@ -875,7 +875,7 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
 
 
         bkeep_mmap(cpaddr, ALIGN_UP(cpsize), PROT_READ|PROT_WRITE,
         bkeep_mmap(cpaddr, ALIGN_UP(cpsize), PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
-                   NULL, 0, "migrated");
+                   NULL, 0, NULL);
 
 
         SAVE_PROFILE_INTERVAL(child_load_checkpoint_by_gipc);
         SAVE_PROFILE_INTERVAL(child_load_checkpoint_by_gipc);
 
 
@@ -897,7 +897,7 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
 
 
         bkeep_mmap(cpaddr, cpsize_pgalign, PROT_READ|PROT_WRITE,
         bkeep_mmap(cpaddr, cpsize_pgalign, PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
-                   NULL, 0, "migrated");
+                   NULL, 0, NULL);
 
 
         cpaddr -= cpaddr_pgalign;
         cpaddr -= cpaddr_pgalign;
 
 
@@ -944,8 +944,8 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
 
 
 void restore_context (struct shim_context * context)
 void restore_context (struct shim_context * context)
 {
 {
-    int nregs = sizeof(struct shim_regs) / sizeof(unsigned long);
-    unsigned long regs[nregs + 1];
+    int nregs = sizeof(struct shim_regs) / sizeof(void *);
+    void * regs[nregs + 1];
 
 
     if (context->regs)
     if (context->regs)
         memcpy(regs, context->regs, sizeof(struct shim_regs));
         memcpy(regs, context->regs, sizeof(struct shim_regs));
@@ -954,7 +954,8 @@ void restore_context (struct shim_context * context)
 
 
     debug("restore context: SP = %p, IP = %p\n", context->sp, context->ret_ip);
     debug("restore context: SP = %p, IP = %p\n", context->sp, context->ret_ip);
 
 
-    regs[nregs] = (unsigned long) context->sp;
+    regs[nregs] = (void *) context->sp - 8;
+    *(void **) (context->sp - 8) = context->ret_ip;
 
 
     memset(context, 0, sizeof(struct shim_context));
     memset(context, 0, sizeof(struct shim_context));
 
 
@@ -962,13 +963,13 @@ void restore_context (struct shim_context * context)
                  "popq %%r15\r\n"
                  "popq %%r15\r\n"
                  "popq %%r14\r\n"
                  "popq %%r14\r\n"
                  "popq %%r13\r\n"
                  "popq %%r13\r\n"
+                 "popq %%r12\r\n"
                  "popq %%r9\r\n"
                  "popq %%r9\r\n"
                  "popq %%r8\r\n"
                  "popq %%r8\r\n"
                  "popq %%rcx\r\n"
                  "popq %%rcx\r\n"
                  "popq %%rdx\r\n"
                  "popq %%rdx\r\n"
                  "popq %%rsi\r\n"
                  "popq %%rsi\r\n"
                  "popq %%rdi\r\n"
                  "popq %%rdi\r\n"
-                 "popq %%r12\r\n"
                  "popq %%rbx\r\n"
                  "popq %%rbx\r\n"
                  "popq %%rbp\r\n"
                  "popq %%rbp\r\n"
                  "popq %%rsp\r\n"
                  "popq %%rsp\r\n"

+ 13 - 160
LibOS/shim/src/shim_debug.c

@@ -44,171 +44,44 @@ struct gdb_link_map
     struct gdb_link_map *l_next, *l_prev;
     struct gdb_link_map *l_next, *l_prev;
 };
 };
 
 
-struct gdb_r_debug
-{
-    int r_version;
-    struct gdb_link_map *r_map;
-    uintptr_t r_brk;
-    enum
-    {
-        RT_CONSISTENT,
-        RT_ADD,
-        RT_DELETE,
-    } r_state;
-    uintptr_t r_ldbase;
-};
-
-struct gdb_r_debug __libc_r_debug;
-
-extern struct gdb_r_debug _r_debug;
-extern void _dl_debug_state_trigger (void);
-
 static struct gdb_link_map * link_map_list = NULL;
 static struct gdb_link_map * link_map_list = NULL;
 
 
-static inline char * translate_file_path (const char * path)
-{
-    struct shim_dentry * dent = NULL;
-
-    int ret = path_lookupat(NULL, path, 0, &dent);
-    if (ret < 0)
-        return NULL;
-
-    struct shim_mount * fs = dent->fs;
-
-    if (!fs->d_ops->open)
-        return NULL;
-
-    char * new_uri = NULL;
-    struct shim_handle * hdl = get_new_handle();
-    if (!hdl)
-        return NULL;
-
-    set_handle_fs(hdl, fs);
-    hdl->dentry = dent;
-
-    ret = fs->d_ops->open(hdl, dent, O_RDONLY);
-    if (ret < 0)
-        goto out;
-
-    new_uri = qstrtostr(&hdl->uri, false);
-out:
-    put_handle(hdl);
-    return new_uri;
-}
-
-void __libc_dl_debug_state (void)
-{
-    /* first make sure libc map list matches the shadow map list */
-    if (link_map_list) {
-        struct gdb_link_map *m = link_map_list, *n;
-        for ( ; m ; m = m->l_next) {
-            for (n = __libc_r_debug.r_map ; n ; n = n->l_next)
-                if (m->l_addr == n->l_addr)
-                    break;
-            if (!n) {
-                if (m->l_prev)
-                    m->l_prev->l_next = m->l_next;
-                if (m->l_next)
-                    m->l_next->l_prev = m->l_prev;
-                if (m == link_map_list)
-                    link_map_list = m->l_next;
-            }
-        }
-    }
-
-    /* now find the end of the shadow map list, where we are adding to */
-    struct gdb_link_map *prev = NULL;
-    struct gdb_link_map **tail = &_r_debug.r_map;
-
-    while (*tail) {
-        prev = *tail;
-        tail = &(*tail)->l_next;
-    }
-
-    /* add new maps to the shadow map list */
-    struct gdb_link_map **t = tail;
-    struct gdb_link_map *m = __libc_r_debug.r_map;
-
-    for ( ; m ; m = m->l_next) {
-        struct gdb_link_map *re = _r_debug.r_map;
-        while (re && re->l_addr != m->l_addr)
-            re = re->l_next;
-
-        if (re)
-            continue;
-
-        char * uri = translate_file_path(m->l_name);
-        if (!uri)
-            continue;
-        debug("add a library for gdb: %s\n", uri);
-
-        struct gdb_link_map * new = malloc(sizeof(struct gdb_link_map));
-
-        new->l_addr = m->l_addr;
-        new->l_ld = m->l_ld;
-        new->l_name = uri;
-        new->l_prev = prev;
-        prev = *t = new;
-        new->l_next = NULL;
-        t = &new->l_next;
-    }
-
-    if (!link_map_list)
-        link_map_list = *tail;
-
-    _r_debug.r_state = __libc_r_debug.r_state;
-    _dl_debug_state_trigger();
-}
-
 void clean_link_map_list (void)
 void clean_link_map_list (void)
 {
 {
     if (!link_map_list)
     if (!link_map_list)
         return;
         return;
 
 
-    _r_debug.r_state = RT_DELETE;
-    _dl_debug_state_trigger();
-
     if (link_map_list->l_prev)
     if (link_map_list->l_prev)
         link_map_list->l_prev->l_next = NULL;
         link_map_list->l_prev->l_next = NULL;
-    if (_r_debug.r_map == link_map_list)
-        _r_debug.r_map = NULL;
 
 
     struct gdb_link_map * m = link_map_list;
     struct gdb_link_map * m = link_map_list;
-    for ( ; m ; m = m->l_next)
+    for ( ; m ; m = m->l_next) {
+        DkDebugDetachBinary(m->l_addr);
         free(m);
         free(m);
+    }
 
 
     link_map_list = NULL;
     link_map_list = NULL;
-
-    _r_debug.r_state = RT_CONSISTENT;
-    _dl_debug_state_trigger();
-
 }
 }
 
 
 void remove_r_debug (void * addr)
 void remove_r_debug (void * addr)
 {
 {
-    struct gdb_link_map * m = _r_debug.r_map;
+    struct gdb_link_map * m = link_map_list;
 
 
-    for ( ; m && m != link_map_list ; m = m->l_next)
+    for ( ; m ; m = m->l_next)
         if (m->l_addr == addr)
         if (m->l_addr == addr)
             break;
             break;
 
 
-    if (!m || m == link_map_list)
+    if (!m)
         return;
         return;
 
 
-    _r_debug.r_state = RT_DELETE;
-    _dl_debug_state_trigger();
-
     debug("remove a library for gdb: %s\n", m->l_name);
     debug("remove a library for gdb: %s\n", m->l_name);
 
 
     if (m->l_prev)
     if (m->l_prev)
         m->l_prev->l_next = m->l_next;
         m->l_prev->l_next = m->l_next;
     if (m->l_next)
     if (m->l_next)
         m->l_next->l_prev = m->l_prev;
         m->l_next->l_prev = m->l_prev;
-    if (_r_debug.r_map == m)
-        _r_debug.r_map = m->l_next;
 
 
-    _r_debug.r_state = RT_CONSISTENT;
-    _dl_debug_state_trigger();
+    DkDebugDetachBinary(addr);
 }
 }
 
 
 void append_r_debug (const char * uri, void * addr, void * dyn_addr)
 void append_r_debug (const char * uri, void * addr, void * dyn_addr)
@@ -224,26 +97,20 @@ void append_r_debug (const char * uri, void * addr, void * dyn_addr)
     new->l_name = new_uri;
     new->l_name = new_uri;
 
 
     struct gdb_link_map *prev = NULL;
     struct gdb_link_map *prev = NULL;
-    struct gdb_link_map **tail = &_r_debug.r_map;
+    struct gdb_link_map **tail = &link_map_list;
 
 
-    while (*tail && *tail != link_map_list) {
+    while (*tail) {
         prev = *tail;
         prev = *tail;
         tail = &(*tail)->l_next;
         tail = &(*tail)->l_next;
     }
     }
 
 
-    _r_debug.r_state = RT_ADD;
-    _dl_debug_state_trigger();
-
-    debug("add a library for gdb: %s\n", new->l_name);
+    debug("add a library for gdb: %s\n", uri);
 
 
     new->l_prev = prev;
     new->l_prev = prev;
-    new->l_next = link_map_list;
+    new->l_next = NULL;
     *tail = new;
     *tail = new;
-    if (link_map_list)
-        link_map_list->l_prev = new;
 
 
-    _r_debug.r_state = RT_CONSISTENT;
-    _dl_debug_state_trigger();
+    DkDebugAttachBinary(uri, addr);
 }
 }
 
 
 DEFINE_MIGRATE_FUNC(gdb_map)
 DEFINE_MIGRATE_FUNC(gdb_map)
@@ -278,10 +145,6 @@ END_MIGRATE_FUNC
 RESUME_FUNC_BODY(gdb_map)
 RESUME_FUNC_BODY(gdb_map)
 {
 {
     uint64_t off = GET_FUNC_ENTRY();
     uint64_t off = GET_FUNC_ENTRY();
-
-    _r_debug.r_state = RT_ADD;
-    _dl_debug_state_trigger ();
-
     struct gdb_link_map *map = (struct gdb_link_map *) (base + off);
     struct gdb_link_map *map = (struct gdb_link_map *) (base + off);
 
 
     RESUME_REBASE(map->l_name);
     RESUME_REBASE(map->l_name);
@@ -299,20 +162,10 @@ RESUME_FUNC_BODY(gdb_map)
     map->l_prev = prev;
     map->l_prev = prev;
     *tail = map;
     *tail = map;
 
 
-    tail = &_r_debug.r_map;
-    while (*tail && *tail != link_map_list) {
-        prev = *tail;
-        tail = &(*tail)->l_next;
-    }
-
-    *tail = link_map_list;
-    link_map_list->l_prev = prev;
-
 #ifdef DEBUG_RESUME
 #ifdef DEBUG_RESUME
     debug("gdb: %s loaded at %p\n", map->l_name, map->l_addr);
     debug("gdb: %s loaded at %p\n", map->l_name, map->l_addr);
 #endif
 #endif
 
 
-    _r_debug.r_state = RT_CONSISTENT;
-    _dl_debug_state_trigger ();
+    DkDebugAttachBinary(map->l_name, map->l_addr);
 }
 }
 END_RESUME_FUNC
 END_RESUME_FUNC

+ 24 - 2
LibOS/shim/src/shim_init.c

@@ -148,6 +148,9 @@ void allocate_tls (void * tcb_location, struct shim_thread * thread)
         thread->tcb       = tcb;
         thread->tcb       = tcb;
         tcb->shim_tcb.tp  = thread;
         tcb->shim_tcb.tp  = thread;
         tcb->shim_tcb.tid = thread->tid;
         tcb->shim_tcb.tid = thread->tid;
+    } else {
+        tcb->shim_tcb.tp  = NULL;
+        tcb->shim_tcb.tid = 0;
     }
     }
 
 
     DkThreadPrivate(tcb);
     DkThreadPrivate(tcb);
@@ -210,7 +213,7 @@ void * allocate_stack (size_t size, size_t protect_size, bool user)
 
 
         if (protect_size &&
         if (protect_size &&
             bkeep_mmap(stack - protect_size, protect_size, 0,
             bkeep_mmap(stack - protect_size, protect_size, 0,
-                       STACK_FLAGS, NULL, 0, "stack-red") < 0)
+                       STACK_FLAGS, NULL, 0, NULL) < 0)
             return NULL;
             return NULL;
     }
     }
 
 
@@ -394,7 +397,8 @@ int init_manifest (PAL_HANDLE manifest_handle)
 
 
     size_t cfg_size = attr.size;
     size_t cfg_size = attr.size;
     void * cfg_addr = DkStreamMap(manifest_handle, NULL,
     void * cfg_addr = DkStreamMap(manifest_handle, NULL,
-                                  PAL_PROT_READ, 0, ALIGN_UP(cfg_size));
+                                  PAL_PROT_READ|PAL_PROT_WRITECOPY, 0,
+                                  ALIGN_UP(cfg_size));
 
 
     if (!cfg_addr)
     if (!cfg_addr)
         return -PAL_ERRNO;
         return -PAL_ERRNO;
@@ -583,6 +587,7 @@ int shim_init (int argc, void * args, void ** return_stack)
 
 
     /* create the initial TCB, shim can not be run without a tcb */
     /* create the initial TCB, shim can not be run without a tcb */
     __libc_tcb_t tcb;
     __libc_tcb_t tcb;
+    memset(&tcb, 0, sizeof(__libc_tcb_t));
     allocate_tls(&tcb, NULL);
     allocate_tls(&tcb, NULL);
     debug_setbuf(&tcb.shim_tcb, true);
     debug_setbuf(&tcb.shim_tcb, true);
 
 
@@ -920,6 +925,23 @@ int create_handle (const char * prefix, char * uri, size_t size,
                          id ? : &suffix, hdl, NULL);
                          id ? : &suffix, hdl, NULL);
 }
 }
 
 
+void check_stack_hook (void)
+{
+    struct shim_thread * cur_thread = get_cur_thread();
+
+    void * rsp;
+    asm volatile ("movq %%rsp, %0" : "=r"(rsp) :: "memory");
+
+    if (rsp <= cur_thread->stack_top && rsp > cur_thread->stack) {
+        if (rsp - cur_thread->stack < PAL_CB(pagesize))
+            sys_printf("*** stack is almost drained (RSP = %p, stack = %p-%p) ***\n",
+                       rsp, cur_thread->stack, cur_thread->stack_top);
+    } else {
+        sys_printf("*** context dismateched with thread stack (RSP = %p, stack = %p-%p) ***\n",
+                   rsp, cur_thread->stack, cur_thread->stack_top);
+    }
+}
+
 #ifdef PROFILE
 #ifdef PROFILE
 static void print_profile_result (PAL_HANDLE hdl, struct shim_profile * root,
 static void print_profile_result (PAL_HANDLE hdl, struct shim_profile * root,
                                   int level)
                                   int level)

+ 2 - 5
LibOS/shim/src/shim_malloc.c

@@ -111,9 +111,7 @@ static struct shim_heap * __alloc_enough_heap (size_t size)
 
 
         unlock(shim_heap_lock);
         unlock(shim_heap_lock);
         bkeep_mmap(start, heap_size, PROT_READ|PROT_WRITE,
         bkeep_mmap(start, heap_size, PROT_READ|PROT_WRITE,
-                   MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0,
-                   "shim-heap");
-
+                   MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL);
         lock(shim_heap_lock);
         lock(shim_heap_lock);
     }
     }
 
 
@@ -175,8 +173,7 @@ int bkeep_shim_heap (void)
             bkeep_mmap(shim_heap_areas[i].start,
             bkeep_mmap(shim_heap_areas[i].start,
                        shim_heap_areas[i].end - shim_heap_areas[i].start,
                        shim_heap_areas[i].end - shim_heap_areas[i].start,
                        PROT_READ|PROT_WRITE,
                        PROT_READ|PROT_WRITE,
-                       MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0,
-                       "shim-heap");
+                       MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL);
 
 
     unlock(shim_heap_lock);
     unlock(shim_heap_lock);
     return 0;
     return 0;

+ 51 - 5
LibOS/shim/src/shim_parser.c

@@ -37,6 +37,7 @@
 #include <asm/prctl.h>
 #include <asm/prctl.h>
 #include <asm/mman.h>
 #include <asm/mman.h>
 #include <asm/ioctls.h>
 #include <asm/ioctls.h>
+#include <linux/sched.h>
 #include <linux/futex.h>
 #include <linux/futex.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <errno.h>
 #include <errno.h>
@@ -45,6 +46,7 @@
 static void parse_open_flags    (const char *, va_list);
 static void parse_open_flags    (const char *, va_list);
 static void parse_open_mode     (const char *, va_list);
 static void parse_open_mode     (const char *, va_list);
 static void parse_access_mode   (const char *, va_list);
 static void parse_access_mode   (const char *, va_list);
+static void parse_clone_flags   (const char *, va_list);
 static void parse_mmap_prot     (const char *, va_list);
 static void parse_mmap_prot     (const char *, va_list);
 static void parse_mmap_flags    (const char *, va_list);
 static void parse_mmap_flags    (const char *, va_list);
 static void parse_exec_args     (const char *, va_list);
 static void parse_exec_args     (const char *, va_list);
@@ -130,7 +132,7 @@ struct parser_table {
       .parser = { NULL, NULL, NULL, &parse_pipe_fds } },
       .parser = { NULL, NULL, NULL, &parse_pipe_fds } },
     { .slow = 0, .parser = { NULL } }, /* setsockopt */
     { .slow = 0, .parser = { NULL } }, /* setsockopt */
     { .slow = 0, .parser = { NULL } }, /* getsockopt */
     { .slow = 0, .parser = { NULL } }, /* getsockopt */
-    { .slow = 1, .parser = { NULL } }, /* clone */
+    { .slow = 1, .parser = { &parse_clone_flags } }, /* clone */
     { .slow = 1, .parser = { NULL } }, /* fork */
     { .slow = 1, .parser = { NULL } }, /* fork */
     { .slow = 1, .parser = { NULL } }, /* vfork */
     { .slow = 1, .parser = { NULL } }, /* vfork */
     { .slow = 1,                       /* execve */
     { .slow = 1,                       /* execve */
@@ -612,6 +614,37 @@ static void parse_access_mode (const char * type, va_list ap)
     }
     }
 }
 }
 
 
+static void parse_clone_flags (const char * type, va_list ap)
+{
+    int flags = va_arg (ap, int);
+
+#define FLG(n) { "CLONE_" #n, CLONE_##n, }
+    const struct {
+        const char * name; int flag;
+    } all_flags[] = {
+        FLG(VM), FLG(FS), FLG(FILES), FLG(SIGHAND), FLG(PTRACE), FLG(VFORK),
+        FLG(PARENT), FLG(THREAD), FLG(NEWNS), FLG(SYSVSEM), FLG(SETTLS),
+        FLG(PARENT_SETTID), FLG(CHILD_CLEARTID), FLG(DETACHED), FLG(UNTRACED),
+        FLG(CHILD_SETTID), FLG(NEWUTS), FLG(NEWIPC), FLG(NEWUSER),
+        FLG(NEWPID), FLG(NEWNET), FLG(IO),
+    };
+#undef FLG
+
+    bool printed = false;
+    for (int i = 0 ; i < sizeof(all_flags) / sizeof(all_flags[0]) ; i++)
+        if (flags & all_flags[i].flag) {
+            if (printed)
+                PUTCH('|');
+            else
+                printed = true;
+            PUTS(all_flags[i].name);
+            flags &= ~all_flags[i].flag;
+        }
+
+    if (flags)
+        PRINTF("|0x%x", flags);
+}
+
 static void parse_mmap_prot (const char * type, va_list ap)
 static void parse_mmap_prot (const char * type, va_list ap)
 {
 {
     int prot = va_arg (ap, int);
     int prot = va_arg (ap, int);
@@ -650,23 +683,36 @@ static void parse_mmap_flags (const char * type, va_list ap)
         PUTS("MAP_SHARED");
         PUTS("MAP_SHARED");
         flags &= ~MAP_SHARED;
         flags &= ~MAP_SHARED;
     }
     }
-    else
+
+    if (flags & MAP_PRIVATE) {
         PUTS("MAP_PRIVATE");
         PUTS("MAP_PRIVATE");
+        flags &= ~MAP_PRIVATE;
+    }
 
 
     if (flags & MAP_ANONYMOUS) {
     if (flags & MAP_ANONYMOUS) {
         PUTS("|MAP_ANON");
         PUTS("|MAP_ANON");
         flags &= ~MAP_ANONYMOUS;
         flags &= ~MAP_ANONYMOUS;
     }
     }
-    else
+
+    if (flags & MAP_FILE) {
         PUTS("|MAP_FILE");
         PUTS("|MAP_FILE");
+        flags &= ~MAP_FILE;
+    }
 
 
     if (flags & MAP_FIXED) {
     if (flags & MAP_FIXED) {
         PUTS("|MAP_FIXED");
         PUTS("|MAP_FIXED");
         flags &= ~MAP_FIXED;
         flags &= ~MAP_FIXED;
     }
     }
 
 
+#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED
+    if (flags & MAP_UNINITIALIZED) {
+        PUTS("|MAP_UNINITIALIZED");
+        flags &= ~MAP_UNINITIALIZED;
+    }
+#endif
+
     if (flags)
     if (flags)
-        PRINTF("|%o", flags);
+        PRINTF("|0x%x", flags);
 }
 }
 
 
 static void parse_exec_args (const char * type, va_list ap)
 static void parse_exec_args (const char * type, va_list ap)
@@ -884,7 +930,7 @@ static void parse_futexop (const char * type, va_list ap)
             PUTS("FUTEX_CMP_REQUEUE");
             PUTS("FUTEX_CMP_REQUEUE");
             break;
             break;
         case FUTEX_WAKE_OP:
         case FUTEX_WAKE_OP:
-            PUTS("FUTEX_WAKE");
+            PUTS("FUTEX_WAKE_OP");
             break;
             break;
         default:
         default:
             PRINTF("OP %d", op);
             PRINTF("OP %d", op);

+ 13 - 4
LibOS/shim/src/sys/shim_brk.c

@@ -50,6 +50,15 @@ DEFINE_PROFILE_OCCURENCE(brk, memory);
 DEFINE_PROFILE_OCCURENCE(brk_count, memory);
 DEFINE_PROFILE_OCCURENCE(brk_count, memory);
 DEFINE_PROFILE_OCCURENCE(brk_migrate_count, memory);
 DEFINE_PROFILE_OCCURENCE(brk_migrate_count, memory);
 
 
+void get_brk_region (void ** start, void ** end, void ** current)
+{
+    master_lock();
+    *start   = region.brk_start;
+    *end     = region.brk_end;
+    *current = region.brk_current;
+    master_unlock();
+}
+
 int init_brk_region (void)
 int init_brk_region (void)
 {
 {
     if (region.brk_start)
     if (region.brk_start)
@@ -88,11 +97,11 @@ int init_brk_region (void)
           brk_region + brk_max_size);
           brk_region + brk_max_size);
 
 
     bkeep_mmap(brk_region, BRK_SIZE, PROT_READ|PROT_WRITE,
     bkeep_mmap(brk_region, BRK_SIZE, PROT_READ|PROT_WRITE,
-               MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "brk");
+               MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "[heap]");
     bkeep_mmap(end_brk_region, brk_max_size - BRK_SIZE,
     bkeep_mmap(end_brk_region, brk_max_size - BRK_SIZE,
                PROT_READ|PROT_WRITE,
                PROT_READ|PROT_WRITE,
                MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED,
                MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED,
-               NULL, 0, "brk-reserved");
+               NULL, 0, NULL);
 
 
     return 0;
     return 0;
 }
 }
@@ -148,7 +157,7 @@ unchanged:
 
 
         bkeep_mmap(region.brk_start, brk_end - region.brk_start,
         bkeep_mmap(region.brk_start, brk_end - region.brk_start,
                    PROT_READ|PROT_WRITE,
                    PROT_READ|PROT_WRITE,
-                   MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "brk");
+                   MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "heap");
 
 
         region.brk_current = brk;
         region.brk_current = brk;
         region.brk_end = brk_end;
         region.brk_end = brk_end;
@@ -203,7 +212,7 @@ RESUME_FUNC_BODY(brk)
         bkeep_mmap(region.brk_end, brk_max_size - brk_size,
         bkeep_mmap(region.brk_end, brk_max_size - brk_size,
                    PROT_READ|PROT_WRITE,
                    PROT_READ|PROT_WRITE,
                    MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED, NULL, 0,
                    MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED, NULL, 0,
-                   "brk-reserved");
+                   NULL);
     }
     }
 
 
 #ifdef DEBUG_RESUME
 #ifdef DEBUG_RESUME

+ 147 - 70
LibOS/shim/src/sys/shim_clone.c

@@ -29,6 +29,7 @@
 #include <shim_table.h>
 #include <shim_table.h>
 #include <shim_thread.h>
 #include <shim_thread.h>
 #include <shim_utils.h>
 #include <shim_utils.h>
+#include <shim_checkpoint.h>
 #include <shim_profile.h>
 #include <shim_profile.h>
 
 
 #include <pal.h>
 #include <pal.h>
@@ -40,6 +41,14 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <asm/prctl.h>
 #include <asm/prctl.h>
 
 
+struct clone_args {
+    PAL_HANDLE create_event;
+    PAL_HANDLE initialize_event;
+    struct shim_thread * thread, * parent;
+    void * stack;
+    void * return_pc;
+};
+
 /* from **sysdeps/unix/sysv/linux/x86_64/clone.S:
 /* from **sysdeps/unix/sysv/linux/x86_64/clone.S:
    The userland implementation is:
    The userland implementation is:
    int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
    int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
@@ -96,10 +105,17 @@ int clone_implementation_wrapper(struct clone_args * arg)
     assert(my_thread);
     assert(my_thread);
     get_thread(my_thread);
     get_thread(my_thread);
 
 
-    if (my_thread->set_child_tid) {
+    if (!my_thread->tcb)
+        my_thread->tcb = __alloca(sizeof(__libc_tcb_t));
+    allocate_tls(my_thread->tcb, my_thread);
+    shim_tcb_t * tcb = &((__libc_tcb_t *) my_thread->tcb)->shim_tcb;
+    debug_setbuf(tcb, true);
+
+    struct shim_regs * regs = __alloca(sizeof(struct shim_regs));
+    *regs = *((__libc_tcb_t *) arg->parent->tcb)->shim_tcb.context.regs;
+
+    if (my_thread->set_child_tid)
         *(my_thread->set_child_tid) = my_thread->tid;
         *(my_thread->set_child_tid) = my_thread->tid;
-        debug("clone: tid set at %p\n", my_thread->set_child_tid);
-    }
 
 
     void * stack = pcargs->stack;
     void * stack = pcargs->stack;
     void * return_pc = pcargs->return_pc;
     void * return_pc = pcargs->return_pc;
@@ -107,12 +123,9 @@ int clone_implementation_wrapper(struct clone_args * arg)
     struct shim_vma * vma = NULL;
     struct shim_vma * vma = NULL;
     lookup_supervma(ALIGN_DOWN(stack), allocsize, &vma);
     lookup_supervma(ALIGN_DOWN(stack), allocsize, &vma);
     assert(vma);
     assert(vma);
-    my_thread->stack_top = stack;
+    my_thread->stack_top = vma->addr + vma->length;
     my_thread->stack_red = my_thread->stack = vma->addr;
     my_thread->stack_red = my_thread->stack = vma->addr;
-
-    __libc_tcb_t tcb;
-    allocate_tls(&tcb, my_thread);
-    debug_setbuf(&tcb.shim_tcb, true);
+    snprintf(vma->comment, VMA_COMMENT_LEN, "stack:%d", my_thread->tid);
 
 
     /* Don't signal the initialize event until we are actually init-ed */ 
     /* Don't signal the initialize event until we are actually init-ed */ 
     DkEventSet(pcargs->initialize_event);
     DkEventSet(pcargs->initialize_event);
@@ -125,13 +138,18 @@ int clone_implementation_wrapper(struct clone_args * arg)
     debug("child swapping stack to %p return %p: %d\n",
     debug("child swapping stack to %p return %p: %d\n",
           stack, return_pc, my_thread->tid);
           stack, return_pc, my_thread->tid);
 
 
-    asm volatile("movq %0, %%rsp\r\n"
-                 "pushq %1\r\n"
-                 "retq\r\n"
-                 : : "r"(stack), "r"(return_pc), "a"(0));
+    tcb->context.regs = regs;
+    tcb->context.sp = stack;
+    tcb->context.ret_ip = return_pc;
+
+    restore_context(&tcb->context);
     return 0;
     return 0;
 }
 }
 
 
+int migrate_fork (struct shim_cp_store * cpstore,
+                  struct shim_process * process,
+                  struct shim_thread * thread, va_list ap);
+
 /*  long int __arg0 - flags
 /*  long int __arg0 - flags
  *  long int __arg1 - 16 bytes ( 2 words ) offset into the child stack allocated
  *  long int __arg1 - 16 bytes ( 2 words ) offset into the child stack allocated
  *                    by the parent     */
  *                    by the parent     */
@@ -144,8 +162,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
     INC_PROFILE_OCCURENCE(syscall_use_ipc);
     INC_PROFILE_OCCURENCE(syscall_use_ipc);
     struct shim_thread * self = get_cur_thread();
     struct shim_thread * self = get_cur_thread();
     assert(self);
     assert(self);
-    struct clone_args * new_args = __alloca(sizeof(struct clone_args));
-    memset(new_args, 0, sizeof(struct clone_args));
+    int * set_parent_tid = NULL;
     int ret = 0;
     int ret = 0;
 
 
     assert((flags & ~(CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
     assert((flags & ~(CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
@@ -158,67 +175,58 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
 #endif
 #endif
                       CLONE_SYSVSEM|CSIGNAL)) == 0);
                       CLONE_SYSVSEM|CSIGNAL)) == 0);
 
 
-    new_args->create_event = DkNotificationEventCreate(0);
-    if (!new_args->create_event) {
-        ret = -PAL_ERRNO;
-        goto failed;
-    }
+    if (!(flags & CLONE_FS))
+        debug("clone without CLONE_FS is not yet implemented\n");
 
 
-    new_args->initialize_event = DkNotificationEventCreate(0);
-    if (!new_args->initialize_event) {
-        ret = -PAL_ERRNO;
-        goto failed;
+    if (!(flags & CLONE_SIGHAND))
+        debug("clone without CLONE_SIGHAND is not yet implemented\n");
+
+    if (!(flags & CLONE_SYSVSEM))
+        debug("clone without CLONE_SYSVSEM is not yet implemented\n");
+
+    if (flags & CLONE_PARENT_SETTID) {
+        if (!parent_tidptr)
+            return -EINVAL;
+        set_parent_tid = parent_tidptr;
     }
     }
 
 
-    new_args->thread = get_new_thread(0);
-    if (!new_args->thread) {
+    struct shim_thread * thread = get_new_thread(0);
+    if (!thread) {
         ret = -ENOMEM;
         ret = -ENOMEM;
         goto failed;
         goto failed;
     }
     }
 
 
-    new_args->stack     = user_stack_addr;
-    new_args->return_pc = *(void **) user_stack_addr;
+    IDTYPE tid = thread->tid;
 
 
-    if (flags & CLONE_PARENT_SETTID)
-        new_args->thread->set_child_tid = parent_tidptr;
-
-    if ((flags & CLONE_CHILD_SETTID) && (flags & CLONE_CHILD_CLEARTID)) {
-        ret = -EINVAL;
-        goto failed;
+    if (flags & CLONE_CHILD_SETTID) {
+        if (!child_tidptr) {
+            ret = -EINVAL;
+            goto failed;
+        }
+        thread->set_child_tid = child_tidptr;
     }
     }
 
 
-    if (flags & CLONE_CHILD_SETTID)
-        new_args->thread->set_child_tid = child_tidptr;
-
     if (flags & CLONE_CHILD_CLEARTID)
     if (flags & CLONE_CHILD_CLEARTID)
         /* Implemented in shim_futex.c: release_clear_child_id */
         /* Implemented in shim_futex.c: release_clear_child_id */
-        new_args->thread->clear_child_tid = parent_tidptr;
+        thread->clear_child_tid = parent_tidptr;
 
 
     if (flags & CLONE_SETTLS) {
     if (flags & CLONE_SETTLS) {
-        new_args->thread->tcb = tls;
+        if (!tls) {
+            ret = -EINVAL;
+            goto failed;
+        }
+        thread->tcb = tls;
     } else {
     } else {
-        new_args->thread->tcb = NULL;
+        thread->tcb = NULL;
     }
     }
 
 
-    if ((flags & CLONE_VM) != CLONE_VM)
-        debug("Fork-like behavior is not yet implemented in clone\n");
-
-    if ((flags & CLONE_FS) != CLONE_FS)
-        debug("clone without CLONE_FS is not yet implemented\n");
-
-    if ((flags & CLONE_SIGHAND) != CLONE_SIGHAND)
-        debug("clone without CLONE_SIGHAND is not yet implemented\n");
-
-    if ((flags & CLONE_SYSVSEM) != CLONE_SYSVSEM)
-        debug("clone without CLONE_SYSVSEM is not yet implemented\n");
-
-    if ((flags & CLONE_THREAD) != CLONE_THREAD)
-        new_args->thread->tgid = new_args->thread->tid;
+    if (!(flags & CLONE_THREAD))
+        thread->tgid = thread->tid;
 
 
     struct shim_handle_map * handle_map = get_cur_handle_map(self);
     struct shim_handle_map * handle_map = get_cur_handle_map(self);
 
 
     if (flags & CLONE_FILES) {
     if (flags & CLONE_FILES) {
-        set_handle_map(new_args->thread, handle_map);
+        set_handle_map(thread, handle_map);
     } else {
     } else {
         /* if CLONE_FILES is not given, the new thread should receive
         /* if CLONE_FILES is not given, the new thread should receive
            a copy of current descriptor table */
            a copy of current descriptor table */
@@ -226,10 +234,81 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
 
 
         get_handle_map(handle_map);
         get_handle_map(handle_map);
         dup_handle_map(&new_map, handle_map);
         dup_handle_map(&new_map, handle_map);
-        set_handle_map(new_args->thread, new_map);
+        set_handle_map(thread, new_map);
         put_handle_map(handle_map);
         put_handle_map(handle_map);
     }
     }
 
 
+    if (!(flags & CLONE_VM)) {
+        __libc_tcb_t * tcb;
+        shim_tcb_t * old_shim_tcb = NULL;
+
+        if (thread->tcb) {
+            tcb = (__libc_tcb_t *) thread->tcb;
+        } else {
+            thread->tcb = tcb = (__libc_tcb_t *) self->tcb;
+            old_shim_tcb = __alloca(sizeof(shim_tcb_t));
+            memcpy(old_shim_tcb, &tcb->shim_tcb, sizeof(shim_tcb_t));
+        }
+
+        if (user_stack_addr) {
+            struct shim_vma * vma = NULL;
+            lookup_supervma(ALIGN_DOWN(user_stack_addr), allocsize, &vma);
+            assert(vma);
+            thread->stack_top = vma->addr + vma->length;
+            thread->stack_red = thread->stack = vma->addr;
+            tcb->shim_tcb.context.sp = user_stack_addr;
+            tcb->shim_tcb.context.ret_ip = *(void **) user_stack_addr;
+        } else {
+            tcb->shim_tcb.context.ret_ip = *(void **) tcb->shim_tcb.context.sp;
+        }
+
+        thread->is_alive = true;
+        thread->in_vm = false;
+        add_thread(thread);
+        set_as_child(self, thread);
+
+        if ((ret = do_migrate_process(&migrate_fork, NULL, NULL, thread)) < 0)
+            goto failed;
+
+        if (old_shim_tcb)
+            memcpy(&tcb->shim_tcb, old_shim_tcb, sizeof(shim_tcb_t));
+
+        lock(thread->lock);
+        handle_map = thread->handle_map;
+        thread->handle_map = NULL;
+        unlock(thread->lock);
+        if (handle_map)
+            put_handle_map(handle_map);
+
+        if (set_parent_tid)
+            *set_parent_tid = tid;
+
+        put_thread(thread);
+        return tid;
+    }
+
+    enable_locking();
+
+    struct clone_args * new_args = __alloca(sizeof(struct clone_args));
+    memset(new_args, 0, sizeof(struct clone_args));
+
+    new_args->create_event = DkNotificationEventCreate(0);
+    if (!new_args->create_event) {
+        ret = -PAL_ERRNO;
+        goto clone_thread_failed;
+    }
+
+    new_args->initialize_event = DkNotificationEventCreate(0);
+    if (!new_args->initialize_event) {
+        ret = -PAL_ERRNO;
+        goto clone_thread_failed;
+    }
+
+    new_args->thread    = thread;
+    new_args->parent    = self;
+    new_args->stack     = user_stack_addr;
+    new_args->return_pc = *(void **) user_stack_addr;
+
     // Invoke DkThreadCreate to spawn off a child process using the actual 
     // Invoke DkThreadCreate to spawn off a child process using the actual 
     // "clone" system call. DkThreadCreate allocates a stack for the child 
     // "clone" system call. DkThreadCreate allocates a stack for the child 
     // and then runs the given function on that stack However, we want our 
     // and then runs the given function on that stack However, we want our 
@@ -240,32 +319,30 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
                                           new_args, flags);
                                           new_args, flags);
     if (!pal_handle) {
     if (!pal_handle) {
         ret = -PAL_ERRNO;
         ret = -PAL_ERRNO;
-        goto failed;
+        goto clone_thread_failed;
     }
     }
 
 
-    new_args->thread->pal_handle = pal_handle;
+    thread->pal_handle = pal_handle;
+    thread->in_vm = thread->is_alive = true;
+    add_thread(thread);
+    set_as_child(self, thread);
 
 
-    new_args->thread->in_vm = new_args->thread->is_alive = true;
-    add_thread(new_args->thread);
-    set_as_child(NULL, new_args->thread);
-    put_thread(new_args->thread);
-
-    if (new_args->thread->set_child_tid)
-        *new_args->thread->set_child_tid = new_args->thread->tid;
+    if (set_parent_tid)
+        *set_parent_tid = tid;
 
 
     DkEventSet(new_args->create_event);
     DkEventSet(new_args->create_event);
-
     DkObjectsWaitAny(1, &new_args->initialize_event, NO_TIMEOUT);
     DkObjectsWaitAny(1, &new_args->initialize_event, NO_TIMEOUT);
     DkObjectClose(new_args->initialize_event);
     DkObjectClose(new_args->initialize_event);
+    put_thread(thread);
+    return tid;
 
 
-    return new_args->thread->tid;
-
-failed:
+clone_thread_failed:
     if (new_args->create_event)
     if (new_args->create_event)
         DkObjectClose(new_args->create_event);
         DkObjectClose(new_args->create_event);
     if (new_args->initialize_event)
     if (new_args->initialize_event)
         DkObjectClose(new_args->initialize_event);
         DkObjectClose(new_args->initialize_event);
-    if (new_args->thread)
-        put_thread(new_args->thread);
+failed:
+    if (thread)
+        put_thread(thread);
     return ret;
     return ret;
 }
 }

+ 1 - 2
LibOS/shim/src/sys/shim_exec.c

@@ -154,8 +154,7 @@ static void * __malloc (size_t size)
     addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
     addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
 
 
     if (addr)
     if (addr)
-        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0,
-                   "checkpoint");
+        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
 
 
     return addr;
     return addr;
 }
 }

+ 4 - 6
LibOS/shim/src/sys/shim_fork.c

@@ -47,8 +47,7 @@ static void * __malloc (size_t size)
     addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
     addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
 
 
     if (addr)
     if (addr)
-        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0,
-                   "checkpoint");
+        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
 
 
     return addr;
     return addr;
 }
 }
@@ -56,9 +55,9 @@ static void * __malloc (size_t size)
 #define malloc_method __malloc
 #define malloc_method __malloc
 #include <shim_checkpoint.h>
 #include <shim_checkpoint.h>
 
 
-static int migrate_fork (struct shim_cp_store * cpstore,
-                         struct shim_process * process,
-                         struct shim_thread * thread, va_list ap)
+int migrate_fork (struct shim_cp_store * cpstore,
+                  struct shim_process * process,
+                  struct shim_thread * thread, va_list ap)
 {
 {
     BEGIN_MIGRATION_DEF(fork, struct shim_process * proc,
     BEGIN_MIGRATION_DEF(fork, struct shim_process * proc,
                         struct shim_thread * thread)
                         struct shim_thread * thread)
@@ -104,7 +103,6 @@ int shim_do_fork (void)
     if (!new_thread)
     if (!new_thread)
         return -ENOMEM;
         return -ENOMEM;
 
 
-    new_thread->stack    = cur_thread->stack;
     new_thread->tcb      = cur_thread->tcb;
     new_thread->tcb      = cur_thread->tcb;
     new_thread->tgid     = new_thread->tid;
     new_thread->tgid     = new_thread->tid;
     new_thread->in_vm    = false;
     new_thread->in_vm    = false;

+ 126 - 20
LibOS/shim/src/sys/shim_futex.c

@@ -43,6 +43,11 @@
 #define FUTEX_MIN_VALUE 0
 #define FUTEX_MIN_VALUE 0
 #define FUTEX_MAX_VALUE 255
 #define FUTEX_MAX_VALUE 255
 
 
+struct futex_waiter {
+    struct shim_thread * thread;
+    struct list_head list;
+};
+
 static LIST_HEAD(futex_list);
 static LIST_HEAD(futex_list);
 static LOCKTYPE futex_list_lock;
 static LOCKTYPE futex_list_lock;
 
 
@@ -66,11 +71,9 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
         }
         }
 
 
     if (futex) {
     if (futex) {
-        hdl = container_of(tmp, struct shim_handle, info.futex);
+        hdl = container_of(futex, struct shim_handle, info.futex);
         get_handle(hdl);
         get_handle(hdl);
     } else {
     } else {
-        struct shim_vma * vma_addr = NULL;
-
         if (!(hdl = get_new_handle())) {
         if (!(hdl = get_new_handle())) {
             unlock(futex_list_lock);
             unlock(futex_list_lock);
             return -ENOMEM;
             return -ENOMEM;
@@ -79,15 +82,6 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
         hdl->type = TYPE_FUTEX;
         hdl->type = TYPE_FUTEX;
         futex = &hdl->info.futex;
         futex = &hdl->info.futex;
         futex->uaddr = uaddr;
         futex->uaddr = uaddr;
-        futex->vma = vma_addr;
-
-        futex->event = DkSynchronizationEventCreate(0);
-        if (futex->event == NULL) {
-            ret = -PAL_ERRNO;
-            unlock(futex_list_lock);
-            goto out;
-        }
-
         get_handle(hdl);
         get_handle(hdl);
         INIT_LIST_HEAD(&futex->waiters);
         INIT_LIST_HEAD(&futex->waiters);
         INIT_LIST_HEAD(&futex->list);
         INIT_LIST_HEAD(&futex->list);
@@ -97,13 +91,9 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
     unlock(futex_list_lock);
     unlock(futex_list_lock);
     lock(hdl->lock);
     lock(hdl->lock);
 
 
-    struct futex_waiter {
-        struct shim_thread * thread;
-        struct list_head list;
-    };
-
     switch (op & FUTEX_CMD_MASK) {
     switch (op & FUTEX_CMD_MASK) {
         case FUTEX_WAIT:
         case FUTEX_WAIT:
+            debug("FUTEX_WAIT: %p (val = %d) vs %d\n", uaddr, *uaddr, val);
             if (*uaddr != val)
             if (*uaddr != val)
                 break;
                 break;
 
 
@@ -118,7 +108,9 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
             break;
             break;
 
 
         case FUTEX_WAKE: {
         case FUTEX_WAKE: {
-            for (int cnt = 0 ; cnt < val ; cnt++) {
+            debug("FUTEX_WAKE: %p (val = %d)\n", uaddr, *uaddr);
+            int cnt;
+            for (cnt = 0 ; cnt < val ; cnt++) {
                 if (list_empty(&futex->waiters))
                 if (list_empty(&futex->waiters))
                     break;
                     break;
 
 
@@ -126,9 +118,89 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
                                                           struct futex_waiter,
                                                           struct futex_waiter,
                                                           list);
                                                           list);
 
 
+                debug("FUTEX_WAKE wake thread %d: %p (val = %d)\n",
+                      waiter->thread->tid, uaddr, *uaddr);
                 list_del(&waiter->list);
                 list_del(&waiter->list);
                 thread_wakeup(waiter->thread);
                 thread_wakeup(waiter->thread);
             }
             }
+            ret = cnt;
+            debug("FUTEX_WAKE done: %p (val = %d)\n", uaddr, *uaddr);
+            break;
+        }
+
+        case FUTEX_CMP_REQUEUE:
+            if (*uaddr != val3) {
+                ret = -EAGAIN;
+                break;
+            }
+
+        case FUTEX_REQUEUE: {
+            struct shim_futex_handle * futex2 = NULL;
+            struct shim_handle * hdl2;
+
+            lock(futex_list_lock);
+
+            list_for_each_entry(tmp, &futex_list, list)
+                if (tmp->uaddr == uaddr2) {
+                    futex2 = tmp;
+                    break;
+                }
+
+            if (futex2) {
+                hdl2 = container_of(futex2, struct shim_handle, info.futex);
+                get_handle(hdl2);
+            } else {
+                if (!(hdl2 = get_new_handle())) {
+                    unlock(futex_list_lock);
+                    ret = -ENOMEM;
+                    goto out;
+                }
+
+                hdl2->type = TYPE_FUTEX;
+                futex2 = &hdl2->info.futex;
+                futex2->uaddr = uaddr2;
+#if 0
+                futex2->event = DkSynchronizationEventCreate(0);
+                if (futex2->event == NULL) {
+                    ret = -PAL_ERRNO;
+                    unlock(futex_list_lock);
+                    put_handle(hdl2);
+                    goto out;
+                }
+#endif
+                get_handle(hdl2);
+                INIT_LIST_HEAD(&futex2->waiters);
+                INIT_LIST_HEAD(&futex2->list);
+                list_add_tail(&futex2->list, &futex_list);
+            }
+
+            unlock(futex_list_lock);
+
+            int cnt;
+            for (cnt = 0 ; cnt < val ; cnt++) {
+                if (list_empty(&futex->waiters))
+                    break;
+
+                struct futex_waiter * waiter = list_entry(futex->waiters.next,
+                                                          struct futex_waiter,
+                                                          list);
+
+                list_del(&waiter->list);
+                thread_wakeup(waiter->thread);
+            }
+
+            lock(hdl2->lock);
+            while (!list_empty(&futex->waiters)) {
+                struct futex_waiter * waiter = list_entry(futex->waiters.next,
+                                                          struct futex_waiter,
+                                                          list);
+
+                list_del(&waiter->list);
+                list_add_tail(&waiter->list, &futex2->waiters);
+            }
+            unlock(hdl2->lock);
+            put_handle(hdl2);
+            ret = cnt;
             break;
             break;
         }
         }
 
 
@@ -137,6 +209,7 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
             break;
             break;
 
 
         default:
         default:
+            debug("unsupported futex op: 0x%x\n", op);
             ret = -ENOSYS;
             ret = -ENOSYS;
             break;
             break;
     }
     }
@@ -205,7 +278,24 @@ void release_robust_list (struct robust_list_head * head)
         if (!futex)
         if (!futex)
             continue;
             continue;
 
 
-        DkEventSet(futex->event);
+        struct shim_handle * hdl =
+            container_of(futex, struct shim_handle, info.futex);
+        get_handle(hdl);
+        lock(hdl->lock);
+
+        debug("release robust list: %p\n", futex_addr);
+        *(int *) futex_addr = 0;
+        while (!list_empty(&futex->waiters)) {
+            struct futex_waiter * waiter = list_entry(futex->waiters.next,
+                                                      struct futex_waiter,
+                                                      list);
+
+            list_del(&waiter->list);
+            thread_wakeup(waiter->thread);
+        }
+
+        unlock(hdl->lock);
+        put_handle(hdl);
     }
     }
 }
 }
 
 
@@ -230,6 +320,22 @@ void release_clear_child_id (int * clear_child_tid)
     if (!futex)
     if (!futex)
         return;
         return;
 
 
+    struct shim_handle * hdl =
+            container_of(futex, struct shim_handle, info.futex);
+    get_handle(hdl);
+    lock(hdl->lock);
+
     debug("release futex at %p\n", clear_child_tid);
     debug("release futex at %p\n", clear_child_tid);
-    DkEventSet(futex->event);
+    *clear_child_tid = 0;
+    while (!list_empty(&futex->waiters)) {
+        struct futex_waiter * waiter = list_entry(futex->waiters.next,
+                                                  struct futex_waiter,
+                                                  list);
+
+        list_del(&waiter->list);
+        thread_wakeup(waiter->thread);
+    }
+
+    unlock(hdl->lock);
+    put_handle(hdl);
 }
 }

+ 1 - 1
LibOS/shim/src/sys/shim_mmap.c

@@ -94,7 +94,7 @@ void * shim_do_mmap (void * addr, size_t length, int prot, int flags, int fd,
     }
     }
 
 
     ret = bkeep_mmap((void *) mapped, mapped_end - mapped, prot,
     ret = bkeep_mmap((void *) mapped, mapped_end - mapped, prot,
-                     flags, hdl, offset, "user");
+                     flags, hdl, offset, NULL);
     assert(!ret);
     assert(!ret);
     if (hdl)
     if (hdl)
         put_handle(hdl);
         put_handle(hdl);

+ 4 - 7
LibOS/shim/src/sys/shim_sigaction.c

@@ -165,8 +165,7 @@ static int __kill_proc (struct shim_thread * thread, void * arg,
     if (!warg->use_ipc && !thread->in_vm)
     if (!warg->use_ipc && !thread->in_vm)
         return 0;
         return 0;
 
 
-    /* only signal thread leader */
-    if (thread->tgid != warg->id || thread->tid != thread->tgid)
+    if (thread->tgid != warg->id)
         return 0;
         return 0;
 
 
     if (warg->current == thread)
     if (warg->current == thread)
@@ -185,7 +184,6 @@ static int __kill_proc (struct shim_thread * thread, void * arg,
         return (!ipc_pid_kill_send(warg->sender, warg->id, KILL_PROCESS,
         return (!ipc_pid_kill_send(warg->sender, warg->id, KILL_PROCESS,
                                    warg->sig)) ? 1 : 0;
                                    warg->sig)) ? 1 : 0;
     } else {
     } else {
-
         lock(thread->lock);
         lock(thread->lock);
 
 
         if (!thread->is_alive)
         if (!thread->is_alive)
@@ -216,7 +214,7 @@ static int __kill_proc_simple (struct shim_simple_thread * sthread,
     struct walk_arg * warg = (struct walk_arg *) arg;
     struct walk_arg * warg = (struct walk_arg *) arg;
     int srched = 0;
     int srched = 0;
 
 
-    if (sthread->tgid != warg->id || sthread->tgid != sthread->tid)
+    if (sthread->tgid != warg->id)
         return 0;
         return 0;
 
 
     lock(sthread->lock);
     lock(sthread->lock);
@@ -276,8 +274,7 @@ static int __kill_pgroup (struct shim_thread * thread, void * arg,
     if (!warg->use_ipc && !thread->in_vm)
     if (!warg->use_ipc && !thread->in_vm)
         return 0;
         return 0;
 
 
-    /* only signal thread leader */
-    if (thread->pgid != warg->id || thread->tgid != thread->tid)
+    if (thread->pgid != warg->id)
         return 0;
         return 0;
 
 
     if (warg->current == thread)
     if (warg->current == thread)
@@ -312,7 +309,7 @@ static int __kill_pgroup_simple (struct shim_simple_thread * sthread,
     struct walk_arg * warg = (struct walk_arg *) arg;
     struct walk_arg * warg = (struct walk_arg *) arg;
     int srched = 0;
     int srched = 0;
 
 
-    if (sthread->pgid != warg->id || sthread->tgid != sthread->tid)
+    if (sthread->pgid != warg->id)
         return 0;
         return 0;
 
 
     lock(sthread->lock);
     lock(sthread->lock);

+ 19 - 22
LibOS/shim/src/syscallas.S

@@ -22,8 +22,8 @@
 
 
 #include <shim_tls.h>
 #include <shim_tls.h>
 
 
-        .text
-        .globl syscalldb
+.text
+        .global syscalldb
         .type syscalldb, @function
         .type syscalldb, @function
         .extern shim_table
         .extern shim_table
 
 
@@ -42,18 +42,10 @@ syscalldb:
         .cfi_def_cfa_register 6
         .cfi_def_cfa_register 6
 
 
         pushq %rbx
         pushq %rbx
-        pushq %r12
 
 
-        movq %rax, %fs:(SHIM_TCB_OFFSET + 24)
-        movq %rsp, %rbx
-        addq $152, %rbx
-        movq %rbx, %fs:(SHIM_TCB_OFFSET + 32)
-        movq (%rbx), %rbx
-        movq %rbx, %fs:(SHIM_TCB_OFFSET + 40)
-
-        movq shim_table@GOTPCREL(%rip), %rbx
-        movq (%rbx,%rax,8), %r12
-        cmp $0, (%r12)
+        leaq shim_table(%rip), %rbx
+        movq (%rbx,%rax,8), %rbx
+        cmp $0, (%rbx)
         je isundef
         je isundef
 
 
 isdef:
 isdef:
@@ -63,16 +55,29 @@ isdef:
         pushq %rcx
         pushq %rcx
         pushq %r8
         pushq %r8
         pushq %r9
         pushq %r9
+        pushq %r12
         pushq %r13
         pushq %r13
         pushq %r14
         pushq %r14
         pushq %r15
         pushq %r15
+
+        movq %rax, %fs:(SHIM_TCB_OFFSET + 24)
+        leaq 224(%rsp), %rax
+        movq %rax, %fs:(SHIM_TCB_OFFSET + 32)
+        movq (%rax), %rax
+        movq %rax, %fs:(SHIM_TCB_OFFSET + 40)
         movq %rsp, %fs:(SHIM_TCB_OFFSET + 48)
         movq %rsp, %fs:(SHIM_TCB_OFFSET + 48)
 
 
-        call *(%rbx,%rax,8)
+        call *%rbx
+
+        movq $0, %fs:(SHIM_TCB_OFFSET + 24)
+        movq $0, %fs:(SHIM_TCB_OFFSET + 32)
+        movq $0, %fs:(SHIM_TCB_OFFSET + 40)
+        movq $0, %fs:(SHIM_TCB_OFFSET + 48)
 
 
         popq %r15
         popq %r15
         popq %r14
         popq %r14
         popq %r13
         popq %r13
+        popq %r12
         popq %r9
         popq %r9
         popq %r8
         popq %r8
         popq %rcx
         popq %rcx
@@ -86,17 +91,9 @@ isundef:
         movq $-38, %rax
         movq $-38, %rax
 
 
 ret:
 ret:
-        popq %r12
         popq %rbx
         popq %rbx
         popq %rbp
         popq %rbp
-
-        movq $0, %fs:(SHIM_TCB_OFFSET + 24)
-        movq $0, %fs:(SHIM_TCB_OFFSET + 32)
-        movq $0, %fs:(SHIM_TCB_OFFSET + 40)
-        movq $0, %fs:(SHIM_TCB_OFFSET + 48)
-
         addq $128, %rsp
         addq $128, %rsp
-
         retq
         retq
 
 
         .cfi_endproc
         .cfi_endproc

+ 4 - 5
LibOS/shim/test/Makefile

@@ -26,12 +26,11 @@ manifest: manifest.template
 	rm -rf $@
 	rm -rf $@
 	cp $@.template $@
 	cp $@.template $@
 
 
-.PHONY: pal palsec
-
 pal:
 pal:
-	ln -sf $(level)../../../Pal/src/libpal.so
-palsec:
-	ln -sf $(level)../../../Pal/src/libpal_sec.so libpal.so
+	[ ! -f $(level)../../../Pal/src/pal ] || ln -sf $(level)../../../Pal/src/pal pal
+
+pal_sec:
+	[ ! -f $(level)../../../Pal/src/pal_sec ] || ln -sf $(level)../../../Pal/src/pal_sec pal_sec
 
 
 # Regression Test
 # Regression Test
 rtest:	$(rtarget)
 rtest:	$(rtarget)

+ 3 - 5
LibOS/shim/test/apps/Makefile

@@ -1,26 +1,24 @@
 apps = lmbench gcc busybox lighttpd bash apache make
 apps = lmbench gcc busybox lighttpd bash apache make
 
 
-targets = pal
+targets = pal pal_sec
 clean-extra = clean-all
 clean-extra = clean-all
 
 
 level = ../
 level = ../
 include ../Makefile
 include ../Makefile
 
 
 manifest_rules = \
 manifest_rules = \
+	-e 's:\$$(PAL):$(shell pwd)/pal_loader:g' \
 	-e 's:\$$(PWD):$(shell pwd)/$(appdir):g' \
 	-e 's:\$$(PWD):$(shell pwd)/$(appdir):g' \
 	-e 's:\$$(BIN):$(subst .manifest,,$(notdir $@)):g' \
 	-e 's:\$$(BIN):$(subst .manifest,,$(notdir $@)):g' \
 	-e 's:\$$(SHIMPATH):$(shell readlink -f ../../src/libsysdb.so):g' \
 	-e 's:\$$(SHIMPATH):$(shell readlink -f ../../src/libsysdb.so):g' \
 	-e 's:\$$(GLIBCDIR):$(shell readlink -f $(glibc_dir)):g' \
 	-e 's:\$$(GLIBCDIR):$(shell readlink -f $(glibc_dir)):g' \
 	$(extra_rules)
 	$(extra_rules)
 
 
-%.manifest: %.manifest.template libpal.so
+%.manifest: %.manifest.template
 	rm -f $@ $@.backup
 	rm -f $@ $@.backup
 	sed $(manifest_rules) $< >$@
 	sed $(manifest_rules) $< >$@
 	chmod +x $@
 	chmod +x $@
 
 
-libpal.so:
-	make pal
-
 build-all:
 build-all:
 	for f in $(apps); do (cd $$f; make $(DEBUG) || true; cd ..); done
 	for f in $(apps); do (cd $$f; make $(DEBUG) || true; cd ..); done
 
 

+ 1 - 1
LibOS/shim/test/apps/apache/httpd.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:obj/bin/httpd
 loader.exec = file:obj/bin/httpd

+ 1 - 1
LibOS/shim/test/apps/bash/bash-local.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:bash-local
 loader.exec = file:bash-local

+ 1 - 1
LibOS/shim/test/apps/bash/bash.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/bin/bash
 loader.exec = file:/bin/bash

+ 1 - 1
LibOS/shim/test/apps/busybox/busybox.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:busybox
 loader.exec = file:busybox

+ 1 - 1
LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:busybox_nofork
 loader.exec = file:busybox_nofork

+ 1 - 1
LibOS/shim/test/apps/gcc/g++-huge.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/g++
 loader.exec = file:/usr/bin/g++

+ 1 - 1
LibOS/shim/test/apps/gcc/g++-local.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.interp = file:$(SHIM)build/elf/ld.so
 loader.interp = file:$(SHIM)build/elf/ld.so
 loader.preload = file:$(SHIM)build/libsysdb.so
 loader.preload = file:$(SHIM)build/libsysdb.so

+ 1 - 1
LibOS/shim/test/apps/gcc/g++.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/g++
 loader.exec = file:/usr/bin/g++

+ 1 - 1
LibOS/shim/test/apps/gcc/gcc-huge.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/gcc
 loader.exec = file:/usr/bin/gcc

+ 1 - 1
LibOS/shim/test/apps/gcc/gcc-local.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.interp = file:$(SHIMROOT)build/elf/ld.so
 loader.interp = file:$(SHIMROOT)build/elf/ld.so
 loader.preload = file:$(SHIMROOT)build/libsysdb.so
 loader.preload = file:$(SHIMROOT)build/libsysdb.so

+ 1 - 1
LibOS/shim/test/apps/gcc/gcc.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/gcc
 loader.exec = file:/usr/bin/gcc

+ 1 - 1
LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:$(PWD)build/sbin/lighttpd-angel
 loader.exec = file:$(PWD)build/sbin/lighttpd-angel

+ 1 - 1
LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:$(PWD)build/sbin/lighttpd
 loader.exec = file:$(PWD)build/sbin/lighttpd

+ 15 - 9
LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c

@@ -12,23 +12,23 @@ char	*id = "$Id$\n";
 #define	FNAME "/usr/include/x86_64-linux-gnu/sys/types.h"
 #define	FNAME "/usr/include/x86_64-linux-gnu/sys/types.h"
 
 
 void
 void
-do_write(int fd)
+do_write(int fd, char *s)
 {
 {
 	char	c;
 	char	c;
 
 
 	if (write(fd, &c, 1) != 1) {
 	if (write(fd, &c, 1) != 1) {
-		perror("/dev/null");
+		perror(s);
 		return;
 		return;
 	}
 	}
 }
 }
 
 
 void
 void
-do_read(int fd)
+do_read(int fd, char *s)
 {
 {
 	char	c;
 	char	c;
 
 
 	if (read(fd, &c, 1) != 1) {
 	if (read(fd, &c, 1) != 1) {
-		perror("/dev/zero");
+		perror(s);
 		return;
 		return;
 	}
 	}
 }
 }
@@ -81,17 +81,23 @@ main(int ac, char **av)
 		BENCH(getppid(), 0);
 		BENCH(getppid(), 0);
 		micro("Simple syscall", get_n());
 		micro("Simple syscall", get_n());
 	} else if (!strcmp("write", av[1])) {
 	} else if (!strcmp("write", av[1])) {
-		fd = open("/dev/null", 1);
-		BENCH(do_write(fd), 0);;
+		file = av[2] ? av[2] : "/dev/null";
+		fd = open(file, 1);
+		if (fd == -1) {
+			fprintf(stderr, "Write from %s: %s\n", file, strerror(errno));
+			return(1);
+		}
+		BENCH(do_write(fd, file), 0);;
 		micro("Simple write", get_n());
 		micro("Simple write", get_n());
 		close(fd);
 		close(fd);
 	} else if (!strcmp("read", av[1])) {
 	} else if (!strcmp("read", av[1])) {
-		fd = open("/dev/zero", 0);
+		file = av[2] ? av[2] : "/dev/null";
+		fd = open(file, 0);
 		if (fd == -1) {
 		if (fd == -1) {
-			fprintf(stderr, "Read from /dev/zero: -1");
+			fprintf(stderr, "Read from %s: %s\n", file, strerror(errno));
 			return(1);
 			return(1);
 		}
 		}
-		BENCH(do_read(fd), 0);
+		BENCH(do_read(fd, file), 0);
 		micro("Simple read", get_n());
 		micro("Simple read", get_n());
 		close(fd);
 		close(fd);
 	} else if (!strcmp("stat", av[1])) {
 	} else if (!strcmp("stat", av[1])) {

+ 1 - 1
LibOS/shim/test/apps/lmbench/manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:$(PWD)lmbench-2.5/bin/linux/$(BIN)
 loader.exec = file:$(PWD)lmbench-2.5/bin/linux/$(BIN)

+ 1 - 1
LibOS/shim/test/apps/make/make-huge.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/make
 loader.exec = file:/usr/bin/make

+ 1 - 1
LibOS/shim/test/apps/make/make-local.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:make-local
 loader.exec = file:make-local

+ 1 - 1
LibOS/shim/test/apps/make/make.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/make
 loader.exec = file:/usr/bin/make

+ 1 - 1
LibOS/shim/test/apps/python/python.manifest.template

@@ -1,4 +1,4 @@
-#!$(PWD)../libpal.so
+#!$(PAL)
 
 
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/usr/bin/python
 loader.exec = file:/usr/bin/python

+ 2 - 2
LibOS/shim/test/inline/Makefile

@@ -2,7 +2,7 @@ INLINE_TESTS_CPP = $(patsubst %.cpp,%,$(wildcard *.cpp))
 INLINE_TESTS = $(patsubst %.c,%,$(wildcard *.c))
 INLINE_TESTS = $(patsubst %.c,%,$(wildcard *.c))
 
 
 rtarget = helloworld fork vfork
 rtarget = helloworld fork vfork
-targets = $(rtarget) manifest pal
+targets = $(rtarget) manifest pal pal_sec
 clean-extra = clean-exec
 clean-extra = clean-exec
 
 
 level = ../
 level = ../
@@ -23,4 +23,4 @@ test-vfork = grep -q "Hello, Dad" OUTPUT && grep -q "Hello, Kid" OUTPUT
 
 
 clean-exec:
 clean-exec:
 	find -type f -executable -exec rm {} \;
 	find -type f -executable -exec rm {} \;
-	rm -rf manifest libpal.so
+	rm -rf manifest pal pal_sec

+ 2 - 2
LibOS/shim/test/native/Makefile

@@ -5,7 +5,7 @@ NATIVE_TESTS_STATIC = static
 NATIVE_TESTS = $(filter-out $(NATIVE_TESTS_STATIC),$(patsubst %.c,%,$(wildcard *.c)))
 NATIVE_TESTS = $(filter-out $(NATIVE_TESTS_STATIC),$(patsubst %.c,%,$(wildcard *.c)))
 
 
 targets = $(NATIVE_TESTS) $(NATIVE_TESTS_CPP) $(NATIVE_TESTS_STATIC) \
 targets = $(NATIVE_TESTS) $(NATIVE_TESTS_CPP) $(NATIVE_TESTS_STATIC) \
-	  manifest static.manifest pal
+	  manifest static.manifest pal pal_sec
 rtarget = helloworld clone vfork fork exec vfork_exec errno dup time \
 rtarget = helloworld clone vfork fork exec vfork_exec errno dup time \
 	  helloworld.pthread udp tcp unix file dev
 	  helloworld.pthread udp tcp unix file dev
 clean-extra = clean-exec
 clean-extra = clean-exec
@@ -47,4 +47,4 @@ test-helloworld = grep -q "Hello world" OUTPUT
 
 
 clean-exec:
 clean-exec:
 	find -type f -executable -exec rm {} \;
 	find -type f -executable -exec rm {} \;
-	rm -rf manifest static.manifest libpal.so
+	rm -rf manifest static.manifest pal pal_sec

+ 4 - 0
LibOS/shim/test/native/manifest.template

@@ -10,6 +10,10 @@ fs.mount.other.lib.type = chroot
 fs.mount.other.lib.path = /lib
 fs.mount.other.lib.path = /lib
 fs.mount.other.lib.uri = file:../../../build
 fs.mount.other.lib.uri = file:../../../build
 
 
+fs.mount.other.bin.type = chroot
+fs.mount.other.bin.path = /bin
+fs.mount.other.bin.uri = file:/bin
+
 # allow to bind on port 8000
 # allow to bind on port 8000
 net.rules.1 = 127.0.0.1:8000:0.0.0.0:0-65535
 net.rules.1 = 127.0.0.1:8000:0.0.0.0:0-65535
 # allow to connect to port 8000
 # allow to connect to port 8000

+ 0 - 1
LibOS/shim/test/native/start.c

@@ -28,6 +28,5 @@ int main (int argc, char ** argv, char ** envp)
     unsigned long long overhead = (msec4 - msec3) / OVERHEAD_TIMES;
     unsigned long long overhead = (msec4 - msec3) / OVERHEAD_TIMES;
 
 
     printf("%llu\n", msec2 - msec1 - overhead);
     printf("%llu\n", msec2 - msec1 - overhead);
-
     return 0;
     return 0;
 }
 }

+ 12 - 0
LibOS/shim/test/native/system.c

@@ -0,0 +1,12 @@
+/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
+/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
+
+/* a simple helloworld test */
+
+#include <stdlib.h>
+
+int main(int argc, char ** argv)
+{
+    system("./helloworld");
+    return 0;
+}

+ 1 - 1
Pal/ipc/linux/graphene-ipc.c

@@ -895,7 +895,7 @@ out:
 		mutex_unlock(&pending->receiver_lock);
 		mutex_unlock(&pending->receiver_lock);
 		up_write(&current_tsk->mm->mmap_sem);
 		up_write(&current_tsk->mm->mmap_sem);
 
 
-		rv = copy_to_user(((struct gipc_recv *)arg)->addr, addrs,
+		rv = copy_to_user(gr.addr, addrs,
 				  sizeof(unsigned long) * gr.entries);
 				  sizeof(unsigned long) * gr.entries);
 		if (rv) {
 		if (rv) {
 			printk(KERN_ERR "Graphene error: bad buffer %p\n",
 			printk(KERN_ERR "Graphene error: bad buffer %p\n",

+ 26 - 11
Pal/src/Makefile

@@ -9,18 +9,21 @@ LD	= ld
 CFLAGS	= -Wall -fPIC -O2 -std=gnu99 -fgnu89-inline -U_FORTIFY_SOURCE \
 CFLAGS	= -Wall -fPIC -O2 -std=gnu99 -fgnu89-inline -U_FORTIFY_SOURCE \
 	  -fno-omit-frame-pointer \
 	  -fno-omit-frame-pointer \
 	  -fno-stack-protector -fno-builtin
 	  -fno-stack-protector -fno-builtin
-LDFLAGS	= -shared -nostdlib --version-script pal.map -z combreloc -z defs \
-	  -T pal.lds
+LDFLAGS	= -shared -nostdlib -z combreloc -z defs
 ARFLAGS	=
 ARFLAGS	=
 
 
 pal_loader = libpal.so
 pal_loader = libpal.so
-pal_lib = libpal.a
+pal_sec =
+pal_lib = libpal.so
+pal_lib_deps =
+pal_lib_post =
+pal_static = libpal.a
 
 
 include host/$(OS)/Makefile.am
 include host/$(OS)/Makefile.am
 
 
 CFLAGS	+= -I. -I../include -Ihost/$(OS) -I../lib
 CFLAGS	+= -I. -I../include -Ihost/$(OS) -I../lib
 
 
-pal_target = $(pal_loader) $(pal_lib)
+pal_target = $(pal_lib) $(pal_lib_post) $(pal_static) $(pal_loader) $(pal_sec) pal pal_sec
 defs	= -DIN_PAL -DSRCDIR="$(PWD)/"
 defs	= -DIN_PAL -DSRCDIR="$(PWD)/"
 objs	= $(addprefix db_,streams memory threading semaphore events process \
 objs	= $(addprefix db_,streams memory threading semaphore events process \
 	    object main misc ipc exception rtld) slab printf
 	    object main misc ipc exception rtld) slab printf
@@ -28,14 +31,14 @@ graphene_lib = ../lib/graphene-lib.a
 host_lib = host/$(OS)/libpal-$(OS).a
 host_lib = host/$(OS)/libpal-$(OS).a
 headers	= $(wildcard *.h) $(wildcard ../lib/*.h)
 headers	= $(wildcard *.h) $(wildcard ../lib/*.h)
 
 
-all: $(pal_target) security
+all: $(pal_target)
 
 
 debug: debug = debug
 debug: debug = debug
 debug: CC = gcc -gdwarf-2 -g3
 debug: CC = gcc -gdwarf-2 -g3
 debug: CFLAGS += -DDEBUG
 debug: CFLAGS += -DDEBUG
-debug: $(pal_target) security
+debug: $(pal_target)
 
 
-.PHONY: security $(host_lib) $(graphene_lib)
+.PHONY: $(host_lib) $(graphene_lib)
 
 
 $(graphene_lib):
 $(graphene_lib):
 	make -C ../lib $(debug)
 	make -C ../lib $(debug)
@@ -43,15 +46,27 @@ $(graphene_lib):
 $(host_lib):
 $(host_lib):
 	@[ ! -d host/$(OS) ] || make -C host/$(OS) $(debug)
 	@[ ! -d host/$(OS) ] || make -C host/$(OS) $(debug)
 
 
-security:
+ifneq ($(pal_sec),)
+$(pal_sec):
 	@[ ! -d security/$(OS) ] || make -C security/$(OS) $(debug)
 	@[ ! -d security/$(OS) ] || make -C security/$(OS) $(debug)
 
 
-$(pal_loader): $(addsuffix .o,$(objs)) $(filter %.map %.lds,$(LDFLAGS)) \
-	    $(host_lib) $(graphene_lib)
+pal_sec: $(pal_sec)
+	ln -sf $(pal_sec) pal_sec
+endif
+
+$(pal_lib): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib) $(pal_lib_deps)
 	@echo [ libpal.exe ]
 	@echo [ libpal.exe ]
 	$(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) $(LDFLAGS-suffix)
 	$(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) $(LDFLAGS-suffix)
 
 
-$(pal_lib): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib)
+pal: $(pal_loader)
+	ln -sf $(pal_loader) pal
+
+ifneq ($(pal_lib_post),)
+$(pal_lib_post): $(pal_lib)
+	make -C host/$(OS) ../../$@
+endif
+
+$(pal_static): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib)
 	@echo [ $@ ]
 	@echo [ $@ ]
 	$(AR) $(ARFLAGS) $@ $^ $(ARFLAGS-suffix)
 	$(AR) $(ARFLAGS) $@ $^ $(ARFLAGS-suffix)
 
 

+ 78 - 65
Pal/src/db_rtld.c

@@ -52,39 +52,6 @@ void __attribute__((noinline)) __assert (void)
 }
 }
 #endif
 #endif
 
 
-/* This structure communicates dl state to the debugger.  The debugger
-   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 pal_r_debug =
-        { 1, NULL, (ElfW(Addr)) &pal_dl_debug_state, RT_CONSISTENT, 0 };
-
-extern __typeof(pal_r_debug) _r_debug
-    __attribute ((alias ("pal_r_debug")));
-
-    /* This function exists solely to have a breakpoint set on it by the
-   debugger.  The debugger is supposed to find this function's address by
-   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.  */
-
-/* The special symbol name is set as breakpoint in gdb */
-void __attribute__((noinline)) pal_dl_debug_state (void)
-{
-}
-
-extern __typeof(pal_dl_debug_state) _dl_debug_state
-    __attribute ((alias ("pal_dl_debug_state")));
-
-void __attribute__((noinline)) _dl_debug_state_trigger (void)
-{
-    struct link_map *l = pal_r_debug.r_map;
-    for ( ; l ; l = l->l_next)
-        if (!memcmp(l->l_name, "file:", 5))
-            l->l_name += 5;
-
-    pal_dl_debug_state();
-}
-
 /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 static ElfW(Addr) resolve_map (const char **strtab, ElfW(Sym) ** ref)
 static ElfW(Addr) resolve_map (const char **strtab, ElfW(Sym) ** ref)
 {
 {
@@ -251,7 +218,7 @@ call_lose:
     /* Scan the program header table, collecting its load commands.  */
     /* Scan the program header table, collecting its load commands.  */
     struct loadcmd {
     struct loadcmd {
         ElfW(Addr) mapstart, mapend, dataend, allocend;
         ElfW(Addr) mapstart, mapend, dataend, allocend;
-        off_t mapoff;
+        unsigned int mapoff;
         int prot;
         int prot;
     } loadcmds[l->l_phnum], *c;
     } loadcmds[l->l_phnum], *c;
 
 
@@ -309,18 +276,13 @@ call_lose:
                     has_holes = true;
                     has_holes = true;
 
 
                 /* Optimize a common case.  */
                 /* Optimize a common case.  */
-#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
-                c->prot = (PF_TO_PROT
-                          >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
-#else
                 c->prot = 0;
                 c->prot = 0;
                 if (ph->p_flags & PF_R)
                 if (ph->p_flags & PF_R)
-                    c->prot |= PROT_READ;
+                    c->prot |= PAL_PROT_READ;
                 if (ph->p_flags & PF_W)
                 if (ph->p_flags & PF_W)
-                    c->prot |= PROT_WRITE;
+                    c->prot |= PAL_PROT_WRITE;
                 if (ph->p_flags & PF_X)
                 if (ph->p_flags & PF_X)
-                    c->prot |= PROT_EXEC;
-#endif
+                    c->prot |= PAL_PROT_EXEC;
                 break;
                 break;
 
 
             case PT_TLS:
             case PT_TLS:
@@ -390,7 +352,7 @@ map_error:
                unallocated.  Then jump into the normal segment-mapping loop to
                unallocated.  Then jump into the normal segment-mapping loop to
                handle the portion of the segment past the end of the file
                handle the portion of the segment past the end of the file
                mapping.  */
                mapping.  */
-            _DkVirtualMemoryProtect((caddr_t) (l->l_addr + c->mapend),
+            _DkVirtualMemoryProtect((void *) (l->l_addr + c->mapend),
                                     loadcmds[nloadcmds - 1].mapstart - c->mapend,
                                     loadcmds[nloadcmds - 1].mapstart - c->mapend,
                                     PAL_PROT_NONE);
                                     PAL_PROT_NONE);
 
 
@@ -414,12 +376,12 @@ map_error:
         }
         }
 
 
 postmap:
 postmap:
-        if (c->prot & PROT_EXEC) {
+        if (c->prot & PAL_PROT_EXEC) {
             l->l_text_start = l->l_addr + c->mapstart;
             l->l_text_start = l->l_addr + c->mapstart;
             l->l_text_end = l->l_addr + c->mapend;
             l->l_text_end = l->l_addr + c->mapend;
         }
         }
 
 
-        if (c->prot & PROT_WRITE) {
+        if (c->prot & PAL_PROT_WRITE) {
             l->l_data_start = l->l_addr + c->mapstart;
             l->l_data_start = l->l_addr + c->mapstart;
             l->l_data_end = l->l_addr + c->mapend;
             l->l_data_end = l->l_addr + c->mapend;
         }
         }
@@ -447,7 +409,7 @@ postmap:
 
 
             if (zerosec > zero) {
             if (zerosec > zero) {
                 /* Zero the final part of the last section of the segment.  */
                 /* Zero the final part of the last section of the segment.  */
-                if (__builtin_expect ((c->prot & PROT_WRITE) == 0, 0))
+                if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0))
                 {
                 {
                     /* Dag nab it.  */
                     /* Dag nab it.  */
                     if (_DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
                     if (_DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
@@ -458,7 +420,7 @@ postmap:
                     }
                     }
                 }
                 }
                 memset ((void *) zero, '\0', zerosec - zero);
                 memset ((void *) zero, '\0', zerosec - zero);
-                if (__builtin_expect ((c->prot & PROT_WRITE) == 0, 0))
+                if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0))
                     _DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
                     _DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
                                             allocsize, c->prot);
                                             allocsize, c->prot);
             }
             }
@@ -563,16 +525,12 @@ void free_elf_object (struct link_map * map)
     _DkVirtualMemoryFree((void *) map->l_map_start,
     _DkVirtualMemoryFree((void *) map->l_map_start,
                          map->l_map_end - map->l_map_start);
                          map->l_map_end - map->l_map_start);
 
 
-    pal_sec_info._r_debug->r_state = RT_DELETE;
-    pal_sec_info._dl_debug_state();
-
     if (map->l_prev)
     if (map->l_prev)
         map->l_prev->l_next = map->l_next;
         map->l_prev->l_next = map->l_next;
     if (map->l_next)
     if (map->l_next)
         map->l_next->l_prev = map->l_prev;
         map->l_next->l_prev = map->l_prev;
 
 
-    pal_sec_info._r_debug->r_state = RT_CONSISTENT;
-    pal_sec_info._dl_debug_state();
+    _DkDebugDelMap(map);
 
 
     if (loaded_libraries == map)
     if (loaded_libraries == map)
         loaded_libraries = map->l_next;
         loaded_libraries = map->l_next;
@@ -675,9 +633,6 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type)
         }
         }
     }
     }
 
 
-    pal_sec_info._r_debug->r_state = RT_ADD;
-    pal_sec_info._dl_debug_state();
-
     struct link_map * map;
     struct link_map * map;
 
 
     if (!(map = map_elf_object_by_handle(handle, type, &fb, len, true))) {
     if (!(map = map_elf_object_by_handle(handle, type, &fb, len, true))) {
@@ -706,8 +661,7 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type)
     map->l_prev = prev;
     map->l_prev = prev;
     map->l_next = NULL;
     map->l_next = NULL;
 
 
-    pal_sec_info._r_debug->r_state = RT_CONSISTENT;
-    pal_sec_info._dl_debug_state();
+    _DkDebugAddMap(map);
 
 
     return 0;
     return 0;
 
 
@@ -969,18 +923,13 @@ static int relocate_elf_object (struct link_map * l)
             if (ret < 0)
             if (ret < 0)
                 return ret;
                 return ret;
 
 
-#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
-            r->prot = (PF_TO_PROT
-                      >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
-#else
             r->prot = 0;
             r->prot = 0;
             if (ph->p_flags & PF_R)
             if (ph->p_flags & PF_R)
-                r->prot |= PROT_READ;
+                r->prot |= PAL_PROT_READ;
             if (ph->p_flags & PF_W)
             if (ph->p_flags & PF_W)
-                r->prot |= PROT_WRITE;
+                r->prot |= PAL_PROT_WRITE;
             if (ph->p_flags & PF_X)
             if (ph->p_flags & PF_X)
-                r->prot |= PROT_EXEC;
-#endif
+                r->prot |= PAL_PROT_EXEC;
             r->next = textrels;
             r->next = textrels;
             textrels = r;
             textrels = r;
         }
         }
@@ -1026,6 +975,70 @@ static int relocate_elf_object (struct link_map * l)
     return 0;
     return 0;
 }
 }
 
 
+void DkDebugAttachBinary (PAL_STR uri, PAL_PTR start_addr)
+{
+    if (memcmp(uri, "file:", 5))
+        return;
+
+    struct link_map * l = new_elf_object(uri + 5, OBJECT_EXTERNAL);
+
+    /* This is the ELF header.  We read it in `open_verify'.  */
+    const ElfW(Ehdr) * header = start_addr;
+
+    l->l_entry = header->e_entry;
+    l->l_phnum = header->e_phnum;
+    l->l_addr = l->l_map_start = (ElfW(Addr)) start_addr;
+
+    ElfW(Phdr) * phdr = (void *) (start_addr + header->e_phoff);
+    const ElfW(Phdr) * ph;
+
+    for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
+        switch (ph->p_type)
+        {
+            /* These entries tell us where to find things once the file's
+               segments are mapped in.  We record the addresses it says
+               verbatim, and later correct for the run-time load address.  */
+            case PT_DYNAMIC:
+                l->l_ld = l->l_real_ld = (void *) ph->p_vaddr;
+                l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+                break;
+
+            case PT_PHDR:
+                l->l_phdr = (void *) ph->p_vaddr;
+                break;
+
+            case PT_LOAD: {
+                ElfW(Addr) start = l->l_addr + ALLOC_ALIGNDOWN(ph->p_vaddr);
+                ElfW(Addr) end = l->l_addr + ALLOC_ALIGNDOWN(ph->p_vaddr +
+                                                             ph->p_memsz);
+
+                if (ph->p_flags & PF_X) {
+                    l->l_text_start = start;
+                    l->l_text_end = end;
+                }
+
+                if (ph->p_flags & PF_W) {
+                    l->l_data_start = start;
+                    l->l_data_end = end;
+                }
+
+                l->l_map_end = end;
+                break;
+            }
+
+            case PT_GNU_RELRO:
+                l->l_relro_addr = ph->p_vaddr;
+                l->l_relro_size = ph->p_memsz;
+                break;
+        }
+
+    _DkDebugAddMap(l);
+}
+
+void DkDebugDetachBinary (PAL_PTR start_addr)
+{
+}
+
 void start_execution (int argc, const char ** argv)
 void start_execution (int argc, const char ** argv)
 {
 {
     /* First we will try to run all the preloaded libraries which come with
     /* First we will try to run all the preloaded libraries which come with

+ 4 - 4
Pal/src/dynamic_link.h

@@ -39,23 +39,23 @@
    copying memory, breaking the very code written to handle the
    copying memory, breaking the very code written to handle the
    unaligned cases.  */
    unaligned cases.  */
 #if ! ELF_MACHINE_NO_REL
 #if ! ELF_MACHINE_NO_REL
-static void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
 elf_machine_rel (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr,
 elf_machine_rel (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr,
                  ElfW(Rel) *reloc, ElfW(Sym) *sym, void *const reloc_addr,
                  ElfW(Rel) *reloc, ElfW(Sym) *sym, void *const reloc_addr,
                  bool rel, bool rel_relative);
                  bool rel, bool rel_relative);
 
 
-static void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
                           void *const reloc_addr);
                           void *const reloc_addr);
 #endif
 #endif
 
 
 #if ! ELF_MACHINE_NO_RELA
 #if ! ELF_MACHINE_NO_RELA
-static void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
 elf_machine_rela (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr,
 elf_machine_rela (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr,
                   ElfW(Rela) *reloc, ElfW(Sym) *sym, void *const reloc_addr,
                   ElfW(Rela) *reloc, ElfW(Sym) *sym, void *const reloc_addr,
                   bool rel, bool rel_relative);
                   bool rel, bool rel_relative);
 
 
-static void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
                            void *const reloc_addr);
                            void *const reloc_addr);
 #endif
 #endif

+ 2 - 1
Pal/src/host/Linux/Makefile

@@ -16,7 +16,8 @@ ARFLAGS	=
 
 
 host_target = libpal-Linux.a
 host_target = libpal-Linux.a
 
 
-defs	= -DIN_PAL -DGDB_SCRIPT="$(CURDIR)/pal-gdb.py"
+defs	= -DIN_PAL -DPAL_LOADER_PATH="$(shell readlink -f ../../pal)" \
+	  -DGDB_SCRIPT="$(CURDIR)/pal-gdb.py"
 objs	= $(addprefix db_,files devices pipes sockets streams memory threading \
 objs	= $(addprefix db_,files devices pipes sockets streams memory threading \
 	    semaphore mutex events process object main rtld misc ipc \
 	    semaphore mutex events process object main rtld misc ipc \
 	    exception) manifest clone-x86_64 gettimeofday-x86_64
 	    exception) manifest clone-x86_64 gettimeofday-x86_64

+ 7 - 0
Pal/src/host/Linux/Makefile.am

@@ -1 +1,8 @@
 # Add host-specific compilation rules here
 # Add host-specific compilation rules here
+HOST_DIR = host/$(OS)
+SEC_DIR = security/$(OS)
+
+pal_sec = $(SEC_DIR)/libpal_sec.so
+pal_lib_deps = $(HOST_DIR)/pal.map $(HOST_DIR)/pal.lds
+
+LDFLAGS += --version-script $(HOST_DIR)/pal.map -T $(HOST_DIR)/pal.lds

+ 8 - 32
Pal/src/host/Linux/db_main.c

@@ -70,7 +70,6 @@ static gid_t gid;
 static ElfW(Addr) sysinfo_ehdr;
 static ElfW(Addr) sysinfo_ehdr;
 #endif
 #endif
 
 
-static const char * libname;
 static const char * child_args;
 static const char * child_args;
 
 
 static void pal_init_bootstrap (void * args, int * pargc,
 static void pal_init_bootstrap (void * args, int * pargc,
@@ -124,9 +123,7 @@ static void pal_init_bootstrap (void * args, int * pargc,
 #endif
 #endif
         }
         }
 
 
-    if (memcmp(*argv + strlen(*argv) - LIBRARY_NAMELEN, LIBRARY_NAME,
-               LIBRARY_NAMELEN) == 0) {
-        libname = *argv;
+    if (!memcmp(*argv + strlen(*argv) - 3, "pal", 3)) {
         argv++;
         argv++;
         argc--;
         argc--;
 
 
@@ -198,8 +195,6 @@ int read_shebang (const char ** argv)
 
 
     if (IS_ERR(fd)) {
     if (IS_ERR(fd)) {
 bad_shebang:
 bad_shebang:
-        printf("The program is either not libpal.so or script with "
-               "shebang. I can't recognize.\n");
         INLINE_SYSCALL(close, 1, fd);
         INLINE_SYSCALL(close, 1, fd);
         return -PAL_ERROR_INVAL;
         return -PAL_ERROR_INVAL;
     }
     }
@@ -215,14 +210,8 @@ bad_shebang:
         goto bad_shebang;
         goto bad_shebang;
 
 
     char * p = &buffer[2];
     char * p = &buffer[2];
-    while (*p && *p != ' ' && *p != '\r' && *p != '\n');
-    p++;
-
-    if (!libname) {
-        char * name = malloc(p - buffer - 1);
-        memcpy(name, &buffer[2], p - buffer - 2);
-        libname = name;
-    }
+    while (*p && *p != ' ' && *p != '\r' && *p != '\n')
+        p++;
 
 
     int len = strlen(*argv);
     int len = strlen(*argv);
     PAL_HANDLE manifest = malloc(HANDLE_SIZE(file) + len + 1);
     PAL_HANDLE manifest = malloc(HANDLE_SIZE(file) + len + 1);
@@ -265,7 +254,7 @@ void pal_linux_main (void * args)
 
 
     init_slab_mgr();
     init_slab_mgr();
 
 
-    setup_pal_map(XSTRINGIFY(SRCDIR) "/" LIBRARY_NAME, pal_dyn, pal_addr);
+    setup_pal_map(XSTRINGIFY(SRCDIR) "/pal", pal_dyn, pal_addr);
 
 
     /* jump to main function */
     /* jump to main function */
     pal_main(argc, argv, envp);
     pal_main(argc, argv, envp);
@@ -345,9 +334,6 @@ int _DkInitHost (int * pargc, const char *** pargv)
         return -PAL_ERROR_INVAL;
         return -PAL_ERROR_INVAL;
     }
     }
 
 
-    if (pal_sec_info.pal_name)
-        libname = pal_sec_info.pal_name;
-
     pal_linux_config.pid = INLINE_SYSCALL(getpid, 0);
     pal_linux_config.pid = INLINE_SYSCALL(getpid, 0);
 
 
     signal_setup();
     signal_setup();
@@ -359,12 +345,8 @@ int _DkInitHost (int * pargc, const char *** pargv)
         goto read_manifest;
         goto read_manifest;
     }
     }
 
 
-    if (!libname) {
-        if ((ret = read_shebang(argv)) < 0)
-            return ret;
-
+    if (!(ret = read_shebang(argv)) < 0)
         goto read_manifest;
         goto read_manifest;
-    }
 
 
     PAL_HANDLE file = NULL;
     PAL_HANDLE file = NULL;
     const char * file_uri = NULL;
     const char * file_uri = NULL;
@@ -468,12 +450,6 @@ read_manifest:
     }
     }
 
 
 done_init:
 done_init:
-    if (!child_args && pal_config.exec)
-        printf("Program \"%s\" loaded in Graphene Library OS\n",
-               pal_config.exec);
-
-    pal_config.lib_name = libname;
-
     if (!child_args && !pal_sec_info.domain_id) {
     if (!child_args && !pal_sec_info.domain_id) {
         if ((ret = create_domain_dir()) < 0)
         if ((ret = create_domain_dir()) < 0)
             return ret;
             return ret;
@@ -490,9 +466,9 @@ done_init:
 #endif
 #endif
 
 
     if (!pal_sec_info.mcast_port) {
     if (!pal_sec_info.mcast_port) {
-        do {
-            getrand(&pal_sec_info.mcast_port, sizeof(unsigned short));
-        } while (pal_sec_info.mcast_port < 1024);
+        unsigned short mcast_port;
+        getrand(&mcast_port, sizeof(unsigned short));
+        pal_sec_info.mcast_port = mcast_port % 1024;
     }
     }
 
 
     __pal_control.broadcast_stream = pal_sec_info.mcast_handle ? :
     __pal_control.broadcast_stream = pal_sec_info.mcast_handle ? :

+ 2 - 2
Pal/src/host/Linux/db_misc.c

@@ -55,10 +55,10 @@ unsigned long _DkSystemTimeQuery (void)
 
 
 #if USE_VDSO_GETTIME == 1
 #if USE_VDSO_GETTIME == 1
     if (__vdso_clock_gettime) {
     if (__vdso_clock_gettime) {
-        ret = __vdso_clock_gettime(CLOCK_MONOTONIC, &time);
+        ret = __vdso_clock_gettime(CLOCK_REALTIME, &time);
     } else {
     } else {
 #endif
 #endif
-        ret = INLINE_SYSCALL(clock_gettime, 2, CLOCK_MONOTONIC, &time);
+        ret = INLINE_SYSCALL(clock_gettime, 2, CLOCK_REALTIME, &time);
 #if USE_VDSO_GETTIME == 1
 #if USE_VDSO_GETTIME == 1
     }
     }
 #endif
 #endif

+ 1 - 1
Pal/src/host/Linux/db_pipes.c

@@ -165,7 +165,7 @@ static int pipe_waitforclient (PAL_HANDLE handle, PAL_HANDLE * client)
     *client = clnt;
     *client = clnt;
 #else
 #else
     PAL_IDX connid;
     PAL_IDX connid;
-    getrand(&connid, sizeof(PAL_IDX));
+    system_getrand(&connid, sizeof(PAL_IDX));
     PAL_HANDLE clnt = malloc(HANDLE_SIZE(pipe));
     PAL_HANDLE clnt = malloc(HANDLE_SIZE(pipe));
     SET_HANDLE_TYPE(clnt, pipecli);
     SET_HANDLE_TYPE(clnt, pipecli);
     clnt->__in.flags |= RFD(0)|WFD(0)|WRITEABLE(0);
     clnt->__in.flags |= RFD(0)|WFD(0)|WRITEABLE(0);

+ 2 - 2
Pal/src/host/Linux/db_process.c

@@ -106,7 +106,7 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri,
     const char ** new_args = __alloca(sizeof(const char *) * (nargs + 3));
     const char ** new_args = __alloca(sizeof(const char *) * (nargs + 3));
     int bufsize = STRARG_SIZE;
     int bufsize = STRARG_SIZE;
     char * argbuf = __alloca(STRARG_SIZE);
     char * argbuf = __alloca(STRARG_SIZE);
-    new_args[0] = pal_config.lib_name;
+    new_args[0] = PAL_LOADER;
     new_args[1] = argbuf;
     new_args[1] = argbuf;
     if (args)
     if (args)
         memcpy(new_args + 2, args, sizeof(const char *) * nargs);
         memcpy(new_args + 2, args, sizeof(const char *) * nargs);
@@ -170,7 +170,7 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri,
         if (manifest_fd >= 0)
         if (manifest_fd >= 0)
             INLINE_SYSCALL(fcntl, 3, manifest_fd, F_SETFD, 0);
             INLINE_SYSCALL(fcntl, 3, manifest_fd, F_SETFD, 0);
 
 
-        rete = INLINE_SYSCALL(execve, 3, pal_config.lib_name, new_args,
+        rete = INLINE_SYSCALL(execve, 3,  PAL_LOADER, new_args,
                               pal_config.environments);
                               pal_config.environments);
 
 
         /* shouldn't get to here */
         /* shouldn't get to here */

+ 106 - 23
Pal/src/host/Linux/db_rtld.c

@@ -43,7 +43,111 @@
 
 
 #include "elf-x86_64.h"
 #include "elf-x86_64.h"
 
 
-struct link_map * rtld_map = NULL;
+/* This structure communicates dl state to the debugger.  The debugger
+   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 pal_r_debug =
+        { 1, NULL, (ElfW(Addr)) &pal_dl_debug_state, RT_CONSISTENT, 0 };
+
+extern __typeof(pal_r_debug) _r_debug
+    __attribute ((alias ("pal_r_debug")));
+
+/* This function exists solely to have a breakpoint set on it by the
+   debugger.  The debugger is supposed to find this function's address by
+   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.  */
+
+/* The special symbol name is set as breakpoint in gdb */
+void __attribute__((noinline)) pal_dl_debug_state (void)
+{
+    if (pal_sec_info._dl_debug_state)
+        pal_sec_info._dl_debug_state();
+}
+
+extern __typeof(pal_dl_debug_state) _dl_debug_state
+    __attribute ((alias ("pal_dl_debug_state")));
+
+void _DkDebugAddMap (struct link_map * map)
+{
+    struct r_debug * dbg = pal_sec_info._r_debug ? : &pal_r_debug;
+    int len = map->l_name ? strlen(map->l_name) + 1 : 0;
+
+    struct link_map ** prev = &dbg->r_map, * last = NULL,
+                    * tmp = *prev;
+    while (tmp) {
+        if (tmp->l_addr == map->l_addr &&
+            tmp->l_ld == map->l_ld &&
+            !memcmp(tmp->l_name, map->l_name, len))
+            return;
+
+        last = tmp;
+        tmp = *(prev = &last->l_next);
+    }
+
+    struct link_gdb_map * m = malloc(sizeof(struct link_gdb_map) + len);
+    if (!m)
+        return;
+
+    if (len) {
+        m->l_name = (char *) m + sizeof(struct link_gdb_map);
+        memcpy((void *) m->l_name, map->l_name, len);
+    } else {
+        m->l_name = NULL;
+    }
+
+    m->l_addr = map->l_addr;
+    m->l_ld   = map->l_real_ld;
+
+    dbg->r_state = RT_ADD;
+    pal_dl_debug_state();
+
+    *prev = (struct link_map *) m;
+    m->l_prev = last;
+    m->l_next = NULL;
+
+    dbg->r_state = RT_CONSISTENT;
+    pal_dl_debug_state();
+}
+
+void _DkDebugDelMap (struct link_map * map)
+{
+    struct r_debug * dbg = pal_sec_info._r_debug ? : &pal_r_debug;
+    int len = map->l_name ? strlen(map->l_name) + 1 : 0;
+
+    struct link_map ** prev = &dbg->r_map, * last = NULL,
+                    * tmp = *prev, * found = NULL;
+    while (tmp) {
+        if (tmp->l_addr == map->l_addr &&
+            tmp->l_ld == map->l_ld &&
+            !memcmp(tmp->l_name, map->l_name, len)) {
+            found = tmp;
+            break;
+        }
+
+        last = tmp;
+        tmp = *(prev = &last->l_next);
+    }
+
+    if (!found)
+        return;
+
+    dbg->r_state = RT_DELETE;
+    pal_dl_debug_state();
+
+    if (last)
+        last->l_next = tmp->l_next;
+    else
+        dbg->r_map = tmp->l_next;
+
+    if (tmp->l_next)
+        tmp->l_next->l_prev = last;
+
+    free(tmp);
+
+    dbg->r_state = RT_CONSISTENT;
+    pal_dl_debug_state();
+}
 
 
 extern void setup_elf_hash (struct link_map *map);
 extern void setup_elf_hash (struct link_map *map);
 
 
@@ -84,30 +188,9 @@ void setup_pal_map (const char * realname, ElfW(Dyn) ** dyn, ElfW(Addr) addr)
         l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &pal_r_debug;
         l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &pal_r_debug;
 
 
     l->l_prev = l->l_next = NULL;
     l->l_prev = l->l_next = NULL;
-    rtld_map = l;
     loaded_libraries = l;
     loaded_libraries = l;
 
 
-    if (!pal_sec_info._r_debug) {
-        pal_r_debug.r_version = 1;
-        pal_r_debug.r_brk = (ElfW(Addr)) &pal_dl_debug_state;
-        pal_r_debug.r_ldbase = addr;
-        pal_r_debug.r_map = loaded_libraries;
-        pal_sec_info._r_debug = &pal_r_debug;
-        pal_sec_info._dl_debug_state = &pal_dl_debug_state;
-    } else {
-        pal_sec_info._r_debug->r_state = RT_ADD;
-        pal_sec_info._dl_debug_state();
-
-        if (pal_sec_info._r_debug->r_map) {
-            l->l_prev = pal_sec_info._r_debug->r_map;
-            pal_sec_info._r_debug->r_map->l_next = l;
-        } else {
-            pal_sec_info._r_debug->r_map = loaded_libraries;
-        }
-
-        pal_sec_info._r_debug->r_state = RT_CONSISTENT;
-        pal_sec_info._dl_debug_state();
-    }
+    _DkDebugAddMap(l);
 }
 }
 
 
 #if USE_VDSO_GETTIME == 1
 #if USE_VDSO_GETTIME == 1

+ 0 - 0
Pal/src/pal.lds → Pal/src/host/Linux/pal.lds


+ 1 - 2
Pal/src/pal.map → Pal/src/host/Linux/pal.map

@@ -44,11 +44,10 @@ PAL {
         DkStreamAttributesSetbyHandle;
         DkStreamAttributesSetbyHandle;
 
 
         # Debugging ABIs
         # Debugging ABIs
-        pal_printf; pal_snprintf;
+        pal_printf; pal_snprintf; DkDebugAttachBinary; DkDebugDetachBinary;
 
 
         # Control block
         # Control block
         pal_control; pal_control_addr; pal_sec_info;
         pal_control; pal_control_addr; pal_sec_info;
 
 
-
     local: *;
     local: *;
 };
 };

+ 3 - 0
Pal/src/host/Linux/pal_linux.h

@@ -23,6 +23,9 @@
 #include "pal_defs.h"
 #include "pal_defs.h"
 #include "pal_linux_defs.h"
 #include "pal_linux_defs.h"
 #include "pal.h"
 #include "pal.h"
+#include "pal_internal.h"
+
+#define PAL_LOADER XSTRINGIFY(PAL_LOADER_PATH)
 
 
 #include <sys/syscall.h>
 #include <sys/syscall.h>
 
 

+ 3 - 0
Pal/src/pal_debug.h

@@ -59,6 +59,9 @@ int pal_snprintf (char *buf, size_t n, const char *fmt, ...);
 int pal_atoi (const char *nptr);
 int pal_atoi (const char *nptr);
 long int pal_atol (const char *nptr);
 long int pal_atol (const char *nptr);
 
 
+void DkDebugAttachBinary (PAL_STR uri, PAL_PTR start_addr);
+void DkDebugDetachBinary (PAL_PTR start_addr);
+
 #endif
 #endif
 
 
 #endif
 #endif

+ 1 - 5
Pal/src/pal_internal.h

@@ -35,9 +35,6 @@
 # error "pal_internal.h can only be included in PAL"
 # error "pal_internal.h can only be included in PAL"
 #endif
 #endif
 
 
-#define LIBRARY_NAME        "libpal.so"
-#define LIBRARY_NAMELEN     9
-
 /* handle_ops is the operators provided for each handler type. They are
 /* handle_ops is the operators provided for each handler type. They are
    mostly used by Stream-related PAL calls, but can also be used by
    mostly used by Stream-related PAL calls, but can also be used by
    some others in special ways. */
    some others in special ways. */
@@ -286,7 +283,6 @@ extern struct pal_config {
     PAL_HANDLE      manifest_handle;
     PAL_HANDLE      manifest_handle;
     PAL_HANDLE      exec_handle;
     PAL_HANDLE      exec_handle;
     struct config_store * root_config;
     struct config_store * root_config;
-    const char *    lib_name;
     const char **   environments;
     const char **   environments;
     unsigned long   pagesize;
     unsigned long   pagesize;
     unsigned long   alloc_align;
     unsigned long   alloc_align;
@@ -430,7 +426,7 @@ int unblock_signals (int * sigs, int nsig);
 void * find_address (void * addr);
 void * find_address (void * addr);
 
 
 /* function and definition for loading binaries */
 /* function and definition for loading binaries */
-enum object_type { OBJECT_RTLD, OBJECT_EXEC, OBJECT_PRELOAD };
+enum object_type { OBJECT_RTLD, OBJECT_EXEC, OBJECT_PRELOAD, OBJECT_EXTERNAL };
 
 
 int check_elf_object (PAL_HANDLE handle);
 int check_elf_object (PAL_HANDLE handle);
 int load_elf_object (const char * uri, enum object_type type);
 int load_elf_object (const char * uri, enum object_type type);

+ 15 - 0
Pal/src/pal_rtld.h

@@ -102,6 +102,16 @@ struct link_map {
     const Elf32_Word * l_gnu_chain_zero;
     const Elf32_Word * l_gnu_chain_zero;
 };
 };
 
 
+struct link_gdb_map {
+    /* These first few members are part of the protocol with the debugger.
+       This is the same format used in SVR4.  */
+
+    ElfW(Addr) l_addr;          /* Base address shared object is loaded at. */
+    const char * l_name;        /* Absolute file name object was found in.  */
+    ElfW(Dyn) * l_ld;           /* Dynamic section of the shared object.    */
+    struct link_map * l_next, * l_prev;     /* Chain of loaded objects.     */
+};
+
 extern struct link_map * loaded_libraries;
 extern struct link_map * loaded_libraries;
 extern struct link_map * rtld_map;
 extern struct link_map * rtld_map;
 extern struct link_map * exec_map;
 extern struct link_map * exec_map;
@@ -207,4 +217,9 @@ do_lookup_map (ElfW(Sym) * ref, const char * undef_name,
                const uint_fast32_t hash, unsigned long int elf_hash,
                const uint_fast32_t hash, unsigned long int elf_hash,
                const struct link_map * map);
                const struct link_map * map);
 
 
+/* for GDB debugging */
+void _DkDebugAddMap (struct link_map * map);
+void _DkDebugDelMap (struct link_map * map);
+
+
 #endif /* PAL_RTLD_H */
 #endif /* PAL_RTLD_H */

+ 0 - 1
Pal/src/security/Linux/Makefile

@@ -27,7 +27,6 @@ libpal_sec.so: $(addsuffix .o,$(objs)) $(graphene_lib)
 	@echo [ security/Linux/$@ ]
 	@echo [ security/Linux/$@ ]
 	@[ ! -f $@ ] || mv -f $@ $@.backup
 	@[ ! -f $@ ] || mv -f $@ $@.backup
 	@$(LD) $(LDFLAGS) -o $@ $^ -soname=libpal_sec.so
 	@$(LD) $(LDFLAGS) -o $@ $^ -soname=libpal_sec.so
-	@cd ../.. && ln -sf security/Linux/libpal_sec.so
 
 
 %.o: %.c
 %.o: %.c
 	@echo [ security/Linux/$@ ]
 	@echo [ security/Linux/$@ ]