@@ -227,7 +227,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
227
227
// This is achieved by overriding the return value in search phase to always
228
228
// say "catch!".
229
229
230
- #[ cfg( not( target_arch = "arm" ) , not( test) ) ]
230
+ #[ cfg( not( target_arch = "arm" ) , not( windows , target_arch = "x86_64" ) , not ( test) ) ]
231
231
#[ doc( hidden) ]
232
232
#[ allow( visible_private_types) ]
233
233
pub mod eabi {
@@ -244,7 +244,8 @@ pub mod eabi {
244
244
}
245
245
246
246
#[ lang="eh_personality" ]
247
- extern fn eh_personality (
247
+ #[ no_mangle] // referenced from rust_try.ll
248
+ extern fn rust_eh_personality (
248
249
version : c_int ,
249
250
actions : uw:: _Unwind_Action ,
250
251
exception_class : uw:: _Unwind_Exception_Class ,
@@ -260,21 +261,19 @@ pub mod eabi {
260
261
261
262
#[ no_mangle] // referenced from rust_try.ll
262
263
pub extern "C" fn rust_eh_personality_catch (
263
- version : c_int ,
264
+ _version : c_int ,
264
265
actions : uw:: _Unwind_Action ,
265
- exception_class : uw:: _Unwind_Exception_Class ,
266
- ue_header : * mut uw:: _Unwind_Exception ,
267
- context : * mut uw:: _Unwind_Context
266
+ _exception_class : uw:: _Unwind_Exception_Class ,
267
+ _ue_header : * mut uw:: _Unwind_Exception ,
268
+ _context : * mut uw:: _Unwind_Context
268
269
) -> uw:: _Unwind_Reason_Code
269
270
{
271
+
270
272
if ( actions as c_int & uw:: _UA_SEARCH_PHASE as c_int ) != 0 { // search phase
271
273
uw:: _URC_HANDLER_FOUND // catch!
272
274
}
273
275
else { // cleanup phase
274
- unsafe {
275
- __gcc_personality_v0 ( version, actions, exception_class, ue_header,
276
- context)
277
- }
276
+ uw:: _URC_INSTALL_CONTEXT
278
277
}
279
278
}
280
279
}
@@ -299,7 +298,7 @@ pub mod eabi {
299
298
}
300
299
301
300
#[ lang="eh_personality" ]
302
- #[ no_mangle] // so we can reference it by name from middle/trans/base.rs
301
+ #[ no_mangle] // referenced from rust_try.ll
303
302
pub extern "C" fn rust_eh_personality (
304
303
version : c_int ,
305
304
actions : uw:: _Unwind_Action ,
@@ -316,29 +315,26 @@ pub mod eabi {
316
315
317
316
#[ no_mangle] // referenced from rust_try.ll
318
317
pub extern "C" fn rust_eh_personality_catch (
319
- version : c_int ,
318
+ _version : c_int ,
320
319
actions : uw:: _Unwind_Action ,
321
- exception_class : uw:: _Unwind_Exception_Class ,
322
- ue_header : * mut uw:: _Unwind_Exception ,
323
- context : * mut uw:: _Unwind_Context
320
+ _exception_class : uw:: _Unwind_Exception_Class ,
321
+ _ue_header : * mut uw:: _Unwind_Exception ,
322
+ _context : * mut uw:: _Unwind_Context
324
323
) -> uw:: _Unwind_Reason_Code
325
324
{
326
325
if ( actions as c_int & uw:: _UA_SEARCH_PHASE as c_int ) != 0 { // search phase
327
326
uw:: _URC_HANDLER_FOUND // catch!
328
327
}
329
328
else { // cleanup phase
330
- unsafe {
331
- __gcc_personality_sj0 ( version, actions, exception_class, ue_header,
332
- context)
333
- }
329
+ uw:: _URC_INSTALL_CONTEXT
334
330
}
335
331
}
336
332
}
337
333
338
334
339
335
// ARM EHABI uses a slightly different personality routine signature,
340
336
// but otherwise works the same.
341
- #[ cfg( target_arch = "arm" , not( test ) , not ( target_os = "ios" ) ) ]
337
+ #[ cfg( target_arch = "arm" , not( target_os = "ios" , not ( test ) ) ) ]
342
338
#[ allow( visible_private_types) ]
343
339
pub mod eabi {
344
340
use uw = libunwind;
@@ -352,7 +348,8 @@ pub mod eabi {
352
348
}
353
349
354
350
#[ lang="eh_personality" ]
355
- extern "C" fn eh_personality (
351
+ #[ no_mangle] // referenced from rust_try.ll
352
+ extern "C" fn rust_eh_personality (
356
353
state : uw:: _Unwind_State ,
357
354
ue_header : * mut uw:: _Unwind_Exception ,
358
355
context : * mut uw:: _Unwind_Context
@@ -366,19 +363,117 @@ pub mod eabi {
366
363
#[ no_mangle] // referenced from rust_try.ll
367
364
pub extern "C" fn rust_eh_personality_catch (
368
365
state : uw:: _Unwind_State ,
369
- ue_header : * mut uw:: _Unwind_Exception ,
370
- context : * mut uw:: _Unwind_Context
366
+ _ue_header : * mut uw:: _Unwind_Exception ,
367
+ _context : * mut uw:: _Unwind_Context
371
368
) -> uw:: _Unwind_Reason_Code
372
369
{
373
370
if ( state as c_int & uw:: _US_ACTION_MASK as c_int )
374
371
== uw:: _US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
375
372
uw:: _URC_HANDLER_FOUND // catch!
376
373
}
377
374
else { // cleanup phase
378
- unsafe {
379
- __gcc_personality_v0 ( state, ue_header, context)
375
+ uw:: _URC_INSTALL_CONTEXT
376
+ }
377
+ }
378
+ }
379
+
380
+ // Win64 SEH (see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx)
381
+ //
382
+ // This looks a bit convoluted because rather than implementing a native SEH handler,
383
+ // GCC reuses the same personality routine as for the other architectures by wrapping it
384
+ // with an "API translator" layer (_GCC_specific_handler).
385
+
386
+ #[ cfg( windows, target_arch = "x86_64" , not( test) ) ]
387
+ #[ allow( visible_private_types) ]
388
+ #[ allow( non_camel_case_types) ]
389
+ #[ allow( unused_variable) ]
390
+ #[ allow( uppercase_variables) ]
391
+ pub mod eabi {
392
+ use uw = libunwind;
393
+ use libc:: { c_void, c_int} ;
394
+
395
+ struct EXCEPTION_RECORD ;
396
+ struct CONTEXT ;
397
+ struct DISPATCHER_CONTEXT ;
398
+
399
+ #[ repr( C ) ]
400
+ enum EXCEPTION_DISPOSITION {
401
+ ExceptionContinueExecution ,
402
+ ExceptionContinueSearch ,
403
+ ExceptionNestedException ,
404
+ ExceptionCollidedUnwind
405
+ }
406
+
407
+ type _Unwind_Personality_Fn =
408
+ extern "C" fn (
409
+ version : c_int ,
410
+ actions : uw:: _Unwind_Action ,
411
+ exception_class : uw:: _Unwind_Exception_Class ,
412
+ ue_header : * mut uw:: _Unwind_Exception ,
413
+ context : * mut uw:: _Unwind_Context
414
+ ) -> uw:: _Unwind_Reason_Code ;
415
+
416
+ extern "C" {
417
+ fn __gcc_personality_seh0 (
418
+ exceptionRecord : * mut EXCEPTION_RECORD ,
419
+ establisherFrame : * mut c_void ,
420
+ contextRecord : * mut CONTEXT ,
421
+ dispatcherContext : * mut DISPATCHER_CONTEXT
422
+ ) -> EXCEPTION_DISPOSITION ;
423
+
424
+ fn _GCC_specific_handler (
425
+ exceptionRecord : * mut EXCEPTION_RECORD ,
426
+ establisherFrame : * mut c_void ,
427
+ contextRecord : * mut CONTEXT ,
428
+ dispatcherContext : * mut DISPATCHER_CONTEXT ,
429
+ personality : _Unwind_Personality_Fn
430
+ ) -> EXCEPTION_DISPOSITION ;
431
+ }
432
+
433
+ #[ lang="eh_personality" ]
434
+ #[ no_mangle] // referenced from rust_try.ll
435
+ extern "C" fn rust_eh_personality (
436
+ exceptionRecord : * mut EXCEPTION_RECORD ,
437
+ establisherFrame : * mut c_void ,
438
+ contextRecord : * mut CONTEXT ,
439
+ dispatcherContext : * mut DISPATCHER_CONTEXT
440
+ ) -> EXCEPTION_DISPOSITION
441
+ {
442
+ unsafe {
443
+ __gcc_personality_seh0 ( exceptionRecord, establisherFrame,
444
+ contextRecord, dispatcherContext)
445
+ }
446
+ }
447
+
448
+ #[ no_mangle] // referenced from rust_try.ll
449
+ pub extern "C" fn rust_eh_personality_catch (
450
+ exceptionRecord : * mut EXCEPTION_RECORD ,
451
+ establisherFrame : * mut c_void ,
452
+ contextRecord : * mut CONTEXT ,
453
+ dispatcherContext : * mut DISPATCHER_CONTEXT
454
+ ) -> EXCEPTION_DISPOSITION
455
+ {
456
+ extern "C" fn inner (
457
+ _version : c_int ,
458
+ actions : uw:: _Unwind_Action ,
459
+ _exception_class : uw:: _Unwind_Exception_Class ,
460
+ _ue_header : * mut uw:: _Unwind_Exception ,
461
+ _context : * mut uw:: _Unwind_Context
462
+ ) -> uw:: _Unwind_Reason_Code
463
+ {
464
+ if ( actions as c_int & uw:: _UA_SEARCH_PHASE as c_int ) != 0 { // search phase
465
+ uw:: _URC_HANDLER_FOUND // catch!
466
+ }
467
+ else { // cleanup phase
468
+ uw:: _URC_INSTALL_CONTEXT
380
469
}
381
470
}
471
+
472
+ unsafe {
473
+ _GCC_specific_handler ( exceptionRecord, establisherFrame,
474
+ contextRecord, dispatcherContext,
475
+ inner)
476
+ }
382
477
}
383
478
}
384
479
0 commit comments