From 848dd4a128fca6a12bf19e024814ee574ac0ca30 Mon Sep 17 00:00:00 2001
From: Pavel <68122101+red-prig@users.noreply.github.com>
Date: Tue, 5 Sep 2023 21:21:53 +0300
Subject: [PATCH] +
---
kernel/libthr/thr_error.pas | 44 +++++
rtl/ntapi.pas | 17 +-
rtl/x86_jit.pas | 33 ++--
sys/dev/dev_dce.pas | 18 +-
sys/dev/dev_tty.pas | 3 +-
sys/errno.pas | 47 ------
sys/fs/devfs/devfs.pas | 1 -
sys/fs/devfs/devfs_vnops.pas | 1 +
sys/fs/ufs/ufs_vnops.pas | 6 +
sys/kern/kern_context.pas | 1 +
sys/kern/kern_dmem.pas | 2 +-
sys/kern/kern_event.pas | 1 +
sys/kern/kern_exec.pas | 1 +
sys/kern/kern_ipmimgr.pas | 1 -
sys/kern/kern_jit.pas | 60 ++++---
sys/kern/kern_ksched.pas | 1 +
sys/kern/kern_proc.pas | 130 +++++++++++++++
sys/kern/kern_resource.pas | 1 +
sys/kern/kern_rtld.pas | 1 +
sys/kern/kern_rtprio.pas | 1 +
sys/kern/kern_sig.pas | 3 +-
sys/kern/kern_synch.pas | 5 +-
sys/kern/kern_sysctl.pas | 7 +-
sys/kern/kern_thr.pas | 135 +--------------
sys/kern/kern_thread.pas | 19 +++
sys/kern/machdep.pas | 4 +-
sys/kern/subr_dynlib.pas | 1 +
sys/kern/subr_sleepqueue.pas | 1 +
sys/kern/trap.pas | 104 ++++++++----
sys/kern/uipc_syscalls.pas | 1 -
sys/md/md_context.pas | 3 +-
sys/md/md_exception.pas | 115 +++++++++++--
sys/md/md_resource.pas | 1 +
sys/sys_mmap.pas | 2 +-
sys/sys_sysinit.pas | 1 +
sys/sys_umtx.pas | 3 +-
sys/test/debug.lpi | 64 ++++++++
sys/test/debug.lpr | 308 +++++++++++++++++++++++++++++++++++
sys/test/project1.lpi | 4 +
sys/test/project1.lpr | 2 +-
sys/vfs/kern_descrip.pas | 1 +
sys/vfs/vfs_syscalls.pas | 7 +-
sys/vfs/vnode_if.pas | 1 -
sys/vfs/vsys_generic.pas | 1 +
sys/vm/vm_fault.pas | 22 ++-
sys/vm/vm_map.pas | 3 +
sys/vm/vm_mmap.pas | 1 +
47 files changed, 893 insertions(+), 296 deletions(-)
create mode 100644 sys/kern/kern_proc.pas
create mode 100644 sys/test/debug.lpi
create mode 100644 sys/test/debug.lpr
diff --git a/kernel/libthr/thr_error.pas b/kernel/libthr/thr_error.pas
index 33b3f844..0d8b13d0 100644
--- a/kernel/libthr/thr_error.pas
+++ b/kernel/libthr/thr_error.pas
@@ -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;
diff --git a/rtl/ntapi.pas b/rtl/ntapi.pas
index 52572d95..5cd1b8ed 100644
--- a/rtl/ntapi.pas
+++ b/rtl/ntapi.pas
@@ -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;
diff --git a/rtl/x86_jit.pas b/rtl/x86_jit.pas
index 1428445c..42c083ea 100644
--- a/rtl/x86_jit.pas
+++ b/rtl/x86_jit.pas
@@ -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;
diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas
index 20928e12..5fee4fae 100644
--- a/sys/dev/dev_dce.pas
+++ b/sys/dev/dev_dce.pas
@@ -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);
diff --git a/sys/dev/dev_tty.pas b/sys/dev/dev_tty.pas
index e4144259..552dd372 100644
--- a/sys/dev/dev_tty.pas
+++ b/sys/dev/dev_tty.pas
@@ -22,8 +22,7 @@ uses
subr_uio,
vpoll,
vm,
- sys_event,
- kern_event;
+ sys_event;
var
dev_console:p_cdev;
diff --git a/sys/errno.pas b/sys/errno.pas
index baaf1d3d..fe8627e8 100644
--- a/sys/errno.pas
+++ b/sys/errno.pas
@@ -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.
diff --git a/sys/fs/devfs/devfs.pas b/sys/fs/devfs/devfs.pas
index 5b417ae7..fda71eed 100644
--- a/sys/fs/devfs/devfs.pas
+++ b/sys/fs/devfs/devfs.pas
@@ -235,7 +235,6 @@ procedure devfs_mtx_init;
implementation
uses
- devfs_devs,
devfs_vnops;
{
diff --git a/sys/fs/devfs/devfs_vnops.pas b/sys/fs/devfs/devfs_vnops.pas
index 8c5976c9..2828d556 100644
--- a/sys/fs/devfs/devfs_vnops.pas
+++ b/sys/fs/devfs/devfs_vnops.pas
@@ -207,6 +207,7 @@ uses
devfs_devs,
devfs_rule,
devfs_vfsops,
+ kern_proc,
kern_descrip,
kern_mtxpool,
subr_uio;
diff --git a/sys/fs/ufs/ufs_vnops.pas b/sys/fs/ufs/ufs_vnops.pas
index 4a168ea8..2c0c875b 100644
--- a/sys/fs/ufs/ufs_vnops.pas
+++ b/sys/fs/ufs/ufs_vnops.pas
@@ -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;
diff --git a/sys/kern/kern_context.pas b/sys/kern/kern_context.pas
index c0c69dbc..69ee79b3 100644
--- a/sys/kern/kern_context.pas
+++ b/sys/kern/kern_context.pas
@@ -23,6 +23,7 @@ uses
systm,
kern_thr,
kern_thread,
+ kern_proc,
signal,
kern_sig,
kern_synch,
diff --git a/sys/kern/kern_dmem.pas b/sys/kern/kern_dmem.pas
index c27357a5..d45808a5 100644
--- a/sys/kern/kern_dmem.pas
+++ b/sys/kern/kern_dmem.pas
@@ -95,7 +95,7 @@ uses
vm_map,
kern_authinfo,
kern_thr,
- trap;
+ kern_proc;
//////////
diff --git a/sys/kern/kern_event.pas b/sys/kern/kern_event.pas
index 2f45acb2..49d9d45e 100644
--- a/sys/kern/kern_event.pas
+++ b/sys/kern/kern_event.pas
@@ -119,6 +119,7 @@ uses
vfs_subr,
subr_hash,
vsys_generic,
+ kern_proc,
kern_callout,
kern_timeout;
diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas
index 99b95390..c5a1bb94 100644
--- a/sys/kern/kern_exec.pas
+++ b/sys/kern/kern_exec.pas
@@ -33,6 +33,7 @@ implementation
uses
systm,
errno,
+ kern_proc,
kern_mtx,
vm,
vmparam,
diff --git a/sys/kern/kern_ipmimgr.pas b/sys/kern/kern_ipmimgr.pas
index 782ad653..6d01d002 100644
--- a/sys/kern/kern_ipmimgr.pas
+++ b/sys/kern/kern_ipmimgr.pas
@@ -13,7 +13,6 @@ uses
errno,
systm,
trap,
- kern_thr,
kern_named_id;
type
diff --git a/sys/kern/kern_jit.pas b/sys/kern/kern_jit.pas
index fa1d70d6..219115e6 100644
--- a/sys/kern/kern_jit.pas
+++ b/sys/kern/kern_jit.pas
@@ -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)]);
diff --git a/sys/kern/kern_ksched.pas b/sys/kern/kern_ksched.pas
index b3b8baf5..17cc71ce 100644
--- a/sys/kern/kern_ksched.pas
+++ b/sys/kern/kern_ksched.pas
@@ -41,6 +41,7 @@ uses
systm,
kern_thr,
kern_rtprio,
+ kern_proc,
md_proc;
const
diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas
new file mode 100644
index 00000000..3594dba7
--- /dev/null
+++ b/sys/kern/kern_proc.pas
@@ -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.
+
diff --git a/sys/kern/kern_resource.pas b/sys/kern/kern_resource.pas
index b91fe018..1d654d5f 100644
--- a/sys/kern/kern_resource.pas
+++ b/sys/kern/kern_resource.pas
@@ -28,6 +28,7 @@ uses
errno,
systm,
kern_thr,
+ kern_proc,
md_proc,
md_resource;
diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas
index 3f2cf663..f8a0e6b5 100644
--- a/sys/kern/kern_rtld.pas
+++ b/sys/kern/kern_rtld.pas
@@ -214,6 +214,7 @@ uses
vm_map,
vm_mmap,
vm_pmap,
+ kern_proc,
kern_patcher;
function maxInt64(a,b:Int64):Int64; inline;
diff --git a/sys/kern/kern_rtprio.pas b/sys/kern/kern_rtprio.pas
index dc7d344d..db00e64f 100644
--- a/sys/kern/kern_rtprio.pas
+++ b/sys/kern/kern_rtprio.pas
@@ -20,6 +20,7 @@ implementation
uses
systm,
errno,
+ kern_proc,
kern_thread,
sched_ule,
md_proc;
diff --git a/sys/kern/kern_sig.pas b/sys/kern/kern_sig.pas
index beba1c96..594bfcb7 100644
--- a/sys/kern/kern_sig.pas
+++ b/sys/kern/kern_sig.pas
@@ -11,7 +11,8 @@ uses
time,
signal,
signalvar,
- kern_thr;
+ kern_thr,
+ kern_proc;
const
SA_KILL =$01; // terminates process by default
diff --git a/sys/kern/kern_synch.pas b/sys/kern/kern_synch.pas
index d185d258..c904fd1f 100644
--- a/sys/kern/kern_synch.pas
+++ b/sys/kern/kern_synch.pas
@@ -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;
diff --git a/sys/kern/kern_sysctl.pas b/sys/kern/kern_sysctl.pas
index 52e30083..219517c9 100644
--- a/sys/kern/kern_sysctl.pas
+++ b/sys/kern/kern_sysctl.pas
@@ -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);
diff --git a/sys/kern/kern_thr.pas b/sys/kern/kern_thr.pas
index 52b18300..e968edb9 100644
--- a/sys/kern/kern_thr.pas
+++ b/sys/kern/kern_thr.pas
@@ -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.
diff --git a/sys/kern/kern_thread.pas b/sys/kern/kern_thread.pas
index 10db62d7..b4fb8878 100644
--- a/sys/kern/kern_thread.pas
+++ b/sys/kern/kern_thread.pas
@@ -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;
diff --git a/sys/kern/machdep.pas b/sys/kern/machdep.pas
index c5a57907..44940085 100644
--- a/sys/kern/machdep.pas
+++ b/sys/kern/machdep.pas
@@ -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;
diff --git a/sys/kern/subr_dynlib.pas b/sys/kern/subr_dynlib.pas
index a0cdc5c2..aef50909 100644
--- a/sys/kern/subr_dynlib.pas
+++ b/sys/kern/subr_dynlib.pas
@@ -367,6 +367,7 @@ uses
vfs_lookup,
vfs_subr,
vnode_if,
+ kern_proc,
kern_reloc,
kern_namedobj,
elf_nid_utils;
diff --git a/sys/kern/subr_sleepqueue.pas b/sys/kern/subr_sleepqueue.pas
index ac3cbc26..cfb5eb5a 100644
--- a/sys/kern/subr_sleepqueue.pas
+++ b/sys/kern/subr_sleepqueue.pas
@@ -71,6 +71,7 @@ implementation
uses
errno,
signalvar,
+ kern_proc,
kern_thread,
kern_sig,
sched_ule,
diff --git a/sys/kern/trap.pas b/sys/kern/trap.pas
index 1c27f180..81619cd5 100644
--- a/sys/kern/trap.pas
+++ b/sys/kern/trap.pas
@@ -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
diff --git a/sys/kern/uipc_syscalls.pas b/sys/kern/uipc_syscalls.pas
index 679559b0..a895c2f0 100644
--- a/sys/kern/uipc_syscalls.pas
+++ b/sys/kern/uipc_syscalls.pas
@@ -12,7 +12,6 @@ function sys_socketclose(fd:Integer):Integer;
implementation
uses
- errno,
kern_thr,
kern_descrip,
kern_conf,
diff --git a/sys/md/md_context.pas b/sys/md/md_context.pas
index 65df04a4..d7d997b0 100644
--- a/sys/md/md_context.pas
+++ b/sys/md/md_context.pas
@@ -9,7 +9,8 @@ uses
Windows,
ntapi,
ucontext,
- kern_thr;
+ kern_thr,
+ kern_proc;
const
XSTATE_LEGACY_FLOATING_POINT=0;
diff --git a/sys/md/md_exception.pas b/sys/md/md_exception.pas
index 4880df43..bfcf3641 100644
--- a/sys/md/md_exception.pas
+++ b/sys/md/md_exception.pas
@@ -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;
diff --git a/sys/md/md_resource.pas b/sys/md/md_resource.pas
index 6a4b5b0a..c263fe79 100644
--- a/sys/md/md_resource.pas
+++ b/sys/md/md_resource.pas
@@ -19,6 +19,7 @@ uses
md_proc,
md_time,
kern_thr,
+ kern_proc,
vmparam,
vm_map;
diff --git a/sys/sys_mmap.pas b/sys/sys_mmap.pas
index 6bfd1ac5..09251b89 100644
--- a/sys/sys_mmap.pas
+++ b/sys/sys_mmap.pas
@@ -83,7 +83,7 @@ implementation
uses
syscalls,
- errno;
+ thr_error;
//sce
diff --git a/sys/sys_sysinit.pas b/sys/sys_sysinit.pas
index a783362b..3b2c46a5 100644
--- a/sys/sys_sysinit.pas
+++ b/sys/sys_sysinit.pas
@@ -16,6 +16,7 @@ uses
kern_sysctl,
kern_thr,
kern_thread,
+ kern_proc,
kern_sig,
kern_timeout,
kern_synch,
diff --git a/sys/sys_umtx.pas b/sys/sys_umtx.pas
index fefc03b6..272ff92d 100644
--- a/sys/sys_umtx.pas
+++ b/sys/sys_umtx.pas
@@ -26,8 +26,7 @@ uses
errno,
syscalls,
kern_umtx,
- trap,
- thr_error;
+ trap;
procedure umtx_init(var umtx:umtx); inline;
begin
diff --git a/sys/test/debug.lpi b/sys/test/debug.lpi
new file mode 100644
index 00000000..253be40d
--- /dev/null
+++ b/sys/test/debug.lpi
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
diff --git a/sys/test/debug.lpr b/sys/test/debug.lpr
new file mode 100644
index 00000000..829b7fbf
--- /dev/null
+++ b/sys/test/debug.lpr
@@ -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.
+
diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi
index eff1c22e..366c8310 100644
--- a/sys/test/project1.lpi
+++ b/sys/test/project1.lpi
@@ -734,6 +734,10 @@
+
+
+
+
diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr
index 75798323..b67d2199 100644
--- a/sys/test/project1.lpr
+++ b/sys/test/project1.lpr
@@ -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;
diff --git a/sys/vfs/kern_descrip.pas b/sys/vfs/kern_descrip.pas
index e59b01aa..7198fbdb 100644
--- a/sys/vfs/kern_descrip.pas
+++ b/sys/vfs/kern_descrip.pas
@@ -7,6 +7,7 @@ interface
uses
kern_thr,
+ kern_proc,
kern_id,
sys_event,
vfile,
diff --git a/sys/vfs/vfs_syscalls.pas b/sys/vfs/vfs_syscalls.pas
index 8b95e151..aa63a816 100644
--- a/sys/vfs/vfs_syscalls.pas
+++ b/sys/vfs/vfs_syscalls.pas
@@ -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;
diff --git a/sys/vfs/vnode_if.pas b/sys/vfs/vnode_if.pas
index f9777175..9bc2b878 100644
--- a/sys/vfs/vnode_if.pas
+++ b/sys/vfs/vnode_if.pas
@@ -950,7 +950,6 @@ const
implementation
uses
- errno,
vfs_subr;
function get_vp_cb(vp:p_vnode;offset:Pointer):Pointer; inline;
diff --git a/sys/vfs/vsys_generic.pas b/sys/vfs/vsys_generic.pas
index b0e50bcf..9a8b7afe 100644
--- a/sys/vfs/vsys_generic.pas
+++ b/sys/vfs/vsys_generic.pas
@@ -113,6 +113,7 @@ uses
subr_uio,
kern_sig,
kern_thread,
+ kern_proc,
md_time,
sys_capability;
diff --git a/sys/vm/vm_fault.pas b/sys/vm/vm_fault.pas
index 8a3f72e3..8e71997e 100644
--- a/sys/vm/vm_fault.pas
+++ b/sys/vm/vm_fault.pas
@@ -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));
diff --git a/sys/vm/vm_map.pas b/sys/vm/vm_map.pas
index 8698a890..117af17c 100644
--- a/sys/vm/vm_map.pas
+++ b/sys/vm/vm_map.pas
@@ -258,6 +258,9 @@ procedure vminit; //SYSINIT
implementation
+uses
+ kern_proc;
+
var
sgrowsiz:QWORD=vmparam.SGROWSIZ;
stack_guard_page:Integer=0;
diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas
index bbeb91ef..71f037d7 100644
--- a/sys/vm/vm_mmap.pas
+++ b/sys/vm/vm_mmap.pas
@@ -52,6 +52,7 @@ uses
systm,
errno,
kern_thr,
+ kern_proc,
vmparam,
_resource,
kern_resource,