Move to libcinternal, atexit

This commit is contained in:
Pavel 2022-12-28 16:24:34 +03:00
parent 9b7e280332
commit 82287af29b
4 changed files with 267 additions and 19 deletions

View File

@ -31,7 +31,7 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="101">
<Units Count="111">
<Unit0>
<Filename Value="fpPS4.lpr"/>
<IsPartOfProject Value="True"/>
@ -427,41 +427,83 @@
<IsPartOfProject Value="True"/>
</Unit92>
<Unit93>
<Filename Value="kernel\ps4_mspace.pas"/>
<IsPartOfProject Value="True"/>
</Unit93>
<Unit94>
<Filename Value="src\ps4_libscerudp.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceRudp"/>
</Unit94>
<Unit95>
</Unit93>
<Unit94>
<Filename Value="src\ps4_libscevoice.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceVoice"/>
</Unit95>
<Unit96>
</Unit94>
<Unit95>
<Filename Value="shaders\shaders.pas"/>
<IsPartOfProject Value="True"/>
</Unit96>
<Unit97>
</Unit95>
<Unit96>
<Filename Value="src\ps4_libscerandom.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceRandom"/>
</Unit96>
<Unit97>
<Filename Value="kernel\ps4_pthread_key.pas"/>
<IsPartOfProject Value="True"/>
</Unit97>
<Unit98>
<Filename Value="kernel\ps4_pthread_key.pas"/>
<Filename Value="src\param_sfo.pas"/>
<IsPartOfProject Value="True"/>
</Unit98>
<Unit99>
<Filename Value="src\param_sfo.pas"/>
<IsPartOfProject Value="True"/>
</Unit99>
<Unit100>
<Filename Value="src\inputs\xinput.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="XInput"/>
</Unit99>
<Unit100>
<Filename Value="sys\sys_file.pas"/>
<IsPartOfProject Value="True"/>
</Unit100>
<Unit101>
<Filename Value="sys\sys_dev.pas"/>
<IsPartOfProject Value="True"/>
</Unit101>
<Unit102>
<Filename Value="sys\sys_pthread.pas"/>
<IsPartOfProject Value="True"/>
</Unit102>
<Unit103>
<Filename Value="sys\sys_fd.pas"/>
<IsPartOfProject Value="True"/>
</Unit103>
<Unit104>
<Filename Value="src\ps4_libscenpwebapi.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceNpWebApi"/>
</Unit104>
<Unit105>
<Filename Value="src\libcinternal\ps4_libscelibcinternal.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceLibcInternal"/>
</Unit105>
<Unit106>
<Filename Value="src\libcinternal\ps4_atexit_internal.pas"/>
<IsPartOfProject Value="True"/>
</Unit106>
<Unit107>
<Filename Value="ps4_program.pas"/>
<IsPartOfProject Value="True"/>
</Unit107>
<Unit108>
<Filename Value="sys\sys_kernel.pas"/>
<IsPartOfProject Value="True"/>
</Unit108>
<Unit109>
<Filename Value="sys\sys_dir.pas"/>
<IsPartOfProject Value="True"/>
</Unit109>
<Unit110>
<Filename Value="src\libcinternal\ps4_mspace_internal.pas"/>
<IsPartOfProject Value="True"/>
</Unit110>
</Units>
</ProjectOptions>
<CompilerOptions>
@ -473,7 +515,7 @@
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);kernel;src\ajm;sys"/>
<Libraries Value="static"/>
<OtherUnitFiles Value="rtl;sys;vulkan;chip;spirv;kernel;src;src\ajm;src\audio;src\np;src\playgo;shaders;src\inputs"/>
<OtherUnitFiles Value="rtl;sys;vulkan;chip;spirv;kernel;src;src\ajm;src\audio;src\np;src\playgo;shaders;src\inputs;src\libcinternal"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>

View File

