Skip to content

Commit

Permalink
i#58 MacOS: Mac signal handling code, part 1:
Browse files Browse the repository at this point in the history
Puts some pieces in place, like the signal lists, but is missing context
and floating-point support.

Added assert that sigset struct matches int for the type difference.

SVN-Revision: 2313
  • Loading branch information
derekbruening committed Oct 8, 2013
1 parent dac617c commit 944e398
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 22 deletions.
1 change: 1 addition & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ if (UNIX)
set(OS_SRCS ${OS_SRCS} unix/memquery_macos.c)
set(OS_SRCS ${OS_SRCS} unix/ksynch_macos.c)
set(OS_SRCS ${OS_SRCS} unix/tls_macos.c)
set(OS_SRCS ${OS_SRCS} unix/signal_macos.c)
elseif (VMKERNEL)
set(VMKUW_DIR ${PROJECT_SOURCE_DIR}/../internal/core/linux)
include_directories(${VMKUW_DIR})
Expand Down
10 changes: 10 additions & 0 deletions core/lib/globals_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,16 @@ typedef struct _instr_t instr_t;
# define IF_LINUX_(x)
#endif

#ifdef MACOS
# define IF_MACOS(x) x
# define IF_MACOS_ELSE(x,y) x
# define IF_MACOS_(x) x,
#else
# define IF_MACOS(x)
# define IF_MACOS_ELSE(x,y) y
# define IF_MACOS_(x)
#endif

#ifdef HAVE_MEMINFO_QUERY
# define IF_MEMQUERY(x) x
# define IF_MEMQUERY_(x) x,
Expand Down
10 changes: 9 additions & 1 deletion core/unix/os_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ bool unhook_vsyscall(void);

#define NUM_NONRT 32 /* includes 0 */
#define OFFS_RT 32
#define NUM_RT 33 /* RT signals are [32..64] inclusive, hence 33. */
#ifdef LINUX
# define NUM_RT 33 /* RT signals are [32..64] inclusive, hence 33. */
#else
# define NUM_RT 0 /* no RT signals */
#endif
/* MAX_SIGNUM is the highest valid signum. */
#define MAX_SIGNUM ((OFFS_RT) + (NUM_RT) - 1)
/* i#336: MAX_SIGNUM is a valid signal, so we must allocate space for it.
Expand All @@ -229,7 +233,11 @@ bool unhook_vsyscall(void);
* each (-> 8 bytes vs. 128 bytes)
*/
typedef struct _kernel_sigset_t {
#ifdef LINUX
unsigned long sig[_NSIG_WORDS];
#elif defined(MACOS)
unsigned int sig[_NSIG_WORDS];
#endif
} kernel_sigset_t;

void receive_pending_signal(dcontext_t *dcontext);
Expand Down
66 changes: 54 additions & 12 deletions core/unix/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,16 @@

#include "signal_private.h" /* pulls in globals.h for us, in right order */

#if !defined(LINUX) && !defined(MACOS)
# error Unknown operating system
#ifdef LINUX
/* We want to build on older toolchains so we have our own copy of signal
* data structures
*/
# include "include/sigcontext.h"
# include "include/signalfd.h"
# include "../globals.h" /* after our sigcontext.h, to preclude bits/sigcontext.h */
#elif defined(MACOS)
# include "../globals.h" /* this defines _XOPEN_SOURCE for Mac */
# include <signal.h> /* after globals.h, for _XOPEN_SOURCE from os_exports.h */
#endif

#ifdef LINUX
Expand All @@ -58,7 +66,6 @@
#include <sys/wait.h>
#include <ucontext.h>
#include <string.h> /* for memcpy and memset */
#include "../globals.h"
#include "os_private.h"
#include "../fragment.h"
#include "../fcache.h"
Expand All @@ -84,6 +91,12 @@
# include <errno.h>
#endif

#ifdef MACOS
/* Define the Linux names, which the code is already using */
# define SA_NOMASK SA_NODEFER
# define SA_ONESHOT SA_RESETHAND
#endif

/**** data structures ***************************************************/

/* The signal numbers are slightly different between operating systems.
Expand Down Expand Up @@ -117,9 +130,13 @@ sig_is_alarm_signal(int sig)
#define SA_RESTORER 0x04000000

/* if no app sigaction, it's RT, since that's our handler */
#define IS_RT_FOR_APP(info, sig) \
#ifdef LINUX
# define IS_RT_FOR_APP(info, sig) \
IF_X64_ELSE(true, ((info)->app_sigaction[(sig)] == NULL ? true : \
(TEST(SA_SIGINFO, (info)->app_sigaction[(sig)]->flags))))
#elif defined(MACOS)
# define IS_RT_FOR_APP(info, sig) (true)
#endif

