apply multiple patches

This commit is contained in:
Chia-Che Tsai
2015-02-12 20:13:00 -08:00
parent 82ea92de08
commit 5eaaf9abfb
73 changed files with 974 additions and 629 deletions
+2 -1
View File
@@ -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' ),
+14 -48
View File
@@ -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
+3 -7
View File
@@ -1,15 +1,11 @@
#include <syscalldb.h>
#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
-10
View File
@@ -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 */
+2
View File
@@ -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);
-14
View File
@@ -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);
+1 -1
View File
@@ -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;
};
+2
View File
@@ -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 */
+1 -1
View File
@@ -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 [ $@ ]
+1
View File
@@ -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;
+73 -6
View File
@@ -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,
+9 -24
View File
@@ -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 != '/')
+32 -9
View File
@@ -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;
}
+98
View File
@@ -11,11 +11,14 @@
#include <pal.h>
#include <pal_error.h>
#include <asm/fcntl.h>
#include <asm/mman.h>
#include <asm/unistd.h>
#include <asm/prctl.h>
#include <errno.h>
#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, },
}, };
+1 -1
View File
@@ -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;
}
+2 -4
View File
@@ -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: *;
};
+7 -6
View File
@@ -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"
+13 -160
View File
@@ -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
+24 -2
View File
@@ -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)
+2 -5
View File
@@ -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;
+51 -5
View File
@@ -37,6 +37,7 @@
#include <asm/prctl.h>
#include <asm/mman.h>
#include <asm/ioctls.h>
#include <linux/sched.h>
#include <linux/futex.h>
#include <linux/wait.h>
#include <errno.h>
@@ -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);
+13 -4
View File
@@ -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
+148 -71
View File
@@ -29,6 +29,7 @@
#include <shim_table.h>
#include <shim_thread.h>
#include <shim_utils.h>
#include <shim_checkpoint.h>
#include <shim_profile.h>
#include <pal.h>
@@ -40,6 +41,14 @@
#include <linux/sched.h>
#include <asm/prctl.h>
struct clone_args {
PAL_HANDLE create_event;
PAL_HANDLE initialize_event;
struct shim_thread * thread, * parent;
void * stack;
void * return_pc;
};
/* from **sysdeps/unix/sysv/linux/x86_64/clone.S:
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;
}
+1 -2
View File
@@ -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;
}
+4 -6
View File
@@ -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 <shim_checkpoint.h>
static int migrate_fork (struct shim_cp_store * cpstore,
struct shim_process * process,
struct shim_thread * thread, va_list ap)
int migrate_fork (struct shim_cp_store * cpstore,
struct shim_process * process,
struct shim_thread * thread, va_list ap)
{
BEGIN_MIGRATION_DEF(fork, struct shim_process * proc,
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;
+126 -20
View File
@@ -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);
}
+1 -1
View File
@@ -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);
+4 -7
View File
@@ -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);
+19 -22
View File
@@ -22,8 +22,8 @@
#include <shim_tls.h>
.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
+4 -5
View File
@@ -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)
+3 -5
View File
@@ -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
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:obj/bin/httpd
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:bash-local
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/bin/bash
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:busybox
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:busybox_nofork
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/g++
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.interp = file:$(SHIM)build/elf/ld.so
loader.preload = file:$(SHIM)build/libsysdb.so
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/g++
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/gcc
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.interp = file:$(SHIMROOT)build/elf/ld.so
loader.preload = file:$(SHIMROOT)build/libsysdb.so
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/gcc
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:$(PWD)build/sbin/lighttpd-angel
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:$(PWD)build/sbin/lighttpd
@@ -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])) {
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:$(PWD)lmbench-2.5/bin/linux/$(BIN)
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/make
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:make-local
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/make
@@ -1,4 +1,4 @@
#!$(PWD)../libpal.so
#!$(PAL)
loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/bin/python
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+4
View File
@@ -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
-1
View File
@@ -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;
}
+12
View File
@@ -0,0 +1,12 @@
/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
/* a simple helloworld test */
#include <stdlib.h>
int main(int argc, char ** argv)
{
system("./helloworld");
return 0;
}
+1 -1
View File
@@ -895,7 +895,7 @@ out:
mutex_unlock(&pending->receiver_lock);
up_write(&current_tsk->mm->mmap_sem);
rv = copy_to_user(((struct gipc_recv *)arg)->addr, addrs,
rv = copy_to_user(gr.addr, addrs,
sizeof(unsigned long) * gr.entries);
if (rv) {
printk(KERN_ERR "Graphene error: bad buffer %p\n",
+26 -11
View File
@@ -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)
+78 -65
View File
@@ -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
+4 -4
View File
@@ -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
+2 -1
View File
@@ -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
+7
View File
@@ -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
+8 -32
View File
@@ -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 ? :
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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 */
+106 -23
View File
@@ -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
@@ -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: *;
};
+3
View File
@@ -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 <sys/syscall.h>
+3
View File
@@ -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
+1 -5
View File
@@ -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);
+15
View File
@@ -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 */
-1
View File
@@ -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/$@ ]