From 7f186ba30aa211f4af6313ef3b8cc198de31ec4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Borys=20Pop=C5=82awski?= Date: Wed, 17 Feb 2021 20:11:37 +0100 Subject: [PATCH] [PAL] Rework PAL API value and error returning interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old version used special function `DkRaiseFailure` (which in turn called LibOS callback, which saved the error code) to return errors, values were returned directly from functions. This was annoying to deal with, as some functions did not return any value, yet they still used `DkRaiseFailure` to indicate errors. Moreover it abused exception handling interface, to callback into LibOS. The new version uniformly returns values via out-arguments (pointer passed by the caller, where the return value is stored). Errors are returned from functions directly, with `0` indicating successful call. This commit additionally fixes multiple bugs around error code checking. Signed-off-by: Borys PopÅ‚awski --- Documentation/pal/host-abi.rst | 3 - LibOS/shim/include/shim_internal.h | 77 +++--- LibOS/shim/include/shim_lock.h | 7 +- LibOS/shim/include/shim_tcb.h | 1 - LibOS/shim/include/shim_thread.h | 8 +- LibOS/shim/include/shim_vma.h | 4 +- LibOS/shim/src/bookkeep/shim_handle.c | 2 +- LibOS/shim/src/bookkeep/shim_thread.c | 40 +-- LibOS/shim/src/bookkeep/shim_vma.c | 16 +- LibOS/shim/src/elf/shim_rtld.c | 55 ++-- LibOS/shim/src/fs/chroot/fs.c | 127 ++++----- LibOS/shim/src/fs/dev/attestation.c | 27 +- LibOS/shim/src/fs/dev/random.c | 4 +- LibOS/shim/src/fs/eventfd/fs.c | 25 +- LibOS/shim/src/fs/pipe/fs.c | 40 +-- LibOS/shim/src/fs/socket/fs.c | 50 ++-- LibOS/shim/src/ipc/shim_ipc.c | 19 +- LibOS/shim/src/ipc/shim_ipc_helper.c | 76 ++--- LibOS/shim/src/ipc/shim_ipc_ranges.c | 21 +- LibOS/shim/src/shim_arch_prctl-x86_64.c | 2 +- LibOS/shim/src/shim_async.c | 38 ++- LibOS/shim/src/shim_checkpoint.c | 123 +++++---- LibOS/shim/src/shim_context-x86_64.c | 4 +- LibOS/shim/src/shim_init.c | 135 +++++---- LibOS/shim/src/shim_malloc.c | 34 +-- LibOS/shim/src/shim_object.c | 11 +- LibOS/shim/src/sys/shim_alarm.c | 20 +- LibOS/shim/src/sys/shim_brk.c | 15 +- LibOS/shim/src/sys/shim_clone.c | 25 +- LibOS/shim/src/sys/shim_epoll.c | 7 +- LibOS/shim/src/sys/shim_eventfd.c | 5 +- LibOS/shim/src/sys/shim_exec.c | 4 +- LibOS/shim/src/sys/shim_exit.c | 2 +- LibOS/shim/src/sys/shim_fs.c | 4 + LibOS/shim/src/sys/shim_futex.c | 7 +- LibOS/shim/src/sys/shim_getrandom.c | 2 +- LibOS/shim/src/sys/shim_ioctl.c | 5 +- LibOS/shim/src/sys/shim_mmap.c | 17 +- LibOS/shim/src/sys/shim_msgget.c | 38 ++- LibOS/shim/src/sys/shim_pipe.c | 14 +- LibOS/shim/src/sys/shim_poll.c | 9 +- LibOS/shim/src/sys/shim_sched.c | 8 +- LibOS/shim/src/sys/shim_semget.c | 8 +- LibOS/shim/src/sys/shim_sigaction.c | 14 +- LibOS/shim/src/sys/shim_socket.c | 145 +++++----- LibOS/shim/src/sys/shim_time.c | 29 +- LibOS/shim/src/sys/shim_wait.c | 4 +- LibOS/shim/src/utils/printf.c | 10 +- Pal/include/pal/pal.h | 210 ++++++++------ Pal/include/pal/pal_error.h | 3 +- Pal/regression/.gitignore | 1 - Pal/regression/AttestationReport.c | 42 ++- Pal/regression/Bootstrap.c | 7 +- Pal/regression/Directory.c | 64 +++-- Pal/regression/Event.c | 50 ++-- Pal/regression/Event2.c | 11 +- Pal/regression/Failure.c | 31 --- Pal/regression/File.c | 106 ++++--- Pal/regression/File2.c | 53 ++-- Pal/regression/HelloWorld.c | 14 +- Pal/regression/Makefile | 1 - Pal/regression/Memory.c | 26 +- Pal/regression/Misc.c | 36 ++- Pal/regression/Pie.c | 14 +- Pal/regression/Pipe.c | 40 +-- Pal/regression/Process.c | 33 ++- Pal/regression/Process2.c | 3 +- Pal/regression/Process3.c | 5 +- Pal/regression/Process4.c | 22 +- Pal/regression/Segment.c | 2 +- Pal/regression/Select.c | 36 ++- Pal/regression/Semaphore.c | 24 +- Pal/regression/SendHandle.c | 71 +++-- Pal/regression/Socket.c | 104 ++++--- Pal/regression/Tcp.c | 104 +++++-- Pal/regression/Thread.c | 9 +- Pal/regression/Thread2.c | 15 +- Pal/regression/Udp.c | 85 ++++-- Pal/regression/Wait.c | 24 +- Pal/regression/Yield.c | 6 +- Pal/regression/avl_tree_test.c | 2 +- Pal/regression/normalize_path.c | 2 +- Pal/regression/test_pal.py | 6 - Pal/src/db_events.c | 48 +--- Pal/src/db_exception.c | 9 +- Pal/src/db_memory.c | 60 ++-- Pal/src/db_misc.c | 78 ++---- Pal/src/db_mutex.c | 19 +- Pal/src/db_object.c | 55 ++-- Pal/src/db_process.c | 14 +- Pal/src/db_rtld.c | 2 +- Pal/src/db_streams.c | 306 ++++++--------------- Pal/src/db_threading.c | 58 +--- Pal/src/host/Linux-SGX/db_exception.c | 13 - Pal/src/host/Linux-SGX/db_files.c | 6 +- Pal/src/host/Linux-SGX/db_mutex.c | 11 +- Pal/src/host/Linux-SGX/enclave_framework.c | 6 +- Pal/src/host/Linux-SGX/enclave_ocalls.c | 10 +- Pal/src/host/Linux-SGX/enclave_pages.c | 2 +- Pal/src/host/Linux-SGX/enclave_pf.c | 2 +- Pal/src/host/Linux-SGX/pal_linux.h | 2 +- Pal/src/host/Linux/db_exception.c | 9 - Pal/src/host/Linux/db_mutex.c | 6 +- Pal/src/host/Linux/pal_host.h | 2 +- Pal/src/host/Skeleton/db_exception.c | 5 - Pal/src/host/Skeleton/db_mutex.c | 4 +- Pal/src/host/Skeleton/pal_host.h | 2 +- Pal/src/pal_error.c | 103 ++++--- Pal/src/pal_internal.h | 2 - 109 files changed, 1783 insertions(+), 1654 deletions(-) delete mode 100644 Pal/regression/Failure.c diff --git a/Documentation/pal/host-abi.rst b/Documentation/pal/host-abi.rst index f873b81492..a30632cc51 100644 --- a/Documentation/pal/host-abi.rst +++ b/Documentation/pal/host-abi.rst @@ -248,9 +248,6 @@ applications. :project: pal -.. doxygendefine:: PAL_STREAM_ERROR - :project: pal - Flags used for stream manipulation """""""""""""""""""""""""""""""""" diff --git a/LibOS/shim/include/shim_internal.h b/LibOS/shim/include/shim_internal.h index a9f71a4b4f..50fad6f9dd 100644 --- a/LibOS/shim/include/shim_internal.h +++ b/LibOS/shim/include/shim_internal.h @@ -19,8 +19,6 @@ void* shim_init(int argc, void* args); /* important macros and static inline functions */ -#define PAL_NATIVE_ERRNO() SHIM_TCB_GET(pal_errno) - #define INTERNAL_TID_BASE ((IDTYPE)1 << (sizeof(IDTYPE) * 8 - 1)) static inline bool is_internal_tid(unsigned int tid) { @@ -177,9 +175,12 @@ bool maybe_emulate_syscall(PAL_CONTEXT* context); */ bool handle_signal(PAL_CONTEXT* context, __sigset_t* old_mask_ptr); -long convert_pal_errno(long err); - -#define PAL_ERRNO() convert_pal_errno(PAL_NATIVE_ERRNO()) +/*! + * \brief Translate PAL error code into UNIX error code. + * + * The sign of the error code is preserved. + */ +long pal_to_unix_errno(long err); void warn_unsupported_syscall(unsigned long sysno); void debug_print_syscall_before(unsigned long sysno, ...); @@ -195,11 +196,7 @@ void debug_print_syscall_after(unsigned long sysno, ...); * Note that using `clear_event` probably requires external locking to avoid races. */ static inline int create_event(AEVENTTYPE* e) { - e->event = DkStreamOpen(URI_PREFIX_PIPE, PAL_ACCESS_RDWR, 0, 0, 0); - if (!e->event) { - return -PAL_ERRNO(); - } - return 0; + return pal_to_unix_errno(DkStreamOpen(URI_PREFIX_PIPE, PAL_ACCESS_RDWR, 0, 0, 0, &e->event)); } static inline PAL_HANDLE event_handle(AEVENTTYPE* e) { @@ -208,7 +205,7 @@ static inline PAL_HANDLE event_handle(AEVENTTYPE* e) { static inline void destroy_event(AEVENTTYPE* e) { if (e->event) { - DkObjectClose(e->event); + DkObjectClose(e->event); // TODO: handle errors e->event = NULL; } } @@ -223,15 +220,19 @@ static inline int set_event(AEVENTTYPE* e, size_t n) { char bytes[n]; memset(bytes, '\0', n); while (n > 0) { - PAL_NUM ret = DkStreamWrite(e->event, 0, n, bytes, NULL); - if (ret == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EINTR || err == EAGAIN || err == EWOULDBLOCK) { + size_t size = n; + int ret = DkStreamWrite(e->event, 0, &size, bytes, NULL); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; } - return -err; + return pal_to_unix_errno(ret); } - n -= ret; + if (size == 0) { + /* This should never happen. */ + return -EINVAL; + } + n -= size; } return 0; @@ -244,14 +245,20 @@ static inline int wait_event(AEVENTTYPE* e) { return -EINVAL; } - int err = 0; + int ret = 0; do { char byte; - PAL_NUM ret = DkStreamRead(e->event, 0, 1, &byte, NULL, 0); - err = ret == PAL_STREAM_ERROR ? PAL_ERRNO() : (ret == 0 ? ENODATA : 0); - } while (err == EINTR || err == EAGAIN || err == EWOULDBLOCK); + size_t size = 1; + ret = DkStreamRead(e->event, 0, &size, &byte, NULL, 0); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + } else if (size == 0) { + ret = -ENODATA; + } + /* XXX(borysp): I think we should actually return both of these. */ + } while (ret == -EINTR || ret == -EAGAIN); - return -err; + return ret; } static inline int clear_event(AEVENTTYPE* e) { @@ -266,16 +273,14 @@ static inline int clear_event(AEVENTTYPE* e) { PAL_FLG ievent = PAL_WAIT_READ; PAL_FLG revent = 0; - shim_get_tcb()->pal_errno = PAL_ERROR_SUCCESS; - PAL_BOL ret = DkStreamsWaitEvents(1, &handle, &ievent, &revent, /*timeout=*/0); - if (!ret) { - int err = PAL_ERRNO(); - if (err == EINTR) { + int ret = DkStreamsWaitEvents(1, &handle, &ievent, &revent, /*timeout=*/0); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED) { continue; - } else if (err == EAGAIN || err == EWOULDBLOCK) { + } else if (ret == -PAL_ERROR_TRYAGAIN) { break; } - return -err; + return pal_to_unix_errno(ret); } /* Even if `revent` has `PAL_WAIT_ERROR` marked, let `DkSitreamRead()` report the error @@ -283,18 +288,18 @@ static inline int clear_event(AEVENTTYPE* e) { assert(revent); char bytes[100]; - PAL_NUM n = DkStreamRead(e->event, 0, sizeof(bytes), bytes, NULL, 0); - if (n == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EINTR) { + size_t n = sizeof(bytes); + ret = DkStreamRead(e->event, 0, &n, bytes, NULL, 0); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED) { continue; - } else if (err == EAGAIN || err == EWOULDBLOCK) { + } else if (ret == -PAL_ERROR_TRYAGAIN) { /* This should not happen, since we polled above... */ break; } - return -err; + return pal_to_unix_errno(ret); } else if (n == 0) { - /* This should not happen, since we polled above... */ + /* This should not happen, something closed the handle? */ return -ENODATA; } } diff --git a/LibOS/shim/include/shim_lock.h b/LibOS/shim/include/shim_lock.h index 5d03b97738..fe1793b670 100644 --- a/LibOS/shim/include/shim_lock.h +++ b/LibOS/shim/include/shim_lock.h @@ -31,12 +31,11 @@ static inline void clear_lock(struct shim_lock* l) { static inline bool create_lock(struct shim_lock* l) { l->owner = 0; - l->lock = DkMutexCreate(0); - return l->lock != NULL; + return DkMutexCreate(0, &l->lock) == 0; } static inline void destroy_lock(struct shim_lock* l) { - DkObjectClose(l->lock); + DkObjectClose(l->lock); // TODO: handle errors clear_lock(l); } @@ -47,7 +46,7 @@ static void lock(struct shim_lock* l) { assert(l->lock); - while (!DkSynchronizationObjectWait(l->lock, NO_TIMEOUT)) + while (DkSynchronizationObjectWait(l->lock, NO_TIMEOUT) < 0) /* nop */; l->owner = get_cur_tid(); diff --git a/LibOS/shim/include/shim_tcb.h b/LibOS/shim/include/shim_tcb.h index 99562a9347..845b24784e 100644 --- a/LibOS/shim/include/shim_tcb.h +++ b/LibOS/shim/include/shim_tcb.h @@ -34,7 +34,6 @@ struct shim_tcb { /* Scratch space to temporarily store a register. On some architectures (e.g. x86_64 inside * an SGX enclave) we lack a way to restore all (or at least some) registers atomically. */ void* syscall_scratch_pc; - int pal_errno; struct debug_buf* debug_buf; void* vma_cache; diff --git a/LibOS/shim/include/shim_thread.h b/LibOS/shim/include/shim_thread.h index 486ba18c69..0a4d92987c 100644 --- a/LibOS/shim/include/shim_thread.h +++ b/LibOS/shim/include/shim_thread.h @@ -196,7 +196,7 @@ static inline void set_cur_thread(struct shim_thread* thread) { static inline void thread_setwait(struct shim_thread** queue, struct shim_thread* thread) { if (!thread) thread = get_cur_thread(); - DkEventClear(thread->scheduler_event); + DkEventClear(thread->scheduler_event); // TODO: handle errors if (queue) { get_thread(thread); *queue = thread; @@ -217,13 +217,11 @@ static inline int thread_sleep(uint64_t timeout_us, bool ignore_pending_signals) return -EINTR; } - if (!DkSynchronizationObjectWait(event, timeout_us)) - return -PAL_ERRNO(); - - return 0; + return pal_to_unix_errno(DkSynchronizationObjectWait(event, timeout_us)); } static inline void thread_wakeup(struct shim_thread* thread) { + // TODO: handle errors DkEventSet(thread->scheduler_event); } diff --git a/LibOS/shim/include/shim_vma.h b/LibOS/shim/include/shim_vma.h index b5495e8758..f4465351d1 100644 --- a/LibOS/shim/include/shim_vma.h +++ b/LibOS/shim/include/shim_vma.h @@ -60,7 +60,9 @@ int init_vma(void); * if (bkeep_munmap(ptr, len, is_internal, &tmp_vma) < 0) { * handle_errors(); * } - * DkVirtualMemoryFree(ptr, len); + * if (DkVirtualMemoryFree(ptr, len) < 0) { + * handle_errors(); + * } * bkeep_remove_tmp_vma(tmp_vma); * * Such a way of freeing is needed, so that no other thread will map the same memory in the window diff --git a/LibOS/shim/src/bookkeep/shim_handle.c b/LibOS/shim/src/bookkeep/shim_handle.c index 17ed85f70a..9e29c4bd9c 100644 --- a/LibOS/shim/src/bookkeep/shim_handle.c +++ b/LibOS/shim/src/bookkeep/shim_handle.c @@ -460,7 +460,7 @@ void put_handle(struct shim_handle* hdl) { #ifdef DEBUG_REF log_debug("handle %p closes PAL handle %p\n", hdl, hdl->pal_handle); #endif - DkObjectClose(hdl->pal_handle); + DkObjectClose(hdl->pal_handle); // TODO: handle errors hdl->pal_handle = NULL; } diff --git a/LibOS/shim/src/bookkeep/shim_thread.c b/LibOS/shim/src/bookkeep/shim_thread.c index 42d1bf7317..092305c672 100644 --- a/LibOS/shim/src/bookkeep/shim_thread.c +++ b/LibOS/shim/src/bookkeep/shim_thread.c @@ -119,16 +119,18 @@ int alloc_thread_libos_stack(struct shim_thread* thread) { } bool need_mem_free = false; - if (DkVirtualMemoryAlloc(addr, SHIM_THREAD_LIBOS_STACK_SIZE, 0, LINUX_PROT_TO_PAL(prot, flags)) - != addr) { - ret = -PAL_ERRNO(); + ret = DkVirtualMemoryAlloc(&addr, SHIM_THREAD_LIBOS_STACK_SIZE, 0, + LINUX_PROT_TO_PAL(prot, flags)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto unmap; } need_mem_free = true; /* Create a stack guard page. */ - if (!DkVirtualMemoryProtect(addr, PAGE_SIZE, PAL_PROT_NONE)) { - ret = -PAL_ERRNO(); + ret = DkVirtualMemoryProtect(addr, PAGE_SIZE, PAL_PROT_NONE); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto unmap; } @@ -145,7 +147,9 @@ unmap:; BUG(); } if (need_mem_free) { - DkVirtualMemoryFree(addr, SHIM_THREAD_LIBOS_STACK_SIZE); + if (DkVirtualMemoryFree(addr, SHIM_THREAD_LIBOS_STACK_SIZE) < 0) { + BUG(); + } } bkeep_remove_tmp_vma(tmp_vma); return ret; @@ -187,15 +191,15 @@ static int init_main_thread(void) { set_sig_mask(cur_thread, &set); unlock(&cur_thread->lock); - cur_thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE); - if (!cur_thread->scheduler_event) { + int ret = DkNotificationEventCreate(PAL_TRUE, &cur_thread->scheduler_event); + if (ret < 0) { put_thread(cur_thread); - return -ENOMEM; + return pal_to_unix_errno(ret);; } /* TODO: I believe there is some Pal allocated initial stack which could be reused by the first * thread. Tracked: https://github.com/oscarlab/graphene/issues/2140 */ - int ret = alloc_thread_libos_stack(cur_thread); + ret = alloc_thread_libos_stack(cur_thread); if (ret < 0) { put_thread(cur_thread); return ret; @@ -287,8 +291,8 @@ struct shim_thread* get_new_thread(void) { unlock(&cur_thread->lock); - thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE); - if (!thread->scheduler_event) { + int ret = DkNotificationEventCreate(PAL_TRUE, &thread->scheduler_event); + if (ret < 0) { put_thread(thread); return NULL; } @@ -348,7 +352,9 @@ void put_thread(struct shim_thread* thread) { addr, (char*)addr + SHIM_THREAD_LIBOS_STACK_SIZE); BUG(); } - DkVirtualMemoryFree(addr, SHIM_THREAD_LIBOS_STACK_SIZE); + if (DkVirtualMemoryFree(addr, SHIM_THREAD_LIBOS_STACK_SIZE) < 0) { + BUG(); + } bkeep_remove_tmp_vma(tmp_vma); } @@ -606,9 +612,9 @@ BEGIN_RS_FUNC(thread) { return -ENOMEM; } - thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE); - if (!thread->scheduler_event) { - return -ENOMEM; + int ret = DkNotificationEventCreate(PAL_TRUE, &thread->scheduler_event); + if (ret < 0) { + return pal_to_unix_errno(ret); } if (thread->handle_map) { @@ -626,7 +632,7 @@ BEGIN_RS_FUNC(thread) { assert(!get_cur_thread()); - int ret = alloc_thread_libos_stack(thread); + ret = alloc_thread_libos_stack(thread); if (ret < 0) { return ret; } diff --git a/LibOS/shim/src/bookkeep/shim_vma.c b/LibOS/shim/src/bookkeep/shim_vma.c index 3fd6595376..5214027c51 100644 --- a/LibOS/shim/src/bookkeep/shim_vma.c +++ b/LibOS/shim/src/bookkeep/shim_vma.c @@ -295,13 +295,14 @@ static void* _vma_malloc(size_t size) { return NULL; } - if (DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_WRITE | PAL_PROT_READ) != addr) { + int ret = DkVirtualMemoryAlloc(&addr, size, 0, PAL_PROT_WRITE | PAL_PROT_READ); + if (ret < 0) { struct shim_vma* vmas_to_free = NULL; spinlock_lock(&vma_tree_lock); /* Since we are freeing a range we just created, additional vma is not needed. */ - int ret = _vma_bkeep_remove((uintptr_t)addr, (uintptr_t)addr + size, /*is_internal=*/true, - NULL, &vmas_to_free); + ret = _vma_bkeep_remove((uintptr_t)addr, (uintptr_t)addr + size, /*is_internal=*/true, NULL, + &vmas_to_free); spinlock_unlock(&vma_tree_lock); if (ret < 0) { log_error("Removing a vma we just created failed with %d!\n", ret); @@ -593,7 +594,7 @@ int init_vma(void) { int ret = DkRandomBitsRead(&gap, sizeof(gap)); if (ret < 0) { - return -convert_pal_errno(-ret); + return pal_to_unix_errno(ret); } /* Resulting distribution is not ideal, but it should not be an issue here. */ @@ -1313,9 +1314,10 @@ BEGIN_RS_FUNC(vma) { } if (need_mapped < vma->addr + vma->length) { - if (DkVirtualMemoryAlloc(need_mapped, vma->addr + vma->length - need_mapped, - /*alloc_type=*/0, - LINUX_PROT_TO_PAL(vma->prot, /*map_flags=*/0))) { + int ret = DkVirtualMemoryAlloc(need_mapped, vma->addr + vma->length - need_mapped, + /*alloc_type=*/0, + LINUX_PROT_TO_PAL(vma->prot, /*map_flags=*/0)); + if (ret >= 0) { need_mapped += vma->length; } } diff --git a/LibOS/shim/src/elf/shim_rtld.c b/LibOS/shim/src/elf/shim_rtld.c index 723cab8413..12f490b7b9 100644 --- a/LibOS/shim/src/elf/shim_rtld.c +++ b/LibOS/shim/src/elf/shim_rtld.c @@ -309,14 +309,23 @@ static struct link_map* __map_elf_object(struct shim_handle* file, const void* f l->loadcmds[l->nloadcmds - 1].mapstart - c->mapend, PROT_NONE, /*is_internal=*/false); if (ret < 0) { + errstring = "failed to bookkeep permissions change"; + goto call_lose; + } + } + if (type == OBJECT_LOAD) { + ret = DkVirtualMemoryProtect((void*)RELOCATE(l, c->mapend), + l->loadcmds[l->nloadcmds - 1].mapstart - c->mapend, + PAL_PROT_NONE); + if (ret < 0) { + /* XXX: this often fails, because the above address might not be allocated. + * We need to rewrite this function soon. errstring = "failed to change permissions"; goto call_lose; + */ + ret = 0; } } - if (type == OBJECT_LOAD) - DkVirtualMemoryProtect((void*)RELOCATE(l, c->mapend), - l->loadcmds[l->nloadcmds - 1].mapstart - c->mapend, - PAL_PROT_NONE); } goto do_remap; @@ -387,15 +396,15 @@ static struct link_map* __map_elf_object(struct shim_handle* file, const void* f /* Zero the final part of the last page of the segment. */ if ((c->prot & PROT_WRITE) == 0) { /* Dag nab it. */ - if (!DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align, - LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0) - | PAL_PROT_WRITE)) { + if (DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align, + LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0) + | PAL_PROT_WRITE) < 0) { errstring = "cannot change memory protections"; goto call_lose; } memset((void*)zero, '\0', zeropage - zero); - if (!DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align, - LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0))) { + if (DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align, + LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0)) < 0) { errstring = "cannot change memory protections"; goto call_lose; } @@ -418,10 +427,10 @@ static struct link_map* __map_elf_object(struct shim_handle* file, const void* f if (type != OBJECT_MAPPED && type != OBJECT_INTERNAL && type != OBJECT_VDSO) { - PAL_PTR mapat = - DkVirtualMemoryAlloc((void*)zeropage, zeroend - zeropage, /*alloc_type=*/0, - LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0)); - if (!mapat) { + void* mapat = (void*)zeropage; + ret = DkVirtualMemoryAlloc(&mapat, zeroend - zeropage, /*alloc_type=*/0, + LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0)); + if (ret < 0) { errstring = "cannot map zero-fill pages"; goto call_lose; } @@ -857,19 +866,21 @@ static int vdso_map_init(void) { return ret; } - void* ret_addr = (void*)DkVirtualMemoryAlloc(addr, ALLOC_ALIGN_UP(vdso_so_size), - /*alloc_type=*/0, PAL_PROT_READ | PAL_PROT_WRITE); - if (!ret_addr) - return -PAL_ERRNO(); - assert(addr == ret_addr); + ret = DkVirtualMemoryAlloc(&addr, ALLOC_ALIGN_UP(vdso_so_size), /*alloc_type=*/0, + PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { + return pal_to_unix_errno(ret); + } memcpy(addr, &vdso_so, vdso_so_size); memset(addr + vdso_so_size, 0, ALLOC_ALIGN_UP(vdso_so_size) - vdso_so_size); __load_elf_object(NULL, addr, OBJECT_VDSO); vdso_map->l_name = "vDSO"; - if (!DkVirtualMemoryProtect(addr, ALLOC_ALIGN_UP(vdso_so_size), PAL_PROT_READ | PAL_PROT_EXEC)) - return -PAL_ERRNO(); + ret = DkVirtualMemoryProtect(addr, ALLOC_ALIGN_UP(vdso_so_size), PAL_PROT_READ | PAL_PROT_EXEC); + if (ret < 0) { + return pal_to_unix_errno(ret); + } vdso_addr = addr; return 0; @@ -1016,8 +1027,8 @@ noreturn void execute_elf_object(struct shim_handle* exec, void* argp, ElfW(auxv ElfW(Addr) random = auxp_extra; /* random 16B for AT_RANDOM */ ret = DkRandomBitsRead((PAL_PTR)random, 16); if (ret < 0) { - log_error("execute_elf_object: DkRandomBitsRead failed.\n"); - DkThreadExit(/*clear_child_tid=*/NULL); + log_error("execute_elf_object: DkRandomBitsRead failed: %d\n", ret); + DkProcessExit(1); /* UNREACHABLE */ } auxp[5].a_un.a_val = random; diff --git a/LibOS/shim/src/fs/chroot/fs.c b/LibOS/shim/src/fs/chroot/fs.c index e83c8cad51..fcb43a61ba 100644 --- a/LibOS/shim/src/fs/chroot/fs.c +++ b/LibOS/shim/src/fs/chroot/fs.c @@ -189,9 +189,15 @@ static int __query_attr(struct shim_dentry* dent, struct shim_file_data* data, PAL_STREAM_ATTR pal_attr; enum shim_file_type old_type = data->type; - if (pal_handle ? !DkStreamAttributesQueryByHandle(pal_handle, &pal_attr) - : !DkStreamAttributesQuery(qstrgetstr(&data->host_uri), &pal_attr)) - return -PAL_ERRNO(); + int ret; + if (pal_handle) { + ret = DkStreamAttributesQueryByHandle(pal_handle, &pal_attr); + } else { + ret = DkStreamAttributesQuery(qstrgetstr(&data->host_uri), &pal_attr); + } + if (ret < 0) { + return pal_to_unix_errno(ret); + } /* need to correct the data type */ if (data->type == FILE_UNKNOWN) @@ -379,14 +385,14 @@ static int __chroot_open(struct shim_dentry* dent, const char* uri, int flags, m if (hdl && hdl->pal_handle) { palhdl = hdl->pal_handle; } else { - palhdl = DkStreamOpen(uri, accmode, mode, create, options); + ret = DkStreamOpen(uri, accmode, mode, create, options, &palhdl); - if (!palhdl) { - if (PAL_NATIVE_ERRNO() == PAL_ERROR_DENIED && accmode != oldmode) - palhdl = DkStreamOpen(uri, oldmode, mode, create, options); + if (ret < 0) { + if (ret == -PAL_ERROR_DENIED && accmode != oldmode) + ret = DkStreamOpen(uri, oldmode, mode, create, options, &palhdl); - if (!palhdl) - return -PAL_ERRNO(); + if (ret < 0) + return pal_to_unix_errno(ret); } /* If DENTRY_LISTED is set on the parent dentry, list_directory_dentry() will not update @@ -583,10 +589,7 @@ static int chroot_hstat(struct shim_handle* hdl, struct stat* stat) { } static int chroot_flush(struct shim_handle* hdl) { - int ret = DkStreamFlush(hdl->pal_handle); - if (ret < 0) - return ret; - return 0; + return pal_to_unix_errno(DkStreamFlush(hdl->pal_handle)); } static int chroot_close(struct shim_handle* hdl) { @@ -619,15 +622,13 @@ static ssize_t chroot_read(struct shim_handle* hdl, void* buf, size_t count) { lock(&hdl->lock); - PAL_NUM pal_ret = DkStreamRead(hdl->pal_handle, file->marker, count, buf, NULL, 0); - if (pal_ret == 0) { - ret = 0; - } else if (pal_ret == PAL_STREAM_ERROR) { - ret = -PAL_ERRNO(); + ret = DkStreamRead(hdl->pal_handle, file->marker, &count, buf, NULL, 0); + if (ret < 0) { + ret = pal_to_unix_errno(ret); } else { - if (__builtin_add_overflow(pal_ret, 0, &ret)) + if (__builtin_add_overflow(count, 0, &ret)) BUG(); - if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker)) + if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, count, &file->marker)) BUG(); } @@ -661,15 +662,13 @@ static ssize_t chroot_write(struct shim_handle* hdl, const void* buf, size_t cou lock(&hdl->lock); - PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void*)buf, NULL); - if (pal_ret == 0) { - ret = 0; - } else if (pal_ret == PAL_STREAM_ERROR) { - ret = -PAL_ERRNO(); + ret = DkStreamWrite(hdl->pal_handle, file->marker, &count, (void*)buf, NULL); + if (ret < 0) { + ret = pal_to_unix_errno(ret); } else { - if (__builtin_add_overflow(pal_ret, 0, &ret)) + if (__builtin_add_overflow(count, 0, &ret)) BUG(); - if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker)) + if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, count, &file->marker)) BUG(); if (file->marker > file->size) { file->size = file->marker; @@ -697,13 +696,7 @@ static int chroot_mmap(struct shim_handle* hdl, void** addr, size_t size, int pr #endif return -EINVAL; - void* alloc_addr = (void*)DkStreamMap(hdl->pal_handle, *addr, pal_prot, offset, size); - - if (!alloc_addr) - return -PAL_ERRNO(); - - *addr = alloc_addr; - return 0; + return pal_to_unix_errno(DkStreamMap(hdl->pal_handle, addr, pal_prot, offset, size)); } static off_t chroot_seek(struct shim_handle* hdl, off_t offset, int whence) { @@ -771,16 +764,12 @@ static int chroot_truncate(struct shim_handle* hdl, off_t len) { __atomic_store_n(&data->size.counter, len, __ATOMIC_SEQ_CST); } - PAL_NUM rv = DkStreamSetLength(hdl->pal_handle, len); - if (rv) { - // For an error, cast it back down to an int return code - ret = -((int)rv); + ret = DkStreamSetLength(hdl->pal_handle, len); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } - // DEP 10/25/16: Truncate returns 0 on success, not the length - ret = 0; - if (file->marker > len) file->marker = len; @@ -817,9 +806,10 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent) const char* uri = qstrgetstr(&data->host_uri); assert(strstartswith(uri, URI_PREFIX_DIR)); - pal_hdl = DkStreamOpen(uri, PAL_ACCESS_RDONLY, 0, 0, 0); - if (!pal_hdl) - return -PAL_ERRNO(); + ret = DkStreamOpen(uri, PAL_ACCESS_RDONLY, 0, 0, 0, &pal_hdl); + if (ret < 0) { + return pal_to_unix_errno(ret); + } buf = malloc(buf_size); if (!buf) { @@ -829,13 +819,14 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent) while (1) { /* DkStreamRead for directory will return as many entries as fits into the buffer. */ - PAL_NUM bytes = DkStreamRead(pal_hdl, 0, buf_size, buf, NULL, 0); - if (bytes == PAL_STREAM_ERROR) { - ret = -PAL_ERRNO(); + size_t bytes = buf_size; + ret = DkStreamRead(pal_hdl, 0, &bytes, buf, NULL, 0); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } else if (bytes == 0) { /* End of directory listing */ - ret = 0; + assert(ret == 0); break; } /* Last entry must be null-terminated */ @@ -945,7 +936,7 @@ static int chroot_checkout(struct shim_handle* hdl) { * the handle over RPC; otherwise, send it. */ PAL_STREAM_ATTR attr; - if (DkStreamAttributesQuery(qstrgetstr(&hdl->uri), &attr)) + if (DkStreamAttributesQuery(qstrgetstr(&hdl->uri), &attr) == 0) hdl->pal_handle = NULL; } @@ -979,12 +970,17 @@ static int chroot_unlink(struct shim_dentry* dir, struct shim_dentry* dent) { if ((ret = try_create_data(dent, NULL, 0, &data)) < 0) return ret; - PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&data->host_uri), 0, 0, 0, 0); - if (!pal_hdl) - return -PAL_ERRNO(); + PAL_HANDLE pal_hdl = NULL; + ret = DkStreamOpen(qstrgetstr(&data->host_uri), 0, 0, 0, 0, &pal_hdl); + if (ret < 0) { + return pal_to_unix_errno(ret); + } - DkStreamDelete(pal_hdl, 0); + ret = DkStreamDelete(pal_hdl, 0); DkObjectClose(pal_hdl); + if (ret < 0) { + return pal_to_unix_errno(ret); + } dent->mode = NO_MODE; data->mode = 0; @@ -1050,14 +1046,16 @@ static int chroot_rename(struct shim_dentry* old, struct shim_dentry* new) { return ret; } - PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&old_data->host_uri), 0, 0, 0, 0); - if (!pal_hdl) { - return -PAL_ERRNO(); + PAL_HANDLE pal_hdl = NULL; + ret = DkStreamOpen(qstrgetstr(&old_data->host_uri), 0, 0, 0, 0, &pal_hdl); + if (ret < 0) { + return pal_to_unix_errno(ret); } - if (!DkStreamChangeName(pal_hdl, qstrgetstr(&new_data->host_uri))) { + ret = DkStreamChangeName(pal_hdl, qstrgetstr(&new_data->host_uri)); + if (ret < 0) { DkObjectClose(pal_hdl); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } new->mode = new_data->mode = old_data->mode; @@ -1081,15 +1079,18 @@ static int chroot_chmod(struct shim_dentry* dent, mode_t mode) { if ((ret = try_create_data(dent, NULL, 0, &data)) < 0) return ret; - PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&data->host_uri), 0, 0, 0, 0); - if (!pal_hdl) - return -PAL_ERRNO(); + PAL_HANDLE pal_hdl = NULL; + ret = DkStreamOpen(qstrgetstr(&data->host_uri), 0, 0, 0, 0, &pal_hdl); + if (ret < 0) { + return pal_to_unix_errno(ret); + } PAL_STREAM_ATTR attr = {.share_flags = mode}; - if (!DkStreamAttributesSetByHandle(pal_hdl, &attr)) { + ret = DkStreamAttributesSetByHandle(pal_hdl, &attr); + if (ret < 0) { DkObjectClose(pal_hdl); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } DkObjectClose(pal_hdl); diff --git a/LibOS/shim/src/fs/dev/attestation.c b/LibOS/shim/src/fs/dev/attestation.c index 1ae10b2a8c..5baf2822ad 100644 --- a/LibOS/shim/src/fs/dev/attestation.c +++ b/LibOS/shim/src/fs/dev/attestation.c @@ -42,10 +42,10 @@ static int init_attestation_struct_sizes(void) { return 0; } - bool ok = DkAttestationReport(/*user_report_data=*/NULL, &g_user_report_data_size, + int ret = DkAttestationReport(/*user_report_data=*/NULL, &g_user_report_data_size, /*target_info=*/NULL, &g_target_info_size, /*report=*/NULL, &g_report_size); - if (!ok) + if (ret < 0) return -EACCES; assert(g_user_report_data_size && g_user_report_data_size <= sizeof(g_user_report_data)); @@ -236,9 +236,9 @@ static int dev_attestation_my_target_info_open(struct shim_handle* hdl, const ch /* below invocation returns this enclave's target info because we zeroed out (via calloc) * target_info: it's a hint to function to update target_info with this enclave's info */ - bool ok = DkAttestationReport(user_report_data, &user_report_data_size, target_info, - &target_info_size, /*report=*/NULL, &report_size); - if (!ok) { + ret = DkAttestationReport(user_report_data, &user_report_data_size, target_info, + &target_info_size, /*report=*/NULL, &report_size); + if (ret < 0) { ret = -EACCES; goto out; } @@ -309,9 +309,9 @@ static int dev_attestation_report_open(struct shim_handle* hdl, const char* name goto out; } - bool ok = DkAttestationReport(&g_user_report_data, &g_user_report_data_size, &g_target_info, - &g_target_info_size, report, &g_report_size); - if (!ok) { + ret = DkAttestationReport(&g_user_report_data, &g_user_report_data_size, &g_target_info, + &g_target_info_size, report, &g_report_size); + if (ret < 0) { ret = -EACCES; goto out; } @@ -389,8 +389,8 @@ static int dev_attestation_quote_open(struct shim_handle* hdl, const char* name, goto out; } - bool ok = DkAttestationQuote(&g_user_report_data, g_user_report_data_size, quote, "e_size); - if (!ok) { + ret = DkAttestationQuote(&g_user_report_data, g_user_report_data_size, quote, "e_size); + if (ret < 0) { ret = -EACCES; goto out; } @@ -434,8 +434,11 @@ static int pfkey_modify(struct shim_handle* hdl) { memcpy(&g_pf_key_hex, hdl->info.str.data->str, sizeof(g_pf_key_hex)); g_pf_key_hex[sizeof(g_pf_key_hex) - 1] = '\0'; - bool ok = DkSetProtectedFilesKey(&g_pf_key_hex); - return ok ? 0 : -EACCES; + int ret = DkSetProtectedFilesKey(&g_pf_key_hex); + if (ret < 0) { + ret = -EACCES; + } + return ret; } /*! diff --git a/LibOS/shim/src/fs/dev/random.c b/LibOS/shim/src/fs/dev/random.c index 8817e253e3..61798a3055 100644 --- a/LibOS/shim/src/fs/dev/random.c +++ b/LibOS/shim/src/fs/dev/random.c @@ -12,10 +12,10 @@ static ssize_t dev_random_read(struct shim_handle* hdl, void* buf, size_t count) { __UNUSED(hdl); - ssize_t ret = DkRandomBitsRead(buf, count); + int ret = DkRandomBitsRead(buf, count); if (ret < 0) - return -convert_pal_errno(-ret); + return pal_to_unix_errno(ret); return count; } diff --git a/LibOS/shim/src/fs/eventfd/fs.c b/LibOS/shim/src/fs/eventfd/fs.c index 248b3a1be2..eb8b1a0f84 100644 --- a/LibOS/shim/src/fs/eventfd/fs.c +++ b/LibOS/shim/src/fs/eventfd/fs.c @@ -20,24 +20,24 @@ static ssize_t eventfd_read(struct shim_handle* hdl, void* buf, size_t count) { if (count < sizeof(uint64_t)) return -EINVAL; - PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0); - - if (bytes == PAL_STREAM_ERROR) - return -PAL_ERRNO(); + int ret = DkStreamRead(hdl->pal_handle, 0, &count, buf, NULL, 0); + if (ret < 0) { + return pal_to_unix_errno(ret); + } - return (ssize_t)bytes; + return (ssize_t)count; } static ssize_t eventfd_write(struct shim_handle* hdl, const void* buf, size_t count) { if (count < sizeof(uint64_t)) return -EINVAL; - PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL); - - if (bytes == PAL_STREAM_ERROR) - return -PAL_ERRNO(); + int ret = DkStreamWrite(hdl->pal_handle, 0, &count, (void*)buf, NULL); + if (ret < 0) { + return pal_to_unix_errno(ret); + } - return (ssize_t)bytes; + return (ssize_t)count; } static off_t eventfd_poll(struct shim_handle* hdl, int poll_type) { @@ -51,8 +51,9 @@ static off_t eventfd_poll(struct shim_handle* hdl, int poll_type) { } PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) { - ret = -PAL_ERRNO(); + int query_ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (query_ret < 0) { + ret = pal_to_unix_errno(query_ret); goto out; } diff --git a/LibOS/shim/src/fs/pipe/fs.c b/LibOS/shim/src/fs/pipe/fs.c index 426c2a61e9..d4c2f77742 100644 --- a/LibOS/shim/src/fs/pipe/fs.c +++ b/LibOS/shim/src/fs/pipe/fs.c @@ -28,23 +28,22 @@ static ssize_t pipe_read(struct shim_handle* hdl, void* buf, size_t count) { if (!hdl->info.pipe.ready_for_ops) return -EACCES; - PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0); - - if (bytes == PAL_STREAM_ERROR) - return -PAL_ERRNO(); + int ret = DkStreamRead(hdl->pal_handle, 0, &count, buf, NULL, 0); + if (ret < 0) { + return pal_to_unix_errno(ret); + } - return (ssize_t)bytes; + return (ssize_t)count; } static ssize_t pipe_write(struct shim_handle* hdl, const void* buf, size_t count) { if (!hdl->info.pipe.ready_for_ops) return -EACCES; - PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL); - - if (bytes == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EPIPE) { + int ret = DkStreamWrite(hdl->pal_handle, 0, &count, (void*)buf, NULL); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + if (ret == -EPIPE) { siginfo_t info = { .si_signo = SIGPIPE, .si_pid = g_process.pid, @@ -54,10 +53,10 @@ static ssize_t pipe_write(struct shim_handle* hdl, const void* buf, size_t count log_error("pipe_write: failed to deliver a signal\n"); } } - return -err; + return ret; } - return (ssize_t)bytes; + return (ssize_t)count; } static int pipe_hstat(struct shim_handle* hdl, struct stat* stat) { @@ -107,8 +106,9 @@ static off_t pipe_poll(struct shim_handle* hdl, int poll_type) { } PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) { - ret = -PAL_ERRNO(); + int query_ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (query_ret < 0) { + ret = pal_to_unix_errno(query_ret); goto out; } @@ -136,8 +136,10 @@ static int pipe_setflags(struct shim_handle* hdl, int flags) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } if (attr.nonblocking) { if (flags & O_NONBLOCK) @@ -151,8 +153,10 @@ static int pipe_setflags(struct shim_handle* hdl, int flags) { attr.nonblocking = PAL_TRUE; } - if (!DkStreamAttributesSetByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + ret = DkStreamAttributesSetByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } return 0; } diff --git a/LibOS/shim/src/fs/socket/fs.c b/LibOS/shim/src/fs/socket/fs.c index 7c3408b799..14a8f650c8 100644 --- a/LibOS/shim/src/fs/socket/fs.c +++ b/LibOS/shim/src/fs/socket/fs.c @@ -47,17 +47,16 @@ static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) { unlock(&hdl->lock); - PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0); - - if (bytes == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); + int ret = DkStreamRead(hdl->pal_handle, 0, &count, buf, NULL, 0); + if (ret < 0) { + ret = pal_to_unix_errno(ret); lock(&hdl->lock); - sock->error = err; + sock->error = -ret; unlock(&hdl->lock); - return -err; + return ret; } - return (ssize_t)bytes; + return (ssize_t)count; } static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t count) { @@ -81,11 +80,11 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou unlock(&hdl->lock); - PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL); + int ret = DkStreamWrite(hdl->pal_handle, 0, &count, (void*)buf, NULL); - if (bytes == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EPIPE) { + if (ret < 0) { + ret = pal_to_unix_errno(ret); + if (ret == -EPIPE) { siginfo_t info = { .si_signo = SIGPIPE, .si_pid = g_process.pid, @@ -97,12 +96,12 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou } lock(&hdl->lock); - sock->error = err; + sock->error = -ret; unlock(&hdl->lock); - return -err; + return ret; } - return (ssize_t)bytes; + return (ssize_t)count; } static int socket_hstat(struct shim_handle* hdl, struct stat* stat) { @@ -111,8 +110,10 @@ static int socket_hstat(struct shim_handle* hdl, struct stat* stat) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } memset(stat, 0, sizeof(struct stat)); @@ -170,8 +171,9 @@ static off_t socket_poll(struct shim_handle* hdl, int poll_type) { } PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) { - ret = -PAL_ERRNO(); + int query_ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (query_ret < 0) { + ret = pal_to_unix_errno(query_ret); goto out; } @@ -204,8 +206,10 @@ static int socket_setflags(struct shim_handle* hdl, int flags) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } if (attr.nonblocking) { if (flags & O_NONBLOCK) @@ -219,8 +223,10 @@ static int socket_setflags(struct shim_handle* hdl, int flags) { attr.nonblocking = PAL_TRUE; } - if (!DkStreamAttributesSetByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + ret = DkStreamAttributesSetByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } return 0; } diff --git a/LibOS/shim/src/ipc/shim_ipc.c b/LibOS/shim/src/ipc/shim_ipc.c index ce0021ee8d..7751a3cb0b 100644 --- a/LibOS/shim/src/ipc/shim_ipc.c +++ b/LibOS/shim/src/ipc/shim_ipc.c @@ -258,19 +258,26 @@ int send_ipc_message(struct shim_ipc_msg* msg, struct shim_ipc_port* port) { size_t bytes = 0; do { - PAL_NUM ret = - DkStreamWrite(port->pal_handle, 0, total_bytes - bytes, (void*)msg + bytes, NULL); + size_t size = total_bytes - bytes; + int ret = DkStreamWrite(port->pal_handle, 0, &size, (void*)msg + bytes, NULL); - if (ret == PAL_STREAM_ERROR) { - if (PAL_ERRNO() == EINTR || PAL_ERRNO() == EAGAIN || PAL_ERRNO() == EWOULDBLOCK) + if (ret < 0 || size == 0) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; + } + if (ret == 0) { + assert(size == 0); + ret = -EINVAL; + } else { + ret = pal_to_unix_errno(ret); + } log_debug("Port %p (handle %p) was removed during sending\n", port, port->pal_handle); del_ipc_port_fini(port); - return -PAL_ERRNO(); + return ret; } - bytes += ret; + bytes += size; } while (bytes < total_bytes); return 0; diff --git a/LibOS/shim/src/ipc/shim_ipc_helper.c b/LibOS/shim/src/ipc/shim_ipc_helper.c index c73affcc40..108be1834d 100644 --- a/LibOS/shim/src/ipc/shim_ipc_helper.c +++ b/LibOS/shim/src/ipc/shim_ipc_helper.c @@ -139,11 +139,11 @@ static int init_ns_ipc_port(void) { if (!g_process_ipc_info.ns->pal_handle) { log_debug("Reconnecting IPC port %s\n", qstrgetstr(&g_process_ipc_info.ns->uri)); - g_process_ipc_info.ns->pal_handle = DkStreamOpen(qstrgetstr(&g_process_ipc_info.ns->uri), - 0, 0, 0, 0); - if (!g_process_ipc_info.ns->pal_handle) { + int ret = DkStreamOpen(qstrgetstr(&g_process_ipc_info.ns->uri), 0, 0, 0, 0, + &g_process_ipc_info.ns->pal_handle); + if (ret < 0) { unlock(&g_process_ipc_info.lock); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } } @@ -287,7 +287,7 @@ static void __del_ipc_port(struct shim_ipc_port* port) { log_debug("Deleting port %p (handle %p) of process %u\n", port, port->pal_handle, port->vmid); - DkStreamDelete(port->pal_handle, 0); + DkStreamDelete(port->pal_handle, 0); // TODO: handle errors LISTP_DEL_INIT(port, &port_list, list); /* Check for pending messages on port (threads might be blocking for responses) */ @@ -563,19 +563,24 @@ static int receive_ipc_message(struct shim_ipc_port* port) { msg = tmp_buf; } - PAL_NUM read = - DkStreamRead(port->pal_handle, /*offset=*/0, expected_size - bytes + readahead, - (void*)msg + bytes, NULL, 0); + size_t read = expected_size - bytes + readahead; + ret = DkStreamRead(port->pal_handle, /*offset=*/0, &read, (void*)msg + bytes, NULL, 0); - if (!read || read == PAL_STREAM_ERROR) { - int err = !read ? ENODATA : PAL_ERRNO(); - if (err == EINTR || err == EAGAIN || err == EWOULDBLOCK) + if (ret < 0 || !read) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; - - log_warning("Port %p (handle %p) closed while receiving IPC message\n", port, - port->pal_handle); + } + if (ret == 0) { + assert(read == 0); + ret = -ENODATA; + log_debug("Port %p (handle %p): closed while receiving IPC message\n", port, + port->pal_handle); + } else { + ret = pal_to_unix_errno(ret); + log_debug("Port %p (handle %p): error while receiving IPC message: %d\n", port, + port->pal_handle, ret); + } del_ipc_port_fini(port); - ret = -err; goto out; } @@ -602,7 +607,6 @@ static int receive_ipc_message(struct shim_ipc_port* port) { if (ret < 0) { log_error("Sending IPC_MSG_RESP msg on port %p (handle %p) to %u failed\n", port, port->pal_handle, msg->src); - ret = -PAL_ERRNO(); goto out; } } @@ -750,8 +754,12 @@ noreturn static void shim_ipc_helper(void* dummy) { unlock(&ipc_helper_lock); /* wait on collected ports' PAL handles + install_new_event_pal */ - PAL_BOL polled = DkStreamsWaitEvents(ports_cnt + 1, pals, pal_events, ret_events, - NO_TIMEOUT); + int ret = DkStreamsWaitEvents(ports_cnt + 1, pals, pal_events, ret_events, NO_TIMEOUT); + if (ret && ret != -PAL_ERROR_INTERRUPTED && ret != -PAL_ERROR_TRYAGAIN) { + debug("shim_ipc_helper: DkStreamsWaitEvents failed: %ld\n", pal_to_unix_errno(ret)); + goto out_err; + } + bool polled = ret == 0; for (size_t i = 0; polled && i < ports_cnt + 1; i++) { if (ret_events[i]) { @@ -768,19 +776,25 @@ noreturn static void shim_ipc_helper(void* dummy) { if (polled_port->type & IPC_PORT_LISTENING) { /* listening port: accept client, create port, and add it to port list */ - PAL_HANDLE client = DkStreamWaitForClient(polled_port->pal_handle); - if (client) { + PAL_HANDLE client = NULL; + ret = DkStreamWaitForClient(polled_port->pal_handle, &client); + if (ret < 0) { + log_warning("Port %p (handle %p) was removed during accepting client\n", + polled_port, polled_port->pal_handle); + del_ipc_port_fini(polled_port); + } else { IDTYPE client_type = (polled_port->type & ~IPC_PORT_LISTENING) | IPC_PORT_CONNECTION; add_ipc_port_by_id(polled_port->vmid, client, client_type, NULL, NULL); - } else { - log_debug("Port %p (handle %p) was removed during accepting client\n", - polled_port, polled_port->pal_handle); - del_ipc_port_fini(polled_port); } } else { PAL_STREAM_ATTR attr; - if (DkStreamAttributesQueryByHandle(polled_port->pal_handle, &attr)) { + ret = DkStreamAttributesQueryByHandle(polled_port->pal_handle, &attr); + if (ret < 0) { + log_warning("Port %p (handle %p) was removed during attr querying\n", + polled_port, polled_port->pal_handle); + del_ipc_port_fini(polled_port); + } else { /* can read on this port, so receive messages */ if (attr.readable) { /* NOTE: IPC helper thread does not handle failures currently */ @@ -791,10 +805,6 @@ noreturn static void shim_ipc_helper(void* dummy) { polled_port->pal_handle); del_ipc_port_fini(polled_port); } - } else { - log_debug("Port %p (handle %p) was removed during attr querying\n", - polled_port, polled_port->pal_handle); - del_ipc_port_fini(polled_port); } } } @@ -869,14 +879,14 @@ static int create_ipc_helper(void) { ipc_helper_thread = new; ipc_helper_state = HELPER_ALIVE; - PAL_HANDLE handle = DkThreadCreate(shim_ipc_helper_prepare, new); + PAL_HANDLE handle = NULL; + int ret = DkThreadCreate(shim_ipc_helper_prepare, new, &handle); - if (!handle) { - int ret = -PAL_ERRNO(); /* put_thread() may overwrite errno */ + if (ret < 0) { ipc_helper_thread = NULL; ipc_helper_state = HELPER_NOTALIVE; put_thread(new); - return ret; + return pal_to_unix_errno(ret); } new->pal_handle = handle; diff --git a/LibOS/shim/src/ipc/shim_ipc_ranges.c b/LibOS/shim/src/ipc/shim_ipc_ranges.c index 4b1f8deb9e..88e082fbbd 100644 --- a/LibOS/shim/src/ipc/shim_ipc_ranges.c +++ b/LibOS/shim/src/ipc/shim_ipc_ranges.c @@ -731,11 +731,12 @@ int connect_ns(IDTYPE* vmid, struct shim_ipc_port** portptr) { return -ESRCH; } - PAL_HANDLE pal_handle = DkStreamOpen(qstrgetstr(&g_process_ipc_info.ns->uri), 0, 0, 0, 0); + PAL_HANDLE pal_handle = NULL; + int ret = DkStreamOpen(qstrgetstr(&g_process_ipc_info.ns->uri), 0, 0, 0, 0, &pal_handle); - if (!pal_handle) { + if (ret < 0) { unlock(&g_process_ipc_info.lock); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } add_ipc_port_by_id(g_process_ipc_info.ns->vmid, pal_handle, IPC_PORT_CONNECTION, @@ -806,10 +807,11 @@ int connect_owner(IDTYPE idx, struct shim_ipc_port** portptr, IDTYPE* owner) { goto success; if (!range.port) { - PAL_HANDLE pal_handle = DkStreamOpen(qstrgetstr(&range.uri), 0, 0, 0, 0); + PAL_HANDLE pal_handle = NULL; + ret = DkStreamOpen(qstrgetstr(&range.uri), 0, 0, 0, 0, &pal_handle); - if (!pal_handle) { - ret = -PAL_ERRNO() ?: -EACCES; + if (ret < 0) { + ret = pal_to_unix_errno(ret) ?: -EACCES; goto out; } @@ -1470,7 +1472,12 @@ int get_all_pid_status(struct pid_status** status) { unlock(&range_map_lock); - PAL_HANDLE pal_handle = DkStreamOpen(uri, 0, 0, 0, 0); + PAL_HANDLE pal_handle = NULL; + int ret = DkStreamOpen(uri, 0, 0, 0, 0, &pal_handle); + if (ret < 0) { + // I have no idea how to handle errors here, this function needs a rework. + BUG(); + } if (pal_handle) add_ipc_port_by_id(owner, pal_handle, IPC_PORT_CONNECTION, NULL, &port); diff --git a/LibOS/shim/src/shim_arch_prctl-x86_64.c b/LibOS/shim/src/shim_arch_prctl-x86_64.c index 0150a89715..97a72007e9 100644 --- a/LibOS/shim/src/shim_arch_prctl-x86_64.c +++ b/LibOS/shim/src/shim_arch_prctl-x86_64.c @@ -19,7 +19,7 @@ long shim_do_arch_prctl(int code, void* addr) { return 0; case ARCH_GET_FS: - return DkSegmentRegisterGet(PAL_SEGMENT_FS, addr) ? 0 : -PAL_ERRNO(); + return pal_to_unix_errno(DkSegmentRegisterGet(PAL_SEGMENT_FS, addr)); default: log_warning("Not supported flag (0x%x) passed to arch_prctl\n", code); diff --git a/LibOS/shim/src/shim_async.c b/LibOS/shim/src/shim_async.c index 0a6f923a25..5202029fb8 100644 --- a/LibOS/shim/src/shim_async.c +++ b/LibOS/shim/src/shim_async.c @@ -58,9 +58,10 @@ int64_t install_async_event(PAL_HANDLE object, uint64_t time, /* if event happens on object, time must be zero */ assert(!object || (object && !time)); - uint64_t now = DkSystemTimeQuery(); - if ((int64_t)now < 0) { - return (int64_t)now; + uint64_t now = 0; + int ret = DkSystemTimeQuery(&now); + if (ret < 0) { + return pal_to_unix_errno(ret); } uint64_t max_prev_expire_time = now; @@ -191,9 +192,11 @@ static void shim_async_helper(void* arg) { ret_events[0] = 0; while (true) { - uint64_t now = DkSystemTimeQuery(); - if ((int64_t)now < 0) { - log_error("DkSystemTimeQuery failed with: %ld\n", (int64_t)now); + uint64_t now = 0; + int ret = DkSystemTimeQuery(&now); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + log_error("DkSystemTimeQuery failed with: %d\n", ret); goto out_err; } @@ -282,12 +285,18 @@ static void shim_async_helper(void* arg) { unlock(&async_helper_lock); /* wait on async IO events + install_new_event + next expiring alarm/timer */ - PAL_BOL polled = DkStreamsWaitEvents(pals_cnt + 1, pals, pal_events, ret_events, - sleep_time); + ret = DkStreamsWaitEvents(pals_cnt + 1, pals, pal_events, ret_events, sleep_time); + if (ret < 0 && ret != -PAL_ERROR_INTERRUPTED && ret != -PAL_ERROR_TRYAGAIN) { + ret = pal_to_unix_errno(ret); + debug("Async helper: DkStreamsWaitEvents failed: %d\n", ret); + goto out_err; + } + PAL_BOL polled = ret == 0; - now = DkSystemTimeQuery(); - if ((int64_t)now < 0) { - log_error("DkSystemTimeQuery failed with: %ld\n", (int64_t)now); + ret = DkSystemTimeQuery(&now); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + log_error("DkSystemTimeQuery failed with: %d\n", ret); goto out_err; } @@ -376,13 +385,14 @@ static int create_async_helper(void) { async_helper_thread = new; async_helper_state = HELPER_ALIVE; - PAL_HANDLE handle = DkThreadCreate(shim_async_helper, new); + PAL_HANDLE handle = NULL; + int ret = DkThreadCreate(shim_async_helper, new, &handle); - if (!handle) { + if (ret < 0) { async_helper_thread = NULL; async_helper_state = HELPER_NOTALIVE; put_thread(new); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } new->pal_handle = handle; diff --git a/LibOS/shim/src/shim_checkpoint.c b/LibOS/shim/src/shim_checkpoint.c index 65a5e88a07..3286032168 100644 --- a/LibOS/shim/src/shim_checkpoint.c +++ b/LibOS/shim/src/shim_checkpoint.c @@ -217,13 +217,13 @@ static int read_exact(PAL_HANDLE handle, void* buf, size_t size) { size_t bytes = 0; while (bytes < size) { - PAL_NUM x = DkStreamRead(handle, 0, size - bytes, (char*)buf + bytes, NULL, 0); - if (x == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EINTR || err == EAGAIN || err == EWOULDBLOCK) { + PAL_NUM x = size - bytes; + int ret = DkStreamRead(handle, 0, &x, (char*)buf + bytes, NULL, 0); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; } - return -err; + return pal_to_unix_errno(ret); } else if (x == 0) { return -ENODATA; } @@ -238,13 +238,15 @@ static int write_exact(PAL_HANDLE handle, void* buf, size_t size) { size_t bytes = 0; while (bytes < size) { - PAL_NUM x = DkStreamWrite(handle, 0, size - bytes, (char*)buf + bytes, NULL); - if (x == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EINTR || err == EAGAIN || err == EWOULDBLOCK) { + size_t x = size - bytes; + int ret = DkStreamWrite(handle, 0, &x, (char*)buf + bytes, NULL); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; } - return -err; + return pal_to_unix_errno(ret); + } else if (x == 0) { + return -EINVAL; } bytes += x; @@ -264,8 +266,9 @@ static int send_memory_on_stream(PAL_HANDLE stream, struct shim_cp_store* store) if (!(mem_prot & PAL_PROT_READ) && mem_size > 0) { /* make the area readable */ - if (!DkVirtualMemoryProtect(mem_addr, mem_size, mem_prot | PAL_PROT_READ)) { - return -PAL_ERRNO(); + ret = DkVirtualMemoryProtect(mem_addr, mem_size, mem_prot | PAL_PROT_READ); + if (ret < 0) { + return pal_to_unix_errno(ret); } } @@ -273,9 +276,9 @@ static int send_memory_on_stream(PAL_HANDLE stream, struct shim_cp_store* store) if (!(mem_prot & PAL_PROT_READ) && mem_size > 0) { /* the area was made readable above; revert to original permissions */ - if (!DkVirtualMemoryProtect(mem_addr, mem_size, mem_prot)) { - if (!ret) - ret = -PAL_ERRNO(); + int ret2 = DkVirtualMemoryProtect(mem_addr, mem_size, mem_prot); + if (ret2 < 0 && !ret) { + ret = pal_to_unix_errno(ret2); } } @@ -322,8 +325,9 @@ static int send_handles_on_stream(PAL_HANDLE stream, struct shim_cp_store* store /* now we can traverse PAL-handle entries in correct order and send them one by one */ for (size_t i = 0; i < entries_cnt; i++) { /* we need to abort migration if DkSendHandle() returned error, otherwise app may fail */ - if (!DkSendHandle(stream, entries[i]->handle)) { - ret = -EINVAL; + ret = DkSendHandle(stream, entries[i]->handle); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } } @@ -349,19 +353,23 @@ static int receive_memory_on_stream(PAL_HANDLE handle, struct checkpoint_hdr* hd PAL_NUM size = (char*)ALLOC_ALIGN_UP_PTR(entry->addr + entry->size) - (char*)addr; PAL_FLG prot = entry->prot; - if (!DkVirtualMemoryAlloc(addr, size, 0, prot | PAL_PROT_WRITE)) { + int ret = DkVirtualMemoryAlloc(&addr, size, 0, prot | PAL_PROT_WRITE); + if (ret < 0) { log_error("failed allocating %p-%p\n", addr, addr + size); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } - int ret = read_exact(handle, entry->addr, entry->size); + ret = read_exact(handle, entry->addr, entry->size); if (ret < 0) { return ret; } - if (!(prot & PAL_PROT_WRITE) && !DkVirtualMemoryProtect(addr, size, prot)) { - log_error("failed protecting %p-%p\n", addr, addr + size); - return -PAL_ERRNO(); + if (!(prot & PAL_PROT_WRITE)) { + ret = DkVirtualMemoryProtect(addr, size, prot); + if (ret < 0) { + log_error("failed protecting %p-%p\n", addr, addr + size); + return pal_to_unix_errno(ret); + } } } } @@ -429,10 +437,11 @@ static int receive_handles_on_stream(struct checkpoint_hdr* hdr, void* base, ssi if (!entry->handle) continue; - PAL_HANDLE hdl = DkReceiveHandle(PAL_CB(parent_process)); + PAL_HANDLE hdl = NULL; + ret = DkReceiveHandle(PAL_CB(parent_process), &hdl); /* need to abort migration if DkReceiveHandle() returned error, otherwise app may fail */ - if (!hdl) { - ret = -EINVAL; + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } *entry->phandle = hdl; @@ -478,13 +487,14 @@ static void* cp_alloc(void* addr, size_t size) { bkeep_remove_tmp_vma(tmp_vma); } - addr = (void*)DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ | PAL_PROT_WRITE); - if (!addr) { + int ret = DkVirtualMemoryAlloc(&addr, size, 0, PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { void* tmp_vma = NULL; if (bkeep_munmap(addr, size, /*is_internal=*/true, &tmp_vma) < 0) { BUG(); } bkeep_remove_tmp_vma(tmp_vma); + addr = NULL; } return addr; @@ -502,9 +512,10 @@ int create_process_and_send_checkpoint(migrate_func_t migrate_func, /* FIXME: Child process requires some time to initialize before starting to receive checkpoint * data. Parallelizing process creation and checkpointing could improve latency of forking. */ const char* exec_uri = pal_control.executable; - PAL_HANDLE pal_process = DkProcessCreate(exec_uri, /*args=*/NULL); - if (!pal_process) { - ret = -PAL_ERRNO(); + PAL_HANDLE pal_process = NULL; + ret = DkProcessCreate(exec_uri, /*args=*/NULL, &pal_process); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } @@ -590,7 +601,9 @@ int create_process_and_send_checkpoint(migrate_func_t migrate_func, log_error("failed unmaping checkpoint (ret = %d)\n", ret); goto out; } - DkVirtualMemoryFree((PAL_PTR)cpstore.base, cpstore.bound); + if (DkVirtualMemoryFree((PAL_PTR)cpstore.base, cpstore.bound) < 0) { + BUG(); + } bkeep_remove_tmp_vma(tmp_vma); /* wait for final ack from child process (contains VMID of child) */ @@ -632,7 +645,6 @@ int create_process_and_send_checkpoint(migrate_func_t migrate_func, int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) { int ret = 0; - PAL_PTR mapped = NULL; void* base = hdr->addr; PAL_PTR mapaddr = (PAL_PTR)ALLOC_ALIGN_DOWN_PTR(base); @@ -663,24 +675,26 @@ int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) { mapsize = (PAL_NUM)ALLOC_ALIGN_UP(hdr->size); } - log_debug("checkpoint mapped at %p-%p\n", base, base + hdr->size); - - mapped = DkVirtualMemoryAlloc(mapaddr, mapsize, 0, PAL_PROT_READ | PAL_PROT_WRITE); - if (!mapped) { - ret = -PAL_ERRNO(); - goto out; + ret = DkVirtualMemoryAlloc(&mapaddr, mapsize, 0, PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { + void* tmp_vma = NULL; + if (bkeep_munmap(mapaddr, mapsize, /*is_internal=*/true, &tmp_vma) < 0) + BUG(); + bkeep_remove_tmp_vma(tmp_vma); + return pal_to_unix_errno(ret); } - assert(mapaddr == mapped); + + log_debug("checkpoint mapped at %p-%p\n", base, base + hdr->size); ret = read_exact(PAL_CB(parent_process), base, hdr->size); if (ret < 0) { - goto out; + goto out_fail; } log_debug("read checkpoint of %lu bytes from parent\n", hdr->size); ret = receive_memory_on_stream(PAL_CB(parent_process), hdr, (uintptr_t)base); if (ret < 0) { - goto out; + goto out_fail; } log_debug("restored memory from checkpoint\n"); @@ -690,7 +704,7 @@ int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) { ret = receive_handles_on_stream(hdr, base, rebase); if (ret < 0) { - goto out; + goto out_fail; } migrated_memory_start = (void*)mapaddr; @@ -698,20 +712,19 @@ int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) { ret = restore_checkpoint(hdr, (uintptr_t)base); if (ret < 0) { - goto out; + goto out_fail; } - ret = 0; -out: - if (ret < 0) { - void* tmp_vma = NULL; - if (mapaddr) - if (bkeep_munmap(mapaddr, mapsize, /*is_internal=*/true, &tmp_vma) < 0) - BUG(); - if (mapped) - DkVirtualMemoryFree(mapped, mapsize); - if (mapaddr) - bkeep_remove_tmp_vma(tmp_vma); + return 0; + +out_fail:; + void* tmp_vma = NULL; + if (bkeep_munmap(mapaddr, mapsize, /*is_internal=*/true, &tmp_vma) < 0) { + BUG(); } + if (DkVirtualMemoryFree(mapaddr, mapsize) < 0) { + BUG(); + } + bkeep_remove_tmp_vma(tmp_vma); return ret; } diff --git a/LibOS/shim/src/shim_context-x86_64.c b/LibOS/shim/src/shim_context-x86_64.c index 551168a34e..6c4e2fd6d7 100644 --- a/LibOS/shim/src/shim_context-x86_64.c +++ b/LibOS/shim/src/shim_context-x86_64.c @@ -42,14 +42,14 @@ uint64_t shim_xstate_size(void) { void shim_xstate_init(void) { unsigned int value[4]; - if (!DkCpuIdRetrieve(CPUID_LEAF_PROCINFO, 0, value)) + if (DkCpuIdRetrieve(CPUID_LEAF_PROCINFO, 0, value) < 0) goto out; if (!(value[PAL_CPUID_WORD_ECX] & CPUID_FEATURE_XSAVE) || !(value[PAL_CPUID_WORD_ECX] & CPUID_FEATURE_OSXSAVE)) goto out; - if (!DkCpuIdRetrieve(CPUID_LEAF_XSAVE, 0, value)) + if (DkCpuIdRetrieve(CPUID_LEAF_XSAVE, 0, value) < 0) goto out; uint32_t xsavesize = value[PAL_CPUID_WORD_ECX]; diff --git a/LibOS/shim/src/shim_init.c b/LibOS/shim/src/shim_init.c index f24bfaade5..91ad438789 100644 --- a/LibOS/shim/src/shim_init.c +++ b/LibOS/shim/src/shim_init.c @@ -37,16 +37,6 @@ size_t g_pal_alloc_align; toml_table_t* g_manifest_root = NULL; -static void handle_failure(bool is_in_pal, PAL_NUM arg, PAL_CONTEXT* context) { - __UNUSED(is_in_pal); - __UNUSED(context); - if ((arg <= PAL_ERROR_NATIVE_COUNT) || - (arg >= PAL_ERROR_CRYPTO_START && arg <= PAL_ERROR_CRYPTO_END)) - shim_get_tcb()->pal_errno = arg; - else - shim_get_tcb()->pal_errno = PAL_ERROR_DENIED; -} - noreturn void __abort(void) { DEBUG_BREAK_ON_FAILURE(); /* `__abort` might be called by any thread, even internal. */ @@ -60,7 +50,7 @@ noreturn void __stack_chk_fail(void) { __abort(); } -static int pal_errno_to_unix_errno[PAL_ERROR_NATIVE_COUNT + 1] = { +static unsigned pal_errno_to_unix_errno_table[PAL_ERROR_NATIVE_COUNT + 1] = { [PAL_ERROR_SUCCESS] = 0, [PAL_ERROR_NOTIMPLEMENTED] = ENOSYS, [PAL_ERROR_NOTDEFINED] = ENOSYS, @@ -78,7 +68,6 @@ static int pal_errno_to_unix_errno[PAL_ERROR_NATIVE_COUNT + 1] = { [PAL_ERROR_OVERFLOW] = EFAULT, [PAL_ERROR_BADADDR] = EFAULT, [PAL_ERROR_NOMEM] = ENOMEM, - [PAL_ERROR_NOTKILLABLE] = EACCES, [PAL_ERROR_INCONSIST] = EFAULT, [PAL_ERROR_TRYAGAIN] = EAGAIN, [PAL_ERROR_NOTSERVER] = EINVAL, @@ -89,8 +78,15 @@ static int pal_errno_to_unix_errno[PAL_ERROR_NATIVE_COUNT + 1] = { [PAL_ERROR_CONNFAILED_PIPE] = EPIPE, }; -long convert_pal_errno(long err) { - return (err >= 0 && err <= PAL_ERROR_NATIVE_COUNT) ? pal_errno_to_unix_errno[err] : EACCES; +static unsigned long pal_to_unix_errno_positive(unsigned long err) { + return (err <= PAL_ERROR_NATIVE_COUNT) ? pal_errno_to_unix_errno_table[err] : EINVAL; +} + +long pal_to_unix_errno(long err) { + if (err >= 0) { + return pal_to_unix_errno_positive((unsigned long)err); + } + return -pal_to_unix_errno_positive((unsigned long)-err); } void* migrated_memory_start; @@ -113,41 +109,59 @@ void* allocate_stack(size_t size, size_t protect_size, bool user) { size = ALLOC_ALIGN_UP(size); protect_size = ALLOC_ALIGN_UP(protect_size); - int flags = MAP_PRIVATE | MAP_ANONYMOUS | (user ? 0 : VMA_INTERNAL) | MAP_GROWSDOWN; - - if (user) { - /* reserve non-readable non-writable page below the user stack to catch stack overflows */ - int ret = bkeep_mmap_any_aslr(size + protect_size, PROT_NONE, flags, NULL, 0, "stack", - &stack); - if (ret < 0) { - return NULL; - } + log_debug("Allocating stack at %p (size = %ld)\n", stack, size); - if (!DkVirtualMemoryAlloc(stack, size + protect_size, 0, PAL_PROT_NONE)) { - void* tmp_vma = NULL; - if (bkeep_munmap(stack, size + protect_size, !user, &tmp_vma) < 0) { - BUG(); - } - bkeep_remove_tmp_vma(tmp_vma); - return NULL; - } - } else { + if (!user) { stack = system_malloc(size + protect_size); if (!stack) { return NULL; } + stack += protect_size; + stack = ALIGN_UP_PTR(stack, 16); + return stack; + } + + /* reserve non-readable non-writable page below the user stack to catch stack overflows */ + int ret = bkeep_mmap_any_aslr(size + protect_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, NULL, 0, "stack", + &stack); + if (ret < 0) { + return NULL; + } + + bool need_mem_free = false; + ret = DkVirtualMemoryAlloc(&stack, size + protect_size, 0, PAL_PROT_NONE); + if (ret < 0) { + goto out_fail; } + need_mem_free = true; - stack += protect_size; /* ensure proper alignment for process' initial stack */ - stack = ALIGN_UP_PTR(stack, 16); - DkVirtualMemoryProtect(stack, size, PAL_PROT_READ | PAL_PROT_WRITE); + assert(IS_ALIGNED_PTR(stack, 16)); - if (bkeep_mprotect(stack, size, PROT_READ | PROT_WRITE, !!(flags & VMA_INTERNAL)) < 0) - return NULL; + if (bkeep_mprotect(stack + protect_size, size, PROT_READ | PROT_WRITE, + /*is_internal=*/false) < 0) { + goto out_fail; + } - log_debug("Allocated stack at %p (size = %ld)\n", stack, size); - return stack; + if (DkVirtualMemoryProtect(stack + protect_size, size, PAL_PROT_READ | PAL_PROT_WRITE) < 0) { + goto out_fail; + } + + return stack + protect_size; + +out_fail:; + void* tmp_vma = NULL; + if (bkeep_munmap(stack, size + protect_size, /*is_internal=*/false, &tmp_vma) < 0) { + BUG(); + } + if (need_mem_free) { + if (DkVirtualMemoryFree(stack, size + protect_size) < 0) { + BUG(); + } + } + bkeep_remove_tmp_vma(tmp_vma); + return NULL; } /* populate already-allocated stack with copied argv and envp and space for auxv; @@ -374,8 +388,6 @@ noreturn void* shim_init(int argc, void* args) { log_debug("Host: %s\n", PAL_CB(host_type)); - DkSetExceptionHandler(&handle_failure, PAL_EVENT_FAILURE); - g_pal_alloc_align = PAL_CB(alloc_align); if (!IS_POWER_OF_2(g_pal_alloc_align)) { log_error("Error during shim_init(): PAL allocation alignment not a power of 2\n"); @@ -408,18 +420,14 @@ noreturn void* shim_init(int argc, void* args) { if (PAL_CB(parent_process)) { struct checkpoint_hdr hdr; + size_t hdr_size = sizeof(hdr); - PAL_NUM ret = DkStreamRead(PAL_CB(parent_process), 0, sizeof(hdr), &hdr, NULL, 0); - int err = 0; - if (ret == PAL_STREAM_ERROR) { - /* PAL_ERRNO() == 0 should not be possible now, but old code allowed for such case. - * This will be removed soon anyway. */ - err = PAL_ERRNO() ?: ENOTRECOVERABLE; - } else if (ret != sizeof(hdr)) { - err = ENODATA; - } - if (err) { - DkProcessExit(err); + int ret = DkStreamRead(PAL_CB(parent_process), 0, &hdr_size, &hdr, NULL, 0); + if (ret < 0) { + DkProcessExit(pal_to_unix_errno(-ret)); + } else if (hdr_size != sizeof(hdr)) { + log_debug("shim_init: failed to read the whole checkpoint header\n"); + DkProcessExit(ENODATA); } assert(hdr.size); @@ -445,10 +453,15 @@ noreturn void* shim_init(int argc, void* args) { if (PAL_CB(parent_process)) { /* Notify the parent process */ IDTYPE child_vmid = g_process_ipc_info.vmid; - PAL_NUM ret = DkStreamWrite(PAL_CB(parent_process), 0, sizeof(child_vmid), &child_vmid, - NULL); - if (ret == PAL_STREAM_ERROR || ret != sizeof(child_vmid)) - DkProcessExit(PAL_ERRNO()); + size_t child_vmid_size = sizeof(child_vmid); + + int ret = DkStreamWrite(PAL_CB(parent_process), 0, &child_vmid_size, &child_vmid, NULL); + if (ret < 0) { + DkProcessExit(pal_to_unix_errno(-ret)); + } else if (child_vmid_size != sizeof(child_vmid)) { + log_debug("shim_init: failed to write child_vmid\n"); + DkProcessExit(EPIPE); + } } log_debug("Shim process initialized\n"); @@ -482,7 +495,7 @@ static int get_256b_random_hex_string(char* buf, size_t size) { int ret = DkRandomBitsRead(&random, sizeof(random)); if (ret < 0) - return -convert_pal_errno(-ret); + return pal_to_unix_errno(ret); BYTES2HEXSTR(random, buf, size); return 0; @@ -515,13 +528,13 @@ int create_pipe(char* name, char* uri, size_t size, PAL_HANDLE* hdl, struct shim if (len >= size) return -ERANGE; - pipe = DkStreamOpen(uri, 0, 0, 0, 0); - if (!pipe) { - if (!use_vmid_for_name && PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMEXIST) { + ret = DkStreamOpen(uri, 0, 0, 0, 0, &pipe); + if (ret < 0) { + if (!use_vmid_for_name && ret == -PAL_ERROR_STREAMEXIST) { /* tried to create a pipe with random name but it already exists */ continue; } - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } break; /* succeeded in creating the pipe with random/vmid name */ diff --git a/LibOS/shim/src/shim_malloc.c b/LibOS/shim/src/shim_malloc.c index dab5002505..ef490a621e 100644 --- a/LibOS/shim/src/shim_malloc.c +++ b/LibOS/shim/src/shim_malloc.c @@ -35,8 +35,7 @@ static SLAB_MGR slab_mgr = NULL; /* Returns NULL on failure */ void* __system_malloc(size_t size) { size_t alloc_size = ALLOC_ALIGN_UP(size); - void* addr; - void* ret_addr; + void* addr = NULL; int ret = bkeep_mmap_any(alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL, NULL, 0, "slab", &addr); @@ -44,24 +43,17 @@ void* __system_malloc(size_t size) { return NULL; } - do { - ret_addr = DkVirtualMemoryAlloc(addr, alloc_size, 0, PAL_PROT_WRITE | PAL_PROT_READ); - - if (!ret_addr) { - if (PAL_NATIVE_ERRNO() == PAL_ERROR_INTERRUPTED) { - continue; - } - - log_error("failed to allocate memory (%ld)\n", -PAL_ERRNO()); - void* tmp_vma = NULL; - if (bkeep_munmap(addr, alloc_size, /*is_internal=*/true, &tmp_vma) < 0) { - BUG(); - } - bkeep_remove_tmp_vma(tmp_vma); - return NULL; + ret = DkVirtualMemoryAlloc(&addr, alloc_size, 0, PAL_PROT_WRITE | PAL_PROT_READ); + if (ret < 0) { + log_error("failed to allocate memory (%ld)\n", pal_to_unix_errno(ret)); + void* tmp_vma = NULL; + if (bkeep_munmap(addr, alloc_size, /*is_internal=*/true, &tmp_vma) < 0) { + BUG(); } - } while (!ret_addr); - assert(addr == ret_addr); + bkeep_remove_tmp_vma(tmp_vma); + return NULL; + } + return addr; } @@ -70,7 +62,9 @@ void __system_free(void* addr, size_t size) { if (bkeep_munmap(addr, ALLOC_ALIGN_UP(size), /*is_internal=*/true, &tmp_vma) < 0) { BUG(); } - DkVirtualMemoryFree(addr, ALLOC_ALIGN_UP(size)); + if (DkVirtualMemoryFree(addr, ALLOC_ALIGN_UP(size)) < 0) { + BUG(); + } bkeep_remove_tmp_vma(tmp_vma); } diff --git a/LibOS/shim/src/shim_object.c b/LibOS/shim/src/shim_object.c index e32569c4d3..3921339203 100644 --- a/LibOS/shim/src/shim_object.c +++ b/LibOS/shim/src/shim_object.c @@ -2,15 +2,14 @@ #include "shim_internal.h" int object_wait_with_retry(PAL_HANDLE handle) { - PAL_BOL ret; + int ret; do { ret = DkSynchronizationObjectWait(handle, NO_TIMEOUT); - } while (!ret && (PAL_NATIVE_ERRNO() == PAL_ERROR_INTERRUPTED || - PAL_NATIVE_ERRNO() == PAL_ERROR_TRYAGAIN)); + } while (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN); - if (!ret) { - log_error("waiting an object resulted in error %s", pal_strerror(PAL_NATIVE_ERRNO())); - return -PAL_NATIVE_ERRNO(); + if (ret < 0) { + log_error("waiting an object resulted in error %s", pal_strerror(ret)); + return pal_to_unix_errno(ret); } return 0; } diff --git a/LibOS/shim/src/sys/shim_alarm.c b/LibOS/shim/src/sys/shim_alarm.c index a66392d165..219cdfe268 100644 --- a/LibOS/shim/src/sys/shim_alarm.c +++ b/LibOS/shim/src/sys/shim_alarm.c @@ -78,7 +78,11 @@ long shim_do_setitimer(int which, struct __kernel_itimerval* value, if (ovalue && test_user_memory(ovalue, sizeof(*ovalue), true)) return -EFAULT; - uint64_t setup_time = DkSystemTimeQuery(); + uint64_t setup_time = 0; + int ret = DkSystemTimeQuery(&setup_time); + if (ret < 0) { + return pal_to_unix_errno(ret); + } uint64_t next_value = value->it_value.tv_sec * (uint64_t)1000000 + value->it_value.tv_usec; uint64_t next_reset = value->it_interval.tv_sec * (uint64_t)1000000 @@ -91,12 +95,12 @@ long shim_do_setitimer(int which, struct __kernel_itimerval* value, : 0; uint64_t current_reset = real_itimer.reset; - int64_t ret = install_async_event(NULL, next_value, &signal_itimer, - (void*)(setup_time + next_value)); + int64_t install_ret = install_async_event(NULL, next_value, &signal_itimer, + (void*)(setup_time + next_value)); - if (ret < 0) { + if (install_ret < 0) { MASTER_UNLOCK(); - return ret; + return install_ret; } real_itimer.timeout = setup_time + next_value; @@ -123,7 +127,11 @@ long shim_do_getitimer(int which, struct __kernel_itimerval* value) { if (test_user_memory(value, sizeof(*value), true)) return -EFAULT; - uint64_t setup_time = DkSystemTimeQuery(); + uint64_t setup_time = 0; + int ret = DkSystemTimeQuery(&setup_time); + if (ret < 0) { + return pal_to_unix_errno(ret); + } MASTER_LOCK(); uint64_t current_timeout = real_itimer.timeout > setup_time diff --git a/LibOS/shim/src/sys/shim_brk.c b/LibOS/shim/src/sys/shim_brk.c index 51a1ae8852..76dcd35475 100644 --- a/LibOS/shim/src/sys/shim_brk.c +++ b/LibOS/shim/src/sys/shim_brk.c @@ -70,7 +70,7 @@ int init_brk_region(void* brk_start, size_t data_segment_size) { if (!PAL_CB(disable_aslr)) { ret = DkRandomBitsRead(&offset, sizeof(offset)); if (ret < 0) { - return -convert_pal_errno(-ret); + return pal_to_unix_errno(ret); } /* Linux randomizes brk at offset from 0 to 0x2000000 from main executable data section * https://elixir.bootlin.com/linux/v5.6.3/source/arch/x86/kernel/process.c#L914 */ @@ -125,7 +125,11 @@ void reset_brk(void) { BUG(); } - DkVirtualMemoryFree(brk_region.brk_start, allocated_size); + if (allocated_size > 0) { + if (DkVirtualMemoryFree(brk_region.brk_start, allocated_size) < 0) { + BUG(); + } + } bkeep_remove_tmp_vma(tmp_vma); brk_region.brk_start = NULL; @@ -157,7 +161,9 @@ void* shim_do_brk(void* _brk) { goto out; } - DkVirtualMemoryFree(brk_aligned, size); + if (DkVirtualMemoryFree(brk_aligned, size) < 0) { + BUG(); + } } brk_region.brk_current = brk; @@ -183,7 +189,8 @@ void* shim_do_brk(void* _brk) { goto out; } - if (!DkVirtualMemoryAlloc(brk_current, size, 0, PAL_PROT_READ | PAL_PROT_WRITE)) { + int ret = DkVirtualMemoryAlloc((void**)&brk_current, size, 0, PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { if (bkeep_mmap_fixed(brk_current, brk_region.brk_end - brk_current, PROT_NONE, MAP_FIXED | VMA_UNMAPPED, NULL, 0, "heap") < 0) { BUG(); diff --git a/LibOS/shim/src/sys/shim_clone.c b/LibOS/shim/src/sys/shim_clone.c index 46b5fef814..9f0a1e2527 100644 --- a/LibOS/shim/src/sys/shim_clone.c +++ b/LibOS/shim/src/sys/shim_clone.c @@ -97,7 +97,7 @@ static int clone_implementation_wrapper(struct shim_clone_args* arg) { tcb->context.tls = arg->tls; /* Inform the parent thread that we finished initialization. */ - DkEventSet(arg->initialize_event); + DkEventSet(arg->initialize_event); // TODO: handle errors put_thread(my_thread); @@ -375,15 +375,15 @@ long shim_do_clone(unsigned long flags, unsigned long user_stack_addr, int* pare struct shim_clone_args new_args; memset(&new_args, 0, sizeof(new_args)); - new_args.create_event = DkNotificationEventCreate(PAL_FALSE); - if (!new_args.create_event) { - ret = -PAL_ERRNO(); + ret = DkNotificationEventCreate(PAL_FALSE, &new_args.create_event); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto clone_thread_failed; } - new_args.initialize_event = DkNotificationEventCreate(PAL_FALSE); - if (!new_args.initialize_event) { - ret = -PAL_ERRNO(); + ret = DkNotificationEventCreate(PAL_FALSE, &new_args.initialize_event); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto clone_thread_failed; } @@ -403,9 +403,10 @@ long shim_do_clone(unsigned long flags, unsigned long user_stack_addr, int* pare // child to run on the Parent allocated stack , so once the DkThreadCreate // returns .The parent comes back here - however, the child is Happily // running the function we gave to DkThreadCreate. - PAL_HANDLE pal_handle = DkThreadCreate(clone_implementation_wrapper, &new_args); - if (!pal_handle) { - ret = -PAL_ERRNO(); + PAL_HANDLE pal_handle = NULL; + ret = DkThreadCreate(clone_implementation_wrapper, &new_args, &pal_handle); + if (ret < 0) { + ret = pal_to_unix_errno(ret); put_thread(new_args.thread); goto clone_thread_failed; } @@ -415,9 +416,9 @@ long shim_do_clone(unsigned long flags, unsigned long user_stack_addr, int* pare if (set_parent_tid) *set_parent_tid = thread->tid; - DkEventSet(new_args.create_event); + DkEventSet(new_args.create_event); // TODO: handle errors object_wait_with_retry(new_args.initialize_event); - DkObjectClose(new_args.initialize_event); + DkObjectClose(new_args.initialize_event); // TODO: handle errors IDTYPE tid = thread->tid; diff --git a/LibOS/shim/src/sys/shim_epoll.c b/LibOS/shim/src/sys/shim_epoll.c index 8ec8fe1fa1..761aab5096 100644 --- a/LibOS/shim/src/sys/shim_epoll.c +++ b/LibOS/shim/src/sys/shim_epoll.c @@ -336,9 +336,10 @@ long shim_do_epoll_wait(int epfd, struct __kernel_epoll_event* events, int maxev unlock(&epoll_hdl->lock); /* TODO: Timeout must be updated in case of retries; otherwise, we may wait for too long */ - PAL_BOL polled = DkStreamsWaitEvents(pal_cnt + 1, pal_handles, pal_events, ret_events, - timeout_ms * 1000); - long error = polled ? 0 : -PAL_ERRNO(); + long error = DkStreamsWaitEvents(pal_cnt + 1, pal_handles, pal_events, ret_events, + timeout_ms * 1000); + bool polled = error == 0; + error = pal_to_unix_errno(error); lock(&epoll_hdl->lock); __atomic_sub_fetch(&epoll->waiter_cnt, 1, __ATOMIC_RELAXED); diff --git a/LibOS/shim/src/sys/shim_eventfd.c b/LibOS/shim/src/sys/shim_eventfd.c index 998e05a06c..e8a08b6ce1 100644 --- a/LibOS/shim/src/sys/shim_eventfd.c +++ b/LibOS/shim/src/sys/shim_eventfd.c @@ -45,9 +45,10 @@ static int create_eventfd(PAL_HANDLE* efd, unsigned count, int flags) { /* eventfd() requires count (aka initval) but PAL's DkStreamOpen() doesn't have such an * argument. Using create arg as a work-around (note: initval is uint32 but create is int32). */ - if (!(hdl = DkStreamOpen(URI_PREFIX_EVENTFD, 0, 0, count, pal_flags))) { + ret = DkStreamOpen(URI_PREFIX_EVENTFD, 0, 0, count, pal_flags, &hdl); + if (ret < 0) { log_error("eventfd open failure\n"); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } *efd = hdl; diff --git a/LibOS/shim/src/sys/shim_exec.c b/LibOS/shim/src/sys/shim_exec.c index e7999143c1..df7b9cb560 100644 --- a/LibOS/shim/src/sys/shim_exec.c +++ b/LibOS/shim/src/sys/shim_exec.c @@ -71,7 +71,9 @@ noreturn static void __shim_do_execve_rtld(struct execve_rtld_arg* __arg) { if (bkeep_munmap(vma->addr, vma->length, !!(vma->flags & VMA_INTERNAL), &tmp_vma) < 0) { BUG(); } - DkVirtualMemoryFree(vma->addr, vma->length); + if (DkVirtualMemoryFree(vma->addr, vma->length) < 0) { + BUG(); + } bkeep_remove_tmp_vma(tmp_vma); } diff --git a/LibOS/shim/src/sys/shim_exit.c b/LibOS/shim/src/sys/shim_exit.c index 0cb3729b2a..4c5763dda7 100644 --- a/LibOS/shim/src/sys/shim_exit.c +++ b/LibOS/shim/src/sys/shim_exit.c @@ -101,7 +101,7 @@ static int mark_thread_to_die(struct shim_thread* thread, void* arg) { * set above (but only if we really set that flag). */ if (need_wakeup) { thread_wakeup(thread); - DkThreadResume(thread->pal_handle); + (void)DkThreadResume(thread->pal_handle); // There is nothing we can do on errors. } return 1; } diff --git a/LibOS/shim/src/sys/shim_fs.c b/LibOS/shim/src/sys/shim_fs.c index 16ddd6837e..4763a41a6f 100644 --- a/LibOS/shim/src/sys/shim_fs.c +++ b/LibOS/shim/src/sys/shim_fs.c @@ -409,6 +409,7 @@ static ssize_t handle_copy(struct shim_handle* hdli, off_t* offseti, struct shim if (do_mapi && do_mapo) { copysize = count - bytes > bufsize ? bufsize : count - bytes; memcpy(bufo + boffo, bufi + boffi, copysize); + /* XXX: ??? Where is vma bookkeeping? Hans, get ze flammenwerfer... */ DkVirtualMemoryFree(bufi, ALLOC_ALIGN_UP(bufsize + boffi)); bufi = NULL; if (fso->fs_ops->flush) { @@ -416,6 +417,7 @@ static ssize_t handle_copy(struct shim_handle* hdli, off_t* offseti, struct shim * explicit flush before freeing PF's mmapped region `bufo` */ fso->fs_ops->flush(hdlo); } + /* XXX: ??? Where is vma bookkeeping? Hans, get ze flammenwerfer... */ DkVirtualMemoryFree(bufo, ALLOC_ALIGN_UP(bufsize + boffo)); bufo = NULL; } else if (do_mapo) { @@ -425,12 +427,14 @@ static ssize_t handle_copy(struct shim_handle* hdli, off_t* offseti, struct shim * explicit flush before freeing PF's mmapped region `bufo` */ fso->fs_ops->flush(hdlo); } + /* XXX: ??? Where is vma bookkeeping? Hans, get ze flammenwerfer... */ DkVirtualMemoryFree(bufo, ALLOC_ALIGN_UP(bufsize + boffo)); bufo = NULL; if (copysize < 0) break; } else if (do_mapi) { copysize = fso->fs_ops->write(hdlo, bufi + boffi, bufsize); + /* XXX: ??? Where is vma bookkeeping? Hans, get ze flammenwerfer... */ DkVirtualMemoryFree(bufi, ALLOC_ALIGN_UP(bufsize + boffi)); bufi = NULL; if (copysize < 0) diff --git a/LibOS/shim/src/sys/shim_futex.c b/LibOS/shim/src/sys/shim_futex.c index 30f8573502..9588057f59 100644 --- a/LibOS/shim/src/sys/shim_futex.c +++ b/LibOS/shim/src/sys/shim_futex.c @@ -724,9 +724,10 @@ static int _shim_do_futex(uint32_t* uaddr, int op, uint32_t val, void* utime, ui if (cmd != FUTEX_WAIT) { /* For FUTEX_WAIT, timeout is interpreted as a relative value, which differs from other * futex operations, where timeout is interpreted as an absolute value. */ - uint64_t current_time = DkSystemTimeQuery(); - if (!current_time) { - return -EINVAL; + uint64_t current_time = 0; + int ret = DkSystemTimeQuery(¤t_time); + if (ret < 0) { + return pal_to_unix_errno(ret); } if (timeout < current_time) { /* We timeouted even before reaching this point. */ diff --git a/LibOS/shim/src/sys/shim_getrandom.c b/LibOS/shim/src/sys/shim_getrandom.c index 057259af64..9fd8623296 100644 --- a/LibOS/shim/src/sys/shim_getrandom.c +++ b/LibOS/shim/src/sys/shim_getrandom.c @@ -28,7 +28,7 @@ long shim_do_getrandom(char* buf, size_t count, unsigned int flags) { */ int ret = DkRandomBitsRead(buf, count); if (ret < 0) - return -EINVAL; + return pal_to_unix_errno(ret); return count; } diff --git a/LibOS/shim/src/sys/shim_ioctl.c b/LibOS/shim/src/sys/shim_ioctl.c index d49f6b2c7f..9789b0bbff 100644 --- a/LibOS/shim/src/sys/shim_ioctl.c +++ b/LibOS/shim/src/sys/shim_ioctl.c @@ -84,8 +84,9 @@ long shim_do_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { size = stat.st_size; } else if (hdl->pal_handle) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) { - ret = -PAL_ERRNO(); + ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + ret = pal_to_unix_errno(ret); break; } size = attr.pending_size; diff --git a/LibOS/shim/src/sys/shim_mmap.c b/LibOS/shim/src/sys/shim_mmap.c index 636d81b990..1241960fbb 100644 --- a/LibOS/shim/src/sys/shim_mmap.c +++ b/LibOS/shim/src/sys/shim_mmap.c @@ -165,11 +165,12 @@ void* shim_do_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t /* From now on `addr` contains the actual address we want to map (and already bookkeeped). */ if (!hdl) { - if (DkVirtualMemoryAlloc(addr, length, 0, LINUX_PROT_TO_PAL(prot, flags)) != addr) { - if (PAL_NATIVE_ERRNO() == PAL_ERROR_DENIED) { + ret = DkVirtualMemoryAlloc(&addr, length, 0, LINUX_PROT_TO_PAL(prot, flags)); + if (ret < 0) { + if (ret == -PAL_ERROR_DENIED) { ret = -EPERM; } else { - ret = -PAL_ERRNO(); + ret = pal_to_unix_errno(ret); } } } else { @@ -258,8 +259,10 @@ long shim_do_mprotect(void* addr, size_t length, int prot) { } } - if (!DkVirtualMemoryProtect(addr, length, LINUX_PROT_TO_PAL(prot, /*map_flags=*/0))) - return -PAL_ERRNO(); + ret = DkVirtualMemoryProtect(addr, length, LINUX_PROT_TO_PAL(prot, /*map_flags=*/0)); + if (ret < 0) { + return pal_to_unix_errno(ret); + } return 0; } @@ -284,7 +287,9 @@ long shim_do_munmap(void* addr, size_t length) { return ret; } - DkVirtualMemoryFree(addr, length); + if (DkVirtualMemoryFree(addr, length) < 0) { + BUG(); + } bkeep_remove_tmp_vma(tmp_vma); diff --git a/LibOS/shim/src/sys/shim_msgget.c b/LibOS/shim/src/sys/shim_msgget.c index e1cc25c16e..bcf1d8aaed 100644 --- a/LibOS/shim/src/sys/shim_msgget.c +++ b/LibOS/shim/src/sys/shim_msgget.c @@ -87,7 +87,11 @@ static int __add_msg_handle(unsigned long key, IDTYPE msqid, bool owned, msgq->owned = owned; msgq->deleted = false; msgq->currentsize = 0; - msgq->event = DkSynchronizationEventCreate(PAL_FALSE); + int ret = DkSynchronizationEventCreate(PAL_FALSE, &msgq->event); + if (ret < 0) { + // Needs some cleanup, but this function is broken anyway... + return pal_to_unix_errno(ret); + } msgq->queue = malloc(MSG_QOBJ_SIZE * DEFAULT_MSG_QUEUE_SIZE); msgq->queuesize = DEFAULT_MSG_QUEUE_SIZE; @@ -555,7 +559,7 @@ int add_sysv_msg(struct shim_msg_handle* msgq, long type, size_t size, const voi if ((ret = __store_msg_qobjs(msgq, mtype, size, data)) < 0) goto out_locked; - DkEventSet(msgq->event); + DkEventSet(msgq->event); // TODO: handle errors ret = 0; out_locked: unlock(&hdl->lock); @@ -685,22 +689,26 @@ static int __store_msg_persist(struct shim_msg_handle* msgq) { char fileuri[20]; snprintf(fileuri, 20, URI_PREFIX_FILE "msgq.%08x", msgq->msqid); - PAL_HANDLE file = DkStreamOpen(fileuri, PAL_ACCESS_RDWR, PERM_rw_______, PAL_CREATE_TRY, 0); - if (!file) { - ret = -PAL_ERRNO(); + PAL_HANDLE file = NULL; + ret = DkStreamOpen(fileuri, PAL_ACCESS_RDWR, PERM_rw_______, PAL_CREATE_TRY, 0, &file); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } int expected_size = sizeof(struct msg_handle_backup) + sizeof(struct msg_backup) * msgq->nmsgs + msgq->currentsize; - if (DkStreamSetLength(file, expected_size)) + ret = DkStreamSetLength(file, expected_size); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto err_file; + } - void* mem = (void*)DkStreamMap(file, NULL, PAL_PROT_READ | PAL_PROT_WRITE, 0, - ALLOC_ALIGN_UP(expected_size)); - if (!mem) { - ret = -EFAULT; + void* mem = NULL; + ret = DkStreamMap(file, &mem, PAL_PROT_READ | PAL_PROT_WRITE, 0, ALLOC_ALIGN_UP(expected_size)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto err_file; } @@ -725,7 +733,11 @@ static int __store_msg_persist(struct shim_msg_handle* msgq) { mtype->msgs = mtype->msg_tail = NULL; } - DkStreamUnmap(mem, ALLOC_ALIGN_UP(expected_size)); + ret = DkStreamUnmap(mem, ALLOC_ALIGN_UP(expected_size)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + goto err_file; + } if (msgq->owned) for (mtype = msgq->types; mtype < &msgq->types[msgq->ntypes]; mtype++) { @@ -748,13 +760,13 @@ static int __store_msg_persist(struct shim_msg_handle* msgq) { goto out; err_file: - DkStreamDelete(file, 0); + DkStreamDelete(file, 0); // TODO: handle errors DkObjectClose(file); out: // To wake up any receiver waiting on local message which must // now be requested from new owner. - DkEventSet(msgq->event); + DkEventSet(msgq->event); // TODO: handle errors return ret; } diff --git a/LibOS/shim/src/sys/shim_pipe.c b/LibOS/shim/src/sys/shim_pipe.c index 2ee40a67eb..19a69be966 100644 --- a/LibOS/shim/src/sys/shim_pipe.c +++ b/LibOS/shim/src/sys/shim_pipe.c @@ -35,15 +35,17 @@ static int create_pipes(struct shim_handle* srv, struct shim_handle* cli, int fl return ret; } - if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0, LINUX_OPEN_FLAGS_TO_PAL_OPTIONS(flags)))) { - ret = -PAL_ERRNO(); + ret = DkStreamOpen(uri, 0, 0, 0, LINUX_OPEN_FLAGS_TO_PAL_OPTIONS(flags), &hdl2); + if (ret < 0) { + ret = pal_to_unix_errno(ret); log_error("pipe connection failure\n"); goto out; } - if (!(hdl1 = DkStreamWaitForClient(hdl0))) { - ret = -PAL_ERRNO(); - log_error("pipe acceptation failure\n"); + ret = DkStreamWaitForClient(hdl0, &hdl1); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + log_error("pipe acceptance failure\n"); goto out; } @@ -70,7 +72,7 @@ static int create_pipes(struct shim_handle* srv, struct shim_handle* cli, int fl if (hdl2) DkObjectClose(hdl2); } - DkStreamDelete(hdl0, 0); + DkStreamDelete(hdl0, 0); // TODO: handle errors DkObjectClose(hdl0); return ret; } diff --git a/LibOS/shim/src/sys/shim_poll.c b/LibOS/shim/src/sys/shim_poll.c index 61130b1a7f..8ac86898e3 100644 --- a/LibOS/shim/src/sys/shim_poll.c +++ b/LibOS/shim/src/sys/shim_poll.c @@ -146,13 +146,12 @@ static long _shim_do_poll(struct pollfd* fds, nfds_t nfds, int timeout_ms) { unlock(&map->lock); - PAL_BOL polled = false; + bool polled = false; long error = 0; if (pal_cnt) { - polled = DkStreamsWaitEvents(pal_cnt, pals, pal_events, ret_events, timeout_us); - if (!polled) { - error = -PAL_ERRNO(); - } + error = DkStreamsWaitEvents(pal_cnt, pals, pal_events, ret_events, timeout_us); + polled = error == 0; + error = pal_to_unix_errno(error); } for (nfds_t i = 0; i < nfds; i++) { diff --git a/LibOS/shim/src/sys/shim_sched.c b/LibOS/shim/src/sys/shim_sched.c index 52d831993f..a2fe3b5c0d 100644 --- a/LibOS/shim/src/sys/shim_sched.c +++ b/LibOS/shim/src/sys/shim_sched.c @@ -164,9 +164,9 @@ long shim_do_sched_setaffinity(pid_t pid, unsigned int cpumask_size, unsigned lo } ret = DkThreadSetCpuAffinity(thread->pal_handle, cpumask_size, user_mask_ptr); - if (!ret) { + if (ret < 0) { put_thread(thread); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } put_thread(thread); @@ -212,9 +212,9 @@ long shim_do_sched_getaffinity(pid_t pid, unsigned int cpumask_size, unsigned lo memset(user_mask_ptr, 0, cpumask_size); ret = DkThreadGetCpuAffinity(thread->pal_handle, bitmask_size_in_bytes, user_mask_ptr); - if (!ret) { + if (ret < 0) { put_thread(thread); - return -PAL_ERRNO(); + return pal_to_unix_errno(ret); } put_thread(thread); diff --git a/LibOS/shim/src/sys/shim_semget.c b/LibOS/shim/src/sys/shim_semget.c index cbab120c23..3277310a3e 100644 --- a/LibOS/shim/src/sys/shim_semget.c +++ b/LibOS/shim/src/sys/shim_semget.c @@ -72,7 +72,11 @@ static int __add_sem_handle(unsigned long key, IDTYPE semid, int nsems, bool own tmp->semkey = key; tmp->semid = semid; tmp->owned = owned; - tmp->event = DkNotificationEventCreate(PAL_FALSE); + ret = DkNotificationEventCreate(PAL_FALSE, &tmp->event); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + goto failed; + } if (owned && nsems) { tmp->nsems = nsems; @@ -509,7 +513,7 @@ static bool __handle_sysv_sems(struct shim_sem_handle* sem) { } if (setevent) - DkEventSet(sem->event); + DkEventSet(sem->event); // TODO: handle errors return progressed; } diff --git a/LibOS/shim/src/sys/shim_sigaction.c b/LibOS/shim/src/sys/shim_sigaction.c index 58967c2dbb..c9a86f248c 100644 --- a/LibOS/shim/src/sys/shim_sigaction.c +++ b/LibOS/shim/src/sys/shim_sigaction.c @@ -197,7 +197,7 @@ long shim_do_rt_sigsuspend(const __sigset_t* mask_ptr, size_t setsize) { set_sig_mask(current, &mask); unlock(¤t->lock); - DkEventClear(current->scheduler_event); + DkEventClear(current->scheduler_event); // TODO: handle errors while (!have_pending_signals()) { int ret = thread_sleep(NO_TIMEOUT, /*ignore_pending_signals=*/false); if (ret < 0 && ret != -EINTR && ret != -EAGAIN) { @@ -262,8 +262,12 @@ static int _wakeup_one_thread(struct shim_thread* thread, void* arg) { if (!__sigismember(&thread->signal_mask, sig)) { thread_wakeup(thread); - DkThreadResume(thread->pal_handle); - ret = 1; + ret = DkThreadResume(thread->pal_handle); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + } else { + ret = 1; + } } unlock(&thread->lock); @@ -397,11 +401,11 @@ int do_kill_thread(IDTYPE sender, IDTYPE tgid, IDTYPE tid, int sig, bool use_ipc } if (thread != get_cur_thread()) { thread_wakeup(thread); - DkThreadResume(thread->pal_handle); + ret = pal_to_unix_errno(DkThreadResume(thread->pal_handle)); } put_thread(thread); - return 0; + return ret; } maybe_try_ipc: diff --git a/LibOS/shim/src/sys/shim_socket.c b/LibOS/shim/src/sys/shim_socket.c index b9c7946f40..b55ecbe83d 100644 --- a/LibOS/shim/src/sys/shim_socket.c +++ b/LibOS/shim/src/sys/shim_socket.c @@ -476,11 +476,12 @@ long shim_do_bind(int sockfd, struct sockaddr* addr, int _addrlen) { create_flags &= ~PAL_CREATE_DUALSTACK; } - PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, create_flags, - hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0); + PAL_HANDLE pal_hdl = NULL; + ret = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, create_flags, + hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0, &pal_hdl); - if (!pal_hdl) { - ret = (PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMEXIST) ? -EADDRINUSE : -PAL_ERRNO(); + if (ret < 0) { + ret = (ret == -PAL_ERROR_STREAMEXIST) ? -EADDRINUSE : pal_to_unix_errno(ret); log_error("bind: invalid handle returned\n"); goto out; } @@ -497,8 +498,9 @@ long shim_do_bind(int sockfd, struct sockaddr* addr, int _addrlen) { if (sock->domain == AF_INET || sock->domain == AF_INET6) { char uri[SOCK_URI_SIZE]; - if (!DkStreamGetName(pal_hdl, uri, SOCK_URI_SIZE)) { - ret = -PAL_ERRNO(); + ret = DkStreamGetName(pal_hdl, uri, sizeof(uri)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } @@ -680,7 +682,7 @@ long shim_do_connect(int sockfd, struct sockaddr* addr, int _addrlen) { if (addr->sa_family == AF_UNSPEC) { sock->sock_state = SOCK_CREATED; if (sock->sock_type == SOCK_STREAM && hdl->pal_handle) { - DkStreamDelete(hdl->pal_handle, 0); + DkStreamDelete(hdl->pal_handle, 0); // TODO: handle errors DkObjectClose(hdl->pal_handle); hdl->pal_handle = NULL; pal_handle_updated = true; @@ -738,7 +740,7 @@ long shim_do_connect(int sockfd, struct sockaddr* addr, int _addrlen) { if (state == SOCK_BOUND) { /* if the socket is bound, the stream needs to be shut and rebound. */ assert(hdl->pal_handle); - DkStreamDelete(hdl->pal_handle, 0); + DkStreamDelete(hdl->pal_handle, 0); // TODO: handle errors DkObjectClose(hdl->pal_handle); hdl->pal_handle = NULL; pal_handle_updated = true; @@ -756,11 +758,12 @@ long shim_do_connect(int sockfd, struct sockaddr* addr, int _addrlen) { if ((ret = create_socket_uri(hdl)) < 0) goto out; - PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, 0, - hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0); + PAL_HANDLE pal_hdl = NULL; + ret = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, 0, + hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0, &pal_hdl); - if (!pal_hdl) { - ret = (PAL_NATIVE_ERRNO() == PAL_ERROR_DENIED) ? -ECONNREFUSED : -PAL_ERRNO(); + if (ret < 0) { + ret = (ret == -PAL_ERROR_DENIED) ? -ECONNREFUSED : pal_to_unix_errno(ret); goto out; } @@ -780,8 +783,9 @@ long shim_do_connect(int sockfd, struct sockaddr* addr, int _addrlen) { if (sock->domain == AF_INET || sock->domain == AF_INET6) { char uri[SOCK_URI_SIZE]; - if (!DkStreamGetName(pal_hdl, uri, SOCK_URI_SIZE)) { - ret = -PAL_ERRNO(); + ret = DkStreamGetName(pal_hdl, uri, sizeof(uri)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } @@ -854,10 +858,7 @@ static int __do_accept(struct shim_handle* hdl, int flags, struct sockaddr* addr /* NOTE: DkStreamWaitForClient() is blocking so we need to unlock before it and lock again * afterwards; we rely on DkStreamWaitForClient() being thread-safe and that `handle` is not * freed during the wait. */ - accepted = DkStreamWaitForClient(handle); - if (!accepted) { - ret = -PAL_ERRNO(); - } + ret = pal_to_unix_errno(DkStreamWaitForClient(handle, &accepted)); lock(&hdl->lock); if (ret < 0) { @@ -874,15 +875,17 @@ static int __do_accept(struct shim_handle* hdl, int flags, struct sockaddr* addr if (flags & O_NONBLOCK) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(accepted, &attr)) { - ret = -PAL_ERRNO(); + ret = DkStreamAttributesQueryByHandle(accepted, &attr); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } attr.nonblocking = PAL_TRUE; - if (!DkStreamAttributesSetByHandle(accepted, &attr)) { - ret = -PAL_ERRNO(); + ret = DkStreamAttributesSetByHandle(accepted, &attr); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } } @@ -925,10 +928,10 @@ static int __do_accept(struct shim_handle* hdl, int flags, struct sockaddr* addr if (sock->domain == AF_INET || sock->domain == AF_INET6) { char uri[SOCK_URI_SIZE]; - int uri_len; - if (!(uri_len = DkStreamGetName(cli->pal_handle, uri, SOCK_URI_SIZE))) { - ret = -PAL_ERRNO(); + ret = DkStreamGetName(cli->pal_handle, uri, sizeof(uri)); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out_cli; } @@ -936,7 +939,7 @@ static int __do_accept(struct shim_handle* hdl, int flags, struct sockaddr* addr &cli_sock->addr.in.bind, &cli_sock->addr.in.conn)) < 0) goto out_cli; - qstrsetstr(&cli->uri, uri, uri_len); + qstrsetstr(&cli->uri, uri, strlen(uri)); inet_rebase_port(true, cli_sock->domain, &cli_sock->addr.in.bind, true); inet_rebase_port(true, cli_sock->domain, &cli_sock->addr.in.conn, false); @@ -1044,10 +1047,10 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags, } if (sock->sock_state == SOCK_CREATED && !pal_hdl) { - pal_hdl = DkStreamOpen(URI_PREFIX_UDP, 0, 0, 0, - hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0); - if (!pal_hdl) { - ret = -PAL_ERRNO(); + ret = DkStreamOpen(URI_PREFIX_UDP, 0, 0, 0, + hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0, &pal_hdl); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out_locked; } @@ -1084,10 +1087,12 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags, ret = 0; for (int i = 0; i < nbufs; i++) { - PAL_NUM pal_ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri); + size_t this_size = bufs[i].iov_len; + ret = DkStreamWrite(pal_hdl, 0, &this_size, bufs[i].iov_base, uri); - if (pal_ret == PAL_STREAM_ERROR) { - if (PAL_ERRNO() == EPIPE && !(flags & MSG_NOSIGNAL)) { + if (ret < 0) { + ret = ret == -PAL_ERROR_STREAMEXIST ? -ECONNABORTED : pal_to_unix_errno(ret); + if (ret == -EPIPE && !(flags & MSG_NOSIGNAL)) { siginfo_t info = { .si_signo = SIGPIPE, .si_pid = g_process.pid, @@ -1097,12 +1102,10 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags, log_error("do_sendmsg: failed to deliver a signal\n"); } } - - ret = (PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMEXIST) ? -ECONNABORTED : -PAL_ERRNO(); break; } - bytes += pal_ret; + bytes += this_size; } if (bytes) @@ -1322,18 +1325,15 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, size_t nbufs, int flags, /* fill peek buffer if this MSG_PEEK read request cannot be satisfied with data already * present in peek buffer; note that buffer can hold expected read size at this point */ size_t left_to_read = expected_size - (peek_buffer->end - peek_buffer->start); - PAL_NUM pal_ret = DkStreamRead(pal_hdl, /*offset=*/0, left_to_read, - &peek_buffer->buf[peek_buffer->end], - uri, uri ? SOCK_URI_SIZE : 0); - if (pal_ret == PAL_STREAM_ERROR) { - ret = PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMNOTEXIST - ? -ECONNABORTED - : -PAL_ERRNO(); + ret = DkStreamRead(pal_hdl, /*offset=*/0, &left_to_read, + &peek_buffer->buf[peek_buffer->end], uri, uri ? SOCK_URI_SIZE : 0); + if (ret < 0) { + ret = ret == -PAL_ERROR_STREAMNOTEXIST ? -ECONNABORTED : pal_to_unix_errno(ret); lock(&hdl->lock); goto out_locked; } - peek_buffer->end += pal_ret; + peek_buffer->end += left_to_read; if (uri) memcpy(peek_buffer->uri, uri, SOCK_URI_SIZE); } @@ -1354,15 +1354,14 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, size_t nbufs, int flags, iov_bytes); uri = peek_buffer->uri; } else { - PAL_NUM pal_ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri, - uri ? SOCK_URI_SIZE : 0); - if (pal_ret == PAL_STREAM_ERROR) { - ret = PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMNOTEXIST - ? -ECONNABORTED - : -PAL_ERRNO(); + size_t read_size = bufs[i].iov_len; + ret = DkStreamRead(pal_hdl, 0, &read_size, bufs[i].iov_base, uri, + uri ? SOCK_URI_SIZE : 0); + if (ret < 0) { + ret = ret == -PAL_ERROR_STREAMNOTEXIST ? -ECONNABORTED : pal_to_unix_errno(ret); break; } - iov_bytes = pal_ret; + iov_bytes = read_size; } total_bytes += iov_bytes; @@ -1553,18 +1552,33 @@ long shim_do_shutdown(int sockfd, int how) { switch (how) { case SHUT_RD: - DkStreamDelete(hdl->pal_handle, PAL_DELETE_RD); + ret = DkStreamDelete(hdl->pal_handle, PAL_DELETE_RD); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + goto out_locked; + } hdl->acc_mode &= ~MAY_READ; break; case SHUT_WR: - DkStreamDelete(hdl->pal_handle, PAL_DELETE_WR); + ret = DkStreamDelete(hdl->pal_handle, PAL_DELETE_WR); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + goto out_locked; + } hdl->acc_mode &= ~MAY_WRITE; break; case SHUT_RDWR: - DkStreamDelete(hdl->pal_handle, 0); + ret = DkStreamDelete(hdl->pal_handle, 0); + if (ret < 0) { + ret = pal_to_unix_errno(ret); + goto out_locked; + } hdl->acc_mode = 0; sock->sock_state = SOCK_SHUTDOWN; break; + default: + ret = -EINVAL; + goto out_locked; } ret = 0; @@ -1792,14 +1806,18 @@ static int __do_setsockopt(struct shim_handle* hdl, int level, int optname, char PAL_STREAM_ATTR local_attr; if (!attr) { attr = &local_attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } } bool need_set_attr = __update_attr(attr, level, optname, optval); if (need_set_attr) { - if (!DkStreamAttributesSetByHandle(hdl->pal_handle, attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesSetByHandle(hdl->pal_handle, attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } } return 0; @@ -1813,8 +1831,10 @@ static int __process_pending_options(struct shim_handle* hdl) { PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) - return -PAL_ERRNO(); + int ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + return pal_to_unix_errno(ret); + } struct shim_sock_option* o = sock->pending_options; @@ -1987,8 +2007,9 @@ long shim_do_getsockopt(int fd, int level, int optname, char* optval, int* optle } } else { /* query PAL to get current attributes */ - if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) { - ret = -PAL_ERRNO(); + ret = DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr); + if (ret < 0) { + ret = pal_to_unix_errno(ret); goto out; } } diff --git a/LibOS/shim/src/sys/shim_time.c b/LibOS/shim/src/sys/shim_time.c index 16c09459af..6e32ee6a83 100644 --- a/LibOS/shim/src/sys/shim_time.c +++ b/LibOS/shim/src/sys/shim_time.c @@ -24,10 +24,11 @@ long shim_do_gettimeofday(struct __kernel_timeval* tv, struct __kernel_timezone* if (tz && test_user_memory(tz, sizeof(*tz), /*write=*/true)) return -EFAULT; - uint64_t time = DkSystemTimeQuery(); - - if (time == (uint64_t)-1) - return -PAL_ERRNO(); + uint64_t time = 0; + int ret = DkSystemTimeQuery(&time); + if (ret < 0) { + return pal_to_unix_errno(ret); + } tv->tv_sec = time / 1000000; tv->tv_usec = time % 1000000; @@ -35,14 +36,15 @@ long shim_do_gettimeofday(struct __kernel_timeval* tv, struct __kernel_timezone* } long shim_do_time(time_t* tloc) { - uint64_t time = DkSystemTimeQuery(); - - if (time == (uint64_t)-1) - return -PAL_ERRNO(); - if (tloc && test_user_memory(tloc, sizeof(*tloc), /*write=*/true)) return -EFAULT; + uint64_t time = 0; + int ret = DkSystemTimeQuery(&time); + if (ret < 0) { + return pal_to_unix_errno(ret); + } + time_t t = time / 1000000; if (tloc) @@ -62,10 +64,11 @@ long shim_do_clock_gettime(clockid_t which_clock, struct timespec* tp) { if (test_user_memory(tp, sizeof(*tp), /*write=*/true)) return -EFAULT; - uint64_t time = DkSystemTimeQuery(); - - if (time == (uint64_t)-1) - return -PAL_ERRNO(); + uint64_t time = 0; + int ret = DkSystemTimeQuery(&time); + if (ret < 0) { + return pal_to_unix_errno(ret); + } tp->tv_sec = time / 1000000; tp->tv_nsec = (time % 1000000) * 1000; diff --git a/LibOS/shim/src/sys/shim_wait.c b/LibOS/shim/src/sys/shim_wait.c index 31fd238f6f..8b53f90f8b 100644 --- a/LibOS/shim/src/sys/shim_wait.c +++ b/LibOS/shim/src/sys/shim_wait.c @@ -81,7 +81,7 @@ static void remove_qnode_from_wait_queue(struct shim_thread_queue* qnode) { unlock(&g_process.children_lock); while (!seen) { - DkEventClear(get_cur_thread()->scheduler_event); + DkEventClear(get_cur_thread()->scheduler_event); // TODO: handle errors /* Check `mark_child_exited` for explanation why we might need this compiler barrier. */ COMPILER_BARRIER(); /* Check if `qnode` is no longer used. */ @@ -178,7 +178,7 @@ static long do_waitid(int which, pid_t id, siginfo_t* infop, int options) { unlock(&g_process.children_lock); - DkEventClear(self->scheduler_event); + DkEventClear(self->scheduler_event); // TODO: handle errors /* Check `mark_child_exited` for explanation why we might need this compiler barrier. */ COMPILER_BARRIER(); /* Check that we are still supposed to sleep. */ diff --git a/LibOS/shim/src/utils/printf.c b/LibOS/shim/src/utils/printf.c index c56d8e3dcb..509ef4ab0c 100644 --- a/LibOS/shim/src/utils/printf.c +++ b/LibOS/shim/src/utils/printf.c @@ -17,13 +17,13 @@ static inline int debug_fputs(const char* buf, size_t size) { size_t bytes = 0; while (bytes < size) { - PAL_NUM x = DkDebugLog((void*)(buf + bytes), size - bytes); - if (x == PAL_STREAM_ERROR) { - int err = PAL_ERRNO(); - if (err == EINTR || err == EAGAIN || err == EWOULDBLOCK) { + PAL_NUM x = size - bytes; + int ret = DkDebugLog((void*)(buf + bytes), &x); + if (ret < 0) { + if (ret == -PAL_ERROR_INTERRUPTED || ret == -PAL_ERROR_TRYAGAIN) { continue; } - return -err; + return pal_to_unix_errno(ret); } bytes += x; diff --git a/Pal/include/pal/pal.h b/Pal/include/pal/pal.h index 7a02bb6c47..54029be0d0 100644 --- a/Pal/include/pal/pal.h +++ b/Pal/include/pal/pal.h @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: LGPL-3.0-or-later */ /* Copyright (C) 2014 Stony Brook University */ -/* - * This file contains definition of PAL host ABI. +/*! + * \file pal.h + * \brief This file contains definition of PAL host ABI. */ #ifndef PAL_H @@ -203,16 +204,17 @@ enum PAL_PROT { /*! * \brief Allocate virtual memory for the library OS and zero it out. * - * \param addr - * can be either `NULL` or any valid address aligned at the allocation alignment. When `addr` is - * non-NULL, the API will try to allocate the memory at the given address and potentially rewrite - * any memory previously allocated at the same address. Overwriting any part of PAL and host kernel - * is forbidden. + * \param[in,out] addr + * `*addr` can be any valid address aligned at the allocation alignment or `NULL`, in which case + * a suitable address will be picked automatically. Any memory previously allocated at the same + * address will be discarded (only if `*addr` was provided). Overwriting any part of PAL memory is + * forbidden. On successful return `*addr` will contain the allocated address (which can differ + * only in the `NULL` case). * \param size must be a positive number, aligned at the allocation alignment. * \param alloc_type can be a combination of any of the #PAL_ALLOC flags * \param prot can be a combination of the #PAL_PROT flags */ -PAL_PTR DkVirtualMemoryAlloc(PAL_PTR addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot); +int DkVirtualMemoryAlloc(PAL_PTR* addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot); /*! * \brief This API deallocates a previously allocated memory mapping. @@ -222,18 +224,18 @@ PAL_PTR DkVirtualMemoryAlloc(PAL_PTR addr, PAL_NUM size, PAL_FLG alloc_type, PAL * * Both `addr` and `size` must be non-zero and aligned at the allocation alignment. */ -void DkVirtualMemoryFree(PAL_PTR addr, PAL_NUM size); +int DkVirtualMemoryFree(PAL_PTR addr, PAL_NUM size); /*! * \brief Modify the permissions of a previously allocated memory mapping. * * \param addr the address * \param size the size - * \param prot see #DkVirtualMemoryAlloc() + * \param prot see #DkVirtualMemoryAlloc * * Both `addr` and `size` must be non-zero and aligned at the allocation alignment. */ -PAL_BOL DkVirtualMemoryProtect(PAL_PTR addr, PAL_NUM size, PAL_FLG prot); +int DkVirtualMemoryProtect(PAL_PTR addr, PAL_NUM size, PAL_FLG prot); /* * PROCESS CREATION @@ -246,8 +248,9 @@ PAL_BOL DkVirtualMemoryProtect(PAL_PTR addr, PAL_NUM size, PAL_FLG prot); * * \param exec_uri the URI of the executable to be loaded in the new process. * \param args an array of strings -- the arguments to be passed to the new process. + * \param[out] handle on success contains the process handle. */ -PAL_HANDLE DkProcessCreate(PAL_STR exec_uri, PAL_STR* args); +int DkProcessCreate(PAL_STR exec_uri, PAL_STR* args, PAL_HANDLE* handle); /*! * \brief Terminate all threads in the process immediately. @@ -307,9 +310,6 @@ enum PAL_OPTION { PAL_OPTION_MASK = 7, }; -/*! error value of read/write */ -#define PAL_STREAM_ERROR ((PAL_NUM)-1L) - #define WITHIN_MASK(val, mask) (((val) | (mask)) == (mask)) /*! @@ -320,9 +320,10 @@ enum PAL_OPTION { * \param share_flags can be a combination of the #PAL_SHARE flags * \param create can be a combination of the #PAL_CREATE flags * \param options can be a combination of the #PAL_OPTION flags + * \param handle[out] if the resource is successfully opened or created, a PAL handle is returned + * in `*handle` for further access such as reading or writing. * - * \return If the resource is successfully opened or created, a PAL handle will be returned for - * further access such as reading or writing. + * \return 0 on success, negative error code on failure. * * Supported URI types: * * `%file:...`, `dir:...`: Files or directories on the host file system. If #PAL_CREATE_TRY is @@ -336,39 +337,55 @@ enum PAL_OPTION { * * `udp.srv::`, `udp::`: Open a UDP socket to listen or connect to * a remote UDP socket. */ -PAL_HANDLE DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share_flags, PAL_FLG create, - PAL_FLG options); +int DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share_flags, PAL_FLG create, PAL_FLG options, + PAL_HANDLE* handle); /*! * \brief Blocks until a new connection is accepted and returns the PAL handle for the connection. * + * \param handle handle to accept a new connection on. + * \param[out] client on success holds handle for the new connection. + * * This API is only available for handles that are opened with `pipe.srv:...`, `tcp.srv:...`, and * `udp.srv:...`. */ -PAL_HANDLE DkStreamWaitForClient(PAL_HANDLE handle); +int DkStreamWaitForClient(PAL_HANDLE handle, PAL_HANDLE* client); /*! * \brief Read data from an open stream. * - * If the handle is a file, `offset` must be specified at each call of DkStreamRead. `source` and - * `size` can be used to return the remote socket address if the handle is a UDP socket. If the - * handle is a directory, DkStreamRead fills the buffer with the names (NULL-ended) of the files or - * subdirectories inside of this directory. + * \param handle handle to the stream. + * \param offset offset to read at. If \p handle is a file, \p offset must be specified at each + * call. + * \param[in,out] count on function call should contain the size of \p buffer. On successful return + * contains the number of bytes read. + * \param buffer pointer to the buffer to read into. + * \param[out] source if \p handle is a UDP socket, \p size is not zero and \p source is not NULL, + * the remote socket address is returned in it. + * \param size size of the \p source buffer. + * + * \return 0 on success, negative error code on failure. + * + * If \p handle is a directory, DkStreamRead fills the buffer with the null-terminated names of the + * directory entries. */ -PAL_NUM DkStreamRead(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM count, PAL_PTR buffer, - PAL_PTR source, PAL_NUM size); +int DkStreamRead(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM* count, PAL_PTR buffer, PAL_PTR source, + PAL_NUM size); /*! * \brief Write data to an open stream. * - * If the handle is a file, `offset` must be specified at each call of DkStreamWrite. `dest` can be - * used to specify the remote socket address if the handle is a UDP socket. + * \param handle handle to the stream. + * \param offset offset to write to. If \p handle is a file, \p offset must be specified at each + * call. + * \param[in,out] count on function call should contain the size of \p buffer. On successful return + * contains the number of bytes written. + * \param buffer pointer to the buffer to write from. + * \param dest if the handle is a UDP socket, specifies the remote socket address. * - * \return number of bytes written if succeeded, PAL_STREAM_ERROR on failure (in which case - * PAL_ERRNO() is set) + * \return 0 on success, negative error code on failure. */ -PAL_NUM DkStreamWrite(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM count, PAL_PTR buffer, - PAL_STR dest); +int DkStreamWrite(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM* count, PAL_PTR buffer, PAL_STR dest); enum PAL_DELETE { PAL_DELETE_RD = 1, /*!< shut down the read side only */ @@ -380,36 +397,43 @@ enum PAL_DELETE { * * \param access which side to shut down (#PAL_DELETE), or both if 0 is given. */ -void DkStreamDelete(PAL_HANDLE handle, PAL_FLG access); +int DkStreamDelete(PAL_HANDLE handle, PAL_FLG access); /*! * \brief Map a file to a virtual memory address in the current process. * - * \param address can be NULL or a valid address that is aligned at the allocation alignment. - * \param prot see #DkVirtualMemoryAlloc() + * \param handle handle to the stream to be mapped. + * \param[in,out] addr see #DkVirtualMemoryAlloc + * \param prot see #DkVirtualMemoryAlloc + * \param offset offset in the stream to be mapped. Must be properly aligned. + * \param size size of the requested mapping. Must be non-zero and properly aligned. * - * `offset` and `size` have to be non-zero and aligned at the allocation alignment + * \return 0 on success, negative error code on failure. */ -PAL_PTR DkStreamMap(PAL_HANDLE handle, PAL_PTR address, PAL_FLG prot, PAL_NUM offset, PAL_NUM size); +int DkStreamMap(PAL_HANDLE handle, PAL_PTR* addr, PAL_FLG prot, PAL_NUM offset, PAL_NUM size); /*! * \brief Unmap virtual memory that is backed by a file stream. * * `addr` and `size` must be aligned at the allocation alignment + * + * \return 0 on success, negative error code on failure. */ -void DkStreamUnmap(PAL_PTR addr, PAL_NUM size); +int DkStreamUnmap(PAL_PTR addr, PAL_NUM size); /*! * \brief Set the length of the file referenced by handle to `length`. * - * \return Returns the 0 on success, a _positive_ errno on failure. + * \return 0 on success, negative error code on failure. */ -PAL_NUM DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length); +int DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length); /*! * \brief Flush the buffer of a file stream. + * + * \return 0 on success, negative error code on failure. */ -PAL_BOL DkStreamFlush(PAL_HANDLE handle); +int DkStreamFlush(PAL_HANDLE handle); /*! * \brief Send a PAL handle over another handle. @@ -417,13 +441,19 @@ PAL_BOL DkStreamFlush(PAL_HANDLE handle); * Currently, the handle that is used to send cargo must be a process handle. * * \param cargo the handle being sent + * + * \return 0 on success, negative error code on failure. */ -PAL_BOL DkSendHandle(PAL_HANDLE handle, PAL_HANDLE cargo); +int DkSendHandle(PAL_HANDLE handle, PAL_HANDLE cargo); /*! * \brief This API receives a handle over another handle. + * + * TODO: document usage and parameters. + * + * \return 0 on success, negative error code on failure. */ -PAL_HANDLE DkReceiveHandle(PAL_HANDLE handle); +int DkReceiveHandle(PAL_HANDLE handle, PAL_HANDLE* cargo); /* stream attribute structure */ typedef struct _PAL_STREAM_ATTR { @@ -452,29 +482,29 @@ typedef struct _PAL_STREAM_ATTR { * * This API only applies for URIs such as `%file:...`, `dir:...`, and `dev:...`. */ -PAL_BOL DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr); +int DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr); /*! * \brief Query the attributes of an open stream. * * This API applies to any stream handle. */ -PAL_BOL DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr); +int DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr); /*! * \brief Set the attributes of an open stream. */ -PAL_BOL DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr); +int DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr); /*! - * \brief Query the name of an open stream. + * \brief Query the name of an open stream. On success `buffer` contains a null-terminated string. */ -PAL_NUM DkStreamGetName(PAL_HANDLE handle, PAL_PTR buffer, PAL_NUM size); +int DkStreamGetName(PAL_HANDLE handle, PAL_PTR buffer, PAL_NUM size); /*! * \brief This API changes the name of an open stream. */ -PAL_BOL DkStreamChangeName(PAL_HANDLE handle, PAL_STR uri); +int DkStreamChangeName(PAL_HANDLE handle, PAL_STR uri); /* * Thread creation @@ -487,8 +517,9 @@ PAL_BOL DkStreamChangeName(PAL_HANDLE handle, PAL_STR uri); * * \param addr is the address of an entry point of execution for the new thread * \param param is the pointer argument that is passed to the new thread + * \param[out] handle on success contains the thread handle */ -PAL_HANDLE DkThreadCreate(PAL_PTR addr, PAL_PTR param); +int DkThreadCreate(PAL_PTR addr, PAL_PTR param, PAL_HANDLE* handle); /*! * \brief Suspend the current thread for a certain duration @@ -514,7 +545,7 @@ noreturn void DkThreadExit(PAL_PTR clear_child_tid); /*! * \brief Resume a thread. */ -PAL_BOL DkThreadResume(PAL_HANDLE thread); +int DkThreadResume(PAL_HANDLE thread); /*! * \brief Sets the CPU affinity of a thread. @@ -526,9 +557,9 @@ PAL_BOL DkThreadResume(PAL_HANDLE thread); * \param cpumask_size size in bytes of the bitmask pointed by \a cpu_mask. * \param cpu_mask pointer to the new CPU mask. * - * \return Returns 1 on success, 0 on failure. Use PAL_ERRNO() to get the actual error code. + * \return Returns 0 on success, negative error code on failure. */ -PAL_BOL DkThreadSetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask); +int DkThreadSetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask); /*! * \brief Gets the CPU affinity of a thread. @@ -541,9 +572,9 @@ PAL_BOL DkThreadSetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR * \param cpumask_size size in bytes of the bitmask pointed by \a cpu_mask. * \param cpu_mask pointer to hold the current CPU mask. * - * \return Returns 1 on success, 0 on failure. Use PAL_ERRNO() to get the actual error code. + * \return Returns 0 on success, negative error code on failure. */ -PAL_BOL DkThreadGetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask); +int DkThreadGetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask); /* * Exception Handling @@ -560,8 +591,6 @@ enum PAL_EVENT { PAL_EVENT_QUIT, /*! interrupted (usually internally to handle aync event) */ PAL_EVENT_INTERRUPTED, - /*! failure within PAL calls */ - PAL_EVENT_FAILURE, PAL_EVENT_NUM_BOUND, }; @@ -580,7 +609,7 @@ typedef void (*PAL_EVENT_HANDLER)(bool is_in_pal, PAL_NUM addr, PAL_CONTEXT* con * * \param event can be one of #PAL_EVENT values */ -PAL_BOL DkSetExceptionHandler(PAL_EVENT_HANDLER handler, PAL_NUM event); +void DkSetExceptionHandler(PAL_EVENT_HANDLER handler, PAL_NUM event); /* * Synchronization @@ -592,8 +621,9 @@ PAL_BOL DkSetExceptionHandler(PAL_EVENT_HANDLER handler, PAL_NUM event); * Destroy a mutex using DkObjectClose. * * \param initialCount 0 is unlocked, 1 is locked + * \param[out] handle on success contains the mutex handle */ -PAL_HANDLE DkMutexCreate(PAL_NUM initialCount); +int DkMutexCreate(PAL_NUM initialCount, PAL_HANDLE* handle); /*! * \brief Unlock the given mutex. @@ -603,31 +633,37 @@ void DkMutexRelease(PAL_HANDLE mutexHandle); /*! * \brief Creates a notification event with the given `initialState`. * + * \param initialState initial state of the event + * \param[out] handle on success `*handle` contains pointer to the event handle + * * The definition of notification events is the same as the WIN32 API. When * a notification event is set to the signaled state it remains in that state * until it is explicitly cleared. */ -PAL_HANDLE DkNotificationEventCreate(PAL_BOL initialState); +int DkNotificationEventCreate(PAL_BOL initialState, PAL_HANDLE* handle); /*! * \brief Creates a synchronization event with the given `initialState`. * + * \param initialState initial state of the event + * \param[out] handle on success `*handle` contains pointer to the event handle + * * The definition of synchronization events is the same as the WIN32 API. When * a synchronization event is set to the signaled state, a single thread of * execution that was waiting for the event is released, and the event is * automatically reset to the not-signaled state. */ -PAL_HANDLE DkSynchronizationEventCreate(PAL_BOL initialState); +int DkSynchronizationEventCreate(PAL_BOL initialState, PAL_HANDLE* handle); /*! * \brief Set (signal) a notification event or a synchronization event. */ -void DkEventSet(PAL_HANDLE eventHandle); +int DkEventSet(PAL_HANDLE eventHandle); /*! * \brief Clear a notification event or a synchronization event. */ -void DkEventClear(PAL_HANDLE eventHandle); +int DkEventClear(PAL_HANDLE eventHandle); /*! block until the handle's event is triggered */ #define NO_TIMEOUT ((PAL_NUM)-1) @@ -638,9 +674,9 @@ void DkEventClear(PAL_HANDLE eventHandle); * \param timeout_us is the maximum time that the API should wait (in * microseconds), or #NO_TIMEOUT to indicate it is to be blocked until the * handle's event is triggered. - * \return true if this handle's event was triggered, false otherwise + * \return 0 if this handle's event was triggered, negative error code otherwise */ -PAL_BOL DkSynchronizationObjectWait(PAL_HANDLE handle, PAL_NUM timeout_us); +int DkSynchronizationObjectWait(PAL_HANDLE handle, PAL_NUM timeout_us); enum PAL_WAIT { PAL_WAIT_SIGNAL = 1, /*!< ignored in events */ @@ -659,10 +695,10 @@ enum PAL_WAIT { * \param timeout_us is the maximum time that the API should wait (in * microseconds), or `NO_TIMEOUT` to indicate it is to be blocked until at * least one handle is ready. - * \return true if there was an event on at least one handle, false otherwise + * \return 0 if there was an event on at least one handle, negative error code otherwise */ -PAL_BOL DkStreamsWaitEvents(PAL_NUM count, PAL_HANDLE* handle_array, PAL_FLG* events, - PAL_FLG* ret_events, PAL_NUM timeout_us); +int DkStreamsWaitEvents(PAL_NUM count, PAL_HANDLE* handle_array, PAL_FLG* events, + PAL_FLG* ret_events, PAL_NUM timeout_us); /*! * \brief Close (deallocate) a PAL handle. @@ -676,16 +712,20 @@ void DkObjectClose(PAL_HANDLE objectHandle); /*! * \brief Output a message to the debug stream. * - * \return number of bytes written if succeeded, PAL_STREAM_ERROR on failure (in which case - * PAL_ERRNO() is set) + * \param buffer message to write. + * \param[in,out] on entry `*size` should hold \p buffer size. On successful return it contains + * the number of bytes written. + * + * \return 0 on success, negative error code on failure. */ -PAL_NUM DkDebugLog(PAL_PTR buffer, PAL_NUM size); +int DkDebugLog(PAL_PTR buffer, PAL_NUM* size); /*! * \brief Get the current time - * \return the current time in microseconds + * + * \param[out] time on success holds the current time in microseconds */ -PAL_NUM DkSystemTimeQuery(void); +int DkSystemTimeQuery(PAL_NUM* time); /*! * \brief Cryptographically secure random. @@ -694,7 +734,7 @@ PAL_NUM DkSystemTimeQuery(void); * \param[in] size buffer size * \return 0 on success, negative on failure */ -PAL_NUM DkRandomBitsRead(PAL_PTR buffer, PAL_NUM size); +int DkRandomBitsRead(PAL_PTR buffer, PAL_NUM size); enum PAL_SEGMENT { PAL_SEGMENT_FS = 1, @@ -707,9 +747,9 @@ enum PAL_SEGMENT { * \param reg the register to get (#PAL_SEGMENT) * \param addr the address where result will be stored * - * \return true on success, false on error + * \return 0 on success, negative error value on failure */ -PAL_BOL DkSegmentRegisterGet(PAL_FLG reg, PAL_PTR* addr); +int DkSegmentRegisterGet(PAL_FLG reg, PAL_PTR* addr); /*! * \brief Set segment register @@ -717,9 +757,9 @@ PAL_BOL DkSegmentRegisterGet(PAL_FLG reg, PAL_PTR* addr); * \param reg the register to be set (#PAL_SEGMENT) * \param addr the address to be set * - * \return true on success, false on error + * \return 0 on success, negative error value on failure */ -PAL_BOL DkSegmentRegisterSet(PAL_FLG reg, PAL_PTR addr); +int DkSegmentRegisterSet(PAL_FLG reg, PAL_PTR addr); /*! * \brief Return the amount of currently available memory for LibOS/application @@ -757,9 +797,9 @@ PAL_NUM DkMemoryAvailableQuota(void); * \param[in,out] report_size Caller specifies size of `report`; on return, contains * PAL-enforced size of `report` (432B in case of SGX PAL). */ -PAL_BOL DkAttestationReport(PAL_PTR user_report_data, PAL_NUM* user_report_data_size, - PAL_PTR target_info, PAL_NUM* target_info_size, PAL_PTR report, - PAL_NUM* report_size); +int DkAttestationReport(PAL_PTR user_report_data, PAL_NUM* user_report_data_size, + PAL_PTR target_info, PAL_NUM* target_info_size, PAL_PTR report, + PAL_NUM* report_size); /*! * \brief Obtain the attestation quote with `user_report_data` embedded into it. @@ -776,8 +816,8 @@ PAL_BOL DkAttestationReport(PAL_PTR user_report_data, PAL_NUM* user_report_data_ * \param[in,out] quote_size Caller specifies maximum size allocated for `quote`; on * return, contains actual size of obtained quote. */ -PAL_BOL DkAttestationQuote(PAL_PTR user_report_data, PAL_NUM user_report_data_size, PAL_PTR quote, - PAL_NUM* quote_size); +int DkAttestationQuote(PAL_PTR user_report_data, PAL_NUM user_report_data_size, PAL_PTR quote, + PAL_NUM* quote_size); /*! * \brief Set wrap key (master key) for protected files. @@ -788,7 +828,7 @@ PAL_BOL DkAttestationQuote(PAL_PTR user_report_data, PAL_NUM user_report_data_si * \param[in] pf_key_hex Wrap key for protected files. Must be a 32-char null-terminated * hex string in case of SGX PAL (AES-GCM encryption key). */ -PAL_BOL DkSetProtectedFilesKey(PAL_PTR pf_key_hex); +int DkSetProtectedFilesKey(PAL_PTR pf_key_hex); #ifdef __GNUC__ #define symbol_version_default(real, name, version) \ @@ -803,7 +843,7 @@ PAL_BOL DkSetProtectedFilesKey(PAL_PTR pf_key_hex); * * \param[out] values the array of the results */ -PAL_BOL DkCpuIdRetrieve(PAL_IDX leaf, PAL_IDX subleaf, PAL_IDX values[PAL_CPUID_WORD_NUM]); +int DkCpuIdRetrieve(PAL_IDX leaf, PAL_IDX subleaf, PAL_IDX values[PAL_CPUID_WORD_NUM]); #endif #endif /* PAL_H */ diff --git a/Pal/include/pal/pal_error.h b/Pal/include/pal/pal_error.h index 7b5f419ffe..8a80817463 100644 --- a/Pal/include/pal/pal_error.h +++ b/Pal/include/pal/pal_error.h @@ -28,7 +28,6 @@ typedef enum _pal_error_t { PAL_ERROR_OVERFLOW, PAL_ERROR_BADADDR, PAL_ERROR_NOMEM, - PAL_ERROR_NOTKILLABLE, PAL_ERROR_INCONSIST, PAL_ERROR_TRYAGAIN, PAL_ERROR_NOTSERVER, @@ -61,7 +60,7 @@ typedef enum _pal_error_t { #define PAL_ERROR_CRYPTO_END PAL_ERROR_CRYPTO_INVALID_DH_STATE } pal_error_t; -/* err - positive value of error code */ +/* err - value of error code, either positive or negative */ const char* pal_strerror(int err); #endif diff --git a/Pal/regression/.gitignore b/Pal/regression/.gitignore index d1113dee79..202df9e2f8 100644 --- a/Pal/regression/.gitignore +++ b/Pal/regression/.gitignore @@ -26,7 +26,6 @@ /Exception /Exception2 /Exit -/Failure /File /File2 /HelloWorld diff --git a/Pal/regression/AttestationReport.c b/Pal/regression/AttestationReport.c index 5b87ace883..87e3992a89 100644 --- a/Pal/regression/AttestationReport.c +++ b/Pal/regression/AttestationReport.c @@ -8,7 +8,7 @@ char zerobuf[sizeof(sgx_report_t)] = {0}; int main(int argc, char** argv) { - bool ret; + int ret; size_t user_report_data_size; size_t target_info_size; @@ -16,7 +16,7 @@ int main(int argc, char** argv) { ret = DkAttestationReport(/*user_report_data=*/NULL, &user_report_data_size, /*target_info=*/NULL, &target_info_size, /*report=*/NULL, &report_size); - if (!ret) { + if (ret < 0) { pal_printf("ERROR: DkAttestationReport() to get sizes of SGX structs failed\n"); return -1; } @@ -39,23 +39,26 @@ int main(int argc, char** argv) { pal_printf("user_report_data_size = %lu, target_info_size = %lu, report_size = %lu\n", user_report_data_size, target_info_size, report_size); - char* user_report_data = DkVirtualMemoryAlloc(NULL, ALLOC_ALIGN_UP(user_report_data_size), 0, - PAL_PROT_READ | PAL_PROT_WRITE); - if (!user_report_data) { + void* user_report_data = NULL; + ret = DkVirtualMemoryAlloc(&user_report_data, ALLOC_ALIGN_UP(user_report_data_size), 0, + PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { pal_printf("ERROR: Cannot allocate memory for user_report_data\n"); return -1; } - char* target_info = DkVirtualMemoryAlloc(NULL, ALLOC_ALIGN_UP(target_info_size), 0, - PAL_PROT_READ | PAL_PROT_WRITE); - if (!target_info) { + void* target_info = NULL; + ret = DkVirtualMemoryAlloc(&target_info, ALLOC_ALIGN_UP(target_info_size), 0, + PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { pal_printf("ERROR: Cannot allocate memory for target_info\n"); return -1; } - char* report = DkVirtualMemoryAlloc(NULL, ALLOC_ALIGN_UP(report_size), 0, - PAL_PROT_READ | PAL_PROT_WRITE); - if (!report) { + void* report = NULL; + ret = DkVirtualMemoryAlloc(&report, ALLOC_ALIGN_UP(report_size), 0, + PAL_PROT_READ | PAL_PROT_WRITE); + if (ret < 0) { pal_printf("ERROR: Cannot allocate memory for report\n"); return -1; } @@ -66,7 +69,7 @@ int main(int argc, char** argv) { ret = DkAttestationReport(user_report_data, &user_report_data_size, target_info, &target_info_size, report, &report_size); - if (!ret) { + if (ret < 0) { pal_printf("ERROR: DkAttestationReport() to get SGX report failed\n"); return -1; } @@ -88,9 +91,18 @@ int main(int argc, char** argv) { return -1; } - DkVirtualMemoryFree(user_report_data, ALLOC_ALIGN_UP(user_report_data_size)); - DkVirtualMemoryFree(target_info, ALLOC_ALIGN_UP(target_info_size)); - DkVirtualMemoryFree(report, ALLOC_ALIGN_UP(report_size)); + if (DkVirtualMemoryFree(user_report_data, ALLOC_ALIGN_UP(user_report_data_size)) < 0) { + pal_printf("DkVirtualMemoryFree on `user_report_data` failed\n"); + return 1; + } + if (DkVirtualMemoryFree(target_info, ALLOC_ALIGN_UP(target_info_size)) < 0) { + pal_printf("DkVirtualMemoryFree on `target_info` failed\n"); + return 1; + } + if (DkVirtualMemoryFree(report, ALLOC_ALIGN_UP(report_size)) < 0) { + pal_printf("DkVirtualMemoryFree on `report` failed\n"); + return 1; + } pal_printf("Success\n"); return 0; diff --git a/Pal/regression/Bootstrap.c b/Pal/regression/Bootstrap.c index ee347bce2b..294e5d93e3 100644 --- a/Pal/regression/Bootstrap.c +++ b/Pal/regression/Bootstrap.c @@ -23,7 +23,12 @@ int main(int argc, char** argv, char** envp) { /* test debug stream */ char* msg = "Written to Debug Stream\n"; - DkDebugLog(msg, strlen(msg)); + size_t msg_size = strlen(msg); + int ret = DkDebugLog(msg, &msg_size); + if (ret < 0 || msg_size != strlen(msg)) { + pal_printf("Failed to write the debug message.\n"); + return 1; + } /* Allocation Alignment */ pal_printf("Allocation Alignment: %ld\n", pal_control.alloc_align); diff --git a/Pal/regression/Directory.c b/Pal/regression/Directory.c index c26166e20c..3eb4770d81 100644 --- a/Pal/regression/Directory.c +++ b/Pal/regression/Directory.c @@ -7,16 +7,20 @@ char buffer[80]; int main(int argc, char** argv, char** envp) { /* test regular directory opening */ - PAL_HANDLE dir1 = DkStreamOpen("dir:dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0); - if (dir1) { + PAL_HANDLE dir1 = NULL; + int ret = DkStreamOpen("dir:dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0, &dir1); + if (ret >= 0 && dir1) { pal_printf("Directory Open Test 1 OK\n"); PAL_STREAM_ATTR attr1; - if (DkStreamAttributesQueryByHandle(dir1, &attr1)) + ret = DkStreamAttributesQueryByHandle(dir1, &attr1); + if (ret >= 0) { pal_printf("Query by Handle: type = %d\n", attr1.handle_type); + } - int bytes = DkStreamRead(dir1, 0, 80, buffer, NULL, 0); - if (bytes) { + size_t bytes = sizeof(buffer); + ret = DkStreamRead(dir1, 0, &bytes, buffer, NULL, 0); + if (ret >= 0 && bytes) { for (char* c = buffer; c < buffer + bytes; c += strlen(c) + 1) if (strlen(c)) pal_printf("Read Directory: %s\n", c); @@ -25,51 +29,63 @@ int main(int argc, char** argv, char** envp) { DkObjectClose(dir1); } - PAL_HANDLE dir2 = DkStreamOpen("dir:./dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0); - if (dir2) { + PAL_HANDLE dir2 = NULL; + ret = DkStreamOpen("dir:./dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0, &dir2); + if (ret >= 0 && dir2) { pal_printf("Directory Open Test 2 OK\n"); DkObjectClose(dir2); } - PAL_HANDLE dir3 = DkStreamOpen("dir:../regression/dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0); - if (dir3) { + PAL_HANDLE dir3 = NULL; + ret = DkStreamOpen("dir:../regression/dir_exist.tmp", PAL_ACCESS_RDONLY, 0, 0, 0, &dir3); + if (ret >= 0 && dir3) { pal_printf("Directory Open Test 3 OK\n"); DkObjectClose(dir3); } PAL_STREAM_ATTR attr2; - if (DkStreamAttributesQuery("dir:dir_exist.tmp", &attr2)) + ret = DkStreamAttributesQuery("dir:dir_exist.tmp", &attr2); + if (ret >= 0) { pal_printf("Query: type = %d\n", attr2.handle_type); + } /* test regular directory creation */ - PAL_HANDLE dir4 = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDONLY, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_X, - PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0); - if (dir4) { + PAL_HANDLE dir4 = NULL; + ret = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDONLY, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_X, + PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0, &dir4); + if (ret >= 0 && dir4) { pal_printf("Directory Creation Test 1 OK\n"); DkObjectClose(dir4); } - PAL_HANDLE dir5 = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDONLY, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_X, - PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0); - if (dir5) { + PAL_HANDLE dir5 = NULL; + ret = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDONLY, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_X, + PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0, &dir5); + if (ret >= 0) { DkObjectClose(dir5); } else { pal_printf("Directory Creation Test 2 OK\n"); } - PAL_HANDLE dir6 = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDWR, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY, 0); - if (dir6) { + PAL_HANDLE dir6 = NULL; + ret = DkStreamOpen("dir:dir_nonexist.tmp", PAL_ACCESS_RDWR, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY, 0, &dir6); + if (ret >= 0 && dir6) { pal_printf("Directory Creation Test 3 OK\n"); DkObjectClose(dir6); } - PAL_HANDLE dir7 = DkStreamOpen("dir:dir_delete.tmp", PAL_ACCESS_RDONLY, 0, 0, 0); - if (dir7) { - DkStreamDelete(dir7, 0); + PAL_HANDLE dir7 = NULL; + ret = DkStreamOpen("dir:dir_delete.tmp", PAL_ACCESS_RDONLY, 0, 0, 0, &dir7); + if (ret >= 0 && dir7) { + ret = DkStreamDelete(dir7, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(dir7); } diff --git a/Pal/regression/Event.c b/Pal/regression/Event.c index b24d059f27..a74aaa1d02 100644 --- a/Pal/regression/Event.c +++ b/Pal/regression/Event.c @@ -19,38 +19,37 @@ static int thread2_run(void* args) { /* UNREACHABLE */ } -static void pal_failure_handler(bool is_in_pal, PAL_NUM error, PAL_CONTEXT* context) { - __UNUSED(is_in_pal); - - pal_printf("pal_failure_handler called\n"); - - if (error == PAL_ERROR_TRYAGAIN) { - pal_printf("Timeout event received.\n"); - timeouts += 1; - } -} - int main(void) { pal_printf("Started main thread.\n"); - DkSetExceptionHandler(pal_failure_handler, PAL_EVENT_FAILURE); - - event1 = DkNotificationEventCreate(0); - if (event1 == NULL) { + int ret = DkNotificationEventCreate(0, &event1); + if (ret < 0 || event1 == NULL) { pal_printf("DkNotificationEventCreate failed\n"); return 1; } - PAL_HANDLE thread2 = DkThreadCreate(thread2_run, NULL); - if (thread2 == NULL) { + PAL_HANDLE thread2 = NULL; + ret = DkThreadCreate(thread2_run, NULL, &thread2); + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); return 1; } - uint64_t t_start = DkSystemTimeQuery(); + uint64_t t_start = 0; + if (DkSystemTimeQuery(&t_start) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("Testing wait with too short timeout...\n"); - DkSynchronizationObjectWait(event1, 1000000); - uint64_t t_wait1 = DkSystemTimeQuery(); + ret = DkSynchronizationObjectWait(event1, 1000000); + if (ret == -PAL_ERROR_TRYAGAIN) { + timeouts++; + } + uint64_t t_wait1 = 0; + if (DkSystemTimeQuery(&t_wait1) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } uint64_t dt_wait1 = t_wait1 - t_start; pal_printf("Wait returned after %lu us.\n", dt_wait1); pal_printf("Timeout count: %d\n", timeouts); @@ -59,8 +58,15 @@ int main(void) { } pal_printf("Testing wait with long enough timeout...\n"); - DkSynchronizationObjectWait(event1, 5000000); - uint64_t t_wait2 = DkSystemTimeQuery(); + ret = DkSynchronizationObjectWait(event1, 5000000); + if (ret == -PAL_ERROR_TRYAGAIN) { + timeouts++; + } + uint64_t t_wait2 = 0; + if (DkSystemTimeQuery(&t_wait2) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } uint64_t dt_wait2 = t_wait2 - t_start; pal_printf("Wait returned after %lu us since start.\n", dt_wait2); pal_printf("Timeout count: %d\n", timeouts); diff --git a/Pal/regression/Event2.c b/Pal/regression/Event2.c index 4c7fcd4bd8..d788f7a0eb 100644 --- a/Pal/regression/Event2.c +++ b/Pal/regression/Event2.c @@ -21,16 +21,15 @@ static int thread_func(void* args) { int main(int argc, char** argv) { pal_printf("Enter main thread\n"); - PAL_HANDLE thd1; - - event1 = DkNotificationEventCreate(0); - if (!event1) { + int ret = DkNotificationEventCreate(0, &event1); + if (ret < 0 || !event1) { pal_printf("DkNotificationEventCreate failed\n"); return -1; } - thd1 = DkThreadCreate(&thread_func, 0); - if (!thd1) { + PAL_HANDLE thd1; + ret = DkThreadCreate(&thread_func, 0, &thd1); + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); return -1; } diff --git a/Pal/regression/Failure.c b/Pal/regression/Failure.c deleted file mode 100644 index 8fbfefecbb..0000000000 --- a/Pal/regression/Failure.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#include "pal.h" -#include "pal_debug.h" -#include "pal_error.h" - -int handled = 0; - -static void FailureHandler(bool is_in_pal, PAL_NUM arg, PAL_CONTEXT* context) { - __UNUSED(is_in_pal); - - pal_printf("Failure notified: %s\n", pal_strerror((unsigned long)arg)); - - handled = 1; -} - -int main(int argc, char** argv, char** envp) { - pal_printf("Enter Main Thread\n"); - - DkSetExceptionHandler(FailureHandler, PAL_EVENT_FAILURE); - - PAL_HANDLE out = DkStreamOpen("foo:unknown", PAL_ACCESS_WRONLY, 0, 0, 0); - - if (!out && !handled) { - pal_printf("DkStreamOpen failed\n"); - return -1; - } - - pal_printf("Leave Main Thread\n"); - return 0; -} diff --git a/Pal/regression/File.c b/Pal/regression/File.c index 36fccb4bf1..ab5e40c3f8 100644 --- a/Pal/regression/File.c +++ b/Pal/regression/File.c @@ -24,46 +24,55 @@ int main(int argc, char** argv, char** envp) { /* test regular file opening */ - PAL_HANDLE file1 = DkStreamOpen("file:File", PAL_ACCESS_RDWR, 0, 0, 0); - if (file1) { + PAL_HANDLE file1 = NULL; + ret = DkStreamOpen("file:File", PAL_ACCESS_RDWR, 0, 0, 0, &file1); + if (ret >= 0 && file1) { pal_printf("File Open Test 1 OK\n"); /* test file read */ - - ret = DkStreamRead(file1, 0, 40, buffer1, NULL, 0); - if (ret > 0) { - print_hex("Read Test 1 (0th - 40th): %s\n", buffer1, 40); + size_t size = sizeof(buffer1); + ret = DkStreamRead(file1, 0, &size, buffer1, NULL, 0); + if (ret == 0 && size == sizeof(buffer1)) { + print_hex("Read Test 1 (0th - 40th): %s\n", buffer1, size); } - ret = DkStreamRead(file1, 0, 40, buffer1, NULL, 0); - if (ret > 0) { - print_hex("Read Test 2 (0th - 40th): %s\n", buffer1, 40); + size = sizeof(buffer1); + ret = DkStreamRead(file1, 0, &size, buffer1, NULL, 0); + if (ret == 0 && size == sizeof(buffer1)) { + print_hex("Read Test 2 (0th - 40th): %s\n", buffer1, size); } - ret = DkStreamRead(file1, 200, 40, buffer2, NULL, 0); - if (ret > 0) { - print_hex("Read Test 3 (200th - 240th): %s\n", buffer2, 40); + size = sizeof(buffer2); + ret = DkStreamRead(file1, 200, &size, buffer2, NULL, 0); + if (ret == 0 && size == sizeof(buffer2)) { + print_hex("Read Test 3 (200th - 240th): %s\n", buffer2, size); } /* test file attribute query */ PAL_STREAM_ATTR attr1; - if (DkStreamAttributesQueryByHandle(file1, &attr1)) + ret = DkStreamAttributesQueryByHandle(file1, &attr1); + if (ret >= 0) { pal_printf("Query by Handle: type = %d, size = %ld\n", attr1.handle_type, attr1.pending_size); + } /* test file map */ - void* mem1 = (void*)DkStreamMap(file1, NULL, PAL_PROT_READ | PAL_PROT_WRITECOPY, 0, - PAGE_SIZE); - if (mem1) { + void* mem1 = NULL; + ret = DkStreamMap(file1, &mem1, PAL_PROT_READ | PAL_PROT_WRITECOPY, 0, PAGE_SIZE); + if (ret >= 0 && mem1) { memcpy(buffer1, mem1, 40); print_hex("Map Test 1 (0th - 40th): %s\n", buffer1, 40); memcpy(buffer2, mem1 + 200, 40); print_hex("Map Test 2 (200th - 240th): %s\n", buffer2, 40); - DkStreamUnmap(mem1, PAGE_SIZE); + ret = DkStreamUnmap(mem1, PAGE_SIZE); + if (ret < 0) { + pal_printf("DkStreamUnmap failed\n"); + return 1; + } } else { pal_printf("Map Test 1 & 2: Failed to map buffer\n"); } @@ -71,40 +80,47 @@ int main(int argc, char** argv, char** envp) { DkObjectClose(file1); } - PAL_HANDLE file2 = DkStreamOpen("file:File", PAL_ACCESS_RDWR, 0, 0, 0); - if (file2) { + PAL_HANDLE file2 = NULL; + ret = DkStreamOpen("file:File", PAL_ACCESS_RDWR, 0, 0, 0, &file2); + if (ret >= 0 && file2) { pal_printf("File Open Test 2 OK\n"); DkObjectClose(file2); } - PAL_HANDLE file3 = DkStreamOpen("file:../regression/File", PAL_ACCESS_RDWR, 0, 0, 0); - if (file3) { + PAL_HANDLE file3 = NULL; + ret = DkStreamOpen("file:../regression/File", PAL_ACCESS_RDWR, 0, 0, 0, &file3); + if (ret >= 0 && file3) { pal_printf("File Open Test 3 OK\n"); DkObjectClose(file3); } PAL_STREAM_ATTR attr2; - if (DkStreamAttributesQuery("file:File", &attr2)) + ret = DkStreamAttributesQuery("file:File", &attr2); + if (ret >= 0) { pal_printf("Query: type = %d, size = %ld\n", attr2.handle_type, attr2.pending_size); + } /* test regular file creation */ - PAL_HANDLE file4 = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0); - if (file4) + PAL_HANDLE file4 = NULL; + ret = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0, &file4); + if (ret >= 0 && file4) pal_printf("File Creation Test 1 OK\n"); - PAL_HANDLE file5 = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0); - if (file5) { + PAL_HANDLE file5 = NULL; + ret = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0, &file5); + if (ret >= 0) { DkObjectClose(file5); } else { pal_printf("File Creation Test 2 OK\n"); } - PAL_HANDLE file6 = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, - PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY, 0); - if (file6) { + PAL_HANDLE file6 = NULL; + ret = DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR, + PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY, 0, &file6); + if (ret >= 0 && file6) { pal_printf("File Creation Test 3 OK\n"); DkObjectClose(file6); } @@ -112,28 +128,42 @@ int main(int argc, char** argv, char** envp) { if (file4) { /* test file writing */ - ret = DkStreamWrite(file4, 0, 40, buffer1, NULL); + size_t size = sizeof(buffer1); + ret = DkStreamWrite(file4, 0, &size, buffer1, NULL); if (ret < 0) goto fail_writing; - ret = DkStreamWrite(file4, 0, 40, buffer2, NULL); + size = sizeof(buffer2); + ret = DkStreamWrite(file4, 0, &size, buffer2, NULL); if (ret < 0) goto fail_writing; - ret = DkStreamWrite(file4, 200, 40, buffer1, NULL); + size = sizeof(buffer1); + ret = DkStreamWrite(file4, 200, &size, buffer1, NULL); if (ret < 0) goto fail_writing; /* test file truncate */ - DkStreamSetLength(file4, pal_control.alloc_align); + ret = DkStreamSetLength(file4, pal_control.alloc_align); + if (ret < 0) { + goto fail_writing; + } fail_writing: DkObjectClose(file4); + if (ret < 0) { + return 1; + } } - PAL_HANDLE file7 = DkStreamOpen("file:file_delete.tmp", PAL_ACCESS_RDONLY, 0, 0, 0); - if (file7) { - DkStreamDelete(file7, 0); + PAL_HANDLE file7 = NULL; + ret = DkStreamOpen("file:file_delete.tmp", PAL_ACCESS_RDONLY, 0, 0, 0, &file7); + if (ret >= 0 && file7) { + ret = DkStreamDelete(file7, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(file7); } diff --git a/Pal/regression/File2.c b/Pal/regression/File2.c index 8ea7569780..7334cea51e 100644 --- a/Pal/regression/File2.c +++ b/Pal/regression/File2.c @@ -8,41 +8,58 @@ char str[12] = "Hello World"; int main(int argc, char** argv, char** envp) { pal_printf("Enter Main Thread\n"); - PAL_HANDLE out = DkStreamOpen(FILE_URI, PAL_ACCESS_RDWR, PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_R, - PAL_CREATE_TRY, 0); + PAL_HANDLE out = NULL; + int ret = DkStreamOpen(FILE_URI, PAL_ACCESS_RDWR, PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_R, + PAL_CREATE_TRY, 0, &out); - if (out == NULL) { + if (ret < 0) { pal_printf("DkStreamOpen failed\n"); - return -1; + return 1; } - int bytes = DkStreamWrite(out, 0, sizeof(str) - 1, str, NULL); - - if (!bytes) { + size_t bytes = sizeof(str) - 1; + ret = DkStreamWrite(out, 0, &bytes, str, NULL); + if (ret < 0 || bytes != sizeof(str) - 1) { pal_printf("DkStreamWrite failed\n"); - return -1; + return 1; } DkObjectClose(out); - PAL_HANDLE in = DkStreamOpen(FILE_URI, PAL_ACCESS_RDONLY, 0, 0, 0); - - bytes = DkStreamRead(in, 0, sizeof(str), str, NULL, 0); + PAL_HANDLE in = NULL; + ret = DkStreamOpen(FILE_URI, PAL_ACCESS_RDONLY, 0, 0, 0, &in); + if (ret < 0) { + pal_printf("DkStreamOpen failed\n"); + return 1; + } - if (!bytes) { + bytes = sizeof(str); + memset(str, 0, bytes); + ret = DkStreamRead(in, 0, &bytes, str, NULL, 0); + if (ret < 0) { pal_printf("DkStreamRead failed\n"); - return -1; + return 1; } + if (bytes > sizeof(str) - 1) { + pal_printf("DkStreamRead read more than expected\n"); + return 1; + } + str[bytes] = '\0'; pal_printf("%s\n", str); - DkStreamDelete(in, 0); + ret = DkStreamDelete(in, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } - PAL_HANDLE del = DkStreamOpen(FILE_URI, PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE del = NULL; + ret = DkStreamOpen(FILE_URI, PAL_ACCESS_RDWR, 0, 0, 0, &del); - if (del) { - pal_printf("DkStreamDelete failed\n"); - return -1; + if (ret >= 0) { + pal_printf("DkStreamDelete did not actually delete\n"); + return 1; } pal_printf("Leave Main Thread\n"); diff --git a/Pal/regression/HelloWorld.c b/Pal/regression/HelloWorld.c index 2536d357ee..d55d8a6886 100644 --- a/Pal/regression/HelloWorld.c +++ b/Pal/regression/HelloWorld.c @@ -6,18 +6,20 @@ char str[13] = "Hello World\n"; int main(int argc, char** argv, char** envp) { pal_printf("start program: %s\n", pal_control.executable); - PAL_HANDLE out = DkStreamOpen("dev:tty", PAL_ACCESS_WRONLY, 0, 0, 0); + PAL_HANDLE out = NULL; + int ret = DkStreamOpen("dev:tty", PAL_ACCESS_WRONLY, 0, 0, 0, &out); - if (out == NULL) { + if (ret < 0) { pal_printf("DkStreamOpen failed\n"); - return -1; + return 1; } - int bytes = DkStreamWrite(out, 0, sizeof(str) - 1, str, NULL); + size_t bytes = sizeof(str) - 1; + ret = DkStreamWrite(out, 0, &bytes, str, NULL); - if (bytes < 0) { + if (ret < 0 || bytes != sizeof(str) - 1) { pal_printf("DkStreamWrite failed\n"); - return -1; + return 1; } DkObjectClose(out); diff --git a/Pal/regression/Makefile b/Pal/regression/Makefile index 20ba0a25e5..72f2f42146 100644 --- a/Pal/regression/Makefile +++ b/Pal/regression/Makefile @@ -30,7 +30,6 @@ executables = \ Event \ Event2 \ Exit \ - Failure \ File \ File2 \ HelloWorld \ diff --git a/Pal/regression/Memory.c b/Pal/regression/Memory.c index d8de4020bf..af79eb3e0d 100644 --- a/Pal/regression/Memory.c +++ b/Pal/regression/Memory.c @@ -29,28 +29,36 @@ int main(int argc, char** argv, char** envp) { volatile int c; DkSetExceptionHandler(handler, PAL_EVENT_MEMFAULT); - void* mem1 = (void*)DkVirtualMemoryAlloc(NULL, UNIT * 4, 0, PAL_PROT_READ | PAL_PROT_WRITE); + void* mem1 = NULL; + int ret = DkVirtualMemoryAlloc(&mem1, UNIT * 4, 0, PAL_PROT_READ | PAL_PROT_WRITE); - if (mem1) + if (!ret && mem1) pal_printf("Memory Allocation OK\n"); - void* mem2 = (void*)DkVirtualMemoryAlloc(NULL, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); + void* mem2 = NULL; + ret = DkVirtualMemoryAlloc(&mem2, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); - if (mem2) { + if (!ret && mem2) { c = count; *(volatile int*)mem2 = 0; pal_printf("(int *) %p = %d\n", mem2, *(volatile int*)mem2); if (c == count) pal_printf("Memory Allocation Protection (RW) OK\n"); - DkVirtualMemoryProtect(mem2, UNIT, PAL_PROT_READ); + if (DkVirtualMemoryProtect(mem2, UNIT, PAL_PROT_READ) < 0) { + pal_printf("DkVirtualMemoryProtect on `mem2` failed\n"); + return 1; + } c = count; *(volatile int*)mem2 = 0; __asm__ volatile("nop"); if (c == count - 1) pal_printf("Memory Protection (R) OK\n"); - DkVirtualMemoryFree(mem2, UNIT); + if (DkVirtualMemoryFree(mem2, UNIT) < 0) { + pal_printf("DkVirtualMemoryFree on `mem2` failed\n"); + return 1; + } c = count; *(volatile int*)mem2 = 0; __asm__ volatile("nop"); @@ -61,10 +69,10 @@ int main(int argc, char** argv, char** envp) { void* mem3 = (void*)pal_control.user_address.start; void* mem4 = (void*)pal_control.user_address.end - UNIT; - mem3 = (void*)DkVirtualMemoryAlloc(mem3, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); - mem4 = (void*)DkVirtualMemoryAlloc(mem4, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); + int ret2 = DkVirtualMemoryAlloc(&mem3, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); + ret = DkVirtualMemoryAlloc(&mem4, UNIT, 0, PAL_PROT_READ | PAL_PROT_WRITE); - if (mem3 && mem4) + if (!ret && !ret2 && mem3 && mem4) pal_printf("Memory Allocation with Address OK\n"); /* Testing total memory */ diff --git a/Pal/regression/Misc.c b/Pal/regression/Misc.c index 53c2cdc91f..cdd6279887 100644 --- a/Pal/regression/Misc.c +++ b/Pal/regression/Misc.c @@ -3,8 +3,16 @@ #include "pal_debug.h" int main(int argc, const char** argv, const char** envp) { - uint64_t time1 = DkSystemTimeQuery(); - uint64_t time2 = DkSystemTimeQuery(); + uint64_t time1 = 0; + if (DkSystemTimeQuery(&time1) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } + uint64_t time2 = 0; + if (DkSystemTimeQuery(&time2) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("Time Query 1: %ld\n", time1); pal_printf("Time Query 2: %ld\n", time2); @@ -12,18 +20,34 @@ int main(int argc, const char** argv, const char** envp) { if (time1 <= time2) pal_printf("Query System Time OK\n"); - uint64_t time3 = DkSystemTimeQuery(); + uint64_t time3 = 0; + if (DkSystemTimeQuery(&time3) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } DkThreadDelayExecution(10000); - uint64_t time4 = DkSystemTimeQuery(); + uint64_t time4 = 0; + if (DkSystemTimeQuery(&time4) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("Sleeped %ld Microseconds\n", time4 - time3); if (time3 < time4 && time4 - time3 > 10000) pal_printf("Delay Execution for 10000 Microseconds OK\n"); - uint64_t time5 = DkSystemTimeQuery(); + uint64_t time5 = 0; + if (DkSystemTimeQuery(&time5) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } DkThreadDelayExecution(3000000); - uint64_t time6 = DkSystemTimeQuery(); + uint64_t time6 = 0; + if (DkSystemTimeQuery(&time6) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("Sleeped %ld Microseconds\n", time6 - time5); diff --git a/Pal/regression/Pie.c b/Pal/regression/Pie.c index 2536d357ee..d55d8a6886 100644 --- a/Pal/regression/Pie.c +++ b/Pal/regression/Pie.c @@ -6,18 +6,20 @@ char str[13] = "Hello World\n"; int main(int argc, char** argv, char** envp) { pal_printf("start program: %s\n", pal_control.executable); - PAL_HANDLE out = DkStreamOpen("dev:tty", PAL_ACCESS_WRONLY, 0, 0, 0); + PAL_HANDLE out = NULL; + int ret = DkStreamOpen("dev:tty", PAL_ACCESS_WRONLY, 0, 0, 0, &out); - if (out == NULL) { + if (ret < 0) { pal_printf("DkStreamOpen failed\n"); - return -1; + return 1; } - int bytes = DkStreamWrite(out, 0, sizeof(str) - 1, str, NULL); + size_t bytes = sizeof(str) - 1; + ret = DkStreamWrite(out, 0, &bytes, str, NULL); - if (bytes < 0) { + if (ret < 0 || bytes != sizeof(str) - 1) { pal_printf("DkStreamWrite failed\n"); - return -1; + return 1; } DkObjectClose(out); diff --git a/Pal/regression/Pipe.c b/Pal/regression/Pipe.c index 267ad43f1d..777e4f1028 100644 --- a/Pal/regression/Pipe.c +++ b/Pal/regression/Pipe.c @@ -9,44 +9,52 @@ int main(int argc, char** argv, char** envp) { char buffer4[20]; int ret; - PAL_HANDLE pipe1 = DkStreamOpen("pipe.srv:1", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE pipe1 = NULL; + ret = DkStreamOpen("pipe.srv:1", PAL_ACCESS_RDWR, 0, 0, 0, &pipe1); - if (pipe1) { + if (ret >= 0 && pipe1) { pal_printf("Pipe Creation 1 OK\n"); // DEP 10/24/16: Try to read some attributes of the pipe PAL_STREAM_ATTR attr; - if (!DkStreamAttributesQueryByHandle(pipe1, &attr)) { + ret = DkStreamAttributesQueryByHandle(pipe1, &attr); + if (ret < 0) { pal_printf("Failed to get any attributes from the pipesrv\n"); - return -1; + return 1; } else { pal_printf("Pipe Attribute Query 1 on pipesrv returned OK\n"); } // DEP: would be nice to sanity check the attributes. // Job for another day... - PAL_HANDLE pipe2 = DkStreamOpen("pipe:1", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE pipe2 = NULL; + ret = DkStreamOpen("pipe:1", PAL_ACCESS_RDWR, 0, 0, 0, &pipe2); - if (pipe2) { - PAL_HANDLE pipe3 = DkStreamWaitForClient(pipe1); + if (ret >= 0 && pipe2) { + PAL_HANDLE pipe3 = NULL; + ret = DkStreamWaitForClient(pipe1, &pipe3); - if (pipe3) { + if (ret >= 0 && pipe3) { pal_printf("Pipe Connection 1 OK\n"); - ret = DkStreamWrite(pipe3, 0, 20, buffer1, NULL); - if (ret > 0) + size_t size = sizeof(buffer1); + ret = DkStreamWrite(pipe3, 0, &size, buffer1, NULL); + if (ret == 0 && size > 0) pal_printf("Pipe Write 1 OK\n"); - ret = DkStreamRead(pipe2, 0, 20, buffer3, NULL, 0); - if (ret > 0) + size = sizeof(buffer3); + ret = DkStreamRead(pipe2, 0, &size, buffer3, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Pipe Read 1: %s\n", buffer3); - ret = DkStreamWrite(pipe2, 0, 20, buffer2, NULL); - if (ret > 0) + size = sizeof(buffer2); + ret = DkStreamWrite(pipe2, 0, &size, buffer2, NULL); + if (ret == 0 && size > 0) pal_printf("Pipe Write 2 OK\n"); - ret = DkStreamRead(pipe3, 0, 20, buffer4, NULL, 0); - if (ret > 0) + size = sizeof(buffer4); + ret = DkStreamRead(pipe3, 0, &size, buffer4, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Pipe Read 2: %s\n", buffer4); } } diff --git a/Pal/regression/Process.c b/Pal/regression/Process.c index 35af22aaee..07ff41bc12 100644 --- a/Pal/regression/Process.c +++ b/Pal/regression/Process.c @@ -6,6 +6,7 @@ int main(int argc, char** argv, char** envp) { char buffer1[20] = "Hello World 1", buffer2[20] = "Hello World 2"; char buffer3[20], buffer4[20]; int ret; + size_t size; if (argc > 1 && !memcmp(argv[1], "Child", 6)) { pal_printf("Child Process Created\n"); @@ -16,39 +17,45 @@ int main(int argc, char** argv, char** envp) { pal_printf("argv[%d] = %s\n", i, argv[i]); } - DkStreamWrite(pal_control.parent_process, 0, 20, buffer1, NULL); + size = sizeof(buffer1); + DkStreamWrite(pal_control.parent_process, 0, &size, buffer1, NULL); - ret = DkStreamWrite(pal_control.parent_process, 0, 20, buffer1, NULL); - if (ret > 0) + size = sizeof(buffer1); + ret = DkStreamWrite(pal_control.parent_process, 0, &size, buffer1, NULL); + if (ret == 0 && size > 0) pal_printf("Process Write 1 OK\n"); - ret = DkStreamRead(pal_control.parent_process, 0, 20, buffer4, NULL, 0); - if (ret > 0) + size = sizeof(buffer4); + ret = DkStreamRead(pal_control.parent_process, 0, &size, buffer4, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Process Read 2: %s\n", buffer4); } else { PAL_STR args[3] = {"Process", "Child", 0}; - PAL_HANDLE children[3]; + PAL_HANDLE children[3] = { 0 }; for (int i = 0; i < 3; i++) { pal_printf("Creating process\n"); - children[i] = DkProcessCreate("file:Process", args); + ret = DkProcessCreate("file:Process", args, &children[i]); - if (children[i]) { + if (ret == 0 && children[i]) { pal_printf("Process created %d\n", i + 1); - DkStreamRead(children[i], 0, 20, buffer4, NULL, 0); + size = sizeof(buffer4); + DkStreamRead(children[i], 0, &size, buffer4, NULL, 0); } } for (int i = 0; i < 3; i++) if (children[i]) { - ret = DkStreamRead(children[i], 0, 20, buffer3, NULL, 0); - if (ret > 0) + size = sizeof(buffer3); + ret = DkStreamRead(children[i], 0, &size, buffer3, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Process Read 1: %s\n", buffer3); - ret = DkStreamWrite(children[i], 0, 20, buffer2, NULL); - if (ret > 0) + size = sizeof(buffer2); + ret = DkStreamWrite(children[i], 0, &size, buffer2, NULL); + if (ret == 0 && size > 0) pal_printf("Process Write 2 OK\n"); } } diff --git a/Pal/regression/Process2.c b/Pal/regression/Process2.c index 2ee1e99779..cf5b2a45b2 100644 --- a/Pal/regression/Process2.c +++ b/Pal/regression/Process2.c @@ -4,7 +4,8 @@ int main(int argc, char** argv, char** envp) { PAL_STR args[1] = {0}; - if (DkProcessCreate("file:Bootstrap", args) == NULL) + PAL_HANDLE handle = NULL; + if (DkProcessCreate("file:Bootstrap", args, &handle) < 0) return 1; return 0; } diff --git a/Pal/regression/Process3.c b/Pal/regression/Process3.c index 47cad58f3c..d8cd2dc79a 100644 --- a/Pal/regression/Process3.c +++ b/Pal/regression/Process3.c @@ -7,9 +7,10 @@ int main(int argc, char** argv, char** envp) { // Hack to differentiate parent from child if (argc == 1) { - PAL_HANDLE child = DkProcessCreate(pal_control.executable, args); + PAL_HANDLE child = NULL; + int ret = DkProcessCreate(pal_control.executable, args, &child); - if (child) + if (ret == 0 && child) pal_printf("Creating child OK\n"); } diff --git a/Pal/regression/Process4.c b/Pal/regression/Process4.c index 625de8314b..d5080206cf 100644 --- a/Pal/regression/Process4.c +++ b/Pal/regression/Process4.c @@ -12,15 +12,20 @@ int main(int argc, char** argv) { pal_printf("\n"); if (argc == 1) { - uint64_t time = DkSystemTimeQuery(); + uint64_t time = 0; + if (DkSystemTimeQuery(&time) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } char time_arg[24]; snprintf(time_arg, 24, "%ld", time); const char* newargs[4] = {"Process4", "0", time_arg, NULL}; - PAL_HANDLE proc = DkProcessCreate("file:Process4", newargs); + PAL_HANDLE proc = NULL; + int ret = DkProcessCreate("file:Process4", newargs, &proc); - if (!proc) + if (ret < 0) pal_printf("Can't create process\n"); DkObjectClose(proc); @@ -35,14 +40,19 @@ int main(int argc, char** argv) { snprintf(count_arg, 8, "%d", count); const char* newargs[4] = {"Process4", count_arg, argv[2], NULL}; - PAL_HANDLE proc = DkProcessCreate("file:Process4", newargs); + PAL_HANDLE proc = NULL; + int ret = DkProcessCreate("file:Process4", newargs, &proc); - if (!proc) + if (ret < 0) pal_printf("Can't create process\n"); DkObjectClose(proc); } else { - uint64_t end = DkSystemTimeQuery(); + uint64_t end = 0; + if (DkSystemTimeQuery(&end) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } uint64_t start = atol(argv[2]); pal_printf("wall time = %ld\n", end - start); } diff --git a/Pal/regression/Segment.c b/Pal/regression/Segment.c index 377e38e64f..1519bd5a3e 100644 --- a/Pal/regression/Segment.c +++ b/Pal/regression/Segment.c @@ -4,7 +4,7 @@ void* dummy = &dummy; int main(int argc, char** argv, char** envp) { - if (!DkSegmentRegisterSet(PAL_SEGMENT_FS, dummy)) { + if (DkSegmentRegisterSet(PAL_SEGMENT_FS, dummy) < 0) { pal_printf("Error setting FS\n"); return 1; } diff --git a/Pal/regression/Select.c b/Pal/regression/Select.c index 3a8df9e109..eadf36df80 100644 --- a/Pal/regression/Select.c +++ b/Pal/regression/Select.c @@ -10,7 +10,8 @@ static int thread_func(void* args) { pal_printf("Thread sets event\n"); char byte = 0; - DkStreamWrite(wakeup, 0, 1, &byte, NULL); + size_t size = 1; + DkStreamWrite(wakeup, 0, &size, &byte, NULL); pal_printf("Leave thread\n"); return 0; @@ -20,15 +21,28 @@ int main(int argc, char** argv) { pal_printf("Enter main thread\n"); PAL_HANDLE handles[3]; - handles[0] = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0); - handles[1] = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0); - handles[2] = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0); - wakeup = handles[2]; + int ret = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0, &handles[0]); + if (ret < 0) { + pal_printf("DkStreamOpen failed\n"); + return 1; + } + ret = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0, &handles[1]); + if (ret < 0) { + pal_printf("DkStreamOpen failed\n"); + return 1; + } + ret = DkStreamOpen("pipe:", PAL_ACCESS_RDWR, 0, 0, 0, &handles[2]); + if (ret < 0) { + pal_printf("DkStreamOpen failed\n"); + return 1; + } + wakeup = handles[2]; - PAL_HANDLE thd = DkThreadCreate(&thread_func, NULL); - if (!thd) { + PAL_HANDLE thd = NULL; + ret = DkThreadCreate(&thread_func, NULL, &thd); + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); - return -1; + return 1; } pal_printf("Waiting on event\n"); @@ -36,10 +50,10 @@ int main(int argc, char** argv) { PAL_FLG events[3] = {PAL_WAIT_READ, PAL_WAIT_READ, PAL_WAIT_READ}; PAL_FLG revents[3] = {0, 0, 0}; - PAL_BOL polled = DkStreamsWaitEvents(3, handles, events, revents, NO_TIMEOUT); - if (!polled) { + ret = DkStreamsWaitEvents(3, handles, events, revents, NO_TIMEOUT); + if (ret < 0) { pal_printf("DkStreamsWaitEvents did not return any events\n"); - return -1; + return 1; } if (revents[2]) diff --git a/Pal/regression/Semaphore.c b/Pal/regression/Semaphore.c index 9b4fc993d2..d3e53e438e 100644 --- a/Pal/regression/Semaphore.c +++ b/Pal/regression/Semaphore.c @@ -1,23 +1,28 @@ #include "api.h" #include "pal.h" #include "pal_debug.h" +#include "pal_error.h" static void helper_timeout(PAL_NUM timeout) { /* Create a binary semaphore */ - PAL_HANDLE sem1 = DkMutexCreate(1); + PAL_HANDLE sem1; + int ret = DkMutexCreate(1, &sem1); - if (!sem1) { + if (ret < 0) { pal_printf("Failed to create a binary semaphore\n"); return; } /* Wait on the binary semaphore with a timeout */ - PAL_BOL rv = DkSynchronizationObjectWait(sem1, timeout); - if (rv == PAL_FALSE) + ret = DkSynchronizationObjectWait(sem1, timeout); + if (ret == -PAL_ERROR_TRYAGAIN) { pal_printf("Locked binary semaphore timed out (%ld).\n", timeout); - else + } else if (ret == 0) { pal_printf("Acquired locked binary semaphore!?! sem1 is %p (%ld)\n", sem1, timeout); + } else { + pal_printf("Binary semaphore error: %d, sem1 is %p (%ld)\n", ret, sem1, timeout); + } DkObjectClose(sem1); } @@ -25,16 +30,17 @@ static void helper_timeout(PAL_NUM timeout) { static void helper_success(PAL_NUM timeout) { /* Create a binary semaphore */ - PAL_HANDLE sem1 = DkMutexCreate(0); + PAL_HANDLE sem1; + int ret = DkMutexCreate(0, &sem1); - if (!sem1) { + if (ret < 0) { pal_printf("Failed to create a binary semaphore\n"); return; } /* Wait on the binary semaphore with a timeout */ - PAL_BOL rv = DkSynchronizationObjectWait(sem1, timeout); - if (rv == PAL_TRUE) + ret = DkSynchronizationObjectWait(sem1, timeout); + if (ret == 0) pal_printf("Locked binary semaphore successfully (%ld).\n", timeout); else pal_printf("Failed to lock binary semaphore: sem1 is %p\n", sem1); diff --git a/Pal/regression/SendHandle.c b/Pal/regression/SendHandle.c index 44bf9a8cc6..54c57dbbe4 100644 --- a/Pal/regression/SendHandle.c +++ b/Pal/regression/SendHandle.c @@ -3,14 +3,17 @@ #include "pal_debug.h" int main(int argc, char** argv) { + int ret; + size_t size; PAL_HANDLE handles[3]; if (argc == 2 && !memcmp(argv[1], "Child", 6)) { char buffer[20]; for (int i = 0; i < 3; i++) { - handles[i] = DkReceiveHandle(pal_control.parent_process); - if (handles[i]) { + handles[i] = NULL; + ret = DkReceiveHandle(pal_control.parent_process, &handles[i]); + if (ret >= 0 && handles[i]) { pal_printf("Receive Handle OK\n"); } else { continue; @@ -20,10 +23,13 @@ int main(int argc, char** argv) { switch (PAL_GET_TYPE(handles[i])) { case pal_type_pipesrv: { - PAL_HANDLE pipe = DkStreamWaitForClient(handles[i]); + PAL_HANDLE pipe = NULL; + ret = DkStreamWaitForClient(handles[i], &pipe); - if (pipe) { - if (DkStreamRead(pipe, 0, 20, buffer, NULL, 0)) + if (ret >= 0 && pipe) { + size = sizeof(buffer); + ret = DkStreamRead(pipe, 0, &size, buffer, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Receive Pipe Handle: %s\n", buffer); DkObjectClose(pipe); @@ -35,14 +41,18 @@ int main(int argc, char** argv) { case pal_type_udpsrv: { char uri[20]; - if ((DkStreamRead(handles[i], 0, 20, buffer, &uri, 20))) + size = sizeof(buffer); + ret = DkStreamRead(handles[i], 0, &size, buffer, &uri, sizeof(uri)); + if (ret == 0 && size > 0) pal_printf("Receive Socket Handle: %s\n", buffer); break; } case pal_type_file: - if (DkStreamRead(handles[i], 0, 20, buffer, NULL, 0)) + size = sizeof(buffer); + ret = DkStreamRead(handles[i], 0, &size, buffer, NULL, 0); + if (ret == 0 && size > 0) pal_printf("Receive File Handle: %s\n", buffer); break; @@ -56,20 +66,24 @@ int main(int argc, char** argv) { } else { const char* args[3] = {"SendHandle", "Child", NULL}; - PAL_HANDLE child = DkProcessCreate("file:SendHandle", args); + PAL_HANDLE child = NULL; + ret = DkProcessCreate("file:SendHandle", args, &child); - if (child) { + if (ret >= 0 && child) { // Sending pipe handle - handles[0] = DkStreamOpen("pipe.srv:1", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0); + ret = DkStreamOpen("pipe.srv:1", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0, &handles[0]); - if (handles[0]) { + if (ret >= 0 && handles[0]) { pal_printf("Send Handle OK\n"); - if (DkSendHandle(child, handles[0])) { + if (DkSendHandle(child, handles[0]) >= 0) { DkObjectClose(handles[0]); - PAL_HANDLE pipe = DkStreamOpen("pipe:1", PAL_ACCESS_RDWR, 0, 0, 0); - if (pipe) { - DkStreamWrite(pipe, 0, 20, "Hello World", NULL); + PAL_HANDLE pipe = NULL; + ret = DkStreamOpen("pipe:1", PAL_ACCESS_RDWR, 0, 0, 0, &pipe); + if (ret >= 0 && pipe) { + char buf[20] = "Hello World"; + size_t buf_size = sizeof(buf); + DkStreamWrite(pipe, 0, &buf_size, buf, NULL); DkObjectClose(pipe); } } else { @@ -78,18 +92,20 @@ int main(int argc, char** argv) { } // Sending udp handle - handles[1] = - DkStreamOpen("udp.srv:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0); + ret = DkStreamOpen("udp.srv:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0, + &handles[1]); - if (handles[1]) { + if (ret >= 0 && handles[1]) { pal_printf("Send Handle OK\n"); - if (DkSendHandle(child, handles[1])) { + if (DkSendHandle(child, handles[1]) >= 0) { DkObjectClose(handles[1]); - PAL_HANDLE socket = - DkStreamOpen("udp:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, 0, 0); - if (socket) { - DkStreamWrite(socket, 0, 20, "Hello World", NULL); + PAL_HANDLE socket = NULL; + ret = DkStreamOpen("udp:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, 0, 0, &socket); + if (ret >= 0 && socket) { + char buf[20] = "Hello World"; + size_t buf_size = sizeof(buf); + DkStreamWrite(socket, 0, &buf_size, buf, NULL); DkObjectClose(socket); } } else { @@ -97,12 +113,15 @@ int main(int argc, char** argv) { } } - handles[2] = DkStreamOpen("file:to_send.tmp", PAL_ACCESS_RDWR, 0600, PAL_CREATE_TRY, 0); + ret = DkStreamOpen("file:to_send.tmp", PAL_ACCESS_RDWR, 0600, PAL_CREATE_TRY, 0, + &handles[2]); - if (handles[2]) { + if (ret >= 0 && handles[2]) { pal_printf("Send Handle OK\n"); - DkStreamWrite(handles[2], 0, 20, "Hello World", NULL); + char buf[20] = "Hello World"; + size_t buf_size = sizeof(buf); + DkStreamWrite(handles[2], 0, &buf_size, buf, NULL); DkStreamSetLength(handles[2], 4096); DkSendHandle(child, handles[2]); diff --git a/Pal/regression/Socket.c b/Pal/regression/Socket.c index e0e0ec3ff2..09a2bb62f9 100644 --- a/Pal/regression/Socket.c +++ b/Pal/regression/Socket.c @@ -6,37 +6,45 @@ int main(int argc, char** argv, char** envp) { char buffer1[20] = "Hello World 1", buffer2[20] = "Hello World 2"; char buffer3[20], buffer4[20]; int ret; + size_t size; memset(buffer3, 0, 20); memset(buffer4, 0, 20); - PAL_HANDLE tcp1 = DkStreamOpen("tcp.srv:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE tcp1 = NULL; + ret = DkStreamOpen("tcp.srv:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0, &tcp1); - if (tcp1) { + if (ret >= 0 && tcp1) { pal_printf("TCP Creation 1 OK\n"); - PAL_HANDLE tcp2 = DkStreamOpen("tcp:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE tcp2 = NULL; + ret = DkStreamOpen("tcp:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0, &tcp2); - if (tcp2) { - PAL_HANDLE tcp3 = DkStreamWaitForClient(tcp1); + if (ret >= 0 && tcp2) { + PAL_HANDLE tcp3 = NULL; + ret = DkStreamWaitForClient(tcp1, &tcp3); - if (tcp3) { + if (ret >= 0 && tcp3) { pal_printf("TCP Connection 1 OK\n"); - ret = DkStreamWrite(tcp3, 0, 20, buffer1, NULL); - if (ret > 0) + size = sizeof(buffer1); + ret = DkStreamWrite(tcp3, 0, &size, buffer1, NULL); + if (ret == 0 && size > 0) pal_printf("TCP Write 1 OK\n"); - ret = DkStreamRead(tcp2, 0, 20, buffer3, NULL, 0); - if (ret > 0) + size = sizeof(buffer3); + ret = DkStreamRead(tcp2, 0, &size, buffer3, NULL, 0); + if (ret == 0 && size > 0) pal_printf("TCP Read 1: %s\n", buffer3); - ret = DkStreamWrite(tcp2, 0, 20, buffer2, NULL); - if (ret > 0) + size = sizeof(buffer2); + ret = DkStreamWrite(tcp2, 0, &size, buffer2, NULL); + if (ret == 0 && size > 0) pal_printf("TCP Write 2 OK\n"); - ret = DkStreamRead(tcp3, 0, 20, buffer4, NULL, 0); - if (ret > 0) + size = sizeof(buffer4); + ret = DkStreamRead(tcp3, 0, &size, buffer4, NULL, 0); + if (ret == 0 && size > 0) pal_printf("TCP Read 2: %s\n", buffer4); DkObjectClose(tcp3); @@ -45,75 +53,93 @@ int main(int argc, char** argv, char** envp) { DkObjectClose(tcp2); } - DkStreamDelete(tcp1, 0); + ret = DkStreamDelete(tcp1, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(tcp1); } - PAL_HANDLE udp1 = DkStreamOpen("udp.srv:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE udp1 = NULL; + ret = DkStreamOpen("udp.srv:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0, &udp1); - if (udp1) { + if (ret >= 0 && udp1) { pal_printf("UDP Creation 1 OK\n"); - PAL_HANDLE udp2 = DkStreamOpen("udp:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE udp2 = NULL; + ret = DkStreamOpen("udp:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0, &udp2); - if (udp2) { + if (ret >= 0 && udp2) { pal_printf("UDP Connection 1 OK\n"); memset(buffer3, 0, 20); memset(buffer4, 0, 20); - ret = DkStreamWrite(udp2, 0, 20, buffer1, NULL); - if (ret > 0) + size = sizeof(buffer1); + ret = DkStreamWrite(udp2, 0, &size, buffer1, NULL); + if (ret == 0 && size > 0) pal_printf("UDP Write 1 OK\n"); char uri[20]; - ret = DkStreamRead(udp1, 0, 20, buffer3, uri, 20); - if (ret > 0) + size = sizeof(buffer3); + ret = DkStreamRead(udp1, 0, &size, buffer3, uri, sizeof(uri)); + if (ret == 0 && size > 0) pal_printf("UDP Read 1: %s\n", buffer3); - ret = DkStreamWrite(udp1, 0, 20, buffer2, uri); - if (ret > 0) + size = sizeof(buffer2); + ret = DkStreamWrite(udp1, 0, &size, buffer2, uri); + if (ret == 0 && size > 0) pal_printf("UDP Write 2 OK\n"); - ret = DkStreamRead(udp2, 0, 20, buffer4, NULL, 0); - if (ret > 0) + size = sizeof(buffer4); + ret = DkStreamRead(udp2, 0, &size, buffer4, NULL, 0); + if (ret == 0 && size > 0) pal_printf("UDP Read 2: %s\n", buffer4); DkObjectClose(udp2); } - PAL_HANDLE udp3 = - DkStreamOpen("udp:127.0.0.1:3001:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0); + PAL_HANDLE udp3 = NULL; + ret = DkStreamOpen("udp:127.0.0.1:3001:127.0.0.1:3000", PAL_ACCESS_RDWR, 0, 0, 0, &udp3); - if (udp3) { + if (ret >= 0 && udp3) { pal_printf("UDP Connection 2 OK\n"); memset(buffer3, 0, 20); memset(buffer4, 0, 20); - ret = DkStreamWrite(udp3, 0, 20, buffer1, NULL); - if (ret > 0) + size = sizeof(buffer1); + ret = DkStreamWrite(udp3, 0, &size, buffer1, NULL); + if (ret == 0 && size > 0) pal_printf("UDP Write 3 OK\n"); char uri[20]; - ret = DkStreamRead(udp1, 0, 20, buffer3, uri, 20); - if (ret > 0) + size = sizeof(buffer3); + ret = DkStreamRead(udp1, 0, &size, buffer3, uri, sizeof(uri)); + if (ret == 0 && size > 0) pal_printf("UDP Read 3: %s\n", buffer3); - ret = DkStreamWrite(udp1, 0, 20, buffer2, "udp:127.0.0.1:3001"); - if (ret > 0) + size = sizeof(buffer2); + ret = DkStreamWrite(udp1, 0, &size, buffer2, "udp:127.0.0.1:3001"); + if (ret == 0 && size > 0) pal_printf("UDP Write 4 OK\n"); - ret = DkStreamRead(udp3, 0, 20, buffer4, NULL, 0); - if (ret > 0) + size = sizeof(buffer4); + ret = DkStreamRead(udp3, 0, &size, buffer4, NULL, 0); + if (ret == 0 && size > 0) pal_printf("UDP Read 4: %s\n", buffer4); DkObjectClose(udp3); } - DkStreamDelete(udp1, 0); + ret = DkStreamDelete(udp1, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(udp1); } diff --git a/Pal/regression/Tcp.c b/Pal/regression/Tcp.c index 4f948b36ca..e202082181 100644 --- a/Pal/regression/Tcp.c +++ b/Pal/regression/Tcp.c @@ -11,85 +11,139 @@ char buffer[12]; int main(int argc, char** argv) { int i; + int ret; if (argc == 1) { - unsigned long time = DkSystemTimeQuery(); + unsigned long time = 0; + if (DkSystemTimeQuery(&time) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("start time = %lu\n", time); snprintf(time_arg, 24, "%ld", time); const char* newargs[4] = {"Tcp", time_arg, NULL}; - PAL_HANDLE srv = DkStreamOpen("tcp.srv:127.0.0.1:8000", 0, 0, 0, 0); + PAL_HANDLE srv = NULL; + ret = DkStreamOpen("tcp.srv:127.0.0.1:8000", 0, 0, 0, 0, &srv); - if (!srv) { + if (ret < 0) { pal_printf("not able to create server\n"); - return -1; + return 1; } - DkStreamGetName(srv, addr, 40); + ret = DkStreamGetName(srv, addr, sizeof(addr)); + if (ret < 0) { + pal_printf("DkStreamGetName failed\n"); + return 1; + } pal_printf("server bound on %s\n", addr); - PAL_HANDLE proc = DkProcessCreate("file:Tcp", newargs); + PAL_HANDLE proc = NULL; + if (DkProcessCreate("file:Tcp", newargs, &proc) < 0) { + pal_printf("Tcp: DkProcessCreate failed\n"); + return 1; + } for (i = 0; i < NTRIES; i++) { - PAL_HANDLE cli = DkStreamWaitForClient(srv); + PAL_HANDLE cli = NULL; + ret = DkStreamWaitForClient(srv, &cli); - if (!cli) { + if (ret < 0) { pal_printf("not able to accept client\n"); - return -1; + return 1; } - DkStreamGetName(cli, addr, 40); + ret = DkStreamGetName(cli, addr, sizeof(addr)); + if (ret < 0) { + pal_printf("DkStreamGetName failed\n"); + return 1; + } pal_printf("client accepted on %s\n", addr); - int bytes = DkStreamWrite(cli, 0, 12, "Hello World", NULL); + char buf[12] = "Hello World"; + size_t buf_size = sizeof(buf); + ret = DkStreamWrite(cli, 0, &buf_size, buf, NULL); - if (!bytes) { + if (ret < 0 || buf_size != sizeof(buf)) { pal_printf("not able to send to client\n"); - return -1; + return 1; } DkObjectClose(cli); } int retval; - DkStreamRead(proc, 0, sizeof(int), &retval, NULL, 0); - DkStreamDelete(srv, 0); + size_t retval_size = sizeof(retval); + ret = DkStreamRead(proc, 0, &retval_size, &retval, NULL, 0); + if (ret < 0) { + pal_printf("DkStreamRead failed\n"); + return 1; + } + if (retval_size != sizeof(retval)) { + pal_printf("DkStreamRead - short read\n"); + return 1; + } + + ret = DkStreamDelete(srv, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(srv); } else { for (i = 0; i < NTRIES; i++) { - PAL_HANDLE cli = DkStreamOpen("tcp:127.0.0.1:8000", 0, 0, 0, 0); + PAL_HANDLE cli = NULL; + ret = DkStreamOpen("tcp:127.0.0.1:8000", 0, 0, 0, 0, &cli); - if (!cli) { + if (ret < 0) { pal_printf("not able to create client\n"); - return -1; + return 1; } - DkStreamGetName(cli, addr, 40); + ret = DkStreamGetName(cli, addr, sizeof(addr)); + if (ret < 0) { + pal_printf("DkStreamGetName failed\n"); + return 1; + } pal_printf("client connected on %s\n", addr); - int bytes = DkStreamRead(cli, 0, 12, buffer, NULL, 0); + size_t bytes = sizeof(buffer); + ret = DkStreamRead(cli, 0, &bytes, buffer, NULL, 0); - if (!bytes) { + if (ret < 0 || bytes == 0) { pal_printf("not able to receive from server\n"); - return -1; + return 1; } pal_printf("read from server: %s\n", buffer); - DkStreamDelete(cli, 0); + ret = DkStreamDelete(cli, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(cli); } - unsigned long end = DkSystemTimeQuery(); + unsigned long end = 0; + if (DkSystemTimeQuery(&end) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("end time = %lu\n", end); unsigned long start = atol(argv[1]); pal_printf("wall time = %ld\n", end - start); int retval = 0; - DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &retval, NULL); + size_t retval_size = sizeof(retval); + ret = DkStreamWrite(pal_control.parent_process, 0, &retval_size, &retval, NULL); + if (ret < 0 || retval_size != sizeof(retval)) { + pal_printf("DkStreamWrite failed\n"); + return 1; + } } return 0; diff --git a/Pal/regression/Thread.c b/Pal/regression/Thread.c index 1be81df301..6fee75fe62 100644 --- a/Pal/regression/Thread.c +++ b/Pal/regression/Thread.c @@ -20,7 +20,7 @@ static void callback(void* args) { pal_printf("Threads Run in Parallel OK\n"); - if (!DkSegmentRegisterSet(PAL_SEGMENT_FS, &private2)) { + if (DkSegmentRegisterSet(PAL_SEGMENT_FS, &private2) < 0) { pal_printf("Failed to set FS\n"); DkThreadExit(/*clear_child_tid=*/NULL); } @@ -35,7 +35,7 @@ static void callback(void* args) { } int main() { - if (!DkSegmentRegisterSet(PAL_SEGMENT_FS, &private1)) { + if (DkSegmentRegisterSet(PAL_SEGMENT_FS, &private1) < 0) { pal_printf("Failed to set FS\n"); return 1; } @@ -43,8 +43,9 @@ int main() { __asm__ volatile("mov %%fs:0, %0" : "=r"(ptr1)::"memory"); pal_printf("Private Message (FS Segment) 1: %s\n", ptr1); - PAL_HANDLE thread1 = DkThreadCreate(callback, "Hello World"); - if (!thread1) + PAL_HANDLE thread1 = NULL; + int ret = DkThreadCreate(callback, "Hello World", &thread1); + if (ret < 0) return 1; pal_printf("Child Thread Created\n"); diff --git a/Pal/regression/Thread2.c b/Pal/regression/Thread2.c index 2feef8b9a9..847a306548 100644 --- a/Pal/regression/Thread2.c +++ b/Pal/regression/Thread2.c @@ -52,8 +52,9 @@ static int thread4_run(void* args) { int main(void) { pal_printf("Thread 1 (main) started.\n"); - PAL_HANDLE thread2 = DkThreadCreate(thread2_run, NULL); - if (!thread2) { + PAL_HANDLE thread2 = NULL; + int ret = DkThreadCreate(thread2_run, NULL, &thread2); + if (ret < 0) { pal_printf("DkThreadCreate failed for thread 2.\n"); return 1; } @@ -66,8 +67,9 @@ int main(void) { pal_printf("Thread 2 ok.\n"); } - PAL_HANDLE thread3 = DkThreadCreate(thread3_run, NULL); - if (!thread3) { + PAL_HANDLE thread3 = NULL; + ret = DkThreadCreate(thread3_run, NULL, &thread3); + if (ret < 0) { pal_printf("DkThreadCreate failed for thread 3.\n"); return 1; } @@ -78,8 +80,9 @@ int main(void) { pal_printf("Thread 3 ok.\n"); } - PAL_HANDLE thread4 = DkThreadCreate(thread4_run, NULL); - if (!thread4) { + PAL_HANDLE thread4 = NULL; + ret = DkThreadCreate(thread4_run, NULL, &thread4); + if (ret < 0) { pal_printf("DkThreadCreate failed for thread 4.\n"); return 1; } diff --git a/Pal/regression/Udp.c b/Pal/regression/Udp.c index 0fc4222e20..0ab2ddf492 100644 --- a/Pal/regression/Udp.c +++ b/Pal/regression/Udp.c @@ -9,61 +9,110 @@ char buffer[20]; int main(int argc, char** argv) { int i; + int ret; if (argc == 1) { - unsigned long start = DkSystemTimeQuery(); + unsigned long start = 0; + if (DkSystemTimeQuery(&start) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } const char* newargs[3] = {"Udp", "child", NULL}; - PAL_HANDLE srv = DkStreamOpen("udp.srv:127.0.0.1:8000", 0, 0, 0, 0); + PAL_HANDLE srv = NULL; + ret = DkStreamOpen("udp.srv:127.0.0.1:8000", 0, 0, 0, 0, &srv); - if (!srv) { + if (ret < 0) { pal_printf("not able to create server\n"); - return -1; + return 1; } - DkStreamGetName(srv, addr, 40); + ret = DkStreamGetName(srv, addr, sizeof(addr)); + if (ret < 0) { + pal_printf("DkStreamGetName failed\n"); + return 1; + } pal_printf("server bound on %s\n", addr); - PAL_HANDLE proc = DkProcessCreate("file:Udp", newargs); + PAL_HANDLE proc = NULL; + if (DkProcessCreate("file:Udp", newargs, &proc) < 0) { + pal_printf("Udp: DkProcessCreate failed\n"); + return 1; + } for (i = 0; i < NTRIES; i++) { - int bytes = DkStreamRead(srv, 0, 20, buffer, addr, 40); + size_t bytes = sizeof(buffer); + ret = DkStreamRead(srv, 0, &bytes, buffer, addr, sizeof(addr)); - if (!bytes) { + if (ret < 0 || bytes == 0) { pal_printf("not able to receive from client\n"); - return -1; + return 1; } pal_printf("read on server (from %s): %s\n", addr, buffer); } - unsigned long end = DkSystemTimeQuery(); + unsigned long end = 0; + if (DkSystemTimeQuery(&end) < 0) { + pal_printf("DkSystemTimeQuery failed\n"); + return 1; + } pal_printf("wall time = %ld\n", end - start); int retval; - DkStreamRead(proc, 0, sizeof(int), &retval, NULL, 0); - DkStreamDelete(srv, 0); + size_t retval_size = sizeof(retval); + ret = DkStreamRead(proc, 0, &retval_size, &retval, NULL, 0); + if (ret < 0) { + pal_printf("DkStreamRead failed\n"); + return 1; + } + if (retval_size != sizeof(retval)) { + pal_printf("DkStreamRead - short read\n"); + return 1; + } + + ret = DkStreamDelete(srv, 0); + if (ret < 0) { + pal_printf("DkStreamDelete failed\n"); + return 1; + } DkObjectClose(srv); } else { - PAL_HANDLE cli = DkStreamOpen("udp:127.0.0.1:8000", 0, 0, 0, 0); + PAL_HANDLE cli = NULL; + ret = DkStreamOpen("udp:127.0.0.1:8000", 0, 0, 0, 0, &cli); + if (ret < 0) { + pal_printf("DkStreamOpen failed\n"); + return 1; + } - DkStreamGetName(cli, addr, 40); + ret = DkStreamGetName(cli, addr, sizeof(addr)); + if (ret < 0) { + pal_printf("DkStreamGetName failed\n"); + return 1; + } pal_printf("client connected on %s\n", addr); for (i = 0; i < NTRIES; i++) { - int bytes = DkStreamWrite(cli, 0, 12, "Hello World", NULL); + char buf[12] = "Hello World"; + size_t buf_size = sizeof(buf); + ret = DkStreamWrite(cli, 0, &buf_size, buf, NULL); - if (!bytes) { + if (ret < 0 || buf_size != sizeof(buf)) { pal_printf("not able to send to server\n"); - return -1; + return 1; } } DkObjectClose(cli); int retval = 0; - DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &retval, NULL); + size_t retval_size = sizeof(retval); + ret = DkStreamWrite(pal_control.parent_process, 0, &retval_size, &retval, NULL); + if (ret < 0 || retval_size != sizeof(retval)) { + pal_printf("DkStreamWrite failed\n"); + return 1; + } } return 0; diff --git a/Pal/regression/Wait.c b/Pal/regression/Wait.c index bbe031c385..59de84dbbd 100644 --- a/Pal/regression/Wait.c +++ b/Pal/regression/Wait.c @@ -30,17 +30,25 @@ int main(int argc, char** argv) { PAL_HANDLE thd1; PAL_HANDLE thd2; - event1 = DkNotificationEventCreate(0); - event2 = DkNotificationEventCreate(0); + int ret = DkNotificationEventCreate(0, &event1); + if (ret < 0) { + pal_printf("DkNotificationEventCreate failed: %d\n", ret); + return 1; + } + ret = DkNotificationEventCreate(0, &event2); + if (ret < 0) { + pal_printf("DkNotificationEventCreate failed: %d\n", ret); + return 1; + } - thd1 = DkThreadCreate(&thread1_func, 0); - if (!thd1) { + ret = DkThreadCreate(&thread1_func, 0, &thd1); + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); return -1; } - thd2 = DkThreadCreate(&thread2_func, 0); - if (!thd2) { + ret = DkThreadCreate(&thread2_func, 0, &thd2); + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); return -1; } @@ -49,8 +57,8 @@ int main(int argc, char** argv) { PAL_FLG events[2] = {PAL_WAIT_READ, PAL_WAIT_READ}; PAL_FLG revents[2] = {0, 0}; - PAL_BOL polled = DkStreamsWaitEvents(2, hdls, events, revents, NO_TIMEOUT); - if (!polled) { + ret = DkStreamsWaitEvents(2, hdls, events, revents, NO_TIMEOUT); + if (ret < 0) { pal_printf("DkStreamsWaitEvents did not return any events\n"); return -1; } diff --git a/Pal/regression/Yield.c b/Pal/regression/Yield.c index 38b9f4216b..dc356aef81 100644 --- a/Pal/regression/Yield.c +++ b/Pal/regression/Yield.c @@ -1,6 +1,8 @@ #include "pal.h" #include "pal_debug.h" +/* XXX: What is this even supposed to test?? */ + PAL_HANDLE parent_thread, child_thread; static int child(void* args) { @@ -22,9 +24,9 @@ int main(void) { pal_printf("Enter Parent Thread\n"); parent_thread = pal_control.first_thread; - child_thread = DkThreadCreate(&child, NULL); + int ret = DkThreadCreate(&child, NULL, &child_thread); - if (child_thread == NULL) { + if (ret < 0) { pal_printf("DkThreadCreate failed\n"); return -1; } diff --git a/Pal/regression/avl_tree_test.c b/Pal/regression/avl_tree_test.c index 58971d84a5..bdb4c00df9 100644 --- a/Pal/regression/avl_tree_test.c +++ b/Pal/regression/avl_tree_test.c @@ -306,7 +306,7 @@ int main(void) { uint32_t seed = 0; if (DkRandomBitsRead(&seed, sizeof(seed)) < 0) { - pal_printf("\n"); + pal_printf("Getting a seed failed\n"); return 1; } pal_printf("Running dynamic tests (with seed: %u): ", seed); diff --git a/Pal/regression/normalize_path.c b/Pal/regression/normalize_path.c index 375e4c1941..43fcbeefca 100644 --- a/Pal/regression/normalize_path.c +++ b/Pal/regression/normalize_path.c @@ -57,7 +57,7 @@ static int run_test(void) { int ret = func_to_test(cases[i][0], buf, &size); if (ret < 0) { - print_err(func_name, i, "failed with error: %s\n", pal_strerror(-ret)); + print_err(func_name, i, "failed with error: %s\n", pal_strerror(ret)); return 1; } diff --git a/Pal/regression/test_pal.py b/Pal/regression/test_pal.py index d758789785..c10343fe26 100644 --- a/Pal/regression/test_pal.py +++ b/Pal/regression/test_pal.py @@ -49,12 +49,6 @@ def test_Exception2(self): self.assertIn('failure in the handler: 0x', stderr) self.assertNotIn('Leave Main Thread', stderr) - def test_Failure(self): - _, stderr = self.run_binary(['Failure']) - self.assertIn('Enter Main Thread', stderr) - self.assertIn('Failure notified: Function not supported', stderr) - self.assertIn('Leave Main Thread', stderr) - def test_File2(self): _, stderr = self.run_binary(['File2']) self.assertIn('Enter Main Thread', stderr) diff --git a/Pal/src/db_events.c b/Pal/src/db_events.c index 7338026606..f726ac782d 100644 --- a/Pal/src/db_events.c +++ b/Pal/src/db_events.c @@ -11,52 +11,28 @@ #include "pal_error.h" #include "pal_internal.h" -PAL_HANDLE DkNotificationEventCreate(PAL_BOL initialState) { - PAL_HANDLE handle = NULL; - int ret = _DkEventCreate(&handle, initialState, true); - - if (ret < 0) { - _DkRaiseFailure(-ret); - handle = NULL; - } - - return handle; +int DkNotificationEventCreate(PAL_BOL initialState, PAL_HANDLE* handle) { + *handle = NULL; + return _DkEventCreate(handle, initialState, true); } -PAL_HANDLE DkSynchronizationEventCreate(PAL_BOL initialState) { - PAL_HANDLE handle = NULL; - int ret = _DkEventCreate(&handle, initialState, false); - - if (ret < 0) { - _DkRaiseFailure(-ret); - handle = NULL; - } - - return handle; +int DkSynchronizationEventCreate(PAL_BOL initialState, PAL_HANDLE* handle) { + *handle = NULL; + return _DkEventCreate(handle, initialState, false); } -/* DkEventDestroy deprecated, replaced by DkObjectClose */ - -void DkEventSet(PAL_HANDLE handle) { +int DkEventSet(PAL_HANDLE handle) { if (!handle || !IS_HANDLE_TYPE(handle, event)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } - int ret = _DkEventSet(handle, -1); - - if (ret < 0) - _DkRaiseFailure(-ret); + return _DkEventSet(handle, -1); } -void DkEventClear(PAL_HANDLE handle) { +int DkEventClear(PAL_HANDLE handle) { if (!handle || !IS_HANDLE_TYPE(handle, event)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } - int ret = _DkEventClear(handle); - - if (ret < 0) - _DkRaiseFailure(-ret); + return _DkEventClear(handle); } diff --git a/Pal/src/db_exception.c b/Pal/src/db_exception.c index 573f395c0c..ac05895813 100644 --- a/Pal/src/db_exception.c +++ b/Pal/src/db_exception.c @@ -22,15 +22,10 @@ PAL_EVENT_HANDLER _DkGetExceptionHandler(PAL_NUM event) { return __atomic_load_n(&g_handlers[event], __ATOMIC_ACQUIRE); } -PAL_BOL -DkSetExceptionHandler(PAL_EVENT_HANDLER handler, PAL_NUM event) { - if (!handler || event == 0 || event >= ARRAY_SIZE(g_handlers)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; - } +void DkSetExceptionHandler(PAL_EVENT_HANDLER handler, PAL_NUM event) { + assert(handler && event != 0 && event < ARRAY_SIZE(g_handlers)); __atomic_store_n(&g_handlers[event], handler, __ATOMIC_RELEASE); - return PAL_TRUE; } /* This does not return */ diff --git a/Pal/src/db_memory.c b/Pal/src/db_memory.c index 8094efc22a..68a7228ac9 100644 --- a/Pal/src/db_memory.c +++ b/Pal/src/db_memory.c @@ -12,75 +12,49 @@ #include "pal_error.h" #include "pal_internal.h" -PAL_PTR DkVirtualMemoryAlloc(PAL_PTR addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot) { - void* map_addr = (void*)addr; +int DkVirtualMemoryAlloc(PAL_PTR* addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot) { + assert(addr); + void* map_addr = *addr; - if ((addr && !IS_ALLOC_ALIGNED_PTR(addr)) || !size || !IS_ALLOC_ALIGNED(size)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return (PAL_PTR)NULL; + if ((map_addr && !IS_ALLOC_ALIGNED_PTR(map_addr)) || !size || !IS_ALLOC_ALIGNED(size)) { + return -PAL_ERROR_INVAL; } if (map_addr && _DkCheckMemoryMappable(map_addr, size)) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return (PAL_PTR)NULL; + return -PAL_ERROR_DENIED; } - int ret = _DkVirtualMemoryAlloc(&map_addr, size, alloc_type, prot); - - if (ret < 0) { - _DkRaiseFailure(-ret); - map_addr = NULL; - } - - return (PAL_PTR)map_addr; + return _DkVirtualMemoryAlloc(addr, size, alloc_type, prot); } -void DkVirtualMemoryFree(PAL_PTR addr, PAL_NUM size) { +int DkVirtualMemoryFree(PAL_PTR addr, PAL_NUM size) { if (!addr || !size) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } if (!IS_ALLOC_ALIGNED_PTR(addr) || !IS_ALLOC_ALIGNED(size)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } if (_DkCheckMemoryMappable((void*)addr, size)) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return; + return -PAL_ERROR_DENIED; } - int ret = _DkVirtualMemoryFree((void*)addr, size); - - if (ret < 0) { - _DkRaiseFailure(-ret); - } + return _DkVirtualMemoryFree((void*)addr, size); } -PAL_BOL -DkVirtualMemoryProtect(PAL_PTR addr, PAL_NUM size, PAL_FLG prot) { +int DkVirtualMemoryProtect(PAL_PTR addr, PAL_NUM size, PAL_FLG prot) { if (!addr || !size) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } if (!IS_ALLOC_ALIGNED_PTR(addr) || !IS_ALLOC_ALIGNED(size)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } if (_DkCheckMemoryMappable((void*)addr, size)) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return PAL_FALSE; - } - - int ret = _DkVirtualMemoryProtect((void*)addr, size, prot); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return -PAL_ERROR_DENIED; } - return PAL_TRUE; + return _DkVirtualMemoryProtect((void*)addr, size, prot); } diff --git a/Pal/src/db_misc.c b/Pal/src/db_misc.c index 63b3a57427..1010f7a3c5 100644 --- a/Pal/src/db_misc.c +++ b/Pal/src/db_misc.c @@ -11,42 +11,21 @@ #include "pal_error.h" #include "pal_internal.h" -PAL_NUM DkSystemTimeQuery(void) { - uint64_t time; - int ret = _DkSystemTimeQuery(&time); - if (ret < 0) { - _DkRaiseFailure(-ret); - // TODO: Fix this interface to allow returning errors. - time = 0; - } - return time; +int DkSystemTimeQuery(PAL_NUM* time) { + return _DkSystemTimeQuery(time); } -PAL_NUM DkRandomBitsRead(PAL_PTR buffer, PAL_NUM size) { +int DkRandomBitsRead(PAL_PTR buffer, PAL_NUM size) { return _DkRandomBitsRead((void*)buffer, size); } #if defined(__x86_64__) -PAL_BOL DkSegmentRegisterGet(PAL_FLG reg, PAL_PTR* addr) { - int ret = _DkSegmentRegisterGet(reg, addr); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; +int DkSegmentRegisterGet(PAL_FLG reg, PAL_PTR* addr) { + return _DkSegmentRegisterGet(reg, addr); } -PAL_BOL DkSegmentRegisterSet(PAL_FLG reg, PAL_PTR addr) { - int ret = _DkSegmentRegisterSet(reg, addr); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; +int DkSegmentRegisterSet(PAL_FLG reg, PAL_PTR addr) { + return _DkSegmentRegisterSet(reg, addr); } #endif @@ -58,13 +37,11 @@ PAL_NUM DkMemoryAvailableQuota(void) { return (PAL_NUM)quota; } -PAL_BOL -DkCpuIdRetrieve(PAL_IDX leaf, PAL_IDX subleaf, PAL_IDX values[4]) { +int DkCpuIdRetrieve(PAL_IDX leaf, PAL_IDX subleaf, PAL_IDX values[4]) { unsigned int vals[4]; int ret = _DkCpuIdRetrieve(leaf, subleaf, vals); if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return ret; } values[0] = vals[0]; @@ -72,36 +49,21 @@ DkCpuIdRetrieve(PAL_IDX leaf, PAL_IDX subleaf, PAL_IDX values[4]) { values[2] = vals[2]; values[3] = vals[3]; - return PAL_TRUE; + return 0; } -PAL_BOL DkAttestationReport(PAL_PTR user_report_data, PAL_NUM* user_report_data_size, - PAL_PTR target_info, PAL_NUM* target_info_size, PAL_PTR report, - PAL_NUM* report_size) { - int ret = _DkAttestationReport(user_report_data, user_report_data_size, target_info, - target_info_size, report, report_size); - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - return PAL_TRUE; +int DkAttestationReport(PAL_PTR user_report_data, PAL_NUM* user_report_data_size, + PAL_PTR target_info, PAL_NUM* target_info_size, PAL_PTR report, + PAL_NUM* report_size) { + return _DkAttestationReport(user_report_data, user_report_data_size, target_info, + target_info_size, report, report_size); } -PAL_BOL DkAttestationQuote(PAL_PTR user_report_data, PAL_NUM user_report_data_size, PAL_PTR quote, - PAL_NUM* quote_size) { - int ret = _DkAttestationQuote(user_report_data, user_report_data_size, quote, quote_size); - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - return PAL_TRUE; +int DkAttestationQuote(PAL_PTR user_report_data, PAL_NUM user_report_data_size, PAL_PTR quote, + PAL_NUM* quote_size) { + return _DkAttestationQuote(user_report_data, user_report_data_size, quote, quote_size); } -PAL_BOL DkSetProtectedFilesKey(PAL_PTR pf_key_hex) { - int ret = _DkSetProtectedFilesKey(pf_key_hex); - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - return PAL_TRUE; +int DkSetProtectedFilesKey(PAL_PTR pf_key_hex) { + return _DkSetProtectedFilesKey(pf_key_hex); } diff --git a/Pal/src/db_mutex.c b/Pal/src/db_mutex.c index 42957d3a64..9f8df7af8d 100644 --- a/Pal/src/db_mutex.c +++ b/Pal/src/db_mutex.c @@ -11,24 +11,13 @@ #include "pal_error.h" #include "pal_internal.h" -PAL_HANDLE -DkMutexCreate(PAL_NUM initialCount) { - PAL_HANDLE handle = NULL; - int ret = _DkMutexCreate(&handle, initialCount); - - if (ret < 0) { - _DkRaiseFailure(-ret); - handle = NULL; - } - - return handle; +int DkMutexCreate(PAL_NUM initialCount, PAL_HANDLE* handle) { + *handle = NULL; + return _DkMutexCreate(handle, initialCount); } void DkMutexRelease(PAL_HANDLE handle) { - if (!handle || !IS_HANDLE_TYPE(handle, mutex)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; - } + assert(handle && IS_HANDLE_TYPE(handle, mutex)); _DkMutexRelease(handle); } diff --git a/Pal/src/db_object.c b/Pal/src/db_object.c index 48a536bfa3..128ee340c3 100644 --- a/Pal/src/db_object.c +++ b/Pal/src/db_object.c @@ -13,8 +13,6 @@ #include "pal_error.h" #include "pal_internal.h" -/* Deprecated DkObjectReference. */ - int _DkObjectClose(PAL_HANDLE objectHandle) { const struct handle_ops* ops = HANDLE_OPS(objectHandle); if (!ops) @@ -37,56 +35,43 @@ int _DkObjectClose(PAL_HANDLE objectHandle) { return ret; } +/* + * TODO: whole LibOS assumes this never returns errors. We need to either make `_DkObjectClose` + * never fail (from a quick look at the code, seems like it cannot return errors in practice) or + * make this return an `int` and handle errors in all call sites (hard to do; in most places we + * cannot handle them in a meaningful way). + */ /* PAL call DkObjectClose: Close the given object handle. */ void DkObjectClose(PAL_HANDLE objectHandle) { - if (!objectHandle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; - } + assert(objectHandle); - int ret = _DkObjectClose(objectHandle); - if (ret < 0) - _DkRaiseFailure(-ret); + _DkObjectClose(objectHandle); } -/* Wait on a synchronization handle and return true if this handle's event was triggered, - * otherwise return false and additionally raise failure. */ -PAL_BOL DkSynchronizationObjectWait(PAL_HANDLE handle, PAL_NUM timeout_us) { +/* Wait on a synchronization handle and return `0` if this handle's event was triggered, + * otherwise return negative error code. */ +int DkSynchronizationObjectWait(PAL_HANDLE handle, PAL_NUM timeout_us) { if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } - int ret = _DkSynchronizationObjectWait(handle, timeout_us); - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; + return _DkSynchronizationObjectWait(handle, timeout_us); } /* Wait for user-specified events of handles in the handle array. The wait can be timed out, unless - * NO_TIMEOUT is given in the timeout_us argument. Returns PAL_TRUE if waiting was successful. */ -PAL_BOL DkStreamsWaitEvents(PAL_NUM count, PAL_HANDLE* handle_array, PAL_FLG* events, - PAL_FLG* ret_events, PAL_NUM timeout_us) { + * NO_TIMEOUT is given in the timeout_us argument. Returns `0` if waiting was successful, negative + * error code otherwise. */ +int DkStreamsWaitEvents(PAL_NUM count, PAL_HANDLE* handle_array, PAL_FLG* events, + PAL_FLG* ret_events, PAL_NUM timeout_us) { if (!count || !handle_array || !events || !ret_events) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } for (PAL_NUM i = 0; i < count; i++) { if (UNKNOWN_HANDLE(handle_array[i])) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } } - int ret = _DkStreamsWaitEvents(count, handle_array, events, ret_events, timeout_us); - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; + return _DkStreamsWaitEvents(count, handle_array, events, ret_events, timeout_us); } diff --git a/Pal/src/db_process.c b/Pal/src/db_process.c index e4a0df9898..378420a45a 100644 --- a/Pal/src/db_process.c +++ b/Pal/src/db_process.c @@ -16,22 +16,14 @@ #include "pal_error.h" #include "pal_internal.h" -PAL_HANDLE DkProcessCreate(PAL_STR exec_uri, PAL_STR* args) { +int DkProcessCreate(PAL_STR exec_uri, PAL_STR* args, PAL_HANDLE* handle) { assert(exec_uri); - PAL_HANDLE handle = NULL; - int ret = _DkProcessCreate(&handle, exec_uri, args); - - if (ret < 0) { - _DkRaiseFailure(-ret); - handle = NULL; - } - - return handle; + *handle = NULL; + return _DkProcessCreate(handle, exec_uri, args); } noreturn void DkProcessExit(PAL_NUM exitcode) { _DkProcessExit(exitcode); - _DkRaiseFailure(PAL_ERROR_NOTKILLABLE); die_or_inf_loop(); } diff --git a/Pal/src/db_rtld.c b/Pal/src/db_rtld.c index f52aedee4b..a9755a3180 100644 --- a/Pal/src/db_rtld.c +++ b/Pal/src/db_rtld.c @@ -23,7 +23,7 @@ struct link_map* g_exec_map = NULL; struct link_map* lookup_symbol(const char* undef_name, ElfW(Sym)** ref); -/* err - positive value of error code */ +/* err - positive or negative value of error code */ static inline void print_error(const char* msg, int err) { printf("%s (%s)\n", msg, pal_strerror(err)); } diff --git a/Pal/src/db_streams.c b/Pal/src/db_streams.c index f55ec6688f..0ade4fb62b 100644 --- a/Pal/src/db_streams.c +++ b/Pal/src/db_streams.c @@ -158,25 +158,15 @@ int _DkStreamOpen(PAL_HANDLE* handle, const char* uri, int access, int share, in /* PAL call DkStreamOpen: Open stream based on uri, as given access/share/ create/options flags. DkStreamOpen return a PAL_HANDLE to access the - stream, or return NULL. Error code is notified. + stream in `handle` argument. FIXME: Currently `share` must match 1-1 to Linux open() `mode` argument. This isn't really portable and will cause problems when implementing other PALs. */ -PAL_HANDLE DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share, PAL_FLG create, - PAL_FLG options) { - PAL_HANDLE handle = NULL; - int ret = _DkStreamOpen(&handle, uri, access, share, create, options); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return NULL; - } - - assert(handle); - assert(!UNKNOWN_HANDLE(handle)); - - return handle; +int DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share, PAL_FLG create, PAL_FLG options, + PAL_HANDLE* handle) { + *handle = NULL; + return _DkStreamOpen(handle, uri, access, share, create, options); } static int _DkStreamWaitForClient(PAL_HANDLE handle, PAL_HANDLE* client) { @@ -193,17 +183,9 @@ static int _DkStreamWaitForClient(PAL_HANDLE handle, PAL_HANDLE* client) { return ops->waitforclient(handle, client); } -PAL_HANDLE -DkStreamWaitForClient(PAL_HANDLE handle) { - PAL_HANDLE client; - int ret = _DkStreamWaitForClient(handle, &client); - - if (ret < 0) { - _DkRaiseFailure(-ret); - client = NULL; - } - - return client; +int DkStreamWaitForClient(PAL_HANDLE handle, PAL_HANDLE* client) { + *client = NULL; + return _DkStreamWaitForClient(handle, client); } /* _DkStreamDelete for internal use. This function will explicit delete @@ -223,18 +205,12 @@ int _DkStreamDelete(PAL_HANDLE handle, int access) { return ops->delete(handle, access); } -/* PAL call DkStreamDelete: Explicitly delete stream as given handle. No - return value, error code is notified. */ -void DkStreamDelete(PAL_HANDLE handle, PAL_FLG access) { +int DkStreamDelete(PAL_HANDLE handle, PAL_FLG access) { if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } - int ret = _DkStreamDelete(handle, access); - - if (ret < 0) - _DkRaiseFailure(-ret); + return _DkStreamDelete(handle, access); } /* _DkStreamRead for internal use. Read from stream as absolute offset. @@ -263,26 +239,21 @@ int64_t _DkStreamRead(PAL_HANDLE handle, uint64_t offset, uint64_t count, void* return ret; } -/* PAL call DkStreamRead: Read from stream at absolute offset. Return number - of bytes if succeeded, - or PAL_STREAM_ERROR for failure. Error code is notified. */ -PAL_NUM -DkStreamRead(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM count, PAL_PTR buffer, PAL_PTR source, - PAL_NUM size) { +int DkStreamRead(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM* count, PAL_PTR buffer, PAL_PTR source, + PAL_NUM size) { if (!handle || !buffer) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_STREAM_ERROR; + return -PAL_ERROR_INVAL; } - int64_t ret = _DkStreamRead(handle, offset, count, (void*)buffer, size ? (char*)source : NULL, + int64_t ret = _DkStreamRead(handle, offset, *count, (void*)buffer, size ? (char*)source : NULL, source ? size : 0); if (ret < 0) { - _DkRaiseFailure(-ret); - ret = PAL_STREAM_ERROR; + return ret; } - return ret; + *count = ret; + return 0; } /* _DkStreamWrite for internal use, write to stream at absolute offset. @@ -311,25 +282,20 @@ int64_t _DkStreamWrite(PAL_HANDLE handle, uint64_t offset, uint64_t count, const return ret; } -/* PAL call DkStreamWrite: Write to stream at absolute offset. Return number - of bytes if succeeded, - or PAL_STREAM_ERROR for failure. Error code is notified. */ -PAL_NUM -DkStreamWrite(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM count, PAL_PTR buffer, PAL_STR dest) { +int DkStreamWrite(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM* count, PAL_PTR buffer, PAL_STR dest) { if (!handle || !buffer) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_STREAM_ERROR; + return -PAL_ERROR_INVAL; } - int64_t ret = - _DkStreamWrite(handle, offset, count, (void*)buffer, dest, dest ? strlen(dest) : 0); + int64_t ret = _DkStreamWrite(handle, offset, *count, (void*)buffer, dest, + dest ? strlen(dest) : 0); if (ret < 0) { - _DkRaiseFailure(-ret); - ret = PAL_STREAM_ERROR; + return ret; } - return ret; + *count = ret; + return 0; } /* _DkStreamAttributesQuery of internal use. The function query attribute @@ -351,13 +317,9 @@ int _DkStreamAttributesQuery(const char* uri, PAL_STREAM_ATTR* attr) { return ret; } -/* PAL call DkStreamAttributeQuery: query attribute of a stream by its - URI, attr is memory given by user space. Return TRUE if succeeded - or FALSE if failed. Error code is notified */ -PAL_BOL DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr) { +int DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr) { if (!uri || !attr) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } PAL_STREAM_ATTR attr_buf; @@ -365,12 +327,11 @@ PAL_BOL DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr) { int ret = _DkStreamAttributesQuery(uri, &attr_buf); if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return ret; } memcpy(attr, &attr_buf, sizeof(PAL_STREAM_ATTR)); - return PAL_TRUE; + return 0; } /* _DkStreamAttributesQueryByHandle for internal use. Query attribute @@ -387,53 +348,29 @@ int _DkStreamAttributesQueryByHandle(PAL_HANDLE hdl, PAL_STREAM_ATTR* attr) { return ops->attrquerybyhdl(hdl, attr); } -/* PAL call DkStreamAttributesQueryByHandle: Query attribute of a stream by - its handle, attr is memory given by user space. Return TRUE if succeeded - or FALSE if failed. Error code is notified */ -PAL_BOL DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { +int DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { if (!handle || !attr) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; - } - - int ret = _DkStreamAttributesQueryByHandle(handle, attr); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } - return PAL_TRUE; + return _DkStreamAttributesQueryByHandle(handle, attr); } -/* PAL call DkStreamAttributesSetByHandle: Set attribute of a stream by - its handle, attr is memory given by user space. Return TRUE if succeeded - or FALSE if failed. Error code is notified */ -PAL_BOL DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { +int DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { if (!handle || !attr) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } const struct handle_ops* ops = HANDLE_OPS(handle); if (!ops) { - _DkRaiseFailure(PAL_ERROR_BADHANDLE); - return PAL_FALSE; + return -PAL_ERROR_BADHANDLE; } if (!ops->attrsetbyhdl) { - _DkRaiseFailure(PAL_ERROR_NOTSUPPORT); - return PAL_FALSE; - } - - int ret = ops->attrsetbyhdl(handle, attr); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return -PAL_ERROR_NOTSUPPORT; } - return PAL_TRUE; + return ops->attrsetbyhdl(handle, attr); } int _DkStreamGetName(PAL_HANDLE handle, char* buffer, int size) { @@ -454,22 +391,12 @@ int _DkStreamGetName(PAL_HANDLE handle, char* buffer, int size) { return ret; } -/* PAL call DkStreamGetName: Copy handle name into buffer. Return size of - * name if succeeded or 0 if failed. Error code is notified */ -PAL_NUM DkStreamGetName(PAL_HANDLE handle, PAL_PTR buffer, PAL_NUM size) { +int DkStreamGetName(PAL_HANDLE handle, PAL_PTR buffer, PAL_NUM size) { if (!handle || !buffer || !size) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return 0; - } - - int ret = _DkStreamGetName(handle, (void*)buffer, size); - - if (ret < 0) { - _DkRaiseFailure(-ret); - ret = 0; + return -PAL_ERROR_INVAL; } - return ret; + return _DkStreamGetName(handle, (void*)buffer, size); } /* _DkStreamMap for internal use. Map specific handle to certain memory, @@ -495,58 +422,38 @@ int _DkStreamMap(PAL_HANDLE handle, void** paddr, int prot, uint64_t offset, uin return 0; } -/* PAL call DkStreamMap: Map a stream of a given handle to certain memery - space. prot/offset/size are the protection, offset and size of the memory - mapping. Return the address if succeeded or NULL if failed. Error code - is notified. */ -PAL_PTR DkStreamMap(PAL_HANDLE handle, PAL_PTR addr, PAL_FLG prot, PAL_NUM offset, PAL_NUM size) { - void* map_addr = (void*)addr; +int DkStreamMap(PAL_HANDLE handle, PAL_PTR* addr, PAL_FLG prot, PAL_NUM offset, PAL_NUM size) { + assert(addr); + void* map_addr = *addr; if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return (PAL_PTR)NULL; + return -PAL_ERROR_INVAL; } - /* Check that all addresses and sizes are aligned */ - if ((addr && !IS_ALLOC_ALIGNED_PTR(addr)) || !size || !IS_ALLOC_ALIGNED(size) || - !IS_ALLOC_ALIGNED(offset)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return (PAL_PTR)NULL; + if (map_addr && !IS_ALLOC_ALIGNED_PTR(map_addr)) { + return -PAL_ERROR_INVAL; } - - if (map_addr && _DkCheckMemoryMappable(map_addr, size)) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return (PAL_PTR)NULL; + if (!size || !IS_ALLOC_ALIGNED(size) || !IS_ALLOC_ALIGNED(offset)) { + return -PAL_ERROR_INVAL; } - int ret = _DkStreamMap(handle, &map_addr, prot, offset, size); - - if (ret < 0) { - _DkRaiseFailure(-ret); - map_addr = NULL; + if (map_addr && _DkCheckMemoryMappable(map_addr, size)) { + return -PAL_ERROR_DENIED; } - return (PAL_PTR)map_addr; + return _DkStreamMap(handle, addr, prot, offset, size); } -/* PAL call DkStreamUnmap: Unmap memory mapped at an address. The memory has - to be a stream map, and it got unmapped as a whole memory area. No - return value. Error code is notified */ -void DkStreamUnmap(PAL_PTR addr, PAL_NUM size) { +int DkStreamUnmap(PAL_PTR addr, PAL_NUM size) { if (!addr || !IS_ALLOC_ALIGNED_PTR(addr) || !size || !IS_ALLOC_ALIGNED(size)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return; + return -PAL_ERROR_INVAL; } if (_DkCheckMemoryMappable((void*)addr, size)) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return; + return -PAL_ERROR_DENIED; } - int ret = _DkStreamUnmap((void*)addr, size); - - if (ret < 0) - _DkRaiseFailure(-ret); + return _DkStreamUnmap((void*)addr, size); } /* _DkStreamSetLength for internal use. This function truncate the stream @@ -563,20 +470,15 @@ int64_t _DkStreamSetLength(PAL_HANDLE handle, uint64_t length) { return ops->setlength(handle, length); } -/* PAL call DkStreamSetLength: Truncate the stream at certain length. - Return 0 if succeeded or positive error code if failed. Error code - is additionally notified. */ -PAL_NUM DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length) { +int DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length) { if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_ERROR_INVAL; + return -PAL_ERROR_INVAL; } int64_t ret = _DkStreamSetLength(handle, length); if (ret < 0) { - _DkRaiseFailure(-ret); - return -ret; + return ret; } assert((uint64_t)ret == length); @@ -600,80 +502,34 @@ int _DkStreamFlush(PAL_HANDLE handle) { return ops->flush(handle); } -/* PAL call DkStreamFlush: Sync up a stream of a given handle. Return TRUE - * if succeeded or FALSE if failed. Error code is notified. */ -PAL_BOL DkStreamFlush(PAL_HANDLE handle) { +int DkStreamFlush(PAL_HANDLE handle) { if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; - } - - int ret = _DkStreamFlush(handle); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } - return PAL_TRUE; + return _DkStreamFlush(handle); } -/* PAL call DkSendHandle: Write to a process handle. - Return TRUE on success and FALSE on failure */ -PAL_BOL DkSendHandle(PAL_HANDLE handle, PAL_HANDLE cargo) { +int DkSendHandle(PAL_HANDLE handle, PAL_HANDLE cargo) { // Return error if any of the handle is NULL if (!handle || !cargo) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; - } - - // Call the internal function after validating input args - int ret = _DkSendHandle(handle, cargo); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } - return PAL_TRUE; + return _DkSendHandle(handle, cargo); } -/* PAL call DkRecvHandle: Read a handle to a pipe/process handle. - Return the received PAL_HANDLE by reference and 0 on success and - negative number on failure */ -/* 1. Should i take the received PAL_HANDLE as an input argument and - pass by reference or return it rather? - Ans - We are not aware of the size of the variable members to return - 2. Would the recieved PAL_HANDLE start functioning automatically in - the new process environment? Should we initialize/modify some - attibutes of the handle? - Ans - Yes, Initialize and make it compatibile in the target process - 3. Should malloc_copy be done or the process shares the same references? - Ans - Variables members have to allocated data again. -*/ -PAL_HANDLE DkReceiveHandle(PAL_HANDLE handle) { +int DkReceiveHandle(PAL_HANDLE handle, PAL_HANDLE* cargo) { // return error if any of the handle is NULL if (!handle) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return NULL; - } - - // create a reference for the received PAL_HANDLE - PAL_HANDLE cargo = NULL; - // call the internal function after validating input args - int ret = _DkReceiveHandle(handle, &cargo); - - // notify failure would have been called from other functions - if (ret < 0) { - _DkRaiseFailure(-ret); - return NULL; + return -PAL_ERROR_INVAL; } - assert(cargo); - return cargo; + *cargo = NULL; + return _DkReceiveHandle(handle, cargo); } -PAL_BOL DkStreamChangeName(PAL_HANDLE hdl, PAL_STR uri) { +int DkStreamChangeName(PAL_HANDLE hdl, PAL_STR uri) { struct handle_ops* ops = NULL; char* type = NULL; int ret; @@ -682,8 +538,7 @@ PAL_BOL DkStreamChangeName(PAL_HANDLE hdl, PAL_STR uri) { ret = parse_stream_uri(&uri, &type, &ops); if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; + return ret; } } @@ -691,19 +546,12 @@ PAL_BOL DkStreamChangeName(PAL_HANDLE hdl, PAL_STR uri) { if (!hops || !hops->rename || (ops && hops != ops)) { free(type); - _DkRaiseFailure(PAL_ERROR_NOTSUPPORT); - return PAL_FALSE; + return -PAL_ERROR_NOTSUPPORT; } ret = hops->rename(hdl, type, uri); free(type); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; + return ret; } /* _DkStreamRealpath is used to obtain the real path of a stream. Some @@ -717,12 +565,12 @@ const char* _DkStreamRealpath(PAL_HANDLE hdl) { return ops->getrealpath(hdl); } -PAL_NUM DkDebugLog(PAL_PTR buffer, PAL_NUM size) { - ssize_t ret = _DkDebugLog(buffer, size); +int DkDebugLog(PAL_PTR buffer, PAL_NUM* size) { + ssize_t ret = _DkDebugLog(buffer, *size); if (ret < 0) { - _DkRaiseFailure(-ret); - ret = PAL_STREAM_ERROR; + return ret; } - return ret; + *size = ret; + return 0; } diff --git a/Pal/src/db_threading.c b/Pal/src/db_threading.c index 7fbf1d70fd..653bacdcf0 100644 --- a/Pal/src/db_threading.c +++ b/Pal/src/db_threading.c @@ -13,28 +13,14 @@ #include "pal_internal.h" /* PAL call DkThreadCreate: create a thread inside the current process */ -PAL_HANDLE DkThreadCreate(PAL_PTR addr, PAL_PTR param) { - PAL_HANDLE handle = NULL; - int ret = _DkThreadCreate(&handle, (int (*)(void*))addr, (const void*)param); - - if (ret < 0) { - _DkRaiseFailure(-ret); - handle = NULL; - } - - return handle; +int DkThreadCreate(PAL_PTR addr, PAL_PTR param, PAL_HANDLE* handle) { + *handle = NULL; + return _DkThreadCreate(handle, (int (*)(void*))addr, (const void*)param); } /* PAL call DkThreadDelayExecution. Delay the current thread (sleep) for the given duration */ PAL_NUM DkThreadDelayExecution(PAL_NUM duration) { - unsigned long dur = duration; - int ret = _DkThreadDelayExecution(&dur); - - if (ret < 0) { - _DkRaiseFailure(PAL_ERROR_INTERRUPTED); - duration = dur; - } - + (void)_DkThreadDelayExecution(&duration); return duration; } @@ -50,40 +36,18 @@ noreturn void DkThreadExit(PAL_PTR clear_child_tid) { } /* PAL call DkThreadResume: resume the execution of a thread which is delayed before */ -PAL_BOL DkThreadResume(PAL_HANDLE threadHandle) { +int DkThreadResume(PAL_HANDLE threadHandle) { if (!threadHandle || !IS_HANDLE_TYPE(threadHandle, thread)) { - _DkRaiseFailure(PAL_ERROR_INVAL); - return PAL_FALSE; + return -PAL_ERROR_INVAL; } - int ret = _DkThreadResume(threadHandle); - - if (ret < 0) { - _DkRaiseFailure(PAL_ERROR_DENIED); - return PAL_FALSE; - } - - return PAL_TRUE; + return _DkThreadResume(threadHandle); } -PAL_BOL DkThreadSetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask) { - int ret = _DkThreadSetCpuAffinity(thread, cpumask_size, cpu_mask); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; +int DkThreadSetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask) { + return _DkThreadSetCpuAffinity(thread, cpumask_size, cpu_mask); } -PAL_BOL DkThreadGetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask) { - int ret = _DkThreadGetCpuAffinity(thread, cpumask_size, cpu_mask); - - if (ret < 0) { - _DkRaiseFailure(-ret); - return PAL_FALSE; - } - - return PAL_TRUE; +int DkThreadGetCpuAffinity(PAL_HANDLE thread, PAL_NUM cpumask_size, PAL_PTR cpu_mask) { + return _DkThreadGetCpuAffinity(thread, cpumask_size, cpu_mask); } diff --git a/Pal/src/host/Linux-SGX/db_exception.c b/Pal/src/host/Linux-SGX/db_exception.c index eefa61d4ab..7404776d8e 100644 --- a/Pal/src/host/Linux-SGX/db_exception.c +++ b/Pal/src/host/Linux-SGX/db_exception.c @@ -270,15 +270,6 @@ void _DkExceptionHandler(unsigned int exit_info, sgx_cpu_context_t* uc, restore_pal_context(uc, &ctx); } -/* TODO: remove this function. It's not an exception handling, it's just returning an error from - * PAL... */ -void _DkRaiseFailure(int error) { - PAL_EVENT_HANDLER upcall = _DkGetExceptionHandler(PAL_EVENT_FAILURE); - if (upcall) { - (*upcall)(/*is_in_pal=*/false, error, /*context=*/NULL); - } -} - /* TODO: shouldn't this function ignore sync events??? * actually what is the point of this function? * Tracked: https://github.com/oscarlab/graphene/issues/2140 */ @@ -287,10 +278,6 @@ noreturn void _DkHandleExternalEvent(PAL_NUM event, sgx_cpu_context_t* uc, assert(event > 0 && event < PAL_EVENT_NUM_BOUND); assert(IS_ALIGNED_PTR(xregs_state, PAL_XSTATE_ALIGN)); - /* we only end up in _DkHandleExternalEvent() if interrupted during host syscall; inform LibOS - * layer that PAL was interrupted (by setting PAL_ERRNO) */ - _DkRaiseFailure(PAL_ERROR_INTERRUPTED); - PAL_CONTEXT ctx; save_pal_context(&ctx, uc, xregs_state); diff --git a/Pal/src/host/Linux-SGX/db_files.c b/Pal/src/host/Linux-SGX/db_files.c index be685312ee..da86e87b3e 100644 --- a/Pal/src/host/Linux-SGX/db_files.c +++ b/Pal/src/host/Linux-SGX/db_files.c @@ -46,7 +46,7 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int char* path = (void*)hdl + HANDLE_SIZE(file); int ret; if ((ret = get_norm_path(uri, path, &len)) < 0) { - log_error("Could not normalize path (%s): %s\n", uri, pal_strerror(-ret)); + log_error("Could not normalize path (%s): %s\n", uri, pal_strerror(ret)); free(hdl); return ret; } @@ -123,7 +123,7 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int if (ret < 0) { log_error("Accessing file:%s is denied (%s). This file is not trusted or allowed." " Trusted files should be regular files (seekable).\n", hdl->file.realpath, - pal_strerror(-ret)); + pal_strerror(ret)); goto out; } @@ -651,7 +651,7 @@ static int file_attrquery(const char* type, const char* uri, PAL_STREAM_ATTR* at size_t len = URI_MAX; ret = get_norm_path(uri, path, &len); if (ret < 0) { - log_error("Could not normalize path (%s): %s\n", uri, pal_strerror(-ret)); + log_error("Could not normalize path (%s): %s\n", uri, pal_strerror(ret)); goto out; } diff --git a/Pal/src/host/Linux-SGX/db_mutex.c b/Pal/src/host/Linux-SGX/db_mutex.c index 7a732bb6c2..5798605520 100644 --- a/Pal/src/host/Linux-SGX/db_mutex.c +++ b/Pal/src/host/Linux-SGX/db_mutex.c @@ -96,8 +96,7 @@ int _DkMutexAcquireTimeout(PAL_HANDLE handle, int64_t timeout_us) { return _DkMutexLockTimeout(&handle->mutex.mut, timeout_us); } -int _DkMutexUnlock(struct mutex_handle* m) { - int ret = 0; +void _DkMutexUnlock(struct mutex_handle* m) { int need_wake; /* Unlock */ @@ -108,16 +107,10 @@ int _DkMutexUnlock(struct mutex_handle* m) { /* If we need to wake someone up... */ if (need_wake) ocall_futex(m->locked, FUTEX_WAKE, 1, -1); - - return ret; } void _DkMutexRelease(PAL_HANDLE handle) { - struct mutex_handle* mut = &handle->mutex.mut; - int ret = _DkMutexUnlock(mut); - if (ret < 0) - _DkRaiseFailure(ret); - return; + _DkMutexUnlock(&handle->mutex.mut); } static int mutex_wait(PAL_HANDLE handle, int64_t timeout_us) { diff --git a/Pal/src/host/Linux-SGX/enclave_framework.c b/Pal/src/host/Linux-SGX/enclave_framework.c index 23ffe0831b..488578eec1 100644 --- a/Pal/src/host/Linux-SGX/enclave_framework.c +++ b/Pal/src/host/Linux-SGX/enclave_framework.c @@ -327,7 +327,7 @@ int load_trusted_file(PAL_HANDLE file, sgx_stub_t** stubptr, uint64_t* sizeptr, ret = get_norm_path(uri + URI_PREFIX_FILE_LEN, normpath + URI_PREFIX_FILE_LEN, &len); if (ret < 0) { log_error("Path (%s) normalization failed: %s\n", uri + URI_PREFIX_FILE_LEN, - pal_strerror(-ret)); + pal_strerror(ret)); return ret; } len += URI_PREFIX_FILE_LEN; @@ -746,7 +746,7 @@ static int init_trusted_file(const char* key, const char* uri) { ret = get_norm_path(uri + URI_PREFIX_FILE_LEN, normpath + URI_PREFIX_FILE_LEN, &len); if (ret < 0) { log_error("Path (%s) normalization failed: %s\n", uri + URI_PREFIX_FILE_LEN, - pal_strerror(-ret)); + pal_strerror(ret)); goto out; } @@ -876,7 +876,7 @@ int init_trusted_files(void) { if (ret < 0) { log_error("Path (%s) normalization failed: %s\n", - toml_allowed_file_str + URI_PREFIX_FILE_LEN, pal_strerror(-ret)); + toml_allowed_file_str + URI_PREFIX_FILE_LEN, pal_strerror(ret)); return ret; } diff --git a/Pal/src/host/Linux-SGX/enclave_ocalls.c b/Pal/src/host/Linux-SGX/enclave_ocalls.c index 021b2ec5f2..32cce6faf7 100644 --- a/Pal/src/host/Linux-SGX/enclave_ocalls.c +++ b/Pal/src/host/Linux-SGX/enclave_ocalls.c @@ -1348,15 +1348,13 @@ int ocall_sleep(uint64_t* microsec) { /* NOTE: no reason to use exitless for sleep() */ retval = sgx_ocall(OCALL_SLEEP, ms); if (microsec) { - if (!retval) { - *microsec = 0; - } else if (retval == -EINTR) { - uint64_t untrusted_microsec = READ_ONCE(ms->ms_microsec); - if (*microsec < untrusted_microsec) { + if (retval) { + uint64_t untrusted_microsec_remaining = READ_ONCE(ms->ms_microsec); + if (*microsec < untrusted_microsec_remaining) { retval = -EPERM; goto out; } - *microsec = untrusted_microsec; + *microsec -= untrusted_microsec_remaining; } } diff --git a/Pal/src/host/Linux-SGX/enclave_pages.c b/Pal/src/host/Linux-SGX/enclave_pages.c index 6c8a4a040c..959bc7a260 100644 --- a/Pal/src/host/Linux-SGX/enclave_pages.c +++ b/Pal/src/host/Linux-SGX/enclave_pages.c @@ -198,7 +198,7 @@ void* get_enclave_pages(void* addr, size_t size, bool is_pal_internal) { if (is_pal_internal && size > g_pal_internal_mem_size - g_pal_internal_mem_used) { /* requested PAL-internal allocation would exceed the limit, fail */ - return NULL; + goto out; } if (addr) { diff --git a/Pal/src/host/Linux-SGX/enclave_pf.c b/Pal/src/host/Linux-SGX/enclave_pf.c index f2ed0aff98..a4f771e064 100644 --- a/Pal/src/host/Linux-SGX/enclave_pf.c +++ b/Pal/src/host/Linux-SGX/enclave_pf.c @@ -334,7 +334,7 @@ static int register_protected_path(const char* path, struct protected_file** new size_t len = URI_MAX; ret = get_norm_path(path, normpath, &len); if (ret < 0) { - log_error("Couldn't normalize path (%s): %s\n", path, pal_strerror(-ret)); + log_error("Couldn't normalize path (%s): %s\n", path, pal_strerror(ret)); goto out; } diff --git a/Pal/src/host/Linux-SGX/pal_linux.h b/Pal/src/host/Linux-SGX/pal_linux.h index 10bec79603..18ead3ab3c 100644 --- a/Pal/src/host/Linux-SGX/pal_linux.h +++ b/Pal/src/host/Linux-SGX/pal_linux.h @@ -75,7 +75,7 @@ int _DkMutexAtomicCreate(struct mutex_handle* mut); int __DkMutexDestroy(struct mutex_handle* mut); int _DkMutexLock(struct mutex_handle* mut); int _DkMutexLockTimeout(struct mutex_handle* mut, int64_t timeout_us); -int _DkMutexUnlock(struct mutex_handle* mut); +void _DkMutexUnlock(struct mutex_handle* mut); int* get_futex(void); void free_futex(int* futex); diff --git a/Pal/src/host/Linux/db_exception.c b/Pal/src/host/Linux/db_exception.c index 205e7c0e32..04c30519dd 100644 --- a/Pal/src/host/Linux/db_exception.c +++ b/Pal/src/host/Linux/db_exception.c @@ -159,15 +159,6 @@ static void handle_async_signal(int signum, siginfo_t* info, struct ucontext* uc perform_signal_handling(event, ADDR_IN_PAL_OR_VDSO(rip), /*addr=*/0, uc); } -/* TODO: remove this function. It's not an exception handling, it's just returning an error from - * PAL... */ -void _DkRaiseFailure(int error) { - PAL_EVENT_HANDLER upcall = _DkGetExceptionHandler(PAL_EVENT_FAILURE); - if (upcall) { - (*upcall)(/*is_in_pal=*/false, error, /*context=*/NULL); - } -} - void signal_setup(void) { int ret; diff --git a/Pal/src/host/Linux/db_mutex.c b/Pal/src/host/Linux/db_mutex.c index 40432be356..2b235c9963 100644 --- a/Pal/src/host/Linux/db_mutex.c +++ b/Pal/src/host/Linux/db_mutex.c @@ -151,8 +151,7 @@ int _DkMutexAcquireTimeout(PAL_HANDLE handle, int64_t timeout_us) { return _DkMutexLockTimeout(&handle->mutex.mut, timeout_us); } -int _DkMutexUnlock(struct mutex_handle* m) { - int ret = 0; +void _DkMutexUnlock(struct mutex_handle* m) { int need_wake; #ifdef DEBUG_MUTEX @@ -167,13 +166,10 @@ int _DkMutexUnlock(struct mutex_handle* m) { /* If we need to wake someone up... */ if (need_wake) INLINE_SYSCALL(futex, 6, &m->locked, FUTEX_WAKE, 1, NULL, NULL, 0); - - return ret; } void _DkMutexRelease(PAL_HANDLE handle) { _DkMutexUnlock(&handle->mutex.mut); - return; } static bool _DkMutexIsLocked(struct mutex_handle* m) { diff --git a/Pal/src/host/Linux/pal_host.h b/Pal/src/host/Linux/pal_host.h index b0c24f3162..3dce04f5da 100644 --- a/Pal/src/host/Linux/pal_host.h +++ b/Pal/src/host/Linux/pal_host.h @@ -43,7 +43,7 @@ typedef struct mutex_handle { /* Locking and unlocking of Mutexes */ int _DkMutexLock(struct mutex_handle* mut); int _DkMutexLockTimeout(struct mutex_handle* mut, int64_t timeout_us); -int _DkMutexUnlock(struct mutex_handle* mut); +void _DkMutexUnlock(struct mutex_handle* mut); typedef struct { PAL_HDR hdr; diff --git a/Pal/src/host/Skeleton/db_exception.c b/Pal/src/host/Skeleton/db_exception.c index 1d0be5f527..a8a1d407f5 100644 --- a/Pal/src/host/Skeleton/db_exception.c +++ b/Pal/src/host/Skeleton/db_exception.c @@ -21,9 +21,4 @@ int (*_DkExceptionHandlers[PAL_EVENT_NUM_BOUND])(int, PAL_UPCALL, int) = { /* Illegal */ NULL, /* Quit */ NULL, /* Interrupt */ NULL, - /* Failure */ NULL, }; - -void _DkRaiseFailure(int error) { - /* needs to be implemented */ -} diff --git a/Pal/src/host/Skeleton/db_mutex.c b/Pal/src/host/Skeleton/db_mutex.c index 7efe28644d..c39bfefe6b 100644 --- a/Pal/src/host/Skeleton/db_mutex.c +++ b/Pal/src/host/Skeleton/db_mutex.c @@ -23,8 +23,8 @@ int _DkMutexAcquireTimeout(PAL_HANDLE handle, int64_t timeout_us) { return -PAL_ERROR_NOTIMPLEMENTED; } -int _DkMutexUnlock(struct mutex_handle* m) { - return -PAL_ERROR_NOTIMPLEMENTED; +void _DkMutexUnlock(struct mutex_handle* m) { + /* Not implemented yet */ } void _DkMutexRelease(PAL_HANDLE handle) { diff --git a/Pal/src/host/Skeleton/pal_host.h b/Pal/src/host/Skeleton/pal_host.h index fa1a082196..009c2dd942 100644 --- a/Pal/src/host/Skeleton/pal_host.h +++ b/Pal/src/host/Skeleton/pal_host.h @@ -22,7 +22,7 @@ typedef struct mutex_handle { /* Locking and unlocking of mutexes */ int _DkMutexLock(struct mutex_handle* mut); int _DkMutexLockTimeout(struct mutex_handle* mut, int64_t timeout_us); -int _DkMutexUnlock(struct mutex_handle* mut); +void _DkMutexUnlock(struct mutex_handle* mut); typedef struct pal_handle { /* TSAI: Here we define the internal types of PAL_HANDLE in PAL design, user has not to access diff --git a/Pal/src/pal_error.c b/Pal/src/pal_error.c index beeb4af898..e80de544b5 100644 --- a/Pal/src/pal_error.c +++ b/Pal/src/pal_error.c @@ -1,67 +1,60 @@ /* SPDX-License-Identifier: LGPL-3.0-or-later */ /* Copyright (C) 2014 Stony Brook University */ +#include "api.h" #include "pal_error.h" #include "assert.h" -struct pal_error_description { - int error; - const char* description; -}; - -static const struct pal_error_description g_pal_error_list[] = { - {PAL_ERROR_SUCCESS, "Success"}, - {PAL_ERROR_NOTIMPLEMENTED, "Function not implemented"}, - {PAL_ERROR_NOTDEFINED, "Symbol not defined"}, - {PAL_ERROR_NOTSUPPORT, "Function not supported"}, - {PAL_ERROR_INVAL, "Invalid argument"}, - {PAL_ERROR_TOOLONG, "Name/path is too long"}, - {PAL_ERROR_DENIED, "Operation denied"}, - {PAL_ERROR_BADHANDLE, "Handle corrupted"}, - {PAL_ERROR_STREAMEXIST, "Stream already exists"}, - {PAL_ERROR_STREAMNOTEXIST, "Stream does not exist"}, - {PAL_ERROR_STREAMISFILE, "Stream is a file"}, - {PAL_ERROR_STREAMISDIR, "Stream is a directory"}, - {PAL_ERROR_STREAMISDEVICE, "Stream is a device"}, - {PAL_ERROR_INTERRUPTED, "Operation interrupted"}, - {PAL_ERROR_OVERFLOW, "Buffer overflowed"}, - {PAL_ERROR_BADADDR, "Invalid address"}, - {PAL_ERROR_NOMEM, "Not enough memory"}, - {PAL_ERROR_NOTKILLABLE, "Thread state unkillable"}, - {PAL_ERROR_INCONSIST, "Inconsistent system state"}, - {PAL_ERROR_TRYAGAIN, "Try again"}, - {PAL_ERROR_NOTSERVER, "Not a server"}, - {PAL_ERROR_NOTCONNECTION, "Not a connection"}, - {PAL_ERROR_CONNFAILED, "Connection failed"}, - {PAL_ERROR_ADDRNOTEXIST, "Resource address does not exist"}, - {PAL_ERROR_AFNOSUPPORT, "Address family not supported by protocol"}, - {PAL_ERROR_CONNFAILED_PIPE, "Broken pipe"}, +static const char* g_pal_error_list[] = { + [PAL_ERROR_SUCCESS] = "Success", + [PAL_ERROR_NOTIMPLEMENTED] = "Function not implemented", + [PAL_ERROR_NOTDEFINED] = "Symbol not defined", + [PAL_ERROR_NOTSUPPORT] = "Function not supported", + [PAL_ERROR_INVAL] = "Invalid argument", + [PAL_ERROR_TOOLONG] = "Name/path is too long", + [PAL_ERROR_DENIED] = "Operation denied", + [PAL_ERROR_BADHANDLE] = "Handle corrupted", + [PAL_ERROR_STREAMEXIST] = "Stream already exists", + [PAL_ERROR_STREAMNOTEXIST] = "Stream does not exist", + [PAL_ERROR_STREAMISFILE] = "Stream is a file", + [PAL_ERROR_STREAMISDIR] = "Stream is a directory", + [PAL_ERROR_STREAMISDEVICE] = "Stream is a device", + [PAL_ERROR_INTERRUPTED] = "Operation interrupted", + [PAL_ERROR_OVERFLOW] = "Buffer overflowed", + [PAL_ERROR_BADADDR] = "Invalid address", + [PAL_ERROR_NOMEM] = "Not enough memory", + [PAL_ERROR_INCONSIST] = "Inconsistent system state", + [PAL_ERROR_TRYAGAIN] = "Try again", + [PAL_ERROR_NOTSERVER] = "Not a server", + [PAL_ERROR_NOTCONNECTION] = "Not a connection", + [PAL_ERROR_CONNFAILED] = "Connection failed", + [PAL_ERROR_ADDRNOTEXIST] = "Resource address does not exist", + [PAL_ERROR_AFNOSUPPORT] = "Address family not supported by protocol", + [PAL_ERROR_CONNFAILED_PIPE] = "Broken pipe", - {PAL_ERROR_CRYPTO_FEATURE_UNAVAILABLE, "[Crypto] Feature not available"}, - {PAL_ERROR_CRYPTO_INVALID_CONTEXT, "[Crypto] Invalid context"}, - {PAL_ERROR_CRYPTO_INVALID_KEY_LENGTH, "[Crypto] Invalid key length"}, - {PAL_ERROR_CRYPTO_INVALID_INPUT_LENGTH, "[Crypto] Invalid input length"}, - {PAL_ERROR_CRYPTO_INVALID_OUTPUT_LENGTH, "[Crypto] Invalid output length"}, - {PAL_ERROR_CRYPTO_BAD_INPUT_DATA, "[Crypto] Bad input parameters"}, - {PAL_ERROR_CRYPTO_INVALID_PADDING, "[Crypto] Invalid padding"}, - {PAL_ERROR_CRYPTO_DATA_MISALIGNED, "[Crypto] Data misaligned"}, - {PAL_ERROR_CRYPTO_INVALID_FORMAT, "[Crypto] Invalid data format"}, - {PAL_ERROR_CRYPTO_AUTH_FAILED, "[Crypto] Authentication failed"}, - {PAL_ERROR_CRYPTO_IO_ERROR, "[Crypto] I/O error"}, - {PAL_ERROR_CRYPTO_KEY_GEN_FAILED, "[Crypto] Key generation failed"}, - {PAL_ERROR_CRYPTO_INVALID_KEY, "[Crypto] Invalid key"}, - {PAL_ERROR_CRYPTO_VERIFY_FAILED, "[Crypto] Verification failed"}, - {PAL_ERROR_CRYPTO_RNG_FAILED, "[Crypto] RNG failed to generate data"}, - {PAL_ERROR_CRYPTO_INVALID_DH_STATE, "[Crypto] Invalid DH state"}, + [PAL_ERROR_CRYPTO_FEATURE_UNAVAILABLE] = "[Crypto] Feature not available", + [PAL_ERROR_CRYPTO_INVALID_CONTEXT] = "[Crypto] Invalid context", + [PAL_ERROR_CRYPTO_INVALID_KEY_LENGTH] = "[Crypto] Invalid key length", + [PAL_ERROR_CRYPTO_INVALID_INPUT_LENGTH] = "[Crypto] Invalid input length", + [PAL_ERROR_CRYPTO_INVALID_OUTPUT_LENGTH] = "[Crypto] Invalid output length", + [PAL_ERROR_CRYPTO_BAD_INPUT_DATA] = "[Crypto] Bad input parameters", + [PAL_ERROR_CRYPTO_INVALID_PADDING] = "[Crypto] Invalid padding", + [PAL_ERROR_CRYPTO_DATA_MISALIGNED] = "[Crypto] Data misaligned", + [PAL_ERROR_CRYPTO_INVALID_FORMAT] = "[Crypto] Invalid data format", + [PAL_ERROR_CRYPTO_AUTH_FAILED] = "[Crypto] Authentication failed", + [PAL_ERROR_CRYPTO_IO_ERROR] = "[Crypto] I/O error", + [PAL_ERROR_CRYPTO_KEY_GEN_FAILED] = "[Crypto] Key generation failed", + [PAL_ERROR_CRYPTO_INVALID_KEY] = "[Crypto] Invalid key", + [PAL_ERROR_CRYPTO_VERIFY_FAILED] = "[Crypto] Verification failed", + [PAL_ERROR_CRYPTO_RNG_FAILED] = "[Crypto] RNG failed to generate data", + [PAL_ERROR_CRYPTO_INVALID_DH_STATE] = "[Crypto] Invalid DH state", }; -#define PAL_ERROR_COUNT (sizeof(g_pal_error_list) / sizeof(g_pal_error_list[0])) - const char* pal_strerror(int err) { - assert(err >= 0); - for (size_t i = 0; i < PAL_ERROR_COUNT; i++) - if (g_pal_error_list[i].error == err) - return g_pal_error_list[i].description; - return "Unknown error"; + unsigned err_idx = err >= 0 ? err : -err; + if (err_idx >= ARRAY_SIZE(g_pal_error_list) || !g_pal_error_list[err_idx]) { + return "Unknown error"; + } + return g_pal_error_list[err_idx]; } diff --git a/Pal/src/pal_internal.h b/Pal/src/pal_internal.h index b3a04865fb..22acc2a437 100644 --- a/Pal/src/pal_internal.h +++ b/Pal/src/pal_internal.h @@ -222,7 +222,6 @@ int _DkVirtualMemoryFree(void* addr, uint64_t size); int _DkVirtualMemoryProtect(void* addr, uint64_t size, int prot); /* DkObject calls */ -int _DkObjectReference(PAL_HANDLE objectHandle); int _DkObjectClose(PAL_HANDLE objectHandle); int _DkSynchronizationObjectWait(PAL_HANDLE handle, int64_t timeout_us); int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events, @@ -230,7 +229,6 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events /* DkException calls & structures */ PAL_EVENT_HANDLER _DkGetExceptionHandler(PAL_NUM event_num); -void _DkRaiseFailure(int error); /* other DK calls */ void _DkInternalLock(PAL_LOCK* mut);