/* kernel sets size and sp to 0 for SS_DISABLE
* when asked, will hand back SS_ONSTACK only if current xsp is inside the
Expand All @@ -135,14 +152,28 @@ sig_is_alarm_signal(int sig)
* assume the stack pointer is 4-aligned already, so we over estimate padding
* size by the alignment minus 4.
*/
#ifdef LINUX
/* An extra 4 for trailing FP_XSTATE_MAGIC2 */
#define AVX_FRAME_EXTRA (sizeof(struct _xstate) + AVX_ALIGNMENT - 4 + 4)
#define FPSTATE_FRAME_EXTRA (sizeof(struct _fpstate) + FPSTATE_ALIGNMENT - 4)
#define XSTATE_FRAME_EXTRA (YMM_ENABLED() ? AVX_FRAME_EXTRA : FPSTATE_FRAME_EXTRA)

#define AVX_DATA_SIZE (sizeof(struct _xstate) + 4)
#define FPSTATE_DATA_SIZE (sizeof(struct _fpstate))
#define XSTATE_DATA_SIZE (YMM_ENABLED() ? AVX_DATA_SIZE : FPSTATE_DATA_SIZE)
# define AVX_FRAME_EXTRA (sizeof(struct _xstate) + AVX_ALIGNMENT - 4 + 4)
# define FPSTATE_FRAME_EXTRA (sizeof(struct _fpstate) + FPSTATE_ALIGNMENT - 4)
# define XSTATE_FRAME_EXTRA (YMM_ENABLED() ? AVX_FRAME_EXTRA : FPSTATE_FRAME_EXTRA)

# define AVX_DATA_SIZE (sizeof(struct _xstate) + 4)
# define FPSTATE_DATA_SIZE (sizeof(struct _fpstate))
# define XSTATE_DATA_SIZE (YMM_ENABLED() ? AVX_DATA_SIZE : FPSTATE_DATA_SIZE)

#elif defined(MACOS)
/* Currently assuming __darwin_mcontext_avx{32,64} is always used in the
* frame. If instead __darwin_mcontext{32,64} is used (w/ just float and no AVX)
* on, say, older machines or OSX versions, we'll have to revisit this.
*/
# define AVX_FRAME_EXTRA 0
# define FPSTATE_FRAME_EXTRA 0
# define XSTATE_FRAME_EXTRA 0
# define AVX_DATA_SIZE 0
# define FPSTATE_DATA_SIZE 0
# define XSTATE_DATA_SIZE 0
#endif

/* If we only intercept a few signals, we leave whether un-intercepted signals
* are blocked unchanged and stored in the kernel. If we intercept all (not
Expand Down Expand Up @@ -356,6 +387,7 @@ void
signal_init()
{
IF_LINUX(IF_X64(ASSERT(ALIGNED(offsetof(sigpending_t, xstate), AVX_ALIGNMENT))));
IF_MACOS(ASSERT(sizeof(kernel_sigset_t) == sizeof(__darwin_sigset_t)));
os_itimers_thread_shared();

/* Set up a handler for safe_read (or other fault detection) during
Expand Down Expand Up @@ -1772,13 +1804,17 @@ thread_set_self_context(void *cxt)
* kernel 2.6.23.9 at least so we leave frame.uc.uc_stack as all zeros.
*/
/* make sure sigreturn's mask setting doesn't change anything */
sigprocmask_syscall(SIG_SETMASK, NULL, &frame.uc.uc_sigmask,
sigprocmask_syscall(SIG_SETMASK, NULL, (kernel_sigset_t *) &frame.uc.uc_sigmask,
sizeof(frame.uc.uc_sigmask));
LOG(THREAD_GET, LOG_ASYNCH, 2, "thread_set_self_context: pc="PFX"\n", sc->SC_XIP);
/* set up xsp to point at &frame + sizeof(char*) */
xsp_for_sigreturn = ((app_pc)&frame) + sizeof(char*);
asm("mov %0, %%"ASM_XSP : : "m"(xsp_for_sigreturn));
#ifdef MACOS
asm("jmp _dynamorio_sigreturn");
#else
asm("jmp dynamorio_sigreturn");
#endif
ASSERT_NOT_REACHED();
}

Expand Down Expand Up @@ -2090,6 +2126,8 @@ fixup_rtframe_pointers(dcontext_t *dcontext, int sig,
# endif
/* 32-bit kernel copies to aligned buf first */
IF_X64(ASSERT(ALIGNED(f_new->uc.uc_mcontext.fpstate, 16)));
#elif defined(MACOS)
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#85: fix up uc_mcontext ptr */
#endif /* LINUX */
}

Expand Down Expand Up @@ -5249,7 +5287,11 @@ handle_suspend_signal(dcontext_t *dcontext, kernel_ucontext_t *ucxt)
#endif
} else {
ksynch_set_value(&ostd->terminated, 1);
#ifdef MACOS
asm("jmp _dynamorio_sys_exit");
#else
asm("jmp dynamorio_sys_exit");
#endif
}
ASSERT_NOT_REACHED();
return false;
Expand Down
142 changes: 142 additions & 0 deletions core/unix/signal_macos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/* *******************************************************************************
* Copyright (c) 2013 Google, Inc. All rights reserved.
* *******************************************************************************/

