2010-06-21 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / mini / mini-unwind.h
blobc99da3c312739249434ac23162e688a39ba3bfd9
1 /*
2 * mini-unwind.h: Stack Unwinding Interface
4 * Authors:
5 * Zoltan Varga (vargaz@gmail.com)
7 * (C) 2007 Novell, Inc.
8 */
10 #ifndef __MONO_UNWIND_H__
11 #define __MONO_UNWIND_H__
13 #include "mini.h"
16 * This is a platform-independent interface for unwinding through stack frames
17 * based on the Dwarf unwinding interface.
18 * See http://dwarfstd.org/Dwarf3.pdf, section "Call Frame Information".
19 * Currently, this is only used for emitting unwind info in AOT files.
22 /* CFA = Canonical Frame Address */
24 /* Unwind ops */
26 /* The low 6 bits contain additional information */
27 #define DW_CFA_advance_loc 0x40
28 #define DW_CFA_offset 0x80
29 #define DW_CFA_restore 0xc0
31 #define DW_CFA_nop 0x00
32 #define DW_CFA_set_loc 0x01
33 #define DW_CFA_advance_loc1 0x02
34 #define DW_CFA_advance_loc2 0x03
35 #define DW_CFA_advance_loc4 0x04
36 #define DW_CFA_offset_extended 0x05
37 #define DW_CFA_restore_extended 0x06
38 #define DW_CFA_undefined 0x07
39 #define DW_CFA_same_value 0x08
40 #define DW_CFA_register 0x09
41 #define DW_CFA_remember_state 0x0a
42 #define DW_CFA_restore_state 0x0b
43 #define DW_CFA_def_cfa 0x0c
44 #define DW_CFA_def_cfa_register 0x0d
45 #define DW_CFA_def_cfa_offset 0x0e
46 #define DW_CFA_def_cfa_expression 0x0f
47 #define DW_CFA_expression 0x10
48 #define DW_CFA_offset_extended_sf 0x11
49 #define DW_CFA_def_cfa_sf 0x12
50 #define DW_CFA_def_cfa_offset_sf 0x13
51 #define DW_CFA_val_offset 0x14
52 #define DW_CFA_val_offset_sf 0x15
53 #define DW_CFA_val_expression 0x16
54 #define DW_CFA_lo_user 0x1c
55 #define DW_CFA_hi_user 0x3f
57 /* Represents one unwind instruction */
58 typedef struct {
59 guint8 op; /* One of DW_CFA_... */
60 guint16 reg; /* register number in the hardware encoding */
61 gint32 val; /* arbitrary value */
62 guint32 when; /* The offset _after_ the cpu instruction this unwind op belongs to */
63 } MonoUnwindOp;
65 /*
66 * Macros for emitting MonoUnwindOp structures.
67 * These should be called _after_ emitting the cpu instruction the unwind op
68 * belongs to.
71 /* Set cfa to reg+offset */
72 #define mono_emit_unwind_op_def_cfa(cfg,ip,reg,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa, (reg), (offset))
73 /* Set cfa to reg+existing offset */
74 #define mono_emit_unwind_op_def_cfa_reg(cfg,ip,reg) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_register, (reg), (0))
75 /* Set cfa to existing reg+offset */
76 #define mono_emit_unwind_op_def_cfa_offset(cfg,ip,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_offset, (0), (offset))
77 /* Reg is the same as it was on enter to the function */
78 #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)
79 /* Reg is saved at cfa+offset */
80 #define mono_emit_unwind_op_offset(cfg,ip,reg,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_offset, (reg), (offset))
82 /* Similar macros usable when a cfg is not available, like for trampolines */
83 #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)
84 #define mono_add_unwind_op_def_cfa_reg(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_register, (reg), (0))); } while (0)
85 #define mono_add_unwind_op_def_cfa_offset(op_list,code,buf,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_offset, 0, (offset))); } while (0)
86 #define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0)
87 #define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0)
89 int
90 mono_hw_reg_to_dwarf_reg (int reg) MONO_INTERNAL;
92 int
93 mono_dwarf_reg_to_hw_reg (int reg) MONO_INTERNAL;
95 int
96 mono_unwind_get_dwarf_data_align (void) MONO_INTERNAL;
98 int
99 mono_unwind_get_dwarf_pc_reg (void) MONO_INTERNAL;
101 guint8*
102 mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len) MONO_INTERNAL;
104 void
105 mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
106 guint8 *start_ip, guint8 *end_ip, guint8 *ip, mgreg_t *regs,
107 int nregs, guint8 **out_cfa) MONO_INTERNAL;
109 void mono_unwind_init (void) MONO_INTERNAL;
111 void mono_unwind_cleanup (void) MONO_INTERNAL;
113 guint32 mono_cache_unwind_info (guint8 *unwind_info, guint32 unwind_info_len) MONO_INTERNAL;
115 guint8* mono_get_cached_unwind_info (guint32 index, guint32 *unwind_info_len) MONO_INTERNAL;
117 guint8* mono_unwind_decode_fde (guint8 *fde, guint32 *out_len, guint32 *code_len, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info, int *this_reg, int *this_offset) MONO_INTERNAL;
119 GSList* mono_unwind_get_cie_program (void) MONO_INTERNAL;
121 #endif