X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-unwind.h;h=1085cbe0e3fcd3e4151a55978bc28c0d3fdf986e;hb=20d845ca07479ece43da9e344c060e49887fd369;hp=1d5be3190da6ae669686d365b8226e45ef936234;hpb=e946a6cdebde729e1c03ec374184254ab38da184;p=mono.git diff --git a/mono/mini/mini-unwind.h b/mono/mini/mini-unwind.h index 1d5be3190da..1085cbe0e3f 100644 --- a/mono/mini/mini-unwind.h +++ b/mono/mini/mini-unwind.h @@ -60,6 +60,13 @@ #define DW_CFA_lo_user 0x1c #define DW_CFA_hi_user 0x3f +/* + * Mono extension, advance loc to a location stored outside the unwind info. + * This is required to make the unwind descriptors sharable, since otherwise each one would contain + * an advance_loc with a different offset just before the unwind ops for the epilog. + */ +#define DW_CFA_mono_advance_loc DW_CFA_lo_user + /* Represents one unwind instruction */ typedef struct { guint8 op; /* One of DW_CFA_... */ @@ -75,15 +82,25 @@ typedef struct { */ /* Set cfa to reg+offset */ -#define mono_emit_unwind_op_def_cfa(cfg,ip,reg,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa, (reg), (offset)); (cfg)->cfa_reg = (reg); (cfg)->cfa_offset = (offset); } while (0) +#define mono_emit_unwind_op_def_cfa(cfg,ip,reg,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa, (reg), (offset)); (cfg)->cur_cfa_reg = (reg); (cfg)->cur_cfa_offset = (offset); } while (0) /* Set cfa to reg+existing offset */ -#define mono_emit_unwind_op_def_cfa_reg(cfg,ip,reg) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_register, (reg), (0)); (cfg)->cfa_reg = (reg); } while (0) +#define mono_emit_unwind_op_def_cfa_reg(cfg,ip,reg) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_register, (reg), (0)); (cfg)->cur_cfa_reg = (reg); } while (0) /* Set cfa to existing reg+offset */ -#define mono_emit_unwind_op_def_cfa_offset(cfg,ip,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_offset, (0), (offset)); (cfg)->cfa_offset = (offset); } while (0) +#define mono_emit_unwind_op_def_cfa_offset(cfg,ip,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_offset, (0), (offset)); (cfg)->cur_cfa_offset = (offset); } while (0) /* Reg is the same as it was on enter to the function */ #define mono_emit_unwind_op_same_value(cfg,ip,reg) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_same_value, (reg), 0) /* Reg is saved at cfa+offset */ #define mono_emit_unwind_op_offset(cfg,ip,reg,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_offset, (reg), (offset)) +/* Save the unwind state into an implicit stack */ +#define mono_emit_unwind_op_remember_state(cfg,ip) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_remember_state, 0, 0) +/* Restore the unwind state from the state stack */ +#define mono_emit_unwind_op_restore_state(cfg,ip) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_restore_state, 0, 0) +/* + * Mark the current location as a location stored outside the unwind info, which will be passed + * explicitly to mono_unwind_frame () in the MARK_LOCATIONS argument. This allows the unwind info + * to be shared among multiple methods. + */ +#define mono_emit_unwind_op_mark_loc(cfg,ip,n) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_mono_advance_loc, 0, (n)) /* Similar macros usable when a cfg is not available, like for trampolines */ #define mono_add_unwind_op_def_cfa(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa, (reg), (offset))); } while (0) @@ -127,7 +144,8 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len) MONO_INTERNAL; void mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len, - guint8 *start_ip, guint8 *end_ip, guint8 *ip, mgreg_t *regs, int nregs, + guint8 *start_ip, guint8 *end_ip, guint8 *ip, guint8 **mark_locations, + mgreg_t *regs, int nregs, mgreg_t **save_locations, int save_locations_len, guint8 **out_cfa) MONO_INTERNAL; @@ -158,4 +176,6 @@ mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8 GSList* mono_unwind_get_cie_program (void) MONO_INTERNAL; +void mono_print_unwind_info (guint8 *unwind_info, int unwind_info_len) MONO_LLVM_INTERNAL; + #endif