Browse Source

beta version 0.2

Plenty of bugfixes for Linux kernel later than 3.5 and Ubuntu later than 10.10.
More organized code to improve portability.
Regression tests for Pal to test completeness of implementation.
Chia-Che Tsai 9 years ago
parent
commit
7f19f62f31
100 changed files with 1479 additions and 1865 deletions
  1. 17 1
      LibOS/Makefile
  2. 10 5
      LibOS/shim/Makefile
  3. 78 83
      LibOS/shim/include/shim_checkpoint.h
  4. 5 4
      LibOS/shim/include/shim_defs.h
  5. 0 2
      LibOS/shim/include/shim_utils.h
  6. 28 2
      LibOS/shim/include/shim_vma.h
  7. BIN
      LibOS/shim/src/.packed/shim.tar.gz
  8. 17 5
      LibOS/shim/src/Makefile
  9. 10 8
      LibOS/shim/src/bookkeep/shim_handle.c
  10. 17 14
      LibOS/shim/src/bookkeep/shim_thread.c
  11. 91 72
      LibOS/shim/src/bookkeep/shim_vma.c
  12. 42 40
      LibOS/shim/src/elf/dl-machine-x86_64.h
  13. 25 5
      LibOS/shim/src/elf/do-rel.h
  14. 19 8
      LibOS/shim/src/elf/rel.h
  15. 57 37
      LibOS/shim/src/elf/shim_rtld.c
  16. 7 9
      LibOS/shim/src/fs/chroot/fs.c
  17. 1 1
      LibOS/shim/src/fs/pipe/fs.c
  18. 62 78
      LibOS/shim/src/fs/proc/info.c
  19. 11 15
      LibOS/shim/src/fs/shim_fs.c
  20. 3 3
      LibOS/shim/src/fs/socket/fs.c
  21. 0 1
      LibOS/shim/src/fs/str/fs.c
  22. 42 36
      LibOS/shim/src/ipc/shim_ipc.c
  23. 38 19
      LibOS/shim/src/ipc/shim_ipc_helper.c
  24. 5 1
      LibOS/shim/src/ipc/shim_ipc_nsimpl.h
  25. 122 90
      LibOS/shim/src/shim_checkpoint.c
  26. 3 3
      LibOS/shim/src/shim_debug.c
  27. 44 27
      LibOS/shim/src/shim_init.c
  28. 5 4
      LibOS/shim/src/shim_malloc.c
  29. 2 2
      LibOS/shim/src/shim_parser.c
  30. 2 1
      LibOS/shim/src/shim_syscalls.c
  31. 5 6
      LibOS/shim/src/sys/shim_brk.c
  32. 5 8
      LibOS/shim/src/sys/shim_exec.c
  33. 7 8
      LibOS/shim/src/sys/shim_exit.c
  34. 5 4
      LibOS/shim/src/sys/shim_fork.c
  35. 1 1
      LibOS/shim/src/sys/shim_ioctl.c
  36. 1 1
      LibOS/shim/src/sys/shim_migrate.c
  37. 2 6
      LibOS/shim/src/sys/shim_mmap.c
  38. 5 4
      LibOS/shim/src/sys/shim_msgget.c
  39. 3 3
      LibOS/shim/src/sys/shim_pipe.c
  40. 1 1
      LibOS/shim/src/sys/shim_sandbox.c
  41. 47 52
      LibOS/shim/src/sys/shim_socket.c
  42. 1 1
      LibOS/shim/src/sys/shim_vfork.c
  43. 2 2
      LibOS/shim/src/syscallas.S
  44. 0 49
      LibOS/shim/src/utils/printf.c
  45. 16 21
      LibOS/shim/test/Makefile
  46. 12 2
      LibOS/shim/test/apps/Makefile
  47. 16 13
      LibOS/shim/test/apps/apache/Makefile
  48. 12 10
      LibOS/shim/test/apps/gcc/Makefile
  49. BIN
      LibOS/shim/test/apps/lmbench/.packed/lmbench.tar.gz
  50. 20 2
      LibOS/shim/test/apps/lmbench/Makefile
  51. 8 53
      LibOS/shim/test/apps/lmbench/lmbench-2.5/scripts/lmbench
  52. 33 0
      LibOS/shim/test/benchmark/Makefile
  53. 0 0
      LibOS/shim/test/benchmark/fork_latency.c
  54. 22 0
      LibOS/shim/test/benchmark/manifest.template
  55. 0 0
      LibOS/shim/test/benchmark/rpc_latency.libos.c
  56. 0 0
      LibOS/shim/test/benchmark/rpc_latency2.libos.c
  57. 0 0
      LibOS/shim/test/benchmark/sig_latency.c
  58. 0 0
      LibOS/shim/test/benchmark/start.c
  59. 0 0
      LibOS/shim/test/benchmark/test_start.m.c
  60. BIN
      LibOS/shim/test/inline/.packed/test.tar.gz
  61. 17 17
      LibOS/shim/test/inline/Makefile
  62. BIN
      LibOS/shim/test/native/.packed/test.tar.gz
  63. 14 25
      LibOS/shim/test/native/Makefile
  64. 0 2
      LibOS/shim/test/native/brk.c
  65. 13 2
      LibOS/shim/test/native/clone.c
  66. 21 28
      LibOS/shim/test/native/condvar.pthread.c
  67. 24 0
      LibOS/shim/test/native/cpuinfo.c
  68. 0 1
      LibOS/shim/test/native/dir.c
  69. 166 200
      LibOS/shim/test/native/epoll_socket.c
  70. 0 1
      LibOS/shim/test/native/errno.c
  71. 7 7
      LibOS/shim/test/native/exec.c
  72. 0 4
      LibOS/shim/test/native/exec_fork.c
  73. 3 1
      LibOS/shim/test/native/exec_victim.c
  74. 0 7
      LibOS/shim/test/native/file.c
  75. 2 2
      LibOS/shim/test/native/fork_bomb.c
  76. 5 16
      LibOS/shim/test/native/fork_exec.c
  77. 16 19
      LibOS/shim/test/native/futextest.pthread.c
  78. 0 123
      LibOS/shim/test/native/greeting.pthread.c
  79. 24 0
      LibOS/shim/test/native/meminfo.c
  80. 0 1
      LibOS/shim/test/native/multiproc.c
  81. 4 3
      LibOS/shim/test/native/vfork_exec.c
  82. 25 0
      LibOS/shim/test/regression/00_bootstrap.py
  83. 56 0
      LibOS/shim/test/regression/Makefile
  84. 16 0
      LibOS/shim/test/regression/bootstrap.c
  85. 17 0
      LibOS/shim/test/regression/bootstrap_pie.c
  86. 12 0
      LibOS/shim/test/regression/bootstrap_static.c
  87. 22 0
      LibOS/shim/test/regression/manifest.template
  88. 10 2
      Makefile
  89. 9 2
      Pal/Makefile
  90. 0 39
      Pal/include/asm-errno-base.h
  91. 0 111
      Pal/include/asm-errno.h
  92. 0 1
      Pal/include/atomic.h
  93. 0 50
      Pal/include/bits/errno.h
  94. 0 7
      Pal/include/elf/elf.h
  95. 0 7
      Pal/include/sysdeps/generic/ldsodefs.h
  96. 9 9
      Pal/include/sysdeps/generic/memcopy.h
  97. 0 3
      Pal/ipc/linux/demo/.gitignore
  98. 0 6
      Pal/ipc/linux/demo/Makefile
  99. 0 139
      Pal/ipc/linux/demo/client.c
  100. 0 207
      Pal/ipc/linux/demo/fork.c

+ 17 - 1
LibOS/Makefile

@@ -1,7 +1,10 @@
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
+
 GLIBC_SRC = glibc-2.17
 SHIM_DIR = shim
 BUILD_DIR = build
-GLIBC_TARGET = $(addprefix $(BUILD_DIR)/,libc.so.6 ld-linux-x86-64.so.2)
+GLIBC_TARGET = $(addprefix $(BUILD_DIR)/,libc.so.6 ld-linux-x86-64.so.2 libpthread.so.0 libm.so.6 libdl.so.2 libutil.so.1 crt1.o crti.o crtn.o liblibos.so.1)
 
 all: $(GLIBC_TARGET)
 	make -C $(SHIM_DIR) all
@@ -13,6 +16,7 @@ debug: $(GLIBC_TARGET)
 # nothing to install
 install:
 
+ifeq ($(SYS),x86_64-linux-gnu)
 $(GLIBC_TARGET): $(BUILD_DIR)/Makefile
 	cd $(BUILD_DIR) && make
 
@@ -25,6 +29,18 @@ $(GLIBC_SRC)/configure:
 	tar -xzf $(GLIBC_SRC).tar.gz
 	[ ! -f $(GLIBC_SRC).patch ] || git apply $(GLIBC_SRC).patch
 
+.PHONY: pack
+pack: $(GLIBC_TARGET)
+	tar -chzf .packed/glibc.tar.gz $^
+	make -C $(SHIM_DIR) pack
+
 clean:
 	make -C $(SHIM_DIR) clean
 	rm -rf $(BUILD_DIR)
+else
+$(GLIBC_TARGET): .packed/glibc.tar.gz
+	tar -xmozf $<
+
+clean:
+	rm -rf $(BUILD_DIR)
+endif

+ 10 - 5
LibOS/shim/Makefile

@@ -1,11 +1,16 @@
 MAKEFLAGS += --check-symlink-times
 
-SRC_DIRS := src
-TESTS_DIRS := test
-DIRS := ${SRC_DIRS} ${TESTS_DIRS}
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
 
-all debug clean: ${DIRS}
-	for d in ${DIRS}; \
+targets = all debug clean
+ifeq ($(SYS),x86_64-linux-gnu)
+targets += pack
+endif
+
+.PHONY: $(targets)
+$(targets): src test
+	for d in src test; \
 	do \
 		make $@ -C $$d; \
 	done

+ 78 - 83
LibOS/shim/include/shim_checkpoint.h

@@ -129,7 +129,7 @@ struct shim_mem_entry {
     void * addr;
     int size;
     int prot;
-    bool need_alloc;
+    bool need_alloc, need_prot;
     struct shim_vma * vma;
     void * data;
 };
@@ -199,11 +199,8 @@ extern const resume_func  __resume_func;
         &migrate_func_##name - &__migrate_func;  })
 
 #define CP_FUNC(name)   CP_FUNC_BASE + CP_FUNC_INDEX(name)
-
 #define CP_FUNC_NAME(type)      (&__migrate_name)[(type) - CP_FUNC_BASE]
 
-#define DEBUG_CP_ENTRY      0
-
 #define ADD_ENTRY(type, value)                                      \
     do {                                                            \
         USED += sizeof(struct shim_cp_entry);                       \
@@ -212,26 +209,27 @@ extern const resume_func  __resume_func;
             tmp->cp_type = CP_##type;                               \
             tmp->cp_un.cp_val = (ptr_t) (value);                    \
                                                                     \
-            if (DEBUG_CP_ENTRY)                                     \
+            if (DEBUG_CHECKPOINT)                                   \
                 debug("ADD CP_" #type "(%p) :%d\n",                 \
                       tmp->cp_un.cp_val,                            \
                       tmp - (struct shim_cp_entry *) base);         \
         } else {                                                    \
-            if (DEBUG_CP_ENTRY)                                     \
+            if (DEBUG_CHECKPOINT)                                   \
                 debug("(dry) ADD CP_" #type "\n");                  \
         }                                                           \
     } while(0)
 
