mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
b6dd272289
commit
848dd4a128
|
@ -13,12 +13,56 @@ uses
|
|||
var
|
||||
g_errno:Integer=0;
|
||||
|
||||
function px2sce(e:Integer):Integer;
|
||||
function sce2px(e:Integer):Integer;
|
||||
|
||||
function _get_errno:Integer;
|
||||
function _set_errno(r:Integer):Integer;
|
||||
function _set_sce_errno(r:Integer):Integer;
|
||||
|
||||
procedure hmqw8GlN_tI(base:Pointer;size:QWORD); //hmqw8GlN+tI
|
||||
function __error:PInteger;
|
||||
procedure cerror;
|
||||
|
||||
implementation
|
||||
|
||||
function px2sce(e:Integer):Integer;
|
||||
begin
|
||||
if (e=0) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=e-$7ffe0000;
|
||||
end;
|
||||
|
||||
function sce2px(e:Integer):Integer;
|
||||
begin
|
||||
if (e=0) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=e+$7ffe0000;
|
||||
end;
|
||||
|
||||
function _get_errno:Integer;
|
||||
begin
|
||||
Result:=__error^;
|
||||
end;
|
||||
|
||||
function _set_errno(r:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
__error^:=r;
|
||||
if (r<>0) then
|
||||
begin
|
||||
Result:=-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _set_sce_errno(r:Integer):Integer;
|
||||
begin
|
||||
__error^:=sce2px(r);
|
||||
Result:=r;
|
||||
end;
|
||||
|
||||
var
|
||||
g_exclude_stack_base:Pointer=nil;
|
||||
g_exclude_stack_size:QWORD =0;
|
||||
|
|
|
@ -487,7 +487,7 @@ function NtClose(Handle:THandle):DWORD; stdcall; external 'ntdll';
|
|||
function NtCreateThread(
|
||||
hThread :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes :Pointer;
|
||||
ObjectAttributes :POBJECT_ATTRIBUTES;
|
||||
ProcessHandle :THandle;
|
||||
ClientId :PCLIENT_ID;
|
||||
ThreadContext :PCONTEXT;
|
||||
|
@ -495,6 +495,13 @@ function NtCreateThread(
|
|||
CreateSuspended :Boolean
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtOpenThread(
|
||||
ThreadHandle :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes:POBJECT_ATTRIBUTES;
|
||||
ClientId :PCLIENT_ID
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtTerminateThread(
|
||||
ThreadHandle:THandle;
|
||||
ExitStatus :DWORD
|
||||
|
@ -618,7 +625,7 @@ function NtQueryPerformanceCounter(
|
|||
function NtCreateTimer(
|
||||
TimerHandle :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes:Pointer;
|
||||
ObjectAttributes:POBJECT_ATTRIBUTES;
|
||||
TimerType :DWORD
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
|
@ -815,7 +822,7 @@ function NtQueryVolumeInformationFile(
|
|||
function NtCreateEvent(
|
||||
EventHandle :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes:Pointer;
|
||||
ObjectAttributes:POBJECT_ATTRIBUTES;
|
||||
EventType :DWORD;
|
||||
InitialState :Boolean
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
@ -835,7 +842,7 @@ function NtClearEvent(EventHandle:THandle):DWORD; stdcall; external 'ntdll';
|
|||
function NtCreateMutant(
|
||||
MutantHandle :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes:Pointer;
|
||||
ObjectAttributes:POBJECT_ATTRIBUTES;
|
||||
InitialOwner :Boolean
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
|
@ -856,7 +863,7 @@ function NtQueryMutant(
|
|||
function NtCreateSection(
|
||||
SectionHandle :PHandle;
|
||||
DesiredAccess :ACCESS_MASK;
|
||||
ObjectAttributes :Pointer;
|
||||
ObjectAttributes :POBJECT_ATTRIBUTES;
|
||||
MaximumSize :PLARGE_INTEGER;
|
||||
SectionPageProtection:ULONG;
|
||||
AllocationAttributes :ULONG;
|
||||
|
|
|
@ -222,6 +222,7 @@ type
|
|||
procedure _push (op:Byte;reg:t_jit_reg);
|
||||
procedure _pushi (size:TOperandSize;imm:Integer);
|
||||
procedure movq (reg0:t_jit_reg ;reg1:t_jit_reg);
|
||||
procedure movi (size:TOperandSize;mem:t_jit_regs;imm:Int64);
|
||||
procedure movi (reg:t_jit_reg ;imm:Int64);
|
||||
procedure movq (reg:t_jit_reg ;mem:t_jit_regs);
|
||||
procedure movq (mem:t_jit_regs ;reg:t_jit_reg);
|
||||
|
@ -832,7 +833,6 @@ type
|
|||
procedure build(Index:Byte;mreg:t_jit_reg);
|
||||
procedure build(reg,mreg:t_jit_reg);
|
||||
procedure emit(var ji:t_jit_instruction);
|
||||
procedure emit8(var ji:t_jit_instruction);
|
||||
end;
|
||||
|
||||
procedure t_modrm_info.build(Index:Byte;mreg:t_jit_reg);
|
||||
|
@ -1026,18 +1026,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure t_modrm_info.emit8(var ji:t_jit_instruction);
|
||||
begin
|
||||
ji.EmitModRM(ModRM.Mode,ModRM.Index,ModRM.RM);
|
||||
|
||||
if (ModRM.RM=4) then
|
||||
begin
|
||||
ji.EmitSIB(SIB.Scale,SIB.Index,SIB.Base);
|
||||
end;
|
||||
|
||||
ji.EmitByte(AOffset); //1
|
||||
end;
|
||||
|
||||
procedure t_jit_builder._mov(op,op8:Byte;reg:t_jit_reg;mem:t_jit_regs);
|
||||
var
|
||||
mreg:t_jit_reg;
|
||||
|
@ -1339,6 +1327,14 @@ begin
|
|||
|
||||
modrm_info.emit(ji);
|
||||
|
||||
case Size of
|
||||
os8:ji.EmitByte (imm);
|
||||
os16:ji.EmitWord (imm);
|
||||
os32:ji.EmitInt32(imm);
|
||||
os64:ji.EmitInt64(imm);
|
||||
else;
|
||||
end;
|
||||
|
||||
_add(ji);
|
||||
end;
|
||||
|
||||
|
@ -1465,7 +1461,9 @@ begin
|
|||
|
||||
ji.EmitByte(op);
|
||||
|
||||
modrm_info.emit8(ji);
|
||||
modrm_info.emit(ji);
|
||||
|
||||
ji.EmitByte(imm); //1
|
||||
|
||||
_add(ji);
|
||||
end;
|
||||
|
@ -1620,6 +1618,11 @@ begin
|
|||
_mov($89,$88,reg0,reg1);
|
||||
end;
|
||||
|
||||
procedure t_jit_builder.movi(size:TOperandSize;mem:t_jit_regs;imm:Int64);
|
||||
begin
|
||||
_movi($C7,$C6,0,size,mem,imm);
|
||||
end;
|
||||
|
||||
procedure t_jit_builder.movi(reg:t_jit_reg;imm:Int64);
|
||||
var
|
||||
rexF,rexB,rexW:Boolean;
|
||||
|
@ -1689,7 +1692,7 @@ begin
|
|||
os8:ji.EmitByte (imm);
|
||||
os16:ji.EmitWord (imm);
|
||||
os32:ji.EmitInt32(imm);
|
||||
os64:ji.EmitInt64(imm);
|
||||
os64:ji.EmitInt32(imm);
|
||||
else;
|
||||
end;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ implementation
|
|||
uses
|
||||
errno,
|
||||
systm,
|
||||
kern_thr,
|
||||
trap,
|
||||
vm,
|
||||
vm_object,
|
||||
|
@ -203,7 +202,14 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
1:; //SetImageAddress
|
||||
1: //SetImageAddress
|
||||
begin
|
||||
addr:=p_cursor_img_addr(@info)^.addr_lo or (QWORD(p_cursor_img_addr(@info)^.addr_hi) shl 32);
|
||||
|
||||
Writeln('dce_set_image_addr:',canary,' ',
|
||||
p_cursor_img_addr(@info)^.index,' ',
|
||||
HexStr(addr,16));
|
||||
end;
|
||||
|
||||
2: //SetPosition
|
||||
begin
|
||||
|
@ -223,9 +229,9 @@ begin
|
|||
p_cursor_update_pending(@info)^.index,' ',
|
||||
p_cursor_update_pending(@info)^.ptype);
|
||||
|
||||
p_cursor_update_pending(@info)^.result:=0;
|
||||
addr:=1;
|
||||
|
||||
Result:=copyout(@p_cursor_update_pending(@info)^.result,@p_cursor_update_pending(data)^.result,8);
|
||||
Result:=copyout(@addr,@p_cursor_update_pending(data)^.result,8);
|
||||
end;
|
||||
|
||||
else
|
||||
|
@ -678,8 +684,8 @@ begin
|
|||
begin
|
||||
knlist_add(@g_video_out_event_flip,kn,0)
|
||||
end;
|
||||
//$0051:Result:=8;
|
||||
//$0058:Result:=12;
|
||||
// $0051:Result:=8;
|
||||
// $0058:Result:=12;
|
||||
else
|
||||
begin
|
||||
Writeln(stderr,'filt_display_attach:',event_id);
|
||||
|
|
|
@ -22,8 +22,7 @@ uses
|
|||
subr_uio,
|
||||
vpoll,
|
||||
vm,
|
||||
sys_event,
|
||||
kern_event;
|
||||
sys_event;
|
||||
|
||||
var
|
||||
dev_console:p_cdev;
|
||||
|
|
|
@ -8,54 +8,7 @@ interface
|
|||
{$I sce_errno.inc}
|
||||
{$I errno.inc}
|
||||
|
||||
function px2sce(e:Integer):Integer;
|
||||
function sce2px(e:Integer):Integer;
|
||||
|
||||
function _get_errno:Integer;
|
||||
function _set_errno(r:Integer):Integer;
|
||||
function _set_sce_errno(r:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
thr_error;
|
||||
|
||||
function px2sce(e:Integer):Integer;
|
||||
begin
|
||||
if (e=0) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=e-$7ffe0000;
|
||||
end;
|
||||
|
||||
function sce2px(e:Integer):Integer;
|
||||
begin
|
||||
if (e=0) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=e+$7ffe0000;
|
||||
end;
|
||||
|
||||
function _get_errno:Integer;
|
||||
begin
|
||||
Result:=__error^;
|
||||
end;
|
||||
|
||||
function _set_errno(r:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
__error^:=r;
|
||||
if (r<>0) then
|
||||
begin
|
||||
Result:=-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _set_sce_errno(r:Integer):Integer;
|
||||
begin
|
||||
__error^:=sce2px(r);
|
||||
Result:=r;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -235,7 +235,6 @@ procedure devfs_mtx_init;
|
|||
implementation
|
||||
|
||||
uses
|
||||
devfs_devs,
|
||||
devfs_vnops;
|
||||
|
||||
{
|
||||
|
|
|
@ -207,6 +207,7 @@ uses
|
|||
devfs_devs,
|
||||
devfs_rule,
|
||||
devfs_vfsops,
|
||||
kern_proc,
|
||||
kern_descrip,
|
||||
kern_mtxpool,
|
||||
subr_uio;
|
||||
|
|
|
@ -98,6 +98,7 @@ uses
|
|||
sysutils,
|
||||
errno,
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
vfs_subr,
|
||||
subr_uio;
|
||||
|
||||
|
@ -549,14 +550,19 @@ begin
|
|||
de:=vp^.v_data;
|
||||
|
||||
error:=vaccess(vp^.v_type, de^.ufs_mode, de^.ufs_uid, de^.ufs_gid, ap^.a_accmode, nil);
|
||||
|
||||
if (error=0) then
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
if (error<>EACCES) then
|
||||
Exit(error);
|
||||
|
||||
if ((p_proc.p_flag and P_CONTROLT)=0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
|
|
@ -23,6 +23,7 @@ uses
|
|||
systm,
|
||||
kern_thr,
|
||||
kern_thread,
|
||||
kern_proc,
|
||||
signal,
|
||||
kern_sig,
|
||||
kern_synch,
|
||||
|
|
|
@ -95,7 +95,7 @@ uses
|
|||
vm_map,
|
||||
kern_authinfo,
|
||||
kern_thr,
|
||||
trap;
|
||||
kern_proc;
|
||||
|
||||
//////////
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ uses
|
|||
vfs_subr,
|
||||
subr_hash,
|
||||
vsys_generic,
|
||||
kern_proc,
|
||||
kern_callout,
|
||||
kern_timeout;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ implementation
|
|||
uses
|
||||
systm,
|
||||
errno,
|
||||
kern_proc,
|
||||
kern_mtx,
|
||||
vm,
|
||||
vmparam,
|
||||
|
|
|
@ -13,7 +13,6 @@ uses
|
|||
errno,
|
||||
systm,
|
||||
trap,
|
||||
kern_thr,
|
||||
kern_named_id;
|
||||
|
||||
type
|
||||
|
|
|
@ -50,6 +50,7 @@ type
|
|||
|
||||
function GetFrameOffsetInt(RegValue:TRegValue):Integer;
|
||||
procedure print_disassemble(addr:Pointer;vsize:Integer);
|
||||
procedure print_frame(td:p_kthread);
|
||||
function classif_memop(var din:TInstruction):t_memop_type;
|
||||
function get_lea_id(memop:t_memop_type):Byte;
|
||||
function get_reg_id(memop:t_memop_type):Byte;
|
||||
|
@ -191,12 +192,33 @@ begin
|
|||
proc.Free;
|
||||
end;
|
||||
|
||||
procedure print_frame(td:p_kthread);
|
||||
begin
|
||||
Writeln('tf_adr:',HexStr(td^.td_frame.tf_addr,16));
|
||||
Writeln('tf_rip:',HexStr(td^.td_frame.tf_rip,16));
|
||||
Writeln('tf_rax:',HexStr(td^.td_frame.tf_rax,16));
|
||||
Writeln('tf_rcx:',HexStr(td^.td_frame.tf_rcx,16));
|
||||
Writeln('tf_rdx:',HexStr(td^.td_frame.tf_rdx,16));
|
||||
Writeln('tf_rbx:',HexStr(td^.td_frame.tf_rbx,16));
|
||||
Writeln('tf_rsp:',HexStr(td^.td_frame.tf_rsp,16));
|
||||
Writeln('tf_rbp:',HexStr(td^.td_frame.tf_rbp,16));
|
||||
Writeln('tf_rsi:',HexStr(td^.td_frame.tf_rsi,16));
|
||||
Writeln('tf_rdi:',HexStr(td^.td_frame.tf_rdi,16));
|
||||
Writeln('tf_r8 :',HexStr(td^.td_frame.tf_r8 ,16));
|
||||
Writeln('tf_r9 :',HexStr(td^.td_frame.tf_r9 ,16));
|
||||
Writeln('tf_r10:',HexStr(td^.td_frame.tf_r10,16));
|
||||
Writeln('tf_r11:',HexStr(td^.td_frame.tf_r11,16));
|
||||
Writeln('tf_r12:',HexStr(td^.td_frame.tf_r12,16));
|
||||
Writeln('tf_r13:',HexStr(td^.td_frame.tf_r13,16));
|
||||
Writeln('tf_r14:',HexStr(td^.td_frame.tf_r14,16));
|
||||
Writeln('tf_r15:',HexStr(td^.td_frame.tf_r15,16));
|
||||
end;
|
||||
|
||||
procedure test_jit;
|
||||
begin
|
||||
writeln('test_jit');
|
||||
end;
|
||||
|
||||
|
||||
//rdi,rsi,edx
|
||||
procedure copyout_mov(vaddr:Pointer;cb:tcopy_cb;size:Integer);
|
||||
var
|
||||
|
@ -306,7 +328,21 @@ begin
|
|||
|
||||
if (RegValue[0].AScale>1) then
|
||||
begin
|
||||
leaq(adr,[adr*RegValue[0].AScale])
|
||||
ofs:=0;
|
||||
if GetTargetOfs(ctx,id,ofs) then
|
||||
begin
|
||||
leaq(adr,[adr*RegValue[0].AScale+ofs]);
|
||||
end else
|
||||
begin
|
||||
leaq(adr,[adr*RegValue[0].AScale]);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
ofs:=0;
|
||||
if GetTargetOfs(ctx,id,ofs) then
|
||||
begin
|
||||
leaq(adr,[adr+ofs]);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (RegValue[1].AType<>regNone) then
|
||||
|
@ -316,16 +352,9 @@ begin
|
|||
|
||||
addq(adr,[tdr+i]);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
ofs:=0;
|
||||
if GetTargetOfs(ctx,id,ofs) then
|
||||
begin
|
||||
with ctx.builder do
|
||||
begin
|
||||
leaq(adr,[adr+ofs]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
@ -403,17 +432,8 @@ begin
|
|||
begin
|
||||
//imm const
|
||||
|
||||
if (copy_size>reg_size) or (imm=0) then
|
||||
begin
|
||||
xorq(rsi,rsi);
|
||||
end;
|
||||
movi(mem.ARegValue[0].ASize,[rdi],imm);
|
||||
|
||||
if (imm<>0) then
|
||||
begin
|
||||
movi(reg,imm);
|
||||
end;
|
||||
|
||||
movq([rdi],mem); //TODO movi([rdi],imm);
|
||||
end else
|
||||
begin
|
||||
movq(rcx,[GS+Integer(teb_thread)]);
|
||||
|
|
|
@ -41,6 +41,7 @@ uses
|
|||
systm,
|
||||
kern_thr,
|
||||
kern_rtprio,
|
||||
kern_proc,
|
||||
md_proc;
|
||||
|
||||
const
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
unit kern_proc;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
kern_mtx,
|
||||
sys_event;
|
||||
|
||||
type
|
||||
{
|
||||
* pargs, used to hold a copy of the command line, if it had a sane length.
|
||||
}
|
||||
p_pargs=^t_pargs;
|
||||
t_pargs=packed record
|
||||
ar_ref :Integer; // Reference count.
|
||||
ar_length:Integer; // Length.
|
||||
ar_args :AnsiChar; // Arguments.
|
||||
end;
|
||||
|
||||
const
|
||||
MAXCOMLEN=19;
|
||||
|
||||
var
|
||||
p_proc:record
|
||||
p_mtx:mtx;
|
||||
|
||||
p_flag :Integer;
|
||||
p_osrel:Integer;
|
||||
|
||||
p_sdk_version:Integer;
|
||||
p_sce_replay_exec:Integer;
|
||||
|
||||
libkernel_start_addr:Pointer;
|
||||
libkernel___end_addr:Pointer;
|
||||
|
||||
p_ptc:Int64;
|
||||
|
||||
p_nsignals:Int64;
|
||||
p_nvcsw :Int64;
|
||||
p_nivcsw :Int64;
|
||||
|
||||
p_comm :array[0..MAXCOMLEN] of AnsiChar;
|
||||
prog_name :array[0..1023] of AnsiChar;
|
||||
p_randomized_path:array[0..7] of AnsiChar;
|
||||
|
||||
p_klist:t_knlist;
|
||||
|
||||
p_args:p_pargs;
|
||||
|
||||
p_dmem_aliasing:Integer;
|
||||
end;
|
||||
|
||||
function pargs_alloc(len:Integer):p_pargs;
|
||||
procedure pargs_free(pa:p_pargs);
|
||||
procedure pargs_hold(pa:p_pargs);
|
||||
procedure pargs_drop(pa:p_pargs);
|
||||
|
||||
procedure PROC_LOCK;
|
||||
procedure PROC_UNLOCK;
|
||||
|
||||
procedure PROC_INIT; //SYSINIT
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kern_event,
|
||||
md_time;
|
||||
|
||||
//
|
||||
|
||||
function pargs_alloc(len:Integer):p_pargs;
|
||||
begin
|
||||
Result:=AllocMem(sizeof(t_pargs) + len);
|
||||
Result^.ar_ref :=1;
|
||||
Result^.ar_length:=len;
|
||||
end;
|
||||
|
||||
procedure pargs_free(pa:p_pargs);
|
||||
begin
|
||||
FreeMem(pa);
|
||||
end;
|
||||
|
||||
procedure pargs_hold(pa:p_pargs);
|
||||
begin
|
||||
if (pa=nil) then Exit;
|
||||
System.InterlockedIncrement(pa^.ar_ref);
|
||||
end;
|
||||
|
||||
procedure pargs_drop(pa:p_pargs);
|
||||
begin
|
||||
if (pa=nil) then Exit;
|
||||
if (System.InterlockedDecrement(pa^.ar_ref)=0) then
|
||||
begin
|
||||
pargs_free(pa);
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure PROC_LOCK;
|
||||
begin
|
||||
mtx_lock(p_proc.p_mtx);
|
||||
end;
|
||||
|
||||
procedure PROC_UNLOCK;
|
||||
begin
|
||||
mtx_unlock(p_proc.p_mtx);
|
||||
end;
|
||||
|
||||
procedure PROC_INIT;
|
||||
const
|
||||
osreldate=$000DBBA0;
|
||||
begin
|
||||
FillChar(p_proc,SizeOf(p_proc),0);
|
||||
mtx_init(p_proc.p_mtx,'process lock');
|
||||
|
||||
knlist_init_mtx(@p_proc.p_klist,@p_proc.p_mtx);
|
||||
|
||||
p_proc.p_osrel:=osreldate;
|
||||
|
||||
p_proc.p_randomized_path:='system';
|
||||
|
||||
p_proc.p_ptc:=rdtsc;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -28,6 +28,7 @@ uses
|
|||
errno,
|
||||
systm,
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
md_proc,
|
||||
md_resource;
|
||||
|
||||
|
|
|
@ -214,6 +214,7 @@ uses
|
|||
vm_map,
|
||||
vm_mmap,
|
||||
vm_pmap,
|
||||
kern_proc,
|
||||
kern_patcher;
|
||||
|
||||
function maxInt64(a,b:Int64):Int64; inline;
|
||||
|
|
|
@ -20,6 +20,7 @@ implementation
|
|||
uses
|
||||
systm,
|
||||
errno,
|
||||
kern_proc,
|
||||
kern_thread,
|
||||
sched_ule,
|
||||
md_proc;
|
||||
|
|
|
@ -11,7 +11,8 @@ uses
|
|||
time,
|
||||
signal,
|
||||
signalvar,
|
||||
kern_thr;
|
||||
kern_thr,
|
||||
kern_proc;
|
||||
|
||||
const
|
||||
SA_KILL =$01; // terminates process by default
|
||||
|
|
|
@ -39,7 +39,7 @@ function msleep(ident :Pointer;
|
|||
function tsleep(ident :Pointer;
|
||||
priority:Integer;
|
||||
wmesg :PChar;
|
||||
timo :Int64):Integer; inline;
|
||||
timo :Int64):Integer;
|
||||
|
||||
function pause(wmesg:PChar;timo:Int64):Integer;
|
||||
|
||||
|
@ -56,6 +56,7 @@ function sys_cpumode_yield():Integer;
|
|||
implementation
|
||||
|
||||
uses
|
||||
kern_proc,
|
||||
kern_thread,
|
||||
sched_ule,
|
||||
md_sleep,
|
||||
|
@ -145,7 +146,7 @@ end;
|
|||
function tsleep(ident :Pointer;
|
||||
priority:Integer;
|
||||
wmesg :PChar;
|
||||
timo :Int64):Integer; inline;
|
||||
timo :Int64):Integer;
|
||||
begin
|
||||
Result:=msleep(ident,nil,priority,wmesg,timo);
|
||||
end;
|
||||
|
|
|
@ -59,7 +59,7 @@ const
|
|||
|
||||
|
||||
//CTL_KERN identifiers
|
||||
KERN_PROC =14;
|
||||
KERN_PROC_ =14;
|
||||
KERN_USRSTACK =33;
|
||||
KERN_ARND =37;
|
||||
KERN_SDKVERSION=38; //SDK version
|
||||
|
@ -163,6 +163,7 @@ uses
|
|||
time,
|
||||
kern_authinfo,
|
||||
md_arc4random,
|
||||
kern_proc,
|
||||
md_proc;
|
||||
|
||||
var
|
||||
|
@ -449,7 +450,7 @@ begin
|
|||
'kern.proc.ptc':
|
||||
begin
|
||||
oid[0]:=CTL_KERN;
|
||||
oid[1]:=KERN_PROC;
|
||||
oid[1]:=KERN_PROC_;
|
||||
oid[2]:=KERN_PROC_PTC;
|
||||
len^ :=3;
|
||||
end;
|
||||
|
@ -574,7 +575,7 @@ begin
|
|||
Result:=ENOENT;
|
||||
|
||||
case name[0] of
|
||||
KERN_PROC :Result:=sysctl_kern_proc(name+1,namelen-1,noid,req);
|
||||
KERN_PROC_ :Result:=sysctl_kern_proc(name+1,namelen-1,noid,req);
|
||||
|
||||
KERN_USRSTACK :Result:=SYSCTL_HANDLE(noid,name,$80008008,@sysctl_kern_usrstack);
|
||||
KERN_ARND :Result:=SYSCTL_HANDLE(noid,name,$80048005,@sysctl_kern_arandom);
|
||||
|
|
|
@ -9,9 +9,7 @@ uses
|
|||
mqueue,
|
||||
ucontext,
|
||||
signal,
|
||||
signalvar,
|
||||
sys_event,
|
||||
kern_mtx;
|
||||
signalvar;
|
||||
|
||||
const
|
||||
TDS_INACTIVE =0;
|
||||
|
@ -163,6 +161,11 @@ const
|
|||
type
|
||||
t_td_name=array[0..31] of AnsiChar;
|
||||
|
||||
t_td_stack=packed record
|
||||
stack:Pointer;
|
||||
sttop:Pointer;
|
||||
end;
|
||||
|
||||
pp_kthread=^p_kthread;
|
||||
p_kthread=^kthread;
|
||||
kthread=record
|
||||
|
@ -196,14 +199,8 @@ type
|
|||
pcb_fsbase :Pointer;
|
||||
pcb_gsbase :Pointer;
|
||||
td_retval :array[0..1] of QWORD;
|
||||
td_ustack :packed record
|
||||
stack :Pointer;
|
||||
sttop :Pointer;
|
||||
end;
|
||||
td_kstack :packed record
|
||||
stack :Pointer;
|
||||
sttop :Pointer;
|
||||
end;
|
||||
td_ustack :t_td_stack;
|
||||
td_kstack :t_td_stack;
|
||||
//
|
||||
td_sleepqueue :Pointer;
|
||||
td_slpq :TAILQ_ENTRY;
|
||||
|
@ -248,16 +245,6 @@ type
|
|||
end;
|
||||
{$IF sizeof(thr_param)<>104}{$STOP sizeof(thr_param)<>104}{$ENDIF}
|
||||
|
||||
{
|
||||
* pargs, used to hold a copy of the command line, if it had a sane length.
|
||||
}
|
||||
p_pargs=^t_pargs;
|
||||
t_pargs=packed record
|
||||
ar_ref :Integer; // Reference count.
|
||||
ar_length:Integer; // Length.
|
||||
ar_args :AnsiChar; // Arguments.
|
||||
end;
|
||||
|
||||
function curkthread:p_kthread;
|
||||
procedure set_curkthread(td:p_kthread);
|
||||
|
||||
|
@ -297,55 +284,8 @@ function curthread_pflags_set(flags:Integer):Integer;
|
|||
procedure curthread_pflags_restore(save:Integer);
|
||||
procedure curthread_set_pcb_onfault(v:Pointer);
|
||||
|
||||
procedure PROC_LOCK;
|
||||
procedure PROC_UNLOCK;
|
||||
|
||||
procedure PROC_INIT; //SYSINIT
|
||||
|
||||
function pargs_alloc(len:Integer):p_pargs;
|
||||
procedure pargs_free(pa:p_pargs);
|
||||
procedure pargs_hold(pa:p_pargs);
|
||||
procedure pargs_drop(pa:p_pargs);
|
||||
|
||||
const
|
||||
MAXCOMLEN=19;
|
||||
|
||||
var
|
||||
p_proc:record
|
||||
p_mtx:mtx;
|
||||
|
||||
p_flag :Integer;
|
||||
p_osrel:Integer;
|
||||
|
||||
p_sdk_version:Integer;
|
||||
p_sce_replay_exec:Integer;
|
||||
|
||||
libkernel_start_addr:Pointer;
|
||||
libkernel___end_addr:Pointer;
|
||||
|
||||
p_ptc:Int64;
|
||||
|
||||
p_nsignals:Int64;
|
||||
p_nvcsw :Int64;
|
||||
p_nivcsw :Int64;
|
||||
|
||||
p_comm :array[0..MAXCOMLEN] of AnsiChar;
|
||||
prog_name :array[0..1023] of AnsiChar;
|
||||
p_randomized_path:array[0..7] of AnsiChar;
|
||||
|
||||
p_klist:t_knlist;
|
||||
|
||||
p_args:p_pargs;
|
||||
|
||||
p_dmem_aliasing:Integer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kern_event,
|
||||
md_time;
|
||||
|
||||
function curkthread:p_kthread; assembler; nostackframe;
|
||||
asm
|
||||
movqq %gs:teb.thread,Result
|
||||
|
@ -549,65 +489,6 @@ begin
|
|||
td^.pcb_onfault:=v;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure PROC_LOCK;
|
||||
begin
|
||||
mtx_lock(p_proc.p_mtx);
|
||||
end;
|
||||
|
||||
procedure PROC_UNLOCK;
|
||||
begin
|
||||
mtx_unlock(p_proc.p_mtx);
|
||||
end;
|
||||
|
||||
|
||||
procedure PROC_INIT;
|
||||
const
|
||||
osreldate=$000DBBA0;
|
||||
begin
|
||||
FillChar(p_proc,SizeOf(p_proc),0);
|
||||
mtx_init(p_proc.p_mtx,'process lock');
|
||||
|
||||
knlist_init_mtx(@p_proc.p_klist,@p_proc.p_mtx);
|
||||
|
||||
p_proc.p_osrel:=osreldate;
|
||||
|
||||
p_proc.p_randomized_path:='system';
|
||||
|
||||
p_proc.p_ptc:=rdtsc;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function pargs_alloc(len:Integer):p_pargs;
|
||||
begin
|
||||
Result:=AllocMem(sizeof(t_pargs) + len);
|
||||
Result^.ar_ref :=1;
|
||||
Result^.ar_length:=len;
|
||||
end;
|
||||
|
||||
procedure pargs_free(pa:p_pargs);
|
||||
begin
|
||||
FreeMem(pa);
|
||||
end;
|
||||
|
||||
procedure pargs_hold(pa:p_pargs);
|
||||
begin
|
||||
if (pa=nil) then Exit;
|
||||
System.InterlockedIncrement(pa^.ar_ref);
|
||||
end;
|
||||
|
||||
procedure pargs_drop(pa:p_pargs);
|
||||
begin
|
||||
if (pa=nil) then Exit;
|
||||
if (System.InterlockedDecrement(pa^.ar_ref)=0) then
|
||||
begin
|
||||
pargs_free(pa);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ uses
|
|||
kern_umtx,
|
||||
kern_sig,
|
||||
kern_synch,
|
||||
kern_proc,
|
||||
sched_ule,
|
||||
subr_sleepqueue;
|
||||
|
||||
|
@ -333,6 +334,19 @@ begin
|
|||
ipi_sigreturn; //switch
|
||||
end;
|
||||
|
||||
procedure main_wrapper; assembler; nostackframe;
|
||||
asm
|
||||
subq $40, %rsp
|
||||
.seh_stackalloc 40
|
||||
.seh_endprologue
|
||||
jmpq %gs:teb.jitcall
|
||||
|
||||
nop
|
||||
addq $40, %rsp
|
||||
.seh_handler __FPC_default_handler,@except,@unwind
|
||||
end;
|
||||
|
||||
|
||||
function create_thread(td :p_kthread; //calling thread
|
||||
ctx :p_mcontext_t;
|
||||
start_func:Pointer;
|
||||
|
@ -470,6 +484,11 @@ begin
|
|||
cpu_set_user_tls(newtd,tls_base);
|
||||
end;
|
||||
|
||||
//seh wrapper
|
||||
newtd^.td_teb^.jitcall:=Pointer(newtd^.td_frame.tf_rip);
|
||||
newtd^.td_frame.tf_rip:=QWORD(@main_wrapper);
|
||||
//seh wrapper
|
||||
|
||||
if (td<>nil) then
|
||||
begin
|
||||
newtd^.td_sigmask:=td^.td_sigmask;
|
||||
|
|
|
@ -9,7 +9,8 @@ uses
|
|||
signal,
|
||||
signalvar,
|
||||
ucontext,
|
||||
kern_thr;
|
||||
kern_thr,
|
||||
kern_proc;
|
||||
|
||||
const
|
||||
_ucodesel=(8 shl 3) or 3;
|
||||
|
@ -148,7 +149,6 @@ begin
|
|||
else
|
||||
With td^.td_frame do
|
||||
begin
|
||||
Writeln(stderr,'syscall error:',error);
|
||||
tf_rax:=error;
|
||||
tf_rflags:=tf_rflags or PSL_C;
|
||||
end;
|
||||
|
|
|
@ -367,6 +367,7 @@ uses
|
|||
vfs_lookup,
|
||||
vfs_subr,
|
||||
vnode_if,
|
||||
kern_proc,
|
||||
kern_reloc,
|
||||
kern_namedobj,
|
||||
elf_nid_utils;
|
||||
|
|
|
@ -71,6 +71,7 @@ implementation
|
|||
uses
|
||||
errno,
|
||||
signalvar,
|
||||
kern_proc,
|
||||
kern_thread,
|
||||
kern_sig,
|
||||
sched_ule,
|
||||
|
|
|
@ -153,7 +153,7 @@ procedure switch_to_jit(frame:p_jit_frame);
|
|||
function IS_TRAP_FUNC(rip:qword):Boolean;
|
||||
|
||||
function trap(frame:p_trapframe):Integer;
|
||||
function trap_pfault(frame:p_trapframe;usermode:Integer):Integer;
|
||||
function trap_pfault(frame:p_trapframe;usermode:Boolean):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -577,6 +577,7 @@ var
|
|||
scall:tsyscall;
|
||||
error:Integer;
|
||||
i,count:Integer;
|
||||
is_guest:Boolean;
|
||||
begin
|
||||
//Call directly to the address or make an ID table?
|
||||
|
||||
|
@ -587,6 +588,7 @@ begin
|
|||
|
||||
error:=0;
|
||||
scall:=nil;
|
||||
is_guest:=False;
|
||||
|
||||
if (td_frame^.tf_rax<=High(sysent_table)) then
|
||||
begin
|
||||
|
@ -638,6 +640,7 @@ begin
|
|||
if (td_frame^.tf_rax<=High(sysent_table)) then
|
||||
if is_guest_addr(td_frame^.tf_rip) then
|
||||
begin
|
||||
is_guest:=True;
|
||||
Writeln('Guest syscall:',sysent_table[td_frame^.tf_rax].sy_name);
|
||||
|
||||
//count:=sysent_table[td_frame^.tf_rax].sy_narg;
|
||||
|
@ -665,6 +668,17 @@ begin
|
|||
td^.td_errno:=error;
|
||||
end;
|
||||
|
||||
if is_guest then
|
||||
Case error of
|
||||
0:;
|
||||
ERESTART:;
|
||||
EJUSTRETURN:; //nothing
|
||||
else
|
||||
begin
|
||||
Writeln('Guest syscall:',sysent_table[td_frame^.tf_rax].sy_name,' error:',error);
|
||||
end;
|
||||
end;
|
||||
|
||||
cpu_set_syscall_retval(td,error);
|
||||
end;
|
||||
|
||||
|
@ -865,21 +879,49 @@ procedure jit_frame_call(frame:p_jit_frame);
|
|||
begin
|
||||
cpu_init_jit(curkthread);
|
||||
|
||||
if QWORD(frame^.reta)-QWORD(frame^.addr)=3 then
|
||||
begin
|
||||
Writeln('tf_rcx>:',HexStr(curkthread^.td_frame.tf_rcx,16));
|
||||
end;
|
||||
|
||||
t_proc(frame^.call)();
|
||||
|
||||
if QWORD(frame^.reta)-QWORD(frame^.addr)=3 then
|
||||
begin
|
||||
Writeln('tf_rcx<:',HexStr(curkthread^.td_frame.tf_rcx,16));
|
||||
end;
|
||||
|
||||
cpu_fini_jit(curkthread);
|
||||
end;
|
||||
|
||||
{
|
||||
//rdi
|
||||
procedure jit_frame_call(frame:p_jit_frame); assembler;
|
||||
var
|
||||
rdi:QWORD;
|
||||
asm
|
||||
movqq %rdi,rdi
|
||||
|
||||
movqq %gs:teb.thread,%rdi
|
||||
call cpu_init_jit
|
||||
|
||||
movqq rdi,%rdi
|
||||
movqq t_jit_frame.call(%rdi),%rax
|
||||
callq %rax
|
||||
|
||||
movqq %gs:teb.thread,%rdi
|
||||
call cpu_fini_jit
|
||||
end;
|
||||
}
|
||||
|
||||
//input:
|
||||
// 1: %gs:teb.jit_rsp (original %rsp)
|
||||
// 2: %rsp (jitcall addr)
|
||||
procedure jit_call; assembler; nostackframe;
|
||||
label
|
||||
_after_call,
|
||||
_doreti,
|
||||
_fail,
|
||||
_ast,
|
||||
_doreti_exit;
|
||||
_ast;
|
||||
asm
|
||||
//%rsp must be saved in %gs:teb.jit_rsp upon enter (Implicit lock interrupt)
|
||||
|
||||
|
@ -948,10 +990,6 @@ asm
|
|||
|
||||
movqq %gs:teb.thread,%rcx //curkthread
|
||||
|
||||
//Requested full context restore
|
||||
testl PCB_FULL_IRET,kthread.pcb_flags(%rcx)
|
||||
jnz _doreti
|
||||
|
||||
testl TDF_AST,kthread.td_flags(%rcx)
|
||||
jne _ast
|
||||
|
||||
|
@ -988,12 +1026,12 @@ asm
|
|||
//fail (curkthread=nil)
|
||||
_fail:
|
||||
|
||||
sahf //restore flags from AH
|
||||
|
||||
movqq %gs:teb.jitcall ,%rax //get struct
|
||||
movqq t_jit_frame.reta(%rax),%rax //get ret addr
|
||||
movqq %rax,%gs:teb.jitcall //save ret
|
||||
|
||||
sahf //restore flags from AH
|
||||
|
||||
movqq %gs:teb.jit_rax,%rax //restore %rax
|
||||
xchgq %gs:teb.jit_rsp,%rsp //restore %rsp (and also set teb.jit_rsp=0)
|
||||
|
||||
|
@ -1005,22 +1043,6 @@ asm
|
|||
|
||||
call ast
|
||||
jmp _after_call
|
||||
|
||||
//doreti
|
||||
_doreti:
|
||||
|
||||
//%rcx=curkthread
|
||||
testl TDF_AST,kthread.td_flags(%rcx)
|
||||
je _doreti_exit
|
||||
|
||||
call ast
|
||||
jmp _doreti
|
||||
|
||||
_doreti_exit:
|
||||
|
||||
//Restore full.
|
||||
call ipi_sigreturn
|
||||
hlt
|
||||
end;
|
||||
|
||||
function IS_TRAP_FUNC(rip:qword):Boolean;
|
||||
|
@ -1031,13 +1053,13 @@ begin
|
|||
) or
|
||||
(
|
||||
(rip>=QWORD(@jit_call)) and
|
||||
(rip<=(QWORD(@jit_call)+$23C)) //jit_call func size
|
||||
(rip<=(QWORD(@jit_call)+$219)) //jit_call func size
|
||||
);
|
||||
end;
|
||||
|
||||
function IS_USERMODE(td:p_kthread;frame:p_trapframe):Integer; inline;
|
||||
function IS_USERMODE(td:p_kthread;frame:p_trapframe):Boolean; inline;
|
||||
begin
|
||||
Result:=ord((frame^.tf_rsp>QWORD(td^.td_kstack.stack)) or (frame^.tf_rsp<=(QWORD(td^.td_kstack.sttop))));
|
||||
Result:=(frame^.tf_rsp>QWORD(td^.td_kstack.stack)) or (frame^.tf_rsp<=(QWORD(td^.td_kstack.sttop)));
|
||||
end;
|
||||
|
||||
function trap(frame:p_trapframe):Integer;
|
||||
|
@ -1060,6 +1082,7 @@ end;
|
|||
|
||||
procedure trap_fatal(frame:p_trapframe;eva:vm_offset_t);
|
||||
var
|
||||
td:p_kthread;
|
||||
trapno:Integer;
|
||||
msg,msg2:pchar;
|
||||
begin
|
||||
|
@ -1070,15 +1093,29 @@ begin
|
|||
else
|
||||
msg:='UNKNOWN';
|
||||
|
||||
if Boolean(IS_USERMODE(curkthread,frame)) then
|
||||
if IS_USERMODE(curkthread,frame) then
|
||||
msg2:='user'
|
||||
else
|
||||
msg2:='kernel';
|
||||
|
||||
Writeln(StdErr,'Fatal trap ',trapno,': ',msg,' while in ',msg2,' mode');
|
||||
|
||||
Writeln(StdErr,'fault virtual address = 0x',HexStr(eva,16));
|
||||
Writeln(StdErr,'instruction pointer = 0x',HexStr(frame^.tf_rip,16));
|
||||
Writeln(StdErr,'stack pointer = 0x',HexStr(frame^.tf_rsp,16));
|
||||
Writeln(StdErr,'frame pointer = 0x',HexStr(frame^.tf_rbp,16));
|
||||
|
||||
td:=curkthread;
|
||||
if (td<>nil) then
|
||||
begin
|
||||
Writeln(StdErr,'td_ustack.stack = 0x',HexStr(td^.td_ustack.stack));
|
||||
Writeln(StdErr,'td_ustack.sttop = 0x',HexStr(td^.td_ustack.sttop));
|
||||
Writeln(StdErr,'td_kstack.stack = 0x',HexStr(td^.td_kstack.stack));
|
||||
Writeln(StdErr,'td_kstack.sttop = 0x',HexStr(td^.td_kstack.sttop));
|
||||
end;
|
||||
end;
|
||||
|
||||
function trap_pfault(frame:p_trapframe;usermode:Integer):Integer;
|
||||
function trap_pfault(frame:p_trapframe;usermode:Boolean):Integer;
|
||||
var
|
||||
td:p_kthread;
|
||||
eva:vm_offset_t;
|
||||
|
@ -1092,6 +1129,7 @@ begin
|
|||
|
||||
if ((td^.td_pflags and TDP_NOFAULTING)<>0) then
|
||||
begin
|
||||
Writeln('TDP_NOFAULTING:',curkthread^.td_name);
|
||||
Exit(SIGSEGV);
|
||||
end;
|
||||
|
||||
|
@ -1114,13 +1152,15 @@ begin
|
|||
|
||||
end else
|
||||
begin
|
||||
Writeln('not is_guest_addr:0x',HexStr(eva,16),':',curkthread^.td_name);
|
||||
Result:=SIGSEGV;
|
||||
end;
|
||||
|
||||
//if (usermode=0) then
|
||||
if (not usermode) then
|
||||
begin
|
||||
if (td^.pcb_onfault<>nil) then
|
||||
begin
|
||||
Writeln('pcb_onfault<:',HexStr(td^.pcb_onfault),':',curkthread^.td_name);
|
||||
frame^.tf_rip:=QWORD(td^.pcb_onfault);
|
||||
Exit(0);
|
||||
end else
|
||||
|
|
|
@ -12,7 +12,6 @@ function sys_socketclose(fd:Integer):Integer;
|
|||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
kern_thr,
|
||||
kern_descrip,
|
||||
kern_conf,
|
||||
|
|
|
@ -9,7 +9,8 @@ uses
|
|||
Windows,
|
||||
ntapi,
|
||||
ucontext,
|
||||
kern_thr;
|
||||
kern_thr,
|
||||
kern_proc;
|
||||
|
||||
const
|
||||
XSTATE_LEGACY_FLOATING_POINT=0;
|
||||
|
|
|
@ -90,6 +90,7 @@ end;
|
|||
|
||||
const
|
||||
FPC_EXCEPTION_CODE=$E0465043;
|
||||
FPC_SET_EH_HANDLER=$E0465044;
|
||||
|
||||
function translate_pageflt_err(v:QWORD):QWORD; inline;
|
||||
begin
|
||||
|
@ -106,14 +107,15 @@ var
|
|||
ExceptionCode:DWORD;
|
||||
td:p_kthread;
|
||||
tf_addr:QWORD;
|
||||
backup:trapframe;
|
||||
//backup:trapframe;
|
||||
rv:Integer;
|
||||
begin
|
||||
Result:=1;
|
||||
td:=curkthread;
|
||||
|
||||
//Context backup to return correctly
|
||||
backup:=td^.td_frame;
|
||||
//backup:=td^.td_frame;
|
||||
|
||||
td^.td_frame.tf_trapno:=0;
|
||||
|
||||
ExceptionCode:=p^.ExceptionRecord^.ExceptionCode;
|
||||
|
@ -128,7 +130,7 @@ begin
|
|||
//Writeln(HexStr(p^.ContextRecord^.Rip,16));
|
||||
//Writeln(HexStr(Get_pc_addr));
|
||||
|
||||
_get_frame(p^.ContextRecord,@td^.td_frame,@td^.td_fpstate);
|
||||
_get_frame(p^.ContextRecord,@td^.td_frame,{@td^.td_fpstate}nil);
|
||||
|
||||
td^.td_frame.tf_trapno:=T_PAGEFLT;
|
||||
td^.td_frame.tf_err :=translate_pageflt_err(p^.ExceptionRecord^.ExceptionInformation[0]);
|
||||
|
@ -142,50 +144,99 @@ begin
|
|||
|
||||
if (rv=0) then
|
||||
begin
|
||||
_set_frame(p^.ContextRecord,@td^.td_frame,@td^.td_fpstate);
|
||||
_set_frame(p^.ContextRecord,@td^.td_frame,{@td^.td_fpstate}nil);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
//simple ret
|
||||
td^.pcb_flags:=td^.pcb_flags and (not PCB_FULL_IRET);
|
||||
//td^.pcb_flags:=td^.pcb_flags and (not PCB_FULL_IRET);
|
||||
|
||||
td^.td_frame:=backup;
|
||||
//td^.td_frame:=backup;
|
||||
end;
|
||||
|
||||
function ProcessException2(p:PExceptionPointers):longint; assembler; nostackframe; SysV_ABI_CDecl;
|
||||
{
|
||||
//rdi,rsi
|
||||
function ProcessException2(p:PExceptionPointers;rsp:Pointer):longint; assembler; nostackframe; SysV_ABI_CDecl;
|
||||
asm
|
||||
//prolog (debugger)
|
||||
pushq %rbp
|
||||
movq %rsp,%rbp
|
||||
//pushq %rbp
|
||||
//movq %rsp,%rbp
|
||||
|
||||
movq ProcessException3,%rax
|
||||
call fast_syscall
|
||||
xchg %rsi,%rsp
|
||||
andq $-32,%rsp //align stack
|
||||
|
||||
pushq %rsi
|
||||
pushq %rbp
|
||||
|
||||
call ProcessException3
|
||||
|
||||
popq %rbp
|
||||
popq %rsp
|
||||
|
||||
//movq ProcessException3,%rax
|
||||
///call fast_syscall
|
||||
|
||||
//epilog (debugger)
|
||||
popq %rbp
|
||||
//popq %rbp
|
||||
end;
|
||||
}
|
||||
|
||||
type
|
||||
TExceptObjProc=function(code: Longint; const rec: TExceptionRecord): Pointer; { Exception }
|
||||
TExceptClsProc=function(code: Longint): Pointer; { ExceptClass }
|
||||
|
||||
function IS_SYSTEM_STACK(td:p_kthread;rsp:qword):Boolean; inline;
|
||||
begin
|
||||
Result:=(rsp<=QWORD(td^.td_kstack.stack)) and (rsp>(QWORD(td^.td_kstack.sttop)));
|
||||
end;
|
||||
|
||||
function ProcessException(p:PExceptionPointers):longint; stdcall;
|
||||
var
|
||||
td:p_kthread;
|
||||
begin
|
||||
Result:=EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
//Writeln('rsp:0x',HexStr(p^.ContextRecord^.Rsp,16));
|
||||
//Writeln('rsp:0x',HexStr(get_frame));
|
||||
//Writeln(' p_ctx:0x',HexStr(p));
|
||||
//Writeln('rsp_ctx:0x',HexStr(p^.ContextRecord^.Rsp,16));
|
||||
//Writeln('rsp_frm:0x',HexStr(get_frame));
|
||||
|
||||
case p^.ExceptionRecord^.ExceptionCode of
|
||||
FPC_EXCEPTION_CODE :Exit;
|
||||
FPC_SET_EH_HANDLER :Exit(EXCEPTION_CONTINUE_EXECUTION);
|
||||
EXCEPTION_BREAKPOINT :Exit;
|
||||
EXCEPTION_SET_THREADNAME:Exit;
|
||||
end;
|
||||
|
||||
if (curkthread=nil) then Exit;
|
||||
//readln;
|
||||
|
||||
//It looks like there is a small stack inside the exception, so you need to switch the context
|
||||
Result:=ProcessException2(p);
|
||||
td:=curkthread;
|
||||
|
||||
if (td=nil) then Exit;
|
||||
|
||||
{
|
||||
if (td^.td_teb^.jit_rsp<>nil) then //debugger switch
|
||||
begin
|
||||
Writeln('td_kstack:0x',HexStr(td^.td_kstack.stack));
|
||||
Writeln('jit_rsp:0x',HexStr(td^.td_teb^.jit_rsp));
|
||||
p^.ContextRecord^.Rsp:=qword(td^.td_teb^.jit_rsp);
|
||||
td^.td_teb^.jit_rsp:=nil;
|
||||
end;
|
||||
}
|
||||
|
||||
Result:=ProcessException3(p);
|
||||
|
||||
{
|
||||
if IS_SYSTEM_STACK(curkthread,p^.ContextRecord^.Rsp) then
|
||||
begin
|
||||
Writeln(IS_SYSTEM_STACK(curkthread,p^.ContextRecord^.Rsp),' ',IS_SYSTEM_STACK(curkthread,qword(get_frame)));
|
||||
//
|
||||
Exit;
|
||||
end else
|
||||
begin
|
||||
//It looks like there is a small stack inside the exception, so you need to switch the context
|
||||
Result:=ProcessException2(p,curkthread^.td_kstack.stack);
|
||||
end;
|
||||
}
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
|
@ -207,6 +258,7 @@ begin
|
|||
|
||||
case p^.ExceptionRecord^.ExceptionCode of
|
||||
FPC_EXCEPTION_CODE :Exit;
|
||||
FPC_SET_EH_HANDLER :Exit(EXCEPTION_CONTINUE_EXECUTION);
|
||||
EXCEPTION_BREAKPOINT :Exit;
|
||||
EXCEPTION_SET_THREADNAME:Exit;
|
||||
end;
|
||||
|
@ -229,6 +281,9 @@ begin
|
|||
ExObj:=Exception(TExceptObjProc(ExceptObjProc)(abs(code),rec^));
|
||||
end;
|
||||
|
||||
if curkthread<>nil then
|
||||
Writeln('curkthread^.td_name:',curkthread^.td_name);
|
||||
|
||||
if (ExObj=nil) then
|
||||
begin
|
||||
Writeln(stderr,'Runtime error ',code,' at $',hexstr(rec^.ExceptionAddress));
|
||||
|
@ -246,6 +301,17 @@ begin
|
|||
md_halt(code);
|
||||
end;
|
||||
|
||||
procedure ExceptionDispatcher(p:PExceptionPointers); stdcall;
|
||||
begin
|
||||
if (ProcessException(p)=EXCEPTION_CONTINUE_EXECUTION) then
|
||||
begin
|
||||
NtContinue(p^.ContextRecord,False);
|
||||
end else
|
||||
begin
|
||||
UnhandledException(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure _Assert(Const Msg,FName:Shortstring;LineNo:Longint;ErrorAddr:Pointer);
|
||||
begin
|
||||
If Length(msg)=0 then
|
||||
|
@ -265,12 +331,27 @@ var
|
|||
UEHandler:Pointer=nil;
|
||||
V2Handler:Pointer=nil;
|
||||
|
||||
type
|
||||
PEH_HANDLER_INFO=^EH_HANDLER_INFO;
|
||||
EH_HANDLER_INFO=record
|
||||
ptr:Pointer;
|
||||
end;
|
||||
|
||||
procedure RaiseException(dwExceptionCode:DWORD;
|
||||
dwExceptionFlags:DWORD;
|
||||
nNumberOfArguments:DWORD;
|
||||
lpArguments:Pointer); external 'kernel32';
|
||||
|
||||
procedure InstallExceptionHandler;
|
||||
var
|
||||
eh:EH_HANDLER_INFO;
|
||||
begin
|
||||
AssertErrorProc:=@_Assert;
|
||||
UEHandler:=SetUnhandledExceptionFilter(@UnhandledException);
|
||||
VEHandler:=AddVectoredExceptionHandler(1,@ProcessException);
|
||||
V2Handler:=AddVectoredExceptionHandler(0,@UnhandledException);
|
||||
eh.ptr:=@ExceptionDispatcher;
|
||||
RaiseException(FPC_SET_EH_HANDLER,0,2,@eh);
|
||||
end;
|
||||
|
||||
procedure UninstallExceptionHandler;
|
||||
|
|
|
@ -19,6 +19,7 @@ uses
|
|||
md_proc,
|
||||
md_time,
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
vmparam,
|
||||
vm_map;
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ implementation
|
|||
|
||||
uses
|
||||
syscalls,
|
||||
errno;
|
||||
thr_error;
|
||||
|
||||
//sce
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ uses
|
|||
kern_sysctl,
|
||||
kern_thr,
|
||||
kern_thread,
|
||||
kern_proc,
|
||||
kern_sig,
|
||||
kern_timeout,
|
||||
kern_synch,
|
||||
|
|
|
@ -26,8 +26,7 @@ uses
|
|||
errno,
|
||||
syscalls,
|
||||
kern_umtx,
|
||||
trap,
|
||||
thr_error;
|
||||
trap;
|
||||
|
||||
procedure umtx_init(var umtx:umtx); inline;
|
||||
begin
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="debug"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes>
|
||||
<Item Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="debug.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="debug"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value="..\kern;..\..\rtl;.."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
|
@ -0,0 +1,308 @@
|
|||
|
||||
uses
|
||||
Windows,
|
||||
ntapi,
|
||||
kern_thr;
|
||||
|
||||
const
|
||||
ProcessName='project1.exe';
|
||||
|
||||
var
|
||||
si:TSTARTUPINFO;
|
||||
pi:PROCESS_INFORMATION;
|
||||
|
||||
b:Bool;
|
||||
|
||||
devent:DEBUG_EVENT;
|
||||
dwContinueStatus:DWORD;
|
||||
|
||||
const
|
||||
FPC_EXCEPTION_CODE=$E0465043;
|
||||
FPC_SET_EH_HANDLER=$E0465044;
|
||||
|
||||
type
|
||||
PTHREADNAME_INFO=^THREADNAME_INFO;
|
||||
THREADNAME_INFO=record
|
||||
dwType :DWord; // Must be 0x1000.
|
||||
szName :PAnsiChar; // Pointer to name (in user addr space).
|
||||
dwThreadID:DWord; // Thread ID (-1=caller thread).
|
||||
dwFlags :DWord; // Reserved for future use, must be zero.
|
||||
end;
|
||||
|
||||
function md_copyin(udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
var
|
||||
num:DWORD;
|
||||
begin
|
||||
num:=0;
|
||||
if (NtReadVirtualMemory(pi.hProcess,udaddr,kaddr,len,@num)=0) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=-1;
|
||||
end;
|
||||
if (lencopied<>nil) then
|
||||
begin
|
||||
lencopied^:=num;
|
||||
end;
|
||||
end;
|
||||
|
||||
function md_copyout(kaddr,udaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
var
|
||||
num:DWORD;
|
||||
begin
|
||||
num:=0;
|
||||
if (NtWriteVirtualMemory(pi.hProcess,udaddr,kaddr,len,@num)=0) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=-1;
|
||||
end;
|
||||
if (lencopied<>nil) then
|
||||
begin
|
||||
lencopied^:=num;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
EhHandler:Pointer=nil;
|
||||
|
||||
type
|
||||
PEH_HANDLER_INFO=^EH_HANDLER_INFO;
|
||||
EH_HANDLER_INFO=record
|
||||
ptr:Pointer;
|
||||
end;
|
||||
|
||||
procedure ProcessSetEhHandler(p:PEXCEPTION_DEBUG_INFO);
|
||||
var
|
||||
info:PEH_HANDLER_INFO;
|
||||
begin
|
||||
info:=@p^.ExceptionRecord.ExceptionInformation;
|
||||
EhHandler:=info^.ptr;
|
||||
|
||||
Writeln('FPC_SET_EH_HANDLER:0x',HexStr(EhHandler));
|
||||
end;
|
||||
|
||||
procedure ProcessSetThreadName(p:PEXCEPTION_DEBUG_INFO);
|
||||
var
|
||||
info:PTHREADNAME_INFO;
|
||||
name:array[0..255] of AnsiChar;
|
||||
len:ptruint;
|
||||
begin
|
||||
info:=@p^.ExceptionRecord.ExceptionInformation;
|
||||
|
||||
Fillchar(name,SizeOf(name),0);
|
||||
|
||||
md_copyin(info^.szName,@name,SizeOf(name),@len);
|
||||
|
||||
Writeln('EXCEPTION_SET_THREADNAME:',name,':',info^.dwThreadID);
|
||||
|
||||
//writeln;
|
||||
end;
|
||||
|
||||
function NtQueryTeb(td_handle:THandle):p_teb;
|
||||
var
|
||||
TBI:THREAD_BASIC_INFORMATION;
|
||||
err:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
TBI:=Default(THREAD_BASIC_INFORMATION);
|
||||
|
||||
err:=NtQueryInformationThread(
|
||||
td_handle,
|
||||
ThreadBasicInformation,
|
||||
@TBI,
|
||||
SizeOf(THREAD_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (err<>0) then Exit;
|
||||
|
||||
Result:=TBI.TebBaseAddress;
|
||||
end;
|
||||
|
||||
Function NtQueryThread(dwProcessId,dwThreadId:DWORD):THandle;
|
||||
var
|
||||
hThread:THandle;
|
||||
ClientId:TCLIENT_ID;
|
||||
OATTR:OBJECT_ATTRIBUTES;
|
||||
begin
|
||||
ClientId.UniqueProcess:=dwProcessId;
|
||||
ClientId.UniqueThread :=dwThreadId;
|
||||
|
||||
OATTR:=Default(OBJECT_ATTRIBUTES);
|
||||
OATTR.Length:=SizeOf(OBJECT_ATTRIBUTES);
|
||||
|
||||
hThread:=0;
|
||||
NtOpenThread(@hThread,THREAD_ALL_ACCESS,@OATTR,@ClientId);
|
||||
|
||||
Result:=hThread;
|
||||
end;
|
||||
|
||||
function IS_SYSTEM_STACK(kstack:t_td_stack;rsp:qword):Boolean; inline;
|
||||
begin
|
||||
Result:=(rsp<=QWORD(kstack.stack)) and (rsp>QWORD(kstack.sttop));
|
||||
end;
|
||||
|
||||
procedure ProcessAV(p:PEXCEPTION_DEBUG_INFO);
|
||||
var
|
||||
hThread:THandle;
|
||||
u_teb:p_teb;
|
||||
k_teb:teb;
|
||||
u_td:p_kthread;
|
||||
_Context:array[0..SizeOf(TCONTEXT)+15] of Byte;
|
||||
Context :PCONTEXT;
|
||||
|
||||
k_exp:TExceptionPointers;
|
||||
u_exp:PExceptionPointers;
|
||||
|
||||
kstack:t_td_stack;
|
||||
|
||||
rsp:QWORD;
|
||||
|
||||
err:DWORD;
|
||||
begin
|
||||
//dwContinueStatus:=DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
hThread:=NtQueryThread(devent.dwProcessId,devent.dwThreadId);
|
||||
|
||||
u_teb:=NtQueryTeb(hThread);
|
||||
|
||||
u_td:=nil;
|
||||
|
||||
if (u_teb<>nil) then
|
||||
begin
|
||||
k_teb:=Default(teb);
|
||||
md_copyin(u_teb,@k_teb,SizeOf(teb),nil);
|
||||
u_td:=k_teb.thread;
|
||||
end;
|
||||
|
||||
if (u_td<>nil) then
|
||||
begin
|
||||
Context:=Align(@_Context,16);
|
||||
|
||||
Context^:=Default(TCONTEXT);
|
||||
Context^.ContextFlags:=CONTEXT_ALL;
|
||||
|
||||
err:=NtGetContextThread(hThread,Context);
|
||||
//Writeln('NtGetContextThread:',HexStr(err,16));
|
||||
|
||||
kstack:=Default(t_td_stack);
|
||||
err:=md_copyin(@u_td^.td_kstack,@kstack,SizeOf(t_td_stack),nil);
|
||||
//Writeln('md_copyin:',err);
|
||||
|
||||
//Writeln('td_kstack.stack:',HexStr(kstack.stack));
|
||||
//Writeln('td_kstack.sttop:',HexStr(kstack.sttop));
|
||||
|
||||
rsp:=Context^.Rsp;
|
||||
//Writeln('Rsp:',HexStr(rsp,16));
|
||||
|
||||
if IS_SYSTEM_STACK(kstack,rsp) then
|
||||
begin
|
||||
rsp:=rsp-128;
|
||||
end else
|
||||
begin
|
||||
rsp:=QWORD(kstack.stack);
|
||||
end;
|
||||
|
||||
rsp:=rsp-SizeOf(EXCEPTION_RECORD);
|
||||
k_exp.ExceptionRecord:=Pointer(rsp);
|
||||
|
||||
rsp:=rsp-SizeOf(TCONTEXT);
|
||||
rsp:=rsp and QWORD(-16); //context align
|
||||
|
||||
k_exp.ContextRecord:=Pointer(rsp);
|
||||
|
||||
rsp:=rsp-SizeOf(EXCEPTION_POINTERS);
|
||||
|
||||
u_exp:=Pointer(rsp);
|
||||
|
||||
rsp:=rsp-SizeOf(QWORD);
|
||||
rsp:=rsp and QWORD(-32); //avx align
|
||||
rsp:=rsp-SizeOf(QWORD);
|
||||
|
||||
err:=md_copyout(@k_exp,u_exp,SizeOf(EXCEPTION_POINTERS),nil); //pointers
|
||||
//Writeln('md_copyout:',err);
|
||||
|
||||
err:=md_copyout(Context,k_exp.ContextRecord,SizeOf(TCONTEXT),nil); //context
|
||||
//Writeln('md_copyout:',err);
|
||||
|
||||
err:=md_copyout(@p^.ExceptionRecord,k_exp.ExceptionRecord,SizeOf(EXCEPTION_RECORD),nil); //record
|
||||
//Writeln('md_copyout:',err);
|
||||
|
||||
//Writeln('start rsp:',HexStr(rsp,16));
|
||||
|
||||
Context^.Rsp:=rsp;
|
||||
Context^.Rbp:=rsp;
|
||||
|
||||
Context^.Rcx:=QWORD(u_exp);
|
||||
Context^.Rip:=QWORD(EhHandler);
|
||||
|
||||
err:=NtSetContextThread(hThread,Context);
|
||||
//Writeln('NtSetContextThread:',err);
|
||||
|
||||
end;
|
||||
|
||||
if (hThread<>0) then
|
||||
begin
|
||||
NtClose(hThread);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure ProcessException(p:PEXCEPTION_DEBUG_INFO);
|
||||
begin
|
||||
|
||||
case p^.ExceptionRecord.ExceptionCode of
|
||||
FPC_EXCEPTION_CODE :Exit;
|
||||
FPC_SET_EH_HANDLER :ProcessSetEhHandler(p);
|
||||
EXCEPTION_BREAKPOINT :Exit;
|
||||
EXCEPTION_SET_THREADNAME :ProcessSetThreadName(p);
|
||||
EXCEPTION_ACCESS_VIOLATION:ProcessAV(p);
|
||||
else
|
||||
Writeln('EXCEPTION_DEBUG_EVENT:0x',HexStr(p^.ExceptionRecord.ExceptionCode,8));
|
||||
end;
|
||||
|
||||
//writeln;
|
||||
end;
|
||||
|
||||
procedure ProcessDebugEvent;
|
||||
begin
|
||||
case devent.dwDebugEventCode of
|
||||
EXCEPTION_DEBUG_EVENT :ProcessException(@devent.Exception);
|
||||
CREATE_THREAD_DEBUG_EVENT :Writeln('CREATE_THREAD_DEBUG_EVENT ');
|
||||
CREATE_PROCESS_DEBUG_EVENT:Writeln('CREATE_PROCESS_DEBUG_EVENT');
|
||||
EXIT_THREAD_DEBUG_EVENT :Writeln('EXIT_THREAD_DEBUG_EVENT ');
|
||||
EXIT_PROCESS_DEBUG_EVENT :Writeln('EXIT_PROCESS_DEBUG_EVENT ');
|
||||
LOAD_DLL_DEBUG_EVENT :Writeln('LOAD_DLL_DEBUG_EVENT ');
|
||||
OUTPUT_DEBUG_STRING_EVENT :Writeln('OUTPUT_DEBUG_STRING_EVENT ');
|
||||
UNLOAD_DLL_DEBUG_EVENT :Writeln('UNLOAD_DLL_DEBUG_EVENT ');
|
||||
RIP_EVENT :Writeln('RIP_EVENT ');
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
si:=Default(TSTARTUPINFO);
|
||||
pi:=Default(PROCESS_INFORMATION);
|
||||
|
||||
si.cb:=SizeOf(si);
|
||||
|
||||
b:=CreateProcessW(ProcessName,nil,nil,nil,False,DEBUG_ONLY_THIS_PROCESS,nil,nil,@si,@pi);
|
||||
|
||||
devent:=Default(Windows.DEBUG_EVENT);
|
||||
|
||||
repeat
|
||||
b:=WaitForDebugEvent(@devent,INFINITE);
|
||||
if not b then Break;
|
||||
|
||||
dwContinueStatus:=DBG_CONTINUE;
|
||||
|
||||
ProcessDebugEvent();
|
||||
|
||||
ContinueDebugEvent(devent.dwProcessId,
|
||||
devent.dwThreadId,
|
||||
dwContinueStatus);
|
||||
until false;
|
||||
|
||||
end.
|
||||
|
|
@ -734,6 +734,10 @@
|
|||
<Filename Value="..\dev\dev_dce.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\kern\kern_proc.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -373,7 +373,7 @@ begin
|
|||
//argv0:='/app0/basic-sample_debug.elf';
|
||||
//argv0:='/app0/simple.elf';
|
||||
argv0:='/app0/videoout_basic.elf';
|
||||
//argv0:='/app0/videoout_cursor.elf';
|
||||
argv0:='/app0/videoout_cursor.elf';
|
||||
|
||||
err:=_execve(argv0,@argv0,nil);
|
||||
end;
|
||||
|
|
|
@ -7,6 +7,7 @@ interface
|
|||
|
||||
uses
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
kern_id,
|
||||
sys_event,
|
||||
vfile,
|
||||
|
|
|
@ -6,6 +6,7 @@ unit vfs_syscalls;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_proc,
|
||||
time,
|
||||
vmount,
|
||||
vuio,
|
||||
|
@ -453,7 +454,7 @@ begin
|
|||
end;
|
||||
if {(priv_check(td, PRIV_VFS_GENERATION))} True then
|
||||
begin
|
||||
Move(sp^, sb, sizeof(sb));
|
||||
sb:=sp^;
|
||||
sb.f_fsid.val[0]:=0;
|
||||
sb.f_fsid.val[1]:=0;
|
||||
//prison_enforce_statfs(td^.td_ucred, mp, @sb);
|
||||
|
@ -461,7 +462,7 @@ begin
|
|||
end;
|
||||
if (bufseg=UIO_SYSSPACE) then
|
||||
begin
|
||||
Move(sp^, sfsp^, sizeof(sb));
|
||||
sfsp^:=sp^;
|
||||
end else
|
||||
begin
|
||||
error:=copyout(sp, sfsp, sizeof(sb));
|
||||
|
@ -1675,7 +1676,7 @@ begin
|
|||
vattr.va_size:=size;
|
||||
|
||||
if (noneg<>0) and
|
||||
((vattr.va_size > High(Int64)) or
|
||||
((vattr.va_size < 0) or
|
||||
((offset > 0) and (vattr.va_size > High(Int64) - offset))) then
|
||||
begin
|
||||
error:=EOVERFLOW;
|
||||
|
|
|
@ -950,7 +950,6 @@ const
|
|||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
vfs_subr;
|
||||
|
||||
function get_vp_cb(vp:p_vnode;offset:Pointer):Pointer; inline;
|
||||
|
|
|
@ -113,6 +113,7 @@ uses
|
|||
subr_uio,
|
||||
kern_sig,
|
||||
kern_thread,
|
||||
kern_proc,
|
||||
md_time,
|
||||
sys_capability;
|
||||
|
||||
|
|
|
@ -218,13 +218,14 @@ begin
|
|||
//Did the exception happen inside a patch? just going out
|
||||
if vm_check_patch_entry(map,rip_addr,@entry) then
|
||||
begin
|
||||
Writeln('exception_inside_patch');
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
obj:=entry^.vm_obj;
|
||||
Assert(obj<>nil,'vm_try_jit_patch (obj=nil)');
|
||||
|
||||
Writeln('mmaped addr 0x',HexStr(mem_addr,16),' to 0x',HexStr(uplift(Pointer(mem_addr))));
|
||||
Writeln('mmaped addr 0x',HexStr(mem_addr,16),' to 0x',HexStr(uplift(Pointer(mem_addr))),' on rip:0x',HexStr(rip_addr,16));
|
||||
|
||||
ctx:=Default(t_jit_context);
|
||||
ctx.Code:=c_data16;
|
||||
|
@ -250,6 +251,8 @@ begin
|
|||
begin
|
||||
//delete patch
|
||||
|
||||
Writeln('Delete overlap patch at:0x',HexStr(info.vaddr));
|
||||
|
||||
tmp_jit:=@info.stub^.body;
|
||||
|
||||
patch_original(map,entry,QWORD(info.vaddr),tmp_jit^.o_len,@tmp_jit^.o_data);
|
||||
|
@ -268,7 +271,6 @@ begin
|
|||
1..2:
|
||||
begin
|
||||
//Not possible
|
||||
chunk_prolog:=nil;
|
||||
end;
|
||||
3:
|
||||
begin
|
||||
|
@ -300,7 +302,10 @@ begin
|
|||
chunk_prolog:=p_alloc(Pointer(rip_addr_jmp),SizeOf(t_jit_prolog));
|
||||
end;
|
||||
else
|
||||
begin
|
||||
Writeln('vm_try_jit_patch (',vsize,')');
|
||||
Assert(false,'vm_try_jit_patch (vsize)');
|
||||
end;
|
||||
end;
|
||||
|
||||
ctx.rip_addr:=rip_addr;
|
||||
|
@ -309,6 +314,7 @@ begin
|
|||
if (chunk_prolog=nil) then
|
||||
begin
|
||||
//Prologue not created?
|
||||
ctx.jit_code^.prolog:=nil;
|
||||
end else
|
||||
begin
|
||||
jit_prolog:=@chunk_prolog^.body;
|
||||
|
@ -321,10 +327,18 @@ begin
|
|||
|
||||
if (vsize<5) then
|
||||
begin
|
||||
Assert(is_mask_valid(Pointer(rip_addr_jmp),jit_prolog,mask),'vm_try_jit_patch (is_mask_valid)');
|
||||
if not is_mask_valid(Pointer(rip_addr_jmp),jit_prolog,mask) then
|
||||
begin
|
||||
Writeln('is_mask_valid:',HexStr(mask,8));
|
||||
Assert(false,'vm_try_jit_patch (is_mask_valid)');
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Assert(is_near_valid(Pointer(rip_addr_jmp),jit_prolog),'vm_try_jit_patch (is_near_valid)');
|
||||
if not is_near_valid(Pointer(rip_addr_jmp),jit_prolog) then
|
||||
begin
|
||||
Writeln('is_near_valid:');
|
||||
Assert(false,'vm_try_jit_patch (is_near_valid)');
|
||||
end;
|
||||
end;
|
||||
|
||||
patch_original(map,entry,rip_addr,vsize,Integer(delta));
|
||||
|
|
|
@ -258,6 +258,9 @@ procedure vminit; //SYSINIT
|
|||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kern_proc;
|
||||
|
||||
var
|
||||
sgrowsiz:QWORD=vmparam.SGROWSIZ;
|
||||
stack_guard_page:Integer=0;
|
||||
|
|
|
@ -52,6 +52,7 @@ uses
|
|||
systm,
|
||||
errno,
|
||||
kern_thr,
|
||||
kern_proc,
|
||||
vmparam,
|
||||
_resource,
|
||||
kern_resource,
|
||||
|
|
Loading…
Reference in New Issue