X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Funwind.c;h=72f5d0d59e0b959373fcb1cb00dee5b86b4b601d;hb=HEAD;hp=2dc04322dc6b22a1f64feac6342fa85d39e5f334;hpb=a3304910e9e08ec965fb06ef6fa4a19257dddf8c;p=mono.git diff --git a/mono/mini/unwind.c b/mono/mini/unwind.c index 2dc04322dc6..72f5d0d59e0 100644 --- a/mono/mini/unwind.c +++ b/mono/mini/unwind.c @@ -867,9 +867,10 @@ read_encoded_val (guint32 encoding, guint8 *p, guint8 **endp) * decode_lsda: * * Decode the Mono specific Language Specific Data Area generated by LLVM. + * This function is async safe. */ static void -decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info, int *this_reg, int *this_offset) +decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo *ex_info, gpointer *type_info, guint32 *ex_info_len, int *this_reg, int *this_offset) { guint8 *p; int i, ncall_sites, this_encoding; @@ -905,12 +906,8 @@ decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 ncall_sites = decode_uleb128 (p, &p); p = (guint8*)ALIGN_TO ((mgreg_t)p, 4); - if (ex_info) { - *ex_info = (MonoJitExceptionInfo *)g_malloc0 (ncall_sites * sizeof (MonoJitExceptionInfo)); + if (ex_info_len) *ex_info_len = ncall_sites; - } - if (type_info) - *type_info = (gpointer *)g_malloc0 (ncall_sites * sizeof (gpointer)); for (i = 0; i < ncall_sites; ++i) { int block_start_offset, block_size, landing_pad; @@ -930,11 +927,11 @@ decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 //printf ("X: %p %d\n", landing_pad, *(int*)tinfo); if (ex_info) { - if (*type_info) - (*type_info) [i] = tinfo; - (*ex_info)[i].try_start = code + block_start_offset; - (*ex_info)[i].try_end = code + block_start_offset + block_size; - (*ex_info)[i].handler_start = code + landing_pad; + if (type_info) + type_info [i] = tinfo; + ex_info[i].try_start = code + block_start_offset; + ex_info[i].try_end = code + block_start_offset + block_size; + ex_info[i].handler_start = code + landing_pad; } } } @@ -1073,7 +1070,16 @@ mono_unwind_decode_fde (guint8 *fde, guint32 *out_len, guint32 *code_len, MonoJi if (lsda_offset != 0) { lsda = fde_aug + lsda_offset; - decode_lsda (lsda, code, ex_info, ex_info_len, type_info, this_reg, this_offset); + /* Get the lengths first */ + guint32 len; + decode_lsda (lsda, code, NULL, NULL, &len, this_reg, this_offset); + + if (ex_info) + *ex_info = (MonoJitExceptionInfo *)g_malloc0 (len * sizeof (MonoJitExceptionInfo)); + if (type_info) + *type_info = (gpointer *)g_malloc0 (len * sizeof (gpointer)); + + decode_lsda (lsda, code, ex_info ? *ex_info : NULL, type_info ? *type_info : NULL, ex_info_len, this_reg, this_offset); } } @@ -1116,13 +1122,15 @@ mono_unwind_decode_fde (guint8 *fde, guint32 *out_len, guint32 *code_len, MonoJi * mono_unwind_decode_mono_fde: * * Decode an FDE entry in the LLVM emitted mono EH frame. - * info->ex_info is set to a malloc-ed array of MonoJitExceptionInfo structures, - * only try_start, try_end and handler_start is set. - * info->type_info is set to a malloc-ed array containing the ttype table from the - * LSDA. + * If EI/TYPE_INFO/UNW_INFO are NULL, compute only the value of the scalar fields in INFO. + * Otherwise: + * - Fill out EX_INFO with try_start, try_end and handler_start. + * - Fill out TYPE_INFO with the ttype table from the LSDA. + * - Fill out UNW_INFO with the unwind info. + * This function is async safe. */ void -mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8 *code, MonoLLVMFDEInfo *res) +mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8 *code, MonoLLVMFDEInfo *res, MonoJitExceptionInfo *ex_info, gpointer *type_info, guint8 *unw_info) { guint8 *p, *fde_aug, *cie_cfi, *fde_cfi, *buf; int has_aug, aug_len, cie_cfi_len, fde_cfi_len; @@ -1152,7 +1160,10 @@ mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8 /* The LSDA is embedded directly into the FDE */ lsda = fde_aug; - decode_lsda (lsda, code, &res->ex_info, &res->ex_info_len, &res->type_info, &res->this_reg, &res->this_offset); + /* Get the lengths first */ + decode_lsda (lsda, code, NULL, NULL, &res->ex_info_len, &res->this_reg, &res->this_offset); + + decode_lsda (lsda, code, ex_info, type_info, NULL, &res->this_reg, &res->this_offset); } /* Decode CIE */ @@ -1183,12 +1194,13 @@ mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8 cie_cfi_len = p - cie_cfi; fde_cfi_len = (fde + fde_len - fde_cfi); - buf = (guint8 *)g_malloc0 (cie_cfi_len + fde_cfi_len); - memcpy (buf, cie_cfi, cie_cfi_len); - memcpy (buf + cie_cfi_len, fde_cfi, fde_cfi_len); + buf = unw_info; + if (buf) { + memcpy (buf, cie_cfi, cie_cfi_len); + memcpy (buf + cie_cfi_len, fde_cfi, fde_cfi_len); + } res->unw_info_len = cie_cfi_len + fde_cfi_len; - res->unw_info = buf; } /*