mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-09 19:57:20 +01:00
* exception_level counting was wrong if dpmi_jmp_buf was copied
This commit is contained in:
parent
6a5776df47
commit
b3635d6190
@ -104,7 +104,6 @@ function djgpp_set_ctrl_c(enable : boolean) : boolean;
|
||||
{ Other }
|
||||
function dpmi_set_coprocessor_emulation(flag : longint) : longint;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{$ASMMODE DIRECT}
|
||||
@ -114,6 +113,7 @@ implementation
|
||||
var
|
||||
v2prt0_ds_alias : pointer;external name '___v2prt0_ds_alias';
|
||||
djgpp_ds_alias : pointer;external name '___djgpp_ds_alias';
|
||||
djgpp_exception_state_ptr : pexception_state;external name '___djgpp_exception_state_ptr';
|
||||
endtext : longint;external name '_etext';
|
||||
starttext : longint;external name 'start';
|
||||
djgpp_old_kbd : tseginfo;external name '___djgpp_old_kbd';
|
||||
@ -169,12 +169,31 @@ end;
|
||||
SetJmp/LongJmp
|
||||
****************************************************************************}
|
||||
|
||||
{ function c_setjmp(var rec : dpmi_jmp_buf) : longint;cdecl;[public, alias : '_setjmp'];
|
||||
function c_setjmp(var rec : dpmi_jmp_buf) : longint;[public, alias : '_setjmp'];
|
||||
begin
|
||||
c_setjmp:=dpmi_setjmp(rec);
|
||||
end; }
|
||||
{ here we need to be subtle :
|
||||
- we need to return with the arg still on the stack
|
||||
- but we also need to jmp to FPC_setjmp and not to call it
|
||||
because otherwise the return address is wrong !!
|
||||
|
||||
For this we shift the return address down and
|
||||
duplicate the rec on stack }
|
||||
asm
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
subl $8,%esp
|
||||
movl %eax,(%esp)
|
||||
movl 8(%esp),%eax
|
||||
movl %eax,4(%esp)
|
||||
movl 12(%esp),%eax
|
||||
movl %eax,8(%esp)
|
||||
popl %eax
|
||||
jmp FPC_setjmp
|
||||
end;
|
||||
end;
|
||||
|
||||
function dpmi_setjmp(var rec : dpmi_jmp_buf) : longint;
|
||||
|
||||
function dpmi_setjmp(var rec : dpmi_jmp_buf) : longint;[alias : 'FPC_setjmp'];
|
||||
begin
|
||||
asm
|
||||
pushl %edi
|
||||
@ -224,15 +243,16 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{procedure c_longjmp(var rec : dpmi_jmp_buf;return_value : longint);cdecl;[public, alias : '_longjmp'];
|
||||
procedure c_longjmp(var rec : dpmi_jmp_buf;return_value : longint);[public, alias : '_longjmp'];
|
||||
begin
|
||||
dpmi_longjmp(rec,return_value);
|
||||
end; }
|
||||
|
||||
procedure dpmi_longjmp(var rec : dpmi_jmp_buf;return_value : longint);
|
||||
{ never gets here !! so pascal stack convention is no problem }
|
||||
end;
|
||||
|
||||
procedure dpmi_longjmp(var rec : dpmi_jmp_buf;return_value : longint);[alias : 'FPC_longjmp'];
|
||||
begin
|
||||
if (@rec=pdpmi_jmp_buf(djgpp_exception_state)) and (exception_level>0) then
|
||||
dec(exception_level);
|
||||
if (exception_level>0) then
|
||||
dec(exception_level);
|
||||
asm
|
||||
{ restore compiler shit }
|
||||
popl %ebp
|
||||
@ -479,15 +499,21 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
const message_level : byte = 0;
|
||||
|
||||
function do_faulting_finish_message : integer;
|
||||
var
|
||||
en : pchar;
|
||||
signum,i : longint;
|
||||
old_vid : byte;
|
||||
label
|
||||
simple_exit;
|
||||
begin
|
||||
inc(message_level);
|
||||
if message_level>2 then
|
||||
goto simple_exit;
|
||||
do_faulting_finish_message:=0;
|
||||
signum:=djgpp_exception_state^.__signum;
|
||||
signum:=djgpp_exception_state_ptr^.__signum;
|
||||
{ check video mode for original here and reset (not if PC98) */ }
|
||||
if ((go32_info_block.linear_address_of_primary_screen <> $a0000) and
|
||||
(farpeekb(dosmemselector, $449) <> old_video_mode)) then
|
||||
@ -520,13 +546,13 @@ begin
|
||||
err('Exception ');
|
||||
itox(signum, 2);
|
||||
err(' at eip=');
|
||||
itox(djgpp_exception_state^.__eip, 8);
|
||||
itox(djgpp_exception_state_ptr^.__eip, 8);
|
||||
end
|
||||
else
|
||||
begin
|
||||
write(stderr, 'FPC ',en);
|
||||
err(' at eip=');
|
||||
itox(djgpp_exception_state^.__eip, 8);
|
||||
itox(djgpp_exception_state_ptr^.__eip, 8);
|
||||
end;
|
||||
{ Control-C should stop the program also !}
|
||||
{if (signum = $79) then
|
||||
@ -536,7 +562,7 @@ begin
|
||||
end;}
|
||||
if ((signum < EXCEPTIONCOUNT) and (has_error[signum]=1)) then
|
||||
begin
|
||||
errorcode := djgpp_exception_state^.__sigmask and $ffff;
|
||||
errorcode := djgpp_exception_state_ptr^.__sigmask and $ffff;
|
||||
if(errorcode<>0) then
|
||||
begin
|
||||
err(', error=');
|
||||
@ -545,43 +571,48 @@ begin
|
||||
end;
|
||||
errln('');
|
||||
err('eax=');
|
||||
itox(djgpp_exception_state^.__eax, 8);
|
||||
err(' ebx='); itox(djgpp_exception_state^.__ebx, 8);
|
||||
err(' ecx='); itox(djgpp_exception_state^.__ecx, 8);
|
||||
err(' edx='); itox(djgpp_exception_state^.__edx, 8);
|
||||
err(' esi='); itox(djgpp_exception_state^.__esi, 8);
|
||||
err(' edi='); itox(djgpp_exception_state^.__edi, 8);
|
||||
itox(djgpp_exception_state_ptr^.__eax, 8);
|
||||
err(' ebx='); itox(djgpp_exception_state_ptr^.__ebx, 8);
|
||||
err(' ecx='); itox(djgpp_exception_state_ptr^.__ecx, 8);
|
||||
err(' edx='); itox(djgpp_exception_state_ptr^.__edx, 8);
|
||||
err(' esi='); itox(djgpp_exception_state_ptr^.__esi, 8);
|
||||
err(' edi='); itox(djgpp_exception_state_ptr^.__edi, 8);
|
||||
errln('');
|
||||
err('ebp='); itox(djgpp_exception_state^.__ebp, 8);
|
||||
err(' esp='); itox(djgpp_exception_state^.__esp, 8);
|
||||
err('ebp='); itox(djgpp_exception_state_ptr^.__ebp, 8);
|
||||
err(' esp='); itox(djgpp_exception_state_ptr^.__esp, 8);
|
||||
err(' program=');
|
||||
errln(paramstr(0));
|
||||
dump_selector('cs', djgpp_exception_state^.__cs);
|
||||
dump_selector('ds', djgpp_exception_state^.__ds);
|
||||
dump_selector('es', djgpp_exception_state^.__es);
|
||||
dump_selector('fs', djgpp_exception_state^.__fs);
|
||||
dump_selector('gs', djgpp_exception_state^.__gs);
|
||||
dump_selector('ss', djgpp_exception_state^.__ss);
|
||||
dump_selector('cs', djgpp_exception_state_ptr^.__cs);
|
||||
dump_selector('ds', djgpp_exception_state_ptr^.__ds);
|
||||
dump_selector('es', djgpp_exception_state_ptr^.__es);
|
||||
dump_selector('fs', djgpp_exception_state_ptr^.__fs);
|
||||
dump_selector('gs', djgpp_exception_state_ptr^.__gs);
|
||||
dump_selector('ss', djgpp_exception_state_ptr^.__ss);
|
||||
errln('');
|
||||
if (djgpp_exception_state^.__cs = get_cs) then
|
||||
show_call_frame(djgpp_exception_state)
|
||||
if (djgpp_exception_state_ptr^.__cs = get_cs) then
|
||||
show_call_frame(djgpp_exception_state_ptr)
|
||||
{$ifdef SYSTEMDEBUG}
|
||||
else
|
||||
errln('Exception occured in another context');
|
||||
{$endif def SYSTEMDEBUG}
|
||||
;
|
||||
if assigned(djgpp_exception_state^.__exception_ptr) then
|
||||
if (djgpp_exception_state^.__exception_ptr^.__cs = get_cs) then
|
||||
if assigned(djgpp_exception_state_ptr^.__exception_ptr) then
|
||||
if (djgpp_exception_state_ptr^.__exception_ptr^.__cs = get_cs) then
|
||||
begin
|
||||
Errln('First exception level stack');
|
||||
show_call_frame(djgpp_exception_state^.__exception_ptr);
|
||||
show_call_frame(djgpp_exception_state_ptr^.__exception_ptr);
|
||||
end
|
||||
{$ifdef SYSTEMDEBUG}
|
||||
else
|
||||
errln('First exception occured in another context');
|
||||
begin
|
||||
errln('First exception occured in another context');
|
||||
djgpp_exception_state_ptr:=djgpp_exception_state_ptr^.__exception_ptr;
|
||||
do_faulting_finish_message();
|
||||
end;
|
||||
{$endif def SYSTEMDEBUG}
|
||||
;
|
||||
{ must not return !! }
|
||||
simple_exit:
|
||||
if exceptions_on then
|
||||
djgpp_exception_toggle;
|
||||
asm
|
||||
@ -601,20 +632,20 @@ procedure djgpp_exception_processor;[public,alias : '___djgpp_exception_processo
|
||||
var
|
||||
sig : longint;
|
||||
begin
|
||||
if not assigned(djgpp_exception_state^.__exception_ptr) then
|
||||
if not assigned(djgpp_exception_state_ptr^.__exception_ptr) then
|
||||
exception_level:=1
|
||||
else
|
||||
inc(exception_level);
|
||||
|
||||
sig:=djgpp_exception_state^.__signum;
|
||||
sig:=djgpp_exception_state_ptr^.__signum;
|
||||
|
||||
if (exception_level=1) or (sig=$78) then
|
||||
begin
|
||||
sig := except_to_sig(sig);
|
||||
_raise(sig);
|
||||
if (djgpp_exception_state^.__signum >= EXCEPTIONCOUNT) then
|
||||
if (djgpp_exception_state_ptr^.__signum >= EXCEPTIONCOUNT) then
|
||||
{ Not exception so continue OK }
|
||||
dpmi_longjmp(pdpmi_jmp_buf(djgpp_exception_state)^, djgpp_exception_state^.__eax);
|
||||
dpmi_longjmp(pdpmi_jmp_buf(djgpp_exception_state_ptr)^, djgpp_exception_state_ptr^.__eax);
|
||||
{ User handler did not exit or longjmp, we must exit }
|
||||
err('FPC cannot continue from exception, exiting due to signal ');
|
||||
itox(sig, 4);
|
||||
@ -876,7 +907,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.2 1998-12-21 14:23:12 pierre
|
||||
Revision 1.3 1999-01-18 09:14:20 pierre
|
||||
* exception_level counting was wrong if dpmi_jmp_buf was copied
|
||||
|
||||
Revision 1.2 1998/12/21 14:23:12 pierre
|
||||
dpmiexcp.pp
|
||||
|
||||
Revision 1.1 1998/12/21 13:07:02 peter
|
||||
|
||||
Loading…
Reference in New Issue
Block a user