/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of VMware, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/

/*
* signal_macos.c - MacOS-specific signal code
*
* FIXME i#58: NYI (see comments below as well):
* + many pieces are not at all implemented, but it should be straightforward
* + longer-term i#1291: use raw syscalls instead of libSystem wrappers
*/

#include "signal_private.h" /* pulls in globals.h for us, in right order */

#ifndef MACOS
# error Mac-only
#endif

/* based on xnu bsd/sys/signalvar.h */
int default_action[] = {
0, /* 0 unused */
DEFAULT_TERMINATE, /* 1 SIGHUP */
DEFAULT_TERMINATE, /* 2 SIGINT */
DEFAULT_TERMINATE_CORE, /* 3 SIGQUIT */
DEFAULT_TERMINATE_CORE, /* 4 SIGILL */
DEFAULT_TERMINATE_CORE, /* 5 SIGTRAP */
DEFAULT_TERMINATE_CORE, /* 6 SIGABRT/SIGIOT */
DEFAULT_TERMINATE_CORE, /* 7 SIGEMT/SIGPOLL */
DEFAULT_TERMINATE_CORE, /* 8 SIGFPE */
DEFAULT_TERMINATE, /* 9 SIGKILL */
DEFAULT_TERMINATE_CORE, /* 10 SIGBUS */
DEFAULT_TERMINATE_CORE, /* 11 SIGSEGV */
DEFAULT_TERMINATE_CORE, /* 12 SIGSYS */
DEFAULT_TERMINATE, /* 13 SIGPIPE */
DEFAULT_TERMINATE, /* 14 SIGALRM */
DEFAULT_TERMINATE, /* 15 SIGTERM */
DEFAULT_IGNORE, /* 16 SIGURG */
DEFAULT_STOP, /* 17 SIGSTOP */
DEFAULT_STOP, /* 18 SIGTSTP */
DEFAULT_CONTINUE, /* 19 SIGCONT */
DEFAULT_IGNORE, /* 20 SIGCHLD */
DEFAULT_STOP, /* 21 SIGTTIN */
DEFAULT_STOP, /* 22 SIGTTOU */
DEFAULT_IGNORE, /* 23 SIGIO */
DEFAULT_TERMINATE, /* 24 SIGXCPU */
DEFAULT_TERMINATE, /* 25 SIGXFSZ */
DEFAULT_TERMINATE, /* 26 SIGVTALRM */
DEFAULT_TERMINATE, /* 27 SIGPROF */
DEFAULT_IGNORE, /* 28 SIGWINCH */
DEFAULT_IGNORE, /* 29 SIGINFO */
DEFAULT_TERMINATE, /* 30 SIGUSR1 */
DEFAULT_TERMINATE, /* 31 SIGUSR2 */
/* no real-time support */
};

bool can_always_delay[] = {
true, /* 0 unused */
true, /* 1 SIGHUP */
true, /* 2 SIGINT */
true, /* 3 SIGQUIT */
false, /* 4 SIGILL */
false, /* 5 SIGTRAP */
false, /* 6 SIGABRT/SIGIOT */
true, /* 7 SIGEMT/SIGPOLL */
false, /* 8 SIGFPE */
true, /* 9 SIGKILL */
false, /* 10 SIGBUS */
false, /* 11 SIGSEGV */
false, /* 12 SIGSYS */
false, /* 13 SIGPIPE */
true, /* 14 SIGALRM */
true, /* 15 SIGTERM */
true, /* 16 SIGURG */
true, /* 17 SIGSTOP */
true, /* 18 SIGTSTP */
true, /* 19 SIGCONT */
true, /* 20 SIGCHLD */
true, /* 21 SIGTTIN */
true, /* 22 SIGTTOU */
true, /* 23 SIGIO */
false, /* 24 SIGXCPU */
true, /* 25 SIGXFSZ */
true, /* 26 SIGVTALRM */
true, /* 27 SIGPROF */
true, /* 28 SIGWINCH */
true, /* 29 SIGINFO */
true, /* 30 SIGUSR1 */
true, /* 31 SIGUSR2 */
/* no real-time support */
};

void
save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame)
{
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#58: MacOS signal handling NYI */
}

void
sigcontext_to_mcontext_mm(priv_mcontext_t *mc, sigcontext_t *sc)
{
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#58: MacOS signal handling NYI */
}

void
mcontext_to_sigcontext_mm(sigcontext_t *sc, priv_mcontext_t *mc)
{
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#58: MacOS signal handling NYI */
}

void
dump_sigcontext(dcontext_t *dcontext, sigcontext_t *sc)
{
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#58: MacOS signal handling NYI */
}
Loading

0 comments on commit 944e398

Please sign in to comment.