diff --git a/rtl/x86_jit.pas b/rtl/x86_jit.pas index d09c153c..33001683 100644 --- a/rtl/x86_jit.pas +++ b/rtl/x86_jit.pas @@ -14,12 +14,15 @@ uses x86_fpdbgdisas; type + t_jit_flags=Set Of (sES,sCS,sSS,sDS,sFS,sGS,sLOCK); + t_jit_lea=packed object ARegValue:TRegValues; AOffset :Int64; AMemSize :TOperandSize; - ASegment :Byte; - ALock :Boolean; + AFlags :t_jit_flags; + function ASegment:t_jit_flags; inline; + function ALock:Boolean; inline; end; t_vw_mode=(vwZero,vwOne,vwR64,vwM64); @@ -63,7 +66,7 @@ type procedure EmitWord(w:Word); inline; procedure EmitInt32(i:Integer); inline; procedure EmitInt64(i:Int64); inline; - procedure EmitSelector(Segment:ShortInt); inline; + procedure EmitSelector(Segments:t_jit_flags); inline; procedure EmitREX(rexB,rexX,rexR,rexW:Boolean); inline; procedure EmitModRM(Mode,Index,RM:Byte); inline; procedure EmitSIB(Scale,Index,Base:Byte); inline; @@ -161,9 +164,9 @@ type p_jit_builder=^t_jit_builder; t_jit_builder=object Const - LOCK:t_jit_lea=(ARegValue:((AType:regNone),(AType:regNone));ALock:True); - FS :t_jit_lea=(ARegValue:((AType:regNone),(AType:regNone));ASegment:4); - GS :t_jit_lea=(ARegValue:((AType:regNone),(AType:regNone));ASegment:5); + LOCK:t_jit_lea=(AFlags:[sLOCK]); + FS :t_jit_lea=(AFlags:[sFS]); + GS :t_jit_lea=(AFlags:[sGS]); ah :TRegValue=(AType:regGeneralH;ASize:os8;AIndex:0); ch :TRegValue=(AType:regGeneralH;ASize:os8;AIndex:1); @@ -474,6 +477,18 @@ function classif_offset_se64(AOffset:Int64):TOperandSize; implementation +function t_jit_lea.ASegment:t_jit_flags; inline; +begin + Result:=AFlags-[sLOCK]; +end; + +function t_jit_lea.ALock:Boolean; inline; +begin + Result:=sLOCK in AFlags; +end; + +/// + function t_jit_data.c(n1,n2:p_jit_data):Integer; begin Result:=Integer(n1^.pData>n2^.pData)-Integer(n1^.pDataos0) then begin if (B.AMemSize<>os0) then @@ -662,7 +656,7 @@ begin Result.AMemSize:=B.AMemSize; end; - Result.ALock:=Result.ALock or B.ALock; + Result.AFlags:=Result.AFlags+B.AFlags; Result.AOffset:=Result.AOffset+B.AOffset; end; @@ -1011,13 +1005,14 @@ begin Inc(ASize,SizeOf(Int64)); end; -procedure t_jit_instruction.EmitSelector(Segment:ShortInt); inline; +procedure t_jit_instruction.EmitSelector(Segments:t_jit_flags); inline; begin - case Segment of //Selector - 4:EmitByte($64); //fs - 5:EmitByte($65); //gs - else; - end; + if (sES in Segments) then EmitByte($26); + if (sCS in Segments) then EmitByte($2E); + if (sSS in Segments) then EmitByte($36); + if (sDS in Segments) then EmitByte($3E); + if (sFS in Segments) then EmitByte($64); + if (sGS in Segments) then EmitByte($65); end; procedure t_jit_instruction.EmitREX(rexB,rexX,rexR,rexW:Boolean); inline; diff --git a/sys/jit/kern_jit.pas b/sys/jit/kern_jit.pas index 9232f13d..a3ab66e7 100644 --- a/sys/jit/kern_jit.pas +++ b/sys/jit/kern_jit.pas @@ -1094,6 +1094,53 @@ begin end; end; +//rdi -> addr +//rsi -> rdi +//rdx -> rsi +//rcx -> rdx +//r8 -> rcx +//r9 -> r8 + +procedure ExecuteGuest; SysV_ABI_CDecl; assembler; nostackframe; public; +asm + //save r13 + movq %r13,%gs:teb.jitcall + + //load curkthread,jit_ctx + movq %gs:teb.thread,%r13 + leaq jit_frame_offset(%r13),%r13 + + //load r14,r15 + movq %r14,jit_frame.tf_r14(%r13) + movq %r15,jit_frame.tf_r15(%r13) + + //load r13 + movq %gs:teb.jitcall,%r14 + movq %r14,jit_frame.tf_r13(%r13) + + //alloc rbp,rsp + + //load addr + movq %rdi,%r14 + + //move params + movq %rsi,%rdi + movq %rdx,%rsi + movq %rcx,%rdx + movq %r8 ,%rcx + movq %r9 ,%r8 + + //call + call %r14 + + //restore rbp,rsp + + //load r14,r15,r13 + movq jit_frame.tf_r14(%r13),%r14 + movq jit_frame.tf_r15(%r13),%r15 + movq jit_frame.tf_r13(%r13),%r13 +end; + procedure op_native2jit(var ctx:t_jit_context2;pcb,switch_stack:Boolean); begin with ctx.builder do