1
1
//! Trap handling on Unix based on POSIX signals.
2
2
3
- use crate :: runtime:: vm:: traphandlers:: { tls, TrapTest } ;
3
+ use crate :: runtime:: vm:: traphandlers:: { tls, TrapRegisters , TrapTest } ;
4
4
use crate :: runtime:: vm:: VMContext ;
5
5
use std:: cell:: RefCell ;
6
6
use std:: io;
@@ -166,23 +166,24 @@ unsafe extern "C" fn trap_handler(
166
166
// Otherwise flag ourselves as handling a trap, do the trap
167
167
// handling, and reset our trap handling flag. Then we figure
168
168
// out what to do based on the result of the trap handling.
169
- let ( pc, fp) = get_pc_and_fp ( context, signum) ;
170
- let test = info. test_if_trap ( pc, |handler| handler ( signum, siginfo, context) ) ;
169
+ let faulting_addr = match signum {
170
+ libc:: SIGSEGV | libc:: SIGBUS => Some ( ( * siginfo) . si_addr ( ) as usize ) ,
171
+ _ => None ,
172
+ } ;
173
+ let regs = get_trap_registers ( context, signum) ;
174
+ let test = info. test_if_trap ( regs, faulting_addr, |handler| {
175
+ handler ( signum, siginfo, context)
176
+ } ) ;
171
177
172
178
// Figure out what to do based on the result of this handling of
173
179
// the trap. Note that our sentinel value of 1 means that the
174
180
// exception was handled by a custom exception handler, so we
175
181
// keep executing.
176
- let ( jmp_buf, trap ) = match test {
182
+ let jmp_buf = match test {
177
183
TrapTest :: NotWasm => return false ,
178
184
TrapTest :: HandledByEmbedder => return true ,
179
- TrapTest :: Trap { jmp_buf, trap } => ( jmp_buf, trap) ,
180
- } ;
181
- let faulting_addr = match signum {
182
- libc:: SIGSEGV | libc:: SIGBUS => Some ( ( * siginfo) . si_addr ( ) as usize ) ,
183
- _ => None ,
185
+ TrapTest :: Trap { jmp_buf } => jmp_buf,
184
186
} ;
185
- info. set_jit_trap ( pc, fp, faulting_addr, trap) ;
186
187
// On macOS this is a bit special, unfortunately. If we were to
187
188
// `siglongjmp` out of the signal handler that notably does
188
189
// *not* reset the sigaltstack state of our signal handler. This
@@ -247,20 +248,20 @@ unsafe extern "C" fn trap_handler(
247
248
}
248
249
}
249
250
250
- unsafe fn get_pc_and_fp ( cx : * mut libc:: c_void , _signum : libc:: c_int ) -> ( * const u8 , usize ) {
251
+ unsafe fn get_trap_registers ( cx : * mut libc:: c_void , _signum : libc:: c_int ) -> TrapRegisters {
251
252
cfg_if:: cfg_if! {
252
253
if #[ cfg( all( any( target_os = "linux" , target_os = "android" ) , target_arch = "x86_64" ) ) ] {
253
254
let cx = & * ( cx as * const libc:: ucontext_t) ;
254
- (
255
- cx. uc_mcontext. gregs[ libc:: REG_RIP as usize ] as * const u8 ,
256
- cx. uc_mcontext. gregs[ libc:: REG_RBP as usize ] as usize
257
- )
255
+ TrapRegisters {
256
+ pc : cx. uc_mcontext. gregs[ libc:: REG_RIP as usize ] as usize ,
257
+ fp : cx. uc_mcontext. gregs[ libc:: REG_RBP as usize ] as usize ,
258
+ }
258
259
} else if #[ cfg( all( any( target_os = "linux" , target_os = "android" ) , target_arch = "aarch64" ) ) ] {
259
260
let cx = & * ( cx as * const libc:: ucontext_t) ;
260
- (
261
- cx. uc_mcontext. pc as * const u8 ,
262
- cx. uc_mcontext. regs[ 29 ] as usize ,
263
- )
261
+ TrapRegisters {
262
+ pc : cx. uc_mcontext. pc as usize ,
263
+ fp : cx. uc_mcontext. regs[ 29 ] as usize ,
264
+ }
264
265
} else if #[ cfg( all( target_os = "linux" , target_arch = "s390x" ) ) ] {
265
266
// On s390x, SIGILL and SIGFPE are delivered with the PSW address
266
267
// pointing *after* the faulting instruction, while SIGSEGV and
@@ -277,46 +278,46 @@ unsafe fn get_pc_and_fp(cx: *mut libc::c_void, _signum: libc::c_int) -> (*const
277
278
_ => 0 ,
278
279
} ;
279
280
let cx = & * ( cx as * const libc:: ucontext_t) ;
280
- (
281
- ( cx. uc_mcontext. psw. addr - trap_offset) as * const u8 ,
282
- * ( cx. uc_mcontext. gregs[ 15 ] as * const usize ) ,
283
- )
281
+ TrapRegisters {
282
+ pc : ( cx. uc_mcontext. psw. addr - trap_offset) as usize ,
283
+ fp : * ( cx. uc_mcontext. gregs[ 15 ] as * const usize ) ,
284
+ }
284
285
} else if #[ cfg( all( target_os = "macos" , target_arch = "x86_64" ) ) ] {
285
286
let cx = & * ( cx as * const libc:: ucontext_t) ;
286
- (
287
- ( * cx. uc_mcontext) . __ss. __rip as * const u8 ,
288
- ( * cx. uc_mcontext) . __ss. __rbp as usize ,
289
- )
287
+ TrapRegisters {
288
+ pc : ( * cx. uc_mcontext) . __ss. __rip as usize ,
289
+ fp : ( * cx. uc_mcontext) . __ss. __rbp as usize ,
290
+ }
290
291
} else if #[ cfg( all( target_os = "macos" , target_arch = "aarch64" ) ) ] {
291
292
let cx = & * ( cx as * const libc:: ucontext_t) ;
292
- (
293
- ( * cx. uc_mcontext) . __ss. __pc as * const u8 ,
294
- ( * cx. uc_mcontext) . __ss. __fp as usize ,
295
- )
293
+ TrapRegisters {
294
+ pc : ( * cx. uc_mcontext) . __ss. __pc as usize ,
295
+ fp : ( * cx. uc_mcontext) . __ss. __fp as usize ,
296
+ }
296
297
} else if #[ cfg( all( target_os = "freebsd" , target_arch = "x86_64" ) ) ] {
297
298
let cx = & * ( cx as * const libc:: ucontext_t) ;
298
- (
299
- cx. uc_mcontext. mc_rip as * const u8 ,
300
- cx. uc_mcontext. mc_rbp as usize ,
301
- )
299
+ TrapRegisters {
300
+ pc : cx. uc_mcontext. mc_rip as usize ,
301
+ fp : cx. uc_mcontext. mc_rbp as usize ,
302
+ }
302
303
} else if #[ cfg( all( target_os = "linux" , target_arch = "riscv64" ) ) ] {
303
304
let cx = & * ( cx as * const libc:: ucontext_t) ;
304
- (
305
- cx. uc_mcontext. __gregs[ libc:: REG_PC ] as * const u8 ,
306
- cx. uc_mcontext. __gregs[ libc:: REG_S0 ] as usize ,
307
- )
305
+ TrapRegisters {
306
+ pc : cx. uc_mcontext. __gregs[ libc:: REG_PC ] as usize ,
307
+ fp : cx. uc_mcontext. __gregs[ libc:: REG_S0 ] as usize ,
308
+ }
308
309
} else if #[ cfg( all( target_os = "freebsd" , target_arch = "aarch64" ) ) ] {
309
310
let cx = & * ( cx as * const libc:: mcontext_t) ;
310
- (
311
- cx. mc_gpregs. gp_elr as * const u8 ,
312
- cx. mc_gpregs. gp_x[ 29 ] as usize ,
313
- )
311
+ TrapRegisters {
312
+ pc : cx. mc_gpregs. gp_elr as usize ,
313
+ fp : cx. mc_gpregs. gp_x[ 29 ] as usize ,
314
+ }
314
315
} else if #[ cfg( all( target_os = "openbsd" , target_arch = "x86_64" ) ) ] {
315
316
let cx = & * ( cx as * const libc:: ucontext_t) ;
316
- (
317
- cx. sc_rip as * const u8 ,
318
- cx. sc_rbp as usize ,
319
- )
317
+ TrapRegisters {
318
+ pc : cx. sc_rip as usize ,
319
+ fp : cx. sc_rbp as usize ,
320
+ }
320
321
}
321
322
else {
322
323
compile_error!( "unsupported platform" ) ;
0 commit comments