Browse Source

* Aarch64-linux: return properly from the signal handler
* Aarch64-linux: clear FPU exception flags before returning from the signal handler

git-svn-id: trunk@46870 -

florian 4 years ago
parent
commit
a22d8a7c38
2 changed files with 36 additions and 5 deletions
  1. 20 3
      rtl/linux/aarch64/sighnd.inc
  2. 16 2
      rtl/linux/aarch64/sighndh.inc

+ 20 - 3
rtl/linux/aarch64/sighnd.inc

@@ -15,6 +15,8 @@
 
 
  **********************************************************************}
  **********************************************************************}
 
 
+{$define SYSTEM_DEBUG}
+
 procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
 procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
 
 
 var
 var
@@ -23,7 +25,19 @@ begin
   res:=0;
   res:=0;
   case sig of
   case sig of
     SIGFPE:
     SIGFPE:
+      begin
         res:=207;
         res:=207;
+{$ifdef SYSTEM_DEBUG}
+        writeln('magic of FPSIMD_Context: $',hexstr(uContext^.uc_mcontext.FPSIMD_Context.head.magic,8));
+        writeln('size of FPSIMD_Context: $',hexstr(uContext^.uc_mcontext.FPSIMD_Context.head.size,8));
+{$endif SYSTEM_DEBUG}
+        if (uContext^.uc_mcontext.FPSIMD_Context.head.magic=$46508001) and
+           (uContext^.uc_mcontext.FPSIMD_Context.head.size=$210) then
+           begin
+             with uContext^.uc_mcontext.FPSIMD_Context do
+               fpsr:=fpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift);
+           end;
+      end;
     SIGILL:
     SIGILL:
         res:=216;
         res:=216;
     SIGSEGV :
     SIGSEGV :
@@ -38,7 +52,10 @@ begin
   reenable_signal(sig);
   reenable_signal(sig);
   { give runtime error at the position where the signal was raised }
   { give runtime error at the position where the signal was raised }
   if res<>0 then
   if res<>0 then
-    HandleErrorAddrFrame(res,
-      pointer(uContext^.uc_mcontext.pc),
-      pointer(uContext^.uc_mcontext.regs[29]));
+    begin
+      uContext^.uc_mcontext.regs[0]:=res;
+      uContext^.uc_mcontext.regs[1]:=uContext^.uc_mcontext.pc;
+      uContext^.uc_mcontext.regs[2]:=uContext^.uc_mcontext.regs[29];
+      pointer(uContext^.uc_mcontext.pc):=@HandleErrorAddrFrame;
+    end;
 end;
 end;

+ 16 - 2
rtl/linux/aarch64/sighndh.inc

@@ -17,6 +17,18 @@
 {$packrecords C}
 {$packrecords C}
 
 
 type
 type
+  TAarch64_ctx = record
+    magic,
+    size : DWord
+  end;
+
+  TFPSIMD_Context = record
+    head : TAarch64_ctx;
+    fpsr,
+    fpcr : DWord;
+    vregs : array[0..31] of array[0..7] of Byte;
+  end;
+
   PSigContext = ^TSigContext;
   PSigContext = ^TSigContext;
   TSigContext = record
   TSigContext = record
     fault_address : cULong;
     fault_address : cULong;
@@ -25,10 +37,12 @@ type
     pc : cULong;
     pc : cULong;
     pstate : cULong;
     pstate : cULong;
     __pad : cULong;
     __pad : cULong;
-    { The following field should be 16-byte-aligned. Currently the
+    { The following fields should be 16-byte-aligned. Currently the
       directive for specifying alignment is buggy, so the preceding
       directive for specifying alignment is buggy, so the preceding
       field was added so that the record has the right size. }
       field was added so that the record has the right size. }
-    __reserved : array[0..4095] of cUChar;
+    case Byte of
+      1: (__reserved : array[0..4095] of cUChar);
+      2: (FPSIMD_Context : TFPSIMD_Context);
   end;
   end;
 
 
   stack_t = record
   stack_t = record