Browse Source

* fixed signal handling under 10.3.2, still have to verify whether it's
backwards compatible

Jonas Maebe 21 years ago
parent
commit
c90bd004c1
3 changed files with 246 additions and 62 deletions
  1. 193 21
      rtl/darwin/powerpc/sig_cpu.inc
  2. 27 8
      rtl/darwin/powerpc/sighnd.inc
  3. 26 33
      rtl/darwin/signal.inc

+ 193 - 21
rtl/darwin/powerpc/sig_cpu.inc

@@ -42,6 +42,9 @@
      09-May-91  Mike DeMoney (mike) at NeXT, Inc.
      09-May-91  Mike DeMoney (mike) at NeXT, Inc.
         Ported to m88k.
         Ported to m88k.
     }
     }
+
+{$packrecords C}
+
   const
   const
      _PPC_SIGNAL_ = 1;
      _PPC_SIGNAL_ = 1;
 
 
@@ -74,33 +77,202 @@
 
 
   type
   type
 
 
-     regs_saved_t = (REGS_SAVED_NONE,REGS_SAVED_CALLER,REGS_SAVED_ALL
-       );
+  { Structure used in sigstack call. }
+    tdarwin_stack_t = record
+        ss_sp    : pchar;        { signal stack base }
+        ss_size  : cint;         { signal stack length }
+        ss_flags : cint;         { SA_DISABLE and/or SA_ONSTACK }
+    end;
+
+     ppc_thread_state = record
+  { Instruction address register (PC)  }
+          srr0 : dword;
+  { Machine state register (supervisor)  }
+          srr1 : dword;
+          r0 : dword;
+          r1 : dword;
+          r2 : dword;
+          r3 : dword;
+          r4 : dword;
+          r5 : dword;
+          r6 : dword;
+          r7 : dword;
+          r8 : dword;
+          r9 : dword;
+          r10 : dword;
+          r11 : dword;
+          r12 : dword;
+          r13 : dword;
+          r14 : dword;
+          r15 : dword;
+          r16 : dword;
+          r17 : dword;
+          r18 : dword;
+          r19 : dword;
+          r20 : dword;
+          r21 : dword;
+          r22 : dword;
+          r23 : dword;
+          r24 : dword;
+          r25 : dword;
+          r26 : dword;
+          r27 : dword;
+          r28 : dword;
+          r29 : dword;
+          r30 : dword;
+          r31 : dword;
+  { Condition register  }
+          cr : dword;
+  { User's integer exception register  }
+          xer : dword;
+  { Link register  }
+          lr : dword;
+  { Count register  }
+          ctr : dword;
+  { MQ register (601 only)  }
+          mq : dword;
+  { Vector Save Register  }
+          vrsave : dword;
+       end;
+     ppc_thread_state_t = ppc_thread_state;
+
+{$packrecords 4}
+     ppc_thread_state64 = record
+          srr0 : qword;
+          srr1 : qword;
+          r0 : qword;
+          r1 : qword;
+          r2 : qword;
+          r3 : qword;
+          r4 : qword;
+          r5 : qword;
+          r6 : qword;
+          r7 : qword;
+          r8 : qword;
+          r9 : qword;
+          r10 : qword;
+          r11 : qword;
+          r12 : qword;
+          r13 : qword;
+          r14 : qword;
+          r15 : qword;
+          r16 : qword;
+          r17 : qword;
+          r18 : qword;
+          r19 : qword;
+          r20 : qword;
+          r21 : qword;
+          r22 : qword;
+          r23 : qword;
+          r24 : qword;
+          r25 : qword;
+          r26 : qword;
+          r27 : qword;
+          r28 : qword;
+          r29 : qword;
+          r30 : qword;
+          r31 : qword;
+          cr : dword;
+          xer : qword;
+          lr : qword;
+          ctr : qword;
+          vrsave : dword;
+       end;
+     ppc_thread_state64_t = ppc_thread_state64;
+
+{$packrecords C}
+
+  { This structure should be double-word aligned for performance  }
+  type
+
+     ppc_float_state = record
+          fpregs : array[0..31] of double;
+  { fpscr is 64 bits, 32 bits of rubbish  }
+          fpscr_pad : dword;
+  { floating point status register  }
+          fpscr : dword;
+       end;
+     ppc_float_state_t = ppc_float_state;
+
+  { VRs that have been saved  }
+     ppc_vector_state = record
+          save_vr : array[0..31] of array[0..3] of dword;
+          save_vscr : array[0..3] of dword;
+          save_pad5 : array[0..3] of dword;
+          save_vrvalid : dword;
+          save_pad6 : array[0..6] of dword;
+       end;
+     ppc_vector_state_t = ppc_vector_state;
+
   {
   {
-     Information pushed on stack when a signal is delivered.
-     This is used by the kernel to restore state following
-     execution of the signal handler.  It is also made available
-     to the handler to allow it to properly restore state if
-     a non-standard exit is performed.
+     ppc_exception_state
+    
+     This structure corresponds to some additional state of the user
+     registers as saved in the PCB upon kernel entry. They are only
+     available if an exception is passed out of the kernel, and even
+     then not all are guaranteed to be updated.
+    
+     Some padding is included in this structure which allows space for
+     servers to store temporary values if need be, to maintain binary
+     compatiblity.
     }
     }
-     sigcontextrec = record
-  { sigstack state to restore  }
-          sc_onstack : longint;
-  { signal mask to restore  }
-          sc_mask : longint;
-  { pc  }
-          sc_ir : longint;
-  { processor status word  }
-          sc_psw : longint;
-  { stack pointer if sc_regs == NULL  }
-          sc_sp : longint;
-  { (kernel private) saved state  }
-          sc_regs : pointer;
+
+  type
+
+     ppc_exception_state = record
+  { Fault registers for coredump  }
+          dar : dword;
+          dsisr : dword;
+  { number of powerpc exception taken  }
+          exception : dword;
+  { align to 16 bytes  }
+          pad0 : dword;
+  { space in PCB "just in case"  }
+          pad1 : array[0..3] of dword;
+       end;
+     ppc_exception_state_t = ppc_exception_state;
+
+{$packrecords 4}
+
+  type
+
+     ppc_exception_state64 = record
+  { Fault registers for coredump  }
+          dar : qword;
+          dsisr : dword;
+  { number of powerpc exception taken  }
+          exception : dword;
+  { space in PCB "just in case"  }
+          pad1 : array[0..3] of dword;
        end;
        end;
+     ppc_exception_state64_t = ppc_exception_state64;
+
+{$packrecords C}
+
+     mcontext_t = record
+        es: ppc_exception_state_t;
+        ss: ppc_thread_state_t;
+        fs: ppc_float_state_t;
+        vs: ppc_vector_state_t;
+     end;
+
+     psigcontextrec = ^sigcontextrec;
+     sigcontextrec = record
+        uc_onstack : cint;
+        uc_sigmask : sigset_t;        { signal mask used by this context }
+        uc_stack   : tdarwin_stack_t; { stack used by this context }
+        uc_link    : psigcontextrec;  { pointer to resuming context }
+        uc_mcsize  : size_t;          { size of the machine context passed in }
+        uc_mcontext: ^mcontext_t;      { machine specific context }
+     end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2004-01-04 20:05:38  jonas
+  Revision 1.2  2004-01-08 21:52:34  jonas
+    * fixed signal handling under 10.3.2, still have to verify whether it's
+      backwards compatible
+
+  Revision 1.1  2004/01/04 20:05:38  jonas
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
       Several non-essential units are still missing, but make cycle works
       Several non-essential units are still missing, but make cycle works
 
 

+ 27 - 8
rtl/darwin/powerpc/sighnd.inc

@@ -14,6 +14,13 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 }
 }
 
 
