From c90bd004c1ff4fde0e7d029495d78492bf49687d Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 8 Jan 2004 21:52:34 +0000 Subject: [PATCH] * fixed signal handling under 10.3.2, still have to verify whether it's backwards compatible --- rtl/darwin/powerpc/sig_cpu.inc | 218 +++++++++++++++++++++++++++++---- rtl/darwin/powerpc/sighnd.inc | 35 ++++-- rtl/darwin/signal.inc | 59 ++++----- 3 files changed, 248 insertions(+), 64 deletions(-) diff --git a/rtl/darwin/powerpc/sig_cpu.inc b/rtl/darwin/powerpc/sig_cpu.inc index be57b02459..c7399951b5 100644 --- a/rtl/darwin/powerpc/sig_cpu.inc +++ b/rtl/darwin/powerpc/sig_cpu.inc @@ -42,6 +42,9 @@ 09-May-91 Mike DeMoney (mike) at NeXT, Inc. Ported to m88k. } + +{$packrecords C} + const _PPC_SIGNAL_ = 1; @@ -74,33 +77,202 @@ type - regs_saved_t = (REGS_SAVED_NONE,REGS_SAVED_CALLER,REGS_SAVED_ALL - ); - { - 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. - } - 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; + { 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; + + { + 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. + } + + 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; + 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$ - 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 Several non-essential units are still missing, but make cycle works diff --git a/rtl/darwin/powerpc/sighnd.inc b/rtl/darwin/powerpc/sighnd.inc index 947e4959ea..c3580d2263 100644 --- a/rtl/darwin/powerpc/sighnd.inc +++ b/rtl/darwin/powerpc/sighnd.inc @@ -14,6 +14,13 @@ 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; var @@ -21,8 +28,6 @@ var begin res:=0; - { have to verify whether this is necessary } - fpc_enable_ppc_fpu_exceptions; case sig of SIGFPE : begin @@ -35,6 +40,12 @@ begin Else Res:=208; {coprocessor error} 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; SIGILL, SIGBUS, @@ -44,16 +55,24 @@ begin {$ifdef FPC_USE_SIGPROCMASK} reenable_signal(sig); {$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; { $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 Several non-essential units are still missing, but make cycle works diff --git a/rtl/darwin/signal.inc b/rtl/darwin/signal.inc index 8375a5ec26..f7da2690bc 100644 --- a/rtl/darwin/signal.inc +++ b/rtl/darwin/signal.inc @@ -63,17 +63,6 @@ @(#)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 SA_NOCLDSTOP = 8; SA_ONSTACK = $001; { take signal on signal stack } @@ -181,15 +170,28 @@ pad : array[0..6] of cint; { Reserved for Future Use } 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; PSignalHandler = ^SignalHandler; SignalRestorer = Procedure;cdecl; PSignalRestorer = ^SignalRestorer; TSigAction = procedure (Sig: cint; var info : tsiginfo_t;Var SigContext:SigContextRec); cdecl; - TSigset=sigset_t; - Sigset=sigset_t; - PSigSet = ^TSigSet; SigActionRec = packed record { @@ -198,8 +200,8 @@ 1: (sa_handler: TSigAction); } Sa_Handler: TSigAction; - Sa_Flags: longint; - Sa_Mask: TSigSet; + Sa_Mask: sigset_t; + Sa_Flags: cint; end; PSigActionRec = ^SigActionRec; @@ -217,14 +219,14 @@ const { Structure used in sigaltstack call. } - { signal stack base } - { signal stack length } - { SA_DISABLE and/or SA_ONSTACK } type sigaltstack = record + { signal stack base } ss_sp : ^char; + { signal stack length } ss_size : longint; + { SA_DISABLE and/or SA_ONSTACK } ss_flags : longint; end; @@ -266,23 +268,14 @@ const 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$ - 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 Several non-essential units are still missing, but make cycle works