fpPS4/sys/sys_kernel.pas

294 lines
4.9 KiB
ObjectPascal
Raw Normal View History

2022-05-31 07:20:10 +00:00
unit sys_kernel;
{$mode ObjFPC}{$H+}
interface
Uses
Windows;
{$I sce_errno.inc}
{$I errno.inc}
2022-09-30 21:25:10 +00:00
var
SDK_VERSION:DWORD=0;
2022-05-31 07:20:10 +00:00
type
SceKernelModule=Integer;
PSceKernelLoadModuleOpt=^SceKernelLoadModuleOpt;
SceKernelLoadModuleOpt=packed record
size:size_t;
end;
atexit_func=function(param:Pointer):Integer;SysV_ABI_CDecl;
2022-09-12 14:13:01 +00:00
TKernelAtexitFuncCount=function(handle:Integer):Integer;SysV_ABI_CDecl;
TKernelAtexitReportFunc=procedure(handle:Integer);
2022-05-31 07:20:10 +00:00
function px2sce(e:Integer):Integer;
function sce2px(e:Integer):Integer;
function _set_errno(r:Integer):Integer;
2022-09-13 13:31:03 +00:00
function _set_sce_errno(r:Integer):Integer;
2022-05-31 07:20:10 +00:00
function _error:Pointer;
function SwFreeMem(p:pointer):ptruint;
function SwAllocMem(Size:ptruint):pointer;
Procedure SwYieldExecution; inline;
function SwDelayExecution(Alertable:Boolean;DelayInterval:PQWORD):DWORD;
function SwWaitForSingleObject(
ObjectHandle:THandle;
TimeOut:PQWORD;
Alertable:LONGBOOL):DWORD;
2022-06-26 20:50:32 +00:00
function SwWaitFor(Handle:THandle;pTimeout:PQWORD):Integer; //pTimeout in ns
2022-05-31 07:20:10 +00:00
Function safe_move(const src;var dst;count:QWORD):QWORD;
procedure safe_move_ptr(const src;var dst);
function safe_test(var src:DWORD;value:DWORD):Boolean;
function safe_str(P:PChar):shortstring;
implementation
uses
ntapi,
sys_pthread,
sys_signal,
sys_time;
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 _set_errno(r:Integer):Integer;
var
t:pthread;
begin
2022-09-13 13:59:10 +00:00
Result:=0;
t:=tcb_thread;
if (t<>nil) then t^.errno:=r;
if (r<>0) then
2022-05-31 07:20:10 +00:00
begin
2022-09-13 13:59:10 +00:00
Result:=-1;
2022-05-31 07:20:10 +00:00
end;
end;
2022-09-13 13:31:03 +00:00
function _set_sce_errno(r:Integer):Integer;
var
t:pthread;
begin
2022-09-13 13:59:10 +00:00
t:=tcb_thread;
if (t<>nil) then t^.errno:=sce2px(r);
2022-09-13 13:31:03 +00:00
Result:=r;
end;
2022-05-31 07:20:10 +00:00
function _error:Pointer;
var
t:pthread;
begin
Result:=nil;
t:=tcb_thread;
if (t<>nil) then Result:=@t^.errno;
end;
function SwFreeMem(p:pointer):ptruint;
begin
_sig_lock;
Result:=FreeMem(p);
_sig_unlock;
end;
function SwAllocMem(Size:ptruint):pointer;
begin
_sig_lock;
Result:=AllocMem(Size);
_sig_unlock;
end;
Procedure SwYieldExecution; inline;
begin
_sig_lock;
NtYieldExecution;
_sig_unlock;
end;
function SwDelayExecution(Alertable:Boolean;DelayInterval:PQWORD):DWORD;
begin
2022-07-14 20:16:23 +00:00
_sig_lock(ord(Alertable));
2022-05-31 07:20:10 +00:00
Result:=NtDelayExecution(Alertable,Pointer(DelayInterval));
_sig_unlock;
end;
function SwWaitForSingleObject(
ObjectHandle:THandle;
TimeOut:PQWORD;
Alertable:LONGBOOL):DWORD;
begin
2022-07-14 20:16:23 +00:00
_sig_lock(ord(Alertable));
2022-05-31 07:20:10 +00:00
Result:=NtWaitForSingleObject(ObjectHandle,Alertable,Pointer(TimeOut));
_sig_unlock;
end;
function SwWaitFor(Handle:THandle;pTimeout:PQWORD):Integer;
var
timeout:Int64;
passed :Int64;
START:QWORD;
QTIME:QWORD;
res:DWORD;
begin
Result:=0;
if (pTimeout<>nil) then
begin
timeout:=(pTimeout^ div 100);
SwSaveTime(START);
end else
begin
timeout:=NT_INFINITE;
end;
repeat
if (pTimeout<>nil) then
begin
if (timeout=0) then
begin
2022-06-07 13:24:08 +00:00
pTimeout^:=0;
2022-05-31 07:20:10 +00:00
Result:=ETIMEDOUT;
Break;
end;
SwSaveTime(QTIME);
timeout:=-timeout;
2022-07-14 20:16:23 +00:00
_sig_lock(SL_ALERTABLE);
2022-05-31 07:20:10 +00:00
res:=NtWaitForSingleObject(Handle,True,@timeout);
_sig_unlock;
timeout:=-timeout;
passed:=SwTimePassedUnits(QTIME);
if (passed>=timeout) then
begin
timeout:=0;
end else
begin
timeout:=timeout-passed;
end;
end else
begin
2022-07-14 20:16:23 +00:00
_sig_lock(SL_ALERTABLE);
2022-05-31 07:20:10 +00:00
res:=NtWaitForSingleObject(Handle,True,@timeout);
_sig_unlock;
end;
case res of
STATUS_ALERTED,
STATUS_USER_APC:
begin
//continue
end;
STATUS_TIMEOUT:
begin
2022-06-07 13:24:08 +00:00
if (pTimeout<>nil) then
begin
2022-06-07 20:12:11 +00:00
pTimeout^:=0;
2022-06-07 13:24:08 +00:00
end;
2022-05-31 07:20:10 +00:00
Result:=ETIMEDOUT;
Break;
end;
STATUS_ABANDONED:
begin
2022-06-07 20:12:11 +00:00
if (pTimeout<>nil) then
begin
pTimeout^:=timeout*100;
end;
2022-05-31 07:20:10 +00:00
Result:=EPERM;
Break;
end;
STATUS_SUCCESS:
begin
2022-06-07 20:12:11 +00:00
if (pTimeout<>nil) then
begin
pTimeout^:=timeout*100;
end;
2022-05-31 07:20:10 +00:00
Result:=0;
Break;
end;
else
begin
2022-06-07 20:12:11 +00:00
if (pTimeout<>nil) then
begin
pTimeout^:=timeout*100;
end;
2022-05-31 07:20:10 +00:00
Result:=EINVAL;
Break;
end;
end;
until false;
end;
Function safe_move(const src;var dst;count:QWORD):QWORD;
begin
_sig_lock;
if not ReadProcessMemory(GetCurrentProcess,@src,@dst,count,Result) then Result:=0;
_sig_unlock;
end;
procedure safe_move_ptr(const src;var dst);
begin
if safe_move(src,dst,SizeOf(Pointer))<>SizeOf(Pointer) then Pointer(dst):=nil;
end;
function safe_test(var src:DWORD;value:DWORD):Boolean;
var
t:DWORD;
begin
Result:=False;
t:=0;
if (safe_move(src,t,SizeOf(DWORD))=SizeOf(DWORD)) then
begin
Result:=(t=value);
end;
end;
function safe_str(P:PChar):shortstring;
var
ch:Char;
begin
Result:='';
repeat
ch:=#0;
safe_move(P^,ch,SizeOf(Char));
if (ch=#0) then Exit;
Result:=Result+ch;
if (Result[0]=#255) then Exit;
Inc(P);
until false;
end;
end.