+ implemented proper stack checking for the i8086

git-svn-id: trunk@33787 -
This commit is contained in:
nickysn 2016-05-24 23:57:47 +00:00
parent 9daa4bd48d
commit c78f406d99
8 changed files with 82 additions and 3 deletions

View File

@ -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;

View File

@ -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]);

View File

@ -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.

View File

@ -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 : '';

View File

@ -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';

View File

@ -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) }

View File

@ -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
****************************************************************************}

View File

@ -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;