* i386-win32 setjmp and longjmp: if SEH support is enabled, save/restore head of exception registration chain. Without this, a longjmp out of a function with exception frame(s) will leave these exception frames below ESP, which will fail integrity checks in OS and cause process termination if an exception occurs later on (or they may be overwritten by subsequent operations on stack and, again, cause undesired results).

* Additionally, use a branchless sequence to fix up result of longjmp.

git-svn-id: trunk@26238 -
This commit is contained in:
sergei 2013-12-16 10:12:36 +00:00
parent 779b92459e
commit 74f9d719f1
2 changed files with 13 additions and 4 deletions

View File

@ -23,6 +23,10 @@ asm
movl %edi,Jmp_buf.sp(%eax)
movl (%esp),%edi
movl %edi,Jmp_buf.pc(%eax)
{$ifdef FPC_USE_WIN32_SEH}
movl %fs:(0),%edi
movl %edi,Jmp_buf.exhead(%eax)
{$endif FPC_USE_WIN32_SEH}
movl Jmp_buf.edi(%eax),%edi
xorl %eax,%eax
end;
@ -31,10 +35,12 @@ end;
Procedure fpc_longJmp (Var S : Jmp_buf; value : longint); assembler;nostackframe;[Public, alias : 'FPC_LONGJMP']; compilerproc;
asm
xchgl %edx,%eax
testl %eax,%eax
jnz .L1
incl %eax
.L1:
cmpl $1,%eax
adcl $0,%eax // if result<1 then inc(result) -- never return zero.
{$ifdef FPC_USE_WIN32_SEH}
movl Jmp_buf.exhead(%edx),%edi
movl %edi,%fs:(0)
{$endif FPC_USE_WIN32_SEH}
movl Jmp_buf.ebx(%edx),%ebx
movl Jmp_buf.esi(%edx),%esi
movl Jmp_buf.edi(%edx),%edi

View File

@ -17,6 +17,9 @@ Type
jmp_buf = packed record
ebx,esi,edi : Longint;
bp,sp,pc : Pointer;
{$ifdef FPC_USE_WIN32_SEH}
exhead: Pointer;
{$endif FPC_USE_WIN32_SEH}
end;
PJmp_buf = ^jmp_buf;