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 @@ + + + + + + + + + + + + + + <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> 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 @@ <Filename Value="..\dev\dev_dce.pas"/> <IsPartOfProject Value="True"/> </Unit> + <Unit> + <Filename Value="..\kern\kern_proc.pas"/> + <IsPartOfProject Value="True"/> + </Unit> </Units> </ProjectOptions> <CompilerOptions> 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,