This commit is contained in:
Pavel 2023-08-14 20:11:44 +03:00
parent d3a950262a
commit 256ff078d0
9 changed files with 5539 additions and 5 deletions

5275
rtl/x86_fpdbgdisas.pp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,13 @@ begin
begin
kern_sigprocmask(td, SIG_SETMASK, @uc.uc_sigmask, nil, 0);
end;
//teb wow64
if ((uc.uc_flags and 2)<>0) then
begin
td^.td_teb^.wow64:=Pointer(uc.__spare[0]);
end;
//teb wow64
end;
if (Result=0) then Exit(EJUSTRETURN);
@ -111,6 +118,13 @@ begin
begin
kern_sigprocmask(td, SIG_SETMASK, @uc.uc_sigmask, nil, 0);
end;
//teb wow64
if ((uc.uc_flags and 2)<>0) then
begin
td^.td_teb^.wow64:=Pointer(uc.__spare[0]);
end;
//teb wow64
end;
end;

View File

@ -1101,7 +1101,15 @@ begin
memsz:=vaddr_hi-vaddr_lo;
cache:=ReAllocMem(cache,memsz);
FillChar(cache^,memsz,0);
if ((prot and VM_PROT_EXECUTE)<>0) then
begin
FillChar(cache^,memsz,$90);
end else
begin
FillChar(cache^,memsz,0);
end;
Move(base^,cache^,filesz);
if ((prot and VM_PROT_EXECUTE)<>0) then

View File

@ -521,6 +521,13 @@ begin
end;
//xmm,ymm
//teb wow64
if ((uc.uc_flags and 2)<>0) then
begin
td^.td_teb^.wow64:=Pointer(uc.__spare[0]);
end;
//teb wow64
bmove(@ucp^.uc_mcontext.mc_rdi,regs,sizeof(trapframe));
if ((ucp^.uc_mcontext.mc_flags and _MC_HASBASES)<>0) then

View File

@ -35,6 +35,9 @@ const
T_RESERVED =30; // reserved (unknown)
T_DTRACE_RET=32; // DTrace pid return
T_CONTINUE=33;
T_SET_CTX =34;
// XXX most of the following codes aren't used, but could be.
// definitions for <sys/signal.h>
@ -116,6 +119,8 @@ procedure fast_syscall;
procedure sigcode;
procedure sigipi;
procedure trap(frame:p_trapframe);
implementation
uses
@ -129,8 +134,7 @@ uses
subr_dynlib,
elf_nid_utils,
ps4libdoc,
kern_rtld,
hamt;
x86_fpdbgdisas;
const
NOT_PCB_FULL_IRET=not PCB_FULL_IRET;
@ -734,7 +738,7 @@ end;
procedure sigcode; assembler; nostackframe;
asm
call sigframe.sf_ahu(%rsp)
lea sigframe.sf_uc(%rsp),%rdi
lea sigframe.sf_uc (%rsp),%rdi
pushq $0
movqq sys_sigreturn,%rax
call fast_syscall
@ -764,6 +768,57 @@ asm
hlt
end;
procedure parse_instr(tf_rip:Pointer);
var
err:Integer;
data:array[0..15] of Byte;
dec:TX86AsmDecoder;
ptr:Pointer;
AProcess: TDbgProcess;
dis:TX86Disassembler;
din:TInstruction;
str1,str2:RawByteString;
begin
err:=copyin(tf_rip,@data,SizeOf(data));
if (err<>0) then Exit;
dis:=Default(TX86Disassembler);
din:=Default(TInstruction);
ptr:=@data;
AProcess:=TDbgProcess.Create;
AProcess.Mode:=dm64;
dec:=TX86AsmDecoder.Create(AProcess);
dec.Disassemble(ptr,str1,str2);
ptr:=@data;
dis.Disassemble(dm64,ptr,din);
end;
procedure trap(frame:p_trapframe);
begin
case frame^.tf_trapno of
T_PAGEFLT:
begin
parse_instr(Pointer(frame^.tf_rip));
print_backtrace_c(stderr);
writeln;
end;
end;
end;
end.

View File

@ -630,6 +630,11 @@ begin
sf.sf_uc.uc_mcontext.mc_ownedfp :=_MC_FPOWNED_FPU;
//xmm,ymm
//teb wow64
sf.sf_uc.uc_flags :=2;
sf.sf_uc.__spare[0]:=QWORD(td^.td_teb^.wow64);
//teb wow64
sp:=QWORD(td^.td_kstack.stack);
sp:=sp-sizeof(sigframe);
@ -666,6 +671,10 @@ begin
end;
//teb stack
//teb wow64
td^.td_teb^.wow64:=nil;
//teb wow64
resume:
NtResumeThread(td_handle,nil);
PROC_UNLOCK;

165
sys/md/md_trap.pas Normal file
View File

