ocaml/asmrun/signals_osdep.h

265 lines
8.3 KiB
C

/***********************************************************************/
/* */
/* Objective Caml */
/* */
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
/* */
/* Copyright 2004 Institut National de Recherche en Informatique et */
/* en Automatique. All rights reserved. This file is distributed */
/* under the terms of the GNU Library General Public License, with */
/* the special exception on linking described in file ../LICENSE. */
/* */
/***********************************************************************/
/* $Id$ */
/* Processor- and OS-dependent signal interface */
/****************** Alpha, all OS */
#if defined(TARGET_alpha)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, int code, struct sigcontext * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = 0
typedef long context_reg;
#define CONTEXT_PC (context->sc_pc)
#define CONTEXT_EXCEPTION_POINTER (context->sc_regs[15])
#define CONTEXT_YOUNG_LIMIT (context->sc_regs[13])
#define CONTEXT_YOUNG_PTR (context->sc_regs[14])
/****************** AMD64, Linux */
#elif defined(TARGET_amd64) && defined (SYS_linux)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, siginfo_t * info, ucontext_t * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \
sigact.sa_flags = SA_SIGINFO
typedef greg_t context_reg;
#define CONTEXT_PC (context->uc_mcontext.gregs[REG_RIP])
#define CONTEXT_EXCEPTION_POINTER (context->uc_mcontext.gregs[REG_R14])
#define CONTEXT_YOUNG_PTR (context->uc_mcontext.gregs[REG_R15])
#define CONTEXT_FAULTING_ADDRESS ((char *) context->uc_mcontext.gregs[REG_CR2])
/****************** I386, Linux */
#elif defined(TARGET_i386) && defined(SYS_linux_elf)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, struct sigcontext context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = 0
#define CONTEXT_FAULTING_ADDRESS ((char *) context.cr2)
/****************** I386, BSD */
#elif defined(TARGET_i386) && defined(SYS_bsd)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, siginfo_t * info, void * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_sigaction = (name);
sigact.sa_flags = SA_SIGINFO
#define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr)
/****************** MIPS, all OS */
#elif defined(TARGET_mips)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, int code, struct sigcontext * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = 0
typedef int context_reg;
#define CONTEXT_PC (context->sc_pc)
#define CONTEXT_EXCEPTION_POINTER (context->sc_regs[30])
#define CONTEXT_YOUNG_LIMIT (context->sc_regs[22])
#define CONTEXT_YOUNG_PTR (context->sc_regs[23])
/****************** PowerPC, MacOS X */
#elif defined(TARGET_power) && defined(SYS_rhapsody)
#ifdef __ppc64__
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, siginfo_t * info, void * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_sigaction = (name); \
sigact.sa_flags = SA_SIGINFO | SA_64REGSET
typedef unsigned long long context_reg;
#include <sys/ucontext.h>
#define CONTEXT_STATE (((struct ucontext64 *)context)->uc_mcontext64->ss)
#define CONTEXT_PC (CONTEXT_STATE.srr0)
#define CONTEXT_EXCEPTION_POINTER (CONTEXT_STATE.r29)
#define CONTEXT_YOUNG_LIMIT (CONTEXT_STATE.r30)
#define CONTEXT_YOUNG_PTR (CONTEXT_STATE.r31)
#define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr)
#else
#include <sys/utsname.h>
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, siginfo_t * info, void * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = SA_SIGINFO
typedef unsigned long context_reg;
#define CONTEXT_PC (*context_gpr_p(context, -2))
#define CONTEXT_EXCEPTION_POINTER (*context_gpr_p(context, 29))
#define CONTEXT_YOUNG_LIMIT (*context_gpr_p(context, 30))
#define CONTEXT_YOUNG_PTR (*context_gpr_p(context, 31))
#define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr)
static int ctx_version = 0;
static void init_ctx (void)
{
struct utsname name;
if (uname (&name) == 0){
if (name.release[1] == '.' && name.release[0] <= '5'){
ctx_version = 1;
}else{
ctx_version = 2;
}
}else{
caml_fatal_error ("cannot determine SIGCONTEXT format");
}
}
#ifdef DARWIN_VERSION_6
#include <sys/ucontext.h>
static unsigned long *context_gpr_p (void *ctx, int regno)
{
unsigned long *regs;
if (ctx_version == 0) init_ctx ();
if (ctx_version == 1){
/* old-style context (10.0 and 10.1) */
regs = (unsigned long *)(((struct sigcontext *)ctx)->sc_regs);
}else{
Assert (ctx_version == 2);
/* new-style context (10.2) */
regs = (unsigned long *)&(((struct ucontext *)ctx)->uc_mcontext->ss);
}
return &(regs[2 + regno]);
}
#else
#define SA_SIGINFO 0x0040
struct ucontext {
int uc_onstack;
sigset_t uc_sigmask;
struct sigaltstack uc_stack;
struct ucontext *uc_link;
size_t uc_mcsize;
unsigned long *uc_mcontext;
};
static unsigned long *context_gpr_p (void *ctx, int regno)
{
unsigned long *regs;
if (ctx_version == 0) init_ctx ();
if (ctx_version == 1){
/* old-style context (10.0 and 10.1) */
regs = (unsigned long *)(((struct sigcontext *)ctx)->sc_regs);
}else{
Assert (ctx_version == 2);
/* new-style context (10.2) */
regs = (unsigned long *)((struct ucontext *)ctx)->uc_mcontext + 8;
}
return &(regs[2 + regno]);
}
#endif
#endif
/****************** PowerPC, ELF (Linux) */
#elif defined(TARGET_power) && defined(SYS_elf)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, struct sigcontext * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = 0
typedef unsigned long context_reg;
#define CONTEXT_PC (context->regs->nip)
#define CONTEXT_EXCEPTION_POINTER (context->regs->gpr[29])
#define CONTEXT_YOUNG_LIMIT (context->regs->gpr[30])
#define CONTEXT_YOUNG_PTR (context->regs->gpr[31])
/****************** PowerPC, BSD */
#elif defined(TARGET_power) && defined(SYS_bsd)
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, int code, struct sigcontext * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (void (*)(int)) (name); \
sigact.sa_flags = 0
typedef unsigned long context_reg;
#define CONTEXT_EXCEPTION_POINTER (context->sc_frame.fixreg[29])
#define CONTEXT_YOUNG_LIMIT (context->sc_frame.fixreg[30])
#define CONTEXT_YOUNG_PTR (context->sc_frame.fixreg[31])
/****************** SPARC, Solaris */
#elif defined(TARGET_sparc) && defined(SYS_solaris)
#include <ucontext.h>
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig, siginfo_t * info, ucontext_t * context)
#define SET_SIGACT(sigact,name) \
sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \
sigact.sa_flags = SA_SIGINFO
typedef long context_reg;
#define CONTEXT_PC (context->uc_mcontext.gregs[REG_PC])
/* Local register number N is saved on the stack N words
after the stack pointer */
#define SPARC_L_REG(n) ((long *)(context->uc_mcontext.gregs[REG_SP]))[n]
#define CONTEXT_EXCEPTION_POINTER (SPARC_L_REG(5))
#define CONTEXT_YOUNG_LIMIT (SPARC_L_REG(7))
#define CONTEXT_YOUNG_PTR (SPARC_L_REG(6))
/******************** Default */
#else
#define DECLARE_SIGNAL_HANDLER(name) \
static void name(int sig)
#define SET_SIGACT(sigact,name) \
sigact.sa_handler = (name); \
sigact.sa_flags = 0
#endif