-#define ADD_OFFSET(size)                                        \
-    do {                                                        \
-        int _size = ((size) + 7) & ~7;                          \
-        USED += _size;                                          \
-        if (!dry)                                               \
-            *offset -= _size;                                   \
-        if (DEBUG_CP_ENTRY)                                     \
-            debug("%sADD OFFSET(%d)\n",                         \
-                  dry ? "(dry) " : "", _size);                  \
-    } while (0)
+#define ADD_OFFSET(size)                                            \
+    ({                                                              \
+        int _size = ((size) + 7) & ~7;                              \
+        USED += _size;                                              \
+        if (!dry)                                                   \
+            *offset -= _size;                                       \
+        if (DEBUG_CHECKPOINT)                                       \
+            debug("%sADD OFFSET(%d)\n",                             \
+                  dry ? "(dry) " : "", _size);                      \
+        dry ? 0 : *offset;                                          \
+    })
 
 #define ADD_FUNC_ENTRY(value)                                       \
     do {                                                            \
@@ -241,58 +239,58 @@ extern const resume_func  __resume_func;
             tmp->cp_type = CP_FUNC_TYPE;                            \
             tmp->cp_un.cp_val = (ptr_t) value;                      \
                                                                     \
-            if (DEBUG_CP_ENTRY)                                     \
+            if (DEBUG_CHECKPOINT)                                   \
                 debug("ADD CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,     \
                       tmp->cp_un.cp_val,                            \
                       tmp - (struct shim_cp_entry *) base);         \
         } else {                                                    \
-            if (DEBUG_CP_ENTRY)                                     \
+            if (DEBUG_CHECKPOINT)                                   \
                 debug("(dry) ADD CP_FUNC_%s\n", CP_FUNC_NAME);      \
         }                                                           \
     } while(0)
 
 
-#define GET_ENTRY(type)                                         \
-    ({  struct shim_cp_entry * tmp = (*ent)++;                  \
-                                                                \
-        while (tmp->cp_type != CP_##type)                       \
-            tmp = (*ent)++;                                     \
-                                                                \
-        /* debug("GET CP_" #type "(%p) :%d\n",                  \
-                 tmp->cp_un.cp_val,                             \
-                 tmp - (struct shim_cp_entry *) base); */       \
-                                                                \
-        tmp->cp_un.cp_val;                                      \
+#define GET_ENTRY(type)                                             \
+    ({  struct shim_cp_entry * tmp = (*ent)++;                      \
+                                                                    \
+        while (tmp->cp_type != CP_##type)                           \
+            tmp = (*ent)++;                                         \
+                                                                    \
+        /* debug("GET CP_" #type "(%p) :%d\n",                      \
+                 tmp->cp_un.cp_val,                                 \
+                 tmp - (struct shim_cp_entry *) base); */           \
+                                                                    \
+        tmp->cp_un.cp_val;                                          \
      })
 
-#define GET_FUNC_ENTRY()                                        \
-    ({  struct shim_cp_entry * tmp = (*ent)++;                  \
-                                                                \
-        while (tmp->cp_type != CP_FUNC_TYPE)                    \
-            tmp = (*ent)++;                                     \
-                                                                \
-        /* debug("GET CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,      \
-                 tmp->cp_un.cp_val,                             \
-                 tmp - (struct shim_cp_entry *) base); */       \
-                                                                \
-        tmp->cp_un.cp_val;                                      \
+#define GET_FUNC_ENTRY()                                            \
+    ({  struct shim_cp_entry * tmp = (*ent)++;                      \
+                                                                    \
+        while (tmp->cp_type != CP_FUNC_TYPE)                        \
+            tmp = (*ent)++;                                         \
+                                                                    \
+        /* debug("GET CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME,          \
+                 tmp->cp_un.cp_val,                                 \
+                 tmp - (struct shim_cp_entry *) base); */           \
+                                                                    \
+        tmp->cp_un.cp_val;                                          \
      })
 
 
-#define DEFINE_MIGRATE_FUNC(name)                                           \
-    const char * migrate_name_##name                                        \
-        __attribute__((section(".migrate_name." #name))) = #name;           \
-                                                                            \
-    extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);             \
-    const migrate_func migrate_func_##name                                  \
-        __attribute__((section(".migrate." #name))) = &migrate_##name;      \
-                                                                            \
-    extern RESUME_FUNC_RET resume_##name (RESUME_FUNC_ARGS);                \
-    const resume_func resume_func_##name                                    \
-        __attribute__((section(".resume." #name))) = &resume_##name;        \
-                                                                            \
-    DEFINE_PROFILE_INTERVAL(migrate_##name, migrate_func);                  \
-    DEFINE_PROFILE_INTERVAL(resume_##name,  resume_func);                   \
+#define DEFINE_MIGRATE_FUNC(name)                                   \
+    const char * migrate_name_##name                                \
+        __attribute__((section(".migrate_name." #name))) = #name;   \
+                                                                    \
+    extern MIGRATE_FUNC_RET migrate_##name (MIGRATE_FUNC_ARGS);     \
+    const migrate_func migrate_func_##name                          \
+        __attribute__((section(".migrate." #name))) = &migrate_##name;\
+                                                                    \
+    extern RESUME_FUNC_RET resume_##name (RESUME_FUNC_ARGS);        \
+    const resume_func resume_func_##name                            \
+        __attribute__((section(".resume." #name))) = &resume_##name;\
+                                                                    \
+    DEFINE_PROFILE_INTERVAL(migrate_##name, migrate_func);          \
+    DEFINE_PROFILE_INTERVAL(resume_##name,  resume_func);           \
 
 
 #define MIGRATE_FUNC_BODY(name)                                 \
@@ -307,7 +305,7 @@ extern const resume_func  __resume_func;
         ASSIGN_PROFILE_INTERVAL(migrate_##name);
 
 #define END_MIGRATE_FUNC                                        \
-        SAVE_PROFILE_INTERVAL_ASSIGNED();                       \
+        if (!dry) SAVE_PROFILE_INTERVAL_ASSIGNED();             \
         return USED;                                            \
     }
 
@@ -451,31 +449,30 @@ static inline __attribute__((always_inline))
 ptr_t add_to_migrate_map (void * map, void * obj, ptr_t off,
                           size_t size, bool dry)
 {
-    struct shim_addr_map * _e = get_addr_map_entry(map,
+    struct shim_addr_map * e = get_addr_map_entry(map,
                     (ptr_t) obj, size, 1);
 
-    ptr_t _off = _e->offset;
-    if (dry)
-    {
-        if (_off & MAP_UNALLOCATED)
-            _e->offset = MAP_UNASSIGNED;
+    ptr_t result = e->offset;
+    if (dry) {
+        if (result & MAP_UNALLOCATED)
+            e->offset = MAP_UNASSIGNED;
         else
-            _off = 0;
-    }
-    else
-        if (_off & MAP_UNUSABLE)
-        {
-            _e->offset = (off) - (size);
-            _e->size = (size);
+            result = 0;
+    } else {
+        if (result & MAP_UNUSABLE) {
+            assert(size);
+            assert(off >= size);
+            e->offset = off - size;
+            e->size = size;
         }
+    }
 
-    return _off;
+    return result;
 }
 
 #define ADD_TO_MIGRATE_MAP(obj, off, size) \
         add_to_migrate_map(store->addr_map, (obj), dry ? 0 : (off), (size), dry)
 
-
 #define MIGRATE_DEF_ARGS    \
         struct shim_cp_store * store, void * data, size_t size, bool dry
 
@@ -503,7 +500,8 @@ ptr_t add_to_migrate_map (void * map, void * obj, ptr_t off,
                   dry ? 0 : &offset, (obj), (size), NULL, recursive, dry);  \
     } while (0)
 
-//#define DEBUG_RESUME
+#define DEBUG_RESUME      0
+#define DEBUG_CHECKPOINT  0
 
 #ifndef malloc_method
 #define malloc_method(size) system_malloc(size)
@@ -573,23 +571,14 @@ struct newproc_header {
 #endif
 };
 
-#ifdef NEWPROC_RESP
 struct newproc_response {
+    IDTYPE child_vmid;
     int failure;
 };
 
-# define NEWPROC_RESP_CONFLICT    140
-#endif
-
-int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr);
-
-int restore_from_checkpoint (const char * filename,
-                             struct newproc_cp_header * hdr,
-                             void ** cpptr);
-int restore_from_file (const char * filename, struct newproc_cp_header * hdr,
-                       void ** cpptr);
+int do_migration (struct newproc_cp_header * hdr, void ** cpptr);
 
-int restore_from_stack (void * cpdata, struct cp_header * hdr, int type);
+int restore_checkpoint (void * cpdata, struct cp_header * hdr, int type);
 int restore_gipc (PAL_HANDLE gipc, struct gipc_header * hdr, void * cpdata,
                   long cprebase);
 int send_checkpoint_by_gipc (PAL_HANDLE gipc_store,
@@ -602,6 +591,12 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
                         struct shim_handle * exec, const char ** argv,
                         struct shim_thread * thread, ...);
 
+int init_from_checkpoint_file (const char * filename,
+                               struct newproc_cp_header * hdr,
+                               void ** cpptr);
+int restore_from_file (const char * filename, struct newproc_cp_header * hdr,
+                       void ** cpptr);
+
 void restore_context (struct shim_context * context);
 
 #define CHECKPOINT_REQUESTED        ((IDTYPE) -1)

+ 5 - 4
LibOS/shim/include/shim_defs.h

@@ -4,10 +4,11 @@
 #ifndef _SHIM_DEFS_H_
 #define _SHIM_DEFS_H_
 
-#define HASH_GIPC                   0
+#define HASH_GIPC                   (0)
 
-#define DEFAULT_MEM_MAX_NPAGES      1024 * 1024 /* 4GB */
-#define DEFAULT_BRK_MAX_SIZE        256 * 1024  /* 256KB */
-#define DEFAULT_SYS_STACK_SIZE      256 * 1024  /* 256KB */
+#define DEFAULT_HEAP_MIN_SIZE       (256 * 1024 * 1024) /* 256MB */
+#define DEFAULT_MEM_MAX_NPAGES      (1024 * 1024)       /* 4GB */
+#define DEFAULT_BRK_MAX_SIZE        (256 * 1024)        /* 256KB */
+#define DEFAULT_SYS_STACK_SIZE      (256 * 1024)        /* 256KB */
 
 #endif /* _SHIM_DEFS_H_ */

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

@@ -34,8 +34,6 @@ struct shim_handle;
 
 void sysparser_printf (const char * fmt, ...);
 
-int snprintf (char * buf, size_t n, const char * fmt, ...);
-
 /* string object */
 struct shim_str * get_str_obj (void);
 int free_str_obj (struct shim_str * str);

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

@@ -33,6 +33,8 @@
 #include <pal.h>
 #include <linux_list.h>
 
+#include <asm/mman.h>
+
 struct shim_handle;
 
 #define VMA_COMMENT_LEN     16
@@ -59,10 +61,34 @@ struct shim_vma {
                                      so it has to be checkpointed during
                                      migration */
 
-#define NEED_MIGRATE_MEMORY(vma) \
-        (((vma)->flags & VMA_TAINTED || !(vma)->file) && \
+#define NEED_MIGRATE_MEMORY(vma)                            \
+        (((vma)->flags & VMA_TAINTED || !(vma)->file) &&    \
         !((vma)->flags & VMA_UNMAPPED))
 
+#if 0
+#define NEED_MIGRATE_MEMORY_IF_GIPC(vma)                    \
+        (!((vma)->flags & VMA_UNMAPPED) &&                  \
+         !((vma)->file && ((vma)->flags & MAP_SHARED)))
+#endif
+#define NEED_MIGRATE_MEMORY_IF_GIPC(vma) NEED_MIGRATE_MEMORY((vma))
+
+static inline PAL_FLG PAL_PROT (int prot, int flags)
+{
+    PAL_FLG pal_prot = 0;
+
+    if (prot & PROT_READ)
+        pal_prot |= PAL_PROT_READ;
+    if (prot & PROT_WRITE)
+        pal_prot |= PAL_PROT_WRITE;
+    if (prot & PROT_EXEC)
+        pal_prot |= PAL_PROT_EXEC;
+
+    if (flags & MAP_PRIVATE)
+        pal_prot |= PAL_PROT_WRITECOPY;
+
+    return pal_prot;
+}
+
 int init_vma (void);
 
 /* Bookkeeping mmap() system call */

BIN
LibOS/shim/src/.packed/shim.tar.gz


+ 17 - 5
LibOS/shim/src/Makefile

@@ -1,4 +1,5 @@
-MAKEFLAGS += --check-symlink-times
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
 
 CC	= gcc
 AS	= gcc
@@ -52,13 +53,14 @@ debug: CC = gcc -gdwarf-2 -g3
 debug: CFLAGS += -DDEBUG
 debug: $(shim_target)
 
-profile: CC = gcc
-profile: CFLAGS += -DPROFILE
-profile: $(shim_target)
+ifeq ($(PROFILING), 1)
+CFLAGS += -DPROFILE
+endif
 
 $(graphene_lib):
 	make -C ../../../Pal/lib $(debug)
 
+ifeq ($(SYS),x86_64-linux-gnu)
 libsysdb.so: $(addsuffix .o,$(objs)) $(filter %.map %.lds,$(LDFLAGS)) \
 	     $(graphene_lib) $(pal_lib)
 	@echo [ $@ ]
@@ -76,13 +78,23 @@ libsysdb.a: $(addsuffix .o,$(objs))
 	@echo [ $@ ]
 	$(AR) $(ARFLAGS) $@ $^
 
+.PHONY: pack
+pack: $(shim_target)
+	tar -czf .packed/shim.tar.gz $^
+else
+$(shim_target): .packed/shim.tar.gz
+	tar -xmozf $<
+endif
+
 %.asm: %.c $(headers)
 	@echo [ $@ ]
 	@$(CC) $(CFLAGS) $(defs) -c $< -o $<.o
 	@objdump -S $<.o > $@
 	@rm $<.o
 
-$(addsuffix .o,$(addprefix ipc/shim_ipc_,$(ipcns))): ipc/*.h
+$(addsuffix .o,$(addprefix ipc/shim_ipc_,$(ipcns))): $(wildcard ipc/*.h)
+elf/shim_rtld.o: $(wildcard elf/*.h)
+
 
 %.o: %.c $(headers)
 	@echo [ $@ ]

+ 10 - 8
LibOS/shim/src/bookkeep/shim_handle.c

@@ -767,12 +767,10 @@ MIGRATE_FUNC_BODY(handle)
                                            sizeof(struct shim_handle));
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_handle));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct shim_handle));
+        off = ADD_OFFSET(sizeof(struct shim_handle));
 
         if (!dry) {
-            new_hdl = (struct shim_handle *) (base + *offset);
+            new_hdl = (struct shim_handle *) (base + off);
             memcpy(new_hdl, hdl, sizeof(struct shim_handle));
 
             if (fs && fs->fs_ops && fs->fs_ops->checkout)
@@ -785,17 +783,21 @@ MIGRATE_FUNC_BODY(handle)
             clear_lock(new_hdl->lock);
         }
 
+        DO_MIGRATE_IN_MEMBER(qstr, hdl, new_hdl, path, false);
+        DO_MIGRATE_IN_MEMBER(qstr, hdl, new_hdl, uri,  false);
+
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct shim_handle));
         ADD_ENTRY(PALHDL, new_hdl->pal_handle ?
                   *offset + offsetof(struct shim_handle, pal_handle) : 0);
-    } else if (!dry)
+
+    } else if (!dry) {
         new_hdl = (struct shim_handle *) (base + off);
+    }
 
     if (new_hdl && objp)
         *objp = (void *) new_hdl;
 
-    DO_MIGRATE_IN_MEMBER(qstr, hdl, new_hdl, path, false);
-    DO_MIGRATE_IN_MEMBER(qstr, hdl, new_hdl, uri,  false);
-
     if (new_hdl)
         assert(new_hdl->uri.len < 1024);
 

+ 17 - 14
LibOS/shim/src/bookkeep/shim_thread.c

@@ -591,7 +591,7 @@ void switch_dummy_thread (struct shim_thread * thread)
     real_thread->stack_top = thread->stack_top;
     real_thread->frameptr  = thread->frameptr;
 
-    DkThreadPrivate(real_thread->tcb);
+    DkSegmentRegister(PAL_SEGMENT_FS, real_thread->tcb);
     set_cur_thread(real_thread);
     debug("set tcb to %p\n", real_thread->tcb);
 
@@ -628,12 +628,10 @@ MIGRATE_FUNC_BODY(thread)
     unsigned long off = ADD_TO_MIGRATE_MAP(obj, *offset, size);
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_thread));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct shim_thread));
+        off = ADD_OFFSET(sizeof(struct shim_thread));
 
         if (!dry) {
-            new_thread = (struct shim_thread *) (base + *offset);
+            new_thread = (struct shim_thread *) (base + off);
             memcpy(new_thread, thread, sizeof(struct shim_thread));
 
             INIT_LIST_HEAD(&new_thread->children);
@@ -670,6 +668,13 @@ MIGRATE_FUNC_BODY(thread)
             }
         }
 
+        DO_MIGRATE_MEMBER(handle, thread, new_thread, exec, 0);
+        DO_MIGRATE_MEMBER_IF_RECURSIVE(handle_map, thread, new_thread,
+                                       handle_map, 1);
+
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct shim_thread));
+
         int rlen, clen;
         const char * rpath = dentry_get_path(thread->root, true, &rlen);
         const char * cpath = dentry_get_path(thread->cwd, true, &clen);
@@ -684,17 +689,13 @@ MIGRATE_FUNC_BODY(thread)
             memcpy(new_rpath, rpath, rlen + 1);
             memcpy(new_cpath, cpath, clen + 1);
         }
+
     } else if (!dry) {
         new_thread = (struct shim_thread *) (base + off);
     }
 
     if (new_thread && objp)
         *objp = (void *) new_thread;
-
-    DO_MIGRATE_MEMBER(handle, thread, new_thread, exec, 0);
-
-    DO_MIGRATE_MEMBER_IF_RECURSIVE(handle_map, thread, new_thread,
-                                   handle_map, 1);
 }
 END_MIGRATE_FUNC
 
@@ -733,13 +734,13 @@ RESUME_FUNC_BODY(thread)
     if (thread->handle_map)
         get_handle_map(thread->handle_map);
 
-//#ifdef DEBUG_RESUME
+#ifdef DEBUG_RESUME
     debug("thread: "
           "tid=%d,tgid=%d,parent=%d,stack=%p,frameptr=%p,tcb=%p\n",
           thread->tid, thread->tgid,
           thread->parent ? thread->parent->tid : thread->tid,
           thread->stack, thread->frameptr, thread->tcb);
-//#endif
+#endif
 }
 END_RESUME_FUNC
 
@@ -756,7 +757,7 @@ MIGRATE_FUNC_BODY(running_thread)
     DO_MIGRATE(thread, thread, thread_obj, recursive);
     ADD_FUNC_ENTRY(new_thread);
 
-    if (!thread->user_tcb) {
+    if (!thread->user_tcb && thread->tcb) {
         ADD_OFFSET(sizeof(__libc_tcb_t));
         if (!dry) {
             __libc_tcb_t * new_tcb = (void *) (base + *offset);
@@ -794,9 +795,11 @@ RESUME_FUNC_BODY(running_thread)
     RESUME_REBASE(thread);
     struct shim_thread * cur_thread = get_cur_thread();
     thread->in_vm = true;
-
     get_thread(thread);
 
+    if (!thread->user_tcb)
+        RESUME_REBASE(thread->tcb);
+
     if (cur_thread) {
         PAL_HANDLE handle = DkThreadCreate(resume_wrapper, thread, 0);
         if (!thread)

+ 91 - 72
LibOS/shim/src/bookkeep/shim_vma.c

@@ -38,6 +38,9 @@
 
 unsigned long mem_max_npages __attribute_migratable = DEFAULT_MEM_MAX_NPAGES;
 
+static void * heap_top    __attribute_migratable;
+static void * heap_bottom __attribute_migratable;
+
 #define VMA_MGR_ALLOC   64
 #define PAGE_SIZE       allocsize
 
@@ -91,12 +94,20 @@ static inline int test_vma_overlap (struct shim_vma * tmp,
 }
 
 int bkeep_shim_heap (void);
+static void __set_heap_top (void * bottom, void * top);
 
 int init_vma (void)
 {
     if (!(vma_mgr = create_mem_mgr(init_align_up(VMA_MGR_ALLOC))))
         return -ENOMEM;
 
+    heap_bottom = (void *) PAL_CB(user_address.start);
+    if (heap_bottom + DEFAULT_HEAP_MIN_SIZE > PAL_CB(executable_range.start) &&
+        heap_bottom < PAL_CB(executable_range.end))
+        heap_bottom = (void *) ALIGN_UP(PAL_CB(executable_range.end));
+
+    __set_heap_top(heap_bottom, (void *) PAL_CB(user_address.end));
+
     bkeep_shim_heap();
     create_lock(vma_list_lock);
 
@@ -108,13 +119,13 @@ int init_vma (void)
 static inline void assert_vma (void)
 {
     struct shim_vma * tmp;
-    struct shim_vma * prv __attribute__((unused)) = NULL;
+    struct shim_vma * prev __attribute__((unused)) = NULL;
 
     list_for_each_entry(tmp, &vma_list, list) {
         /* Assert we are really sorted */
         assert(tmp->length > 0);
-        assert(!prv || prv->addr + prv->length <= tmp->addr);
-        prv = tmp;
+        assert(!prev || prev->addr + prev->length <= tmp->addr);
+        prev = tmp;
     }
 }
 
@@ -594,43 +605,61 @@ int bkeep_mprotect (void * addr, size_t length, int prot, const int * flags)
     return ret;
 }
 
+static void __set_heap_top (void * bottom, void * top)
+{
+    bottom += DEFAULT_HEAP_MIN_SIZE;
+
+    if (bottom >= top) {
+        heap_top = top;
+        return;
+    }
+
+    unsigned long rand;
+    while (getrand(&rand, sizeof(unsigned long)) < sizeof(unsigned long));
+
+    rand %= (unsigned long) (top - bottom) / allocsize;
+    heap_top = bottom + rand * allocsize;
+    debug("heap top adjusted to %p\n", heap_top);
+}
+
 void * get_unmapped_vma (size_t length, int flags)
 {
-    struct shim_vma * new = get_new_vma();
+    struct shim_vma * new = get_new_vma(), * tmp = NULL;
     if (!new)
         return NULL;
 
-    struct shim_vma * tmp, * prev = NULL;
     lock(vma_list_lock);
 
-    new->addr = pal_control.user_address_begin;
-    new->length = length;
-    new->flags = flags|VMA_UNMAPPED;
+    do {
+        new->addr   = heap_top - length;
+        new->length = length;
+        new->flags  = flags|VMA_UNMAPPED;
 
-    list_for_each_entry(tmp, &vma_list, list) {
-        if (tmp->addr <= new->addr) {
-            if (tmp->addr + tmp->length > new->addr)
-                new->addr = tmp->addr + tmp->length;
-            prev = tmp;
-            continue;
-        }
+        list_for_each_entry_reverse(tmp, &vma_list, list) {
+            if (new->addr >= tmp->addr + tmp->length)
+                break;
 
-        if (tmp->addr >= new->addr + length)
-            break;
+            if (new->addr < heap_bottom)
+                break;
 
-        new->addr = tmp->addr + tmp->length;
-        prev = tmp;
-    }
+            if (new->addr > tmp->addr - length)
+                new->addr = tmp->addr - length;
+        }
 
-    if (new->addr + length > pal_control.user_address_end) {
-        unlock(vma_list_lock);
-        put_vma(new);
-        return NULL;
-    }
+        if (new->addr < heap_bottom) {
+            if (heap_top == PAL_CB(user_address.end)) {
+                unlock(vma_list_lock);
+                put_vma(new);
+                return NULL;
+            } else {
+                __set_heap_top(heap_top, (void *) PAL_CB(user_address.end));
+                new->addr = NULL;
+            }
+        }
+    } while (!new->addr);
 
-    assert(!prev || prev->addr + prev->length <= new->addr);
     get_vma(new);
-    list_add(&new->list, prev ? &prev->list : &vma_list);
+    list_add(&new->list, tmp ? &tmp->list : &vma_list);
     unlock(vma_list_lock);
     return new->addr;
 }
@@ -638,32 +667,27 @@ void * get_unmapped_vma (size_t length, int flags)
 /* This might not give the same vma but we might need to
    split after we find something */
 static struct shim_vma * __lookup_overlap_vma (const void * addr, size_t length,
-                                               struct shim_vma ** prev)
+                                               struct shim_vma ** pprev)
 {
-    struct shim_vma * tmp;
-    struct shim_vma * prv = NULL;
+    struct shim_vma * tmp, * prev = NULL;
 
     list_for_each_entry(tmp, &vma_list, list) {
         if (test_vma_overlap (tmp, addr, length)) {
-            if (prev)
-                *prev = prv;
-
+            if (pprev)
+                *pprev = prev;
             return tmp;
         }
 
         /* Assert we are really sorted */
-        assert(!prv || prv->addr < tmp->addr);
-
+        assert(!prev || prev->addr < tmp->addr);
         /* Insert in order; break once we are past the appropriate point  */
         if (tmp->addr > addr)
             break;
-
-        prv = tmp;
+        prev = tmp;
     }
 
-    if (prev)
-        *prev = prv;
-
+    if (pprev)
+        *pprev = prev;
     return NULL;
 }
 
@@ -671,7 +695,6 @@ int lookup_overlap_vma (const void * addr, size_t length,
                         struct shim_vma ** vma)
 {
     struct shim_vma * tmp = NULL;
-
     lock(vma_list_lock);
 
     if ((tmp = __lookup_overlap_vma(addr, length, NULL)) && vma)
@@ -681,55 +704,48 @@ int lookup_overlap_vma (const void * addr, size_t length,
 
     if (vma)
         *vma = tmp;
-
     return tmp ? 0: -ENOENT;
 }
 
 static struct shim_vma * __lookup_vma (const void * addr, size_t length)
 {
     struct shim_vma * tmp;
-    struct shim_vma * prv __attribute__((unused)) = NULL;
+    struct shim_vma * prev __attribute__((unused)) = NULL;
 
     list_for_each_entry(tmp, &vma_list, list) {
         if (test_vma_equal(tmp, addr, length))
             return tmp;
 
         /* Assert we are really sorted */
-        assert(!prv || prv->addr + prv->length <= tmp->addr);
-
-        prv = tmp;
+        assert(!prev || prev->addr + prev->length <= tmp->addr);
+        prev = tmp;
     }
 
     return NULL;
 }
 
 static struct shim_vma * __lookup_supervma (const void * addr, size_t length,
-                                            struct shim_vma ** prev)
+                                            struct shim_vma ** pprev)
 {
-    struct shim_vma * tmp;
-    struct shim_vma * prv = NULL;
+    struct shim_vma * tmp, * prev = NULL;
 
     list_for_each_entry(tmp, &vma_list, list) {
         if (test_vma_contain(tmp, addr, length)) {
-            if (prev)
-                *prev = prv;
-
+            if (pprev)
+                *pprev = prev;
             return tmp;
         }
 
         /* Assert we are really sorted */
-        assert(!prv || prv->addr + prv->length <= tmp->addr);
-
+        assert(!prev || prev->addr + prev->length <= tmp->addr);
         /* Insert in order; break once we are past the appropriate point  */
         if (tmp->addr > addr)
             break;
-
-        prv = tmp;
+        prev = tmp;
     }
 
-    if (prev)
-        *prev = prv;
-
+    if (pprev)
+        *pprev = prev;
     return NULL;
 }
 
@@ -911,8 +927,8 @@ MIGRATE_FUNC_BODY(vma)
 
     struct shim_vma * vma = (struct shim_vma *) obj;
     struct shim_vma * new_vma = NULL;
-
     struct shim_handle * file = NULL;
+    PAL_FLG pal_prot = PAL_PROT(vma->prot, 0);
 
     if (vma->file && recursive)
         __DO_MIGRATE(handle, vma->file, &file, 1);
@@ -920,12 +936,10 @@ MIGRATE_FUNC_BODY(vma)
     unsigned long off = ADD_TO_MIGRATE_MAP(obj, *offset, size);
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_vma));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct shim_vma));
+        off = ADD_OFFSET(sizeof(struct shim_vma));
 
         if (!dry) {
-            new_vma = (struct shim_vma *) (base + *offset);
+            new_vma = (struct shim_vma *) (base + off);
             memcpy(new_vma, vma, sizeof(struct shim_vma));
 
             new_vma->file = file;
@@ -950,10 +964,10 @@ MIGRATE_FUNC_BODY(vma)
                 bool protected = false;
                 if (store->use_gipc) {
 #if HASH_GIPC == 1
-                    if (!dry && !(vma->prot & PROT_READ)) {
+                    if (!dry && !(prot & PAL_PROT_READ)) {
                         protected = true;
-                        DkVirtualMemoryProtect(send_addr, send_size, vma->prot |
-                                               PAL_PROT_READ);
+                        DkVirtualMemoryProtect(send_addr, send_size,
+                                               pal_prot|PAL_PROT_READ);
                     }
 #endif /* HASH_GIPC == 1 */
                     struct shim_gipc_entry * gipc;
@@ -964,27 +978,32 @@ MIGRATE_FUNC_BODY(vma)
                     }
 #if HASH_GIPC == 1
                     if (protected)
-                        DkVirtualMemoryProtect(send_addr, send_size, vma->prot);
+                        DkVirtualMemoryProtect(send_addr, send_size, pal_prot);
 #endif /* HASH_GIPC == 1 */
                 } else {
                     if (!dry && !(vma->prot & PROT_READ)) {
                         protected = true;
-                        DkVirtualMemoryProtect(send_addr, send_size, vma->prot |
-                                               PAL_PROT_READ);
+                        DkVirtualMemoryProtect(send_addr, send_size,
+                                               pal_prot|PAL_PROT_READ);
                     }
 
                     struct shim_mem_entry * mem;
                     DO_MIGRATE_SIZE(memory, send_addr, send_size, &mem, false);
                     if (!dry) {
                         mem->prot = vma->prot;
-                        mem->vma = vma;
+                        mem->vma = new_vma;
+                        mem->need_alloc = true;
                     }
 
                     if (protected)
-                        DkVirtualMemoryProtect(send_addr, send_size, vma->prot);
+                        DkVirtualMemoryProtect(send_addr, send_size, pal_prot);
                 }
             }
         }
+
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct shim_vma));
+
     } else if (!dry)
         new_vma = (struct shim_vma *) (base + off);
 

+ 42 - 40
LibOS/shim/src/elf/dl-machine-x86_64.h

@@ -58,9 +58,9 @@ elf_machine_matches_host (const Elf64_Ehdr * ehdr)
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-//#define DEBUG_RELOC
+#define DEBUG_RELOC
 
-static void
+static bool
 elf_machine_rela (struct link_map * l, ElfW(Rela) * reloc, Elf64_Sym * sym,
                   void * const reloc_addr_arg)
 {
@@ -71,7 +71,7 @@ elf_machine_rela (struct link_map * l, ElfW(Rela) * reloc, Elf64_Sym * sym,
                             (const void *) D_PTR (l->l_info[DT_STRTAB]);
 
 #ifdef DEBUG_RELOC
-#define elf_machine_rela_debug(r_type, sym, value)                  \
+#define debug_reloc(r_type, sym, value)                             \
     ({  if (strtab && sym && sym->st_name)                          \
             debug(#r_type ": %s\n", strtab + sym->st_name);         \
         else if (value)                                             \
@@ -80,52 +80,54 @@ elf_machine_rela (struct link_map * l, ElfW(Rela) * reloc, Elf64_Sym * sym,
             debug(#r_type "\n", value);                             \
     })
 #else
-#define elf_machine_rela_debug(...) ({})
+#define debug_reloc(...) ({})
 #endif
 
+    if (r_type == R_X86_64_RELATIVE || r_type == R_X86_64_NONE)
+        return false;
+
     Elf64_Sym * refsym = sym;
+    Elf64_Addr value;
     Elf64_Addr sym_map = RESOLVE_MAP(&strtab, &sym);
-#define SYM (sym ? : refsym)
 
-    if (!sym_map)
-        sym_map = l->l_addr;
+    if (!sym_map || !sym || refsym == sym)
+        return false;
 
-    Elf64_Addr value = sym_map + (sym == NULL ? refsym->st_value : sym->st_value);
+    value = sym_map + sym->st_value;
 
     /* We do a very special relocation for loaded libraries */
-    if (sym && refsym && refsym != sym) {
-        PROTECT_PAGE(l, refsym, sizeof(*refsym));
-        PROTECT_PAGE(l, reloc_addr, sizeof(*reloc_addr));
-
-        refsym->st_info = sym->st_info;
-        refsym->st_size = sym->st_size;
-
-        if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info)
-                              == STT_GNU_IFUNC, 0)
-            && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
-        {
-            value = ((Elf64_Addr (*) (void)) value) ();
-
-            refsym->st_info ^= ELFW(ST_TYPE)(sym->st_info);
-            refsym->st_info |= STT_FUNC;
-        }
-
-        elf_machine_rela_debug ("shim symbol", SYM, value);
-
-        refsym->st_value = value - l->l_addr;
-        *reloc_addr = value +
-            ((r_type == R_X86_64_GLOB_DAT ||
-              r_type == R_X86_64_JUMP_SLOT ||
-              r_type == R_X86_64_64) ? reloc->r_addend : 0);
-
-        /* We have relocated the symbol, we don't want the
-           interpreter to relocate it again. */
-        if (r_type != R_X86_64_NONE) {
-            PROTECT_PAGE(l, reloc, sizeof(*reloc));
-            reloc->r_info = (reloc->r_info ^ ELF64_R_TYPE (reloc->r_info))|
-                            R_X86_64_NONE;
-        }
+    PROTECT_PAGE(l, refsym, sizeof(*refsym));
+    PROTECT_PAGE(l, reloc_addr, sizeof(*reloc_addr));
+
+    refsym->st_info = sym->st_info;
+    refsym->st_size = sym->st_size;
+
+    if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info)
+                          == STT_GNU_IFUNC, 0)
+        && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)) {
+        value = ((Elf64_Addr (*) (void)) value) ();
+
+        refsym->st_info ^= ELFW(ST_TYPE)(sym->st_info);
+        refsym->st_info |= STT_FUNC;
     }
+
+    debug_reloc("shim symbol", sym, value);
+
+    refsym->st_value = value - l->l_addr;
+    *reloc_addr = value +
+        ((r_type == R_X86_64_GLOB_DAT ||
+          r_type == R_X86_64_JUMP_SLOT ||
+          r_type == R_X86_64_64) ? reloc->r_addend : 0);
+
+    /* We have relocated the symbol, we don't want the
+       interpreter to relocate it again. */
+    if (r_type != R_X86_64_NONE) {
+        PROTECT_PAGE(l, reloc, sizeof(*reloc));
+        reloc->r_info = (reloc->r_info ^ ELF64_R_TYPE (reloc->r_info))|
+            R_X86_64_NONE;
+    }
+
+    return true;
 }
 
 #endif /* !dl_machine_h */

+ 25 - 5
LibOS/shim/src/elf/do-rel.h

@@ -32,6 +32,7 @@
 #define Rel                         Rela
 #define elf_machine_rel             elf_machine_rela
 #define elf_machine_rel_relative    elf_machine_rela_relative
+#define elf_dynamic_redo_rel        elf_dynamic_redo_rela
 
 #ifndef DO_ELF_MACHINE_REL_RELATIVE
 # define DO_ELF_MACHINE_REL_RELATIVE(l, relative)           \
@@ -64,15 +65,32 @@ elf_dynamic_do_rel (struct link_map * l, ElfW(Addr) reladdr, int relsize)
     ElfW(Rel) * end = (void *) (reladdr + relsize);
     ElfW(Word) nrelative = l->l_info[RELCOUNT_IDX] == NULL
                            ? 0 : l->l_info[RELCOUNT_IDX]->d_un.d_val;
-    /* ElfW(Rel) * relative = r; */
     int nrelsize = relsize / sizeof (ElfW(Rel));
+
     r = r + (nrelative < nrelsize ? nrelative : nrelsize);
+    for (; r < end; ++r) {
+        ElfW(Sym) * sym = &symtab[ELFW(R_SYM) (r->r_info)];
+        void * reloc = (void *) l->l_addr + r->r_offset;
+        if (elf_machine_rel(l, r, sym, reloc)) {
+            assert(l->nlinksyms < MAX_LINKSYMS);
+            l->linksyms[l->nlinksyms].rel = r;
+            l->linksyms[l->nlinksyms].sym = sym;
+            l->linksyms[l->nlinksyms].reloc = reloc;
+            l->nlinksyms++;
+        }
+    }
+}
 
-    for (; r < end; ++r)
-        elf_machine_rel(l, r, &symtab[ELFW(R_SYM) (r->r_info)],
-                        (void *) (l->l_addr + r->r_offset));
+static void __attribute__((unused))
+elf_dynamic_redo_rel (struct link_map * l)
+{
+    for (int i = 0 ; i < l->nlinksyms ; i++)
+        elf_machine_rel(l, l->linksyms[i].rel,
+                        l->linksyms[i].sym,
+                        l->linksyms[i].reloc);
 }
 
+#if 0
 static void inline elf_copy_rel (struct link_map * l1, struct link_map * l2,
                                  int reloc, int reloc_sz)
 {
@@ -116,6 +134,7 @@ elf_dynamic_copy_rel (struct link_map * l1, struct link_map * l2)
     elf_copy_rel(l1, l2, dt_reloc, dt_reloc_sz);
     elf_copy_rel(l1, l2, DT_JMPREL, DT_PLTRELSZ);
 }
+#endif
 
 #undef elf_dynamic_do_rel
 #undef Rel
@@ -123,6 +142,7 @@ elf_dynamic_copy_rel (struct link_map * l1, struct link_map * l2)
 #undef elf_machine_rel_relative
 #undef DO_ELF_MACHINE_REL_RELATIVE
 #undef RELCOUNT_IDX
-#undef elf_dynamic_copy_rel
+//#undef elf_dynamic_copy_rel
 #undef dt_reloc
 #undef dt_reloc_sz
+#undef elf_dynamic_redo_rel

+ 19 - 8
LibOS/shim/src/elf/rel.h

@@ -158,7 +158,7 @@ _elf_dynamic_do_reloc(struct link_map * l, int dt_reloc, int dt_reloc_sz,
 
 static void __attribute__((unused))
 _elf_dynamic_do_reloc(struct link_map * l, int dt_reloc, int dt_reloc_sz,
-                      void (*do_reloc) (struct link_map * l, ElfW(Addr), int))
+                      void (*do_reloc) (struct link_map *, ElfW(Addr), int))
 {
     struct { ElfW(Addr) start, size; } ranges[2];
     ranges[0].size = ranges[1].size = 0;
@@ -196,6 +196,7 @@ _elf_dynamic_do_reloc(struct link_map * l, int dt_reloc, int dt_reloc_sz,
 #define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, l)                  \
     _elf_dynamic_do_reloc(l, DT_##RELOC, DT_##RELOC##SZ,        \
                           &elf_dynamic_do_##reloc)
+#define _ELF_DYNAMIC_REDO_RELOC(RELOC, reloc, l) elf_dynamic_redo_##reloc(l)
 
 #if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
 # define _ELF_CHECK_REL 0
@@ -205,25 +206,27 @@ _elf_dynamic_do_reloc(struct link_map * l, int dt_reloc, int dt_reloc_sz,
 
 #if ! ELF_MACHINE_NO_REL
 # include "do-rel.h"
-# define ELF_DYNAMIC_DO_REL(l) \
-  _ELF_DYNAMIC_DO_RELOC (REL, rel, l)
+# define ELF_DYNAMIC_DO_REL(l) _ELF_DYNAMIC_DO_RELOC (REL, rel, l)
 # define ELF_DYNAMIC_COPY_REL(l1, l2) elf_dynamic_copy_rel(l1, l2)
+# define ELF_DYNAMIC_REDO_REL(l) _ELF_DYNAMIC_REDO_RELOC (REL, rel, l)
 #else
 /* nothing to do */
 # define ELF_DYNAMIC_DO_REL(l)
-# define ELF_DYNAMIC_COPY_REL(l1, l2)
+//# define ELF_DYNAMIC_COPY_REL(l1, l2)
+# define ELF_DYNAMIC_REDO_REL(l)
 #endif
 
 #if ! ELF_MACHINE_NO_RELA
 # define DO_RELA
 # include "do-rel.h"
-# define ELF_DYNAMIC_DO_RELA(l) \
-  _ELF_DYNAMIC_DO_RELOC (RELA, rela, l)
-# define ELF_DYNAMIC_COPY_RELA(l1, l2) elf_dynamic_copy_rela(l, l2)
+# define ELF_DYNAMIC_DO_RELA(l) _ELF_DYNAMIC_DO_RELOC (RELA, rela, l)
+//# define ELF_DYNAMIC_COPY_RELA(l1, l2) elf_dynamic_copy_rela(l, l2)
+# define ELF_DYNAMIC_REDO_RELA(l) _ELF_DYNAMIC_REDO_RELOC (RELA, rela, l)
 #else
 /* nothing to do */
 # define ELF_DYNAMIC_DO_RELA(l)
-# define ELF_DYNAMIC_COPY_RELA(l1, l2)
+//# define ELF_DYNAMIC_COPY_RELA(l1, l2)
+# define ELF_DYNAMIC_REDO_RELA(l)
 #endif
 
 /* This can't just be an inline function because GCC is too dumb
@@ -234,8 +237,16 @@ _elf_dynamic_do_reloc(struct link_map * l, int dt_reloc, int dt_reloc_sz,
         ELF_DYNAMIC_DO_RELA(l);        \
     } while (0)
 
+#if 0
 #define ELF_DYNAMIC_COPY(l1, l2)       \
     do {                               \
         ELF_DYNAMIC_COPY_REL(l1, l2);  \
         ELF_DYNAMIC_COPY_RELA(l1, l2); \
     } while (0)
+#endif
+
+# define ELF_REDO_DYNAMIC_RELOCATE(l)  \
+    do {                               \
+        ELF_DYNAMIC_REDO_REL(l);       \
+        ELF_DYNAMIC_REDO_RELA(l);      \
+    } while (0)

+ 57 - 37
LibOS/shim/src/elf/shim_rtld.c

@@ -123,7 +123,6 @@ struct link_map {
     enum object_type l_type;
 
 #define MAX_LOADCMDS    4
-
     struct loadcmd {
         ElfW(Addr) mapstart, mapend, dataend, allocend;
         off_t mapoff;
@@ -137,6 +136,14 @@ struct link_map {
         int prot;
         struct textrel * next;
     } * textrels;
+
+#define MAX_LINKSYMS    32
+    struct linksym {
+        void * rel;
+        ElfW(Sym) * sym;
+        void * reloc;
+    } linksyms[MAX_LINKSYMS];
+    int nlinksyms;
 };
 
 struct link_map * lookup_symbol (const char * undef_name, ElfW(Sym) ** ref);
@@ -196,7 +203,7 @@ static int protect_page (struct link_map * l, void * addr, size_t size)
     void * end = ALIGN_UP(addr + size);
 
     if (!DkVirtualMemoryProtect(start, end - start,
-                                PAL_PROT_READ|PAL_PROT_WRITE))
+                                PAL_PROT_READ|PAL_PROT_WRITE|prot))
         return -PAL_ERRNO;
 
     if (!c)
@@ -372,7 +379,7 @@ __map_elf_object (struct shim_handle * file,
         errstring = "shared object has to be backed by file";
         errval = -EINVAL;
 call_lose:
-        debug("loading %s: %s (%e)\n", l->l_name, errstring, errval);
+        debug("loading %s: %s\n", l->l_name, errstring);
         return NULL;
     }
 
@@ -790,7 +797,8 @@ static int __remove_elf_object (struct link_map * l)
 
 static int __free_elf_object (struct link_map * l)
 {
-    debug("removing %s as runtime object at %p\n", l->l_name, l->l_map_start);
+    debug("removing %s as runtime object loaded at %p\n", l->l_name,
+          l->l_map_start);
 
     struct loadcmd *c = l->loadcmds;
 
@@ -1044,7 +1052,7 @@ int load_elf_object (struct shim_handle * file, void * addr, size_t mapped)
         return -EINVAL;
 
     if (mapped)
-        debug("adding %s as runtime object at %p-%p\n",
+        debug("adding %s as runtime object loaded at %p-%p\n",
               file ? qstrgetstr(&file->uri) : "(unknown)", addr, addr + mapped);
     else
         debug("loading %s as runtime object at %p\n",
@@ -1153,7 +1161,7 @@ int reload_elf_object (struct shim_handle * file)
     if (!map)
         return -ENOENT;
 
-    debug("reloading %s as runtime object at %p-%p\n",
+    debug("reloading %s as runtime object loaded at %p-%p\n",
           qstrgetstr(&file->uri), map->l_map_start, map->l_map_end);
 
     return __load_elf_object(file, NULL, OBJECT_REMAP, map);
@@ -1234,7 +1242,8 @@ do_lookup_map (ElfW(Sym) * ref, const char * undef_name,
     int len = strlen(undef_name);
 
     /* Nested routine to check whether the symbol matches.  */
-    ElfW(Sym) * check_match (ElfW(Sym) * sym) {
+    ElfW(Sym) * check_match (ElfW(Sym) * sym)
+    {
         unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
 
         if (__builtin_expect ((sym->st_value == 0 /* No value.  */
@@ -1376,10 +1385,12 @@ static int do_relocate_object (struct link_map * l)
 {
     int ret = 0;
 
-    ELF_DYNAMIC_RELOCATE(l);
+    if (l->l_resolved)
+        ELF_REDO_DYNAMIC_RELOCATE(l);
+    else
+        ELF_DYNAMIC_RELOCATE(l);
 
-    ret = reprotect_map(l);
-    if (ret < 0)
+    if ((ret = reprotect_map(l)) < 0)
         return ret;
 
     return 0;
@@ -1550,25 +1561,24 @@ int init_loader (void)
     struct link_map * exec_map = __search_map_by_handle(exec);
 
     if (!exec_map) {
-        void * addr = (void *) PAL_CB(executable_begin);
-        void * addr_end = (void *) PAL_CB(executable_end);
-
-        if (!addr || !addr_end) {
-            ret = -EACCES;
-            goto out;
-        }
-
-        if ((ret = load_elf_object(exec, addr, addr_end - addr)) < 0)
+        if ((ret = load_elf_object(exec,
+                            (void *) PAL_CB(executable_range.start),
+                            PAL_CB(executable_range.end) -
+                            PAL_CB(executable_range.start))) < 0)
             goto out;
 
         exec_map = __search_map_by_handle(exec);
     }
 
-    if (!interp_map && __need_interp(exec_map))
-        ret = __load_interp_object(exec_map);
+    if (!interp_map
+        && __need_interp(exec_map)
+        && (ret = __load_interp_object(exec_map)) < 0)
+        goto out;
+
+    ret = 0;
 out:
     put_handle(exec);
-    return 0;
+    return ret;
 }
 
 int register_library (const char * name, unsigned long load_address)
@@ -1610,7 +1620,6 @@ int execute_elf_object (struct shim_handle * exec, int argc, const char ** argp,
     auxp[4].a_un.a_val = interp_map ? interp_map->l_addr : 0;
     auxp[5].a_type = AT_NULL;
 
-    int ret = 0;
     ElfW(Addr) entry = interp_map ? interp_map->l_entry : exec_map->l_entry;
 
 #if defined(__x86_64__)
@@ -1628,15 +1637,8 @@ int execute_elf_object (struct shim_handle * exec, int argc, const char ** argp,
 #else
 # error "architecture not supported"
 #endif
-    ret = 0;
-#if 0
-    int (*main_entry) (int, const char **, const char **, ElfW(auxv_t) *) =
-        (void *) exec_map->l_entry;
-
-    ret = main_entry(argc, argp, argp + argc + 1, auxp);
-#endif
-    shim_do_exit(ret);
-    return ret;
+    shim_do_exit(0);
+    return 0;
 }
 
 DEFINE_MIGRATE_FUNC(library)
@@ -1658,18 +1660,17 @@ MIGRATE_FUNC_BODY(library)
     int sonamelen = map->l_soname ? strlen(map->l_soname) : 0;
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct link_map));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct link_map));
+        off = ADD_OFFSET(sizeof(struct link_map));
 
         if (!dry) {
-            new_map = (struct link_map *) (base + *offset);
+            new_map = (struct link_map *) (base + off);
             memcpy(new_map, map, sizeof(struct link_map));
 
             get_handle(file);
             new_map->l_file = file;
             new_map->l_prev = NULL;
             new_map->l_next = NULL;
+            new_map->textrels = NULL;
         }
 
         if (map->l_ld) {
@@ -1707,6 +1708,10 @@ MIGRATE_FUNC_BODY(library)
                 new_map->l_soname = soname;
             }
         }
+
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct link_map));
+
     } else if (!dry) {
         new_map = (struct link_map *) (base + off);
     }
@@ -1716,6 +1721,12 @@ MIGRATE_FUNC_BODY(library)
 }
 END_MIGRATE_FUNC
 
+DEFINE_PROFILE_CATAGORY(inside_resume_library,  resume_func);
+DEFINE_PROFILE_INTERVAL(clean_up_library,       inside_resume_library);
+DEFINE_PROFILE_INTERVAL(search_library_vma,     inside_resume_library);
+DEFINE_PROFILE_INTERVAL(relocate_library,       inside_resume_library);
+DEFINE_PROFILE_INTERVAL(add_or_replace_library, inside_resume_library);
+
 RESUME_FUNC_BODY(library)
 {
     unsigned long off = GET_FUNC_ENTRY();
@@ -1731,11 +1742,15 @@ RESUME_FUNC_BODY(library)
         RESUME_REBASE(map->l_info);
     }
 
+    BEGIN_PROFILE_INTERVAL();
+
     struct link_map * old_map = __search_map_by_name(map->l_name);
 
     if (old_map)
         remove_r_debug((void *) old_map->l_addr);
 
+    SAVE_PROFILE_INTERVAL(clean_up_library);
+
     struct shim_vma * vma = NULL;
 
     if (lookup_supervma((void *) map->l_map_start, allocsize, &vma) < 0 ||
@@ -1752,16 +1767,21 @@ RESUME_FUNC_BODY(library)
     }
 
     put_vma(vma);
+    SAVE_PROFILE_INTERVAL(search_library_vma);
 
     if (internal_map && (!map->l_resolved ||
-        map->l_resolved_map != internal_map->l_addr))
+        map->l_resolved_map != internal_map->l_addr)) {
         do_relocate_object(map);
+        SAVE_PROFILE_INTERVAL(relocate_library);
+    }
 
     if (old_map)
         replace_link_map(map, old_map);
     else
         add_link_map(map);
 
+    SAVE_PROFILE_INTERVAL(add_or_replace_library);
+
 #ifdef DEBUG_RESUME
     debug("library: loaded at %p,name=%s\n", map->l_addr, map->l_name);
 #endif

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

@@ -224,7 +224,7 @@ static int __query_attr (struct shim_file_data * data, PAL_HANDLE pal_handle)
 
     /* need to correct the data type */
     if (data->type == FILE_UNKNOWN)
-        switch (pal_attr.type) {
+        switch (pal_attr.handle_type) {
             case pal_type_file: data->type = FILE_REGULAR;  break;
             case pal_type_dir:  data->type = FILE_DIR;      break;
             case pal_type_dev:  data->type = FILE_DEV;      break;
@@ -234,7 +234,7 @@ static int __query_attr (struct shim_file_data * data, PAL_HANDLE pal_handle)
                  (pal_attr.writeable ? S_IWUSR : 0) |
                  (pal_attr.runnable  ? S_IXUSR : 0);
 
-    atomic_set(&data->size, pal_attr.size);
+    atomic_set(&data->size, pal_attr.pending_size);
     data->queried = true;
 
     return 0;
@@ -590,7 +590,8 @@ static inline int __map_buffer (struct shim_handle * hdl, int size)
     while (mapoff + maplen < file->marker + size)
         maplen *= 2;
 
-    void * mapbuf = DkStreamMap(hdl->pal_handle, NULL, prot, mapoff, maplen);
+    void * mapbuf =
+        (void *) DkStreamMap(hdl->pal_handle, NULL, prot, mapoff, maplen);
     if (!mapbuf)
         return -PAL_ERRNO;
 
@@ -774,7 +775,7 @@ static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
     if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
         return ret;
 
-    int pal_prot = prot & (PROT_READ|PROT_WRITE|PROT_EXEC);
+    int pal_prot = PAL_PROT(prot, flags);
 
 #if MAP_FILE == 0
     if (flags & MAP_ANONYMOUS)
@@ -783,11 +784,8 @@ static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
 #endif
         return -EINVAL;
 
-    if (flags & MAP_PRIVATE)
-        pal_prot |= PAL_PROT_WRITECOPY;
-
-    void * alloc_addr = DkStreamMap(hdl->pal_handle, *addr, pal_prot, offset,
-                                    size);
+    void * alloc_addr =
+        (void *) DkStreamMap(hdl->pal_handle, *addr, pal_prot, offset, size);
 
     if (!alloc_addr)
         return -PAL_ERRNO;

+ 1 - 1
LibOS/shim/src/fs/pipe/fs.c

@@ -117,7 +117,7 @@ static int pipe_poll (struct shim_handle * hdl, int poll_type)
     }
 
     if (poll_type == FS_POLL_SZ) {
-        ret = attr.size;
+        ret = attr.pending_size;
         goto out;
     }
 

+ 62 - 78
LibOS/shim/src/fs/proc/info.c

@@ -13,9 +13,6 @@
 #include <asm/prctl.h>
 #include <errno.h>
 
-#define MEMINFO_READ_PASSTHROUGH 1
-#define CPUINFO_READ_PASSTHROUGH 1
-
 static int proc_info_mode (const char * name, mode_t * mode)
 {
     *mode = 0444;
@@ -25,87 +22,46 @@ static int proc_info_mode (const char * name, mode_t * mode)
 static int proc_info_stat (const char * name, struct stat * buf)
 {
     memset(buf, 0, sizeof(struct stat));
-
     buf->st_dev = buf->st_ino = 1;
     buf->st_mode = 0444|S_IFDIR;
     buf->st_uid = 0;
     buf->st_gid = 0;
     buf->st_size = 0;
-
     return 0;
 }
 
-#if MEMINFO_READ_PASSTHROUGH == 1 || CPUINFO_READ_PASSTHROUGH == 1
-
-# define DEFAULT_BUFFER_SIZE 256
-
-static int proc_info_read_passthrough (const char * uri, char ** strptr)
-{
-    int size = DEFAULT_BUFFER_SIZE;
-    char * strbuf = malloc(size);
-    int bytes = 0, ret = 0;
-
-    if (!strbuf) {
-        ret = -ENOMEM;
-        goto out;
-    }
-
-    PAL_HANDLE hdl = DkStreamOpen(uri, PAL_ACCESS_RDONLY, 0, 0, 0);
-
-    if (!hdl)
-        return -PAL_ERRNO;
-
-retry:
-    ret = DkStreamRead(hdl, bytes, size - bytes, strbuf + bytes, NULL, 0);
-
-    if (!ret) {
-        ret = -PAL_ERRNO;
-        goto out_free;
-    }
-
-    bytes += ret;
-
-    if (bytes == size) {
-        char * newbuf = malloc(size * 2);
-        memcpy(newbuf, strbuf, size);
-        free(strbuf);
-        strbuf = newbuf;
-        size *= 2;
-        goto retry;
-    }
-
-    ret = bytes;
-    *strptr = strbuf;
-    goto out;
-
-out_free:
-    free(strbuf);
-out:
-    DkObjectClose(hdl);
-    return ret;
-}
-#endif
-
 static int proc_meminfo_open (struct shim_handle * hdl, const char * name,
                               int flags)
 {
     if (flags & (O_WRONLY|O_RDWR))
         return -EACCES;
 
+    int len, max = 128;
     char * str = NULL;
-    int ret = 0, len = 0;
-#if MEMINFO_READ_PASSTHROUGH == 1
-    ret = proc_info_read_passthrough("file:/proc/meminfo", &str);
 
-    if (ret >= 0) {
-        len = ret;
-        ret = 0;
+    struct { const char * fmt; unsigned long val; }
+        meminfo[] = {
+            { "MemTotal:      %8lu kB\n", pal_control.mem_info.mem_total / 1024, },
+            { "MemFree:       %8lu kB\n", DkMemoryAvailableQuota() / 1024, },
+        };
+
+retry:
+    if (str) free(str);
+    max *= 2;
+    len = 0;
+    str = malloc(max);
+    if (!str)
+        return -ENOMEM;
+
+    for (int i = 0 ; i < sizeof(meminfo) / sizeof(meminfo[0]) ; i++) {
+        int ret = snprintf(str + len, max - len, meminfo[i].fmt,
+                           meminfo[i].val);
+
+        if (len + ret == max)
+            goto retry;
+
+        len += ret;
     }
-#else
-    ret = -EACCES;
-#endif
-    if (ret < 0)
-        return ret;
 
     struct shim_str_data * data = malloc(sizeof(struct shim_str_data));
     if (!data) {
@@ -129,20 +85,48 @@ static int proc_cpuinfo_open (struct shim_handle * hdl, const char * name,
     if (flags & (O_WRONLY|O_RDWR))
         return -EACCES;
 
+    int len, max = 128;
     char * str = NULL;
-    int ret = 0, len = 0;
-#if CPUINFO_READ_PASSTHROUGH == 1
-    ret = proc_info_read_passthrough("file:/proc/cpuinfo", &str);
 
-    if (ret >= 0) {
-        len = ret;
-        ret = 0;
+    struct { const char * fmt; unsigned long val; }
+        cpuinfo[] = {
+            { "processor      : %lu\n", 0, },
+            { "vendor_id      : %s\n",  (unsigned long) pal_control.cpu_info.cpu_vendor, },
+            { "cpu_family     : %lu\n", pal_control.cpu_info.cpu_family, },
+            { "model          : %lu\n", pal_control.cpu_info.cpu_model, },
+            { "model name     : %s\n",  (unsigned long) pal_control.cpu_info.cpu_brand, },
+            { "stepping       : %lu\n", pal_control.cpu_info.cpu_stepping, },
+            { "core id        : %lu\n", 0, },
+            { "cpu_core       : %lu\n", pal_control.cpu_info.cpu_num, },
+        };
+
+retry:
+    if (str) free(str);
+    max *= 2;
+    len = 0;
+    str = malloc(max);
+    if (!str)
+        return -ENOMEM;
+
+    for (int n = 0 ; n < pal_control.cpu_info.cpu_num ; n++) {
+        cpuinfo[0].val = n;
+        cpuinfo[6].val = n;
+        for (int i = 0 ; i < sizeof(cpuinfo) / sizeof(cpuinfo[0]) ; i++) {
+            int ret = snprintf(str + len, max - len, cpuinfo[i].fmt,
+                               cpuinfo[i].val);
+
+            if (len + ret == max)
+                goto retry;
+
+            len += ret;
+        }
+
+        if (len >= max - 1)
+            goto retry;
+
+        str[len++] = '\n';
+        str[len] = 0;
     }
-#else
-    ret = -EACCES;
-#endif
-    if (ret < 0)
-        return ret;
 
     struct shim_str_data * data = malloc(sizeof(struct shim_str_data));
     if (!data) {

+ 11 - 15
LibOS/shim/src/fs/shim_fs.c

@@ -404,9 +404,7 @@ MIGRATE_FUNC_BODY(mount)
                                            sizeof(struct shim_mount));
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_mount));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct shim_mount));
+        off = ADD_OFFSET(sizeof(struct shim_mount));
 
         if (dry) {
             mount->cpdata = NULL;
@@ -415,10 +413,7 @@ MIGRATE_FUNC_BODY(mount)
             if (mount->fs_ops &&
                 mount->fs_ops->checkpoint) {
                 void * cpdata = NULL;
-
-                int bytes = mount->fs_ops->checkpoint
-                                (&cpdata, mount->data);
-
+                int bytes = mount->fs_ops->checkpoint(&cpdata, mount->data);
                 if (bytes > 0 && cpdata) {
                     mount->cpdata = cpdata;
                     mount->cpsize = bytes;
@@ -426,16 +421,13 @@ MIGRATE_FUNC_BODY(mount)
                 }
             }
         } else {
-            new_mount = (struct shim_mount *) (base + *offset);
-
+            new_mount = (struct shim_mount *) (base + off);
             memcpy(new_mount, mount, sizeof(struct shim_mount));
 
             if (mount->cpdata) {
                 ADD_OFFSET(mount->cpsize);
                 new_mount->cpdata = (void *) (base + *offset);
-
-                memcpy (new_mount->cpdata, mount->cpdata,
-                        mount->cpsize);
+                memcpy(new_mount->cpdata, mount->cpdata, mount->cpsize);
             }
 
             new_mount->data = NULL;
@@ -443,15 +435,19 @@ MIGRATE_FUNC_BODY(mount)
             new_mount->root = NULL;
             INIT_LIST_HEAD(&new_mount->list);
         }
+
+        DO_MIGRATE_IN_MEMBER(qstr, mount, new_mount, path, false);
+        DO_MIGRATE_IN_MEMBER(qstr, mount, new_mount, uri,  false);
+
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct shim_mount));
+
     } else if (!dry) {
         new_mount = (struct shim_mount *) (base + off);
     }
 
     if (new_mount && objp)
         *objp = (void *) new_mount;
-
-    DO_MIGRATE_IN_MEMBER(qstr, mount, new_mount, path, false);
-    DO_MIGRATE_IN_MEMBER(qstr, mount, new_mount, uri,  false);
 }
 END_MIGRATE_FUNC
 

+ 3 - 3
LibOS/shim/src/fs/socket/fs.c

@@ -151,8 +151,8 @@ static int socket_hstat (struct shim_handle * hdl, struct stat * stat)
 
     memset(stat, 0, sizeof(struct stat));
 
-    stat->st_ino    = (ino_t) attr.file_id;
-    stat->st_size   = (off_t) attr.size;
+    stat->st_ino    = 0;
+    stat->st_size   = (off_t) attr.pending_size;
     stat->st_mode   = S_IFSOCK;
 
     return 0;
@@ -225,7 +225,7 @@ static int socket_poll (struct shim_handle * hdl, int poll_type)
     }
 
     if (poll_type == FS_POLL_SZ) {
-        ret = attr.size;
+        ret = attr.pending_size;
         goto out;
     }
 

+ 0 - 1
LibOS/shim/src/fs/str/fs.c

@@ -83,7 +83,6 @@ int str_close (struct shim_handle * hdl)
     }
 
     str_dput(hdl->dentry);
-
     return 0;
 }
 

+ 42 - 36
LibOS/shim/src/ipc/shim_ipc.c

@@ -59,12 +59,6 @@ int init_ns_sysv   (void);
 int init_ipc (void)
 {
     int ret = 0;
-    if (!cur_process.vmid) {
-        if (getrand(&cur_process.vmid, sizeof(IDTYPE)) < sizeof(IDTYPE))
-            return -EINVAL;
-
-        debug("process started: %u\n", cur_process.vmid);
-    }
 
     create_lock(ipc_info_lock);
 
@@ -257,17 +251,11 @@ struct shim_ipc_info * discover_client (struct shim_ipc_port * port,
 
 struct shim_process * create_new_process (bool inherit_parent)
 {
-    IDTYPE vmid;
-    if (getrand(&vmid, sizeof(IDTYPE)) < sizeof(IDTYPE))
-        return NULL;
-
     struct shim_process * new_process = malloc(sizeof(struct shim_process));
     if (!new_process)
         return NULL;
 
-    assert(vmid != cur_process.vmid);
     memset(new_process, 0, sizeof(struct shim_process));
-    new_process->vmid = vmid;
     new_process->parent = get_new_ipc_info(cur_process.vmid, NULL, 0);
 
     if (!inherit_parent)
@@ -282,8 +270,8 @@ struct shim_process * create_new_process (bool inherit_parent)
         if (cur_process.ns[i])
             new_process->ns[i] =
                 get_new_ipc_info(cur_process.ns[i]->vmid,
-                                  qstrgetstr(&cur_process.ns[i]->uri),
-                                  cur_process.ns[i]->uri.len);
+                                 qstrgetstr(&cur_process.ns[i]->uri),
+                                 cur_process.ns[i]->uri.len);
 
     unlock(cur_process.lock);
     return new_process;
@@ -674,24 +662,26 @@ MIGRATE_FUNC_BODY(ipc_info)
     struct shim_ipc_info * new_port = NULL;
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_ipc_info));
+        off = ADD_OFFSET(sizeof(struct shim_ipc_info));
 
         if (!dry) {
-            new_port = (struct shim_ipc_info *) (base + *offset);
+            new_port = (struct shim_ipc_info *) (base + off);
             *new_port = *port;
             REF_SET(new_port->ref_count, 0);
         }
 
         ADD_ENTRY(PALHDL, port->pal_handle && port->pal_handle !=
-                  IPC_FORCE_RECONNECT ? *offset +
+                  IPC_FORCE_RECONNECT ? off +
                   offsetof(struct shim_ipc_info, pal_handle) : 0);
-    } else if (!dry)
+
+        DO_MIGRATE_IN_MEMBER(qstr, port, new_port, uri, false);
+
+    } else if (!dry) {
         new_port = (struct shim_ipc_info *) (base + off);
+    }
 
     if (new_port && objp)
         *objp = (void *) new_port;
-
-    DO_MIGRATE_IN_MEMBER(qstr, port, new_port, uri, false);
 }
 END_MIGRATE_FUNC
 
@@ -714,29 +704,38 @@ MIGRATE_FUNC_BODY(process)
     struct shim_process * new_proc = NULL;
 
     if (ENTRY_JUST_CREATED(off)) {
-        ADD_OFFSET(sizeof(struct shim_process));
-        ADD_FUNC_ENTRY(*offset);
-        ADD_ENTRY(SIZE, sizeof(struct shim_process));
+        off = ADD_OFFSET(sizeof(struct shim_process));
 
         if (!dry) {
-            new_proc = (struct shim_process *) (base + *offset);
+            new_proc = (struct shim_process *) (base + off);
             *new_proc = *proc;
         }
-    } else if (!dry)
-        new_proc = (struct shim_process *) (base + off);
 
-    if (new_proc && objp)
-        *objp = (void *) new_proc;
+        if (proc->self)
+            __DO_MIGRATE(ipc_info, proc->self,
+                         &new_proc->self,
+                         true);
 
-    if (proc->self)
-        __DO_MIGRATE(ipc_info, proc->self, &new_proc->self, true);
+        if (proc->parent)
+            __DO_MIGRATE(ipc_info, proc->parent,
+                         &new_proc->parent,
+                         true);
 
-    if (proc->parent)
-        __DO_MIGRATE(ipc_info, proc->parent, &new_proc->parent, true);
+        for (int i = 0 ; i < TOTAL_NS ; i++)
+            if (proc->ns[i])
+                __DO_MIGRATE(ipc_info, proc->ns[i],
+                             &new_proc->ns[i],
+                             true);
 
-    for (int i = 0 ; i < TOTAL_NS ; i++)
-        if (proc->ns[i])
-            __DO_MIGRATE(ipc_info, proc->ns[i], &new_proc->ns[i], true);
+        ADD_FUNC_ENTRY(off);
+        ADD_ENTRY(SIZE, sizeof(struct shim_process));
+
+    } else if (!dry) {
+        new_proc = (struct shim_process *) (base + off);
+    }
+
+    if (new_proc && objp)
+        *objp = (void *) new_proc;
 }
 END_MIGRATE_FUNC
 
@@ -746,8 +745,14 @@ RESUME_FUNC_BODY(process)
     assert((size_t) GET_ENTRY(SIZE) == sizeof(struct shim_process));
     struct shim_process * proc = (struct shim_process *) (base + off);
 
-    if (proc->self)
+    RESUME_REBASE(proc->self);
+    RESUME_REBASE(proc->parent);
+    RESUME_REBASE(proc->ns);
+
+    if (proc->self) {
+        proc->self->vmid = cur_process.vmid;
         get_ipc_info(proc->self);
+    }
 
     if (proc->parent)
         get_ipc_info(proc->parent);
@@ -756,6 +761,7 @@ RESUME_FUNC_BODY(process)
         if (proc->ns[i])
             get_ipc_info(proc->ns[i]);
 
+    proc->vmid = cur_process.vmid;
     memcpy(&cur_process, proc, sizeof(struct shim_process));
     create_lock(cur_process.lock);
 

+ 38 - 19
LibOS/shim/src/ipc/shim_ipc_helper.c

@@ -302,6 +302,7 @@ void add_ipc_port_by_id (IDTYPE vmid, PAL_HANDLE hdl, int type,
     debug("adding port (handle %p) for process %u (type %04x)\n",
           hdl, vmid, type);
 
+    assert(!!hdl && PAL_GET_TYPE(hdl));
     lock(ipc_helper_lock);
 
     struct hlist_head * head = vmid ? &ipc_port_pool[PID_HASH(vmid)] : NULL;
@@ -517,7 +518,7 @@ int broadcast_ipc (struct shim_ipc_msg * msg, struct shim_ipc_port ** exclude,
                    int exsize, int target_type)
 {
     struct shim_ipc_port ** exend = exclude + exsize, ** ex;
-    struct shim_ipc_port * pobj, * n;
+    struct shim_ipc_port * pobj;
 
     if (!target_type && broadcast_port) {
         for (ex = exclude ; ex < exend && *ex != broadcast_port ; ex++);
@@ -534,29 +535,47 @@ int broadcast_ipc (struct shim_ipc_msg * msg, struct shim_ipc_port ** exclude,
 
     lock(ipc_helper_lock);
 
-    list_for_each_entry_safe(pobj, n, &pobj_list, list) {
-        debug("found port %p (handle %p) for process %u (type %04x)\n",
-              pobj, pobj->pal_handle, pobj->info.vmid, pobj->info.type);
+    int ntargets = 0;
+    list_for_each_entry(pobj, &pobj_list, list) {
+        debug("found port %p (handle %p) for process %u (type %04x)\n", pobj,
+              pobj->pal_handle, pobj->info.vmid, pobj->info.type);
+        if (pobj->info.type & target_type)
+            ntargets++;
+    }
+
+    struct shim_ipc_port ** targets = __alloca(sizeof(struct shim_ipc_port *)
+                                               * ntargets);
+    int i = 0;
+    list_for_each_entry(pobj, &pobj_list, list)
         if (pobj->info.type & target_type) {
-            debug("broadcast to port %p (handle %p) for process %u "
-                  "(type %x, target %x)\n",
-                  pobj, pobj->pal_handle, pobj->info.vmid,
-                  pobj->info.type, target_type);
-
-            if (exsize) {
-                for (ex = exclude ; ex < exend && *ex != pobj ; ex++);
-                if (ex != exend)
-                    continue;
-            }
+            get_ipc_port(pobj);
+            targets[i++] = pobj;
+        }
+
+    unlock(ipc_helper_lock);
 
-            msg->dst = pobj->info.vmid;
-            /* has to be assigned, so shim_send_ipc_message will not try
-               to grab ipc_helper_lock */
-            send_ipc_message(msg, pobj);
+    for (i = 0 ; i < ntargets ; i++) {
+        pobj = targets[i];
+
+        debug("broadcast to port %p (handle %p) for process %u "
+              "(type %x, target %x)\n",
+              pobj, pobj->pal_handle, pobj->info.vmid,
+              pobj->info.type, target_type);
+
+        if (exsize) {
+            for (ex = exclude ; ex < exend && *ex != pobj ; ex++);
+            if (ex != exend)
+                continue;
         }
+
+        msg->dst = pobj->info.vmid;
+
+        /* has to be assigned, so shim_send_ipc_message will not try
+           to grab ipc_helper_lock */
+        send_ipc_message(msg, pobj);
+        put_ipc_port(pobj);
     }
 
-    unlock(ipc_helper_lock);
     return 0;
 }
 

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

@@ -853,8 +853,8 @@ int CONCAT3(prepare, NS, leader) (void)
 static int connect_owner (IDTYPE idx, struct shim_ipc_port ** portptr,
                           IDTYPE * owner)
 {
-    struct CONCAT2(NS, range) range;
     struct shim_ipc_info * info = NULL;
+    struct CONCAT2(NS, range) range;
     memset(&range, 0, sizeof(struct CONCAT2(NS, range)));
 
     int ret = CONCAT3(get, NS, range) (idx, &range, &info);
@@ -870,6 +870,7 @@ static int connect_owner (IDTYPE idx, struct shim_ipc_port ** portptr,
 
     if (range.owner == cur_process.vmid) {
         ret = -ESRCH;
+        assert(!range.port);
         goto out;
     }
 
@@ -888,6 +889,7 @@ static int connect_owner (IDTYPE idx, struct shim_ipc_port ** portptr,
         }
 
         add_ipc_port_by_id(range.owner, pal_handle, type, NULL, &range.port);
+        assert(range.port);
     }
 
     lock(range_map_lock);
@@ -908,6 +910,8 @@ success:
 out:
     if (info)
         put_ipc_info(info);
+
+    assert(ret || range.port);
     return ret;
 }
 

+ 122 - 90
LibOS/shim/src/shim_checkpoint.c

@@ -157,8 +157,7 @@ get_addr_map_entry (void * map, ptr_t addr, size_t size, bool create)
         if (tmp->map.addr == addr)
             e = &tmp->map;
 
-    if (create && !e)
-    {
+    if (create && !e) {
         struct addr_map_buffer *buffer = m->buffer;
 
         if (buffer->cnt == buffer->num)
@@ -201,20 +200,23 @@ MIGRATE_FUNC_BODY(memory)
     struct shim_mem_entry * entry = NULL;
 
     if (off & MAP_UNUSABLE) {
-        ADD_OFFSET(size);
-        void * data = dry ? NULL : (void *) base + *offset;
-        ADD_OFFSET(sizeof(struct shim_gipc_entry));
-        ADD_FUNC_ENTRY(*offset);
+        off = ADD_OFFSET(size);
+        void * data = dry ? NULL : (void *) base + off;
+        ptr_t entry_off = ADD_OFFSET(sizeof(struct shim_gipc_entry));
 
         if (!dry) {
-            entry = (struct shim_mem_entry *) (base + *offset);
             memcpy(data, obj, size);
+
+            entry = (struct shim_mem_entry *) (base + entry_off);
             entry->addr = (void *) addr;
             entry->size = size;
             entry->data = data;
             entry->prot = PROT_READ|PROT_WRITE;
+            entry->need_alloc = entry->need_prot = true;
             entry->vma  = NULL;
         }
+
+        ADD_FUNC_ENTRY(entry_off);
     }
 
     if (!dry && recursive) {
@@ -229,7 +231,7 @@ MIGRATE_FUNC_BODY(memory)
             struct shim_addr_map * e = get_addr_map_entry (map, val, 0, 0);
 
             if (e)
-                *(ptr_t *)p = base + e->offset + (val - e->addr);
+                *(ptr_t *) p = base + e->offset + (val - e->addr);
 
             p += sizeof(ptr_t);
         }
@@ -255,24 +257,29 @@ RESUME_FUNC_BODY(memory)
           entry->addr, entry->addr + entry->size);
 #endif
 
-    if (entry->need_alloc)
-        DkVirtualMemoryAlloc((void *) ALIGN_DOWN(entry->addr),
-                             ALIGN_UP(entry->addr + entry->size) -
-                             ALIGN_DOWN(entry->addr),
-                             0, PAL_PROT_READ|PAL_PROT_WRITE);
-    else if (entry->prot != (PROT_READ|PROT_WRITE))
-        DkVirtualMemoryProtect((void *) ALIGN_DOWN(entry->addr),
-                               ALIGN_UP(entry->addr + entry->size) -
-                               ALIGN_DOWN(entry->addr),
-                               PAL_PROT_READ|PAL_PROT_WRITE);
+    PAL_PTR mapaddr = ALIGN_DOWN(entry->addr);
+    PAL_NUM mapsize = ALIGN_UP(entry->addr + entry->size) - mapaddr;
+    int pal_prot = PAL_PROT(entry->prot, 0);
+
+    if (entry->need_alloc &&
+        !DkVirtualMemoryAlloc(mapaddr, mapsize, 0,
+                              pal_prot|PAL_PROT_READ|PAL_PROT_WRITE))
+        return -PAL_ERRNO;
+
+    if (entry->need_prot &&
+        !DkVirtualMemoryProtect(mapaddr, mapsize,
+                                pal_prot|PAL_PROT_READ|PAL_PROT_WRITE))
+        return -PAL_ERRNO;
 
     memcpy(entry->addr, entry->data, entry->size);
 
-    if (entry->prot != (PROT_READ|PROT_WRITE))
-        DkVirtualMemoryProtect((void *) ALIGN_DOWN(entry->addr),
-                               ALIGN_UP(entry->addr + entry->size) -
-                               ALIGN_DOWN(entry->addr),
-                               entry->prot);
+    if (entry->vma)
+        entry->vma->received = (entry->addr + entry->size) - entry->vma->addr;
+
+    if ((entry->need_alloc || entry->need_prot) &&
+        (pal_prot & (PAL_PROT_READ|PAL_PROT_WRITE)) !=
+        (PAL_PROT_READ|PAL_PROT_WRITE))
+        DkVirtualMemoryProtect(mapaddr, mapsize, pal_prot);
 }
 END_RESUME_FUNC
 
@@ -282,13 +289,13 @@ MIGRATE_FUNC_BODY(migratable)
 {
     size = &__migratable_end - &__migratable;
 
-    ADD_OFFSET(size);
+    unsigned long off = ADD_OFFSET(size);
     ADD_FUNC_ENTRY(*offset);
     ADD_ENTRY(ADDR, &__migratable);
     ADD_ENTRY(SIZE, size);
 
     if (!dry)
-        memcpy((void *) (base + *offset), &__migratable, size);
+        memcpy((void *) (base + off), &__migratable, size);
 }
 END_MIGRATE_FUNC
 
@@ -341,11 +348,11 @@ MIGRATE_FUNC_BODY(qstr)
             qstr->oflow = NULL;
         }
     } else {
-        ADD_OFFSET(sizeof(struct shim_str));
-        ADD_FUNC_ENTRY((ptr_t) qstr - base);
+        unsigned long off = ADD_OFFSET(sizeof(struct shim_str));
+        ADD_FUNC_ENTRY(qstr - base);
 
         if (!dry) {
-            struct shim_str * str = (struct shim_str *) (base + *offset);
+            struct shim_str * str = (struct shim_str *) (base + off);
             memcpy(str, qstr->oflow, qstr->len + 1);
             qstr->oflow = str;
         }
@@ -368,12 +375,11 @@ MIGRATE_FUNC_BODY(gipc)
     void * send_addr = (void *) ALIGN_DOWN(obj);
     size_t send_size = (void *) ALIGN_UP(obj + size) - send_addr;
 
-    ADD_OFFSET(sizeof(struct shim_gipc_entry));
-    ADD_FUNC_ENTRY(*offset);
+    unsigned long off = ADD_OFFSET(sizeof(struct shim_gipc_entry));
+    ADD_FUNC_ENTRY(off);
 
     if (!dry) {
-        struct shim_gipc_entry * entry =
-            (struct shim_gipc_entry *) (base + *offset);
+        struct shim_gipc_entry * entry = (void *) (base + off);
         entry->addr_type = ABS_ADDR;
         entry->addr   = send_addr;
         entry->npages = send_size / allocsize;
@@ -411,9 +417,10 @@ RESUME_FUNC_BODY(gipc)
     RESUME_REBASE(entry->vma);
 
 #if HASH_GIPC == 1
-    if (!(entry->prot & PAL_PROT_READ))
+    PAL_FLG pal_prot = PAL_PROT(entry->prot, 0);
+    if (!(pal_prot & PROT_READ))
         DkVirtualMemoryProtect(entry->addr, entry->npages * allocsize,
-                               entry->prot|PAL_PROT_READ);
+                               pal_prot|PAL_PROT_READ);
 
     struct md5_ctx ctx;
     md5_init(&ctx);
@@ -421,9 +428,9 @@ RESUME_FUNC_BODY(gipc)
     md5_final(&ctx);
     assert(*(unsigned long *) ctx.digest == entry->first_hash);
 
-    if (!(entry->prot & PAL_PROT_READ))
+    if (!(pal_prot & PAL_PROT_READ))
         DkVirtualMemoryProtect(entry->addr, entry->npages * allocsize,
-                               entry->prot);
+                               pal_prot);
 #endif /* HASH_GIPC == 1 */
 }
 END_RESUME_FUNC
@@ -431,15 +438,16 @@ END_RESUME_FUNC
 int send_checkpoint_by_gipc (PAL_HANDLE gipc_store,
                              struct shim_cp_store * cpstore)
 {
-    void * addrs[1] = { cpstore->cpaddr };
-    unsigned long sizes[1] = { cpstore->cpsize };
+    PAL_PTR hdr_addr = cpstore->cpaddr;
+    PAL_NUM hdr_size = ALIGN_UP(cpstore->cpsize);
+    assert(ALIGNED(hdr_addr));
 
-    int npages = DkPhysicalMemoryCommit(gipc_store, 1, addrs, sizes, 0);
+    int npages = DkPhysicalMemoryCommit(gipc_store, 1, &hdr_addr, &hdr_size, 0);
     if (!npages)
         return -EPERM;
 
     int nentries = cpstore->gipc_nentries;
-    PAL_BUF * gipc_addrs = __alloca(sizeof(PAL_BUF) * nentries);
+    PAL_PTR * gipc_addrs = __alloca(sizeof(PAL_BUF) * nentries);
     PAL_NUM * gipc_sizes = __alloca(sizeof(PAL_NUM) * nentries);
     int total_pages = 0;
     int cnt = 0;
@@ -481,8 +489,8 @@ int send_checkpoint_by_gipc (PAL_HANDLE gipc_store,
 int restore_gipc (PAL_HANDLE gipc, struct gipc_header * hdr, void * cpdata,
                   long cprebase)
 {
-    struct shim_gipc_entry * gipc_entries = (void *) (cpdata +
-                                                      hdr->gipc_entoffset);
+    struct shim_gipc_entry * gipc_entries =
+                (void *) (cpdata + hdr->gipc_entoffset);
     int nentries = hdr->gipc_nentries;
 
     if (!nentries)
@@ -490,7 +498,7 @@ int restore_gipc (PAL_HANDLE gipc, struct gipc_header * hdr, void * cpdata,
 
     debug("restore memory by gipc: %d entries\n", nentries);
 
-    PAL_BUF * addrs = __alloca(sizeof(PAL_BUF) * nentries);
+    PAL_PTR * addrs = __alloca(sizeof(PAL_PTR) * nentries);
     PAL_NUM * sizes = __alloca(sizeof(PAL_NUM) * nentries);
     PAL_FLG * prots = __alloca(sizeof(PAL_FLG) * nentries);
 
@@ -548,7 +556,7 @@ int restore_gipc (PAL_HANDLE gipc, struct gipc_header * hdr, void * cpdata,
     return 0;
 }
 
-int restore_from_stack (void * cpaddr, struct cp_header * cphdr, int type)
+int restore_checkpoint (void * cpaddr, struct cp_header * cphdr, int type)
 {
     struct shim_cp_entry * cpent =
                 (struct shim_cp_entry *) (cpaddr + cphdr->cpoffset);
@@ -591,9 +599,9 @@ int restore_from_stack (void * cpaddr, struct cp_header * cphdr, int type)
     return 0;
 }
 
-int restore_from_checkpoint (const char * filename,
-                             struct newproc_cp_header * hdr,
-                             void ** cpptr)
+int init_from_checkpoint_file (const char * filename,
+                               struct newproc_cp_header * hdr,
+                               void ** cpptr)
 {
     struct shim_dentry * dir = NULL;
     int ret;
@@ -723,7 +731,6 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     int bytes;
 
 #ifdef PROFILE
-    BEGIN_PROFILE_INTERVAL();
     unsigned long begin_create_time = GET_PROFILE_INTERVAL();
     unsigned long create_time = begin_create_time;
 #endif
@@ -752,16 +759,14 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
         goto err;
     }
 
-    thread->vmid = new_process->vmid;
-
-    if (!(new_process->self = create_ipc_port(new_process->vmid, false))) {
+    if (!(new_process->self = create_ipc_port(0, false))) {
         ret = -EACCES;
         goto err;
     }
 
     cpstore = __alloca(sizeof(struct shim_cp_store));
     INIT_CP_STORE(cpstore);
-    cpstore->use_gipc = (gipc_hdl != NULL);
+    cpstore->use_gipc = (!!gipc_hdl);
     va_list ap;
     va_start(ap, thread);
     ret = migrate(cpstore, new_process, thread, ap);
@@ -803,8 +808,6 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     if (gipc_hdl) {
         if ((ret = send_checkpoint_by_gipc(gipc_hdl, cpstore)) < 0)
             goto err;
-
-        DkObjectClose(gipc_hdl);
     } else {
         ret = DkStreamWrite(proc, 0, cpstore->cpsize, cpstore->cpdata, NULL);
         if (ret < cpstore->cpsize) {
@@ -816,15 +819,24 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     if ((ret = send_handles_on_stream(proc, cpstore->cpdata)) < 0)
         goto err;
 
-    ipc_pid_sublease_send(new_process->self->vmid,
-                          thread->tid,
+    struct newproc_response res;
+    bytes = DkStreamRead(proc, 0, sizeof(struct newproc_response), &res,
+                         NULL, 0);
+    if (bytes == 0) {
+        ret = -PAL_ERRNO;
+        goto err;
+    }
+
+    if (gipc_hdl)
+        DkObjectClose(gipc_hdl);
+
+    ipc_pid_sublease_send(res.child_vmid, thread->tid,
                           qstrgetstr(&new_process->self->uri),
                           NULL);
 
     system_free(cpstore->cpaddr, cpstore->cpsize);
 
-    add_ipc_port_by_id(new_process->self->vmid,
-                       proc,
+    add_ipc_port_by_id(res.child_vmid, proc,
                        IPC_PORT_DIRCLD|IPC_PORT_LISTEN|IPC_PORT_KEEPALIVE,
                        &ipc_child_exit,
                        NULL);
@@ -832,32 +844,45 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     destroy_process(new_process);
     return 0;
 err:
-    sys_printf("process creation failed (%e)\n", -ret);
-
+    if (gipc_hdl)
+        DkObjectClose(gipc_hdl);
     if (proc)
         DkObjectClose(proc);
-
     if (new_process)
         destroy_process(new_process);
 
+    sys_printf("process creation failed\n");
     return ret;
 }
 
 DEFINE_PROFILE_INTERVAL(child_load_checkpoint_by_gipc, resume);
-DEFINE_PROFILE_INTERVAL(child_load_memory_by_gipc, resume);
+DEFINE_PROFILE_INTERVAL(child_load_memory_by_gipc,     resume);
 DEFINE_PROFILE_INTERVAL(child_load_checkpoint_on_pipe, resume);
-DEFINE_PROFILE_INTERVAL(child_receive_handles, resume);
+DEFINE_PROFILE_INTERVAL(child_receive_handles,         resume);
 
-int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
+int do_migration (struct newproc_cp_header * hdr, void ** cpptr)
 {
-    PAL_NUM cpsize = hdr->data.cpsize;
-    PAL_BUF cpaddr = hdr->data.cpaddr;
-    PAL_FLG prot = PAL_PROT_READ|PAL_PROT_WRITE;
+    void *        cpaddr = hdr->data.cpaddr;
+    unsigned long cpsize = hdr->data.cpsize;
+    PAL_PTR mapaddr;
+    PAL_NUM mapsize;
+    unsigned long mapoff;
     int ret = 0;
 
     debug("checkpoint detected (%d bytes, expected at %p)\n",
           cpsize, cpaddr);
 
+    if (cpaddr &&
+        !lookup_overlap_vma(cpaddr, cpsize, NULL)) {
+        mapaddr = (PAL_PTR) ALIGN_DOWN(cpaddr);
+        mapsize = (PAL_PTR) ALIGN_UP(cpaddr + cpsize) - mapaddr;
+        mapoff  = cpaddr - (void *) mapaddr;
+    } else {
+        mapaddr = (PAL_PTR) 0;
+        mapsize = ALIGN_UP(cpsize);
+        mapoff  = 0;
+    }
+
     BEGIN_PROFILE_INTERVAL();
 
     if (hdr->gipc.gipc_key) {
@@ -865,21 +890,24 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
         snprintf(gipc_uri, 20, "gipc:%lu", hdr->gipc.gipc_key);
         debug("open gipc store: %s\n", gipc_uri);
 
+        PAL_FLG mapprot = PAL_PROT_READ|PAL_PROT_WRITE;
         PAL_HANDLE gipc_store = DkStreamOpen(gipc_uri, 0, 0, 0, 0);
         if (!gipc_store ||
-            !DkPhysicalMemoryMap(gipc_store, 1, &cpaddr, &cpsize,
-                                 &prot))
+            !DkPhysicalMemoryMap(gipc_store, 1, &mapaddr, &mapsize,
+                                 &mapprot))
             return -PAL_ERRNO;
 
         debug("checkpoint loaded at %p\n", cpaddr);
 
-        bkeep_mmap(cpaddr, ALIGN_UP(cpsize), PROT_READ|PROT_WRITE,
+        bkeep_mmap((void *) mapaddr, mapsize,
+                   PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
                    NULL, 0, NULL);
 
         SAVE_PROFILE_INTERVAL(child_load_checkpoint_by_gipc);
 
-        if ((ret = restore_gipc(gipc_store, &hdr->gipc, cpaddr,
+        cpaddr = (void *) mapaddr + mapoff;
+        if ((ret = restore_gipc(gipc_store, &hdr->gipc, (void *) cpaddr,
                                 (long) cpaddr - (long) hdr->data.cpaddr)) < 0)
             return ret;
 
@@ -887,26 +915,22 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
 
         DkStreamDelete(gipc_store, 0);
     } else {
-        long cpsize_pgalign = ALIGN_UP(cpaddr + cpsize) - cpaddr;
-        long cpaddr_pgalign = cpaddr - ALIGN_DOWN(cpaddr);
-
-        if (!(cpaddr = DkVirtualMemoryAlloc(cpaddr - cpaddr_pgalign,
-                                            cpsize_pgalign,
-                                            0, prot)))
+        if (!(mapaddr = DkVirtualMemoryAlloc(mapaddr, mapsize, 0,
+                                             PAL_PROT_READ|PAL_PROT_WRITE)))
             return -PAL_ERRNO;
 
-        bkeep_mmap(cpaddr, cpsize_pgalign, PROT_READ|PROT_WRITE,
+        bkeep_mmap((void *) mapaddr, mapsize,
+                   PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL,
                    NULL, 0, NULL);
 
-        cpaddr -= cpaddr_pgalign;
-
+        cpaddr = (void *) mapaddr + mapoff;
         for (int total_bytes = 0 ; total_bytes < cpsize ; ) {
             int bytes = DkStreamRead(PAL_CB(parent_process), 0,
                                      cpsize - total_bytes,
-                                     cpaddr + total_bytes, NULL, 0);
+                                     (void *) cpaddr + total_bytes, NULL, 0);
 
-            if (bytes == 0)
+            if (!bytes)
                 return -PAL_ERRNO;
 
             total_bytes += bytes;
@@ -917,11 +941,20 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
         SAVE_PROFILE_INTERVAL(child_load_checkpoint_on_pipe);
     }
 
-    void * cpdata = cpaddr + hdr->data.cpoffset;
-    int nreceived __attribute__((unused)) = 0;
+    struct newproc_response res;
+    res.child_vmid = cur_process.vmid;
+    res.failure = 0;
+    int bytes = DkStreamWrite(PAL_CB(parent_process), 0,
+                              sizeof(struct newproc_response),
+                              &res, NULL);
+    if (!bytes)
+        return -PAL_ERRNO;
+
+    void * cpdata = (void *) cpaddr + hdr->data.cpoffset;
+    struct shim_cp_entry * cpent;
+    unsigned long nreceived __attribute__((unused)) = 0;
 
-    for (struct shim_cp_entry * cpent = (void *) cpdata ;
-         cpent->cp_type != CP_NULL ; cpent++)
+    for (cpent = cpdata ; cpent->cp_type != CP_NULL ; cpent++)
         if (cpent->cp_type == CP_PALHDL &&
             cpent->cp_un.cp_val) {
             PAL_HANDLE hdl = DkReceiveHandle(PAL_CB(parent_process));
@@ -933,11 +966,10 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr)
 
     SAVE_PROFILE_INTERVAL(child_receive_handles);
 
-    debug("received %d handles\n", nreceived);
-
-    migrated_memory_start = cpaddr;
-    migrated_memory_end = cpaddr + hdr->data.cpsize;
+    debug("received %ld handles\n", nreceived);
 
+    migrated_memory_start = (void *) cpaddr;
+    migrated_memory_end = (void *) cpaddr + hdr->data.cpsize;
     *cpptr = (void *) cpdata;
     return 0;
 }

+ 3 - 3
LibOS/shim/src/shim_debug.c

@@ -121,11 +121,10 @@ MIGRATE_FUNC_BODY(gdb_map)
     struct gdb_link_map *newm = NULL;
 
     while (m) {
-        ADD_OFFSET(sizeof(struct gdb_link_map));
-        ADD_FUNC_ENTRY(*offset);
+        unsigned long off = ADD_OFFSET(sizeof(struct gdb_link_map));
 
         if (!dry) {
-            newm = (struct gdb_link_map *) (base + *offset);
+            newm = (struct gdb_link_map *) (base + off);
             memcpy(newm, m, sizeof(struct gdb_link_map));
             newm->l_prev = newm->l_next = NULL;
         }
@@ -137,6 +136,7 @@ MIGRATE_FUNC_BODY(gdb_map)
             memcpy(newm->l_name, m->l_name, strlen(m->l_name) + 1);
         }
 
+        ADD_FUNC_ENTRY(off);
         m = m->l_next;
     }
 }

+ 44 - 27
LibOS/shim/src/shim_init.c

@@ -154,7 +154,7 @@ void allocate_tls (void * tcb_location, struct shim_thread * thread)
         tcb->shim_tcb.tid = 0;
     }
 
-    DkThreadPrivate(tcb);
+    DkSegmentRegister(PAL_SEGMENT_FS, tcb);
     assert(SHIM_TLS_CHECK_CANARY());
 }
 
@@ -171,7 +171,7 @@ void populate_tls (void * tcb_location, bool user)
         thread->user_tcb = user;
     }
 
-    DkThreadPrivate(tcb);
+    DkSegmentRegister(PAL_SEGMENT_FS, tcb);
     assert(SHIM_TLS_CHECK_CANARY());
 }
 
@@ -192,8 +192,8 @@ void * allocate_stack (size_t size, size_t protect_size, bool user)
                    NULL;
 
     if (user)
-        stack = DkVirtualMemoryAlloc(stack, size + protect_size,
-                                     0, PAL_PROT_READ|PAL_PROT_WRITE);
+        stack = (void *) DkVirtualMemoryAlloc(stack, size + protect_size,
+                                0, PAL_PROT_READ|PAL_PROT_WRITE);
     else
         stack = system_malloc(size + protect_size);
 
@@ -398,8 +398,8 @@ int init_manifest (PAL_HANDLE manifest_handle)
     if (!DkStreamAttributesQuerybyHandle(manifest_handle, &attr))
         return -PAL_ERRNO;
 
-    size_t cfg_size = attr.size;
-    void * cfg_addr = DkStreamMap(manifest_handle, NULL,
+    size_t cfg_size = attr.pending_size;
+    void * cfg_addr = (void *) DkStreamMap(manifest_handle, NULL,
                                   PAL_PROT_READ|PAL_PROT_WRITECOPY, 0,
                                   ALIGN_UP(cfg_size));
 
@@ -540,8 +540,18 @@ static int init_newproc (struct newproc_header * hdr)
     return hdr->failure;
 }
 
+DEFINE_PROFILE_CATAGORY(pal, );
+DEFINE_PROFILE_INTERVAL(pal_startup_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_host_specific_startup_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_relocation_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_linking_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_manifest_loading_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_allocation_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_tail_startup_time, pal);
+DEFINE_PROFILE_INTERVAL(pal_child_creation_time, pal);
+
 DEFINE_PROFILE_CATAGORY(init, );
-DEFINE_PROFILE_INTERVAL(init_signal, init);
+DEFINE_PROFILE_INTERVAL(init_randgen, init);
 DEFINE_PROFILE_INTERVAL(init_heap, init);
 DEFINE_PROFILE_INTERVAL(init_slab, init);
 DEFINE_PROFILE_INTERVAL(init_str_mgr, init);
@@ -549,15 +559,14 @@ DEFINE_PROFILE_INTERVAL(init_internal_map, init);
 DEFINE_PROFILE_INTERVAL(init_vma, init);
 DEFINE_PROFILE_INTERVAL(init_fs, init);
 DEFINE_PROFILE_INTERVAL(init_handle, init);
-DEFINE_PROFILE_INTERVAL(init_randgen, init);
 DEFINE_PROFILE_INTERVAL(read_from_checkpoint, init);
 DEFINE_PROFILE_INTERVAL(read_from_file, init);
 DEFINE_PROFILE_INTERVAL(init_newproc, init);
-DEFINE_PROFILE_INTERVAL(init_checkpoint, init);
+DEFINE_PROFILE_INTERVAL(do_migration, init);
 DEFINE_PROFILE_INTERVAL(init_mount_root, init);
-DEFINE_PROFILE_INTERVAL(restore_from_checkpoint, init);
+DEFINE_PROFILE_INTERVAL(init_from_checkpoint_file, init);
 DEFINE_PROFILE_INTERVAL(restore_from_file, init);
-DEFINE_PROFILE_INTERVAL(restore_from_stack, init);
+DEFINE_PROFILE_INTERVAL(restore_checkpoint, init);
 DEFINE_PROFILE_INTERVAL(init_manifest, init);
 DEFINE_PROFILE_INTERVAL(init_ipc, init);
 DEFINE_PROFILE_INTERVAL(init_thread, init);
@@ -568,6 +577,7 @@ DEFINE_PROFILE_INTERVAL(init_stack, init);
 DEFINE_PROFILE_INTERVAL(read_environs, init);
 DEFINE_PROFILE_INTERVAL(init_loader, init);
 DEFINE_PROFILE_INTERVAL(init_ipc_helper, init);
+DEFINE_PROFILE_INTERVAL(init_signal, init);
 
 #define CALL_INIT(func, args ...)   func(args)
 
@@ -575,8 +585,8 @@ DEFINE_PROFILE_INTERVAL(init_ipc_helper, init);
     do {                                                                \
         int _err = CALL_INIT(func, ##__VA_ARGS__);                      \
         if (_err < 0) {                                                 \
-            sys_printf("shim initialization failed in " #func " (%e)",  \
-                       -_err);                                          \
+            sys_printf("shim initialization failed in " #func " (%d)",  \
+                       _err);                                           \
             shim_terminate();                                           \
         }                                                               \
         SAVE_PROFILE_INTERVAL(func);                                    \
@@ -587,6 +597,7 @@ extern PAL_HANDLE thread_start_event;
 int shim_init (int argc, void * args, void ** return_stack)
 {
     debug_handle = PAL_CB(debug_stream);
+    cur_process.vmid = (IDTYPE) PAL_CB(process_id);
 
     /* create the initial TCB, shim can not be run without a tcb */
     __libc_tcb_t tcb;
@@ -627,7 +638,7 @@ int shim_init (int argc, void * args, void ** return_stack)
 #endif
 
     BEGIN_PROFILE_INTERVAL();
-    RUN_INIT(init_signal);
+    RUN_INIT(init_randgen);
     RUN_INIT(init_heap);
     RUN_INIT(init_slab);
     RUN_INIT(init_str_mgr);
@@ -635,7 +646,6 @@ int shim_init (int argc, void * args, void ** return_stack)
     RUN_INIT(init_vma);
     RUN_INIT(init_fs);
     RUN_INIT(init_handle);
-    RUN_INIT(init_randgen);
 
     debug("shim loaded at %p, ready to initialize\n", &__load_address);
 
@@ -645,19 +655,10 @@ int shim_init (int argc, void * args, void ** return_stack)
             argc -= 2;
             argv += 2;
             RUN_INIT(init_mount_root);
-            RUN_INIT(restore_from_checkpoint, filename, &hdr.checkpoint,
+            RUN_INIT(init_from_checkpoint_file, filename, &hdr.checkpoint,
                      &cpaddr);
             goto restore;
         }
-
-        if (!memcmp(argv[0], "-resume-file", 13) && argc >= 2) {
-            const char * filename = *(argv + 1);
-            argc -= 2;
-            argv += 2;
-            RUN_INIT(init_mount_root);
-            RUN_INIT(restore_from_file, filename, &hdr.checkpoint, &cpaddr);
-            goto restore;
-        }
     }
 
     if (PAL_CB(parent_process)) {
@@ -669,13 +670,13 @@ int shim_init (int argc, void * args, void ** return_stack)
 #endif
 
         if (hdr.checkpoint.data.cpsize)
-            RUN_INIT(init_checkpoint, &hdr.checkpoint, &cpaddr);
+            RUN_INIT(do_migration, &hdr.checkpoint, &cpaddr);
     }
 
     if (cpaddr) {
 restore:
         thread_start_event = DkNotificationEventCreate(0);
-        RUN_INIT(restore_from_stack, cpaddr, &hdr.checkpoint.data, 0);
+        RUN_INIT(restore_checkpoint, cpaddr, &hdr.checkpoint.data, 0);
     }
 
     if (PAL_CB(manifest_handle))
@@ -691,6 +692,7 @@ restore:
     RUN_INIT(read_environs, envp);
     RUN_INIT(init_loader);
     RUN_INIT(init_ipc_helper);
+    RUN_INIT(init_signal);
 
     debug("shim process initialized\n");
 
@@ -700,6 +702,21 @@ restore:
                                     begin_create_time);
 #endif
 
+    SAVE_PROFILE_INTERVAL_SET(pal_startup_time, 0, pal_control.startup_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_host_specific_startup_time, 0,
+                              pal_control.host_specific_startup_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_relocation_time, 0,
+                              pal_control.relocation_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_linking_time, 0, pal_control.linking_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_manifest_loading_time, 0,
+                              pal_control.manifest_loading_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_allocation_time, 0,
+                              pal_control.allocation_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_tail_startup_time, 0,
+                              pal_control.tail_startup_time);
+    SAVE_PROFILE_INTERVAL_SET(pal_child_creation_time, 0,
+                              pal_control.child_creation_time);
+
     if (thread_start_event)
         DkEventSet(thread_start_event);
 

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

@@ -43,6 +43,7 @@ static LOCKTYPE slab_mgr_lock;
 #endif
 
 #define SLAB_CANARY
+#define STARTUP_SIZE    4
 
 #include <slabmgr.h>
 
@@ -94,8 +95,8 @@ static struct shim_heap * __alloc_enough_heap (size_t size)
         while (size > heap_size)
             heap_size *= 2;
 
-        if (!(start = DkVirtualMemoryAlloc(NULL, heap_size, 0,
-                                           PAL_PROT_WRITE|PAL_PROT_READ)))
+        if (!(start = (void *) DkVirtualMemoryAlloc(NULL, heap_size, 0,
+                                    PAL_PROT_WRITE|PAL_PROT_READ)))
             return NULL;
 
         debug("allocate internal heap at %p - %p\n", start, start + heap_size);
@@ -150,8 +151,8 @@ int init_heap (void)
 {
     create_lock(shim_heap_lock);
 
-    void * start = DkVirtualMemoryAlloc(NULL, INIT_SHIM_HEAP, 0,
-                                        PAL_PROT_WRITE|PAL_PROT_READ);
+    void * start = (void *) DkVirtualMemoryAlloc(NULL, INIT_SHIM_HEAP, 0,
+                                    PAL_PROT_WRITE|PAL_PROT_READ);
     if (!start)
         return -ENOMEM;
 

+ 2 - 2
LibOS/shim/src/shim_parser.c

@@ -544,12 +544,12 @@ void parse_syscall_after (int sysno, const char * name, int nr, ...)
         if (ret_ptr < -4095L)
             PRINTF(") = %p\n", ret_ptr);
         else
-            PRINTF(") = %ld (%e)\n", (long) ret_ptr, -ret_ptr);
+            PRINTF(") = %ld\n", (long) ret_ptr);
     } else {
         if (ret_val >= 0)
             PRINTF(") = %d\n", ret_val);
         else
-            PRINTF(") = %d (%e)\n", ret_val, ret_val);
+            PRINTF(") = %d\n", ret_val);
     }
 
     va_end (ap);

+ 2 - 1
LibOS/shim/src/shim_syscalls.c

@@ -676,7 +676,8 @@ void * shim_do_arch_prctl (int code, void * addr)
             return NULL;
 
         case ARCH_GET_FS:
-            return DkThreadPrivate(NULL) ? : (void *) -PAL_ERRNO;
+            return (void *) DkSegmentRegister(PAL_SEGMENT_FS, NULL) ? :
+                   (void *) -PAL_ERRNO;
     }
 
     return (void *) -ENOSYS;

+ 5 - 6
LibOS/shim/src/sys/shim_brk.c

@@ -78,8 +78,8 @@ int init_brk_region (void)
     void * end_brk_region = NULL;
 
     // brk region assigned
-    brk_region = DkVirtualMemoryAlloc(brk_region, brk_max_size,
-                                      0, PAL_PROT_READ|PAL_PROT_WRITE);
+    brk_region = (void *) DkVirtualMemoryAlloc(brk_region, brk_max_size, 0,
+                                    PAL_PROT_READ|PAL_PROT_WRITE);
     if (!brk_region)
         return -ENOMEM;
 
@@ -196,10 +196,9 @@ RESUME_FUNC_BODY(brk)
     unsigned long brk_size = region.brk_end - region.brk_start;
 
     if (brk_size < brk_max_size) {
-        void * brk_region = DkVirtualMemoryAlloc(region.brk_end,
-                                                 brk_max_size - brk_size,
-                                                 0,
-                                                 PAL_PROT_READ|PAL_PROT_WRITE);
+        void * brk_region = (void *) DkVirtualMemoryAlloc(region.brk_end,
+                                            brk_max_size - brk_size, 0,
+                                            PAL_PROT_READ|PAL_PROT_WRITE);
         if (brk_region != region.brk_end)
             return -EACCES;
 

+ 5 - 8
LibOS/shim/src/sys/shim_exec.c

@@ -152,11 +152,12 @@ static void * __malloc (size_t size)
     size = ALIGN_UP(size);
     void * addr = get_unmapped_vma(size, flags);
 
-    addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
-
-    if (addr)
-        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
+    addr = (void *)
+        DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
+    if (!addr)
+        return NULL;
 
+    bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
     return addr;
 }
 
@@ -281,10 +282,6 @@ err:
 
     INC_PROFILE_OCCURENCE(syscall_use_ipc);
 
-#ifdef PROFILE
-    unsigned long create_time = GET_PROFILE_INTERVAL();
-#endif
-
     size_t envsize = allocsize;
     void * envptr = NULL;
     const char ** empty_argv = NULL;

+ 7 - 8
LibOS/shim/src/sys/shim_exit.c

@@ -47,6 +47,11 @@ void release_clear_child_id (int * clear_child_tid);
 
 int thread_exit(struct shim_thread * self, bool send_ipc)
 {
+    /* Chia-Che: Broadcast exit message as early as possible,
+       so other process can start early on responding. */
+    if (self->in_vm && send_ipc)
+        ipc_cld_exit_send(self->tid, self->exit_code);
+
     lock(self->lock);
 
     if (!self->is_alive) {
@@ -62,12 +67,10 @@ out:
         goto out;
 
     struct shim_handle_map * handle_map = self->handle_map;
-    self->handle_map = NULL;
-
     struct shim_handle * exec = self->exec;
-    self->exec = NULL;
-
     struct shim_thread * parent = self->parent;
+    self->handle_map = NULL;
+    self->exec = NULL;
 
     if (parent) {
         assert(parent != self);
@@ -113,10 +116,6 @@ out:
         release_clear_child_id (self->clear_child_tid);
 
     DkEventSet(self->exit_event);
-
-    if (self->in_vm && send_ipc)
-        ipc_cld_exit_send(self->tid, exit_code);
-
     return 0;
 }
 

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

@@ -44,11 +44,12 @@ static void * __malloc (size_t size)
     size = ALIGN_UP(size);
     void * addr = get_unmapped_vma(size, flags);
 
-    addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
-
-    if (addr)
-        bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
+    addr = (void *)
+        DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE);
+    if (!addr)
+        return NULL;
 
+    bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL);
     return addr;
 }
 

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

@@ -411,7 +411,7 @@ int shim_do_ioctl (int fd, int cmd, unsigned long arg)
                     ret = -PAL_ERRNO;
                     break;
                 }
-                size = attr.size;
+                size = attr.pending_size;
                 goto done_fioread;
             }
 

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

@@ -188,7 +188,7 @@ int join_checkpoint (struct shim_thread * cur, ucontext_t * context)
 
     ret = finish_checkpoint();
     if (ret < 0)
-        debug("failed creating checkpoint: %e\n", -ret);
+        debug("failed creating checkpoint\n");
     else
         debug("finish checkpointing, time to wake up all threads\n");
 

+ 2 - 6
LibOS/shim/src/sys/shim_mmap.c

@@ -47,7 +47,6 @@ void * shim_do_mmap (void * addr, size_t length, int prot, int flags, int fd,
     assert(!(flags & (VMA_UNMAPPED|VMA_TAINTED)));
 
     int pal_alloc_type = ((flags & MAP_32BIT) ? PAL_ALLOC_32BIT : 0);
-    int pal_prot = prot;
 
     addr = addr ? : get_unmapped_vma(ALIGN_UP(length), flags);
 
@@ -58,8 +57,8 @@ void * shim_do_mmap (void * addr, size_t length, int prot, int flags, int fd,
     length = mapped_end - mapped;
 
     if (flags & MAP_ANONYMOUS) {
-        addr = DkVirtualMemoryAlloc(addr, length, pal_alloc_type,
-                                    pal_prot);
+        addr = (void *) DkVirtualMemoryAlloc(addr, length, pal_alloc_type,
+                                             PAL_PROT(prot, 0));
 
         if (!addr)
             return (void *) -PAL_ERRNO;
@@ -78,9 +77,6 @@ void * shim_do_mmap (void * addr, size_t length, int prot, int flags, int fd,
             return (void *) -ENODEV;
         }
 
-        if (flags & MAP_PRIVATE)
-            prot |= PAL_PROT_WRITECOPY;
-
         if ((ret = hdl->fs->fs_ops->mmap(hdl, &addr, length, prot,
                                          flags, offset)) < 0) {
             put_handle(hdl);

+ 5 - 4
LibOS/shim/src/sys/shim_msgget.c

@@ -787,8 +787,9 @@ static int __store_msg_persist (struct shim_msg_handle * msgq)
     if (DkStreamSetLength(file, expected_size) != expected_size)
         goto err_file;
 
-    void * mem = DkStreamMap(file, NULL, PAL_PROT_READ|PAL_PROT_WRITE,
-                             0, ALIGN_UP(expected_size));
+    void * mem = (void *) DkStreamMap(file, NULL,
+                                      PAL_PROT_READ|PAL_PROT_WRITE,
+                                      0, ALIGN_UP(expected_size));
     if (!mem) {
         ret = -EFAULT;
         goto err_file;
@@ -881,8 +882,8 @@ static int __load_msg_persist (struct shim_msg_handle * msgq, bool readmsg)
                         sizeof(struct msg_backup) * mback.nmsgs +
                         mback.currentsize;
 
-    void * mem = DkStreamMap(file, NULL, PAL_PROT_READ,
-                             0, ALIGN_UP(expected_size));
+    void * mem = (void *) DkStreamMap(file, NULL, PAL_PROT_READ, 0,
+                                      ALIGN_UP(expected_size));
 
     if (!mem) {
         ret = -PAL_ERRNO;

+ 3 - 3
LibOS/shim/src/sys/shim_pipe.c

@@ -44,20 +44,20 @@ int create_pipes (IDTYPE * pipeid, PAL_HANDLE * srv, PAL_HANDLE * cli,
 
     if ((ret = create_pipe(pipeid, uri, PIPE_URI_SIZE, &hdl0,
                            qstr)) < 0) {
-        debug("pipe creation failure: %e\n", -ret);
+        debug("pipe creation failure\n");
         return ret;
     }
 
     if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0,
                               flags & O_NONBLOCK))) {
         ret = -PAL_ERRNO;
-        debug("pipe connection failure: %e\n", -ret);
+        debug("pipe connection failure\n");
         goto err;
     }
 
     if (!(hdl1 = DkStreamWaitForClient(hdl0))) {
         ret = -PAL_ERRNO;
-        debug("pipe acception failure: %e\n", -ret);
+        debug("pipe acception failure\n");
         goto err;
     }
 

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

@@ -300,7 +300,7 @@ struct cfg_arg {
     int offset;
 };
 
-static size_t __write (void * f, void * buf, size_t len)
+static int __write (void * f, void * buf, int len)
 {
     struct cfg_arg * arg = f;
 

+ 47 - 52
LibOS/shim/src/sys/shim_socket.c

@@ -569,7 +569,7 @@ static int inet_parse_addr (int domain, int type, const char * uri,
             char ip_buf[20];
             memcpy(ip_buf, ip_str, ip_len);
             ip_buf[ip_len] = 0;
-            inet_pton(AF_INET, ip_buf, &addr->addr.v4);
+            inet_pton4(ip_buf, &addr->addr.v4);
             addr->ext_port = atoi(port_str);
         }
 
@@ -577,7 +577,7 @@ static int inet_parse_addr (int domain, int type, const char * uri,
             char ip_buf[48];
             memcpy(ip_buf, ip_str, ip_len);
             ip_buf[ip_len] = 0;
-            inet_pton(AF_INET6, ip_str, &addr->addr.v6);
+            inet_pton6(ip_str, &addr->addr.v6);
             addr->ext_port = atoi(port_str);
         }
     }
@@ -1392,65 +1392,60 @@ query:
     if (level == SOL_SOCKET) {
         switch(optname) {
             case SO_KEEPALIVE:
-                if (bolval != attr->tcp_keepalive) {
-                    attr->tcp_keepalive = bolval;
+                if (bolval != attr->socket.tcp_keepalive) {
+                    attr->socket.tcp_keepalive = bolval;
                     goto set;
                 }
                 break;
             case SO_LINGER: {
-                                struct __kernel_linger * l =
-                                    (struct __kernel_linger *) optval;
-                                int linger = l->l_onoff ? l->l_linger : 0;
-                                if (linger != (int) attr->linger) {
-                                    attr->linger = linger;
-                                    goto set;
-                                }
-                                break;
-                            }
+                struct __kernel_linger * l = (struct __kernel_linger *) optval;
+                int linger = l->l_onoff ? l->l_linger : 0;
+                if (linger != (int) attr->socket.linger) {
+                    attr->socket.linger = linger;
+                    goto set;
+                }
+                break;
+            }
             case SO_RCVBUF:
-                            if (intval != (int) attr->receivebuf) {
-                                attr->receivebuf = intval;
-                                goto set;
-                            }
-                            break;
+                if (intval != (int) attr->socket.receivebuf) {
+                    attr->socket.receivebuf = intval;
+                    goto set;
+                }
+                break;
             case SO_SNDBUF:
-                            if (intval != (int) attr->sendbuf) {
-                                attr->sendbuf = intval;
-                                goto set;
-                            }
-                            break;
+                if (intval != (int) attr->socket.sendbuf) {
+                    attr->socket.sendbuf = intval;
+                    goto set;
+                }
+                break;
             case SO_RCVTIMEO:
-                            if (intval != (int) attr->receivetimeout) {
-                                attr->receivetimeout = intval;
-                                goto set;
-                            }
-                            break;
+                if (intval != (int) attr->socket.receivetimeout) {
+                    attr->socket.receivetimeout = intval;
+                    goto set;
+                }
+                break;
             case SO_SNDTIMEO:
-                            if (intval != (int) attr->sendtimeout) {
-                                attr->sendtimeout = intval;
-                                goto set;
-                            }
-                            break;
+                if (intval != (int) attr->socket.sendtimeout) {
+                    attr->socket.sendtimeout = intval;
+                    goto set;
+                }
+                break;
             case SO_REUSEADDR:
-                            if (bolval != attr->reuseaddr) {
-                                attr->reuseaddr = bolval;
-                                goto set;
-                            }
-                            break;
+                break;
         }
     }
 
     if (level == SOL_TCP) {
         switch(optname) {
             case TCP_CORK:
-                if (bolval != attr->tcp_cork) {
-                    attr->tcp_cork = bolval;
+                if (bolval != attr->socket.tcp_cork) {
+                    attr->socket.tcp_cork = bolval;
                     goto set;
                 }
                 break;
             case TCP_NODELAY:
-                if (bolval != attr->tcp_nodelay) {
-                    attr->tcp_nodelay = bolval;
+                if (bolval != attr->socket.tcp_nodelay) {
+                    attr->socket.tcp_nodelay = bolval;
                     goto set;
                 }
                 break;
@@ -1634,29 +1629,29 @@ query:
         if (level == SOL_SOCKET) {
             switch(optname) {
                 case SO_KEEPALIVE:
-                    *intval = attr.tcp_keepalive ? 1 : 0;
+                    *intval = attr.socket.tcp_keepalive ? 1 : 0;
                     break;
                 case SO_LINGER: {
                     struct __kernel_linger * l =
                             (struct __kernel_linger *) optval;
-                    l->l_onoff = attr.linger ? 1 : 0;
-                    l->l_linger = attr.linger;
+                    l->l_onoff = attr.socket.linger ? 1 : 0;
+                    l->l_linger = attr.socket.linger;
                     break;
                 }
                 case SO_RCVBUF:
-                    *intval = attr.receivebuf;
+                    *intval = attr.socket.receivebuf;
                     break;
                 case SO_SNDBUF:
-                    *intval = attr.sendbuf;
+                    *intval = attr.socket.sendbuf;
                     break;
                 case SO_RCVTIMEO:
-                    *intval = attr.receivetimeout;
+                    *intval = attr.socket.receivetimeout;
                     break;
                 case SO_SNDTIMEO:
-                    *intval = attr.sendtimeout;
+                    *intval = attr.socket.sendtimeout;
                     break;
                 case SO_REUSEADDR:
-                    *intval = attr.reuseaddr ? 1 : 0;
+                    *intval = 1;
                     break;
             }
         }
@@ -1664,10 +1659,10 @@ query:
         if (level == SOL_TCP) {
             switch(optname) {
                 case TCP_CORK:
-                    *intval = attr.tcp_cork ? 1 : 0;
+                    *intval = attr.socket.tcp_cork ? 1 : 0;
                     break;
                 case TCP_NODELAY:
-                    *intval = attr.tcp_nodelay ? 1 : 0;
+                    *intval = attr.socket.tcp_nodelay ? 1 : 0;
                     break;
             }
         }

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

@@ -70,7 +70,7 @@ int shim_do_vfork (void)
     void * dummy_stack = system_malloc(stack_size);
 
     if (!dummy_stack) {
-        debug("creation of stack failed: %e\n", PAL_ERRNO);
+        debug("creation of stack failed\n");
         put_thread(new_thread);
         return -PAL_ERRNO;
     }

+ 2 - 2
LibOS/shim/src/syscallas.S

@@ -61,9 +61,9 @@ isdef:
         pushq %r15
 
         movq %rax, %fs:(SHIM_TCB_OFFSET + 24)
-        leaq 224(%rsp), %rax
+        leaq 232(%rsp), %rax
         movq %rax, %fs:(SHIM_TCB_OFFSET + 32)
-        movq (%rax), %rax
+        movq -8(%rax), %rax
         movq %rax, %fs:(SHIM_TCB_OFFSET + 40)
         movq %rsp, %fs:(SHIM_TCB_OFFSET + 48)
 

+ 0 - 49
LibOS/shim/src/utils/printf.c

@@ -174,52 +174,3 @@ void handle_printf (PAL_HANDLE hdl, const char * fmt, ...)
     sys_vfprintf(hdl, fmt, ap);
     va_end(ap);
 }
-
-struct sprintbuf {
-    char *buf;
-    char *ebuf;
-    int cnt;
-};
-
-static void
-sprintputch(void * f, int ch, struct sprintbuf * b)
-{
-    b->cnt++;
-    if (b->buf < b->ebuf)
-        *b->buf++ = ch;
-}
-
-int snprintfmt(char * buf, size_t n, const char * fmt, va_list ap)
-{
-    struct sprintbuf b = {buf, buf + n - 1, 0};
-
-    if (buf == NULL || n < 1)
-        return -1;
-
-    vfprintfmt((void *) sprintputch, NULL, &b, fmt, ap);
-    // null terminate the buffer
-    *b.buf = '\0';
-
-    return b.cnt;
-}
-
-int
-snprintf(char * buf, size_t n, const char * fmt, ...)
-{
-    va_list ap;
-    struct sprintbuf b = {buf, buf + n - 1, 0};
-
-    if (buf == NULL || n < 1)
-        return -1;
-
-    va_start(ap, fmt);
-
-    // print the string to the buffer
-    vfprintfmt((void *) sprintputch, NULL, &b, fmt, ap);
-    // null terminate the buffer
-    *b.buf = '\0';
-
-    va_end(ap);
-
-    return b.cnt;
-}

+ 16 - 21
LibOS/shim/test/Makefile

@@ -1,4 +1,7 @@
-subdirs = inline native apps
+subdirs = inline native benchmark regression apps
+
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
 
 CC = gcc
 CXX = g++
@@ -14,15 +17,12 @@ LDFLAGS-debug = $(LDFLAGS) -L$(level)../src -L$(level)../../../Pal/src \
 libs = $(level)../src/libsysdb_debug.so $(level)../../../Pal/src/libpal.so
 glibc_dir = $(level)../../build
 
-all: $(targets) $(if $(level),,build-subdirs)
+all: $(target) $(if $(level),,build-subdirs)
 
 debug: DEBUG=debug
 debug: CC=gcc -g
 debug: CXX=g++ -g
-debug: $(targets) $(if $(level),,build-subdirs)
-
-$(subdirs): %:
-	cd $@ && make
+debug: $(target) $(if $(level),,build-subdirs)
 
 manifest: manifest.template
 	rm -rf $@
@@ -34,26 +34,21 @@ pal:
 pal_sec:
 	[ ! -f $(level)../../../Pal/src/pal_sec ] || ln -sf $(level)../../../Pal/src/pal_sec pal_sec
 
-# Regression Test
-rtest:	$(rtarget)
-	for d in $(rtarget); \
-	do \
-		make run-$$d || return $$?; \
-	done
-
-.PHONY: test rtest clean
-
-$(patsubst %,run-%,$(rtarget)): run-%: %
-	@echo [ run $< $(value arg-$<) ]
-	@./libpal.so $< $(value arg-$<) > OUTPUT 2> ERROR
-	@$(value test-$<)
-	@rm -rf OUTPUT ERROR
+.PHONY: test clean
 
 clean: $(clean-extra) $(if $(level),,clean-subdirs)
-	rm -rf $(targets)
+	rm -rf $(target)
 
 build-subdirs:
 	for f in $(subdirs); do (cd $$f; make $(DEBUG); cd ..); done
 
+ifeq ($(SYS),x86_64-linux-gnu)
+ifeq ($(level),)
+.PHONY: pack
+pack:
+	for f in $(subdirs); do (cd $$f; make pack; cd ..); done
+endif
+endif
+
 clean-subdirs:
 	for f in $(subdirs); do (cd $$f; make clean; cd ..); done

+ 12 - 2
LibOS/shim/test/apps/Makefile

@@ -1,4 +1,5 @@
 apps = lmbench gcc busybox lighttpd bash apache make
+packed_apps = lmbench
 
 targets = pal pal_sec
 clean-extra = clean-all
@@ -8,10 +9,10 @@ include ../Makefile
 
 manifest_rules = \
 	-e 's:\$$(PAL):$(abspath $(PWD)/../pal_loader):g' \
-	-e 's:\$$(PWD):$(PWD):g' \
+	-e 's:\$$(PWD):$(PWD)/:g' \
 	-e 's:\$$(BIN):$(subst .manifest,,$(notdir $@)):g' \
 	-e 's:\$$(SHIMPATH):$(abspath ../../src/libsysdb.so):g' \
-	-e 's:\$$(GLIBCDIR):$(abspath $(glibc_dir)):g' \
+	-e 's:\$$(GLIBCDIR):$(abspath $(glibc_dir))/:g' \
 	$(extra_rules)
 
 %.manifest: %.manifest.template
@@ -19,8 +20,17 @@ manifest_rules = \
 	sed $(manifest_rules) $< >$@
 	chmod +x $@
 
+ifeq ($(SYS),x86_64-linux-gnu)
 build-all:
 	for f in $(apps); do (cd $$f; make $(DEBUG) || true; cd ..); done
 
+.PHONY: pack
+pack:
+	for f in $(packed_apps); do (cd $$f; make pack; cd ..); done
+else
+build-all:
+	for f in $(packed_apps); do (cd $$f; make || true; cd ..); done
+endif
+
 clean-all:
 	for f in $(apps); do (cd $$f; make clean; cd ..); done

+ 16 - 13
LibOS/shim/test/apps/apache/Makefile

@@ -72,24 +72,27 @@ $(INSTALL_DIR)/modules/mod_auth_basic_sandbox.so: mod_auth_basic_sandbox.c $(INS
 
 
 conf:
-	cd $(INSTALL_DIR)/conf && ([ -f httpd.conf.old ] || mv httpd.conf httpd.conf.old)
-	cd $(INSTALL_DIR)/conf && \
-		sed -e "s/Listen 80/Listen $(HOST):$(PORT)/g" \
-		    -e "s/User daemon/#User root/g" \
-		    -e "s/Group daemon/#Group root/g" \
-		    -e "s/#EnableMMAP off/EnableMMAP off/g" \
-		    -e "s/#EnableSendfile on/EnableSendfile on/g" \
-		    -e "s/DirectoryIndex index.html/DirectoryIndex index.html index.php/g" \
-		    -e "s/^[ ]*CustomLog/#CustomLog/g" \
-		httpd.conf.old > httpd.conf.new
-	cd $(INSTALL_DIR)/conf && \
-		echo "\n\
+	[ -f $(INSTALL_DIR)/conf/httpd.conf.old ] || \
+		mv $(INSTALL_DIR)/conf/httpd.conf $(INSTALL_DIR)/conf/httpd.conf.old
+	sed -e "s/Listen 80/Listen $(HOST):$(PORT)/g" \
+	    -e "s/User daemon/#User root/g" \
+	    -e "s/Group daemon/#Group root/g" \
+	    -e "s/#EnableMMAP off/EnableMMAP off/g" \
+	    -e "s/#EnableSendfile on/EnableSendfile on/g" \
+	    -e "s/DirectoryIndex index.html/DirectoryIndex index.html index.php/g" \
+	    -e "s/^[ ]*CustomLog/#CustomLog/g" \
+	$(INSTALL_DIR)/conf/httpd.conf.old > $(INSTALL_DIR)/conf/httpd.conf.new
+	echo "\n\
 <IfModule mpm_prefork_module>\n\
     StartServers             4\n\
     MinSpareServers          1\n\
     MaxSpareServers          4\n\
     MaxConnectionsPerChild   0\n\
-</IfModule>\n" >> httpd.conf.new
+</IfModule>\n" >> $(INSTALL_DIR)/conf/httpd.conf.new
+	echo "\n\
+<IfModule mime_module>\n\
+    AddType application/x-httpd-php .php\n\
+</IfModule>\n" >> $(INSTALL_DIR)/conf/httpd.conf.new
 	cd $(INSTALL_DIR)/conf && ln -sf httpd.conf.new httpd.conf
 
 start-native-server:

+ 12 - 10
LibOS/shim/test/apps/gcc/Makefile

@@ -57,10 +57,12 @@ GCC_FLAGS = \
 GCC_MAKE_FLAGS = \
 	LD_LIBRARY_PATH="$(PWD)/obj/lib:/usr/lib:/lib"
 
+export CFLAGS
+export CXXFLAGS="-fpermissive"
 
 obj/bin/gcc: src/gcc-$(GCC_VER) obj/bin/ld $(addprefix obj/lib/,$(GMP_OBJ) $(PPL_OBJ) $(MPFR_OBJ) $(MPC_OBJ))
 	cd $< && ./configure --prefix=$(PWD)/obj $(GCC_FLAGS)
-	$(MAKE) -C $< $(GCC_MAKE_FLAGS) $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $< $(GCC_MAKE_FLAGS)
 	$(MAKE) -C $< install
 
 src/gcc-$(GCC_VER): gcc-$(GCC_VER).tar.bz2 src
@@ -68,43 +70,43 @@ src/gcc-$(GCC_VER): gcc-$(GCC_VER).tar.bz2 src
 
 obj/bin/ld: src/binutils-$(BINUTILS_VER)
 	cd $< && ./configure --prefix=$(PWD)/obj $(GCC_FLAGS)
-	$(MAKE) -C $< $(GCC_MAKE_FLAGS) $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $< $(GCC_MAKE_FLAGS)
 	$(MAKE) -C $< install
 
 src/binutils-$(BINUTILS_VER): binutils-$(BINUTILS_VER).tar.bz2 src
 	cd src && tar -xjf ../$<
 
 obj/lib/$(GMP_OBJ): src/$(GMP_SRC)
-	cd $< && ./configure --prefix=$(PWD)/obj --enable-cxx \
+	cd $< && ./configure --prefix=$(PWD)/obj --enable-shared --enable-cxx \
 	$(LINK_LIBC)
-	$(MAKE) -C $< $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $<
 	$(MAKE) -C $< install
 
 src/$(GMP_SRC): $(GMP_SRC).tar.bz2 src
 	cd src && tar -xjf ../$<
 
 obj/lib/$(PPL_OBJ): src/$(PPL_SRC) obj/lib/$(GMP_OBJ)
-	cd $< && ./configure --prefix=$(PWD)/obj --with-libgmp-prefix=$(PWD)/obj \
+	cd $< && ./configure --prefix=$(PWD)/obj --with-libgmp-prefix=$(PWD)/obj --enable-shared \
 	$(LINK_LIBC)
-	$(MAKE) -C $< $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $<
 	$(MAKE) -C $< install
 
 src/$(PPL_SRC): $(PPL_SRC).tar.gz src
 	cd src && tar -xzf ../$<
 
 obj/lib/$(MPFR_OBJ): src/$(MPFR_SRC) obj/lib/$(GMP_OBJ)
-	cd $< && ./configure --prefix=$(PWD)/obj \
+	cd $< && ./configure --prefix=$(PWD)/obj --enable-shared \
 	$(LINK_LIBC)
-	$(MAKE) -C $< $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $<
 	$(MAKE) -C $< install
 
 src/$(MPFR_SRC): $(MPFR_SRC).tar.bz2 src
 	cd src && tar -xjf ../$<
 
 obj/lib/$(MPC_OBJ): src/$(MPC_SRC)
-	cd $< && ./configure --prefix=$(PWD)/obj --with-gmp=$(PWD)/obj \
+	cd $< && ./configure --prefix=$(PWD)/obj --with-gmp=$(PWD)/obj --enable-shared \
 	$(LINK_LIBC)
-	$(MAKE) -C $< $(if $(CFLAGS),CFLAGS="$(CFLAGS)",)
+	$(MAKE) -C $<
 	$(MAKE) -C $< install
 
 src/$(MPC_SRC): $(MPC_SRC).tar.gz src

BIN
LibOS/shim/test/apps/lmbench/.packed/lmbench.tar.gz


+ 20 - 2
LibOS/shim/test/apps/lmbench/Makefile

@@ -1,3 +1,6 @@
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
+
 LMBENCHDIR = lmbench-2.5
 LMBENCHMANIFEST = manifest-list
 
@@ -18,7 +21,7 @@ servers = lat_udp lat_tcp lat_rpc lat_connect bw_tcp
 	make -C .. lmbench/$@ appdir=lmbench/
 	echo $(if $(findstring $(notdir $(basename $@)),$(servers)),"loader.daemonize = 1") >> $@
 
-
+ifeq ($(SYS),x86_64-linux-gnu)
 $(LMBENCHDIR)/bin/linux: $(wildcard $(LMBENCHDIR)/src/*.c) $(wildcard $(LMBENCHDIR)/src/*.h)
 	make -C $(LMBENCHDIR)/src OS=linux CC="gcc -g"
 
@@ -33,6 +36,21 @@ manifest-list: $(LMBENCHDIR)/bin/linux
 	for f in `cat manifest-list`; do f=$${f%.manifest.template}; \
 		ln -sf $${f##*/}.manifest $$f ; done
 
+.PHONY: pack
+pack: $(LMBENCHDIR)/bin/linux manifest-list
+	tar -czf .packed/lmbench.tar.gz $^
+else
+$(LMBENCHDIR)/bin/linux manifest-list: .packed/lmbench.tar.gz
+	tar -xmozf $<
+	mkdir -p $(LMBENCHDIR)/bin/graphene
+	cp -n $(LMBENCHDIR)/bin/linux/* $(LMBENCHDIR)/bin/graphene
+	for f in `cat manifest-list`; \
+		do ln -sf ../../../manifest.template $$f ; done
+	for f in `cat manifest-list`; do f=$${f%.manifest.template}; \
+		ln -sf $${f##*/}.manifest $$f ; done
+endif
+
+
 config = $(shell $(LMBENCHDIR)/scripts/config)
 
 config-native: $(LMBENCHDIR)/bin/linux
@@ -52,5 +70,5 @@ test-graphene: config-graphene
 	make -C $(LMBENCHDIR) OS=graphene rerun
 
 clean:
-	rm -rf $(LMBENCHMANFIEST)
+	rm -rf $(LMBENCHMANFIEST) manifest-list
 	make -C $(LMBENCHDIR) clean

+ 8 - 53
LibOS/shim/test/apps/lmbench/lmbench-2.5/scripts/lmbench

@@ -140,12 +140,11 @@ work lat_sig catch
 work lat_sig prot lat_sig
 
 #AF_UNIX
-echo "***"; echo "AF_UNIX TESTS"
+echo AF_UNIX socket latenct >> ${OUTPUT}
 for i in $(eval echo "{1..$N_RUNS}")
 do
     work lat_unix
 done
-echo "***"; echo "";
 
 #forks
 cp hello /tmp/hello
@@ -163,25 +162,11 @@ date >> ${OUTPUT}
 
 date >> ${OUTPUT}
 
-echo "sleeep for 30" 
-sleep 30
 echo Local networking >> ${OUTPUT}
-#if [ ! -d /tmp/webpage-lm ]
-#then	TAR=${PWD}/../../src/webpage-lm.tar
-#	(cd /tmp && tar xf ${TAR})
-#	sync
-#	sleep 5
-#fi
-#SERVERS="lat_udp lat_tcp lat_rpc lat_connect bw_tcp"
-
-#SERVERS="lat_udp lat_tcp"
-#for server in $SERVERS; do work $server -s; done
-
-#work env DOCROOT=/tmp/webpage-lm lmhttp 8008 &
-#sleep 60
-
-echo ""; echo"UDP TESTS"
-work lat_udp -s
+
+echo UDP socket latency >> ${OUTPUT}
+work lat_udp -s &
+sleep 5
 for i in $(eval echo "{1..$N_RUNS}")
 do
         work lat_udp 127.0.0.1
@@ -189,11 +174,10 @@ do
 done
 work lat_udp -127.0.0.1
 sleep 5
-echo "***"; echo "";
 
-
-echo "***"; echo"TCP TESTS"
-work lat_tcp -s
+echo TCP socket latency >> ${OUTPUT}
+work lat_tcp -s &
+sleep 5
 for i in $(eval echo "{1..$N_RUNS}")
 do
 	work lat_tcp 127.0.0.1
@@ -201,35 +185,6 @@ do
 done
 work lat_tcp -127.0.0.1
 sleep 5
-echo "***"; echo "";
-
-#done for graphene tests
-exit 0
-
-for remote in $REMOTE
-do	echo Networking to $remote >> ${OUTPUT}
-	$RCP $SERVERS lmhttp /tmp/webpage-lm.tar ${remote}:/tmp/rcp/
-	for server in $SERVERS
-	do	$RSH $remote -n /tmp/$server -s &
-	done
-	$RSH $remote -n 'cd /tmp; tar xf webpage-lm.tar; cd webpage-lm; ../lmhttp 8008' &
-	sleep 10
-	echo "[ Networking remote to $remote: `$RSH $remote uname -a` ]" 1>&2
-	work lat_udp $remote; lat_udp -$remote;
-	work lat_tcp $remote; lat_tcp -$remote;
-	#work lat_rpc $remote udp; lat_rpc $remote tcp; lat_rpc -$remote; 
-	work lat_connect $remote; lat_connect -$remote;
-	work bw_tcp $remote; bw_tcp -$remote
-	# I want a hot cache number
-	#work lat_http $remote 8008 < /tmp/webpage-lm/URLS > /dev/null 2>&1
-	#work lat_http $remote 8008 < /tmp/webpage-lm/URLS
-	#work lat_http -$remote 8008
-	RM=
-	for server in $SERVERS
-	do	RM="/tmp/$server $RM"
-	done
-	$RSH $remote rm $RM
-done
 
 exit #exit because we do not need these bandwith tests for the paper 
 date >> ${OUTPUT}

+ 33 - 0
LibOS/shim/test/benchmark/Makefile

@@ -0,0 +1,33 @@
+CFLAGS-libos = -L../../../build/libos -I../../include
+
+c_executables = $(patsubst %.c,%,$(wildcard *.c))
+cxx_executables = $(patsubst %.cpp,%,$(wildcard *.cpp))
+
+target = $(c_executables) $(cxx_executables) \
+	  manifest pal pal_sec
+
+level = ../
+include ../Makefile
+
+%.manifest: %.manifest.template
+	rm -rf $@
+	cp $@.template $@
+
+ifeq ($(SYS),x86_64-linux-gnu)
+$(c_executables): %: %.c
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) $(if $(findstring .libos,$@),$(CFLAGS-libos),) -o $@ $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+$(cxx_executables): %: %.cpp
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) -o $@ $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+.PHONY: pack
+pack: $(c_executables) $(cxx_executables)
+	tar -czf .packed/test.tar.gz $^
+else
+$(c_executables) $(cxx_executables): .packed/test.tar.gz
+	tar -xmozf $<
+endif

+ 0 - 0
LibOS/shim/test/native/fork_latency.c → LibOS/shim/test/benchmark/fork_latency.c


+ 22 - 0
LibOS/shim/test/benchmark/manifest.template

@@ -0,0 +1,22 @@
+loader.preload = file:../../src/libsysdb.so
+loader.env.LD_LIBRARY_PATH = /lib
+loader.debug_type = none
+loader.syscall_symbol = syscalldb
+
+fs.mount.root.type = chroot
+fs.mount.root.uri = file:
+
+fs.mount.other.lib.type = chroot
+fs.mount.other.lib.path = /lib
+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
+net.rules.1 = 127.0.0.1:8000:0.0.0.0:0-65535
+# allow to connect to port 8000
+net.rules.2 = 0.0.0.0:0-65535:127.0.0.1:8000
+
+# sys.ask_for_checkpoint = 1

+ 0 - 0
LibOS/shim/test/native/rpc_latency.libos.c → LibOS/shim/test/benchmark/rpc_latency.libos.c


+ 0 - 0
LibOS/shim/test/native/rpc_latency2.libos.c → LibOS/shim/test/benchmark/rpc_latency2.libos.c


+ 0 - 0
LibOS/shim/test/native/sig_latency.c → LibOS/shim/test/benchmark/sig_latency.c


+ 0 - 0
LibOS/shim/test/native/start.c → LibOS/shim/test/benchmark/start.c


+ 0 - 0
LibOS/shim/test/native/test_start.m.c → LibOS/shim/test/benchmark/test_start.m.c


BIN
LibOS/shim/test/inline/.packed/test.tar.gz


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

@@ -1,26 +1,26 @@
-INLINE_TESTS_CPP = $(patsubst %.cpp,%,$(wildcard *.cpp))
-INLINE_TESTS = $(patsubst %.c,%,$(wildcard *.c))
+c_executables = $(patsubst %.c,%,$(wildcard *.c))
+cxx_executables = $(patsubst %.cpp,%,$(wildcard *.cpp))
 
-rtarget = helloworld fork vfork
-targets = $(rtarget) manifest pal pal_sec
-clean-extra = clean-exec
+target = $(c_executables) $(cxx_executables) manifest pal pal_sec
 
 level = ../
 include ../Makefile
 
-$(INLINE_TESTS): %: %.c $(libs)
-	@echo [ $@ ]
-	@$(CC) $(CFLAGS-debug) -nostdlib -nostartfiles -e main $(LDFLAGS-debug) -o $@ $^
+CFLAGS-debug += -fno-builtin -nostdlib
 
-$(INLINE_TESTS_CPP): %: %.cpp $(libs)
+ifeq ($(SYS),x86_64-linux-gnu)
+$(c_executables): %: %.c $(libs) $(level)../../../Pal/src/user_start.o
 	@echo [ $@ ]
-	@$(CXX) $(CFLAGS-debug) -nostdlib -nostartfiles -e main $(LDFLAGS-debug) -o $@ $^
+	@$(CC) $(CFLAGS-debug) $(LDFLAGS-debug) -o $@ $^
 
-test-helloworld = grep -q "Hello world" OUTPUT
-test-printf = grep -q "1 printf printf" OUTPUT
-test-fork = grep -q "Hello, Dad" OUTPUT && grep -q "Hello, Kid" OUTPUT
-test-vfork = grep -q "Hello, Dad" OUTPUT && grep -q "Hello, Kid" OUTPUT
+$(cxx_executables): %: %.cpp $(libs) $(level)../../../Pal/src/user_start.o
+	@echo [ $@ ]
+	@$(CXX) $(CFLAGS-debug) $(LDFLAGS-debug) -o $@ $^
 
-clean-exec:
-	find -type f -executable -exec rm {} \;
-	rm -rf manifest pal pal_sec
+.PHONY: pack
+pack: $(c_executables) $(cxx_executables)
+	tar -czf .packed/test.tar.gz $^
+else
+$(c_executables) $(cxx_executables): .packed/test.tar.gz
+	tar -xmozf $<
+endif

BIN
LibOS/shim/test/native/.packed/test.tar.gz


+ 14 - 25
LibOS/shim/test/native/Makefile

@@ -1,39 +1,26 @@
 CFLAGS-libos = -L../../../build/libos -I../../include
 
-SPECIALS = static pie
-NATIVE_TESTS_CPP = $(patsubst %.cpp,%,$(wildcard *.cpp))
-NATIVE_TESTS = $(patsubst %.c,%,$(wildcard *.c))
+special_executables = static pie
+c_executables = $(filter-out $(special_executables),$(patsubst %.c,%,$(wildcard *.c)))
+cxx_executables = $(patsubst %.cpp,%,$(wildcard *.cpp))
 
-targets = $(NATIVE_TESTS) $(NATIVE_TESTS_CPP) $(NATIVE_TESTS_STATIC) \
+target = $(special_executables) $(c_executables) $(cxx_executables) \
 	  manifest static.manifest pal pal_sec
-rtarget = helloworld clone vfork fork exec vfork_exec errno dup time \
-	  helloworld.pthread udp tcp unix file dev
-clean-extra = clean-exec
 
 level = ../
 include ../Makefile
 
-test-helloworld = grep -q "Hello World" OUTPUT
-test-clone = grep -q "in the child: pid = 2" OUTPUT
-test-vfork = grep -q "Hello, Dad!" OUTPUT
-test-fork = grep -q "Hello, Dad!" OUTPUT
-test-exec = grep -q "Hello World" OUTPUT
-test-file = grep -q "Hello World" OUTPUT && [ ! -f testfile ]
-test-errno = grep -q "errno = 22" OUTPUT
-test-dup = grep -q "Hello World" OUTPUT
-test-time = grep -q "Current timestamp" OUTPUT
-test-helloworld.pthread = grep -q "Hello World" OUTPUT
-
 %.manifest: %.manifest.template
 	rm -rf $@
 	cp $@.template $@
 
-$(filter-out $(SPECIALS),$(NATIVE_TESTS)): %: %.c
+ifeq ($(SYS),x86_64-linux-gnu)
+$(c_executables): %: %.c
 	@echo [ $@ ]
 	@$(CC) $(CFLAGS) $(if $(findstring .libos,$@),$(CFLAGS-libos),) -o $@ $< \
 	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
 
-$(filter-out $(SPECIALS),$(NATIVE_TESTS_CPP)): %: %.cpp
+$(cxx_executables): %: %.cpp
 	@echo [ $@ ]
 	@$(CC) $(CFLAGS) -o $@ $< \
 	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
@@ -48,8 +35,10 @@ pie: %: %.c
 	@$(CC) $(CFLAGS) -fPIC --pie -o $@ $< \
 	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
 
-test-helloworld = grep -q "Hello world" OUTPUT
-
-clean-exec:
-	find -type f -executable -exec rm {} \;
-	rm -rf manifest static.manifest pal pal_sec
+.PHONY: pack
+pack: $(special_executables) $(c_executables) $(cxx_executables)
+	tar -czf .packed/test.tar.gz $^
+else
+$(special_executables) $(c_executables) $(cxx_executables): .packed/test.tar.gz
+	tar -xmozf $<
+endif

+ 0 - 2
LibOS/shim/test/native/brk.c

@@ -1,8 +1,6 @@
 /* -*- 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 <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>

+ 13 - 2
LibOS/shim/test/native/clone.c

@@ -9,18 +9,28 @@
 #include <signal.h>
 #include <sched.h>
 #include <stdio.h>
+#include <sys/syscall.h>
+#include <asm/prctl.h>
 
 // 64kB stack
 #define FIBER_STACK 1024 * 64
 
 __thread int mypid = 0;
 
+unsigned long gettls (void)
+{
+    unsigned long tls;
+    syscall(__NR_arch_prctl, ARCH_GET_FS, &tls);
+    return tls;
+}
+
 int thread_function (void * argument)
 {
     mypid = getpid();
     int * ptr = (int *) argument;
     printf("in the child: pid (%016lx) = %d\n", (unsigned long) &mypid, mypid);
     printf("in the child: pid = %d\n", getpid());
+    printf("in the child: tls = %08lx\n", gettls());
     printf("child thread exiting\n");
     printf("argument passed %d\n", *ptr);
     return 0;
@@ -51,7 +61,7 @@ int main (int argc, const char ** argv)
                 CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM,
                 &varx);
 
-    printf("clone() returned %d\n", pid);
+    printf("clone() creates new thread %d\n", pid);
 
     if (pid == -1) {
         perror("clone");
@@ -59,7 +69,7 @@ int main (int argc, const char ** argv)
     }
 
     // Wait for the child thread to exit
-    pid = waitpid(pid, 0, 0);
+    pid = waitpid(0, NULL, __WALL);
     if (pid == -1) {
         perror("waitpid");
         _exit(3);
@@ -70,6 +80,7 @@ int main (int argc, const char ** argv)
 
     printf("in the parent: pid (%016lx) = %d\n", (unsigned long) &mypid, mypid);
     printf("in the parent: pid = %d\n", getpid());
+    printf("in the parent: tls = %08lx\n", gettls());
 
     return 0;
 }

+ 21 - 28
LibOS/shim/test/native/condvar.pthread.c

@@ -8,8 +8,8 @@
 pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
 
-void * functionCount1();
-void * functionCount2();
+void * function1();
+void * function2();
 int count = 0;
 
 #define COUNT_DONE  10
@@ -20,21 +20,19 @@ int main (int argc, const char ** argv)
 {
    pthread_t thread1, thread2;
 
-   pthread_create( &thread1, NULL, &functionCount1, NULL);
-   pthread_create( &thread2, NULL, &functionCount2, NULL);
+   pthread_create(&thread1, NULL, &function1, NULL);
+   pthread_create(&thread2, NULL, &function2, NULL);
 
-   pthread_join( thread1, NULL);
-   pthread_join( thread2, NULL);
+   pthread_join(thread1, NULL);
+   pthread_join(thread2, NULL);
 
-   printf("Final count: %d\n",count);
-
-   exit(0);
+   printf("Final count: %d\n", count);
+   return 0;
 }
 
-void * functionCount1 (void)
+void * function1 (void)
 {
-   for(;;)
-   {
+   for(;;) {
       // Lock mutex and then wait for signal to relase mutex
       pthread_mutex_lock(&count_mutex);
 
@@ -42,7 +40,7 @@ void * functionCount1 (void)
       // mutex unlocked if condition varialbe in functionCount2() signaled.
       pthread_cond_wait(&condvar, &count_mutex);
       count++;
-      printf("Counter value functionCount1: %d\n", count);
+      printf("Counter value in function1: %d\n", count);
 
       pthread_mutex_unlock(&count_mutex);
 
@@ -51,23 +49,19 @@ void * functionCount1 (void)
    }
 }
 
-void * functionCount2 (void)
+void * function2 (void)
 {
-    for(;;)
-    {
+    for(;;) {
        pthread_mutex_lock(&count_mutex);
 
-       if (count < COUNT_HALT1 || count > COUNT_HALT2)
-       {
-          // Condition of if statement has been met.
-          // Signal to free waiting thread by freeing the mutex.
-          // Note: functionCount1() is now permitted to modify "count".
-          pthread_cond_signal(&condvar);
-       }
-       else
-       {
-          count++;
-          printf("Counter value functionCount2: %d\n", count);
+       if (count < COUNT_HALT1 || count > COUNT_HALT2) {
+            // Condition of if statement has been met.
+            // Signal to free waiting thread by freeing the mutex.
+            // Note: functionCount1() is now permitted to modify "count".
+            pthread_cond_signal(&condvar);
+       } else {
+            count++;
+            printf("Counter value function2: %d\n", count);
        }
 
        pthread_mutex_unlock(&count_mutex);
@@ -75,5 +69,4 @@ void * functionCount2 (void)
        if (count >= COUNT_DONE)
            return NULL;
     }
-
 }

+ 24 - 0
LibOS/shim/test/native/cpuinfo.c

@@ -0,0 +1,24 @@
+/* -*- 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: */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int main (int argc, char ** argv)
+{
+    FILE * cpuinfo = fopen("/proc/cpuinfo", "rb");
+    char * arg = 0;
+    size_t size = 0;
+
+    if (!cpuinfo)
+        return errno;
+
+    while(getdelim(&arg, &size, 0, cpuinfo) != -1)
+        puts(arg);
+
+    free(arg);
+    fclose(cpuinfo);
+    return 0;
+}

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

@@ -24,7 +24,6 @@ int main(int argc, char ** argv)
         exit(1);
     }
 
-
     if ((ret = creat(TESTDIR "/file", 0600)) < 0) {
         perror("open");
         exit(1);

+ 166 - 200
LibOS/shim/test/native/epoll_socket.c

@@ -23,255 +23,221 @@
 static int
 make_socket_non_blocking (int sfd)
 {
-  int flags, s;
+    int flags, s;
 
-  flags = fcntl (sfd, F_GETFL, 0);
-  if (flags == -1)
-    {
-      perror ("fcntl");
-      return -1;
+    flags = fcntl (sfd, F_GETFL, 0);
+    if (flags == -1) {
+        perror ("fcntl");
+        return -1;
     }
 
-  flags |= O_NONBLOCK;
-  s = fcntl (sfd, F_SETFL, flags);
-  if (s == -1)
-    {
-      perror ("fcntl");
-      return -1;
+    flags |= O_NONBLOCK;
+    s = fcntl (sfd, F_SETFL, flags);
+    if (s == -1) {
+        perror ("fcntl");
+        return -1;
     }
 
-  return 0;
+    return 0;
 }
 
 static int
 create_and_bind (char *port)
 {
-  struct addrinfo hints;
-  struct addrinfo *result, *rp;
-  int s, sfd;
-
-  memset (&hints, 0, sizeof (struct addrinfo));
-  hints.ai_family = AF_UNSPEC;     /* Return IPv4 and IPv6 choices */
-  hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
-  hints.ai_flags = AI_PASSIVE;     /* All interfaces */
-
-  s = getaddrinfo (NULL, port, &hints, &result);
-  if (s != 0)
-    {
-      fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
-      return -1;
+    struct addrinfo hints;
+    struct addrinfo *result, *rp;
+    int s, sfd;
+
+    memset (&hints, 0, sizeof (struct addrinfo));
+    hints.ai_family = AF_UNSPEC;     /* Return IPv4 and IPv6 choices */
+    hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
+    hints.ai_flags = AI_PASSIVE;     /* All interfaces */
+
+    s = getaddrinfo (NULL, port, &hints, &result);
+    if (s != 0) {
+        fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
+        return -1;
     }
 
-  for (rp = result; rp != NULL; rp = rp->ai_next)
-    {
-      sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
-      if (sfd == -1)
-        continue;
-
-      s = bind (sfd, rp->ai_addr, rp->ai_addrlen);
-      if (s == 0)
-        {
-          /* We managed to bind successfully! */
-          break;
-        }
+    for (rp = result; rp != NULL; rp = rp->ai_next) {
+        sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+        if (sfd == -1)
+            continue;
+
+        s = bind (sfd, rp->ai_addr, rp->ai_addrlen);
+        if (s == 0)
+            /* We managed to bind successfully! */
+            break;
 
-      close (sfd);
+        close (sfd);
     }
 
-  if (rp == NULL)
-    {
-      fprintf (stderr, "Could not bind\n");
-      return -1;
+    if (rp == NULL) {
+        fprintf (stderr, "Could not bind\n");
+        return -1;
     }
 
-  freeaddrinfo (result);
+    freeaddrinfo (result);
 
-  return sfd;
+    return sfd;
 }
 
-int
-main (int argc, char *argv[])
+int main (int argc, char *argv[])
 {
-  int sfd, s;
-  int efd;
-  struct epoll_event event;
-  struct epoll_event *events;
-
-  if (argc != 2)
-    {
-      fprintf (stderr, "Usage: %s [port]\n", argv[0]);
-      exit (EXIT_FAILURE);
+    int sfd, s;
+    int efd;
+    struct epoll_event event;
+    struct epoll_event *events;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s [port]\n", argv[0]);
+        exit(EXIT_FAILURE);
     }
 
-  sfd = create_and_bind (argv[1]);
-  if (sfd == -1)
-    abort ();
+    sfd = create_and_bind (argv[1]);
+    if (sfd == -1)
+        abort();
 
-  s = make_socket_non_blocking (sfd);
-  if (s == -1)
-    abort ();
+    s = make_socket_non_blocking(sfd);
+    if (s == -1)
+        abort();
 
-  s = listen (sfd, SOMAXCONN);
-  if (s == -1)
-    {
-      perror ("listen");
-      abort ();
+    s = listen(sfd, SOMAXCONN);
+    if (s == -1) {
+        perror("listen");
+        abort();
     }
 
-  efd = epoll_create1 (0);
-  if (efd == -1)
-    {
-      perror ("epoll_create");
-      abort ();
+    efd = epoll_create1(0);
+    if (efd == -1) {
+        perror("epoll_create");
+        abort();
     }
 
-  event.data.fd = sfd;
-  event.events = EPOLLIN | EPOLLET;
-  s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
-  if (s == -1)
-    {
-      perror ("epoll_ctl");
-      abort ();
+    event.data.fd = sfd;
+    event.events = EPOLLIN | EPOLLET;
+    s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event);
+    if (s == -1) {
+        perror("epoll_ctl");
+        abort();
     }
 
-  /* Buffer where events are returned */
-  events = calloc (MAXEVENTS, sizeof event);
-
-  /* The event loop */
-  while (1)
-    {
-      int n, i;
-
-      n = epoll_wait (efd, events, MAXEVENTS, -1);
-      for (i = 0; i < n; i++)
-    {
-      if ((events[i].events & EPOLLERR) ||
-              (events[i].events & EPOLLHUP) ||
-              (!(events[i].events & EPOLLIN)))
-        {
-              /* An error has occured on this fd, or the socket is not
-                 ready for reading (why were we notified then?) */
-          fprintf (stderr, "epoll error\n");
-          close (events[i].data.fd);
-          continue;
-        }
+    /* Buffer where events are returned */
+    events = calloc(MAXEVENTS, sizeof event);
+
+    /* The event loop */
+    while (1) {
+        int n, i;
+
+        n = epoll_wait(efd, events, MAXEVENTS, -1);
+        for (i = 0; i < n; i++) {
+            if ((events[i].events & EPOLLERR) ||
+                (events[i].events & EPOLLHUP) ||
+                (!(events[i].events & EPOLLIN))) {
+                /* An error has occured on this fd, or the socket is not
+                   ready for reading (why were we notified then?) */
+                fprintf(stderr, "epoll error\n");
+                close(events[i].data.fd);
+                continue;
+            }
 
-      else if (sfd == events[i].data.fd)
-        {
-              /* We have a notification on the listening socket, which
-                 means one or more incoming connections. */
-              while (1)
-                {
-                  struct sockaddr in_addr;
-                  socklen_t in_len;
-                  int infd;
-                  char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
-
-                  in_len = sizeof in_addr;
-                  infd = accept (sfd, &in_addr, &in_len);
-                  if (infd == -1)
-                    {
-                      if ((errno == EAGAIN) ||
-                          (errno == EWOULDBLOCK))
-                        {
-                          /* We have processed all incoming
-                             connections. */
-                          break;
-                        }
-                      else
-                        {
-                          perror ("accept");
-                          break;
+            else if (sfd == events[i].data.fd) {
+                /* We have a notification on the listening socket, which
+                   means one or more incoming connections. */
+                while (1) {
+                    struct sockaddr in_addr;
+                    socklen_t in_len;
+                    int infd;
+                    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
+
+                    in_len = sizeof in_addr;
+                    infd = accept (sfd, &in_addr, &in_len);
+                    if (infd == -1) {
+                        if ((errno == EAGAIN) ||
+                            (errno == EWOULDBLOCK)) {
+                            /* We have processed all incoming
+                               connections. */
+                            break;
+                        } else {
+                            perror ("accept");
+                            break;
                         }
                     }
 
-                  s = getnameinfo (&in_addr, in_len,
-                                   hbuf, sizeof hbuf,
-                                   sbuf, sizeof sbuf,
-                                   NI_NUMERICHOST | NI_NUMERICSERV);
-                  if (s == 0)
-                    {
-                      printf("Accepted connection on descriptor %d "
-                             "(host=%s, port=%s)\n", infd, hbuf, sbuf);
-                    }
-
-                  /* Make the incoming socket non-blocking and add it to the
-                     list of fds to monitor. */
-                  s = make_socket_non_blocking (infd);
-                  if (s == -1)
-                    abort ();
-
-                  event.data.fd = infd;
-                  event.events = EPOLLIN | EPOLLET;
-                  s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
-                  if (s == -1)
-                    {
-                      perror ("epoll_ctl");
-                      abort ();
+                    s = getnameinfo(&in_addr, in_len,
+                                    hbuf, sizeof hbuf,
+                                    sbuf, sizeof sbuf,
+                                    NI_NUMERICHOST | NI_NUMERICSERV);
+                    if (s == 0)
+                        printf("Accepted connection on descriptor %d "
+                               "(host=%s, port=%s)\n", infd, hbuf, sbuf);
+
+                    /* Make the incoming socket non-blocking and add it to the
+                       list of fds to monitor. */
+                    s = make_socket_non_blocking(infd);
+                    if (s == -1)
+                        abort();
+
+                    event.data.fd = infd;
+                    event.events = EPOLLIN | EPOLLET;
+                    s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
+                    if (s == -1) {
+                        perror("epoll_ctl");
+                        abort();
                     }
                 }
-              continue;
-            }
-          else
-            {
-              /* We have data on the fd waiting to be read. Read and
-                 display it. We must read whatever data is available
-                 completely, as we are running in edge-triggered mode
-                 and won't get a notification again for the same
-                 data. */
-              int done = 0;
-
-              while (1)
-                {
-                  ssize_t count;
-                  char buf[512];
-
-                  count = read (events[i].data.fd, buf, sizeof buf);
-                  if (count == -1)
-                    {
-                      /* If errno == EAGAIN, that means we have read all
-                         data. So go back to the main loop. */
-                      if (errno != EAGAIN)
-                        {
-                          perror ("read");
-                          done = 1;
+                continue;
+            } else {
+                /* We have data on the fd waiting to be read. Read and
+                   display it. We must read whatever data is available
+                   completely, as we are running in edge-triggered mode
+                   and won't get a notification again for the same
+                   data. */
+                int done = 0;
+
+                while (1) {
+                    ssize_t count;
+                    char buf[512];
+
+                    count = read(events[i].data.fd, buf, sizeof buf);
+                    if (count == -1) {
+                        /* If errno == EAGAIN, that means we have read all
+                           data. So go back to the main loop. */
+                        if (errno != EAGAIN) {
+                            perror ("read");
+                            done = 1;
                         }
-                      break;
-                    }
-                  else if (count == 0)
-                    {
-                      /* End of file. The remote has closed the
-                         connection. */
-                      done = 1;
-                      break;
+                        break;
+                    } else if (count == 0) {
+                        /* End of file. The remote has closed the
+                           connection. */
+                        done = 1;
+                        break;
                     }
 
-                  /* Write the buffer to standard output */
-                  s = write (1, buf, count);
-                  if (s == -1)
-                    {
-                      perror ("write");
-                      abort ();
+                    /* Write the buffer to standard output */
+                    s = write(1, buf, count);
+                    if (s == -1) {
+                        perror("write");
+                        abort();
                     }
                 }
 
-              if (done)
-                {
-                  printf ("Closed connection on descriptor %d\n",
-                          events[i].data.fd);
+                if (done) {
+                    printf("Closed connection on descriptor %d\n",
+                           events[i].data.fd);
 
-                  /* Closing the descriptor will make epoll remove it
-                     from the set of descriptors which are monitored. */
-                  close (events[i].data.fd);
+                    /* Closing the descriptor will make epoll remove it
+                       from the set of descriptors which are monitored. */
+                    close (events[i].data.fd);
                 }
             }
         }
     }
 
-  free (events);
-
-  close (sfd);
+    free(events);
+    close(sfd);
 
-  return EXIT_SUCCESS;
+    return EXIT_SUCCESS;
 }
 

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

@@ -1,7 +1,6 @@
 /* -*- 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: */
 
-
 #include <stdio.h>
 #include <errno.h>
 

+ 7 - 7
LibOS/shim/test/native/exec.c

@@ -1,20 +1,20 @@
 /* -*- 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: */
 
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
+#include <stdio.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <unistd.h>
 
 int main (int argc, const char ** argv, const char ** envp)
 {
-    char fds[2] = { dup(1), 0 };
-    int outfd = dup(1);
-    char * new_argv[] = { "./exec_victim", fds, NULL };
+    int newfd = dup(1), outfd = dup(1);
+    char fd_argv[4];
+    snprintf(fd_argv, 4, "%d", newfd);
+    char * const new_argv[] = { "./exec_victim", fd_argv, NULL };
+
     setenv("IN_EXECVE", "1", 1);
+    
     execv(new_argv[0], new_argv);
     return 0;
 }

+ 0 - 4
LibOS/shim/test/native/exec_fork.c

@@ -1,12 +1,8 @@
 /* -*- 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: */
 
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <unistd.h>
 
 int main() {

+ 3 - 1
LibOS/shim/test/native/exec_victim.c

@@ -9,7 +9,9 @@ int main(int argc, char ** argv, const char ** envp)
     FILE * out = stdout;
 
     if (argc > 1) {
-        out = fdopen(argv[1][0], "a");
+        int fd = atoi(argv[1]);
+        printf("inherited file descriptor %d\n", fd);
+        out = fdopen(fd, "a");
         if (!out) {
             perror("fdopen");
             exit(1);

+ 0 - 7
LibOS/shim/test/native/file.c

@@ -1,8 +1,6 @@
 /* -*- 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 <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -17,7 +15,6 @@ int main(int argc, char ** argv)
     }
 
     write(fd1, "Hello World\n", 12);
-
     close(fd1);
 
     int fd2 = open("testfile", O_RDONLY, 0600);
@@ -37,9 +34,7 @@ int main(int argc, char ** argv)
 
     buffer[11] = 0;
     printf("read from file: %s\n", buffer);
-
     close(fd2);
-
     unlink("testfile");
 
     int fd3 = open("testfile", O_RDWR|O_CREAT|O_EXCL, 0600);
@@ -50,8 +45,6 @@ int main(int argc, char ** argv)
     }
 
     close(fd3);
-
     unlink("testfile");
-
     return 0;
 }

+ 2 - 2
LibOS/shim/test/native/fork_bomb.c

@@ -38,8 +38,8 @@ void sighand2 (int signum)
 int main(int argc, char ** argv)
 {
     int times = TEST_TIMES;
-    
-    for (int i = 0 ; i < times; i++ ) {
+
+    for (int i = 0 ; i < times; i++) {
         int pipes[2];
 
         pipe(pipes);

+ 5 - 16
LibOS/shim/test/native/fork_exec.c

@@ -4,33 +4,22 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <sys/wait.h>
 
 int main (int argc, char * const * argv, const char * const * envp)
 {
-    char fds[2] = { dup(1), 0 };
-    int outfd = dup(1);
-
-    if (argc > 1) {
-        argv++;
-    } else {
-        char ** new_argv = malloc(sizeof(const char *) * 3);
-        new_argv[0] = "./exec_victim";
-        new_argv[1] = fds;
-        new_argv[2] = NULL;
-        argv = new_argv;
-    }
+    int newfd = dup(1), outfd = dup(1);
+    char fd_argv[4];
+    snprintf(fd_argv, 4, "%d", newfd);
+    char * const new_argv[] = { "./exec_victim", fd_argv, NULL };
 
     setenv("IN_EXECVE", "1", 1);
 
     int pid = fork();
-
     if (pid == 0) {
         close(outfd);
-        execv(argv[0], argv);
+        execv(new_argv[0], new_argv);
     }
 
     wait(NULL);

+ 16 - 19
LibOS/shim/test/native/futextest.pthread.c

@@ -5,45 +5,42 @@
 #include <pthread.h>
 #include <unistd.h>
 
-void * print2(void * arg)
+void * print1 (void *arg)
 {
-    printf("This is Function 2 - go to sleep\n");
+    printf("This is Function 1 - go to sleep\n");
     sleep(5);
-    printf("Function2 out of sleep\n");
+    printf("Function1 out of sleep\n");
     printf("%s",(char *) arg);
     return NULL;
 }
 
-void * print (void *arg)
+void * print2(void * arg)
 {
-    printf("This is Function 1 - go to sleep\n");
+    printf("This is Function 2 - go to sleep\n");
     sleep(5);
-    printf("Function1 out of sleep\n");
+    printf("Function2 out of sleep\n");
     printf("%s",(char *) arg);
     return NULL;
 }
 
-void * TestFunc(void * arg )
+void * func(void * arg )
 {
     int * ptr = (int *) arg;
     printf("Parent gave %d\n",*ptr);
 }
 
-int main(int argc, char ** argv) {
-    pthread_t threadId1,threadId2,threadId3;
+int main(int argc, char ** argv)
+{
+    pthread_t thread1, thread2,thread3;
     int intvar = 12;
 
-    printf("MANISAYS :The Functions are at %p %p %p \n",print,print2,TestFunc);
-    pthread_create(&threadId1, NULL, print, "Thread1 Executing ...\n");
-    //sleep(2);
-    pthread_create(&threadId2, NULL, print2, "Thread2 Executing ...\n");
-    //sleep(2);
-    pthread_create(&threadId3, NULL, TestFunc,&intvar);
+    pthread_create(&thread1, NULL, print1, "Thread1 Executing ...\n");
+    pthread_create(&thread2, NULL, print2, "Thread2 Executing ...\n");
+    pthread_create(&thread3, NULL, func, &intvar);
     printf("going to sleep\n");
-    //sleep(2);
     printf("out of sleep\n");
-    pthread_join(threadId1, NULL);
-    pthread_join(threadId2, NULL);
-    pthread_join(threadId3, NULL);
+    pthread_join(thread1, NULL);
+    pthread_join(thread2, NULL);
+    pthread_join(thread3, NULL);
     return 0;
 }

+ 0 - 123
LibOS/shim/test/native/greeting.pthread.c

@@ -1,123 +0,0 @@
-/* -*- 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: */
-
-
-/* greetings.c -- greetings program
- * 
- * Send a message from all processes with rank != 0 to process 0. Process 0
- * prints the messages received.
- * 
- * Input: none. Output: contents of messages received by process 0.
- * 
- * See Chapter 3, pp. 41 & ff in PPMPI. */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#define MAX_THREAD 1000
-
-typedef struct
-{
-	int             id;
-	int             nproc;
-}               parm;
-
-char            message[100];	/* storage for message  */
-pthread_mutex_t msg_mutex = PTHREAD_MUTEX_INITIALIZER;
-int             token = 0;
-
-void* greeting(void *arg)
-{
-	parm           *p = (parm *) arg;
-	int             id = p->id;
-	int             i;
-
-	if (id != 0)
-		{
-			/* Create message */
-			while (1)
-				{
-					pthread_mutex_lock(&msg_mutex);
-					if (token  == 0)
-						{
-							sprintf(message, "Greetings from process %d!", id);
-							token++;
-							pthread_mutex_unlock(&msg_mutex);
-							break;
-						}
-					pthread_mutex_unlock(&msg_mutex);
-					sleep(1);
-				}
-			/* Use strlen+1 so that '\0' gets transmitted */
-		} else
-		{				/* my_rank == 0 */
-			for (i = 1; i < p->nproc; i++)
-				{
-					while (1)
-						{
-							pthread_mutex_lock(&msg_mutex);
-							if (token == 1)
-								{
-									printf("%s\n", message);
-									token--;
-									pthread_mutex_unlock(&msg_mutex);
-									break;
-								}
-							pthread_mutex_unlock(&msg_mutex);
-							sleep(1);
-						}
-				}
-		}
-
-	return NULL;
-}
-
-int main(int argc, char *argv[])
-{
-	int             my_rank;	/* rank of process      */
-	int             dest;		/* rank of receiver     */
-	int             tag = 0;	/* tag for messages     */
-
-	pthread_t      *threads;
-	pthread_attr_t  pthread_custom_attr;
-	parm           *p;
-
-	int             n, i;
-
-	if (argc != 2)
-		{
-			printf("Usage: %s n\n  where n is no. of thread\n", argv[0]);
-			return 1;
-		}
-	n = atoi(argv[1]);
-
-	if ((n < 1) || (n > MAX_THREAD))
-		{
-			printf("The no of thread should between 1 and %d.\n", MAX_THREAD);
-			return 1;
-		}
-	threads = (pthread_t *) malloc(n * sizeof(*threads));
-	pthread_attr_init(&pthread_custom_attr);
-
-	p=(parm *)malloc(sizeof(parm)*n);
-	/* Start up thread */
-
-	for (i = 0; i < n; i++)
-		{
-			p[i].id = i;
-			p[i].nproc = n;
-			pthread_create(&threads[i], &pthread_custom_attr, greeting, (void *)(p+i));
-		}
-
-	/* Synchronize the completion of each thread. */
-
-	for (i = 0; i < n; i++)
-		{
-			pthread_join(threads[i], NULL);
-		}
-	free(p);
-}				/* main */

+ 24 - 0
LibOS/shim/test/native/meminfo.c

@@ -0,0 +1,24 @@
+/* -*- 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: */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int main (int argc, char ** argv)
+{
+    FILE * cpuinfo = fopen("/proc/meminfo", "rb");
+    char * arg = 0;
+    size_t size = 0;
+
+    if (!cpuinfo)
+        return errno;
+
+    while(getdelim(&arg, &size, 0, cpuinfo) != -1)
+        puts(arg);
+
+    free(arg);
+    fclose(cpuinfo);
+    return 0;
+}

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

@@ -26,6 +26,5 @@ int main(int argc, char ** argv)
     }
 
     sleep(1);
-
     return 0;
 }

+ 4 - 3
LibOS/shim/test/native/vfork_exec.c

@@ -11,9 +11,10 @@
 
 int main (int argc, const char ** argv, const char ** envp)
 {
-    char fds[2] = { dup(1), 0 };
-    int outfd = dup(1);
-    char * new_argv[] = { "./exec_victim", fds, NULL };
+    int newfd = dup(1), outfd = dup(1);
+    char fd_argv[4];
+    snprintf(fd_argv, 4, "%d", newfd);
+    char * const new_argv[] = { "./exec_victim", fd_argv, NULL };
 
     setenv("IN_EXECVE", "1", 1);
 

+ 25 - 0
LibOS/shim/test/regression/00_bootstrap.py

@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+import os, sys, mmap
+from regression import Regression
+
+loader = './pal'
+
+# Running Bootstrap
+regression = Regression(loader, "bootstrap")
+
+regression.add_check(name="Basic Bootstrapping",
+    check=lambda res: "User Program Started" in res[0].out)
+
+regression.add_check(name="One Argument Given",
+    check=lambda res: "# of Arguments: 1" in res[0].out and \
+            "argv[0] = file:bootstrap" in res[0].out)
+
+regression.add_check(name="Five Arguments Given",
+    args = ['a', 'b', 'c', 'd'],
+    check=lambda res: "# of Arguments: 5" in res[0].out and \
+           "argv[0] = file:bootstrap" in res[0].out and \
+           "argv[1] = a" in res[0].out and "argv[2] = b" in res[0].out and \
+           "argv[3] = c" in res[0].out and "argv[4] = d" in res[0].out)
+
+regression.run_checks()

+ 56 - 0
LibOS/shim/test/regression/Makefile

@@ -0,0 +1,56 @@
+CFLAGS-libos = -L../../../build/libos -I../../include
+
+special_executables = bootstrap_static bootstrap_pie
+c_executables = $(filter-out $(special_executables),$(patsubst %.c,%,$(wildcard *.c)))
+cxx_executables = $(patsubst %.cpp,%,$(wildcard *.cpp))
+
+target = $(special_executables) $(c_executables) $(cxx_executables) \
+	  manifest pal pal_sec
+
+clean-extra += clean-tmp
+
+level = ../
+include ../Makefile
+
+%.manifest: %.manifest.template
+	rm -rf $@
+	cp $@.template $@
+
+ifeq ($(SYS),x86_64-linux-gnu)
+$(c_executables): %: %.c
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) $(if $(findstring .libos,$@),$(CFLAGS-libos),) -o $@ $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+$(cxx_executables): %: %.cpp
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) -o $@ $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+bootstrap_static: %: %.c
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) -o $@ -static $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+bootstrap_pie: %: %.c
+	@echo [ $@ ]
+	@$(CC) $(CFLAGS) -fPIC --pie -o $@ $< \
+	$(shell echo $@ | sed 's/^[^\.]*//g' | sed 's/\./ -l/g')
+
+.PHONY: pack
+pack: $(special_executables) $(c_executables) $(cxx_executables)
+	tar -czf .packed/test.tar.gz $^
+else
+$(special_executables) $(c_executables) $(cxx_executables): .packed/test.tar.gz
+	tar -xmozf $<
+endif
+
+PYTHONENV="PYTHONPATH=../../../../Scripts"
+
+regression: $(target)
+	@echo "\n\nBasic Bootstrapping:"
+	@for f in $(wildcard 00_*.py); do env $(PYTHONENV) python $$f; done
+	@echo "\n\n"
+
+clean-tmp:
+	rm -rf *.tmp

+ 16 - 0
LibOS/shim/test/regression/bootstrap.c

@@ -0,0 +1,16 @@
+/* -*- 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: */
+
+#include <stdio.h>
+
+int main(int argc, const char ** argv, const char ** envp)
+{
+    printf("User Program Started\n");
+
+    printf("# of Arguments: %d\n", argc);
+
+    for (int i = 0 ; i < argc ; i++)
+        printf("argv[%d] = %s\n", i, argv[i]);
+
+    return 0;
+}

+ 17 - 0
LibOS/shim/test/regression/bootstrap_pie.c

@@ -0,0 +1,17 @@
+/* -*- 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: */
+
+#include <stdio.h>
+
+static void * ptr = NULL;
+
+int main(int argc, const char ** argv, const char ** envp)
+{
+    printf("User program started\n");
+    printf("Local Address in Executable: %p\n", &ptr);
+
+    for (int i = 0 ; i < argc ; i++)
+        printf("argv[%d] = %s\n", i, argv[i]);
+
+    return 0;
+}

+ 12 - 0
LibOS/shim/test/regression/bootstrap_static.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 <stdio.h>
+
+int main(int argc, char ** argv)
+{
+    printf("Hello world (%s)!\n", argv[0]);
+    return 0;
+}

+ 22 - 0
LibOS/shim/test/regression/manifest.template

@@ -0,0 +1,22 @@
+loader.preload = file:../../src/libsysdb.so
+loader.env.LD_LIBRARY_PATH = /lib
+loader.debug_type = none
+loader.syscall_symbol = syscalldb
+
+fs.mount.root.type = chroot
+fs.mount.root.uri = file:
+
+fs.mount.other.lib.type = chroot
+fs.mount.other.lib.path = /lib
+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
+net.rules.1 = 127.0.0.1:8000:0.0.0.0:0-65535
+# allow to connect to port 8000
+net.rules.2 = 0.0.0.0:0-65535:127.0.0.1:8000
+
+# sys.ask_for_checkpoint = 1

+ 10 - 2
Makefile

@@ -1,6 +1,14 @@
-.PHONY: all debug clean install
+SYS ?= $(shell gcc -dumpmachine)
+export SYS
 
-all debug clean install:
+targets = all debug clean install
+
+ifeq ($(SYS),x86_64-linux-gnu)
+targets += pack
+endif
+
+.PHONY: $(targets)
+$(targets):
 	for d in Pal LibOS; \
 	do \
 		make -C $$d $@; \

+ 9 - 2
Pal/Makefile

@@ -11,7 +11,7 @@ ifeq ($(OS),Linux)
 	LINUX_KERNEL := $(LINUX_SRC)/arch/x86/boot/bzImage
 endif
 
-DIRS = src test
+DIRS = src test regression
 
 all debug clean:
 	for d in $(DIRS); \
@@ -23,7 +23,7 @@ all debug clean:
 kernel: $(LINUX_KERNEL)
 
 ifneq ($(LINUX_KERNEL),)
-$(LINUX_KERNEL): $(LINUX_SRC)/Makefile $(LINUX_SRC)/.config
+$(LINUX_KERNEL): $(LINUX_SRC)/Makefile $(LINUX_SRC)/graphene $(LINUX_SRC)/.config
 	make -C $(LINUX_SRC) -j$(NPROCS)
 
 $(LINUX_SRC)/Makefile:
@@ -32,6 +32,9 @@ $(LINUX_SRC)/Makefile:
 	tar -xzf $(LINUX_SRC).tar.gz
 	[ ! -f $(LINUX_SRC).patch ] || git apply $(LINUX_SRC).patch
 
+$(LINUX_SRC)/graphene: linux-kernel/graphene
+	cd $(LINUX_SRC) && ln -s ../linux-kernel/graphene graphene
+
 $(LINUX_SRC)/.config: $(LINUX_SRC)/Makefile
 	cd $(LINUX_SRC) && make menuconfig
 
@@ -53,3 +56,7 @@ endif
 .PHONY: test
 test:
 	make -C test test
+
+.PHONY: pack
+pack:
+	make -C test pack

+ 0 - 39
Pal/include/asm-errno-base.h

@@ -1,39 +0,0 @@
-#ifndef _ASM_GENERIC_ERRNO_BASE_H
-#define _ASM_GENERIC_ERRNO_BASE_H
-
-#define	EPERM		 1	/* Operation not permitted */
-#define	ENOENT		 2	/* No such file or directory */
-#define	ESRCH		 3	/* No such process */
-#define	EINTR		 4	/* Interrupted system call */
-#define	EIO		 5	/* I/O error */
-#define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Argument list too long */
-#define	ENOEXEC		 8	/* Exec format error */
-#define	EBADF		 9	/* Bad file number */
-#define	ECHILD		10	/* No child processes */
-#define	EAGAIN		11	/* Try again */
-#define	ENOMEM		12	/* Out of memory */
-#define	EACCES		13	/* Permission denied */
-#define	EFAULT		14	/* Bad address */
-#define	ENOTBLK		15	/* Block device required */
-#define	EBUSY		16	/* Device or resource busy */
-#define	EEXIST		17	/* File exists */
-#define	EXDEV		18	/* Cross-device link */
-#define	ENODEV		19	/* No such device */
-#define	ENOTDIR		20	/* Not a directory */
-#define	EISDIR		21	/* Is a directory */
-#define	EINVAL		22	/* Invalid argument */
-#define	ENFILE		23	/* File table overflow */
-#define	EMFILE		24	/* Too many open files */
-#define	ENOTTY		25	/* Not a typewriter */
-#define	ETXTBSY		26	/* Text file busy */
-#define	EFBIG		27	/* File too large */
-#define	ENOSPC		28	/* No space left on device */
-#define	ESPIPE		29	/* Illegal seek */
-#define	EROFS		30	/* Read-only file system */
-#define	EMLINK		31	/* Too many links */
-#define	EPIPE		32	/* Broken pipe */
-#define	EDOM		33	/* Math argument out of domain of func */
-#define	ERANGE		34	/* Math result not representable */
-
-#endif

+ 0 - 111
Pal/include/asm-errno.h

@@ -1,111 +0,0 @@
-#ifndef _ASM_GENERIC_ERRNO_H
-#define _ASM_GENERIC_ERRNO_H
-
-#include <asm-errno-base.h>
-
-#define	EDEADLK		35	/* Resource deadlock would occur */
-#define	ENAMETOOLONG	36	/* File name too long */
-#define	ENOLCK		37	/* No record locks available */
-#define	ENOSYS		38	/* Function not implemented */
-#define	ENOTEMPTY	39	/* Directory not empty */
-#define	ELOOP		40	/* Too many symbolic links encountered */
-#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
-#define	ENOMSG		42	/* No message of desired type */
-#define	EIDRM		43	/* Identifier removed */
-#define	ECHRNG		44	/* Channel number out of range */
-#define	EL2NSYNC	45	/* Level 2 not synchronized */
-#define	EL3HLT		46	/* Level 3 halted */
-#define	EL3RST		47	/* Level 3 reset */
-#define	ELNRNG		48	/* Link number out of range */
-#define	EUNATCH		49	/* Protocol driver not attached */
-#define	ENOCSI		50	/* No CSI structure available */
-#define	EL2HLT		51	/* Level 2 halted */
-#define	EBADE		52	/* Invalid exchange */
-#define	EBADR		53	/* Invalid request descriptor */
-#define	EXFULL		54	/* Exchange full */
-#define	ENOANO		55	/* No anode */
-#define	EBADRQC		56	/* Invalid request code */
-#define	EBADSLT		57	/* Invalid slot */
-
-#define	EDEADLOCK	EDEADLK
-
-#define	EBFONT		59	/* Bad font file format */
-#define	ENOSTR		60	/* Device not a stream */
-#define	ENODATA		61	/* No data available */
-#define	ETIME		62	/* Timer expired */
-#define	ENOSR		63	/* Out of streams resources */
-#define	ENONET		64	/* Machine is not on the network */
-#define	ENOPKG		65	/* Package not installed */
-#define	EREMOTE		66	/* Object is remote */
-#define	ENOLINK		67	/* Link has been severed */
-#define	EADV		68	/* Advertise error */
-#define	ESRMNT		69	/* Srmount error */
-#define	ECOMM		70	/* Communication error on send */
-#define	EPROTO		71	/* Protocol error */
-#define	EMULTIHOP	72	/* Multihop attempted */
-#define	EDOTDOT		73	/* RFS specific error */
-#define	EBADMSG		74	/* Not a data message */
-#define	EOVERFLOW	75	/* Value too large for defined data type */
-#define	ENOTUNIQ	76	/* Name not unique on network */
-#define	EBADFD		77	/* File descriptor in bad state */
-#define	EREMCHG		78	/* Remote address changed */
-#define	ELIBACC		79	/* Can not access a needed shared library */
-#define	ELIBBAD		80	/* Accessing a corrupted shared library */
-#define	ELIBSCN		81	/* .lib section in a.out corrupted */
-#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
-#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
-#define	EILSEQ		84	/* Illegal byte sequence */
-#define	ERESTART	85	/* Interrupted system call should be restarted */
-#define	ESTRPIPE	86	/* Streams pipe error */
-#define	EUSERS		87	/* Too many users */
-#define	ENOTSOCK	88	/* Socket operation on non-socket */
-#define	EDESTADDRREQ	89	/* Destination address required */
-#define	EMSGSIZE	90	/* Message too long */
-#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
-#define	ENOPROTOOPT	92	/* Protocol not available */
-#define	EPROTONOSUPPORT	93	/* Protocol not supported */
-#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
-#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
-#define	EPFNOSUPPORT	96	/* Protocol family not supported */
-#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
-#define	EADDRINUSE	98	/* Address already in use */
-#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
-#define	ENETDOWN	100	/* Network is down */
-#define	ENETUNREACH	101	/* Network is unreachable */
-#define	ENETRESET	102	/* Network dropped connection because of reset */
-#define	ECONNABORTED	103	/* Software caused connection abort */
-#define	ECONNRESET	104	/* Connection reset by peer */
-#define	ENOBUFS		105	/* No buffer space available */
-#define	EISCONN		106	/* Transport endpoint is already connected */
-#define	ENOTCONN	107	/* Transport endpoint is not connected */
-#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
-#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
-#define	ETIMEDOUT	110	/* Connection timed out */
-#define	ECONNREFUSED	111	/* Connection refused */
-#define	EHOSTDOWN	112	/* Host is down */
-#define	EHOSTUNREACH	113	/* No route to host */
-#define	EALREADY	114	/* Operation already in progress */
-#define	EINPROGRESS	115	/* Operation now in progress */
-#define	ESTALE		116	/* Stale NFS file handle */
-#define	EUCLEAN		117	/* Structure needs cleaning */
-#define	ENOTNAM		118	/* Not a XENIX named type file */
-#define	ENAVAIL		119	/* No XENIX semaphores available */
-#define	EISNAM		120	/* Is a named type file */
-#define	EREMOTEIO	121	/* Remote I/O error */
-#define	EDQUOT		122	/* Quota exceeded */
-
-#define	ENOMEDIUM	123	/* No medium found */
-#define	EMEDIUMTYPE	124	/* Wrong medium type */
-#define	ECANCELED	125	/* Operation Canceled */
-#define	ENOKEY		126	/* Required key not available */
-#define	EKEYEXPIRED	127	/* Key has expired */
-#define	EKEYREVOKED	128	/* Key has been revoked */
-#define	EKEYREJECTED	129	/* Key was rejected by service */
-
-/* for robust mutexes */
-#define	EOWNERDEAD	130	/* Owner died */
-#define	ENOTRECOVERABLE	131	/* State not recoverable */
-
-#define ERFKILL		132	/* Operation not possible due to RF-kill */
-
-#endif

+ 0 - 1
Pal/include/atomic.h

@@ -51,7 +51,6 @@ static inline int atomic_sub_and_test_nonnegative (int i, struct atomic_int * v)
     return c;
 }
 
-
 static inline void atomic_inc (struct atomic_int * v)
 {
     asm volatile(LOCK_PREFIX "incl %0"

+ 0 - 50
Pal/include/bits/errno.h

@@ -1,50 +0,0 @@
-/* Error constants.  Linux specific version.
-   Copyright (C) 1996-1999, 2005, 2009 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
-# include <asm-errno.h>
-
-/* Linux has no ENOTSUP error code.  */
-# define ENOTSUP EOPNOTSUPP
-
-/* Older Linux versions also had no ECANCELED error code.  */
-# ifndef ECANCELED
-#  define ECANCELED	125
-# endif
-
-/* Support for error codes to support robust mutexes was added later, too.  */
-# ifndef EOWNERDEAD
-#  define EOWNERDEAD		130
-#  define ENOTRECOVERABLE	131
-# endif
-
-# ifndef ERFKILL
-#  define ERFKILL		132
-# endif
-
-#if defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	84	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* __need_Emath */

+ 0 - 7
Pal/include/elf/elf.h

@@ -21,10 +21,6 @@
 #ifndef _ELF_H
 #define	_ELF_H 1
 
-#include <features.h>
-
-__BEGIN_DECLS
-
 /* Standard ELF types.  */
 
 #include <stdint.h>
@@ -2795,7 +2791,4 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
 #define R_M32R_NUM		256	/* Keep this the last entry. */
 
-
-__END_DECLS
-
 #endif	/* elf.h */

+ 0 - 7
Pal/include/sysdeps/generic/ldsodefs.h

@@ -20,18 +20,13 @@
 #ifndef	_LDSODEFS_H
 #define	_LDSODEFS_H	1
 
-#include <features.h>
-
 #include <stdbool.h>
 #define __need_size_t
 #define __need_NULL
 #include <stddef.h>
 #include <sys/mman.h>
-
 #include <elf/elf.h>
 
-__BEGIN_DECLS
-
 /* We use this macro to refer to ELF types independent of the native wordsize.
    `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'.  */
 #define ElfW(type)	_ElfW (Elf, __ELF_NATIVE_CLASS, type)
@@ -213,6 +208,4 @@ enum
 #define DL_LOOKUP_RETURN_NEWEST  dl_lookup_return_newest
 #define DL_LOOKUP_GSCOPE_LOCK    dl_lookup_gscope_lock
 
-__END_DECLS
-
 #endif /* ldsodefs.h */

+ 9 - 9
Pal/include/sysdeps/generic/memcopy.h

@@ -36,7 +36,7 @@
    exhaustive in the sense that I tried all alignment and length
    combinations, with and without overlap.  */
 
-#include <endian.h>
+#include <host_endian.h>
 
 /* Type to use for aligned memory operations.
    This should normally be the biggest type supported by a single load
@@ -50,10 +50,10 @@ typedef unsigned char byte;
 /* Optimal type for storing bytes in registers.  */
 #define	reg_char	char
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
 #define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
 #endif
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if BYTE_ORDER == BIG_ENDIAN
 #define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
 #endif
 
@@ -62,7 +62,7 @@ typedef unsigned char byte;
 #define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)				      \
   do									      \
     {									      \
-      size_t __nbytes = (nbytes);					      \
+      int __nbytes = (nbytes);					      \
       while (__nbytes > 0)						      \
 	{								      \
 	  byte __x = ((byte *) src_bp)[0];				      \
@@ -80,7 +80,7 @@ typedef unsigned char byte;
 #define BYTE_COPY_BWD(dst_ep, src_ep, nbytes)				      \
   do									      \
     {									      \
-      size_t __nbytes = (nbytes);					      \
+      int __nbytes = (nbytes);					      \
       while (__nbytes > 0)						      \
 	{								      \
 	  byte __x;							      \
@@ -96,8 +96,8 @@ typedef unsigned char byte;
    the assumption that DST_BP is aligned on an OPSIZ multiple.  If
    not all bytes could be easily copied, store remaining number of bytes
    in NBYTES_LEFT, otherwise store 0.  */
-extern void _wordcopy_fwd_aligned (long int, long int, size_t);
-extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t);
+extern void _wordcopy_fwd_aligned (long int, long int, int);
+extern void _wordcopy_fwd_dest_aligned (long int, long int, int);
 #define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)		      \
   do									      \
     {									      \
@@ -116,8 +116,8 @@ extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t);
    DST_END_PTR is aligned on an OPSIZ multiple.  If not all bytes could be
    easily copied, store remaining number of bytes in NBYTES_REMAINING,
    otherwise store 0.  */
-extern void _wordcopy_bwd_aligned (long int, long int, size_t);
-extern void _wordcopy_bwd_dest_aligned (long int, long int, size_t);
+extern void _wordcopy_bwd_aligned (long int, long int, int);
+extern void _wordcopy_bwd_dest_aligned (long int, long int, int);
 #define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes)		      \
   do									      \
     {									      \

+ 0 - 3
Pal/ipc/linux/demo/.gitignore

@@ -1,3 +0,0 @@
-client
-server
-fork

+ 0 - 6
Pal/ipc/linux/demo/Makefile

@@ -1,6 +0,0 @@
-CC=gcc -g
-
-all: client server fork test_optimization
-
-clean:
-	rm -f client server *~

+ 0 - 139
Pal/ipc/linux/demo/client.c

@@ -1,139 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#include "../graphene-ipc.h"
-#define PAGE_SIZE 4096
-#define MAX_PIDBUF 20
-#define MAX_PATH 256
-
-int main () {
-
-	volatile int *x = NULL;
-	int fd, fd1, rv;
-	struct gipc_recv gr;
-	struct gipc_send gs;
-	pid_t other_client;
-	char pidbuf[MAX_PIDBUF];	
-	unsigned long len = PAGE_SIZE;
-	unsigned long addr = 0;
-	int64_t token;
-	int order;
-	unsigned long gr_addr, gr_len;
-	int gr_prot;
-
-	gr.entries = 1;
-	gr.addr = &gr_addr;
-	gr.len = &gr_len;
-	gr.prot = &gr_prot;
-
-	read(0, &token, sizeof(token));
-	read(0, &order, sizeof(order));
-
-	/* Open an IPC link */
-	fd = open (GIPC_FILE, O_RDWR);
-	if (fd < 0) {
-		printf ("[client] Fd is %d %d\n", fd, errno);
-		return -1;
-	}
-
-	/* Set the channel */
-	rv = ioctl(fd, GIPC_JOIN, token);
-	if (rv < 0) {
-		printf("[client] Failed to join ipc channel - %d, %d\n", rv, errno);
-		return -1;
-	}
-
-	gr_len = PAGE_SIZE * 3;
-	gr_addr = 0;
-	gr_prot = PROT_READ | PROT_WRITE;
-
-	/* Recv the page */
-	rv = ioctl(fd, GIPC_RECV, &gr);
-	if (rv) {
-		printf ("Bad map %p rv %d %d\n", (void *)gr_addr, rv, errno);
-		return 1;
-	}
-
-	/* Try a memory barrier */
-	asm volatile ("nop" :::"memory");
-
-	x = (int *) gr_addr;
-
-	/* Print the value */
-	printf("[client] X contains %d, from %d\n", *x, fd);
-	x += PAGE_SIZE / sizeof(int);
-	printf("[client] X contains %d, from %d\n", *x, fd);
-	x += PAGE_SIZE / sizeof(int);
-	printf("[client] X contains %d, from %d\n", *x, fd);
-	*x += 3820;
-
-	other_client = *(int *) gr_addr;
-
-	printf("[client] other pid is %d\n", other_client);
-
-	/* Map an anonymous page */
-	addr = (unsigned long) x;
-	gs.entries = 1;
-	gs.addr = &addr;
-	gs.len = &len;
-
-	/* Send the pages to other client */
-	fd1 = open (GIPC_FILE, O_RDWR);
-	if (!order) {
-		// Create the queue
-		token = ioctl(fd1, GIPC_CREATE, 0);
-		if (token < 0) {
-			printf ("[server] Failed to create a new token %ld\n", token);
-			return -1;
-		}
-
-		// Write to token to handle 3 (write pipe)
-		write(3, &token, sizeof(token));
-	} else {
-		// Join the queue
-		rv = read(3, &token, sizeof(token));
-		if (rv != sizeof(token)) {
-			printf("Failed to get the token - %d\n", errno);
-		}
-
-		rv = ioctl(fd1, GIPC_JOIN, token);
-		if (rv < 0) {
-			printf("[client] Failed to join ipc channel - %d, %d\n", rv, errno);
-			return -1;
-		}
-	}
-
-	rv = ioctl(fd1, GIPC_SEND, &gs);
-	if (rv != gs.entries)
-		printf ("[client] Bad rv %d (%d)\n", errno, rv);
-
-	gr_len = PAGE_SIZE;
-	gr_addr = 0;
-	//gr.wait_on_src = other_client;
-
-	/* Recv the page */
-	rv = ioctl(fd1, GIPC_RECV, &gr);
-	if (rv) {
-		printf ("Bad map %p rv %d %d\n", (void *)gr_addr, rv, errno);
-		return 1;
-	}
-
-	/* Try a memory barrier */
-	asm volatile ("nop" :::"memory");
-
-	x = (int *) gr_addr;
-
-	/* Print the value */
-	printf("[client] X contains %d, from %d\n", *x, fd1);
-
-	close(fd1);
-	close(fd);
-
-
-	return 0;
-}

+ 0 - 207
Pal/ipc/linux/demo/fork.c

@@ -1,207 +0,0 @@
-#include <stdio.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include "../graphene-ipc.h"
-
-#define PAGE_SIZE 4096
-#define MAX_PIDBUF 7
-#define TEST_PAGES 20
-
-struct mapping {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long perms;
-	unsigned long flags;
-};
-
-int main(int argc, char **argv) 
-{
-	char *pages[TEST_PAGES];
-	int p0[2];
-	int64_t token;
-
-	if (argc == 1) {
-		// Server
-
-		int pid;
-		struct gipc_send gs;
-		unsigned long addr[TEST_PAGES];
-		unsigned long len[TEST_PAGES];
-		int gfd;
-		int i;
-		int rv;
-
-		/* Map some anonymous memory, fill with crap */
-		for (i = 0; i < TEST_PAGES; i++) {
-			pages[i] = mmap(NULL, PAGE_SIZE * TEST_PAGES, 
-					PROT_READ|PROT_WRITE,
-					MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-			if (!pages[i]) {
-				perror("mmap");
-				return -1;
-			}
-
-			memset(pages[i], 'a' + i, 256);
-			pages[i][256] = '\0';
-		}
-
-		/* Set up a communications channel */
-		if (pipe(p0) == -1) {
-			printf("Pipe failed %d\n", errno);
-			return -1;
-		}
-
-
-		/* fork + exec this program with an arg */
-		pid = fork();
-		if (pid == -1) {
-			perror("Fork");
-			return -1;
-		} else if (pid == 0) {
-			char *args[3];
-			args[0] = argv[0];
-			args[1] = "quack";
-			args[2] = NULL;
-			close(p0[1]);
-			dup2(p0[0], 0);
-			execv(argv[0], args);
-			printf("Failed to EXEC %s %s!, %d\n", argv[0], args[0], errno);
-			return -1;
-
-		} 
-		
-		/* Parent */
-		close (p0[0]);
-
-		/* Open an IPC link */
-		gfd = open (GIPC_FILE, O_RDWR);
-		if (gfd < 0) {
-			printf ("Fd is %d %d\n", gfd, errno);
-			return -1;
-		}
-
-		token = ioctl(gfd, GIPC_CREATE, 0);
-		if (token < 0) {
-			printf ("Failed to create the gipc queue. %d\n", errno);
-			return -1;
-		}
-
-		/* Write the token to the child */
-		rv = write(p0[1], &token, sizeof(token));
-		if  ( rv != sizeof(token)) {
-			perror("Failed to write map size\n");
-			return -1;
-		}
-
-		/* Send each region */
-		gs.entries = TEST_PAGES;
-		gs.addr = addr;
-		gs.len = len;
-
-		i = TEST_PAGES;
-		rv = write(p0[1], &i, sizeof(int));
-		if  ( rv != sizeof(int)) {
-			perror("Failed to write map size\n");
-			return -1;
-		}
-
-		for (i = 0; i < TEST_PAGES; i++) {
-			struct mapping map = {(unsigned long) pages[i],
-					      TEST_PAGES * PAGE_SIZE,
-					      PROT_READ|PROT_WRITE,
-					      MAP_PRIVATE|MAP_ANONYMOUS};
-
-			rv = write(p0[1], &map, sizeof(map));
-			if  ( rv != sizeof(map)) {
-				perror("Failed to write map\n");
-				return -1;
-			}
-
-			addr[i] = (unsigned long) pages[i];
-			len[i] = TEST_PAGES * PAGE_SIZE;
-		}		
-
-		rv = ioctl(gfd, GIPC_SEND, &gs);
-		if (rv)
-			printf ("[server] Bad rv %d (2)\n", errno);
-
-		close (gfd);
-		close (p0[1]);
-
-		/* Exit */
-		wait();
-
-	} else {
-
-		int rv, gfd;
-		int max, i;
-		struct gipc_recv gr;
-
-		/* Read the token from parent */
-		rv = read(0, &token, sizeof(token));
-		if (rv != sizeof(token)) {
-			perror ("Size read failed\n");
-			return -1;
-		}
-
-		/* Open the gipc channel */
-		gfd = open (GIPC_FILE, O_RDWR);
-		if (gfd < 0) {
-			printf ("Fd is %d %d\n", gfd, errno);
-			return -1;
-		}
-
-		/* Join the queue */
-		rv = ioctl(gfd, GIPC_JOIN, token);
-		if (rv < 0) {
-			printf ("Failed to join GIPC queue - %d\n", errno);
-			return -1;
-		}
-
-		/* Read count of descriptors */
-		rv = read(0, &max, sizeof(int));
-		if (rv != sizeof(int)) {
-			perror ("Size read failed\n");
-			return -1;
-		}
-
-
-		/* For each memory descriptor on the pipe */
-		for (i = 0; i < max; i++) {
-			struct mapping map;
-
-			rv = read(0, &map, sizeof(map));
-			if (rv != sizeof(map)) {
-				perror ("Size read failed\n");
-				return -1;
-			}
-
-			gr.len = map.len;
-			gr.addr = map.addr;
-			// Perms?
-
-			/* map the memory */
-			rv = ioctl(gfd, GIPC_RECV, &gr);
-			if (rv) {
-				printf ("Bad map %p rv %d %d\n", (void *)gr.addr, rv, errno);
-				return 1;
-			}
-
-			/* Do some sanity checks that it worked */
-			if ('a' + i != ((char *) map.addr)[250]) {
-				printf("Failed to map right shiz\n");
-				return -1;
-			}
-
-			printf("%s\n", (char *) map.addr);
-		}
-
-		close(gfd);
-	}
-	
-	return 0;
-}

Some files were not shown because too many files changed in this diff