+procedure darwin_signal_trampoline(pc,r1: pointer; res: longint);
+begin
+{ give runtime error at the position where the signal was raised }
+  HandleErrorAddrFrame(res,pc,r1);
+end;
+
+
 procedure SignalToRunerror(Sig: cint; var info : tsiginfo_t;Var SigContext:SigContextRec); cdecl;
 procedure SignalToRunerror(Sig: cint; var info : tsiginfo_t;Var SigContext:SigContextRec); cdecl;
 
 
 var
 var
@@ -21,8 +28,6 @@ var
 
 
 begin
 begin
   res:=0;
   res:=0;
-  { have to verify whether this is necessary }
-  fpc_enable_ppc_fpu_exceptions;
   case sig of
   case sig of
     SIGFPE :
     SIGFPE :
       begin
       begin
@@ -35,6 +40,12 @@ begin
           Else
           Else
               Res:=208; {coprocessor error}
               Res:=208; {coprocessor error}
         end;
         end;
+        { FPU exceptions are completely disabled by the kernel if one occurred, it  }
+        { seems this is necessary to be able to return to user mode. They can be    }
+        { enabled by executing a sigreturn, however then the exception is triggered }
+        { triggered again immediately if we don't turn off the "exception occurred" }
+        { flags in fpscr                                                            }
+        SigContext.uc_mcontext^.fs.fpscr := SigContext.uc_mcontext^.fs.fpscr and not($fffc0000);
       end;
       end;
     SIGILL,
     SIGILL,
     SIGBUS,
     SIGBUS,
@@ -44,16 +55,24 @@ begin
   {$ifdef FPC_USE_SIGPROCMASK}
   {$ifdef FPC_USE_SIGPROCMASK}
    reenable_signal(sig);
    reenable_signal(sig);
   {$endif }
   {$endif }
-{ give runtime error at the position where the signal was raised }
-  if res<>0 then
-   begin
-     HandleErrorAddrFrame(res,Pointer(SigContext.sc_ir),pointer(SigContext.sc_sp));
-   end;
+
+  { return to trampoline }
+  if res <> 0 then
+    begin
+      SigContext.uc_mcontext^.ss.r3 := SigContext.uc_mcontext^.ss.srr0;
+      SigContext.uc_mcontext^.ss.r4 := SigContext.uc_mcontext^.ss.r1;
+      SigContext.uc_mcontext^.ss.r5 := res;
+      pointer(SigContext.uc_mcontext^.ss.srr0) := @darwin_signal_trampoline;
+    end;
 end;
 end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2004-01-04 20:05:38  jonas
+  Revision 1.2  2004-01-08 21:52:34  jonas
+    * fixed signal handling under 10.3.2, still have to verify whether it's
+      backwards compatible
+
+  Revision 1.1  2004/01/04 20:05:38  jonas
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
       Several non-essential units are still missing, but make cycle works
       Several non-essential units are still missing, but make cycle works
 
 

+ 26 - 33
rtl/darwin/signal.inc

@@ -63,17 +63,6 @@
         @(#)signal.h    8.2 (Berkeley) 1/21/94
         @(#)signal.h    8.2 (Berkeley) 1/21/94
     }
     }
 
 
-{$ifdef cpupowerpc}
-{$include powerpc/sig_cpu.inc}    { sigcontext }
-{$else cpupowerpc}
-{$ifdef cpui386}
-{$include i386/sig_cpu.inc}       { sigcontext }
-{$else cpui386}
-{$error Unsupported cpu type!}
-{$endif cpui386}
-{$endif cpupowerpc}
-
-
   const
   const
     SA_NOCLDSTOP = 8;
     SA_NOCLDSTOP = 8;
     SA_ONSTACK   = $001; { take signal on signal stack }
     SA_ONSTACK   = $001; { take signal on signal stack }
@@ -181,15 +170,28 @@
                 pad             : array[0..6] of cint; { Reserved for Future Use }
                 pad             : array[0..6] of cint; { Reserved for Future Use }
                end;
                end;
 
 
+    TSigset=sigset_t;
+    Sigset=sigset_t;
+    PSigSet = ^TSigSet;
+
+{$ifdef cpupowerpc}
+    {$include powerpc/sig_cpu.inc}    { SigContextRec }
+{$else cpupowerpc}
+{$ifdef cpui386}
+    {$include i386/sig_cpu.inc}       { SigContextRec }
+{$else cpui386}
+    {$error Unsupported cpu type!}
+{$endif cpui386}
+{$endif cpupowerpc}
+
+
+
     SignalHandler   = Procedure(Sig : Longint);cdecl;
     SignalHandler   = Procedure(Sig : Longint);cdecl;
     PSignalHandler  = ^SignalHandler;
     PSignalHandler  = ^SignalHandler;
     SignalRestorer  = Procedure;cdecl;
     SignalRestorer  = Procedure;cdecl;
     PSignalRestorer = ^SignalRestorer;
     PSignalRestorer = ^SignalRestorer;
     TSigAction = procedure (Sig: cint; var info : tsiginfo_t;Var SigContext:SigContextRec); cdecl;
     TSigAction = procedure (Sig: cint; var info : tsiginfo_t;Var SigContext:SigContextRec); cdecl;
 
 
-    TSigset=sigset_t;
-    Sigset=sigset_t;
-    PSigSet = ^TSigSet;
 
 
     SigActionRec = packed record
     SigActionRec = packed record
 {
 {
@@ -198,8 +200,8 @@
         1: (sa_handler: TSigAction);
         1: (sa_handler: TSigAction);
 }
 }
       Sa_Handler: TSigAction;
       Sa_Handler: TSigAction;
-      Sa_Flags: longint;
-      Sa_Mask: TSigSet;
+      Sa_Mask: sigset_t;
+      Sa_Flags: cint;
    end;
    end;
    PSigActionRec = ^SigActionRec;
    PSigActionRec = ^SigActionRec;
 
 
@@ -217,14 +219,14 @@ const
   {
   {
      Structure used in sigaltstack call.
      Structure used in sigaltstack call.
     }
     }
-  { signal stack base  }
-  { signal stack length  }
-  { SA_DISABLE and/or SA_ONSTACK  }
 
 
   type
   type
      sigaltstack = record
      sigaltstack = record
+  { signal stack base  }
           ss_sp : ^char;
           ss_sp : ^char;
+  { signal stack length  }
           ss_size : longint;
           ss_size : longint;
+  { SA_DISABLE and/or SA_ONSTACK  }
           ss_flags : longint;
           ss_flags : longint;
        end;
        end;
 
 
@@ -266,23 +268,14 @@ const
      FPE_FLTINV    =  5;       { invalid floating point operation }
      FPE_FLTINV    =  5;       { invalid floating point operation }
 
 
 
 
-(*
-  {
-     Structure used in sigstack call.
-    }
-  { signal stack pointer  }
-  { current status  }
-
-  type
-     sigstack = record
-          ss_sp : ^char;
-          ss_onstack : longint;
-       end;
-*)
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2004-01-04 20:05:38  jonas
+  Revision 1.5  2004-01-08 21:52:34  jonas
+    * fixed signal handling under 10.3.2, still have to verify whether it's
+      backwards compatible
+
+  Revision 1.4  2004/01/04 20:05:38  jonas
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
     * first working version of the Darwin/Mac OS X (for PowerPC) RTL
       Several non-essential units are still missing, but make cycle works
       Several non-essential units are still missing, but make cycle works