@ -0,0 +1,165 @@
unit md_trap;
{$mode objfpc}{$H+}
interface
implementation
uses
Windows,
ntapi,
machdep,
md_context,
//SysConst,
//SysUtils,
kern_thr,
trap,
signal,
ucontext,
vmparam;
function AddVectoredExceptionHandler(FirstHandler: DWORD; VectoredHandler: pointer): pointer; stdcall;
external 'kernel32.dll' name 'AddVectoredExceptionHandler';
function RemoveVectoredExceptionHandler(VectoredHandlerHandle: pointer): ULONG; stdcall;
external 'kernel32.dll' name 'RemoveVectoredExceptionHandler';
function GetModuleHandleEx(dwFlags: DWORD; lpModuleName: pointer; var hModule: THandle): BOOL; stdcall;
external 'kernel32.dll' name 'GetModuleHandleExA';
function RunErrorCode(const rec: TExceptionRecord): longint;
begin
{ negative result means 'FPU reset required' }
case rec.ExceptionCode of
STATUS_INTEGER_DIVIDE_BY_ZERO: result := 200; { reDivByZero }
STATUS_FLOAT_DIVIDE_BY_ZERO: result := -208; { !!reZeroDivide }
STATUS_ARRAY_BOUNDS_EXCEEDED: result := 201; { reRangeError }
STATUS_STACK_OVERFLOW: result := 202; { reStackOverflow }
STATUS_FLOAT_OVERFLOW: result := -205; { reOverflow }
STATUS_FLOAT_DENORMAL_OPERAND,
STATUS_FLOAT_UNDERFLOW: result := -206; { reUnderflow }
STATUS_FLOAT_INEXACT_RESULT,
STATUS_FLOAT_INVALID_OPERATION,
STATUS_FLOAT_STACK_CHECK: result := -207; { reInvalidOp }
STATUS_INTEGER_OVERFLOW: result := 215; { reIntOverflow }
STATUS_ILLEGAL_INSTRUCTION: result := -216;
STATUS_ACCESS_VIOLATION: result := 216; { reAccessViolation }
STATUS_CONTROL_C_EXIT: result := 217; { reControlBreak }
STATUS_PRIVILEGED_INSTRUCTION: result := 218; { rePrivilegedInstruction }
STATUS_FLOAT_MULTIPLE_TRAPS,
STATUS_FLOAT_MULTIPLE_FAULTS: result := -255; { indicate FPU reset }
else
result := 255; { reExternalException }
end;
end;
procedure TranslateMxcsr(mxcsr: longword; var code: longint);
begin
{ we can return only one value, further one's are lost }
{ InvalidOp }
if (mxcsr and 1)<>0 then
code:=-207
{ Denormal }
else if (mxcsr and 2)<>0 then
code:=-206
{ !!reZeroDivide }
else if (mxcsr and 4)<>0 then
code:=-208
{ reOverflow }
else if (mxcsr and 8)<>0 then
code:=-205
{ Underflow }
else if (mxcsr and 16)<>0 then
code:=-206
{ Precision }
else if (mxcsr and 32)<>0 then
code:=-207
else { this should not happen }
code:=-255
end;
function RunErrorCodex64(const rec: TExceptionRecord; const context: TContext): Longint;
begin
Result:=RunErrorCode(rec);
if (Result=-255) then
TranslateMxcsr(context.MxCsr,result);
end;
const
FPC_EXCEPTION_CODE=$E0465043;
function ProcessException(p:PExceptionPointers):longint; stdcall;
var
ExceptionCode:DWORD;
td:p_kthread;
tf_addr:QWORD;
uc:ucontext_t;
begin
Result:=EXCEPTION_CONTINUE_SEARCH;
td:=curkthread;
if (td=nil) then Exit;
if not is_guest_addr(QWORD(p^.ExceptionRecord^.ExceptionAddress)) then Exit;
td^.td_frame.tf_trapno:=0;
ExceptionCode:=p^.ExceptionRecord^.ExceptionCode;
case ExceptionCode of
FPC_EXCEPTION_CODE:;
STATUS_ACCESS_VIOLATION:
begin
tf_addr:=p^.ExceptionRecord^.ExceptionInformation[1];
uc:=Default(ucontext_t);
_get_ucontext(p^.ContextRecord,@uc);
set_mcontext(td, @uc.uc_mcontext);
td^.td_frame.tf_trapno:=T_PAGEFLT;
td^.td_frame.tf_addr :=tf_addr;
trap.trap(@td^.td_frame);
end;
else;
end;
case td^.td_frame.tf_trapno of
T_CONTINUE:Exit(EXCEPTION_CONTINUE_EXECUTION);
T_SET_CTX :
begin
get_mcontext(td, @uc.uc_mcontext, TF_HASFPXSTATE);
_set_ucontext(p^.ContextRecord,@uc);
Exit(EXCEPTION_CONTINUE_EXECUTION);
end
else;
end;
end;
var
VEHandler:pointer=nil;
procedure InstallExceptionHandler;
begin
//SetUnhandledExceptionFilter
VEHandler:=AddVectoredExceptionHandler(1,@ProcessException);
end;
procedure UninstallExceptionHandler;
begin
if Assigned(VEHandler) then
begin
RemoveVectoredExceptionHandler(VEHandler);
VEHandler:=nil;
end;
end;
initialization
InstallExceptionHandler;
finalization
UninstallExceptionHandler;
end.

View File

@ -102,6 +102,7 @@ uses
uipc_syscalls,
kern_ipmimgr,
kern_mdbg,
md_trap,
ps4_libSceSystemService,
ps4_libSceIpmi,
ps4_libSceDialogs;

View File

@ -109,7 +109,7 @@ var
i:Integer;
begin
Result:=False;
For i:=0 to High(pmap_mem) do
For i:=0 to High(pmap_mem)-1 do //exclude ext GPU_ADDRESS
begin
if (addr>=pmap_mem[i].start) and (addr<pmap_mem[i].__end) then
begin