From 5eaaf9abfbf75aa674e7b85dcb0d38286639b734 Mon Sep 17 00:00:00 2001 From: Chia-Che Tsai Date: Thu, 12 Feb 2015 20:13:00 -0800 Subject: [PATCH] apply multiple patches --- LibOS/buildglibc.py | 3 +- LibOS/glibc-2.17.patch | 62 ++--- LibOS/glibc-2.17/syscallas.S | 10 +- LibOS/glibc-2.17/syscalldb.h | 10 - LibOS/shim/include/shim_internal.h | 2 + LibOS/shim/include/shim_thread.h | 14 -- LibOS/shim/include/shim_tls.h | 2 +- LibOS/shim/include/shim_vma.h | 2 + LibOS/shim/src/Makefile | 2 +- LibOS/shim/src/bookkeep/shim_thread.c | 1 + LibOS/shim/src/bookkeep/shim_vma.c | 79 ++++++- LibOS/shim/src/elf/shim_rtld.c | 33 +-- LibOS/shim/src/fs/chroot/fs.c | 41 +++- LibOS/shim/src/fs/proc/thread.c | 98 ++++++++ LibOS/shim/src/ipc/shim_ipc_nsimpl.h | 2 +- LibOS/shim/src/shim.map | 6 +- LibOS/shim/src/shim_checkpoint.c | 13 +- LibOS/shim/src/shim_debug.c | 173 ++------------ LibOS/shim/src/shim_init.c | 26 ++- LibOS/shim/src/shim_malloc.c | 7 +- LibOS/shim/src/shim_parser.c | 56 ++++- LibOS/shim/src/sys/shim_brk.c | 17 +- LibOS/shim/src/sys/shim_clone.c | 219 ++++++++++++------ LibOS/shim/src/sys/shim_exec.c | 3 +- LibOS/shim/src/sys/shim_fork.c | 10 +- LibOS/shim/src/sys/shim_futex.c | 146 ++++++++++-- LibOS/shim/src/sys/shim_mmap.c | 2 +- LibOS/shim/src/sys/shim_sigaction.c | 11 +- LibOS/shim/src/syscallas.S | 41 ++-- LibOS/shim/test/Makefile | 9 +- LibOS/shim/test/apps/Makefile | 8 +- .../test/apps/apache/httpd.manifest.template | 2 +- .../apps/bash/bash-local.manifest.template | 2 +- .../test/apps/bash/bash.manifest.template | 2 +- .../apps/busybox/busybox.manifest.template | 2 +- .../busybox/busybox_nofork.manifest.template | 2 +- .../test/apps/gcc/g++-huge.manifest.template | 2 +- .../test/apps/gcc/g++-local.manifest.template | 2 +- .../shim/test/apps/gcc/g++.manifest.template | 2 +- .../test/apps/gcc/gcc-huge.manifest.template | 2 +- .../test/apps/gcc/gcc-local.manifest.template | 2 +- .../shim/test/apps/gcc/gcc.manifest.template | 2 +- .../lighttpd/lighttpd-angel.manifest.template | 2 +- .../apps/lighttpd/lighttpd.manifest.template | 2 +- .../lmbench/lmbench-2.5/src/lat_syscall.c | 24 +- .../shim/test/apps/lmbench/manifest.template | 2 +- .../apps/make/make-huge.manifest.template | 2 +- .../apps/make/make-local.manifest.template | 2 +- .../test/apps/make/make.manifest.template | 2 +- .../test/apps/python/python.manifest.template | 2 +- LibOS/shim/test/inline/Makefile | 4 +- LibOS/shim/test/native/Makefile | 4 +- LibOS/shim/test/native/manifest.template | 4 + LibOS/shim/test/native/start.c | 1 - LibOS/shim/test/native/system.c | 12 + Pal/ipc/linux/graphene-ipc.c | 2 +- Pal/src/Makefile | 37 ++- Pal/src/db_rtld.c | 143 ++++++------ Pal/src/dynamic_link.h | 8 +- Pal/src/host/Linux/Makefile | 3 +- Pal/src/host/Linux/Makefile.am | 7 + Pal/src/host/Linux/db_main.c | 40 +--- Pal/src/host/Linux/db_misc.c | 4 +- Pal/src/host/Linux/db_pipes.c | 2 +- Pal/src/host/Linux/db_process.c | 4 +- Pal/src/host/Linux/db_rtld.c | 129 +++++++++-- Pal/src/{ => host/Linux}/pal.lds | 0 Pal/src/{ => host/Linux}/pal.map | 3 +- Pal/src/host/Linux/pal_linux.h | 3 + Pal/src/pal_debug.h | 3 + Pal/src/pal_internal.h | 6 +- Pal/src/pal_rtld.h | 15 ++ Pal/src/security/Linux/Makefile | 1 - 73 files changed, 974 insertions(+), 629 deletions(-) create mode 100644 LibOS/shim/test/native/system.c rename Pal/src/{ => host/Linux}/pal.lds (100%) rename Pal/src/{ => host/Linux}/pal.map (95%) diff --git a/LibOS/buildglibc.py b/LibOS/buildglibc.py index f4fae2bf..22e41dc0 100755 --- a/LibOS/buildglibc.py +++ b/LibOS/buildglibc.py @@ -86,7 +86,7 @@ try: os.chdir(buildDir) - cflags= '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector'.format(debug_flags) + cflags = '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector'.format(debug_flags) disabled_features = { 'nscd' } extra_flags = '--with-tls --enable-add-ons=nptl --without-selinux {0}'.format(' '.join(['--disable-' + f for f in disabled_features])) @@ -108,6 +108,7 @@ try: ( 'nptl', 'libpthread.so.0' ), ( 'nptl_db','libthread_db.so.1' ), ( 'dlfcn', 'libdl.so.2' ), + ( 'math', 'libm.so.6' ), ( 'csu', 'crt1.o' ), ( 'csu', 'crti.o' ), ( 'csu', 'crtn.o' ), diff --git a/LibOS/glibc-2.17.patch b/LibOS/glibc-2.17.patch index 7c119c3b..e4b17143 100644 --- a/LibOS/glibc-2.17.patch +++ b/LibOS/glibc-2.17.patch @@ -926,10 +926,10 @@ index dc95421..a772f66 100644 cmpl $0, (%rdi) jne 1f diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h -index 5a80ddd..bcc8d57 100644 +index 5a80ddd..f7319ca 100644 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h -@@ -214,12 +214,12 @@ LLL_STUB_UNWIND_INFO_END +@@ -214,7 +214,7 @@ LLL_STUB_UNWIND_INFO_END register const struct timespec *__to __asm ("r10") = timeout; \ int __status; \ register __typeof (val) _val __asm ("edx") = (val); \ @@ -938,13 +938,7 @@ index 5a80ddd..bcc8d57 100644 : "=a" (__status) \ : "0" (SYS_futex), "D" (futex), \ "S" (__lll_private_flag (FUTEX_WAIT, private)), \ - "d" (_val), "r" (__to) \ -- : "memory", "cc", "r11", "cx"); \ -+ : "memory", "cc", "r11", "cx", "bx"); \ - __status; \ - }) - -@@ -229,12 +229,12 @@ LLL_STUB_UNWIND_INFO_END +@@ -229,7 +229,7 @@ LLL_STUB_UNWIND_INFO_END int __ignore; \ register __typeof (nr) _nr __asm ("edx") = (nr); \ LIBC_PROBE (lll_futex_wake, 3, futex, nr, private); \ @@ -953,13 +947,7 @@ index 5a80ddd..bcc8d57 100644 : "=a" (__ignore) \ : "0" (SYS_futex), "D" (futex), \ "S" (__lll_private_flag (FUTEX_WAKE, private)), \ - "d" (_nr) \ -- : "memory", "cc", "r10", "r11", "cx"); \ -+ : "memory", "cc", "r10", "r11", "cx", "bx"); \ - } while (0) - - -@@ -532,12 +532,12 @@ LLL_STUB_UNWIND_INFO_END +@@ -532,7 +532,7 @@ LLL_STUB_UNWIND_INFO_END { \ int ignore; \ __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t" \ @@ -968,13 +956,7 @@ index 5a80ddd..bcc8d57 100644 : "=m" (futex), "=a" (ignore) \ : "D" (&(futex)), "i" (FUTEX_OWNER_DIED), \ "S" (__lll_private_flag (FUTEX_WAKE, private)), \ - "1" (__NR_futex), "d" (1) \ -- : "cx", "r11", "cc", "memory"); \ -+ : "cx", "bx", "r11", "cc", "memory"); \ - } \ - while (0) - -@@ -547,13 +547,13 @@ LLL_STUB_UNWIND_INFO_END +@@ -547,7 +547,7 @@ LLL_STUB_UNWIND_INFO_END register int __nr_move __asm ("r10") = nr_move; \ register void *__mutex __asm ("r8") = mutex; \ register int __val __asm ("r9") = val; \ @@ -983,14 +965,7 @@ index 5a80ddd..bcc8d57 100644 : "=a" (__res) \ : "0" (__NR_futex), "D" ((void *) ftx), \ "S" (__lll_private_flag (FUTEX_CMP_REQUEUE, \ - private)), "d" (nr_wake), \ - "r" (__nr_move), "r" (__mutex), "r" (__val) \ -- : "cx", "r11", "cc", "memory"); \ -+ : "cx", "bx", "r11", "cc", "memory"); \ - __res < 0; }) - - #define lll_islocked(futex) \ -@@ -573,13 +573,13 @@ LLL_STUB_UNWIND_INFO_END +@@ -573,7 +573,7 @@ LLL_STUB_UNWIND_INFO_END if (_tid != 0) \ __asm __volatile ("xorq %%r10, %%r10\n\t" \ "1:\tmovq %2, %%rax\n\t" \ @@ -999,13 +974,6 @@ index 5a80ddd..bcc8d57 100644 "cmpl $0, (%%rdi)\n\t" \ "jne 1b" \ : "=&a" (__ignore) \ - : "S" (FUTEX_WAIT), "i" (SYS_futex), "D" (&tid), \ - "d" (_tid) \ -- : "memory", "cc", "r10", "r11", "cx"); \ -+ : "memory", "cc", "r10", "r11", "cx", "bx"); \ - } while (0) - - extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) diff --git a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S index 0b4ef71..36c5572 100644 --- a/LibOS/glibc-2.17/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S @@ -1401,7 +1369,7 @@ index 50587b8..374b553 100644 + asm volatile ("pushq %%rbx\n\tmovq syscalldb@GOTPCREL(%%rip), %%rbx\n\t" \ + "call %%rbx\n\t" :: "a" (__NR_exit), "D" (val) : "bx" ) diff --git a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h -index f3b7649..b466cb1 100644 +index f3b7649..433b8c9 100644 --- a/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h +++ b/LibOS/glibc-2.17/nptl/sysdeps/x86_64/tls.h @@ -28,6 +28,7 @@ @@ -1423,16 +1391,20 @@ index f3b7649..b466cb1 100644 int rtld_must_xmm_save; /* Reservation of some values for the TM ABI. */ void *__private_tm[5]; -@@ -135,6 +140,8 @@ typedef struct +@@ -135,6 +140,12 @@ typedef struct # define GET_DTV(descr) \ (((tcbhead_t *) (descr))->dtv) +/* For Graphene */ -+#define SYSCALLDB "movq syscalldb@GOTPCREL(%%rip), %%rbx\n\tcall %%rbx\n\t" ++#define SYSCALLDB \ ++ "pushq %%rbx\n\t" \ ++ "movq syscalldb@GOTPCREL(%%rip), %%rbx\n\t" \ ++ "callq *%%rbx\n\t" \ ++ "popq %%rbx\n\t" /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the -@@ -152,12 +159,12 @@ typedef struct +@@ -152,7 +163,7 @@ typedef struct _head->self = _thrdescr; \ \ /* It is a simple syscall to set the %fs value for the thread. */ \ @@ -1441,12 +1413,6 @@ index f3b7649..b466cb1 100644 : "=a" (_result) \ : "0" ((unsigned long int) __NR_arch_prctl), \ "D" ((unsigned long int) ARCH_SET_FS), \ - "S" (_thrdescr) \ -- : "memory", "cc", "r11", "cx"); \ -+ : "memory", "cc", "r11", "cx", "bx"); \ - \ - _result ? "cannot set %fs base address for thread-local storage" : 0; \ - }) diff --git a/LibOS/glibc-2.17/scripts/mkinstalldirs b/LibOS/glibc-2.17/scripts/mkinstalldirs index f945dbf..3c0e48c 100755 --- a/LibOS/glibc-2.17/scripts/mkinstalldirs diff --git a/LibOS/glibc-2.17/syscallas.S b/LibOS/glibc-2.17/syscallas.S index d33874a5..07c6ffce 100644 --- a/LibOS/glibc-2.17/syscallas.S +++ b/LibOS/glibc-2.17/syscallas.S @@ -1,15 +1,11 @@ #include -#ifdef WEAK_SYSCALLDB .weak syscalldb -#else -.global syscalldb -#endif .type syscalldb,@function syscalldb: .cfi_startproc syscall - ret -.cfi_endproc -.size syscalldb,.-syscalldb + retq + .cfi_endproc + .size syscalldb,.-syscalldb diff --git a/LibOS/glibc-2.17/syscalldb.h b/LibOS/glibc-2.17/syscalldb.h index e473f398..c8414474 100644 --- a/LibOS/glibc-2.17/syscalldb.h +++ b/LibOS/glibc-2.17/syscalldb.h @@ -1,23 +1,13 @@ #ifndef _SYSCALLDB_H_ #define _SYSCALLDB_H_ -#define WEAK_SYSCALLDB 1 - #ifdef __ASSEMBLER__ -# ifdef WEAK_SYSCALLDB .weak syscalldb -# else -.global syscalldb -# endif .type syscalldb, @function #else /* !__ASSEMBLER__ */ asm ( -# ifdef WEAK_SYSCALLDB ".weak syscalldb\r\n" -# else -".global syscalldb\r\n" -# endif ".type syscalldb, @function\r\n"); #endif /* Assembler */ diff --git a/LibOS/shim/include/shim_internal.h b/LibOS/shim/include/shim_internal.h index 3c97b487..a83d6b06 100644 --- a/LibOS/shim/include/shim_internal.h +++ b/LibOS/shim/include/shim_internal.h @@ -742,6 +742,8 @@ extern const char ** initial_envp; _stack; \ }) +void get_brk_region (void ** start, void ** end, void ** current); + int init_randgen (void); int init_brk (void); int init_heap (void); diff --git a/LibOS/shim/include/shim_thread.h b/LibOS/shim/include/shim_thread.h index cff47242..b4393296 100644 --- a/LibOS/shim/include/shim_thread.h +++ b/LibOS/shim/include/shim_thread.h @@ -265,21 +265,7 @@ void set_handle_map (struct shim_thread * thread, int thread_exit (struct shim_thread * self, bool send_ipc); int try_process_exit (int error_code); -/* thread cloning helpers */ -struct clone_args { - PAL_HANDLE create_event; - PAL_HANDLE initialize_event; - struct shim_thread * thread; - void * stack; - void * return_pc; -}; - -int clone_implementation_wrapper(struct clone_args * arg); - -int clean_held_locks (struct shim_thread * self); - void * allocate_stack (size_t size, size_t protect_size, bool user); - int populate_user_stack (void * stack, size_t stack_size, int nauxv, elf_auxv_t ** auxpp, const char *** argvp, const char *** envpp); diff --git a/LibOS/shim/include/shim_tls.h b/LibOS/shim/include/shim_tls.h index bbf2d176..4f6befff 100644 --- a/LibOS/shim/include/shim_tls.h +++ b/LibOS/shim/include/shim_tls.h @@ -32,13 +32,13 @@ struct shim_regs { unsigned long r15; unsigned long r14; unsigned long r13; + unsigned long r12; unsigned long r9; unsigned long r8; unsigned long rcx; unsigned long rdx; unsigned long rsi; unsigned long rdi; - unsigned long r12; unsigned long rbx; unsigned long rbp; }; diff --git a/LibOS/shim/include/shim_vma.h b/LibOS/shim/include/shim_vma.h index 1bc8ae92..565e50df 100644 --- a/LibOS/shim/include/shim_vma.h +++ b/LibOS/shim/include/shim_vma.h @@ -87,6 +87,8 @@ struct shim_vma * next_vma (struct shim_vma * vma); void * get_unmapped_vma (size_t len, int flags); +int dump_all_vmas (struct shim_thread * thread, char * buf, size_t size); + void unmap_all_vmas (void); /* Debugging */ diff --git a/LibOS/shim/src/Makefile b/LibOS/shim/src/Makefile index f32c4360..1ab95571 100644 --- a/LibOS/shim/src/Makefile +++ b/LibOS/shim/src/Makefile @@ -64,7 +64,7 @@ libsysdb.so: $(addsuffix .o,$(objs)) $(filter %.map %.lds,$(LDFLAGS)) \ $(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) -soname $@ \ -e shim_start -libsysdb_debug.so: $(addsuffix .o,$(objs)) \ +libsysdb_debug.so: $(addsuffix .o,$(filter-out syscallas,$(objs))) \ $(filter %.map %.lds,$($LDFLAGS-debug)) \ $(graphene_lib) $(pal_lib) @echo [ $@ ] diff --git a/LibOS/shim/src/bookkeep/shim_thread.c b/LibOS/shim/src/bookkeep/shim_thread.c index f7f595b9..c5d01469 100644 --- a/LibOS/shim/src/bookkeep/shim_thread.c +++ b/LibOS/shim/src/bookkeep/shim_thread.c @@ -231,6 +231,7 @@ struct shim_thread * get_new_thread (IDTYPE new_tid) thread->parent = cur_thread; thread->stack = cur_thread->stack; thread->stack_top = cur_thread->stack_top; + thread->stack_red = cur_thread->stack_red; thread->cwd = cur_thread->cwd; thread->root = cur_thread->root; thread->umask = cur_thread->umask; diff --git a/LibOS/shim/src/bookkeep/shim_vma.c b/LibOS/shim/src/bookkeep/shim_vma.c index 3e481ac8..1e9bd38d 100644 --- a/LibOS/shim/src/bookkeep/shim_vma.c +++ b/LibOS/shim/src/bookkeep/shim_vma.c @@ -282,6 +282,7 @@ static int __bkeep_mmap (void * addr, size_t length, prev->length = addr - prev->addr; } + assert(prev->addr + prev->length <= addr); cont = prev; pos = &prev->list; } else { /* has no precendent vma */ @@ -584,9 +585,12 @@ static int __bkeep_mprotect (void * addr, size_t length, int prot, /* no more vmas, protect the whole area */ ret = __bkeep_mmap((void *) addr, length, prot, VMA_UNMAPPED|(flags ? *flags : 0), - NULL, 0, "bkeep"); + NULL, 0, NULL); if (ret < 0) return ret; + + candidate = __lookup_vma((void *) addr, length); + assert(candidate); } length -= candidate->addr - addr; @@ -801,6 +805,73 @@ struct shim_vma * next_vma (struct shim_vma * vma) return tmp; } +int dump_all_vmas (struct shim_thread * thread, char * buf, size_t size) +{ + lock(vma_list_lock); + + struct shim_vma * vma; + int cnt = 0; + + list_for_each_entry(vma, &vma_list, list) { + void * start = vma->addr, * end = vma->addr + vma->length; + + if ((vma->flags & (VMA_INTERNAL|VMA_UNMAPPED)) && !vma->comment[0]) + continue; + + char prot[3] = {'-', '-', '-'}; + if (vma->prot & PROT_READ) + prot[0] = 'r'; + if (vma->prot & PROT_WRITE) + prot[1] = 'w'; + if (vma->prot & PROT_EXEC) + prot[2] = 'x'; + + if (vma->file) { + int dev_major = 0, dev_minor = 0; + unsigned long ino = vma->file->dentry ? vma->file->dentry->ino : 0; + const char * name = "[unknown]"; + + if (!qstrempty(&vma->file->path)) + name = qstrgetstr(&vma->file->path); + + cnt += snprintf(buf + cnt, size - cnt, + start > (void *) 0xffffffff ? "%lx" : "%08x", start); + + cnt += snprintf(buf + cnt, size - cnt, + end > (void *) 0xffffffff ? "-%lx" : "-%08x", end); + + cnt += snprintf(buf + cnt, size - cnt, + " %c%c%cp %08x %02d:%02d %u %s\n", + prot[0], prot[1], prot[2], + vma->offset, dev_major, dev_minor, ino, + name); + } else { + cnt += snprintf(buf + cnt, size - cnt, + start > (void *) 0xffffffff ? "%lx" : "%08x", start); + + cnt += snprintf(buf + cnt, size - cnt, + end > (void *) 0xffffffff ? "-%lx" : "-%08x", end); + + if (vma->comment[0]) + cnt += snprintf(buf + cnt, size - cnt, + " %c%c%cp 00000000 00:00 0 [%s]\n", + prot[0], prot[1], prot[2], vma->comment[0]); + else + cnt += snprintf(buf + cnt, size - cnt, + " %c%c%cp 00000000 00:00 0\n", + prot[0], prot[1], prot[2]); + } + + if (cnt >= size) { + cnt = -EOVERFLOW; + break; + } + } + + unlock(vma_list_lock); + return cnt; +} + void unmap_all_vmas (void) { struct shim_thread * cur_thread = get_cur_thread(); @@ -1085,12 +1156,10 @@ RESUME_FUNC_BODY(all_vmas) } END_RESUME_FUNC -void debug_print_vma_list () +void debug_print_vma_list (void) { sys_printf("vma bookkeeping:\n"); - lock(vma_list_lock); - struct shim_vma * vma; list_for_each_entry(vma, &vma_list, list) { const char * type = "", * name = ""; @@ -1116,8 +1185,6 @@ void debug_print_vma_list () vma->comment[0] ? " comment=" : "", vma->comment[0] ? vma->comment : ""); } - - unlock(vma_list_lock); } void print_vma_hash (struct shim_vma * vma, void * addr, int len, diff --git a/LibOS/shim/src/elf/shim_rtld.c b/LibOS/shim/src/elf/shim_rtld.c index 90b123bc..df73787d 100644 --- a/LibOS/shim/src/elf/shim_rtld.c +++ b/LibOS/shim/src/elf/shim_rtld.c @@ -339,23 +339,6 @@ void setup_elf_hash (struct link_map * map) map->l_chain = hash; } -static const char * __obj_type_str (int type, struct link_map * remap) -{ - switch (type) { - case OBJECT_INTERNAL: - return "elf-internal"; - case OBJECT_LOAD: - return "elf-load"; - case OBJECT_MAPPED: - return "elf-mapped"; - case OBJECT_REMAP: - return __obj_type_str(remap->l_type, NULL); - case OBJECT_USER: - return "elf-user"; - } - return NULL; -} - /* Map in the shared object NAME, actually located in REALNAME, and already opened on FD */ static struct link_map * @@ -376,7 +359,6 @@ __map_elf_object (struct shim_handle * file, if (file && (!read || !mmap || !seek)) return NULL; - const char * obj_type = __obj_type_str(type, remap); struct link_map * l = remap ? : new_elf_object(file ? (!qstrempty(&file->path) ? qstrgetstr(&file->path) : @@ -404,6 +386,7 @@ call_lose: /* Extract the remaining details we need from the ELF header and then read in the program header table. */ + l->l_addr = (ElfW(Addr)) addr; l->l_entry = header->e_entry; int e_type = header->e_type; l->l_phnum = header->e_phnum; @@ -438,7 +421,7 @@ call_lose: break; case PT_INTERP: - l->l_interp_libname = ((const char *) l->l_addr + ph->p_vaddr); + l->l_interp_libname = (const char *) ph->p_vaddr; break; case PT_PHDR: @@ -559,7 +542,7 @@ map_error: bkeep_mmap((void *) mappref, ALIGN_UP(maplength), c->prot, c->flags|MAP_PRIVATE| (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0), - file, c->mapoff, obj_type); + file, c->mapoff, NULL); l->l_addr = l->l_map_start - c->mapstart; @@ -593,6 +576,7 @@ map_error: } /* Remember which part of the address space this object uses. */ + l->l_addr = 0; l->l_map_start = c->mapstart; l->l_map_end = l->l_map_start + maplength; @@ -615,7 +599,7 @@ do_remap: bkeep_mmap(mapaddr, c->mapend - c->mapstart, c->prot, c->flags|MAP_FIXED|MAP_PRIVATE| (type == OBJECT_INTERNAL ? VMA_INTERNAL : 0), - file, c->mapoff, obj_type); + file, c->mapoff, NULL); } postmap: @@ -1143,12 +1127,12 @@ static int __load_elf_object (struct shim_handle * file, void * addr, add_link_map(map); } - if ((type == OBJECT_LOAD || type == OBJECT_REMAP) && + if ((type == OBJECT_LOAD || type == OBJECT_REMAP || type == OBJECT_USER) && map->l_file && !qstrempty(&map->l_file->uri)) { if (type == OBJECT_REMAP) remove_r_debug((void *) map->l_addr); - append_r_debug(qstrgetstr(&map->l_file->uri), (void *) map->l_addr, + append_r_debug(qstrgetstr(&map->l_file->uri), (void *) map->l_map_start, (void *) map->l_real_ld); } @@ -1440,7 +1424,8 @@ int free_elf_interp (void) static int __load_interp_object (struct link_map * exec_map) { - const char * interp_name = exec_map->l_interp_libname; + const char * interp_name = (const char *) exec_map->l_interp_libname + + (long) exec_map->l_addr; int len = strlen(interp_name); const char * filename = interp_name + len - 1; while (filename > interp_name && *filename != '/') diff --git a/LibOS/shim/src/fs/chroot/fs.c b/LibOS/shim/src/fs/chroot/fs.c index 2531b730..7caddcf5 100644 --- a/LibOS/shim/src/fs/chroot/fs.c +++ b/LibOS/shim/src/fs/chroot/fs.c @@ -595,7 +595,7 @@ static inline int __map_buffer (struct shim_handle * hdl, int size) return -PAL_ERRNO; bkeep_mmap(mapbuf, maplen, prot, MAP_FILE|MAP_SHARED|VMA_INTERNAL, - hdl, mapoff, "chroot-buffer"); + hdl, mapoff, NULL); file->mapbuf = mapbuf; file->mapoffset = mapoff; @@ -706,14 +706,26 @@ static int chroot_read (struct shim_handle * hdl, void * buf, goto out; } - if (hdl->info.file.buf_type == FILEBUF_MAP) { + struct shim_file_handle * file = &hdl->info.file; + + if (file->buf_type == FILEBUF_MAP) { ret = map_read(hdl, buf, count); - goto out; + if (ret != -EACCES) + goto out; + + lock(hdl->lock); + file->buf_type = FILEBUF_NONE; + } else { + lock(hdl->lock); } - ret = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0) ? : + ret = DkStreamRead(hdl->pal_handle, file->marker, count, buf, NULL, 0) ? : (PAL_NATIVE_ERRNO == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO); + if (ret > 0) + file->marker += ret; + + unlock(hdl->lock); out: return ret; } @@ -730,13 +742,26 @@ static int chroot_write (struct shim_handle * hdl, const void * buf, goto out; } + struct shim_file_handle * file = &hdl->info.file; + if (hdl->info.file.buf_type == FILEBUF_MAP) { ret = map_write(hdl, buf, count); + if (ret != -EACCES) + goto out; + + lock(hdl->lock); + file->buf_type = FILEBUF_NONE; } else { - ret = DkStreamWrite(hdl->pal_handle, 0, count, buf, NULL) ? : - -PAL_ERRNO; + lock(hdl->lock); } + ret = DkStreamWrite(hdl->pal_handle, file->marker, count, buf, NULL) ? : + -PAL_ERRNO; + + if (ret > 0) + file->marker += ret; + + unlock(hdl->lock); out: return ret; @@ -804,9 +829,7 @@ static int chroot_seek (struct shim_handle * hdl, off_t offset, int wence) break; case SEEK_END: - if (offset < 0) - goto out; - marker = size - offset; + marker = size + offset; break; } diff --git a/LibOS/shim/src/fs/proc/thread.c b/LibOS/shim/src/fs/proc/thread.c index 7b62ca15..5450cce4 100644 --- a/LibOS/shim/src/fs/proc/thread.c +++ b/LibOS/shim/src/fs/proc/thread.c @@ -11,11 +11,14 @@ #include #include +#include #include #include #include #include +#define DEFAULT_BUFFER_SIZE 256 + static int parse_thread_name (const char * name, const char ** next, int * next_len, const char ** nextnext) @@ -461,6 +464,100 @@ static const struct proc_dir dir_fd = { .size = 1, .ent = { { .nm_ops = &nm_thread_each_fd, .fs_ops = &fs_thread_each_fd, }, }, }; +static int proc_thread_maps_open (struct shim_handle * hdl, + const char * name, int flags) +{ + if (flags & (O_WRONLY|O_RDWR)) + return -EACCES; + + const char * next; + int next_len; + int pid = parse_thread_name(name, &next, &next_len, NULL); + + if (pid < 0) + return pid; + + struct shim_thread * thread = lookup_thread(pid); + + if (!thread) + return -ENOENT; + + int size = DEFAULT_BUFFER_SIZE; + char * strbuf = malloc(size); + int ret = 0, len = 0; + + if (!strbuf) { + ret = -ENOMEM; + goto out; + } + +retry: + ret = dump_all_vmas(thread, strbuf, size); + + if (ret == -EOVERFLOW) { + char * newbuf = malloc(size * 2); + if (!newbuf) { + ret = -ENOMEM; + goto err; + } + free(strbuf); + strbuf = newbuf; + size *= 2; + goto retry; + } + + if (ret < 0) + goto err; + + len = ret; + + struct shim_str_data * data = malloc(sizeof(struct shim_str_data)); + if (!data) { + ret = -ENOMEM; + goto err; + } + + memset(data, 0, sizeof(struct shim_str_data)); + data->str = strbuf; + data->len = len; + hdl->type = TYPE_STR; + hdl->flags = flags & ~O_RDONLY; + hdl->acc_mode = MAY_READ; + hdl->info.str.data = data; + ret = 0; +out: + put_thread(thread); + return ret; +err: + free(strbuf); + goto out; +} + +static int proc_thread_maps_mode (const char * name, mode_t * mode) +{ + *mode = 0400; + return 0; +} + +static int proc_thread_maps_stat (const char * name, struct stat * buf) +{ + memset(buf, 0, sizeof(struct stat)); + + buf->st_dev = buf->st_ino = 1; + buf->st_mode = 0400|S_IFREG; + buf->st_uid = 0; + buf->st_gid = 0; + buf->st_size = 0; + + return 0; +} + +static const struct proc_fs_ops fs_thread_maps = { + .open = &proc_thread_maps_open, + .mode = &proc_thread_maps_mode, + .stat = &proc_thread_maps_stat, + }; + static int proc_thread_dir_mode (const char * name, mode_t * mode) { const char * next; @@ -570,4 +667,5 @@ const struct proc_dir dir_thread = { .size = 5, .ent = { { .name = "exe", .fs_ops = &fs_thread_link, }, { .name = "root", .fs_ops = &fs_thread_link, }, { .name = "fd", .dir = &dir_fd, .fs_ops = &fs_thread_fd, }, + { .name = "maps", .fs_ops = &fs_thread_maps, }, }, }; diff --git a/LibOS/shim/src/ipc/shim_ipc_nsimpl.h b/LibOS/shim/src/ipc/shim_ipc_nsimpl.h index 086a0b7a..2b36d05d 100644 --- a/LibOS/shim/src/ipc/shim_ipc_nsimpl.h +++ b/LibOS/shim/src/ipc/shim_ipc_nsimpl.h @@ -639,7 +639,7 @@ IDTYPE CONCAT2(allocate, NS) (IDTYPE min, IDTYPE max) for ( ; j < BITS ; f <<= 1, j++) if (!(map & f)) { (*m) |= f; - idx = base + i * RANGE_SIZE + j; + idx = base + i * BITS + j; debug("allocated " NS_STR ": %u\n", idx); goto out; } diff --git a/LibOS/shim/src/shim.map b/LibOS/shim/src/shim.map index c93e8050..715e95e2 100644 --- a/LibOS/shim/src/shim.map +++ b/LibOS/shim/src/shim.map @@ -1,8 +1,6 @@ SHIM { global: - syscalldb; - __libc_r_debug; __libc_dl_debug_state; - glibc_vers_2_17; - register_library; + syscalldb; register_library; + glibc_vers_*; local: *; }; diff --git a/LibOS/shim/src/shim_checkpoint.c b/LibOS/shim/src/shim_checkpoint.c index 683daee3..623ea8b1 100644 --- a/LibOS/shim/src/shim_checkpoint.c +++ b/LibOS/shim/src/shim_checkpoint.c @@ -875,7 +875,7 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr) bkeep_mmap(cpaddr, ALIGN_UP(cpsize), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, - NULL, 0, "migrated"); + NULL, 0, NULL); SAVE_PROFILE_INTERVAL(child_load_checkpoint_by_gipc); @@ -897,7 +897,7 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr) bkeep_mmap(cpaddr, cpsize_pgalign, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, - NULL, 0, "migrated"); + NULL, 0, NULL); cpaddr -= cpaddr_pgalign; @@ -944,8 +944,8 @@ int init_checkpoint (struct newproc_cp_header * hdr, void ** cpptr) void restore_context (struct shim_context * context) { - int nregs = sizeof(struct shim_regs) / sizeof(unsigned long); - unsigned long regs[nregs + 1]; + int nregs = sizeof(struct shim_regs) / sizeof(void *); + void * regs[nregs + 1]; if (context->regs) memcpy(regs, context->regs, sizeof(struct shim_regs)); @@ -954,7 +954,8 @@ void restore_context (struct shim_context * context) debug("restore context: SP = %p, IP = %p\n", context->sp, context->ret_ip); - regs[nregs] = (unsigned long) context->sp; + regs[nregs] = (void *) context->sp - 8; + *(void **) (context->sp - 8) = context->ret_ip; memset(context, 0, sizeof(struct shim_context)); @@ -962,13 +963,13 @@ void restore_context (struct shim_context * context) "popq %%r15\r\n" "popq %%r14\r\n" "popq %%r13\r\n" + "popq %%r12\r\n" "popq %%r9\r\n" "popq %%r8\r\n" "popq %%rcx\r\n" "popq %%rdx\r\n" "popq %%rsi\r\n" "popq %%rdi\r\n" - "popq %%r12\r\n" "popq %%rbx\r\n" "popq %%rbp\r\n" "popq %%rsp\r\n" diff --git a/LibOS/shim/src/shim_debug.c b/LibOS/shim/src/shim_debug.c index fafe2f48..57564644 100644 --- a/LibOS/shim/src/shim_debug.c +++ b/LibOS/shim/src/shim_debug.c @@ -44,171 +44,44 @@ struct gdb_link_map struct gdb_link_map *l_next, *l_prev; }; -struct gdb_r_debug -{ - int r_version; - struct gdb_link_map *r_map; - uintptr_t r_brk; - enum - { - RT_CONSISTENT, - RT_ADD, - RT_DELETE, - } r_state; - uintptr_t r_ldbase; -}; - -struct gdb_r_debug __libc_r_debug; - -extern struct gdb_r_debug _r_debug; -extern void _dl_debug_state_trigger (void); - static struct gdb_link_map * link_map_list = NULL; -static inline char * translate_file_path (const char * path) -{ - struct shim_dentry * dent = NULL; - - int ret = path_lookupat(NULL, path, 0, &dent); - if (ret < 0) - return NULL; - - struct shim_mount * fs = dent->fs; - - if (!fs->d_ops->open) - return NULL; - - char * new_uri = NULL; - struct shim_handle * hdl = get_new_handle(); - if (!hdl) - return NULL; - - set_handle_fs(hdl, fs); - hdl->dentry = dent; - - ret = fs->d_ops->open(hdl, dent, O_RDONLY); - if (ret < 0) - goto out; - - new_uri = qstrtostr(&hdl->uri, false); -out: - put_handle(hdl); - return new_uri; -} - -void __libc_dl_debug_state (void) -{ - /* first make sure libc map list matches the shadow map list */ - if (link_map_list) { - struct gdb_link_map *m = link_map_list, *n; - for ( ; m ; m = m->l_next) { - for (n = __libc_r_debug.r_map ; n ; n = n->l_next) - if (m->l_addr == n->l_addr) - break; - if (!n) { - if (m->l_prev) - m->l_prev->l_next = m->l_next; - if (m->l_next) - m->l_next->l_prev = m->l_prev; - if (m == link_map_list) - link_map_list = m->l_next; - } - } - } - - /* now find the end of the shadow map list, where we are adding to */ - struct gdb_link_map *prev = NULL; - struct gdb_link_map **tail = &_r_debug.r_map; - - while (*tail) { - prev = *tail; - tail = &(*tail)->l_next; - } - - /* add new maps to the shadow map list */ - struct gdb_link_map **t = tail; - struct gdb_link_map *m = __libc_r_debug.r_map; - - for ( ; m ; m = m->l_next) { - struct gdb_link_map *re = _r_debug.r_map; - while (re && re->l_addr != m->l_addr) - re = re->l_next; - - if (re) - continue; - - char * uri = translate_file_path(m->l_name); - if (!uri) - continue; - debug("add a library for gdb: %s\n", uri); - - struct gdb_link_map * new = malloc(sizeof(struct gdb_link_map)); - - new->l_addr = m->l_addr; - new->l_ld = m->l_ld; - new->l_name = uri; - new->l_prev = prev; - prev = *t = new; - new->l_next = NULL; - t = &new->l_next; - } - - if (!link_map_list) - link_map_list = *tail; - - _r_debug.r_state = __libc_r_debug.r_state; - _dl_debug_state_trigger(); -} - void clean_link_map_list (void) { if (!link_map_list) return; - _r_debug.r_state = RT_DELETE; - _dl_debug_state_trigger(); - if (link_map_list->l_prev) link_map_list->l_prev->l_next = NULL; - if (_r_debug.r_map == link_map_list) - _r_debug.r_map = NULL; struct gdb_link_map * m = link_map_list; - for ( ; m ; m = m->l_next) + for ( ; m ; m = m->l_next) { + DkDebugDetachBinary(m->l_addr); free(m); + } link_map_list = NULL; - - _r_debug.r_state = RT_CONSISTENT; - _dl_debug_state_trigger(); - } void remove_r_debug (void * addr) { - struct gdb_link_map * m = _r_debug.r_map; + struct gdb_link_map * m = link_map_list; - for ( ; m && m != link_map_list ; m = m->l_next) + for ( ; m ; m = m->l_next) if (m->l_addr == addr) break; - if (!m || m == link_map_list) + if (!m) return; - _r_debug.r_state = RT_DELETE; - _dl_debug_state_trigger(); - debug("remove a library for gdb: %s\n", m->l_name); if (m->l_prev) m->l_prev->l_next = m->l_next; if (m->l_next) m->l_next->l_prev = m->l_prev; - if (_r_debug.r_map == m) - _r_debug.r_map = m->l_next; - _r_debug.r_state = RT_CONSISTENT; - _dl_debug_state_trigger(); + DkDebugDetachBinary(addr); } void append_r_debug (const char * uri, void * addr, void * dyn_addr) @@ -224,26 +97,20 @@ void append_r_debug (const char * uri, void * addr, void * dyn_addr) new->l_name = new_uri; struct gdb_link_map *prev = NULL; - struct gdb_link_map **tail = &_r_debug.r_map; + struct gdb_link_map **tail = &link_map_list; - while (*tail && *tail != link_map_list) { + while (*tail) { prev = *tail; tail = &(*tail)->l_next; } - _r_debug.r_state = RT_ADD; - _dl_debug_state_trigger(); - - debug("add a library for gdb: %s\n", new->l_name); + debug("add a library for gdb: %s\n", uri); new->l_prev = prev; - new->l_next = link_map_list; + new->l_next = NULL; *tail = new; - if (link_map_list) - link_map_list->l_prev = new; - _r_debug.r_state = RT_CONSISTENT; - _dl_debug_state_trigger(); + DkDebugAttachBinary(uri, addr); } DEFINE_MIGRATE_FUNC(gdb_map) @@ -278,10 +145,6 @@ END_MIGRATE_FUNC RESUME_FUNC_BODY(gdb_map) { uint64_t off = GET_FUNC_ENTRY(); - - _r_debug.r_state = RT_ADD; - _dl_debug_state_trigger (); - struct gdb_link_map *map = (struct gdb_link_map *) (base + off); RESUME_REBASE(map->l_name); @@ -299,20 +162,10 @@ RESUME_FUNC_BODY(gdb_map) map->l_prev = prev; *tail = map; - tail = &_r_debug.r_map; - while (*tail && *tail != link_map_list) { - prev = *tail; - tail = &(*tail)->l_next; - } - - *tail = link_map_list; - link_map_list->l_prev = prev; - #ifdef DEBUG_RESUME debug("gdb: %s loaded at %p\n", map->l_name, map->l_addr); #endif - _r_debug.r_state = RT_CONSISTENT; - _dl_debug_state_trigger (); + DkDebugAttachBinary(map->l_name, map->l_addr); } END_RESUME_FUNC diff --git a/LibOS/shim/src/shim_init.c b/LibOS/shim/src/shim_init.c index ab99e824..5e5d9be8 100644 --- a/LibOS/shim/src/shim_init.c +++ b/LibOS/shim/src/shim_init.c @@ -148,6 +148,9 @@ void allocate_tls (void * tcb_location, struct shim_thread * thread) thread->tcb = tcb; tcb->shim_tcb.tp = thread; tcb->shim_tcb.tid = thread->tid; + } else { + tcb->shim_tcb.tp = NULL; + tcb->shim_tcb.tid = 0; } DkThreadPrivate(tcb); @@ -210,7 +213,7 @@ void * allocate_stack (size_t size, size_t protect_size, bool user) if (protect_size && bkeep_mmap(stack - protect_size, protect_size, 0, - STACK_FLAGS, NULL, 0, "stack-red") < 0) + STACK_FLAGS, NULL, 0, NULL) < 0) return NULL; } @@ -394,7 +397,8 @@ int init_manifest (PAL_HANDLE manifest_handle) size_t cfg_size = attr.size; void * cfg_addr = DkStreamMap(manifest_handle, NULL, - PAL_PROT_READ, 0, ALIGN_UP(cfg_size)); + PAL_PROT_READ|PAL_PROT_WRITECOPY, 0, + ALIGN_UP(cfg_size)); if (!cfg_addr) return -PAL_ERRNO; @@ -583,6 +587,7 @@ int shim_init (int argc, void * args, void ** return_stack) /* create the initial TCB, shim can not be run without a tcb */ __libc_tcb_t tcb; + memset(&tcb, 0, sizeof(__libc_tcb_t)); allocate_tls(&tcb, NULL); debug_setbuf(&tcb.shim_tcb, true); @@ -920,6 +925,23 @@ int create_handle (const char * prefix, char * uri, size_t size, id ? : &suffix, hdl, NULL); } +void check_stack_hook (void) +{ + struct shim_thread * cur_thread = get_cur_thread(); + + void * rsp; + asm volatile ("movq %%rsp, %0" : "=r"(rsp) :: "memory"); + + if (rsp <= cur_thread->stack_top && rsp > cur_thread->stack) { + if (rsp - cur_thread->stack < PAL_CB(pagesize)) + sys_printf("*** stack is almost drained (RSP = %p, stack = %p-%p) ***\n", + rsp, cur_thread->stack, cur_thread->stack_top); + } else { + sys_printf("*** context dismateched with thread stack (RSP = %p, stack = %p-%p) ***\n", + rsp, cur_thread->stack, cur_thread->stack_top); + } +} + #ifdef PROFILE static void print_profile_result (PAL_HANDLE hdl, struct shim_profile * root, int level) diff --git a/LibOS/shim/src/shim_malloc.c b/LibOS/shim/src/shim_malloc.c index 8ef90a89..c279e2a5 100644 --- a/LibOS/shim/src/shim_malloc.c +++ b/LibOS/shim/src/shim_malloc.c @@ -111,9 +111,7 @@ static struct shim_heap * __alloc_enough_heap (size_t size) unlock(shim_heap_lock); bkeep_mmap(start, heap_size, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, - "shim-heap"); - + MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL); lock(shim_heap_lock); } @@ -175,8 +173,7 @@ int bkeep_shim_heap (void) bkeep_mmap(shim_heap_areas[i].start, shim_heap_areas[i].end - shim_heap_areas[i].start, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, - "shim-heap"); + MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL); unlock(shim_heap_lock); return 0; diff --git a/LibOS/shim/src/shim_parser.c b/LibOS/shim/src/shim_parser.c index b9b024aa..692ae39f 100644 --- a/LibOS/shim/src/shim_parser.c +++ b/LibOS/shim/src/shim_parser.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ static void parse_open_flags (const char *, va_list); static void parse_open_mode (const char *, va_list); static void parse_access_mode (const char *, va_list); +static void parse_clone_flags (const char *, va_list); static void parse_mmap_prot (const char *, va_list); static void parse_mmap_flags (const char *, va_list); static void parse_exec_args (const char *, va_list); @@ -130,7 +132,7 @@ struct parser_table { .parser = { NULL, NULL, NULL, &parse_pipe_fds } }, { .slow = 0, .parser = { NULL } }, /* setsockopt */ { .slow = 0, .parser = { NULL } }, /* getsockopt */ - { .slow = 1, .parser = { NULL } }, /* clone */ + { .slow = 1, .parser = { &parse_clone_flags } }, /* clone */ { .slow = 1, .parser = { NULL } }, /* fork */ { .slow = 1, .parser = { NULL } }, /* vfork */ { .slow = 1, /* execve */ @@ -612,6 +614,37 @@ static void parse_access_mode (const char * type, va_list ap) } } +static void parse_clone_flags (const char * type, va_list ap) +{ + int flags = va_arg (ap, int); + +#define FLG(n) { "CLONE_" #n, CLONE_##n, } + const struct { + const char * name; int flag; + } all_flags[] = { + FLG(VM), FLG(FS), FLG(FILES), FLG(SIGHAND), FLG(PTRACE), FLG(VFORK), + FLG(PARENT), FLG(THREAD), FLG(NEWNS), FLG(SYSVSEM), FLG(SETTLS), + FLG(PARENT_SETTID), FLG(CHILD_CLEARTID), FLG(DETACHED), FLG(UNTRACED), + FLG(CHILD_SETTID), FLG(NEWUTS), FLG(NEWIPC), FLG(NEWUSER), + FLG(NEWPID), FLG(NEWNET), FLG(IO), + }; +#undef FLG + + bool printed = false; + for (int i = 0 ; i < sizeof(all_flags) / sizeof(all_flags[0]) ; i++) + if (flags & all_flags[i].flag) { + if (printed) + PUTCH('|'); + else + printed = true; + PUTS(all_flags[i].name); + flags &= ~all_flags[i].flag; + } + + if (flags) + PRINTF("|0x%x", flags); +} + static void parse_mmap_prot (const char * type, va_list ap) { int prot = va_arg (ap, int); @@ -650,23 +683,36 @@ static void parse_mmap_flags (const char * type, va_list ap) PUTS("MAP_SHARED"); flags &= ~MAP_SHARED; } - else + + if (flags & MAP_PRIVATE) { PUTS("MAP_PRIVATE"); + flags &= ~MAP_PRIVATE; + } if (flags & MAP_ANONYMOUS) { PUTS("|MAP_ANON"); flags &= ~MAP_ANONYMOUS; } - else + + if (flags & MAP_FILE) { PUTS("|MAP_FILE"); + flags &= ~MAP_FILE; + } if (flags & MAP_FIXED) { PUTS("|MAP_FIXED"); flags &= ~MAP_FIXED; } +#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED + if (flags & MAP_UNINITIALIZED) { + PUTS("|MAP_UNINITIALIZED"); + flags &= ~MAP_UNINITIALIZED; + } +#endif + if (flags) - PRINTF("|%o", flags); + PRINTF("|0x%x", flags); } static void parse_exec_args (const char * type, va_list ap) @@ -884,7 +930,7 @@ static void parse_futexop (const char * type, va_list ap) PUTS("FUTEX_CMP_REQUEUE"); break; case FUTEX_WAKE_OP: - PUTS("FUTEX_WAKE"); + PUTS("FUTEX_WAKE_OP"); break; default: PRINTF("OP %d", op); diff --git a/LibOS/shim/src/sys/shim_brk.c b/LibOS/shim/src/sys/shim_brk.c index a8dc9a9f..76e4b4e1 100644 --- a/LibOS/shim/src/sys/shim_brk.c +++ b/LibOS/shim/src/sys/shim_brk.c @@ -50,6 +50,15 @@ DEFINE_PROFILE_OCCURENCE(brk, memory); DEFINE_PROFILE_OCCURENCE(brk_count, memory); DEFINE_PROFILE_OCCURENCE(brk_migrate_count, memory); +void get_brk_region (void ** start, void ** end, void ** current) +{ + master_lock(); + *start = region.brk_start; + *end = region.brk_end; + *current = region.brk_current; + master_unlock(); +} + int init_brk_region (void) { if (region.brk_start) @@ -88,11 +97,11 @@ int init_brk_region (void) brk_region + brk_max_size); bkeep_mmap(brk_region, BRK_SIZE, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "brk"); + MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "[heap]"); bkeep_mmap(end_brk_region, brk_max_size - BRK_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED, - NULL, 0, "brk-reserved"); + NULL, 0, NULL); return 0; } @@ -148,7 +157,7 @@ unchanged: bkeep_mmap(region.brk_start, brk_end - region.brk_start, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "brk"); + MAP_ANONYMOUS|MAP_PRIVATE, NULL, 0, "heap"); region.brk_current = brk; region.brk_end = brk_end; @@ -203,7 +212,7 @@ RESUME_FUNC_BODY(brk) bkeep_mmap(region.brk_end, brk_max_size - brk_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|VMA_UNMAPPED, NULL, 0, - "brk-reserved"); + NULL); } #ifdef DEBUG_RESUME diff --git a/LibOS/shim/src/sys/shim_clone.c b/LibOS/shim/src/sys/shim_clone.c index 947c64e9..4df9e674 100644 --- a/LibOS/shim/src/sys/shim_clone.c +++ b/LibOS/shim/src/sys/shim_clone.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,14 @@ #include #include +struct clone_args { + PAL_HANDLE create_event; + PAL_HANDLE initialize_event; + struct shim_thread * thread, * parent; + void * stack; + void * return_pc; +}; + /* from **sysdeps/unix/sysv/linux/x86_64/clone.S: The userland implementation is: int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg), @@ -96,10 +105,17 @@ int clone_implementation_wrapper(struct clone_args * arg) assert(my_thread); get_thread(my_thread); - if (my_thread->set_child_tid) { + if (!my_thread->tcb) + my_thread->tcb = __alloca(sizeof(__libc_tcb_t)); + allocate_tls(my_thread->tcb, my_thread); + shim_tcb_t * tcb = &((__libc_tcb_t *) my_thread->tcb)->shim_tcb; + debug_setbuf(tcb, true); + + struct shim_regs * regs = __alloca(sizeof(struct shim_regs)); + *regs = *((__libc_tcb_t *) arg->parent->tcb)->shim_tcb.context.regs; + + if (my_thread->set_child_tid) *(my_thread->set_child_tid) = my_thread->tid; - debug("clone: tid set at %p\n", my_thread->set_child_tid); - } void * stack = pcargs->stack; void * return_pc = pcargs->return_pc; @@ -107,12 +123,9 @@ int clone_implementation_wrapper(struct clone_args * arg) struct shim_vma * vma = NULL; lookup_supervma(ALIGN_DOWN(stack), allocsize, &vma); assert(vma); - my_thread->stack_top = stack; + my_thread->stack_top = vma->addr + vma->length; my_thread->stack_red = my_thread->stack = vma->addr; - - __libc_tcb_t tcb; - allocate_tls(&tcb, my_thread); - debug_setbuf(&tcb.shim_tcb, true); + snprintf(vma->comment, VMA_COMMENT_LEN, "stack:%d", my_thread->tid); /* Don't signal the initialize event until we are actually init-ed */ DkEventSet(pcargs->initialize_event); @@ -125,13 +138,18 @@ int clone_implementation_wrapper(struct clone_args * arg) debug("child swapping stack to %p return %p: %d\n", stack, return_pc, my_thread->tid); - asm volatile("movq %0, %%rsp\r\n" - "pushq %1\r\n" - "retq\r\n" - : : "r"(stack), "r"(return_pc), "a"(0)); + tcb->context.regs = regs; + tcb->context.sp = stack; + tcb->context.ret_ip = return_pc; + + restore_context(&tcb->context); return 0; } +int migrate_fork (struct shim_cp_store * cpstore, + struct shim_process * process, + struct shim_thread * thread, va_list ap); + /* long int __arg0 - flags * long int __arg1 - 16 bytes ( 2 words ) offset into the child stack allocated * by the parent */ @@ -144,8 +162,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr, INC_PROFILE_OCCURENCE(syscall_use_ipc); struct shim_thread * self = get_cur_thread(); assert(self); - struct clone_args * new_args = __alloca(sizeof(struct clone_args)); - memset(new_args, 0, sizeof(struct clone_args)); + int * set_parent_tid = NULL; int ret = 0; assert((flags & ~(CLONE_PARENT_SETTID|CLONE_CHILD_SETTID| @@ -158,67 +175,58 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr, #endif CLONE_SYSVSEM|CSIGNAL)) == 0); - new_args->create_event = DkNotificationEventCreate(0); - if (!new_args->create_event) { - ret = -PAL_ERRNO; - goto failed; + if (!(flags & CLONE_FS)) + debug("clone without CLONE_FS is not yet implemented\n"); + + if (!(flags & CLONE_SIGHAND)) + debug("clone without CLONE_SIGHAND is not yet implemented\n"); + + if (!(flags & CLONE_SYSVSEM)) + debug("clone without CLONE_SYSVSEM is not yet implemented\n"); + + if (flags & CLONE_PARENT_SETTID) { + if (!parent_tidptr) + return -EINVAL; + set_parent_tid = parent_tidptr; } - new_args->initialize_event = DkNotificationEventCreate(0); - if (!new_args->initialize_event) { - ret = -PAL_ERRNO; - goto failed; - } - - new_args->thread = get_new_thread(0); - if (!new_args->thread) { + struct shim_thread * thread = get_new_thread(0); + if (!thread) { ret = -ENOMEM; goto failed; } - new_args->stack = user_stack_addr; - new_args->return_pc = *(void **) user_stack_addr; + IDTYPE tid = thread->tid; - if (flags & CLONE_PARENT_SETTID) - new_args->thread->set_child_tid = parent_tidptr; - - if ((flags & CLONE_CHILD_SETTID) && (flags & CLONE_CHILD_CLEARTID)) { - ret = -EINVAL; - goto failed; + if (flags & CLONE_CHILD_SETTID) { + if (!child_tidptr) { + ret = -EINVAL; + goto failed; + } + thread->set_child_tid = child_tidptr; } - if (flags & CLONE_CHILD_SETTID) - new_args->thread->set_child_tid = child_tidptr; - if (flags & CLONE_CHILD_CLEARTID) /* Implemented in shim_futex.c: release_clear_child_id */ - new_args->thread->clear_child_tid = parent_tidptr; + thread->clear_child_tid = parent_tidptr; if (flags & CLONE_SETTLS) { - new_args->thread->tcb = tls; + if (!tls) { + ret = -EINVAL; + goto failed; + } + thread->tcb = tls; } else { - new_args->thread->tcb = NULL; + thread->tcb = NULL; } - if ((flags & CLONE_VM) != CLONE_VM) - debug("Fork-like behavior is not yet implemented in clone\n"); - - if ((flags & CLONE_FS) != CLONE_FS) - debug("clone without CLONE_FS is not yet implemented\n"); - - if ((flags & CLONE_SIGHAND) != CLONE_SIGHAND) - debug("clone without CLONE_SIGHAND is not yet implemented\n"); - - if ((flags & CLONE_SYSVSEM) != CLONE_SYSVSEM) - debug("clone without CLONE_SYSVSEM is not yet implemented\n"); - - if ((flags & CLONE_THREAD) != CLONE_THREAD) - new_args->thread->tgid = new_args->thread->tid; + if (!(flags & CLONE_THREAD)) + thread->tgid = thread->tid; struct shim_handle_map * handle_map = get_cur_handle_map(self); if (flags & CLONE_FILES) { - set_handle_map(new_args->thread, handle_map); + set_handle_map(thread, handle_map); } else { /* if CLONE_FILES is not given, the new thread should receive a copy of current descriptor table */ @@ -226,10 +234,81 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr, get_handle_map(handle_map); dup_handle_map(&new_map, handle_map); - set_handle_map(new_args->thread, new_map); + set_handle_map(thread, new_map); put_handle_map(handle_map); } + if (!(flags & CLONE_VM)) { + __libc_tcb_t * tcb; + shim_tcb_t * old_shim_tcb = NULL; + + if (thread->tcb) { + tcb = (__libc_tcb_t *) thread->tcb; + } else { + thread->tcb = tcb = (__libc_tcb_t *) self->tcb; + old_shim_tcb = __alloca(sizeof(shim_tcb_t)); + memcpy(old_shim_tcb, &tcb->shim_tcb, sizeof(shim_tcb_t)); + } + + if (user_stack_addr) { + struct shim_vma * vma = NULL; + lookup_supervma(ALIGN_DOWN(user_stack_addr), allocsize, &vma); + assert(vma); + thread->stack_top = vma->addr + vma->length; + thread->stack_red = thread->stack = vma->addr; + tcb->shim_tcb.context.sp = user_stack_addr; + tcb->shim_tcb.context.ret_ip = *(void **) user_stack_addr; + } else { + tcb->shim_tcb.context.ret_ip = *(void **) tcb->shim_tcb.context.sp; + } + + thread->is_alive = true; + thread->in_vm = false; + add_thread(thread); + set_as_child(self, thread); + + if ((ret = do_migrate_process(&migrate_fork, NULL, NULL, thread)) < 0) + goto failed; + + if (old_shim_tcb) + memcpy(&tcb->shim_tcb, old_shim_tcb, sizeof(shim_tcb_t)); + + lock(thread->lock); + handle_map = thread->handle_map; + thread->handle_map = NULL; + unlock(thread->lock); + if (handle_map) + put_handle_map(handle_map); + + if (set_parent_tid) + *set_parent_tid = tid; + + put_thread(thread); + return tid; + } + + enable_locking(); + + struct clone_args * new_args = __alloca(sizeof(struct clone_args)); + memset(new_args, 0, sizeof(struct clone_args)); + + new_args->create_event = DkNotificationEventCreate(0); + if (!new_args->create_event) { + ret = -PAL_ERRNO; + goto clone_thread_failed; + } + + new_args->initialize_event = DkNotificationEventCreate(0); + if (!new_args->initialize_event) { + ret = -PAL_ERRNO; + goto clone_thread_failed; + } + + new_args->thread = thread; + new_args->parent = self; + new_args->stack = user_stack_addr; + new_args->return_pc = *(void **) user_stack_addr; + // Invoke DkThreadCreate to spawn off a child process using the actual // "clone" system call. DkThreadCreate allocates a stack for the child // and then runs the given function on that stack However, we want our @@ -240,32 +319,30 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr, new_args, flags); if (!pal_handle) { ret = -PAL_ERRNO; - goto failed; + goto clone_thread_failed; } - new_args->thread->pal_handle = pal_handle; + thread->pal_handle = pal_handle; + thread->in_vm = thread->is_alive = true; + add_thread(thread); + set_as_child(self, thread); - new_args->thread->in_vm = new_args->thread->is_alive = true; - add_thread(new_args->thread); - set_as_child(NULL, new_args->thread); - put_thread(new_args->thread); - - if (new_args->thread->set_child_tid) - *new_args->thread->set_child_tid = new_args->thread->tid; + if (set_parent_tid) + *set_parent_tid = tid; DkEventSet(new_args->create_event); - DkObjectsWaitAny(1, &new_args->initialize_event, NO_TIMEOUT); DkObjectClose(new_args->initialize_event); + put_thread(thread); + return tid; - return new_args->thread->tid; - -failed: +clone_thread_failed: if (new_args->create_event) DkObjectClose(new_args->create_event); if (new_args->initialize_event) DkObjectClose(new_args->initialize_event); - if (new_args->thread) - put_thread(new_args->thread); +failed: + if (thread) + put_thread(thread); return ret; } diff --git a/LibOS/shim/src/sys/shim_exec.c b/LibOS/shim/src/sys/shim_exec.c index 75449b8d..2334a888 100644 --- a/LibOS/shim/src/sys/shim_exec.c +++ b/LibOS/shim/src/sys/shim_exec.c @@ -154,8 +154,7 @@ static void * __malloc (size_t size) addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE); if (addr) - bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, - "checkpoint"); + bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL); return addr; } diff --git a/LibOS/shim/src/sys/shim_fork.c b/LibOS/shim/src/sys/shim_fork.c index 9396ac86..d5c3715f 100644 --- a/LibOS/shim/src/sys/shim_fork.c +++ b/LibOS/shim/src/sys/shim_fork.c @@ -47,8 +47,7 @@ static void * __malloc (size_t size) addr = DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ|PAL_PROT_WRITE); if (addr) - bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, - "checkpoint"); + bkeep_mmap(addr, size, PROT_READ|PROT_WRITE, flags, NULL, 0, NULL); return addr; } @@ -56,9 +55,9 @@ static void * __malloc (size_t size) #define malloc_method __malloc #include -static int migrate_fork (struct shim_cp_store * cpstore, - struct shim_process * process, - struct shim_thread * thread, va_list ap) +int migrate_fork (struct shim_cp_store * cpstore, + struct shim_process * process, + struct shim_thread * thread, va_list ap) { BEGIN_MIGRATION_DEF(fork, struct shim_process * proc, struct shim_thread * thread) @@ -104,7 +103,6 @@ int shim_do_fork (void) if (!new_thread) return -ENOMEM; - new_thread->stack = cur_thread->stack; new_thread->tcb = cur_thread->tcb; new_thread->tgid = new_thread->tid; new_thread->in_vm = false; diff --git a/LibOS/shim/src/sys/shim_futex.c b/LibOS/shim/src/sys/shim_futex.c index bcbb601a..7b273385 100644 --- a/LibOS/shim/src/sys/shim_futex.c +++ b/LibOS/shim/src/sys/shim_futex.c @@ -43,6 +43,11 @@ #define FUTEX_MIN_VALUE 0 #define FUTEX_MAX_VALUE 255 +struct futex_waiter { + struct shim_thread * thread; + struct list_head list; +}; + static LIST_HEAD(futex_list); static LOCKTYPE futex_list_lock; @@ -66,11 +71,9 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, } if (futex) { - hdl = container_of(tmp, struct shim_handle, info.futex); + hdl = container_of(futex, struct shim_handle, info.futex); get_handle(hdl); } else { - struct shim_vma * vma_addr = NULL; - if (!(hdl = get_new_handle())) { unlock(futex_list_lock); return -ENOMEM; @@ -79,15 +82,6 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, hdl->type = TYPE_FUTEX; futex = &hdl->info.futex; futex->uaddr = uaddr; - futex->vma = vma_addr; - - futex->event = DkSynchronizationEventCreate(0); - if (futex->event == NULL) { - ret = -PAL_ERRNO; - unlock(futex_list_lock); - goto out; - } - get_handle(hdl); INIT_LIST_HEAD(&futex->waiters); INIT_LIST_HEAD(&futex->list); @@ -97,13 +91,9 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, unlock(futex_list_lock); lock(hdl->lock); - struct futex_waiter { - struct shim_thread * thread; - struct list_head list; - }; - switch (op & FUTEX_CMD_MASK) { case FUTEX_WAIT: + debug("FUTEX_WAIT: %p (val = %d) vs %d\n", uaddr, *uaddr, val); if (*uaddr != val) break; @@ -118,7 +108,76 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, break; case FUTEX_WAKE: { - for (int cnt = 0 ; cnt < val ; cnt++) { + debug("FUTEX_WAKE: %p (val = %d)\n", uaddr, *uaddr); + int cnt; + for (cnt = 0 ; cnt < val ; cnt++) { + if (list_empty(&futex->waiters)) + break; + + struct futex_waiter * waiter = list_entry(futex->waiters.next, + struct futex_waiter, + list); + + debug("FUTEX_WAKE wake thread %d: %p (val = %d)\n", + waiter->thread->tid, uaddr, *uaddr); + list_del(&waiter->list); + thread_wakeup(waiter->thread); + } + ret = cnt; + debug("FUTEX_WAKE done: %p (val = %d)\n", uaddr, *uaddr); + break; + } + + case FUTEX_CMP_REQUEUE: + if (*uaddr != val3) { + ret = -EAGAIN; + break; + } + + case FUTEX_REQUEUE: { + struct shim_futex_handle * futex2 = NULL; + struct shim_handle * hdl2; + + lock(futex_list_lock); + + list_for_each_entry(tmp, &futex_list, list) + if (tmp->uaddr == uaddr2) { + futex2 = tmp; + break; + } + + if (futex2) { + hdl2 = container_of(futex2, struct shim_handle, info.futex); + get_handle(hdl2); + } else { + if (!(hdl2 = get_new_handle())) { + unlock(futex_list_lock); + ret = -ENOMEM; + goto out; + } + + hdl2->type = TYPE_FUTEX; + futex2 = &hdl2->info.futex; + futex2->uaddr = uaddr2; +#if 0 + futex2->event = DkSynchronizationEventCreate(0); + if (futex2->event == NULL) { + ret = -PAL_ERRNO; + unlock(futex_list_lock); + put_handle(hdl2); + goto out; + } +#endif + get_handle(hdl2); + INIT_LIST_HEAD(&futex2->waiters); + INIT_LIST_HEAD(&futex2->list); + list_add_tail(&futex2->list, &futex_list); + } + + unlock(futex_list_lock); + + int cnt; + for (cnt = 0 ; cnt < val ; cnt++) { if (list_empty(&futex->waiters)) break; @@ -129,6 +188,19 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, list_del(&waiter->list); thread_wakeup(waiter->thread); } + + lock(hdl2->lock); + while (!list_empty(&futex->waiters)) { + struct futex_waiter * waiter = list_entry(futex->waiters.next, + struct futex_waiter, + list); + + list_del(&waiter->list); + list_add_tail(&waiter->list, &futex2->waiters); + } + unlock(hdl2->lock); + put_handle(hdl2); + ret = cnt; break; } @@ -137,6 +209,7 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime, break; default: + debug("unsupported futex op: 0x%x\n", op); ret = -ENOSYS; break; } @@ -205,7 +278,24 @@ void release_robust_list (struct robust_list_head * head) if (!futex) continue; - DkEventSet(futex->event); + struct shim_handle * hdl = + container_of(futex, struct shim_handle, info.futex); + get_handle(hdl); + lock(hdl->lock); + + debug("release robust list: %p\n", futex_addr); + *(int *) futex_addr = 0; + while (!list_empty(&futex->waiters)) { + struct futex_waiter * waiter = list_entry(futex->waiters.next, + struct futex_waiter, + list); + + list_del(&waiter->list); + thread_wakeup(waiter->thread); + } + + unlock(hdl->lock); + put_handle(hdl); } } @@ -230,6 +320,22 @@ void release_clear_child_id (int * clear_child_tid) if (!futex) return; + struct shim_handle * hdl = + container_of(futex, struct shim_handle, info.futex); + get_handle(hdl); + lock(hdl->lock); + debug("release futex at %p\n", clear_child_tid); - DkEventSet(futex->event); + *clear_child_tid = 0; + while (!list_empty(&futex->waiters)) { + struct futex_waiter * waiter = list_entry(futex->waiters.next, + struct futex_waiter, + list); + + list_del(&waiter->list); + thread_wakeup(waiter->thread); + } + + unlock(hdl->lock); + put_handle(hdl); } diff --git a/LibOS/shim/src/sys/shim_mmap.c b/LibOS/shim/src/sys/shim_mmap.c index 56e2023b..ff738de0 100644 --- a/LibOS/shim/src/sys/shim_mmap.c +++ b/LibOS/shim/src/sys/shim_mmap.c @@ -94,7 +94,7 @@ void * shim_do_mmap (void * addr, size_t length, int prot, int flags, int fd, } ret = bkeep_mmap((void *) mapped, mapped_end - mapped, prot, - flags, hdl, offset, "user"); + flags, hdl, offset, NULL); assert(!ret); if (hdl) put_handle(hdl); diff --git a/LibOS/shim/src/sys/shim_sigaction.c b/LibOS/shim/src/sys/shim_sigaction.c index 14643199..a597e525 100644 --- a/LibOS/shim/src/sys/shim_sigaction.c +++ b/LibOS/shim/src/sys/shim_sigaction.c @@ -165,8 +165,7 @@ static int __kill_proc (struct shim_thread * thread, void * arg, if (!warg->use_ipc && !thread->in_vm) return 0; - /* only signal thread leader */ - if (thread->tgid != warg->id || thread->tid != thread->tgid) + if (thread->tgid != warg->id) return 0; if (warg->current == thread) @@ -185,7 +184,6 @@ static int __kill_proc (struct shim_thread * thread, void * arg, return (!ipc_pid_kill_send(warg->sender, warg->id, KILL_PROCESS, warg->sig)) ? 1 : 0; } else { - lock(thread->lock); if (!thread->is_alive) @@ -216,7 +214,7 @@ static int __kill_proc_simple (struct shim_simple_thread * sthread, struct walk_arg * warg = (struct walk_arg *) arg; int srched = 0; - if (sthread->tgid != warg->id || sthread->tgid != sthread->tid) + if (sthread->tgid != warg->id) return 0; lock(sthread->lock); @@ -276,8 +274,7 @@ static int __kill_pgroup (struct shim_thread * thread, void * arg, if (!warg->use_ipc && !thread->in_vm) return 0; - /* only signal thread leader */ - if (thread->pgid != warg->id || thread->tgid != thread->tid) + if (thread->pgid != warg->id) return 0; if (warg->current == thread) @@ -312,7 +309,7 @@ static int __kill_pgroup_simple (struct shim_simple_thread * sthread, struct walk_arg * warg = (struct walk_arg *) arg; int srched = 0; - if (sthread->pgid != warg->id || sthread->tgid != sthread->tid) + if (sthread->pgid != warg->id) return 0; lock(sthread->lock); diff --git a/LibOS/shim/src/syscallas.S b/LibOS/shim/src/syscallas.S index cb22bf41..16fd9fe1 100644 --- a/LibOS/shim/src/syscallas.S +++ b/LibOS/shim/src/syscallas.S @@ -22,8 +22,8 @@ #include - .text - .globl syscalldb +.text + .global syscalldb .type syscalldb, @function .extern shim_table @@ -42,18 +42,10 @@ syscalldb: .cfi_def_cfa_register 6 pushq %rbx - pushq %r12 - movq %rax, %fs:(SHIM_TCB_OFFSET + 24) - movq %rsp, %rbx - addq $152, %rbx - movq %rbx, %fs:(SHIM_TCB_OFFSET + 32) - movq (%rbx), %rbx - movq %rbx, %fs:(SHIM_TCB_OFFSET + 40) - - movq shim_table@GOTPCREL(%rip), %rbx - movq (%rbx,%rax,8), %r12 - cmp $0, (%r12) + leaq shim_table(%rip), %rbx + movq (%rbx,%rax,8), %rbx + cmp $0, (%rbx) je isundef isdef: @@ -63,16 +55,29 @@ isdef: pushq %rcx pushq %r8 pushq %r9 + pushq %r12 pushq %r13 pushq %r14 pushq %r15 + + movq %rax, %fs:(SHIM_TCB_OFFSET + 24) + leaq 224(%rsp), %rax + movq %rax, %fs:(SHIM_TCB_OFFSET + 32) + movq (%rax), %rax + movq %rax, %fs:(SHIM_TCB_OFFSET + 40) movq %rsp, %fs:(SHIM_TCB_OFFSET + 48) - call *(%rbx,%rax,8) + call *%rbx + + movq $0, %fs:(SHIM_TCB_OFFSET + 24) + movq $0, %fs:(SHIM_TCB_OFFSET + 32) + movq $0, %fs:(SHIM_TCB_OFFSET + 40) + movq $0, %fs:(SHIM_TCB_OFFSET + 48) popq %r15 popq %r14 popq %r13 + popq %r12 popq %r9 popq %r8 popq %rcx @@ -86,17 +91,9 @@ isundef: movq $-38, %rax ret: - popq %r12 popq %rbx popq %rbp - - movq $0, %fs:(SHIM_TCB_OFFSET + 24) - movq $0, %fs:(SHIM_TCB_OFFSET + 32) - movq $0, %fs:(SHIM_TCB_OFFSET + 40) - movq $0, %fs:(SHIM_TCB_OFFSET + 48) - addq $128, %rsp - retq .cfi_endproc diff --git a/LibOS/shim/test/Makefile b/LibOS/shim/test/Makefile index d94b1d19..eaebf971 100644 --- a/LibOS/shim/test/Makefile +++ b/LibOS/shim/test/Makefile @@ -26,12 +26,11 @@ manifest: manifest.template rm -rf $@ cp $@.template $@ -.PHONY: pal palsec - pal: - ln -sf $(level)../../../Pal/src/libpal.so -palsec: - ln -sf $(level)../../../Pal/src/libpal_sec.so libpal.so + [ ! -f $(level)../../../Pal/src/pal ] || ln -sf $(level)../../../Pal/src/pal pal + +pal_sec: + [ ! -f $(level)../../../Pal/src/pal_sec ] || ln -sf $(level)../../../Pal/src/pal_sec pal_sec # Regression Test rtest: $(rtarget) diff --git a/LibOS/shim/test/apps/Makefile b/LibOS/shim/test/apps/Makefile index 6f890c69..ab04165e 100644 --- a/LibOS/shim/test/apps/Makefile +++ b/LibOS/shim/test/apps/Makefile @@ -1,26 +1,24 @@ apps = lmbench gcc busybox lighttpd bash apache make -targets = pal +targets = pal pal_sec clean-extra = clean-all level = ../ include ../Makefile manifest_rules = \ + -e 's:\$$(PAL):$(shell pwd)/pal_loader:g' \ -e 's:\$$(PWD):$(shell pwd)/$(appdir):g' \ -e 's:\$$(BIN):$(subst .manifest,,$(notdir $@)):g' \ -e 's:\$$(SHIMPATH):$(shell readlink -f ../../src/libsysdb.so):g' \ -e 's:\$$(GLIBCDIR):$(shell readlink -f $(glibc_dir)):g' \ $(extra_rules) -%.manifest: %.manifest.template libpal.so +%.manifest: %.manifest.template rm -f $@ $@.backup sed $(manifest_rules) $< >$@ chmod +x $@ -libpal.so: - make pal - build-all: for f in $(apps); do (cd $$f; make $(DEBUG) || true; cd ..); done diff --git a/LibOS/shim/test/apps/apache/httpd.manifest.template b/LibOS/shim/test/apps/apache/httpd.manifest.template index 082c35bd..8df3569e 100644 --- a/LibOS/shim/test/apps/apache/httpd.manifest.template +++ b/LibOS/shim/test/apps/apache/httpd.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:obj/bin/httpd diff --git a/LibOS/shim/test/apps/bash/bash-local.manifest.template b/LibOS/shim/test/apps/bash/bash-local.manifest.template index e7205d0a..08fc359b 100644 --- a/LibOS/shim/test/apps/bash/bash-local.manifest.template +++ b/LibOS/shim/test/apps/bash/bash-local.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:bash-local diff --git a/LibOS/shim/test/apps/bash/bash.manifest.template b/LibOS/shim/test/apps/bash/bash.manifest.template index b92d4a30..864e958b 100644 --- a/LibOS/shim/test/apps/bash/bash.manifest.template +++ b/LibOS/shim/test/apps/bash/bash.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/bin/bash diff --git a/LibOS/shim/test/apps/busybox/busybox.manifest.template b/LibOS/shim/test/apps/busybox/busybox.manifest.template index c92f18ca..61d38903 100644 --- a/LibOS/shim/test/apps/busybox/busybox.manifest.template +++ b/LibOS/shim/test/apps/busybox/busybox.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:busybox diff --git a/LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template b/LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template index 5e2f82e3..0285a928 100644 --- a/LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template +++ b/LibOS/shim/test/apps/busybox/busybox_nofork.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:busybox_nofork diff --git a/LibOS/shim/test/apps/gcc/g++-huge.manifest.template b/LibOS/shim/test/apps/gcc/g++-huge.manifest.template index 3f6795e0..5e79cf2b 100644 --- a/LibOS/shim/test/apps/gcc/g++-huge.manifest.template +++ b/LibOS/shim/test/apps/gcc/g++-huge.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/g++ diff --git a/LibOS/shim/test/apps/gcc/g++-local.manifest.template b/LibOS/shim/test/apps/gcc/g++-local.manifest.template index 9771ae24..128bd0d0 100644 --- a/LibOS/shim/test/apps/gcc/g++-local.manifest.template +++ b/LibOS/shim/test/apps/gcc/g++-local.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.interp = file:$(SHIM)build/elf/ld.so loader.preload = file:$(SHIM)build/libsysdb.so diff --git a/LibOS/shim/test/apps/gcc/g++.manifest.template b/LibOS/shim/test/apps/gcc/g++.manifest.template index c6012bc4..b11b8c26 100644 --- a/LibOS/shim/test/apps/gcc/g++.manifest.template +++ b/LibOS/shim/test/apps/gcc/g++.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/g++ diff --git a/LibOS/shim/test/apps/gcc/gcc-huge.manifest.template b/LibOS/shim/test/apps/gcc/gcc-huge.manifest.template index e8b2116b..53adac8b 100644 --- a/LibOS/shim/test/apps/gcc/gcc-huge.manifest.template +++ b/LibOS/shim/test/apps/gcc/gcc-huge.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/gcc diff --git a/LibOS/shim/test/apps/gcc/gcc-local.manifest.template b/LibOS/shim/test/apps/gcc/gcc-local.manifest.template index 4c4934f2..e1ad3af0 100644 --- a/LibOS/shim/test/apps/gcc/gcc-local.manifest.template +++ b/LibOS/shim/test/apps/gcc/gcc-local.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.interp = file:$(SHIMROOT)build/elf/ld.so loader.preload = file:$(SHIMROOT)build/libsysdb.so diff --git a/LibOS/shim/test/apps/gcc/gcc.manifest.template b/LibOS/shim/test/apps/gcc/gcc.manifest.template index a481badf..12a457b4 100644 --- a/LibOS/shim/test/apps/gcc/gcc.manifest.template +++ b/LibOS/shim/test/apps/gcc/gcc.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/gcc diff --git a/LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template b/LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template index 1a5f6bd1..fafb02fb 100644 --- a/LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template +++ b/LibOS/shim/test/apps/lighttpd/lighttpd-angel.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:$(PWD)build/sbin/lighttpd-angel diff --git a/LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template b/LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template index a209595e..3db784b3 100644 --- a/LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template +++ b/LibOS/shim/test/apps/lighttpd/lighttpd.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:$(PWD)build/sbin/lighttpd diff --git a/LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c b/LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c index 166fb5b7..7fdb7f79 100644 --- a/LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c +++ b/LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_syscall.c @@ -12,23 +12,23 @@ char *id = "$Id$\n"; #define FNAME "/usr/include/x86_64-linux-gnu/sys/types.h" void -do_write(int fd) +do_write(int fd, char *s) { char c; if (write(fd, &c, 1) != 1) { - perror("/dev/null"); + perror(s); return; } } void -do_read(int fd) +do_read(int fd, char *s) { char c; if (read(fd, &c, 1) != 1) { - perror("/dev/zero"); + perror(s); return; } } @@ -81,17 +81,23 @@ main(int ac, char **av) BENCH(getppid(), 0); micro("Simple syscall", get_n()); } else if (!strcmp("write", av[1])) { - fd = open("/dev/null", 1); - BENCH(do_write(fd), 0);; + file = av[2] ? av[2] : "/dev/null"; + fd = open(file, 1); + if (fd == -1) { + fprintf(stderr, "Write from %s: %s\n", file, strerror(errno)); + return(1); + } + BENCH(do_write(fd, file), 0);; micro("Simple write", get_n()); close(fd); } else if (!strcmp("read", av[1])) { - fd = open("/dev/zero", 0); + file = av[2] ? av[2] : "/dev/null"; + fd = open(file, 0); if (fd == -1) { - fprintf(stderr, "Read from /dev/zero: -1"); + fprintf(stderr, "Read from %s: %s\n", file, strerror(errno)); return(1); } - BENCH(do_read(fd), 0); + BENCH(do_read(fd, file), 0); micro("Simple read", get_n()); close(fd); } else if (!strcmp("stat", av[1])) { diff --git a/LibOS/shim/test/apps/lmbench/manifest.template b/LibOS/shim/test/apps/lmbench/manifest.template index 7c49d031..6596c87a 100644 --- a/LibOS/shim/test/apps/lmbench/manifest.template +++ b/LibOS/shim/test/apps/lmbench/manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:$(PWD)lmbench-2.5/bin/linux/$(BIN) diff --git a/LibOS/shim/test/apps/make/make-huge.manifest.template b/LibOS/shim/test/apps/make/make-huge.manifest.template index d6af829b..5096e4ee 100644 --- a/LibOS/shim/test/apps/make/make-huge.manifest.template +++ b/LibOS/shim/test/apps/make/make-huge.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/make diff --git a/LibOS/shim/test/apps/make/make-local.manifest.template b/LibOS/shim/test/apps/make/make-local.manifest.template index 801f85fe..9e3e6b46 100644 --- a/LibOS/shim/test/apps/make/make-local.manifest.template +++ b/LibOS/shim/test/apps/make/make-local.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:make-local diff --git a/LibOS/shim/test/apps/make/make.manifest.template b/LibOS/shim/test/apps/make/make.manifest.template index 11ffc26c..b4a207df 100644 --- a/LibOS/shim/test/apps/make/make.manifest.template +++ b/LibOS/shim/test/apps/make/make.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/make diff --git a/LibOS/shim/test/apps/python/python.manifest.template b/LibOS/shim/test/apps/python/python.manifest.template index 49024d7f..3b409658 100644 --- a/LibOS/shim/test/apps/python/python.manifest.template +++ b/LibOS/shim/test/apps/python/python.manifest.template @@ -1,4 +1,4 @@ -#!$(PWD)../libpal.so +#!$(PAL) loader.preload = file:$(SHIMPATH) loader.exec = file:/usr/bin/python diff --git a/LibOS/shim/test/inline/Makefile b/LibOS/shim/test/inline/Makefile index 4785ac10..b97f12cf 100644 --- a/LibOS/shim/test/inline/Makefile +++ b/LibOS/shim/test/inline/Makefile @@ -2,7 +2,7 @@ INLINE_TESTS_CPP = $(patsubst %.cpp,%,$(wildcard *.cpp)) INLINE_TESTS = $(patsubst %.c,%,$(wildcard *.c)) rtarget = helloworld fork vfork -targets = $(rtarget) manifest pal +targets = $(rtarget) manifest pal pal_sec clean-extra = clean-exec level = ../ @@ -23,4 +23,4 @@ test-vfork = grep -q "Hello, Dad" OUTPUT && grep -q "Hello, Kid" OUTPUT clean-exec: find -type f -executable -exec rm {} \; - rm -rf manifest libpal.so + rm -rf manifest pal pal_sec diff --git a/LibOS/shim/test/native/Makefile b/LibOS/shim/test/native/Makefile index 49cec333..db281a67 100644 --- a/LibOS/shim/test/native/Makefile +++ b/LibOS/shim/test/native/Makefile @@ -5,7 +5,7 @@ NATIVE_TESTS_STATIC = static NATIVE_TESTS = $(filter-out $(NATIVE_TESTS_STATIC),$(patsubst %.c,%,$(wildcard *.c))) targets = $(NATIVE_TESTS) $(NATIVE_TESTS_CPP) $(NATIVE_TESTS_STATIC) \ - manifest static.manifest pal + manifest static.manifest pal pal_sec rtarget = helloworld clone vfork fork exec vfork_exec errno dup time \ helloworld.pthread udp tcp unix file dev clean-extra = clean-exec @@ -47,4 +47,4 @@ test-helloworld = grep -q "Hello world" OUTPUT clean-exec: find -type f -executable -exec rm {} \; - rm -rf manifest static.manifest libpal.so + rm -rf manifest static.manifest pal pal_sec diff --git a/LibOS/shim/test/native/manifest.template b/LibOS/shim/test/native/manifest.template index 43237a52..5efdf707 100644 --- a/LibOS/shim/test/native/manifest.template +++ b/LibOS/shim/test/native/manifest.template @@ -10,6 +10,10 @@ fs.mount.other.lib.type = chroot fs.mount.other.lib.path = /lib fs.mount.other.lib.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 diff --git a/LibOS/shim/test/native/start.c b/LibOS/shim/test/native/start.c index 6d13720f..0f9ef2a3 100644 --- a/LibOS/shim/test/native/start.c +++ b/LibOS/shim/test/native/start.c @@ -28,6 +28,5 @@ int main (int argc, char ** argv, char ** envp) unsigned long long overhead = (msec4 - msec3) / OVERHEAD_TIMES; printf("%llu\n", msec2 - msec1 - overhead); - return 0; } diff --git a/LibOS/shim/test/native/system.c b/LibOS/shim/test/native/system.c new file mode 100644 index 00000000..488d37e8 --- /dev/null +++ b/LibOS/shim/test/native/system.c @@ -0,0 +1,12 @@ +/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ +/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ + +/* a simple helloworld test */ + +#include + +int main(int argc, char ** argv) +{ + system("./helloworld"); + return 0; +} diff --git a/Pal/ipc/linux/graphene-ipc.c b/Pal/ipc/linux/graphene-ipc.c index b12ee3b3..0c8e9b79 100644 --- a/Pal/ipc/linux/graphene-ipc.c +++ b/Pal/ipc/linux/graphene-ipc.c @@ -895,7 +895,7 @@ out: mutex_unlock(&pending->receiver_lock); up_write(¤t_tsk->mm->mmap_sem); - rv = copy_to_user(((struct gipc_recv *)arg)->addr, addrs, + rv = copy_to_user(gr.addr, addrs, sizeof(unsigned long) * gr.entries); if (rv) { printk(KERN_ERR "Graphene error: bad buffer %p\n", diff --git a/Pal/src/Makefile b/Pal/src/Makefile index 13edb1a2..e2d7a19d 100644 --- a/Pal/src/Makefile +++ b/Pal/src/Makefile @@ -9,18 +9,21 @@ LD = ld CFLAGS = -Wall -fPIC -O2 -std=gnu99 -fgnu89-inline -U_FORTIFY_SOURCE \ -fno-omit-frame-pointer \ -fno-stack-protector -fno-builtin -LDFLAGS = -shared -nostdlib --version-script pal.map -z combreloc -z defs \ - -T pal.lds +LDFLAGS = -shared -nostdlib -z combreloc -z defs ARFLAGS = pal_loader = libpal.so -pal_lib = libpal.a +pal_sec = +pal_lib = libpal.so +pal_lib_deps = +pal_lib_post = +pal_static = libpal.a include host/$(OS)/Makefile.am CFLAGS += -I. -I../include -Ihost/$(OS) -I../lib -pal_target = $(pal_loader) $(pal_lib) +pal_target = $(pal_lib) $(pal_lib_post) $(pal_static) $(pal_loader) $(pal_sec) pal pal_sec defs = -DIN_PAL -DSRCDIR="$(PWD)/" objs = $(addprefix db_,streams memory threading semaphore events process \ object main misc ipc exception rtld) slab printf @@ -28,14 +31,14 @@ graphene_lib = ../lib/graphene-lib.a host_lib = host/$(OS)/libpal-$(OS).a headers = $(wildcard *.h) $(wildcard ../lib/*.h) -all: $(pal_target) security +all: $(pal_target) debug: debug = debug debug: CC = gcc -gdwarf-2 -g3 debug: CFLAGS += -DDEBUG -debug: $(pal_target) security +debug: $(pal_target) -.PHONY: security $(host_lib) $(graphene_lib) +.PHONY: $(host_lib) $(graphene_lib) $(graphene_lib): make -C ../lib $(debug) @@ -43,15 +46,27 @@ $(graphene_lib): $(host_lib): @[ ! -d host/$(OS) ] || make -C host/$(OS) $(debug) -security: +ifneq ($(pal_sec),) +$(pal_sec): @[ ! -d security/$(OS) ] || make -C security/$(OS) $(debug) -$(pal_loader): $(addsuffix .o,$(objs)) $(filter %.map %.lds,$(LDFLAGS)) \ - $(host_lib) $(graphene_lib) +pal_sec: $(pal_sec) + ln -sf $(pal_sec) pal_sec +endif + +$(pal_lib): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib) $(pal_lib_deps) @echo [ libpal.exe ] $(LD) $(LDFLAGS) -o $@ $(filter-out %.map %.lds,$^) $(LDFLAGS-suffix) -$(pal_lib): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib) +pal: $(pal_loader) + ln -sf $(pal_loader) pal + +ifneq ($(pal_lib_post),) +$(pal_lib_post): $(pal_lib) + make -C host/$(OS) ../../$@ +endif + +$(pal_static): $(addsuffix .o,$(objs)) $(host_lib) $(graphene_lib) @echo [ $@ ] $(AR) $(ARFLAGS) $@ $^ $(ARFLAGS-suffix) diff --git a/Pal/src/db_rtld.c b/Pal/src/db_rtld.c index 591da1d2..b8c22aae 100644 --- a/Pal/src/db_rtld.c +++ b/Pal/src/db_rtld.c @@ -52,39 +52,6 @@ void __attribute__((noinline)) __assert (void) } #endif -/* This structure communicates dl state to the debugger. The debugger - normally finds it via the DT_DEBUG entry in the dynamic section, but in - a statically-linked program there is no dynamic section for the debugger - to examine and it looks for this particular symbol name. */ -struct r_debug pal_r_debug = - { 1, NULL, (ElfW(Addr)) &pal_dl_debug_state, RT_CONSISTENT, 0 }; - -extern __typeof(pal_r_debug) _r_debug - __attribute ((alias ("pal_r_debug"))); - - /* This function exists solely to have a breakpoint set on it by the - debugger. The debugger is supposed to find this function's address by - examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks - for this particular symbol name in the PT_INTERP file. */ - -/* The special symbol name is set as breakpoint in gdb */ -void __attribute__((noinline)) pal_dl_debug_state (void) -{ -} - -extern __typeof(pal_dl_debug_state) _dl_debug_state - __attribute ((alias ("pal_dl_debug_state"))); - -void __attribute__((noinline)) _dl_debug_state_trigger (void) -{ - struct link_map *l = pal_r_debug.r_map; - for ( ; l ; l = l->l_next) - if (!memcmp(l->l_name, "file:", 5)) - l->l_name += 5; - - pal_dl_debug_state(); -} - /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ static ElfW(Addr) resolve_map (const char **strtab, ElfW(Sym) ** ref) { @@ -251,7 +218,7 @@ call_lose: /* Scan the program header table, collecting its load commands. */ struct loadcmd { ElfW(Addr) mapstart, mapend, dataend, allocend; - off_t mapoff; + unsigned int mapoff; int prot; } loadcmds[l->l_phnum], *c; @@ -309,18 +276,13 @@ call_lose: has_holes = true; /* Optimize a common case. */ -#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 - c->prot = (PF_TO_PROT - >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; -#else c->prot = 0; if (ph->p_flags & PF_R) - c->prot |= PROT_READ; + c->prot |= PAL_PROT_READ; if (ph->p_flags & PF_W) - c->prot |= PROT_WRITE; + c->prot |= PAL_PROT_WRITE; if (ph->p_flags & PF_X) - c->prot |= PROT_EXEC; -#endif + c->prot |= PAL_PROT_EXEC; break; case PT_TLS: @@ -390,7 +352,7 @@ map_error: unallocated. Then jump into the normal segment-mapping loop to handle the portion of the segment past the end of the file mapping. */ - _DkVirtualMemoryProtect((caddr_t) (l->l_addr + c->mapend), + _DkVirtualMemoryProtect((void *) (l->l_addr + c->mapend), loadcmds[nloadcmds - 1].mapstart - c->mapend, PAL_PROT_NONE); @@ -414,12 +376,12 @@ map_error: } postmap: - if (c->prot & PROT_EXEC) { + if (c->prot & PAL_PROT_EXEC) { l->l_text_start = l->l_addr + c->mapstart; l->l_text_end = l->l_addr + c->mapend; } - if (c->prot & PROT_WRITE) { + if (c->prot & PAL_PROT_WRITE) { l->l_data_start = l->l_addr + c->mapstart; l->l_data_end = l->l_addr + c->mapend; } @@ -447,7 +409,7 @@ postmap: if (zerosec > zero) { /* Zero the final part of the last section of the segment. */ - if (__builtin_expect ((c->prot & PROT_WRITE) == 0, 0)) + if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0)) { /* Dag nab it. */ if (_DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero), @@ -458,7 +420,7 @@ postmap: } } memset ((void *) zero, '\0', zerosec - zero); - if (__builtin_expect ((c->prot & PROT_WRITE) == 0, 0)) + if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0)) _DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero), allocsize, c->prot); } @@ -563,16 +525,12 @@ void free_elf_object (struct link_map * map) _DkVirtualMemoryFree((void *) map->l_map_start, map->l_map_end - map->l_map_start); - pal_sec_info._r_debug->r_state = RT_DELETE; - pal_sec_info._dl_debug_state(); - if (map->l_prev) map->l_prev->l_next = map->l_next; if (map->l_next) map->l_next->l_prev = map->l_prev; - pal_sec_info._r_debug->r_state = RT_CONSISTENT; - pal_sec_info._dl_debug_state(); + _DkDebugDelMap(map); if (loaded_libraries == map) loaded_libraries = map->l_next; @@ -675,9 +633,6 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type) } } - pal_sec_info._r_debug->r_state = RT_ADD; - pal_sec_info._dl_debug_state(); - struct link_map * map; if (!(map = map_elf_object_by_handle(handle, type, &fb, len, true))) { @@ -706,8 +661,7 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type) map->l_prev = prev; map->l_next = NULL; - pal_sec_info._r_debug->r_state = RT_CONSISTENT; - pal_sec_info._dl_debug_state(); + _DkDebugAddMap(map); return 0; @@ -969,18 +923,13 @@ static int relocate_elf_object (struct link_map * l) if (ret < 0) return ret; -#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 - r->prot = (PF_TO_PROT - >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; -#else r->prot = 0; if (ph->p_flags & PF_R) - r->prot |= PROT_READ; + r->prot |= PAL_PROT_READ; if (ph->p_flags & PF_W) - r->prot |= PROT_WRITE; + r->prot |= PAL_PROT_WRITE; if (ph->p_flags & PF_X) - r->prot |= PROT_EXEC; -#endif + r->prot |= PAL_PROT_EXEC; r->next = textrels; textrels = r; } @@ -1026,6 +975,70 @@ static int relocate_elf_object (struct link_map * l) return 0; } +void DkDebugAttachBinary (PAL_STR uri, PAL_PTR start_addr) +{ + if (memcmp(uri, "file:", 5)) + return; + + struct link_map * l = new_elf_object(uri + 5, OBJECT_EXTERNAL); + + /* This is the ELF header. We read it in `open_verify'. */ + const ElfW(Ehdr) * header = start_addr; + + l->l_entry = header->e_entry; + l->l_phnum = header->e_phnum; + l->l_addr = l->l_map_start = (ElfW(Addr)) start_addr; + + ElfW(Phdr) * phdr = (void *) (start_addr + header->e_phoff); + const ElfW(Phdr) * ph; + + for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph) + switch (ph->p_type) + { + /* These entries tell us where to find things once the file's + segments are mapped in. We record the addresses it says + verbatim, and later correct for the run-time load address. */ + case PT_DYNAMIC: + l->l_ld = l->l_real_ld = (void *) ph->p_vaddr; + l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); + break; + + case PT_PHDR: + l->l_phdr = (void *) ph->p_vaddr; + break; + + case PT_LOAD: { + ElfW(Addr) start = l->l_addr + ALLOC_ALIGNDOWN(ph->p_vaddr); + ElfW(Addr) end = l->l_addr + ALLOC_ALIGNDOWN(ph->p_vaddr + + ph->p_memsz); + + if (ph->p_flags & PF_X) { + l->l_text_start = start; + l->l_text_end = end; + } + + if (ph->p_flags & PF_W) { + l->l_data_start = start; + l->l_data_end = end; + } + + l->l_map_end = end; + break; + } + + case PT_GNU_RELRO: + l->l_relro_addr = ph->p_vaddr; + l->l_relro_size = ph->p_memsz; + break; + } + + _DkDebugAddMap(l); +} + +void DkDebugDetachBinary (PAL_PTR start_addr) +{ +} + void start_execution (int argc, const char ** argv) { /* First we will try to run all the preloaded libraries which come with diff --git a/Pal/src/dynamic_link.h b/Pal/src/dynamic_link.h index 732fa905..f1f28d24 100644 --- a/Pal/src/dynamic_link.h +++ b/Pal/src/dynamic_link.h @@ -39,23 +39,23 @@ copying memory, breaking the very code written to handle the unaligned cases. */ #if ! ELF_MACHINE_NO_REL -static void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) elf_machine_rel (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr, ElfW(Rel) *reloc, ElfW(Sym) *sym, void *const reloc_addr, bool rel, bool rel_relative); -static void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, void *const reloc_addr); #endif #if ! ELF_MACHINE_NO_RELA -static void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) elf_machine_rela (ElfW(Dyn) ** l_info, ElfW(Addr) l_addr, ElfW(Rela) *reloc, ElfW(Sym) *sym, void *const reloc_addr, bool rel, bool rel_relative); -static void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr); #endif diff --git a/Pal/src/host/Linux/Makefile b/Pal/src/host/Linux/Makefile index ebbb3ec9..a0f6fb8d 100644 --- a/Pal/src/host/Linux/Makefile +++ b/Pal/src/host/Linux/Makefile @@ -16,7 +16,8 @@ ARFLAGS = host_target = libpal-Linux.a -defs = -DIN_PAL -DGDB_SCRIPT="$(CURDIR)/pal-gdb.py" +defs = -DIN_PAL -DPAL_LOADER_PATH="$(shell readlink -f ../../pal)" \ + -DGDB_SCRIPT="$(CURDIR)/pal-gdb.py" objs = $(addprefix db_,files devices pipes sockets streams memory threading \ semaphore mutex events process object main rtld misc ipc \ exception) manifest clone-x86_64 gettimeofday-x86_64 diff --git a/Pal/src/host/Linux/Makefile.am b/Pal/src/host/Linux/Makefile.am index d2f2f455..00adea8b 100644 --- a/Pal/src/host/Linux/Makefile.am +++ b/Pal/src/host/Linux/Makefile.am @@ -1 +1,8 @@ # Add host-specific compilation rules here +HOST_DIR = host/$(OS) +SEC_DIR = security/$(OS) + +pal_sec = $(SEC_DIR)/libpal_sec.so +pal_lib_deps = $(HOST_DIR)/pal.map $(HOST_DIR)/pal.lds + +LDFLAGS += --version-script $(HOST_DIR)/pal.map -T $(HOST_DIR)/pal.lds diff --git a/Pal/src/host/Linux/db_main.c b/Pal/src/host/Linux/db_main.c index f9ae57bd..09c188ab 100644 --- a/Pal/src/host/Linux/db_main.c +++ b/Pal/src/host/Linux/db_main.c @@ -70,7 +70,6 @@ static gid_t gid; static ElfW(Addr) sysinfo_ehdr; #endif -static const char * libname; static const char * child_args; static void pal_init_bootstrap (void * args, int * pargc, @@ -124,9 +123,7 @@ static void pal_init_bootstrap (void * args, int * pargc, #endif } - if (memcmp(*argv + strlen(*argv) - LIBRARY_NAMELEN, LIBRARY_NAME, - LIBRARY_NAMELEN) == 0) { - libname = *argv; + if (!memcmp(*argv + strlen(*argv) - 3, "pal", 3)) { argv++; argc--; @@ -198,8 +195,6 @@ int read_shebang (const char ** argv) if (IS_ERR(fd)) { bad_shebang: - printf("The program is either not libpal.so or script with " - "shebang. I can't recognize.\n"); INLINE_SYSCALL(close, 1, fd); return -PAL_ERROR_INVAL; } @@ -215,14 +210,8 @@ bad_shebang: goto bad_shebang; char * p = &buffer[2]; - while (*p && *p != ' ' && *p != '\r' && *p != '\n'); - p++; - - if (!libname) { - char * name = malloc(p - buffer - 1); - memcpy(name, &buffer[2], p - buffer - 2); - libname = name; - } + while (*p && *p != ' ' && *p != '\r' && *p != '\n') + p++; int len = strlen(*argv); PAL_HANDLE manifest = malloc(HANDLE_SIZE(file) + len + 1); @@ -265,7 +254,7 @@ void pal_linux_main (void * args) init_slab_mgr(); - setup_pal_map(XSTRINGIFY(SRCDIR) "/" LIBRARY_NAME, pal_dyn, pal_addr); + setup_pal_map(XSTRINGIFY(SRCDIR) "/pal", pal_dyn, pal_addr); /* jump to main function */ pal_main(argc, argv, envp); @@ -345,9 +334,6 @@ int _DkInitHost (int * pargc, const char *** pargv) return -PAL_ERROR_INVAL; } - if (pal_sec_info.pal_name) - libname = pal_sec_info.pal_name; - pal_linux_config.pid = INLINE_SYSCALL(getpid, 0); signal_setup(); @@ -359,12 +345,8 @@ int _DkInitHost (int * pargc, const char *** pargv) goto read_manifest; } - if (!libname) { - if ((ret = read_shebang(argv)) < 0) - return ret; - + if (!(ret = read_shebang(argv)) < 0) goto read_manifest; - } PAL_HANDLE file = NULL; const char * file_uri = NULL; @@ -468,12 +450,6 @@ read_manifest: } done_init: - if (!child_args && pal_config.exec) - printf("Program \"%s\" loaded in Graphene Library OS\n", - pal_config.exec); - - pal_config.lib_name = libname; - if (!child_args && !pal_sec_info.domain_id) { if ((ret = create_domain_dir()) < 0) return ret; @@ -490,9 +466,9 @@ done_init: #endif if (!pal_sec_info.mcast_port) { - do { - getrand(&pal_sec_info.mcast_port, sizeof(unsigned short)); - } while (pal_sec_info.mcast_port < 1024); + unsigned short mcast_port; + getrand(&mcast_port, sizeof(unsigned short)); + pal_sec_info.mcast_port = mcast_port % 1024; } __pal_control.broadcast_stream = pal_sec_info.mcast_handle ? : diff --git a/Pal/src/host/Linux/db_misc.c b/Pal/src/host/Linux/db_misc.c index 6481b635..14c1a380 100644 --- a/Pal/src/host/Linux/db_misc.c +++ b/Pal/src/host/Linux/db_misc.c @@ -55,10 +55,10 @@ unsigned long _DkSystemTimeQuery (void) #if USE_VDSO_GETTIME == 1 if (__vdso_clock_gettime) { - ret = __vdso_clock_gettime(CLOCK_MONOTONIC, &time); + ret = __vdso_clock_gettime(CLOCK_REALTIME, &time); } else { #endif - ret = INLINE_SYSCALL(clock_gettime, 2, CLOCK_MONOTONIC, &time); + ret = INLINE_SYSCALL(clock_gettime, 2, CLOCK_REALTIME, &time); #if USE_VDSO_GETTIME == 1 } #endif diff --git a/Pal/src/host/Linux/db_pipes.c b/Pal/src/host/Linux/db_pipes.c index b458de10..2e796756 100644 --- a/Pal/src/host/Linux/db_pipes.c +++ b/Pal/src/host/Linux/db_pipes.c @@ -165,7 +165,7 @@ static int pipe_waitforclient (PAL_HANDLE handle, PAL_HANDLE * client) *client = clnt; #else PAL_IDX connid; - getrand(&connid, sizeof(PAL_IDX)); + system_getrand(&connid, sizeof(PAL_IDX)); PAL_HANDLE clnt = malloc(HANDLE_SIZE(pipe)); SET_HANDLE_TYPE(clnt, pipecli); clnt->__in.flags |= RFD(0)|WFD(0)|WRITEABLE(0); diff --git a/Pal/src/host/Linux/db_process.c b/Pal/src/host/Linux/db_process.c index 6377e815..09c8e82a 100644 --- a/Pal/src/host/Linux/db_process.c +++ b/Pal/src/host/Linux/db_process.c @@ -106,7 +106,7 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri, const char ** new_args = __alloca(sizeof(const char *) * (nargs + 3)); int bufsize = STRARG_SIZE; char * argbuf = __alloca(STRARG_SIZE); - new_args[0] = pal_config.lib_name; + new_args[0] = PAL_LOADER; new_args[1] = argbuf; if (args) memcpy(new_args + 2, args, sizeof(const char *) * nargs); @@ -170,7 +170,7 @@ int _DkProcessCreate (PAL_HANDLE * handle, const char * uri, if (manifest_fd >= 0) INLINE_SYSCALL(fcntl, 3, manifest_fd, F_SETFD, 0); - rete = INLINE_SYSCALL(execve, 3, pal_config.lib_name, new_args, + rete = INLINE_SYSCALL(execve, 3, PAL_LOADER, new_args, pal_config.environments); /* shouldn't get to here */ diff --git a/Pal/src/host/Linux/db_rtld.c b/Pal/src/host/Linux/db_rtld.c index 394c5589..2476ab75 100644 --- a/Pal/src/host/Linux/db_rtld.c +++ b/Pal/src/host/Linux/db_rtld.c @@ -43,7 +43,111 @@ #include "elf-x86_64.h" -struct link_map * rtld_map = NULL; +/* This structure communicates dl state to the debugger. The debugger + normally finds it via the DT_DEBUG entry in the dynamic section, but in + a statically-linked program there is no dynamic section for the debugger + to examine and it looks for this particular symbol name. */ +struct r_debug pal_r_debug = + { 1, NULL, (ElfW(Addr)) &pal_dl_debug_state, RT_CONSISTENT, 0 }; + +extern __typeof(pal_r_debug) _r_debug + __attribute ((alias ("pal_r_debug"))); + +/* This function exists solely to have a breakpoint set on it by the + debugger. The debugger is supposed to find this function's address by + examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks + for this particular symbol name in the PT_INTERP file. */ + +/* The special symbol name is set as breakpoint in gdb */ +void __attribute__((noinline)) pal_dl_debug_state (void) +{ + if (pal_sec_info._dl_debug_state) + pal_sec_info._dl_debug_state(); +} + +extern __typeof(pal_dl_debug_state) _dl_debug_state + __attribute ((alias ("pal_dl_debug_state"))); + +void _DkDebugAddMap (struct link_map * map) +{ + struct r_debug * dbg = pal_sec_info._r_debug ? : &pal_r_debug; + int len = map->l_name ? strlen(map->l_name) + 1 : 0; + + struct link_map ** prev = &dbg->r_map, * last = NULL, + * tmp = *prev; + while (tmp) { + if (tmp->l_addr == map->l_addr && + tmp->l_ld == map->l_ld && + !memcmp(tmp->l_name, map->l_name, len)) + return; + + last = tmp; + tmp = *(prev = &last->l_next); + } + + struct link_gdb_map * m = malloc(sizeof(struct link_gdb_map) + len); + if (!m) + return; + + if (len) { + m->l_name = (char *) m + sizeof(struct link_gdb_map); + memcpy((void *) m->l_name, map->l_name, len); + } else { + m->l_name = NULL; + } + + m->l_addr = map->l_addr; + m->l_ld = map->l_real_ld; + + dbg->r_state = RT_ADD; + pal_dl_debug_state(); + + *prev = (struct link_map *) m; + m->l_prev = last; + m->l_next = NULL; + + dbg->r_state = RT_CONSISTENT; + pal_dl_debug_state(); +} + +void _DkDebugDelMap (struct link_map * map) +{ + struct r_debug * dbg = pal_sec_info._r_debug ? : &pal_r_debug; + int len = map->l_name ? strlen(map->l_name) + 1 : 0; + + struct link_map ** prev = &dbg->r_map, * last = NULL, + * tmp = *prev, * found = NULL; + while (tmp) { + if (tmp->l_addr == map->l_addr && + tmp->l_ld == map->l_ld && + !memcmp(tmp->l_name, map->l_name, len)) { + found = tmp; + break; + } + + last = tmp; + tmp = *(prev = &last->l_next); + } + + if (!found) + return; + + dbg->r_state = RT_DELETE; + pal_dl_debug_state(); + + if (last) + last->l_next = tmp->l_next; + else + dbg->r_map = tmp->l_next; + + if (tmp->l_next) + tmp->l_next->l_prev = last; + + free(tmp); + + dbg->r_state = RT_CONSISTENT; + pal_dl_debug_state(); +} extern void setup_elf_hash (struct link_map *map); @@ -84,30 +188,9 @@ void setup_pal_map (const char * realname, ElfW(Dyn) ** dyn, ElfW(Addr) addr) l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &pal_r_debug; l->l_prev = l->l_next = NULL; - rtld_map = l; loaded_libraries = l; - if (!pal_sec_info._r_debug) { - pal_r_debug.r_version = 1; - pal_r_debug.r_brk = (ElfW(Addr)) &pal_dl_debug_state; - pal_r_debug.r_ldbase = addr; - pal_r_debug.r_map = loaded_libraries; - pal_sec_info._r_debug = &pal_r_debug; - pal_sec_info._dl_debug_state = &pal_dl_debug_state; - } else { - pal_sec_info._r_debug->r_state = RT_ADD; - pal_sec_info._dl_debug_state(); - - if (pal_sec_info._r_debug->r_map) { - l->l_prev = pal_sec_info._r_debug->r_map; - pal_sec_info._r_debug->r_map->l_next = l; - } else { - pal_sec_info._r_debug->r_map = loaded_libraries; - } - - pal_sec_info._r_debug->r_state = RT_CONSISTENT; - pal_sec_info._dl_debug_state(); - } + _DkDebugAddMap(l); } #if USE_VDSO_GETTIME == 1 diff --git a/Pal/src/pal.lds b/Pal/src/host/Linux/pal.lds similarity index 100% rename from Pal/src/pal.lds rename to Pal/src/host/Linux/pal.lds diff --git a/Pal/src/pal.map b/Pal/src/host/Linux/pal.map similarity index 95% rename from Pal/src/pal.map rename to Pal/src/host/Linux/pal.map index 40723920..a1c1349d 100644 --- a/Pal/src/pal.map +++ b/Pal/src/host/Linux/pal.map @@ -44,11 +44,10 @@ PAL { DkStreamAttributesSetbyHandle; # Debugging ABIs - pal_printf; pal_snprintf; + pal_printf; pal_snprintf; DkDebugAttachBinary; DkDebugDetachBinary; # Control block pal_control; pal_control_addr; pal_sec_info; - local: *; }; diff --git a/Pal/src/host/Linux/pal_linux.h b/Pal/src/host/Linux/pal_linux.h index d9b1bdf4..66c6e2bc 100644 --- a/Pal/src/host/Linux/pal_linux.h +++ b/Pal/src/host/Linux/pal_linux.h @@ -23,6 +23,9 @@ #include "pal_defs.h" #include "pal_linux_defs.h" #include "pal.h" +#include "pal_internal.h" + +#define PAL_LOADER XSTRINGIFY(PAL_LOADER_PATH) #include diff --git a/Pal/src/pal_debug.h b/Pal/src/pal_debug.h index 2332ffe3..b4552641 100644 --- a/Pal/src/pal_debug.h +++ b/Pal/src/pal_debug.h @@ -59,6 +59,9 @@ int pal_snprintf (char *buf, size_t n, const char *fmt, ...); int pal_atoi (const char *nptr); long int pal_atol (const char *nptr); +void DkDebugAttachBinary (PAL_STR uri, PAL_PTR start_addr); +void DkDebugDetachBinary (PAL_PTR start_addr); + #endif #endif diff --git a/Pal/src/pal_internal.h b/Pal/src/pal_internal.h index fe4c7ce1..b59d77fd 100644 --- a/Pal/src/pal_internal.h +++ b/Pal/src/pal_internal.h @@ -35,9 +35,6 @@ # error "pal_internal.h can only be included in PAL" #endif -#define LIBRARY_NAME "libpal.so" -#define LIBRARY_NAMELEN 9 - /* handle_ops is the operators provided for each handler type. They are mostly used by Stream-related PAL calls, but can also be used by some others in special ways. */ @@ -286,7 +283,6 @@ extern struct pal_config { PAL_HANDLE manifest_handle; PAL_HANDLE exec_handle; struct config_store * root_config; - const char * lib_name; const char ** environments; unsigned long pagesize; unsigned long alloc_align; @@ -430,7 +426,7 @@ int unblock_signals (int * sigs, int nsig); void * find_address (void * addr); /* function and definition for loading binaries */ -enum object_type { OBJECT_RTLD, OBJECT_EXEC, OBJECT_PRELOAD }; +enum object_type { OBJECT_RTLD, OBJECT_EXEC, OBJECT_PRELOAD, OBJECT_EXTERNAL }; int check_elf_object (PAL_HANDLE handle); int load_elf_object (const char * uri, enum object_type type); diff --git a/Pal/src/pal_rtld.h b/Pal/src/pal_rtld.h index 7431fe34..f951dc6c 100644 --- a/Pal/src/pal_rtld.h +++ b/Pal/src/pal_rtld.h @@ -102,6 +102,16 @@ struct link_map { const Elf32_Word * l_gnu_chain_zero; }; +struct link_gdb_map { + /* These first few members are part of the protocol with the debugger. + This is the same format used in SVR4. */ + + ElfW(Addr) l_addr; /* Base address shared object is loaded at. */ + const char * l_name; /* Absolute file name object was found in. */ + ElfW(Dyn) * l_ld; /* Dynamic section of the shared object. */ + struct link_map * l_next, * l_prev; /* Chain of loaded objects. */ +}; + extern struct link_map * loaded_libraries; extern struct link_map * rtld_map; extern struct link_map * exec_map; @@ -207,4 +217,9 @@ do_lookup_map (ElfW(Sym) * ref, const char * undef_name, const uint_fast32_t hash, unsigned long int elf_hash, const struct link_map * map); +/* for GDB debugging */ +void _DkDebugAddMap (struct link_map * map); +void _DkDebugDelMap (struct link_map * map); + + #endif /* PAL_RTLD_H */ diff --git a/Pal/src/security/Linux/Makefile b/Pal/src/security/Linux/Makefile index a309ffd1..87b0ae16 100644 --- a/Pal/src/security/Linux/Makefile +++ b/Pal/src/security/Linux/Makefile @@ -27,7 +27,6 @@ libpal_sec.so: $(addsuffix .o,$(objs)) $(graphene_lib) @echo [ security/Linux/$@ ] @[ ! -f $@ ] || mv -f $@ $@.backup @$(LD) $(LDFLAGS) -o $@ $^ -soname=libpal_sec.so - @cd ../.. && ln -sf security/Linux/libpal_sec.so %.o: %.c @echo [ security/Linux/$@ ]