paxCompiler/Sources/PAXCOMP_PAUSE.pas
Dalibor Marković 9d0de424e8
Init
Signed-off-by: Dalibor Marković <dalibor31@gmail.com>
2024-07-06 22:28:12 +02:00

170 lines
3.0 KiB
ObjectPascal

////////////////////////////////////////////////////////////////////////////
// PaxCompiler
// Site: http://www.paxcompiler.com
// Author: Alexander Baranovsky (paxscript@gmail.com)
// ========================================================================
// Copyright (c) Alexander Baranovsky, 2006-2014. All rights reserved.
// Code Version: 4.2
// ========================================================================
// Unit: PAXCOMP_PAUSE.pas
// ========================================================================
////////////////////////////////////////////////////////////////////////////
{$I PaxCompiler.def}
unit PAXCOMP_PAUSE;
interface
uses {$I uses.def}
SysUtils,
PAXCOMP_CONSTANTS,
PAXCOMP_SYS;
type
TPauseRec = class
public
_EBP: IntPax;
_ESP: IntPax;
ESP0: IntPax;
ProgOffset: Integer;
StackFrame: Pointer;
StackFrameSize: Integer;
PaxExcFrame1: PPaxExcFrame;
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure SaveStackFrame;
function GetPtr(EBP_Value, Shift: Integer): Pointer;
end;
implementation
//-- TPauseRec -----------------------------------------------------------------
constructor TPauseRec.Create;
begin
inherited;
StackFrame := nil;
Clear;
end;
destructor TPauseRec.Destroy;
begin
Clear;
inherited;
end;
procedure TPauseRec.Clear;
begin
if StackFrame <> nil then
FreeMem(StackFrame, StackFrameSize);
_ESP := 0;
ESP0 := 0;
ProgOffset := 0;
StackFrame := nil;
StackFrameSize := 0;
PaxExcFrame1 := nil;
end;
{$IFDEF PAX64}
procedure _Save(I: Int64; P: Pointer; K: Int64); assembler;
asm
mov rax, I
mov rbx, P
mov rcx, K
@@loop:
mov rdx, [rax]
mov [rbx], rdx
sub rax, 8
sub rbx, 8
sub rcx, 1
cmp rcx, 0
jnz @@loop
end;
procedure TPauseRec.SaveStackFrame;
var
P: Pointer;
I, K: Integer;
begin
if ESP0 = _ESP then
Exit;
if StackFrame <> nil then
FreeMem(StackFrame, StackFrameSize);
StackFrameSize := ESP0 - _ESP;
if StackFrameSize < 0 then
Exit;
StackFrame := AllocMem(StackFrameSize);
I := ESP0 - SizeOf(Pointer);
P := ShiftPointer(StackFrame, StackFrameSize - SizeOf(Pointer));
K := StackFrameSize div SizeOf(Pointer);
_Save(I, P, K);
end;
{$ELSE}
procedure TPauseRec.SaveStackFrame;
var
P: Pointer;
I, K: Integer;
begin
if ESP0 = _ESP then
Exit;
if StackFrame <> nil then
FreeMem(StackFrame, StackFrameSize);
StackFrameSize := ESP0 - _ESP;
if StackFrameSize < 0 then
Exit;
StackFrame := AllocMem(StackFrameSize);
I := ESP0 - 4;
P := ShiftPointer(StackFrame, StackFrameSize - 4);
K := StackFrameSize div 4;
asm
mov eax, I
mov ebx, P
mov ecx, K
@@loop:
mov edx, [eax]
mov [ebx], edx
sub eax, 4
sub ebx, 4
sub ecx, 1
cmp ecx, 0
jnz @@loop
end;
end;
{$ENDIF}
function TPauseRec.GetPtr(EBP_Value, Shift: Integer): Pointer;
var
K: Integer;
begin
K := EBP_Value + Shift - _ESP;
result := ShiftPointer(StackFrame, K);
end;
end.