mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 15:29:25 +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);
|
procedure tcg8086.g_stackpointer_alloc(list : TAsmList;localsize: longint);
|
||||||
begin
|
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
|
if localsize>0 then
|
||||||
list.concat(Taicpu.Op_const_reg(A_SUB,S_W,localsize,NR_STACK_POINTER_REG));
|
list.concat(Taicpu.Op_const_reg(A_SUB,S_W,localsize,NR_STACK_POINTER_REG));
|
||||||
end;
|
end;
|
||||||
|
@ -1317,7 +1317,8 @@ implementation
|
|||||||
);
|
);
|
||||||
tcb.free;
|
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
|
begin
|
||||||
{ stacksize can be specified and is now simulated }
|
{ stacksize can be specified and is now simulated }
|
||||||
tcb:=ctai_typedconstbuilder.create([tcalo_new_section,tcalo_make_dead_strippable]);
|
tcb:=ctai_typedconstbuilder.create([tcalo_new_section,tcalo_make_dead_strippable]);
|
||||||
|
@ -137,6 +137,7 @@ interface
|
|||||||
tf_pic_default,
|
tf_pic_default,
|
||||||
{ the os does some kind of stack checking and it can be converted into a rte 202 }
|
{ the os does some kind of stack checking and it can be converted into a rte 202 }
|
||||||
tf_no_generic_stackcheck,
|
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_has_winlike_resources,
|
||||||
tf_safecall_clearstack, // With this flag set, after safecall calls the caller cleans up the stack
|
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.
|
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';
|
name : 'MS-DOS 16-bit real mode';
|
||||||
shortname : 'MSDOS';
|
shortname : 'MSDOS';
|
||||||
flags : [tf_use_8_3,tf_smartlink_library,
|
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;
|
cpu : cpu_i8086;
|
||||||
unit_env : 'MSDOSUNITS';
|
unit_env : 'MSDOSUNITS';
|
||||||
extradefines : '';
|
extradefines : '';
|
||||||
|
@ -43,6 +43,7 @@ unit i_win16;
|
|||||||
shortname : 'Win16';
|
shortname : 'Win16';
|
||||||
flags : [tf_use_8_3,tf_smartlink_library,
|
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,
|
||||||
tf_x86_far_procs_push_odd_bp];
|
tf_x86_far_procs_push_odd_bp];
|
||||||
cpu : cpu_i8086;
|
cpu : cpu_i8086;
|
||||||
unit_env : 'WIN16UNITS';
|
unit_env : 'WIN16UNITS';
|
||||||
|
@ -3067,7 +3067,14 @@ unit cgx86;
|
|||||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
|
current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
|
||||||
current_procinfo.final_localsize:=localsize;
|
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}
|
{$ifdef i8086}
|
||||||
{ win16 exported proc prologue follow-up (see the huge comment above for details) }
|
{ win16 exported proc prologue follow-up (see the huge comment above for details) }
|
||||||
|
@ -727,6 +727,64 @@ asm
|
|||||||
end;
|
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
|
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;
|
procedure fpc_longjmp(var s : jmp_buf; value : {$ifdef CPU16}smallint{$else}longint{$endif}); compilerproc;
|
||||||
|
|
||||||
{$ifdef cpui8086}
|
{$ifdef cpui8086}
|
||||||
|
{ i8086 stack checking }
|
||||||
|
procedure fpc_stackcheck_i8086; compilerproc;
|
||||||
|
|
||||||
{ i8086 huge pointer helpers }
|
{ i8086 huge pointer helpers }
|
||||||
function fpc_hugeptr_add_longint(p: HugePointer; n: LongInt): HugePointer; compilerproc;
|
function fpc_hugeptr_add_longint(p: HugePointer; n: LongInt): HugePointer; compilerproc;
|
||||||
function fpc_hugeptr_add_longint_normalized(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