@@ -172,125 +172,127 @@ unsafe extern "C" fn rust_eh_personality_impl(version: c_int,
172
172
}
173
173
}
174
174
175
- // The personality routine for most of our targets, except ARM, which has a slightly different ABI
176
- // (however, iOS goes here as it uses SjLj unwinding). Also, the 64-bit Windows implementation
177
- // uses a different personality (below) but eventually also calls rust_eh_personality_impl.
178
- #[ cfg( all( any( target_os = "ios" , target_os = "netbsd" , not( target_arch = "arm" ) ) ,
179
- not( all( windows, target_arch = "x86_64" , target_env = "gnu" ) ) ) ) ]
180
- #[ lang = "eh_personality" ]
181
- #[ no_mangle]
182
- #[ allow( unused) ]
183
- unsafe extern "C" fn rust_eh_personality ( version : c_int ,
184
- actions : uw:: _Unwind_Action ,
185
- exception_class : uw:: _Unwind_Exception_Class ,
186
- exception_object : * mut uw:: _Unwind_Exception ,
187
- context : * mut uw:: _Unwind_Context )
188
- -> uw:: _Unwind_Reason_Code {
189
- rust_eh_personality_impl ( version, actions, exception_class, exception_object, context)
190
- }
191
-
192
- // ARM EHABI personality routine.
193
- // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
194
- #[ cfg( all( target_arch = "arm" , not( target_os = "ios" ) , not( target_os = "netbsd" ) ) ) ]
195
- #[ lang = "eh_personality" ]
196
- #[ no_mangle]
197
- unsafe extern "C" fn rust_eh_personality ( state : uw:: _Unwind_State ,
198
- exception_object : * mut uw:: _Unwind_Exception ,
199
- context : * mut uw:: _Unwind_Context )
200
- -> uw:: _Unwind_Reason_Code {
201
- let state = state as c_int ;
202
- let action = state & uw:: _US_ACTION_MASK as c_int ;
203
- let search_phase = if action == uw:: _US_VIRTUAL_UNWIND_FRAME as c_int {
204
- // Backtraces on ARM will call the personality routine with
205
- // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
206
- // we want to continue unwinding the stack, otherwise all our backtraces
207
- // would end at __rust_try
208
- if state & uw:: _US_FORCE_UNWIND as c_int != 0 {
209
- return continue_unwind ( exception_object, context) ;
210
- }
211
- true
212
- } else if action == uw:: _US_UNWIND_FRAME_STARTING as c_int {
213
- false
214
- } else if action == uw:: _US_UNWIND_FRAME_RESUME as c_int {
215
- return continue_unwind ( exception_object, context) ;
216
- } else {
217
- return uw:: _URC_FAILURE;
218
- } ;
219
175
220
- // The DWARF unwinder assumes that _Unwind_Context holds things like the function
221
- // and LSDA pointers, however ARM EHABI places them into the exception object.
222
- // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
223
- // take only the context pointer, GCC personality routines stash a pointer to exception_object
224
- // in the context, using location reserved for ARM's "scratch register" (r12).
225
- uw:: _Unwind_SetGR ( context,
226
- uw:: UNWIND_POINTER_REG ,
227
- exception_object as uw:: _Unwind_Ptr ) ;
228
- // ...A more principled approach would be to provide the full definition of ARM's
229
- // _Unwind_Context in our libunwind bindings and fetch the required data from there directly,
230
- // bypassing DWARF compatibility functions.
176
+ cfg_if:: cfg_if! {
177
+ if #[ cfg( all( target_arch = "arm" , not( target_os = "ios" ) , not( target_os = "netbsd" ) ) ) ] {
178
+ // ARM EHABI personality routine.
179
+ // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
180
+ //
181
+ // iOS uses the default routine instead since it uses SjLj unwinding.
182
+ #[ lang = "eh_personality" ]
183
+ #[ no_mangle]
184
+ unsafe extern "C" fn rust_eh_personality( state: uw:: _Unwind_State,
185
+ exception_object: * mut uw:: _Unwind_Exception,
186
+ context: * mut uw:: _Unwind_Context)
187
+ -> uw:: _Unwind_Reason_Code {
188
+ let state = state as c_int;
189
+ let action = state & uw:: _US_ACTION_MASK as c_int;
190
+ let search_phase = if action == uw:: _US_VIRTUAL_UNWIND_FRAME as c_int {
191
+ // Backtraces on ARM will call the personality routine with
192
+ // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
193
+ // we want to continue unwinding the stack, otherwise all our backtraces
194
+ // would end at __rust_try
195
+ if state & uw:: _US_FORCE_UNWIND as c_int != 0 {
196
+ return continue_unwind( exception_object, context) ;
197
+ }
198
+ true
199
+ } else if action == uw:: _US_UNWIND_FRAME_STARTING as c_int {
200
+ false
201
+ } else if action == uw:: _US_UNWIND_FRAME_RESUME as c_int {
202
+ return continue_unwind( exception_object, context) ;
203
+ } else {
204
+ return uw:: _URC_FAILURE;
205
+ } ;
206
+
207
+ // The DWARF unwinder assumes that _Unwind_Context holds things like the function
208
+ // and LSDA pointers, however ARM EHABI places them into the exception object.
209
+ // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
210
+ // take only the context pointer, GCC personality routines stash a pointer to
211
+ // exception_object in the context, using location reserved for ARM's
212
+ // "scratch register" (r12).
213
+ uw:: _Unwind_SetGR( context,
214
+ uw:: UNWIND_POINTER_REG ,
215
+ exception_object as uw:: _Unwind_Ptr) ;
216
+ // ...A more principled approach would be to provide the full definition of ARM's
217
+ // _Unwind_Context in our libunwind bindings and fetch the required data from there
218
+ // directly, bypassing DWARF compatibility functions.
219
+
220
+ let exception_class = unsafe { ( * exception_object) . exception_class } ;
221
+ let foreign_exception = exception_class != rust_exception_class( ) ;
222
+ let eh_action = match find_eh_action( context, foreign_exception) {
223
+ Ok ( action) => action,
224
+ Err ( _) => return uw:: _URC_FAILURE,
225
+ } ;
226
+ if search_phase {
227
+ match eh_action {
228
+ EHAction :: None |
229
+ EHAction :: Cleanup ( _) => return continue_unwind( exception_object, context) ,
230
+ EHAction :: Catch ( _) => return uw:: _URC_HANDLER_FOUND,
231
+ EHAction :: Terminate => return uw:: _URC_FAILURE,
232
+ }
233
+ } else {
234
+ match eh_action {
235
+ EHAction :: None => return continue_unwind( exception_object, context) ,
236
+ EHAction :: Cleanup ( lpad) |
237
+ EHAction :: Catch ( lpad) => {
238
+ uw:: _Unwind_SetGR( context, UNWIND_DATA_REG . 0 ,
239
+ exception_object as uintptr_t) ;
240
+ uw:: _Unwind_SetGR( context, UNWIND_DATA_REG . 1 , 0 ) ;
241
+ uw:: _Unwind_SetIP( context, lpad) ;
242
+ return uw:: _URC_INSTALL_CONTEXT;
243
+ }
244
+ EHAction :: Terminate => return uw:: _URC_FAILURE,
245
+ }
246
+ }
231
247
232
- let exception_class = unsafe { ( * exception_object) . exception_class } ;
233
- let foreign_exception = exception_class != rust_exception_class ( ) ;
234
- let eh_action = match find_eh_action ( context, foreign_exception) {
235
- Ok ( action) => action,
236
- Err ( _) => return uw:: _URC_FAILURE,
237
- } ;
238
- if search_phase {
239
- match eh_action {
240
- EHAction :: None |
241
- EHAction :: Cleanup ( _) => return continue_unwind ( exception_object, context) ,
242
- EHAction :: Catch ( _) => return uw:: _URC_HANDLER_FOUND,
243
- EHAction :: Terminate => return uw:: _URC_FAILURE,
244
- }
245
- } else {
246
- match eh_action {
247
- EHAction :: None => return continue_unwind ( exception_object, context) ,
248
- EHAction :: Cleanup ( lpad) |
249
- EHAction :: Catch ( lpad) => {
250
- uw:: _Unwind_SetGR ( context, UNWIND_DATA_REG . 0 , exception_object as uintptr_t ) ;
251
- uw:: _Unwind_SetGR ( context, UNWIND_DATA_REG . 1 , 0 ) ;
252
- uw:: _Unwind_SetIP ( context, lpad) ;
253
- return uw:: _URC_INSTALL_CONTEXT;
248
+ // On ARM EHABI the personality routine is responsible for actually
249
+ // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
250
+ unsafe fn continue_unwind( exception_object: * mut uw:: _Unwind_Exception,
251
+ context: * mut uw:: _Unwind_Context)
252
+ -> uw:: _Unwind_Reason_Code {
253
+ if __gnu_unwind_frame( exception_object, context) == uw:: _URC_NO_REASON {
254
+ uw:: _URC_CONTINUE_UNWIND
255
+ } else {
256
+ uw:: _URC_FAILURE
257
+ }
258
+ }
259
+ // defined in libgcc
260
+ extern "C" {
261
+ fn __gnu_unwind_frame( exception_object: * mut uw:: _Unwind_Exception,
262
+ context: * mut uw:: _Unwind_Context)
263
+ -> uw:: _Unwind_Reason_Code;
254
264
}
255
- EHAction :: Terminate => return uw:: _URC_FAILURE,
256
265
}
257
- }
258
-
259
- // On ARM EHABI the personality routine is responsible for actually
260
- // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
261
- unsafe fn continue_unwind ( exception_object : * mut uw:: _Unwind_Exception ,
262
- context : * mut uw:: _Unwind_Context )
263
- -> uw:: _Unwind_Reason_Code {
264
- if __gnu_unwind_frame ( exception_object, context) == uw:: _URC_NO_REASON {
265
- uw:: _URC_CONTINUE_UNWIND
266
- } else {
267
- uw:: _URC_FAILURE
266
+ } else if #[ cfg( all( windows, target_arch = "x86_64" , target_env = "gnu" ) ) ] {
267
+ // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
268
+ // handler data (aka LSDA) uses GCC-compatible encoding.
269
+ #[ lang = "eh_personality" ]
270
+ #[ no_mangle]
271
+ #[ allow( nonstandard_style) ]
272
+ unsafe extern "C" fn rust_eh_personality( exceptionRecord: * mut uw:: EXCEPTION_RECORD ,
273
+ establisherFrame: uw:: LPVOID ,
274
+ contextRecord: * mut uw:: CONTEXT ,
275
+ dispatcherContext: * mut uw:: DISPATCHER_CONTEXT )
276
+ -> uw:: EXCEPTION_DISPOSITION {
277
+ uw:: _GCC_specific_handler( exceptionRecord,
278
+ establisherFrame,
279
+ contextRecord,
280
+ dispatcherContext,
281
+ rust_eh_personality_impl)
282
+ }
283
+ } else {
284
+ // The personality routine for most of our targets.
285
+ #[ lang = "eh_personality" ]
286
+ #[ no_mangle]
287
+ unsafe extern "C" fn rust_eh_personality( version: c_int,
288
+ actions: uw:: _Unwind_Action,
289
+ exception_class: uw:: _Unwind_Exception_Class,
290
+ exception_object: * mut uw:: _Unwind_Exception,
291
+ context: * mut uw:: _Unwind_Context)
292
+ -> uw:: _Unwind_Reason_Code {
293
+ rust_eh_personality_impl( version, actions, exception_class, exception_object, context)
268
294
}
269
295
}
270
- // defined in libgcc
271
- extern "C" {
272
- fn __gnu_unwind_frame ( exception_object : * mut uw:: _Unwind_Exception ,
273
- context : * mut uw:: _Unwind_Context )
274
- -> uw:: _Unwind_Reason_Code ;
275
- }
276
- }
277
-
278
- // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
279
- // handler data (aka LSDA) uses GCC-compatible encoding.
280
- #[ cfg( all( windows, target_arch = "x86_64" , target_env = "gnu" ) ) ]
281
- #[ lang = "eh_personality" ]
282
- #[ no_mangle]
283
- #[ allow( nonstandard_style) ]
284
- unsafe extern "C" fn rust_eh_personality ( exceptionRecord : * mut uw:: EXCEPTION_RECORD ,
285
- establisherFrame : uw:: LPVOID ,
286
- contextRecord : * mut uw:: CONTEXT ,
287
- dispatcherContext : * mut uw:: DISPATCHER_CONTEXT )
288
- -> uw:: EXCEPTION_DISPOSITION {
289
- uw:: _GCC_specific_handler ( exceptionRecord,
290
- establisherFrame,
291
- contextRecord,
292
- dispatcherContext,
293
- rust_eh_personality_impl)
294
296
}
295
297
296
298
unsafe fn find_eh_action ( context : * mut uw:: _Unwind_Context , foreign_exception : bool )
0 commit comments