* Correct SigContext structures

git-svn-id: trunk@14203 -
This commit is contained in:
pierre 2009-11-17 10:27:20 +00:00
parent 73b7248597
commit 59204b21d5
2 changed files with 281 additions and 56 deletions

View File

@ -15,48 +15,70 @@
**********************************************************************}
const
FPE_INTDIV = 1;
FPE_INTOVF = 2;
FPE_FLTDIV = 3;
FPE_FLTOVF = 4;
FPE_FLTUND = 5;
FPE_FLTRES = 6;
FPE_FLTINV = 7;
FPE_FLTSUB = 8;
procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext);public name '_FPC_DEFAULTSIGHANDLER';cdecl;
var
res,fpustate : word;
res : word;
addr : pointer;
frame : pointer;
begin
res:=0;
if assigned(sigcontext) then
begin
addr := pointer(sigcontext^.uc_mcontext.gregs[REG_PC]);
frame := pointer(sigcontext^.uc_mcontext.gregs[REG_FP])
end
else
begin
addr := nil;
frame := nil;
end;
case sig of
SIGFPE :
begin
res:=200;
(*
fpustate:=GetFPUState(SigContext^);
if (FpuState and FPU_All) <> 0 then
begin
{ first check the more precise options }
if (FpuState and FPU_DivisionByZero)<>0 then
res:=200
else if (FpuState and FPU_Overflow)<>0 then
res:=205
else if (FpuState and FPU_Underflow)<>0 then
res:=206
else if (FpuState and FPU_Denormal)<>0 then
res:=216
else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow or FPU_Invalid))<>0 Then
res:=207
else
res:=207; {'Coprocessor Error'}
end;
*)
sysResetFPU;
begin
case siginfo^.si_code of
FPE_INTDIV:
res:=200;
FPE_INTOVF:
res:=205;
FPE_FLTDIV:
res:=200;
FPE_FLTOVF:
res:=205;
FPE_FLTUND:
res:=206;
else
res:=207;
end;
end;
SIGILL,
SIGBUS,
SIGSEGV :
res:=216;
begin
res:=216;
end;
SIGBUS :
begin
res:=214;
end;
SIGINT:
res:=217;
SIGKILL :
SIGQUIT:
res:=233;
end;
{ give runtime error at the position where the signal was raised }
reenable_signal(sig);
{ give runtime error at the position where the signal was raised }
if res<>0 then
HandleErrorAddrFrame(res,pointer(SigContext^.eip),pointer(SigContext^.ebp));
HandleErrorAddrFrame(res,addr,frame);
end;

View File

