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[])