@@ -1023,6 +1023,7 @@ impl Task {
1023
1023
// deliverSignal delivers the given signal and returns the following run state.
1024
1024
pub fn ThreadDeliverSignal ( & mut self , info : & SignalInfo , act : & SigAct ) -> TaskRunState {
1025
1025
let sigact = ComputeAction ( Signal ( info. Signo ) , act) ;
1026
+ debug ! ( "task_signals: thread deliver signal {:#?}" , act) ;
1026
1027
1027
1028
if self . haveSyscallReturn {
1028
1029
let ret = self . Return ( ) ;
@@ -1125,12 +1126,12 @@ impl Task {
1125
1126
// xsave features that are always enabled in signal frame fpstate.
1126
1127
pub const XFEATURE_MASK_FPSSE : u64 = 0x3 ;
1127
1128
1129
+ #[ cfg( target_arch="x86" ) ]
1128
1130
pub fn deliverSignalToHandler ( & mut self , info : & SignalInfo , sigAct : & SigAct ) -> Result < ( ) > {
1129
- #[ cfg( target_arch="aarch64" ) ]
1130
- todo ! ( "deliverSignalToHandler not implemented for aarch64" ) ;
1131
1131
let pt = self . GetPtRegs ( ) ;
1132
1132
let mut userStack = Stack :: New ( pt. get_stack_pointer ( ) - 128 ) ; // red zone
1133
1133
1134
+
1134
1135
if sigAct. flags . IsOnStack ( ) && self . signalStack . IsEnable ( ) {
1135
1136
self . signalStack . SetOnStack ( ) ;
1136
1137
if !self . signalStack . Contains ( pt. get_stack_pointer ( ) ) {
@@ -1202,25 +1203,23 @@ impl Task {
1202
1203
let currTask = Task :: Current ( ) ;
1203
1204
let regs = currTask. GetPtRegs ( ) ;
1204
1205
* regs = PtRegs :: default ( ) ;
1205
- #[ cfg( target_arch = "x86_64" ) ]
1206
- {
1207
- regs. rsp = rsp;
1208
- regs. rcx = sigAct. handler ;
1209
- regs. r11 = 0x2 ;
1210
- regs. rdi = signo;
1211
- regs. rsi = sigInfoAddr;
1212
- regs. rdx = sigCtxAddr;
1213
- regs. rax = 0 ;
1214
- regs. rip = regs. rcx ;
1215
- regs. eflags = regs. r11 ;
1216
- }
1217
-
1206
+ regs. rsp = rsp;
1207
+ regs. rcx = sigAct. handler ; // x86 return address
1208
+ regs. r11 = 0x2 ; // x86 rflags
1209
+ regs. rdi = signo; // paras to handler
1210
+ regs. rsi = sigInfoAddr;
1211
+ regs. rdx = sigCtxAddr;
1212
+ regs. rax = 0 ;
1213
+ regs. rip = regs. rcx ;
1214
+ regs. eflags = regs. r11 ;
1218
1215
1219
1216
return Ok ( ( ) ) ;
1220
1217
}
1221
1218
1222
1219
#[ cfg( target_arch = "x86_64" ) ]
1223
1220
pub fn SignalReturn ( & mut self , _rt : bool ) -> Result < i64 > {
1221
+ // sigret from user signal handler
1222
+ // sys_sigreturn
1224
1223
let pt = self . GetPtRegs ( ) ;
1225
1224
1226
1225
let mut userStack = Stack :: New ( pt. get_stack_pointer ( ) ) ;
@@ -1239,6 +1238,7 @@ impl Task {
1239
1238
self . savefpsate = true ;
1240
1239
}
1241
1240
1241
+ // restore user stack?
1242
1242
let alt = uc. Stack ;
1243
1243
1244
1244
self . SetSignalStack ( alt) ;
@@ -1263,9 +1263,97 @@ impl Task {
1263
1263
return Err ( Error :: SysCallRetCtrl ( TaskRunState :: RunSyscallRet ) ) ;
1264
1264
}
1265
1265
1266
- // TODO has to define a SignalRestore for each arch
1266
+
1267
+ #[ cfg( target_arch = "aarch64" ) ]
1268
+ pub fn deliverSignalToHandler ( & mut self , info : & SignalInfo , sigAct : & SigAct ) -> Result < ( ) > {
1269
+ let pt = self . GetPtRegs ( ) ;
1270
+ let mut userStack = Stack :: New ( pt. get_stack_pointer ( ) - 128 ) ; // red zone
1271
+
1272
+ // if user specifies their own stack
1273
+ if sigAct. flags . IsOnStack ( ) && self . signalStack . IsEnable ( ) {
1274
+ self . signalStack . SetOnStack ( ) ;
1275
+ if !self . signalStack . Contains ( pt. get_stack_pointer ( ) ) {
1276
+ userStack = Stack :: New ( self . signalStack . Top ( ) ) ;
1277
+ }
1278
+ }
1279
+ let t = self . Thread ( ) ;
1280
+ let mut mask = t. lock ( ) . signalMask ;
1281
+ let haveSavedSignalMask = t. lock ( ) . haveSavedSignalMask ;
1282
+ if haveSavedSignalMask {
1283
+ mask = t. lock ( ) . savedSignalMask ;
1284
+ t. lock ( ) . haveSavedSignalMask = false ;
1285
+ }
1286
+
1287
+ let mut newMask = t. lock ( ) . signalMask ;
1288
+ newMask. 0 |= sigAct. mask ;
1289
+ if !sigAct. flags . IsNoDefer ( ) {
1290
+ newMask. 0 |= SignalSet :: New ( Signal ( info. Signo ) ) . 0 ;
1291
+ }
1292
+ t. SetSignalMask ( newMask) ;
1293
+
1294
+ let mut fault_addr = 0 ;
1295
+ if info. Signo == Signal :: SIGBUS || info. Signo == Signal :: SIGSEGV {
1296
+ fault_addr = info. SigFault ( ) . addr ;
1297
+ }
1298
+
1299
+ // set up signal frame
1300
+
1301
+ // let's forget about the fp units for the moment
1302
+ let uc = UContext :: New ( pt, mask. 0 , fault_addr, 0 , & self . signalStack ) ;
1303
+ // TODO if SA_SIGINFO is not requested, the handler takes the form
1304
+ // void handler(int signo)
1305
+ // we should push the siginfo and sigctx conditionally
1306
+ let sigInfoAddr = userStack. PushType :: < SignalInfo > ( self , info) ?;
1307
+ let sigCtxAddr = userStack. PushType :: < UContext > ( self , & uc) ?;
1308
+ let signo = info. Signo as u64 ;
1309
+ let currTask = Task :: Current ( ) ;
1310
+ let regs = currTask. GetPtRegs ( ) ;
1311
+ * regs = PtRegs :: default ( ) ;
1312
+ regs. sp = sigCtxAddr;
1313
+ regs. pc = sigAct. handler ;
1314
+ regs. pstate = 0x0 ;
1315
+
1316
+ // parameters to the handler
1317
+ // handler(int signo, siginfo_t *info, void *context)
1318
+ regs. regs [ 0 ] = signo;
1319
+ regs. regs [ 1 ] = sigInfoAddr;
1320
+ regs. regs [ 2 ] = sigCtxAddr;
1321
+ // TODO set frame pointer regs[29] if there are other sig frames
1322
+ if sigAct. flags . HasRestorer ( ) {
1323
+ regs. regs [ 30 ] = sigAct. restorer ;
1324
+ } else {
1325
+ let vdsoAddr = Task :: Current ( ) . mm . GetUserVDSOBase ( ) ;
1326
+ assert ! ( vdsoAddr != 0 ) ;
1327
+ regs. regs [ 30 ] = vdsoAddr + VDSO_OFFSET_SIGRETURN ;
1328
+ }
1329
+ return Ok ( ( ) ) ;
1330
+ }
1331
+
1267
1332
#[ cfg( target_arch = "aarch64" ) ]
1268
1333
pub fn SignalReturn ( & mut self , _rt : bool ) -> Result < i64 > {
1269
- todo ! ( "task_signals: SignalReturn not implemented for aarch64" ) ;
1334
+ let pt = self . GetPtRegs ( ) ;
1335
+ // pop the signal frame
1336
+ let mut userStack = Stack :: New ( pt. get_stack_pointer ( ) ) ;
1337
+ let mut uc = UContext :: default ( ) ;
1338
+ userStack. PopType :: < UContext > ( self , & mut uc) ?;
1339
+ let mut sigInfo = SignalInfo :: default ( ) ;
1340
+ userStack. PopType :: < SignalInfo > ( self , & mut sigInfo) ?;
1341
+
1342
+ let alt = uc. Stack ;
1343
+ self . SetSignalStack ( alt) ;
1344
+ // restore user context
1345
+ // ignore restoring fpstate for now.
1346
+ pt. Set ( & uc. MContext ) ;
1347
+
1348
+ let oldMask = uc. MContext . oldmask & !( UNBLOCKED_SIGNALS . 0 ) ;
1349
+ let t = self . Thread ( ) ;
1350
+ t. SetSignalMask ( SignalSet ( oldMask) ) ;
1351
+ // TODO restart syscall if needed
1352
+ if t. lock ( ) . HasSignal ( ) {
1353
+ t. lock ( ) . interruptSelf ( ) ;
1354
+ }
1355
+
1356
+ // TODO Segfault if badframe
1357
+ return Err ( Error :: SysCallRetCtrl ( TaskRunState :: RunSyscallRet ) ) ;
1270
1358
}
1271
1359
}
0 commit comments