Print this page
OS-4470 lxbrand unblocking signals in new threads must be atomic

*** 496,505 **** --- 496,526 ---- lx_err_fatal("Unable to initialize thread-specific data: %s", strerror(err)); } } + void + lx_jump_to_linux(ucontext_t *ucp) + { + extern void setcontext_sigmask(ucontext_t *); + + /* + * Call into this private libc interface to allow us to use only the + * signal mask handling part of a regular setcontext() operation. + */ + setcontext_sigmask(ucp); + + if (syscall(SYS_brand, B_JUMP_TO_LINUX, ucp) != 0) { + lx_err_fatal("B_JUMP_TO_LINUX failed: %s", strerror(errno)); + } + + /* + * This system call should not return. + */ + abort(); + } + static void lx_start(uintptr_t sp, uintptr_t entry) { ucontext_t jump_uc;
*** 528,546 **** */ LX_REG(&jump_uc, REG_RDX) = NULL; #endif lx_debug("starting Linux program sp %p ldentry %p", sp, entry); ! ! /* ! * This system call should not return. ! */ ! if (syscall(SYS_brand, B_JUMP_TO_LINUX, &jump_uc) == -1) { ! lx_err_fatal("B_JUMP_TO_LINUX failed: %s", ! strerror(errno)); ! } ! abort(); } /*ARGSUSED*/ int lx_init(int argc, char *argv[], char *envp[]) --- 549,559 ---- */ LX_REG(&jump_uc, REG_RDX) = NULL; #endif lx_debug("starting Linux program sp %p ldentry %p", sp, entry); ! lx_jump_to_linux(&jump_uc); } /*ARGSUSED*/ int lx_init(int argc, char *argv[], char *envp[])