#endif /* PLATFORM_WIN32 */
-
-#ifdef MONO_USE_EXC_TABLES
-
-/*************************************/
-/* STACK UNWINDING STUFF */
-/*************************************/
-
-/* These definitions are from unwind-dw2.c in glibc 2.2.5 */
-
-/* For x86 */
-#define DWARF_FRAME_REGISTERS 17
-
-typedef struct frame_state
-{
- void *cfa;
- void *eh_ptr;
- long cfa_offset;
- long args_size;
- long reg_or_offset[DWARF_FRAME_REGISTERS+1];
- unsigned short cfa_reg;
- unsigned short retaddr_column;
- char saved[DWARF_FRAME_REGISTERS+1];
-} frame_state;
-
-static long
-get_sigcontext_reg (struct sigcontext *ctx, int dwarf_regnum)
-{
- switch (dwarf_regnum) {
- case X86_EAX:
- return ctx->SC_EAX;
- case X86_EBX:
- return ctx->SC_EBX;
- case X86_ECX:
- return ctx->SC_ECX;
- case X86_EDX:
- return ctx->SC_EDX;
- case X86_ESI:
- return ctx->SC_ESI;
- case X86_EDI:
- return ctx->SC_EDI;
- case X86_EBP:
- return ctx->SC_EBP;
- case X86_ESP:
- return ctx->SC_ESP;
- default:
- g_assert_not_reached ();
- }
-
- return 0;
-}
-
-static void
-set_sigcontext_reg (struct sigcontext *ctx, int dwarf_regnum, long value)
-{
- switch (dwarf_regnum) {
- case X86_EAX:
- ctx->SC_EAX = value;
- break;
- case X86_EBX:
- ctx->SC_EBX = value;
- break;
- case X86_ECX:
- ctx->SC_ECX = value;
- break;
- case X86_EDX:
- ctx->SC_EDX = value;
- break;
- case X86_ESI:
- ctx->SC_ESI = value;
- break;
- case X86_EDI:
- ctx->SC_EDI = value;
- break;
- case X86_EBP:
- ctx->SC_EBP = value;
- break;
- case X86_ESP:
- ctx->SC_ESP = value;
- break;
- case 8:
- ctx->SC_EIP = value;
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-typedef struct frame_state * (*framesf) (void *, struct frame_state *);
-
-static framesf frame_state_for = NULL;
-
-static gboolean inited = FALSE;
-
-typedef char ** (*get_backtrace_symbols_type) (void *__const *__array, int __size);
-
-static get_backtrace_symbols_type get_backtrace_symbols = NULL;
-
-static void
-init_frame_state_for (void)
-{
- GModule *module;
-
- /*
- * There are two versions of __frame_state_for: one in libgcc.a and the
- * other in glibc.so. We need the version from glibc.
- * For more info, see this:
- * http://gcc.gnu.org/ml/gcc/2002-08/msg00192.html
- */
- if ((module = g_module_open ("libc.so.6", G_MODULE_BIND_LAZY))) {
-
- if (!g_module_symbol (module, "__frame_state_for", (gpointer*)&frame_state_for))
- frame_state_for = NULL;
-
- if (!g_module_symbol (module, "backtrace_symbols", (gpointer*)&get_backtrace_symbols)) {
- get_backtrace_symbols = NULL;
- frame_state_for = NULL;
- }
-
- g_module_close (module);
- }
-
- inited = TRUE;
-}
-
-/* mono_arch_has_unwind_info:
- *
- * Tests if a function has an DWARF exception table able to restore
- * all caller saved registers.
- */
-gboolean
-mono_arch_has_unwind_info (gconstpointer addr)
-{
- struct frame_state state_in;
- struct frame_state *res;
-
- if (!inited)
- init_frame_state_for ();
-
- if (!frame_state_for)
- return FALSE;
-
- g_assert (addr);
-
- memset (&state_in, 0, sizeof (state_in));
-
- /* offset 10 is just a guess, but it works for all methods tested */
- if ((res = frame_state_for ((char *)addr + 10, &state_in))) {
-
- if (res->saved [X86_EBX] == 1 &&
- res->saved [X86_EDI] == 1 &&
- res->saved [X86_EBP] == 1 &&
- res->saved [X86_ESI] == 1)
- return TRUE;
- }
-
- return FALSE;
-}
-
-struct stack_frame
-{
- void *next;
- void *return_address;
-};
-
-static MonoJitInfo *
-x86_unwind_native_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, struct sigcontext *ctx,
- struct sigcontext *new_ctx, MonoLMF *lmf, char **trace)
-{
- struct stack_frame *frame;
- gpointer max_stack;
- MonoJitInfo *ji;
- struct frame_state state_in;
- struct frame_state *res;
-
- if (trace)
- *trace = NULL;
-
- if (!inited)
- init_frame_state_for ();
-
- if (!frame_state_for)
- return FALSE;
-
- frame = MONO_CONTEXT_GET_BP (ctx);
-
- max_stack = lmf && lmf->method ? lmf : jit_tls->end_of_stack;
-
- *new_ctx = *ctx;
-
- memset (&state_in, 0, sizeof (state_in));
-
- while ((gpointer)frame->next < (gpointer)max_stack) {
- gpointer ip, addr = frame->return_address;
- void *cfa;
- char *tmp, **symbols;
-
- if (trace) {
- ip = MONO_CONTEXT_GET_IP (new_ctx);
- symbols = get_backtrace_symbols (&ip, 1);
- if (*trace)
- tmp = g_strdup_printf ("%s\nin (unmanaged) %s", *trace, symbols [0]);
- else
- tmp = g_strdup_printf ("in (unmanaged) %s", symbols [0]);
-
- free (symbols);
- g_free (*trace);
- *trace = tmp;
- }
-
- if ((res = frame_state_for (addr, &state_in))) {
- int i;
-
- cfa = (gint8*) (get_sigcontext_reg (new_ctx, res->cfa_reg) + res->cfa_offset);
- frame = (struct stack_frame *)((gint8*)cfa - 8);
- for (i = 0; i < DWARF_FRAME_REGISTERS + 1; i++) {
- int how = res->saved[i];
- long val;
- g_assert ((how == 0) || (how == 1));
-
- if (how == 1) {
- val = * (long*) ((gint8*)cfa + res->reg_or_offset[i]);
- set_sigcontext_reg (new_ctx, i, val);
- }
- }
- new_ctx->SC_ESP = (long)cfa;
-
- if (res->saved [X86_EBX] == 1 &&
- res->saved [X86_EDI] == 1 &&
- res->saved [X86_EBP] == 1 &&
- res->saved [X86_ESI] == 1 &&
- (ji = mono_jit_info_table_find (domain, frame->return_address))) {
- //printf ("FRAME CFA %s\n", mono_method_full_name (ji->method, TRUE));
- return ji;
- }
-
- } else {
- //printf ("FRAME %p %p %p\n", frame, MONO_CONTEXT_GET_IP (new_ctx), mono_jit_info_table_find (domain, MONO_CONTEXT_GET_IP (new_ctx)));
-
- MONO_CONTEXT_SET_IP (new_ctx, frame->return_address);
- frame = frame->next;
- MONO_CONTEXT_SET_BP (new_ctx, frame);
-
- /* stop if !frame or when we detect an unexpected managed frame */
- if (!frame || mono_jit_info_table_find (domain, frame->return_address)) {
- if (trace) {
- g_free (*trace);
- *trace = NULL;
- }
- return NULL;
- }
- }
- }
-
- //if (!lmf)
- //g_assert_not_reached ();
-
- if (trace) {
- g_free (*trace);
- *trace = NULL;
- }
- return NULL;
-}
-
-#endif
-
/*
* mono_arch_get_restore_context:
*
#endif
}
-#ifdef MONO_USE_EXC_TABLES
-static gboolean
-mono_type_blittable (MonoType *type)
-{
- if (type->byref)
- return FALSE;
-
- switch (type->type){
- case MONO_TYPE_VOID:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- return TRUE;
- case MONO_TYPE_VALUETYPE:
- case MONO_TYPE_CLASS:
- return type->data.klass->blittable;
- break;
- default:
- break;
- }
-
- return FALSE;
-}
-
-gboolean
-mono_method_blittable (MonoMethod *method)
-{
- MonoMethodSignature *sig;
- int i;
-
- if (!method->addr)
- return FALSE;
-
- if (!mono_arch_has_unwind_info (method->addr)) {
- return FALSE;
- }
-
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
- return TRUE;
-
- sig = method->signature;
-
- if (!mono_type_blittable (sig->ret))
- return FALSE;
-
- for (i = 0; i < sig->param_count; i++)
- if (!mono_type_blittable (sig->params [i]))
- return FALSE;
-
- if (mono_method_has_marshal_info (method))
- return FALSE;
-
- if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) && ((MonoMethodPInvoke*)method)->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR)
- return FALSE;
-
- return TRUE;
-}
-#endif
-
/* debug function */
G_GNUC_UNUSED static void
print_method_from_ip (void *ip)
mono_class_init (cmethod->klass);
if (cmethod->signature->pinvoke) {
-#ifdef MONO_USE_EXC_TABLES
- if (mono_method_blittable (cmethod)) {
- fsig = cmethod->signature;
- } else {
-#endif
MonoMethod *wrapper = mono_marshal_get_native_wrapper (cmethod);
fsig = wrapper->signature;
-#ifdef MONO_USE_EXC_TABLES
- }
-#endif
} else {
fsig = mono_method_get_signature (cmethod, image, token);
}
if (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
cmethod = mono_marshal_get_native_wrapper (cmethod);
- if (costs = inline_method (cfg, cmethod, fsig, bblock, sp, ip, real_offset, dont_inline, &ebblock, FALSE)) {
+ if ((costs = inline_method (cfg, cmethod, fsig, bblock, sp, ip, real_offset, dont_inline, &ebblock, FALSE))) {
ip += 5;
real_offset += 5;
info->func = func;
info->sig = sig;
- if (is_save
-#ifdef MONO_USE_EXC_TABLES
- || mono_arch_has_unwind_info (func)
-#endif
- ) {
+ if (is_save) {
info->wrapper = func;
} else {
info->wrapper = NULL;
if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
mono_lookup_pinvoke_call (method, NULL, NULL);
}
-#ifdef MONO_USE_EXC_TABLES
- if (mono_method_blittable (method)) {
- return method->addr;
- } else {
-#endif
nm = mono_marshal_get_native_wrapper (method);
return mono_compile_method (nm);
//if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
//mono_debug_add_wrapper (method, nm);
-#ifdef MONO_USE_EXC_TABLES
- }
-#endif
} else if ((method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
const char *name = method->name;
MonoMethod *nm;