@ -0,0 +1,195 @@
unit ps4_atexit_internal;
{$mode ObjFPC}{$H+}
interface
uses
sys_types,
ps4_libkernel,
ps4_mutex;
const
ATEXIT_FN_EMPTY=0;
ATEXIT_FN_STD =1;
ATEXIT_FN_CXA =2;
ATEXIT_SIZE =32;
type
t_std_func=Procedure; SysV_ABI_CDecl;
t_cxa_func=Procedure(arg:Pointer); SysV_ABI_CDecl;
p_atexit_fn=^atexit_fn;
atexit_fn=packed record
fn_type:Integer;
_align:Integer;
fn_ptr:Pointer;
fn_arg:Pointer;
fn_dso:Pointer;
end;
p_atexit=^t_atexit;
t_atexit=packed record
next:p_atexit;
ind:Integer;
_align:Integer;
fns:array[0..ATEXIT_SIZE-1] of atexit_fn;
end;
function ps4_atexit(func:Pointer):Integer; SysV_ABI_CDecl;
function ps4___cxa_atexit(func,arg,dso:Pointer):Integer; SysV_ABI_CDecl;
function ps4___cxa_finalize(dso:Pointer):Integer; SysV_ABI_CDecl;
implementation
var
atexit_mutex:pthread_mutex=nil;
__atexit:p_atexit=nil;
__atexit0:t_atexit;
global_exit:Integer=0;
procedure _MUTEX_LOCK; inline;
begin
ps4_pthread_mutex_lock(@atexit_mutex);
end;
procedure _MUTEX_UNLOCK; inline;
begin
ps4_pthread_mutex_unlock(@atexit_mutex);
end;
procedure _MUTEX_DESTROY; inline;
begin
ps4_pthread_mutex_destroy(@atexit_mutex);
end;
function atexit_register(fptr:p_atexit_fn):Integer; SysV_ABI_CDecl;
var
p:p_atexit;
old__atexit:p_atexit;
begin
_MUTEX_LOCK;
p:=__atexit;
if (p=nil) then
begin
p:=@__atexit0;
__atexit:=p;
end else
While (p^.ind>=ATEXIT_SIZE) do
begin
old__atexit:=__atexit;
_MUTEX_UNLOCK;
p:=AllocMem(SizeOf(t_atexit));
if (p=nil) then Exit(-1);
_MUTEX_LOCK;
if (old__atexit<>__atexit) then
begin
_MUTEX_UNLOCK;
FreeMem(p);
_MUTEX_LOCK;
p:=__atexit;
continue
end;
p^.ind:=0;
p^.next:=__atexit;
__atexit:=p;
end;
p^.fns[p^.ind]:=fptr^;
p^.ind:=p^.ind+1;
_MUTEX_UNLOCK;
Result:=0;
end;
function ps4_atexit(func:Pointer):Integer; SysV_ABI_CDecl;
var
fn:atexit_fn;
begin
fn.fn_type:=ATEXIT_FN_STD;
fn.fn_ptr :=func;
fn.fn_arg :=nil;
fn.fn_dso :=nil;
Result:=atexit_register(@fn);
end;
function ps4___cxa_atexit(func,arg,dso:Pointer):Integer; SysV_ABI_CDecl;
var
fn:atexit_fn;
begin
fn.fn_type:=ATEXIT_FN_CXA;
fn.fn_ptr :=func;
fn.fn_arg :=arg;
fn.fn_dso :=dso;
Result:=atexit_register(@fn);
end;
function ps4___cxa_finalize(dso:Pointer):Integer; SysV_ABI_CDecl;
var
phdr_info:SceKernelModuleInfoEx;
p:p_atexit;
fn:atexit_fn;
n,has_phdr:Integer;
begin
if (dso<>nil) then
begin
has_phdr:=ps4_sceKernelGetModuleInfoFromAddr(dso,2,@phdr_info);
end else
begin
has_phdr:=0;
global_exit:=1;
end;
_MUTEX_LOCK;
p:=__atexit;
While (p<>nil) do
begin
For n:=p^.ind downto 0 do
begin
if (p^.fns[n].fn_type=ATEXIT_FN_EMPTY) then Continue;
fn:=p^.fns[n];
if (dso<>nil) and (dso<>fn.fn_dso) then
begin
if ((not Boolean(has_phdr)) or
Boolean(global_exit) or
(not Boolean(ps4___elf_phdr_match_addr(@phdr_info,fn.fn_ptr)))) then
begin
continue;
end;
end;
p^.fns[n].fn_type:=ATEXIT_FN_EMPTY;
_MUTEX_UNLOCK;
Case fn.fn_type of
ATEXIT_FN_CXA:t_cxa_func(fn.fn_ptr)(fn.fn_arg);
ATEXIT_FN_STD:t_std_func(fn.fn_ptr)();
else;
end;
_MUTEX_LOCK;
end;
p:=p^.next;
end;
_MUTEX_UNLOCK;
if (dso=nil) then
begin
_MUTEX_DESTROY;
end;
if Boolean(has_phdr) and
(not Boolean(global_exit)) then
begin
ps4___pthread_cxa_finalize(@phdr_info);
end;
end;
end.

View File

@ -16,7 +16,8 @@ uses
implementation
uses
ps4_mspace,
ps4_mspace_internal,
ps4_atexit_internal,
sys_kernel,
sys_signal;
@ -294,6 +295,16 @@ begin
lib^.set_proc($4AE73C5B440FC63C,@ps4__ZdaPvS_);
lib^.set_proc($D6FA3AAAAA9AF45E,@ps4__ZdlPvS_);
//mspace
//atexit
lib^.set_proc($F06D8B07E037AF38,@ps4_atexit);
lib^.set_proc($B6CBC49A77A7CF8F,@ps4___cxa_atexit);
lib^.set_proc($1F67BCB7949C4067,@ps4___cxa_finalize);
//atexit
lib:=Result._add_lib('libSceLibcInternalExt');
lib^.set_proc($356B53375D1C2731,@ps4_sceLibcHeapGetTraceInfo);

View File

@ -1,4 +1,4 @@
unit ps4_mspace;
unit ps4_mspace_internal;
{$mode ObjFPC}{$H+}