mirror of https://github.com/red-prig/fpPS4.git
406 lines
7.6 KiB
Plaintext
406 lines
7.6 KiB
Plaintext
unit kern_mdbg;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
function sys_mdbg_service(op:Integer;arg1,arg2:Pointer):Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
sysutils,
|
|
errno,
|
|
systm,
|
|
kern_mtx,
|
|
kern_condvar,
|
|
kern_thr,
|
|
kern_proc,
|
|
subr_backtrace;
|
|
|
|
type
|
|
t_SetProcessProperty=packed record //0x48
|
|
f_0:QWORD;
|
|
f_1:QWORD;
|
|
f_2:QWORD;
|
|
f_3:QWORD;
|
|
f_4:QWORD;
|
|
name:array[0..31] of AnsiChar;
|
|
end;
|
|
|
|
t_coredump_ret=packed record //0x28
|
|
ret :Integer;
|
|
flags:Integer;
|
|
data :array[0..3] of QWORD;
|
|
end;
|
|
|
|
t_pevt_state=(pevt_none,pevt_inited,pevt_wait,pevt_finish);
|
|
|
|
p_mdbg_pevt=^t_mdbg_pevt;
|
|
t_mdbg_pevt=record
|
|
cv :t_cv;
|
|
mtx:mtx;
|
|
|
|
td_tid :Integer;
|
|
td_cancel :Integer;
|
|
td_ret :Integer;
|
|
td_flags :Integer;
|
|
td_state :t_pevt_state;
|
|
crash_state:Integer;
|
|
|
|
//
|
|
Sce:record
|
|
Flags :QWORD;
|
|
PSM_AppName :array[0..3] of QWORD;
|
|
PSM_SdbInfo :array[0..1] of QWORD;
|
|
PSM_LogArea :array[0..3] of QWORD;
|
|
Debug_UserObjArray:array[0..1] of QWORD;
|
|
Debug_Gnm :array[0..1] of QWORD;
|
|
end;
|
|
//
|
|
|
|
end;
|
|
|
|
var
|
|
g_mdbg_pevt:p_mdbg_pevt=nil;
|
|
|
|
function init_mdbg_pevt:p_mdbg_pevt;
|
|
var
|
|
props:p_mdbg_pevt;
|
|
begin
|
|
mtx_lock(p_proc.p_mtx);
|
|
|
|
props:=g_mdbg_pevt;
|
|
|
|
if (props<>nil) then
|
|
begin
|
|
mtx_unlock(p_proc.p_mtx);
|
|
Exit(props);
|
|
end;
|
|
|
|
props:=AllocMem(SizeOf(t_mdbg_pevt));
|
|
|
|
mtx_init(props^.mtx,'mdbg_pevt_MTX');
|
|
cv_init (@props^.cv,'mDBG Debug event');
|
|
|
|
props^.td_state:=pevt_inited;
|
|
|
|
g_mdbg_pevt:=props;
|
|
|
|
mtx_unlock(p_proc.p_mtx);
|
|
|
|
Writeln('init_mdbg_pevt');
|
|
|
|
Exit(props);
|
|
end;
|
|
|
|
function SetProcessProperty(arg1:Pointer):Integer;
|
|
var
|
|
data :t_SetProcessProperty;
|
|
props:p_mdbg_pevt;
|
|
begin
|
|
Result:=copyin(arg1,@data,SizeOf(t_SetProcessProperty));
|
|
if (Result<>0) then Exit;
|
|
|
|
props:=init_mdbg_pevt;
|
|
|
|
Result:=0;
|
|
|
|
mtx_lock(p_proc.p_mtx);
|
|
|
|
case String(data.name) of
|
|
'Sce.PSM:AppName': //1
|
|
begin
|
|
props^.Sce.Flags :=props^.Sce.Flags or $02;
|
|
props^.Sce.PSM_AppName[0]:=data.f_1;
|
|
props^.Sce.PSM_AppName[1]:=data.f_2;
|
|
props^.Sce.PSM_AppName[2]:=data.f_3;
|
|
props^.Sce.PSM_AppName[3]:=data.f_4;
|
|
end;
|
|
'Sce.PSM:SdbInfo': //2
|
|
begin
|
|
props^.Sce.Flags :=props^.Sce.Flags or $04;
|
|
props^.Sce.PSM_SdbInfo[0]:=data.f_1;
|
|
props^.Sce.PSM_SdbInfo[1]:=data.f_2;
|
|
end;
|
|
'Sce.PSM:LogArea': //3
|
|
begin
|
|
props^.Sce.Flags :=props^.Sce.Flags or $08;
|
|
props^.Sce.PSM_LogArea[0]:=data.f_1;
|
|
props^.Sce.PSM_LogArea[1]:=data.f_2;
|
|
props^.Sce.PSM_LogArea[2]:=data.f_3;
|
|
props^.Sce.PSM_LogArea[3]:=data.f_4;
|
|
end;
|
|
'Sce.Debug:UserObjArray': //4
|
|
begin
|
|
props^.Sce.Flags :=props^.Sce.Flags or $10;
|
|
props^.Sce.Debug_UserObjArray[0]:=data.f_1;
|
|
props^.Sce.Debug_UserObjArray[1]:=data.f_2;
|
|
end;
|
|
'Sce.Debug:Gnm': //5
|
|
begin
|
|
props^.Sce.Flags :=props^.Sce.Flags or $20;
|
|
props^.Sce.Debug_Gnm[0]:=data.f_1;
|
|
props^.Sce.Debug_Gnm[1]:=data.f_2;
|
|
end;
|
|
else
|
|
Result:=EINVAL;
|
|
end;
|
|
|
|
mtx_unlock(p_proc.p_mtx);
|
|
|
|
if (Result<>0) then Exit;
|
|
|
|
Writeln('SetProcessProperty("',data.name,'",0x',
|
|
HexStr(data.f_1,16),',0x',
|
|
HexStr(data.f_2,16),',0x',
|
|
HexStr(data.f_3,16),',0x',
|
|
HexStr(data.f_4,16),')');
|
|
|
|
end;
|
|
|
|
function sys_mdbg_service(op:Integer;arg1,arg2:Pointer):Integer;
|
|
var
|
|
props:p_mdbg_pevt;
|
|
ret,size:Integer;
|
|
|
|
coredump_ret:t_coredump_ret;
|
|
begin
|
|
Result:=0;
|
|
|
|
case op of
|
|
|
|
1: //SetProcessProperty
|
|
begin
|
|
Result:=SetProcessProperty(arg1);
|
|
end;
|
|
|
|
3: //sceKernelDebugRaiseException
|
|
begin
|
|
print_error_td('sceKernelDebugRaiseException:0x'+HexStr(DWORD(arg1),8));
|
|
Assert(False);
|
|
Result:=EINVAL;
|
|
end;
|
|
|
|
4: //sceKernelDebugRaiseExceptionOnReleaseMode
|
|
begin
|
|
Writeln('sceKernelDebugRaiseExceptionOnReleaseMode:0x',HexStr(DWORD(arg1),8));
|
|
print_backtrace_td(stderr);
|
|
Result:=0;
|
|
end;
|
|
|
|
8:
|
|
begin
|
|
//signal coredump thread start and wait
|
|
|
|
props:=init_mdbg_pevt;
|
|
//td->td_dbgflags = td->td_dbgflags | 0x100;
|
|
|
|
mtx_lock(props^.mtx);
|
|
|
|
props^.td_tid:=curkthread^.td_tid;
|
|
|
|
Result:=0;
|
|
|
|
if (props^.td_cancel=0) then
|
|
begin
|
|
props^.td_state:=pevt_wait;
|
|
cv_signal(@props^.cv);
|
|
ret:=_cv_wait_sig(@props^.cv,@props^.mtx);
|
|
Result:=0;
|
|
props^.td_state:=pevt_inited;
|
|
if (ret<>0) and (props^.td_cancel=0) then
|
|
begin
|
|
Result:=EINTR;
|
|
end;
|
|
end;
|
|
|
|
props^.td_cancel:=0;
|
|
|
|
if (props^.crash_state=0) then
|
|
begin
|
|
//
|
|
end else
|
|
begin
|
|
Result:=EINVAL;
|
|
end;
|
|
|
|
if (Result=0) then
|
|
begin
|
|
coredump_ret:=Default(t_coredump_ret);
|
|
coredump_ret.ret :=props^.td_ret;
|
|
coredump_ret.flags:=props^.td_flags;
|
|
|
|
mtx_unlock(props^.mtx);
|
|
|
|
size:=Integer(arg2);
|
|
|
|
if (size < 0) then
|
|
begin
|
|
Result:=EFAULT;
|
|
end else
|
|
begin
|
|
|
|
if (DWORD(size) < $28) then
|
|
begin
|
|
//
|
|
end else
|
|
begin
|
|
size:=$28;
|
|
end;
|
|
|
|
Result:=copyout(@coredump_ret,arg1,size);
|
|
|
|
if (Result=0) then
|
|
begin
|
|
Writeln('mDBG: Debughandler starting(',curkthread^.td_tid,':',curkthread^.td_name,')');
|
|
end;
|
|
|
|
end;
|
|
|
|
Exit;
|
|
end;
|
|
|
|
mtx_unlock(props^.mtx);
|
|
end;
|
|
|
|
9: //sceCoredumpUnregisterCoredumpHandler
|
|
begin
|
|
//cancel coredump thread and wait exit
|
|
|
|
mtx_lock(p_proc.p_mtx);
|
|
|
|
props:=g_mdbg_pevt;
|
|
|
|
if (props<>nil) then
|
|
begin
|
|
mtx_lock(props^.mtx);
|
|
|
|
props^.td_flags :=props^.td_flags or 1;
|
|
props^.td_ret :=Integer(arg1);
|
|
props^.td_cancel:=1;
|
|
|
|
if (props^.td_state=pevt_wait) then
|
|
begin
|
|
cv_signal(@props^.cv);
|
|
end;
|
|
|
|
mtx_unlock(props^.mtx);
|
|
|
|
mtx_unlock(p_proc.p_mtx);
|
|
|
|
//TODO: wait thread exit
|
|
|
|
Exit;
|
|
end else
|
|
begin
|
|
Result:=ESRCH;
|
|
end;
|
|
|
|
mtx_unlock(p_proc.p_mtx);
|
|
end;
|
|
|
|
10: //sceCoredumpAttach*
|
|
begin
|
|
//only in coredump thread
|
|
//(td->td_dbgflags | 0x100)=0 && not sceSblACMgrIsSystemUcred
|
|
Result:=EPERM;
|
|
end;
|
|
|
|
11:
|
|
begin
|
|
init_mdbg_pevt;
|
|
Result:=0;
|
|
end;
|
|
|
|
12:
|
|
begin
|
|
//wait coredump thread start
|
|
|
|
mtx_lock(p_proc.p_mtx);
|
|
props:=g_mdbg_pevt;
|
|
mtx_unlock(p_proc.p_mtx);
|
|
|
|
if (props=nil) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
mtx_lock(props^.mtx);
|
|
|
|
if (props^.td_state=pevt_inited) then
|
|
begin
|
|
ret:=_cv_wait_sig(@props^.cv,@props^.mtx);
|
|
if (ret<>-1) then
|
|
begin
|
|
Result:=ret;
|
|
end else
|
|
begin
|
|
Result:=EINTR;
|
|
end;
|
|
end else
|
|
if (props^.td_state<>pevt_wait) then
|
|
begin
|
|
if (props^.td_state=pevt_finish) then
|
|
begin
|
|
Result:=ESRCH;
|
|
end else
|
|
begin
|
|
Result:=EAGAIN;
|
|
end;
|
|
end;
|
|
|
|
mtx_unlock(props^.mtx);
|
|
end;
|
|
|
|
13:
|
|
begin
|
|
//coredump thread reset
|
|
|
|
mtx_lock(p_proc.p_mtx);
|
|
|
|
//if (((td->td_dbgflags & 0x100) != 0) && (proc->debug_event == 0)) {
|
|
// td->td_dbgflags = td->td_dbgflags & (~0x100);
|
|
//}
|
|
|
|
props:=g_mdbg_pevt;
|
|
|
|
if (props<>nil) then
|
|
begin
|
|
mtx_lock(props^.mtx);
|
|
|
|
props^.td_flags:=props^.td_flags and (not 1);
|
|
|
|
if (arg1<>nil) then
|
|
begin
|
|
props^.td_state:=pevt_finish;
|
|
end;
|
|
|
|
mtx_unlock(props^.mtx);
|
|
end;
|
|
|
|
mtx_unlock(p_proc.p_mtx);
|
|
end;
|
|
|
|
20:
|
|
begin
|
|
//td->td_dbgflags = td->td_dbgflags | 0x800;
|
|
Result:=0;
|
|
end;
|
|
|
|
else
|
|
begin
|
|
print_error_td('sys_mdbg_service('+IntToStr(op)+')');
|
|
Assert(False);
|
|
Result:=EINVAL;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|