@@ -59,8 +59,7 @@ use any::{Any, AnyRefExt};
59
59
use c_str:: CString ;
60
60
use cast;
61
61
use kinds:: Send ;
62
- use libc:: { c_char, size_t} ;
63
- use libc:: { c_void, c_int} ;
62
+ use libc:: { c_void, c_char, size_t} ;
64
63
use option:: { Some , None , Option } ;
65
64
use result:: { Err , Ok } ;
66
65
use rt:: local:: Local ;
@@ -78,6 +77,7 @@ mod libunwind {
78
77
79
78
use libc:: { uintptr_t, uint64_t} ;
80
79
80
+ #[ cfg( not( target_os = "android" ) ) ]
81
81
#[ repr( C ) ]
82
82
pub enum _Unwind_Action
83
83
{
@@ -88,6 +88,18 @@ mod libunwind {
88
88
_UA_END_OF_STACK = 16 ,
89
89
}
90
90
91
+ #[ cfg( target_os = "android" ) ]
92
+ #[ repr( C ) ]
93
+ pub enum _Unwind_State
94
+ {
95
+ _US_VIRTUAL_UNWIND_FRAME = 0 ,
96
+ _US_UNWIND_FRAME_STARTING = 1 ,
97
+ _US_UNWIND_FRAME_RESUME = 2 ,
98
+ _US_ACTION_MASK = 3 ,
99
+ _US_FORCE_UNWIND = 8 ,
100
+ _US_END_OF_STACK = 16
101
+ }
102
+
91
103
#[ repr( C ) ]
92
104
pub enum _Unwind_Reason_Code {
93
105
_URC_NO_REASON = 0 ,
@@ -99,6 +111,7 @@ mod libunwind {
99
111
_URC_HANDLER_FOUND = 6 ,
100
112
_URC_INSTALL_CONTEXT = 7 ,
101
113
_URC_CONTINUE_UNWIND = 8 ,
114
+ _URC_FAILURE = 9 , // used only by ARM EABI
102
115
}
103
116
104
117
pub type _Unwind_Exception_Class = uint64_t ;
@@ -108,8 +121,7 @@ mod libunwind {
108
121
pub struct _Unwind_Exception {
109
122
exception_class : _Unwind_Exception_Class ,
110
123
exception_cleanup : _Unwind_Exception_Cleanup_Fn ,
111
- private_1 : _Unwind_Word ,
112
- private_2 : _Unwind_Word ,
124
+ private : [ _Unwind_Word , ..20 ] ,
113
125
}
114
126
115
127
pub enum _Unwind_Context { }
@@ -148,7 +160,7 @@ impl Unwinder {
148
160
let ep = rust_try ( try_fn, closure. code as * c_void ,
149
161
closure. env as * c_void ) ;
150
162
if !ep. is_null ( ) {
151
- rtdebug ! ( "Caught {}" , ( * ep) . exception_class) ;
163
+ rtdebug ! ( "caught {}" , ( * ep) . exception_class) ;
152
164
uw:: _Unwind_DeleteException ( ep) ;
153
165
}
154
166
}
@@ -190,8 +202,7 @@ impl Unwinder {
190
202
let exception = ~uw:: _Unwind_Exception {
191
203
exception_class : rust_exception_class ( ) ,
192
204
exception_cleanup : exception_cleanup,
193
- private_1 : 0 ,
194
- private_2 : 0
205
+ private : [ 0 , ..20 ] ,
195
206
} ;
196
207
let error = uw:: _Unwind_RaiseException ( cast:: transmute ( exception) ) ;
197
208
rtabort ! ( "Could not unwind stack, error = {}" , error as int)
@@ -242,51 +253,107 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
242
253
// This is achieved by overriding the return value in search phase to always
243
254
// say "catch!".
244
255
245
- extern "C" {
246
- fn __gcc_personality_v0 ( version : c_int ,
247
- actions : uw:: _Unwind_Action ,
248
- exception_class : uw:: _Unwind_Exception_Class ,
249
- ue_header : * uw:: _Unwind_Exception ,
250
- context : * uw:: _Unwind_Context )
251
- -> uw:: _Unwind_Reason_Code ;
252
- }
256
+ #[ cfg( not( target_os = "android" ) ) ]
257
+ pub mod eabi {
258
+ use uw = super :: libunwind;
259
+ use libc:: c_int;
253
260
254
- #[ lang="eh_personality" ]
255
- #[ no_mangle] // so we can reference it by name from middle/trans/base.rs
256
- #[ doc( hidden) ]
257
- #[ cfg( not( test) ) ]
258
- pub extern "C" fn rust_eh_personality (
259
- version : c_int ,
260
- actions : uw:: _Unwind_Action ,
261
- exception_class : uw:: _Unwind_Exception_Class ,
262
- ue_header : * uw:: _Unwind_Exception ,
263
- context : * uw:: _Unwind_Context
264
- ) -> uw:: _Unwind_Reason_Code
265
- {
266
- unsafe {
267
- __gcc_personality_v0 ( version, actions, exception_class, ue_header,
268
- context)
261
+ extern "C" {
262
+ fn __gcc_personality_v0 ( version : c_int ,
263
+ actions : uw:: _Unwind_Action ,
264
+ exception_class : uw:: _Unwind_Exception_Class ,
265
+ ue_header : * uw:: _Unwind_Exception ,
266
+ context : * uw:: _Unwind_Context )
267
+ -> uw:: _Unwind_Reason_Code ;
268
+ }
269
+
270
+ #[ lang="eh_personality" ]
271
+ #[ no_mangle] // so we can reference it by name from middle/trans/base.rs
272
+ #[ doc( hidden) ]
273
+ #[ cfg( not( test) ) ]
274
+ pub extern "C" fn rust_eh_personality (
275
+ version : c_int ,
276
+ actions : uw:: _Unwind_Action ,
277
+ exception_class : uw:: _Unwind_Exception_Class ,
278
+ ue_header : * uw:: _Unwind_Exception ,
279
+ context : * uw:: _Unwind_Context
280
+ ) -> uw:: _Unwind_Reason_Code
281
+ {
282
+ unsafe {
283
+ __gcc_personality_v0 ( version, actions, exception_class, ue_header,
284
+ context)
285
+ }
286
+ }
287
+
288
+ #[ no_mangle] // referenced from rust_try.ll
289
+ #[ doc( hidden) ]
290
+ #[ cfg( not( test) ) ]
291
+ pub extern "C" fn rust_eh_personality_catch (
292
+ version : c_int ,
293
+ actions : uw:: _Unwind_Action ,
294
+ exception_class : uw:: _Unwind_Exception_Class ,
295
+ ue_header : * uw:: _Unwind_Exception ,
296
+ context : * uw:: _Unwind_Context
297
+ ) -> uw:: _Unwind_Reason_Code
298
+ {
299
+ if ( actions as c_int & uw:: _UA_SEARCH_PHASE as c_int ) != 0 { // search phase
300
+ uw:: _URC_HANDLER_FOUND // catch!
301
+ }
302
+ else { // cleanup phase
303
+ unsafe {
304
+ __gcc_personality_v0 ( version, actions, exception_class, ue_header,
305
+ context)
306
+ }
307
+ }
269
308
}
270
309
}
271
310
272
- #[ no_mangle] // referenced from rust_try.ll
273
- #[ doc( hidden) ]
274
- #[ cfg( not( test) ) ]
275
- pub extern "C" fn rust_eh_personality_catch (
276
- version : c_int ,
277
- actions : uw:: _Unwind_Action ,
278
- exception_class : uw:: _Unwind_Exception_Class ,
279
- ue_header : * uw:: _Unwind_Exception ,
280
- context : * uw:: _Unwind_Context
281
- ) -> uw:: _Unwind_Reason_Code
282
- {
283
- if ( actions as c_int & uw:: _UA_SEARCH_PHASE as c_int ) != 0 { // search phase
284
- uw:: _URC_HANDLER_FOUND // catch!
311
+ // ARM EHABI uses a slightly different personality routine signature,
312
+ // but otherwise works the same.
313
+ #[ cfg( target_os = "android" ) ]
314
+ pub mod eabi {
315
+ use uw = super :: libunwind;
316
+ use libc:: c_int;
317
+
318
+ extern "C" {
319
+ fn __gcc_personality_v0 ( state : uw:: _Unwind_State ,
320
+ ue_header : * uw:: _Unwind_Exception ,
321
+ context : * uw:: _Unwind_Context )
322
+ -> uw:: _Unwind_Reason_Code ;
285
323
}
286
- else { // cleanup phase
324
+
325
+ #[ lang="eh_personality" ]
326
+ #[ no_mangle] // so we can reference it by name from middle/trans/base.rs
327
+ #[ doc( hidden) ]
328
+ #[ cfg( not( test) ) ]
329
+ pub extern "C" fn rust_eh_personality (
330
+ state : uw:: _Unwind_State ,
331
+ ue_header : * uw:: _Unwind_Exception ,
332
+ context : * uw:: _Unwind_Context
333
+ ) -> uw:: _Unwind_Reason_Code
334
+ {
287
335
unsafe {
288
- __gcc_personality_v0 ( version, actions, exception_class, ue_header,
289
- context)
336
+ __gcc_personality_v0 ( state, ue_header, context)
337
+ }
338
+ }
339
+
340
+ #[ no_mangle] // referenced from rust_try.ll
341
+ #[ doc( hidden) ]
342
+ #[ cfg( not( test) ) ]
343
+ pub extern "C" fn rust_eh_personality_catch (
344
+ state : uw:: _Unwind_State ,
345
+ ue_header : * uw:: _Unwind_Exception ,
346
+ context : * uw:: _Unwind_Context
347
+ ) -> uw:: _Unwind_Reason_Code
348
+ {
349
+ if ( state as c_int & uw:: _US_ACTION_MASK as c_int )
350
+ == uw:: _US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
351
+ uw:: _URC_HANDLER_FOUND // catch!
352
+ }
353
+ else { // cleanup phase
354
+ unsafe {
355
+ __gcc_personality_v0 ( state, ue_header, context)
356
+ }
290
357
}
291
358
}
292
359
}
0 commit comments