/* * mono-context.h: plat independent machine state definitions * * * Copyright (c) 2011 Novell, Inc (http://www.novell.com) */ #ifndef __MONO_MONO_CONTEXT_H__ #define __MONO_MONO_CONTEXT_H__ #include "mono-compiler.h" #include "mono-sigcontext.h" #include "mono-machine.h" #ifdef HAVE_SIGNAL_H #include #endif /* * General notes about mono-context. * Each arch defines a MonoContext struct with all GPR regs + IP/PC. * IP/PC should be the last element of the struct (this is a mild sgen constraint we could drop if needed) * Macros to get/set BP, SP and IP are defined too. * MONO_CONTEXT_GET_CURRENT captures the current context as close as possible. One reg might be clobbered * to hold the address of the target MonoContext. It will be a caller save one, so should not be a problem. */ #if defined(__i386__) /*HACK, move this to an eventual mono-signal.c*/ #if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \ defined(__FreeBSD__) || defined(__OpenBSD__) #define MONO_SIGNAL_USE_SIGACTION #endif #if defined(__native_client__) #undef MONO_SIGNAL_USE_SIGACTION #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) # define SC_EAX sc_eax # define SC_EBX sc_ebx # define SC_ECX sc_ecx # define SC_EDX sc_edx # define SC_EBP sc_ebp # define SC_EIP sc_eip # define SC_ESP sc_esp # define SC_EDI sc_edi # define SC_ESI sc_esi #elif defined(__HAIKU__) # define SC_EAX regs.eax # define SC_EBX regs._reserved_2[2] # define SC_ECX regs.ecx # define SC_EDX regs.edx # define SC_EBP regs.ebp # define SC_EIP regs.eip # define SC_ESP regs.esp # define SC_EDI regs._reserved_2[0] # define SC_ESI regs._reserved_2[1] #else # define SC_EAX eax # define SC_EBX ebx # define SC_ECX ecx # define SC_EDX edx # define SC_EBP ebp # define SC_EIP eip # define SC_ESP esp # define SC_EDI edi # define SC_ESI esi #endif typedef struct { mgreg_t eax; mgreg_t ebx; mgreg_t ecx; mgreg_t edx; mgreg_t ebp; mgreg_t esp; mgreg_t esi; mgreg_t edi; mgreg_t eip; } MonoContext; #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (mgreg_t)(ip); } while (0); #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->ebp = (mgreg_t)(bp); } while (0); #define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->esp = (mgreg_t)(sp); } while (0); #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->eip)) #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->ebp)) #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->esp)) /*We set EAX to zero since we are clobering it anyway*/ #define MONO_CONTEXT_GET_CURRENT(ctx) \ __asm__ __volatile__( \ "movl $0x0, 0x00(%0)\n" \ "mov %%ebx, 0x04(%0)\n" \ "mov %%ecx, 0x08(%0)\n" \ "mov %%edx, 0x0c(%0)\n" \ "mov %%ebp, 0x10(%0)\n" \ "mov %%esp, 0x14(%0)\n" \ "mov %%esi, 0x18(%0)\n" \ "mov %%edi, 0x1c(%0)\n" \ "call 1f\n" \ "1: pop 0x20(%0)\n" \ : \ : "a" (&(ctx)) \ : "memory") #else /* defined(__i386__) */ #error "Implement mono-context for the current arch" #endif void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) MONO_INTERNAL; void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) MONO_INTERNAL; #endif /* __MONO_MONO_CONTEXT_H__ */