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;
 
 var
@@ -23,7 +25,19 @@ begin
   res:=0;
   case sig of
     SIGFPE:
+      begin
         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:
         res:=216;
     SIGSEGV :
@@ -38,7 +52,10 @@ begin
   reenable_signal(sig);
   { give runtime error at the position where the signal was raised }
   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;

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

@@ -17,6 +17,18 @@
 {$packrecords C}
 
 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;
   TSigContext = record
     fault_address : cULong;
@@ -25,10 +37,12 @@ type
     pc : cULong;
     pstate : 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
       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;
 
   stack_t = record