@ -1,9 +1,12 @@
{
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2000 by Jonas Maebe,
Copyright (c) 2009 by Pierre Muller,
member of the Free Pascal development team.
Sigcontext and Sigaction
Sigcontext and Sigaction for amd64/i386 CPUs
Adapted from
http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/intel/sys/regset.h
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
@ -16,33 +19,233 @@
{$packrecords C}
{$packrecords C}
const
{ i386/amd64 definition }
{
#if defined(__amd64)
#define _NGREG 28
#else
#define _NGREG 19
#endif
}
{$ifdef x86_64 }
_NGREG = 28;
{$else i386 }
_NGREG = 19;
{$endif i386 }
_NGREG32 = 19;
_NGREG64 = 28;
{$ifdef x86_64}
(* AMD64 layout
#define REG_GSBASE 27
#define REG_FSBASE 26
#define REG_DS 25
#define REG_ES 24
#define REG_GS 23
#define REG_FS 22
#define REG_SS 21
#define REG_RSP 20
#define REG_RFL 19
#define REG_CS 18
#define REG_RIP 17
#define REG_ERR 16
#define REG_TRAPNO 15
#define REG_RAX 14
#define REG_RCX 13
#define REG_RDX 12
#define REG_RBX 11
#define REG_RBP 10
#define REG_RSI 9
#define REG_RDI 8
#define REG_R8 7
#define REG_R9 6
#define REG_R10 5
#define REG_R11 4
#define REG_R12 3
#define REG_R13 2
#define REG_R14 1
#define REG_R15 0
*)
REG_R15 = 0;
REG_R14 = 1;
REG_R13 = 2;
REG_R12 = 3;
REG_R11 = 4;
REG_R10 = 5;
REG_R9 = 6;
REG_R8 = 7;
REG_RDI = 8;
REG_RSI = 9;
REG_RBP = 10;
REG_RBX = 11;
REG_RDX = 12;
REG_RCX = 13;
REG_RAX = 14;
REG_TRAPNO = 15;
REG_ERR = 16;
REG_RIP = 17;
REG_CS = 18;
REG_RFL = 19;
REG_RSP = 20;
REG_SS = 21;
REG_FS = 22;
REG_GS = 23;
REG_ES = 24;
REG_DS = 25;
REG_FSBASE = 26;
REG_GSBASE = 27;
{$else i386}
(* I386 layout
#define SS 18 /* only stored on a privilege transition */
#define UESP 17 /* only stored on a privilege transition */
#define EFL 16
#define CS 15
#define EIP 14
#define ERR 13
#define TRAPNO 12
#define EAX 11
#define ECX 10
#define EDX 9
#define EBX 8
#define ESP 7
#define EBP 6
#define ESI 5
#define EDI 4
#define DS 3
#define ES 2
#define FS 1
#define GS 0
*)
REG_GS = 0;
REG_FS = 1;
REG_ES = 2;
REG_DS = 3;
REG_EDI = 4;
REG_ESI = 5;
REG_EBP = 6;
REG_ESP = 7;
REG_EBX = 8;
REG_EDX = 9;
REG_ECX = 10;
REG_EAX = 11;
REG_TRAPNO = 12;
REG_ERR = 13;
REG_EIP = 14;
REG_CS = 15;
REG_EFL = 16;
REG_UESP = 17; (* only stored on a privilege transition *)
REG_SS = 18; (* only stored on a privilege transition *)
{$endif i386}
{$ifdef x86_64 }
REG_PC = REG_RIP;
REG_FP = REG_RBP;
REG_SP = REG_RSP;
REG_PS = REG_RFL;
REG_R0 = REG_RAX;
REG_R1 = REG_RDX;
{$else /* __i386 */ }
REG_PC = REG_EIP;
REG_FP = REG_EBP;
REG_SP = REG_UESP;
REG_PS = REG_EFL;
REG_R0 = REG_EAX;
REG_R1 = REG_EDX;
{$endif }
type
PSigContext = ^TSigContext;
TSigContext = record
{ WARNING: this is a blind copy of
the linux strcuture, probably totally wrong PM }
gs, __gsh: word;
fs, __fsh: word;
es, __esh: word;
ds, __dsh: word;
edi: cardinal;
esi: cardinal;
ebp: cardinal;
esp: cardinal;
ebx: cardinal;
edx: cardinal;
ecx: cardinal;
eax: cardinal;
trapno: cardinal;
err: cardinal;
eip: cardinal;
cs, __csh: word;
eflags: cardinal;
esp_at_signal: cardinal;
ss, __ssh: word;
// commented out for now : fpstate: pfpstate;
oldmask: cardinal;
cr2: cardinal;
{$ifdef x86_64}
TGReg = cint64;
{$else}
TGReg = cint32;
{$endif}
TGReg32 = cint32;
TGReg64 = cint64;
TGRegSet = array[0.._NGREG-1] of TGReg;
TGRegSet32 = array[0.._NGREG32-1] of TGReg32;
TGRegSet64 = array[0.._NGREG64-1] of TGReg64;
type
FPU_SAVE_TYPE = (fnsave_type, fxsave_type);
TFPURegs = record
case longint of
0: ( fpuregs: array[0..31] of cardinal);
1: ( fpudregs: array[0..15] of double);
end;
PFQ = ^TFQ;
TFQ = record
fpq_addr : ^cuint;
fpq_instr : cuint;
end;
(* struct fpchip_state {
uint32_t state[27]; /* 287/387 saved state */
uint32_t status; /* saved at exception */
uint32_t mxcsr; /* SSE control and status */
uint32_t xstatus; /* SSE mxcsr at exception */
uint32_t __pad[2]; /* align to 128-bits */
upad128_t xmm[8]; /* %xmm0-%xmm7 */
} fpchip_state;
*)
TUpad128 = record
case longint of
0: (_q : extended;);
1: (_l : array [0..4-1] of cuint32;);
end;
TFPChip_State = record
state : array [0..27-1] of cuint32;
status : cuint32;
mxcsr : cuint32;
xstatus : cuint32;
__pad : array [0..1] of cuint32;
xmm : array [0..8-1] of TUpad128;
end;
TFP_emul_space = record
fp_emul : array [0..248-1] of cuint8;
fp_epad : array [0..1] of cuint8;
end;
TFPU = record
case longint of
0: (fpchip_state : TFPChip_state;);
1: (fp_emul_space : TFP_emul_space;);
2: (f_fpregs : Array[0..130-1] of cuint32;);
end;
TFPRegSet = TFPU;
TMContext = record
gregs : TGRegSet;
fpregs : TFPRegSet;
end;
TStack = record
ss_sp : pointer;
ss_size : size_t;
ss_flags : cint;
end;
PSigContext = ^TSigContext;
TSigContext = record
uc_flags : cuint;
uc_link : PSigContext;
uc_sigmask : sigset_t;
uc_stack : TStack;
uc_mcontext : TMContext;
__uc_filler : array[0..5-1] of clong;
end;