This commit is contained in:
Pavel 2024-05-20 09:48:55 +03:00
parent 37c7eedace
commit 11c35d1671
11 changed files with 153 additions and 46 deletions

View File

@ -1009,6 +1009,22 @@
<Filename Value="rtl\renderdoc.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="vulkan\vRender.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="vulkan\vCmdBuffer.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="ps4libdoc.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="vulkan\vSetsPoolManager.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -157,7 +157,7 @@ const
INITIAL_MXCSR =$1f80;
CONTEXT_THREAD =CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS;
CONTEXT_THREAD =CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS or CONTEXT_FLOATING_POINT;
ViewShare=1;
ViewUnmap=2;

View File

@ -328,6 +328,8 @@ type
function leaj(reg:TRegValue;mem:t_jit_leas;_label_id:t_jit_i_link):t_jit_i_link;
function leap(reg:TRegValue):t_jit_i_link;
//
Procedure jmp(reg:TRegValue);
Procedure call(reg:TRegValue);
Procedure reta;
Procedure ud2;
//
@ -1502,6 +1504,24 @@ begin
LinkLabel(Result.ALink);
end;
Procedure t_jit_builder.jmp(reg:TRegValue);
const
desc:t_op_type=(op:$FF;index:4);
begin
Assert(is_reg_size(reg,[os64]));
_R(desc,reg);
end;
Procedure t_jit_builder.call(reg:TRegValue);
const
desc:t_op_type=(op:$FF;index:2);
begin
Assert(is_reg_size(reg,[os64]));
_R(desc,reg);
end;
Procedure t_jit_builder.reta;
begin
_O($C3);

View File

@ -265,7 +265,8 @@ begin
with ctx.builder do
begin
leap(r15);
call_far(@jit_plt_cache); //input:r14,r15
call_far(@jit_jmp_plt_cache); //input:r14,r15 out:r14
jmp(r14);
end;
end;
@ -274,7 +275,8 @@ begin
with ctx.builder do
begin
leap(r15);
call_far(@jit_plt_cache); //input:r14,r15
call_far(@jit_jmp_plt_cache); //input:r14,r15 out:r14
jmp(r14);
end;
end;
@ -826,7 +828,7 @@ begin
with ctx.builder do
begin
stack:=r_tmp0;
new :=r_tmp0;
new :=r_tmp1;
op_load_rbp(ctx,stack);
@ -860,7 +862,7 @@ begin
begin
stack:=r_tmp0;
new:=new_reg_size(r_tmp0,ctx.din.Operand[1]);
new:=new_reg_size(r_tmp1,ctx.din.Operand[1]);
mem_size:=ctx.din.Operand[1].Size;
@ -884,6 +886,7 @@ end;
procedure op_pop(var ctx:t_jit_context2);
var
new,stack:TRegValue;
reload_rsp:Boolean;
begin
//mov reg,[rsp]
//lea rsp,[rsp+len]
@ -896,21 +899,25 @@ begin
op_uplift(ctx,os64); //in/out:r14
reload_rsp:=False;
if is_memory(ctx.din) then
begin
new:=new_reg_size(r_tmp1,ctx.din.Operand[1]);
movq(new,[stack]);
build_lea(ctx,1,r_tmp0);
build_lea(ctx,1,stack,[not_use_r_tmp1]);
op_uplift(ctx,os64,[not_use_r_tmp1]); //in/out:r14
movq([r_tmp0],new);
movq([stack],new);
reload_rsp:=True;
end else
if is_preserved(ctx.din) then
begin
new:=new_reg_size(r_tmp0,ctx.din.Operand[1]);
new:=new_reg_size(r_tmp1,ctx.din.Operand[1]);
movq(new,[stack]);
@ -925,7 +932,10 @@ begin
//For transactionality,
//first we move the memory,
//then we update the register
op_load_rsp(ctx,stack);
if reload_rsp then
begin
op_load_rsp(ctx,stack);
end;
leaq(stack,[stack+OPERAND_BYTES[new.ASize]]);
op_save_rsp(ctx,stack);
end;

View File

