mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 16:09:17 +02:00
+ implemented proper stack checking for the i8086
git-svn-id: trunk@33787 -
This commit is contained in:
parent
9daa4bd48d
commit
c78f406d99
@ -1809,6 +1809,13 @@ unit cgcpu;
|
||||
|
||||
procedure tcg8086.g_stackpointer_alloc(list : TAsmList;localsize: longint);
|
||||
begin
|
||||
if cs_check_stack in current_settings.localswitches then
|
||||
begin
|
||||
cg.getcpuregister(list,NR_AX);
|
||||
cg.a_load_const_reg(list,OS_16, localsize,NR_AX);
|
||||
cg.a_call_name(list,'FPC_STACKCHECK_I8086',false);
|
||||
cg.ungetcpuregister(list, NR_AX);
|
||||
end;
|
||||
if localsize>0 then
|
||||
list.concat(Taicpu.Op_const_reg(A_SUB,S_W,localsize,NR_STACK_POINTER_REG));
|
||||
end;
|
||||
|
@ -1317,7 +1317,8 @@ implementation
|
||||
);
|
||||
tcb.free;
|
||||
|
||||
if not(tf_no_generic_stackcheck in target_info.flags) then
|
||||
if (tf_emit_stklen in target_info.flags) or
|
||||
not(tf_no_generic_stackcheck in target_info.flags) then
|
||||
begin
|
||||
{ stacksize can be specified and is now simulated }
|
||||
tcb:=ctai_typedconstbuilder.create([tcalo_new_section,tcalo_make_dead_strippable]);
|
||||
|
@ -137,6 +137,7 @@ interface
|
||||
tf_pic_default,
|
||||
{ the os does some kind of stack checking and it can be converted into a rte 202 }
|
||||
tf_no_generic_stackcheck,
|
||||
tf_emit_stklen, // Means that the compiler should emit a _stklen variable with the stack size, even if tf_no_generic_stackcheck is specified
|
||||
tf_has_winlike_resources,
|
||||
tf_safecall_clearstack, // With this flag set, after safecall calls the caller cleans up the stack
|
||||
tf_safecall_exceptions, // Exceptions in safecall calls are not raised, but passed to the caller as an ordinal (hresult) in the function result.
|
||||
|
@ -42,7 +42,8 @@ unit i_msdos;
|
||||
name : 'MS-DOS 16-bit real mode';
|
||||
shortname : 'MSDOS';
|
||||
flags : [tf_use_8_3,tf_smartlink_library,
|
||||
tf_no_objectfiles_when_smartlinking,tf_cld];
|
||||
tf_no_objectfiles_when_smartlinking,tf_cld,
|
||||
tf_no_generic_stackcheck,tf_emit_stklen];
|
||||
cpu : cpu_i8086;
|
||||
unit_env : 'MSDOSUNITS';
|
||||
extradefines : '';
|
||||
|
@ -43,6 +43,7 @@ unit i_win16;
|
||||
shortname : 'Win16';
|
||||
flags : [tf_use_8_3,tf_smartlink_library,
|
||||
tf_no_objectfiles_when_smartlinking,tf_cld,
|
||||
tf_no_generic_stackcheck,tf_emit_stklen,
|
||||
tf_x86_far_procs_push_odd_bp];
|
||||
cpu : cpu_i8086;
|
||||
unit_env : 'WIN16UNITS';
|
||||
|
@ -3067,7 +3067,14 @@ unit cgx86;
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
|
||||
current_procinfo.final_localsize:=localsize;
|
||||
end;
|
||||
end
|
||||
{$ifdef i8086}
|
||||
else
|
||||
{ on i8086 we always call g_stackpointer_alloc, even with a zero size,
|
||||
because it will generate code for stack checking, if stack checking is on }
|
||||
g_stackpointer_alloc(list,0)
|
||||
{$endif i8086}
|
||||
;
|
||||
|
||||
{$ifdef i8086}
|
||||
{ win16 exported proc prologue follow-up (see the huge comment above for details) }
|
||||
|
@ -727,6 +727,64 @@ asm
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Stack checking
|
||||
****************************************************************************}
|
||||
|
||||
|
||||
procedure fpc_stackcheck_i8086;[public,alias:'FPC_STACKCHECK_I8086'];compilerproc;assembler;nostackframe;
|
||||
const
|
||||
STACK_MARGIN=512;
|
||||
asm
|
||||
{ on entry: AX = required stack size to check if available
|
||||
(function is called before stack allocation) }
|
||||
{$ifdef FPC_MM_HUGE}
|
||||
push ds
|
||||
push ax
|
||||
mov ax, SEG @DATA
|
||||
mov ds, ax
|
||||
pop ax
|
||||
{$endif FPC_MM_HUGE}
|
||||
add ax, STACK_MARGIN
|
||||
jc @@stack_overflow
|
||||
add ax, word ptr [__stkbottom]
|
||||
jc @@stack_overflow
|
||||
cmp ax, sp
|
||||
ja @@stack_overflow
|
||||
@@no_overflow:
|
||||
{$ifdef FPC_MM_HUGE}
|
||||
pop ds
|
||||
{$endif FPC_MM_HUGE}
|
||||
ret
|
||||
|
||||
@@stack_overflow:
|
||||
{ check StackError flag, to avoid recursive calls from the exit routines }
|
||||
cmp byte ptr [StackError], 1
|
||||
je @@no_overflow
|
||||
mov byte ptr [StackError], 1
|
||||
{ cleanup return address (and maybe saved ds) from call to this function }
|
||||
{$if defined(FPC_MM_HUGE)}
|
||||
add sp, 6
|
||||
{$elseif defined(FPC_X86_CODE_FAR)}
|
||||
pop ax
|
||||
pop ax
|
||||
{$else}
|
||||
pop ax
|
||||
{$endif}
|
||||
{ call HandleError(202) }
|
||||
{$ifdef CPU8086}
|
||||
xor ax, ax
|
||||
push ax
|
||||
mov al, 202
|
||||
push ax
|
||||
{$else}
|
||||
push 0
|
||||
push 202
|
||||
{$endif}
|
||||
call HandleError
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
BSR/BSF
|
||||
****************************************************************************}
|
||||
|
@ -756,6 +756,9 @@ function fpc_setjmp(var s : jmp_buf) : {$ifdef CPU16}smallint{$else}longint{$end
|
||||
procedure fpc_longjmp(var s : jmp_buf; value : {$ifdef CPU16}smallint{$else}longint{$endif}); compilerproc;
|
||||
|
||||
{$ifdef cpui8086}
|
||||
{ i8086 stack checking }
|
||||
procedure fpc_stackcheck_i8086; compilerproc;
|
||||
|
||||
{ i8086 huge pointer helpers }
|
||||
function fpc_hugeptr_add_longint(p: HugePointer; n: LongInt): HugePointer; compilerproc;
|
||||
function fpc_hugeptr_add_longint_normalized(p: HugePointer; n: LongInt): HugePointer; compilerproc;
|
||||
|
Loading…
Reference in New Issue
Block a user