* StringTest.cs: Added test for Concat when one of the arguments is an
[mono.git] / mono / mini / exceptions-sparc.c
1 /*
2  * exceptions-sparc.c: exception support for 64 bit sparc
3  *
4  * Authors:
5  *   Mark Crichton (crichton@gimp.org)
6  *   Dietmar Maurer (dietmar@ximian.com)
7  *
8  * (C) 2003 Ximian, Inc.
9  */
10
11 #include <config.h>
12 #include <glib.h>
13 #include <signal.h>
14 #include <string.h>
15
16 #include <mono/arch/sparc/sparc-codegen.h>
17 #include <mono/metadata/appdomain.h>
18 #include <mono/metadata/tabledefs.h>
19 #include <mono/metadata/threads.h>
20 #include <mono/metadata/debug-helpers.h>
21 #include <mono/metadata/exception.h>
22 #include <mono/metadata/mono-debug.h>
23
24 #include "mini.h"
25 #include "mini-sparc.h"
26
27 #warning NotReady
28
29 typedef struct sigcontext MonoContext;
30
31 gboolean  mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only);
32
33 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->SC_EIP = (long)ip; } while (0); 
34 #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->SC_EBP = (long)bp; } while (0); 
35
36 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->SC_EIP))
37 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->SC_EBP))
38
39 #ifdef MONO_USE_EXC_TABLES
40
41 /*************************************/
42 /*    STACK UNWINDING STUFF          */
43 /*************************************/
44
45 /* These definitions are from unwind-dw2.c in glibc 2.2.5 */
46
47 /* For x86 */
48 #define DWARF_FRAME_REGISTERS 17
49
50 typedef struct frame_state
51 {
52   void *cfa;
53   void *eh_ptr;
54   long cfa_offset;
55   long args_size;
56   long reg_or_offset[DWARF_FRAME_REGISTERS+1];
57   unsigned short cfa_reg;
58   unsigned short retaddr_column;
59   char saved[DWARF_FRAME_REGISTERS+1];
60 } frame_state;
61
62
63 typedef struct frame_state * (*framesf) (void *, struct frame_state *);
64
65 static framesf frame_state_for = NULL;
66
67 static gboolean inited = FALSE;
68
69 typedef char ** (*get_backtrace_symbols_type) (void *__const *__array, int __size);
70
71 static get_backtrace_symbols_type get_backtrace_symbols = NULL;
72
73 static void
74 init_frame_state_for (void)
75 {
76         GModule *module;
77
78         /*
79          * There are two versions of __frame_state_for: one in libgcc.a and the
80          * other in glibc.so. We need the version from glibc.
81          * For more info, see this:
82          * http://gcc.gnu.org/ml/gcc/2002-08/msg00192.html
83          */
84         if ((module = g_module_open ("libc.so.6", G_MODULE_BIND_LAZY))) {
85         
86                 if (!g_module_symbol (module, "__frame_state_for", (gpointer*)&frame_state_for))
87                         frame_state_for = NULL;
88
89                 if (!g_module_symbol (module, "backtrace_symbols", (gpointer*)&get_backtrace_symbols)) {
90                         get_backtrace_symbols = NULL;
91                         frame_state_for = NULL;
92                 }
93
94                 g_module_close (module);
95         }
96
97         inited = TRUE;
98 }
99
100 /* mono_arch_has_unwind_info:
101  *
102  * Tests if a function has an DWARF exception table able to restore
103  * all caller saved registers. 
104  */
105 gboolean
106 mono_arch_has_unwind_info (gconstpointer addr)
107 {
108         return FALSE;
109 }
110
111 struct stack_frame
112 {
113   void *next;
114   void *return_address;
115 };
116 #endif
117
118 gpointer 
119 mono_arch_get_throw_exception (void)
120 {
121         return 0xdeadbeef;
122 }
123
124 /**
125  * arch_get_throw_exception_by_name:
126  *
127  * Returns a function pointer which can be used to raise 
128  * corlib exceptions. The returned function has the following 
129  * signature: void (*func) (char *exc_name); 
130  * For example to raise an arithmetic exception you can use:
131  *
132  * x86_push_imm (code, "ArithmeticException"); 
133  * x86_call_code (code, arch_get_throw_exception_by_name ()); 
134  *
135  */
136 gpointer 
137 mono_arch_get_throw_exception_by_name (void)
138 {
139         return 0xdecafbad;
140 }       
141
142 static MonoArray *
143 glist_to_array (GList *list) 
144 {
145         MonoDomain *domain = mono_domain_get ();
146         MonoArray *res;
147         int len, i;
148
149         if (!list)
150                 return NULL;
151
152         len = g_list_length (list);
153         res = mono_array_new (domain, mono_defaults.int_class, len);
154
155         for (i = 0; list; list = list->next, i++)
156                 mono_array_set (res, gpointer, i, list->data);
157
158         return res;
159 }
160
161 MonoArray *
162 ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
163 {
164         return NULL;
165 }
166
167 void
168 mono_jit_walk_stack (MonoStackWalk func, gpointer user_data) {
169 }
170
171 MonoBoolean
172 ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info, 
173                           MonoReflectionMethod **method, 
174                           gint32 *iloffset, gint32 *native_offset,
175                           MonoString **file, gint32 *line, gint32 *column)
176 {
177         return FALSE;
178 }
179
180 /**
181  * arch_handle_exception:
182  * @ctx: saved processor state
183  * @obj: the exception object
184  * @test_only: only test if the exception is caught, but dont call handlers
185  *
186  *
187  */
188 gboolean
189 mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
190 {
191         g_assert_not_reached ();
192 }