@ -49,7 +49,7 @@ type
end;
procedure jit_syscall; assembler;
procedure jit_plt_cache; assembler;
procedure jit_jmp_plt_cache; assembler;
procedure jit_jmp_dispatch; assembler;
procedure jit_jmp_internal; assembler;
@ -416,8 +416,8 @@ asm
//tf_r15=tf_r15
end;
//in:r14(addr) r15(plt)
procedure jit_plt_cache; assembler; nostackframe;
//in:r14(addr) r15(plt) out:r14(addr)
procedure jit_jmp_plt_cache; assembler; nostackframe;
label
_exit;
asm
@ -440,13 +440,11 @@ asm
popf
//pop internal
lea 8(%rsp),%rsp
//restore rbp
movq %rsp,%rbp
leaq 8(%rbp),%rbp
jmp %r14
ret
_exit:
@ -459,7 +457,7 @@ asm
jmp jit_jmp_dispatch
end;
//in:r14(addr) r15(plt)
//in:r14(addr) r15(plt) out:r14(addr)
procedure jit_jmp_dispatch; assembler; nostackframe;
asm
//prolog (debugger)
@ -484,10 +482,6 @@ asm
//epilog
movq %rbp,%rsp
pop %rbp
//pop internal
lea 8(%rsp),%rsp
jmp %r14
end;
procedure stack_set_user; assembler; nostackframe;
@ -529,9 +523,6 @@ end;
procedure jit_jmp_internal; assembler; nostackframe;
asm
//push internal call
lea -8(%rsp),%rsp
//prolog (debugger)
push %rbp
movq %rsp,%rbp
@ -608,8 +599,8 @@ begin
(rip<=(QWORD(@jit_jmp_dispatch)+$2C)) //jit_jmp_dispatch func size
) or
(
(rip>=QWORD(@jit_plt_cache)) and
(rip<=(QWORD(@jit_plt_cache)+$33)) //jit_plt_cache func size
(rip>=QWORD(@jit_jmp_plt_cache)) and
(rip<=(QWORD(@jit_jmp_plt_cache)+$33)) //jit_jmp_plt_cache func size
);
end;

View File

@ -252,17 +252,38 @@ var
node:p_jit_entry_point;
jctx:p_td_jctx;
frame:p_jit_frame;
//jit_state:Boolean;
begin
if (td=nil) then Exit;
//jit_state:=((td^.pcb_flags and PCB_IS_JIT)<>0);
if not is_guest_addr(td^.td_frame.tf_rip) then
if is_guest_addr(td^.td_frame.tf_rip) then
begin
//clear jit flag
td^.pcb_flags:=td^.pcb_flags and (not PCB_IS_JIT);
Exit; //internal?
//host->jit
//jit->jit
end else
begin
if ((td^.pcb_flags and PCB_IS_JIT)<>0) then
begin
//jit->host
if ((td^.td_pflags and TDP_KTHREAD)<>0) then
begin
//clear jit flag
td^.pcb_flags:=td^.pcb_flags and (not PCB_IS_JIT);
Exit; //internal?
end else
begin
//forbidden
Assert(false,'forbidden jump to 0x'+HexStr(td^.td_frame.tf_rip,16));
end;
end else
begin
//host->host
Exit; //internal?
end;
end;
_start:

View File

@ -1813,7 +1813,7 @@ begin
if (Result=0) then
begin
jit_prepare(0);
jit_prepare(curkthread,0);
ipi_sigreturn;
Writeln(stderr,'I''m a teapot!');
end;

View File

@ -353,10 +353,19 @@ begin
}
end;
const
p__INITIAL_FPUCW__:Word =__INITIAL_FPUCW__;
p__INITIAL_MXCSR__:DWord=__INITIAL_MXCSR__;
procedure before_start(td:p_kthread);
begin
InitThread(td^.td_ustack.stack-td^.td_ustack.sttop);
asm
fldcw p__INITIAL_FPUCW__(%rip)
ldmxcsr p__INITIAL_MXCSR__(%rip)
end;
if (init_tty_cb<>nil) then
begin
init_tty_cb();
@ -373,6 +382,11 @@ type
begin
InitThread(td^.td_ustack.stack-td^.td_ustack.sttop);
asm
fldcw p__INITIAL_FPUCW__(%rip)
ldmxcsr p__INITIAL_MXCSR__(%rip)
end;
if (init_tty_cb<>nil) then
begin
init_tty_cb();
@ -549,6 +563,9 @@ begin
// Setup user TLS address and TLS pointer register.
cpu_set_fsbase(newtd,tls_base);
Writeln('set_fsbase=0x',HexStr(tls_base));
//
fpuinit(@newtd^.td_fpstate);
newtd^.td_frame.tf_flags:=newtd^.td_frame.tf_flags or TF_HASFPXSTATE;
end;
//jit wrapper
@ -656,6 +673,9 @@ begin
cpu_set_upcall_kse(newtd,func,arg,@stack);
fpuinit(@newtd^.td_fpstate);
newtd^.td_frame.tf_flags:=newtd^.td_frame.tf_flags or TF_HASFPXSTATE;
//jit wrapper
switch_to_jit(newtd);
//jit wrapper

