Mercurial > projects > ldc
comparison runtime/internal/eh.d @ 1584:f4c56ed32238
Fixed issue in exception runtime with recent LLVM revisions, with this in place EH seems to work properly on x86-64. These fixes need to be merged into tango trunk still!
author | tomas@localhost.localdomain |
---|---|
date | Wed, 21 Oct 2009 05:46:56 +0200 |
parents | 4a5eea0334e5 |
children | 761bf823e59e |
comparison
equal
deleted
inserted
replaced
1583:593f99fddd2f | 1584:f4c56ed32238 |
---|---|
6 | 6 |
7 import util.console; | 7 import util.console; |
8 import ldc.cstdarg; | 8 import ldc.cstdarg; |
9 | 9 |
10 // debug = EH_personality; | 10 // debug = EH_personality; |
11 // debug = EH_personality_verbose; | |
11 | 12 |
12 // current EH implementation works on x86 | 13 // current EH implementation works on x86 |
13 // if it has a working unwind runtime | 14 // if it has a working unwind runtime |
14 version(X86) { | 15 version(X86) { |
15 version(linux) version=X86_UNWIND; | 16 version(linux) version=X86_UNWIND; |
34 } | 35 } |
35 | 36 |
36 // libunwind headers | 37 // libunwind headers |
37 extern(C) | 38 extern(C) |
38 { | 39 { |
39 enum _Unwind_Reason_Code | 40 enum _Unwind_Reason_Code : int |
40 { | 41 { |
41 NO_REASON = 0, | 42 NO_REASON = 0, |
42 FOREIGN_EXCEPTION_CAUGHT = 1, | 43 FOREIGN_EXCEPTION_CAUGHT = 1, |
43 FATAL_PHASE2_ERROR = 2, | 44 FATAL_PHASE2_ERROR = 2, |
44 FATAL_PHASE1_ERROR = 3, | 45 FATAL_PHASE1_ERROR = 3, |
47 HANDLER_FOUND = 6, | 48 HANDLER_FOUND = 6, |
48 INSTALL_CONTEXT = 7, | 49 INSTALL_CONTEXT = 7, |
49 CONTINUE_UNWIND = 8 | 50 CONTINUE_UNWIND = 8 |
50 } | 51 } |
51 | 52 |
52 enum _Unwind_Action | 53 enum _Unwind_Action : int |
53 { | 54 { |
54 SEARCH_PHASE = 1, | 55 SEARCH_PHASE = 1, |
55 CLEANUP_PHASE = 2, | 56 CLEANUP_PHASE = 2, |
56 HANDLER_PHASE = 3, | 57 HANDLER_PHASE = 3, |
57 FORCE_UNWIND = 4 | 58 FORCE_UNWIND = 4 |
61 | 62 |
62 alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn; | 63 alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn; |
63 | 64 |
64 struct _Unwind_Exception | 65 struct _Unwind_Exception |
65 { | 66 { |
66 char[8] exception_class; | 67 ulong exception_class; |
67 _Unwind_Exception_Cleanup_Fn exception_cleanup; | 68 _Unwind_Exception_Cleanup_Fn exception_cleanup; |
68 ptrdiff_t private_1; | 69 ptrdiff_t private_1; |
69 ptrdiff_t private_2; | 70 ptrdiff_t private_2; |
70 } | 71 } |
71 | 72 |
205 | 206 |
206 // the personality routine gets called by the unwind handler and is responsible for | 207 // the personality routine gets called by the unwind handler and is responsible for |
207 // reading the EH tables and deciding what to do | 208 // reading the EH tables and deciding what to do |
208 extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) | 209 extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) |
209 { | 210 { |
211 debug(EH_personality_verbose) printf("entering personality function. context: %p\n", context); | |
210 // check ver: the C++ Itanium ABI only allows ver == 1 | 212 // check ver: the C++ Itanium ABI only allows ver == 1 |
211 if(ver != 1) | 213 if(ver != 1) |
212 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; | 214 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; |
213 | 215 |
214 // check exceptionClass | 216 // check exceptionClass |
222 // Note: classinfo_table points past the end of the table | 224 // Note: classinfo_table points past the end of the table |
223 ubyte* callsite_table; | 225 ubyte* callsite_table; |
224 ubyte* action_table; | 226 ubyte* action_table; |
225 ClassInfo* classinfo_table; | 227 ClassInfo* classinfo_table; |
226 _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); | 228 _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); |
227 | 229 if (callsite_table is null) |
230 return _Unwind_Reason_Code.CONTINUE_UNWIND; | |
228 | 231 |
229 /* | 232 /* |
230 find landing pad and action table index belonging to ip by walking | 233 find landing pad and action table index belonging to ip by walking |
231 the callsite_table | 234 the callsite_table |
232 */ | 235 */ |
375 } | 378 } |
376 | 379 |
377 private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) | 380 private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) |
378 { | 381 { |
379 ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); | 382 ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); |
383 if (data is null) | |
384 { | |
385 //printf("language specific data was null\n"); | |
386 callsite = null; | |
387 action = null; | |
388 ci = null; | |
389 return; | |
390 } | |
380 | 391 |
381 //TODO: Do proper DWARF reading here | 392 //TODO: Do proper DWARF reading here |
382 if(*data++ != 0xff) | 393 if(*data++ != 0xff) |
383 fatalerror("DWARF header has unexpected format 1"); | 394 fatalerror("DWARF header has unexpected format 1"); |
384 | 395 |
403 extern(C) void _d_throw_exception(Object e) | 414 extern(C) void _d_throw_exception(Object e) |
404 { | 415 { |
405 if (e !is null) | 416 if (e !is null) |
406 { | 417 { |
407 _d_exception* exc_struct = new _d_exception; | 418 _d_exception* exc_struct = new _d_exception; |
408 exc_struct.unwind_info.exception_class[] = _d_exception_class; | 419 exc_struct.unwind_info.exception_class = *cast(ulong*)_d_exception_class.ptr; |
409 exc_struct.exception_object = e; | 420 exc_struct.exception_object = e; |
410 _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); | 421 _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); |
411 console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); | 422 console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); |
412 } | 423 } |
413 abort(); | 424 abort(); |