View File

@ -97,7 +97,7 @@ procedure sig_unlock;
procedure fast_syscall;
procedure amd64_syscall;
procedure jit_prepare(rip:QWORD);
procedure jit_prepare(td:p_kthread;rip:QWORD);
procedure host_sigcode;
procedure host_sigipi;
@ -324,15 +324,13 @@ begin
cpu_set_syscall_retval(td,error);
jit_prepare(rip);
jit_prepare(td,rip);
end;
procedure jit_prepare(rip:QWORD);
procedure jit_prepare(td:p_kthread;rip:QWORD);
var
td:p_kthread;
is_jit:Boolean;
begin
td:=curkthread;
if (td=nil) then Exit;
is_jit:=((td^.pcb_flags and PCB_IS_JIT)<>0);

View File

@ -74,6 +74,16 @@ type
_align:QWORD;
end;
const
_ucodesel=(8 shl 3) or 3;
_udatasel=(7 shl 3) or 3;
_ufssel =(2 shl 3) or 3;
_ugssel =(3 shl 3) or 3;
__INITIAL_FPUCW__ =$037F;
__INITIAL_MXCSR__ =$1F80;
__INITIAL_MXCSR_MASK__=$FFBF;
procedure teb_set_kernel(td:p_kthread);
procedure teb_set_user (td:p_kthread);
@ -85,6 +95,8 @@ function _get_ctx_flags(src:p_ucontext_t):DWORD;
procedure _get_fpcontext(src:PCONTEXT;xstate:Pointer);
procedure _set_fpcontext(dst:PCONTEXT;xstate:Pointer);
procedure fpuinit(xstate:Pointer);
procedure _get_frame(src:PCONTEXT;dst:p_trapframe;xstate:Pointer;is_jit:Boolean);
procedure _set_frame(dst:PCONTEXT;src:p_trapframe;xstate:Pointer;is_jit:Boolean);
@ -137,12 +149,6 @@ begin
//teb stack
end;
const
_ucodesel=(8 shl 3) or 3;
_udatasel=(7 shl 3) or 3;
_ufssel =(2 shl 3) or 3;
_ugssel =(3 shl 3) or 3;
function GetEnabledXStateFeatures:QWORD; stdcall external 'kernel32';
function InitializeContext(
@ -271,6 +277,25 @@ begin
xs^:=uc_xstate^;
end;
procedure fpuinit(xstate:Pointer);
var
uc_xsave :PXmmSaveArea;
uc_xstate:PXSTATE;
begin
if (xstate=nil) then Exit;
uc_xsave :=PXmmSaveArea(xstate);
uc_xstate:=PXSTATE(uc_xsave+1);
//uc_xstate^.Mask:=
//uc_xstate^.CompactionMask:=
uc_xsave^.ControlWord:=__INITIAL_FPUCW__;
//uc_xsave^.StatusWord: WORD;
uc_xsave^.MxCsr :=__INITIAL_MXCSR__;
uc_xsave^.MxCsr_Mask :=__INITIAL_MXCSR_MASK__;
end;
procedure _get_frame(src:PCONTEXT;dst:p_trapframe;xstate:Pointer;is_jit:Boolean);
var
flags:DWORD;

View File

@ -45,6 +45,7 @@ procedure seh_wrapper_after (td:p_kthread;func:Pointer);
implementation
uses
md_context,
vmparam;
//
@ -194,7 +195,12 @@ begin
Context^.EFlags:=$3000 or EFLAGS_INTERRUPT_MASK;
Context^.MxCsr:=INITIAL_MXCSR;
Context^.MxCsr:=__INITIAL_MXCSR__;
Context^.FltSave.ControlWord:=__INITIAL_FPUCW__;
//Context^.FltSave.StatusWord: WORD;
Context^.FltSave.MxCsr :=__INITIAL_MXCSR__;
Context^.FltSave.MxCsr_Mask :=__INITIAL_MXCSR_MASK__;
Context^.ContextFlags:=CONTEXT_THREAD;
end;