mirror of https://github.com/red-prig/fpPS4.git
713 lines
16 KiB
Plaintext
713 lines
16 KiB
Plaintext
unit kern_dynlib;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
sysutils,
|
|
mqueue,
|
|
kern_rtld,
|
|
subr_dynlib,
|
|
kern_dlsym,
|
|
kern_reloc,
|
|
kern_named_id;
|
|
|
|
const
|
|
SCE_DBG_MAX_NAME_LENGTH = 256;
|
|
SCE_DBG_MAX_SEGMENTS = 4;
|
|
SCE_DBG_NUM_FINGERPRINT = 20;
|
|
|
|
type
|
|
SceKernelModuleSegmentInfo=packed record
|
|
addr:Pointer;
|
|
size:DWORD;
|
|
prot:Integer; //PF_
|
|
end;
|
|
|
|
SceDynlibName=array[0..SCE_DBG_MAX_NAME_LENGTH-1] of AnsiChar;
|
|
|
|
pSceKernelModuleInfo=^SceKernelModuleInfo;
|
|
SceKernelModuleInfo=packed record
|
|
size :QWORD; //Size of this structure
|
|
name :SceDynlibName; //name.prx
|
|
segmentInfo :array[0..SCE_DBG_MAX_SEGMENTS-1] of SceKernelModuleSegmentInfo;
|
|
segmentCount:DWORD;
|
|
fingerprint :array[0..SCE_DBG_NUM_FINGERPRINT-1] of Byte;
|
|
end;
|
|
{$IF sizeof(SceKernelModuleInfo)<>352}{$STOP sizeof(SceKernelModuleInfo)<>352}{$ENDIF}
|
|
|
|
pSceKernelModuleInfoEx=^SceKernelModuleInfoEx;
|
|
SceKernelModuleInfoEx=packed record
|
|
st_size :QWORD; //424
|
|
name :SceDynlibName; //name.prx
|
|
id :Integer;
|
|
tls_index :DWORD;
|
|
tls_init_addr :Pointer;
|
|
tls_init_size :DWORD;
|
|
tls_size :DWORD;
|
|
tls_offset :DWORD;
|
|
tls_align :DWORD;
|
|
init_proc_addr :Pointer;
|
|
fini_proc_addr :Pointer;
|
|
reserved1 :QWORD;
|
|
reserved2 :QWORD;
|
|
eh_frame_hdr_addr:Pointer;
|
|
eh_frame_addr :Pointer;
|
|
eh_frame_hdr_size:DWORD;
|
|
eh_frame_size :DWORD;
|
|
segments :array[0..SCE_DBG_MAX_SEGMENTS-1] of SceKernelModuleSegmentInfo;
|
|
segment_count :DWORD;
|
|
ref_count :DWORD;
|
|
end;
|
|
{$IF sizeof(SceKernelModuleInfoEx)<>424}{$STOP sizeof(SceKernelModuleInfoEx)<>424}{$ENDIF}
|
|
|
|
pSceModuleInfoForUnwind=^SceModuleInfoForUnwind;
|
|
SceModuleInfoForUnwind=packed record
|
|
st_size :qword; //304
|
|
name :SceDynlibName; //name.prx
|
|
eh_frame_hdr_addr:Pointer;
|
|
eh_frame_addr :Pointer;
|
|
eh_frame_size :qword;
|
|
seg0_addr :Pointer;
|
|
seg0_size :qword;
|
|
end;
|
|
|
|
function sys_dynlib_dlsym(handle:Integer;symbol:pchar;addrp:ppointer):Integer;
|
|
function sys_dynlib_process_needed_and_relocate():Integer;
|
|
function sys_dynlib_do_copy_relocations():Integer;
|
|
function sys_dynlib_load_prx(moduleFileName:pchar;flags:DWORD;pRes:PInteger;unused:Pointer):Integer;
|
|
function sys_dynlib_unload_prx(handle:Integer;args:QWORD;argp:Pointer):Integer;
|
|
function sys_dynlib_get_info(handle:Integer;info:Pointer):Integer;
|
|
function sys_dynlib_get_info2(handle:Integer;info:Pointer):Integer;
|
|
function sys_dynlib_get_info_ex(handle,flags:Integer;info:Pointer):Integer;
|
|
function sys_dynlib_get_info_for_libdbg(handle:Integer;info:Pointer):Integer;
|
|
function sys_dynlib_get_list(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
function sys_dynlib_get_list2(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
function sys_dynlib_get_list_for_libdbg(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
function sys_dynlib_get_obj_member(handle:Integer;num:Byte;pout:PPointer):Integer;
|
|
function sys_dynlib_get_proc_param(pout:PPointer;psize:PQWORD):Integer;
|
|
function sys_dl_get_info(pid,handle:Integer;pout:PPointer):Integer;
|
|
function sys_dl_get_list(pid:Integer;pArray:PInteger;numArray:Integer;pActualNum:PInteger):Integer;
|
|
function sys_dl_get_metadata(pid,handle:Integer;pout:Pointer;size:Integer;pactual_size:PInteger):Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
errno,
|
|
systm,
|
|
vm,
|
|
kern_proc,
|
|
kern_budget;
|
|
|
|
function not_dynamic:Boolean; inline;
|
|
begin
|
|
Result:=True;
|
|
if (dynlibs_info.libprogram=nil) then Exit;
|
|
if (dynlibs_info.libprogram^.rel_data=nil) then Exit;
|
|
Result:=False;
|
|
end;
|
|
|
|
function sys_dynlib_dlsym(handle:Integer;symbol:pchar;addrp:ppointer):Integer;
|
|
label
|
|
_exit;
|
|
var
|
|
obj:p_lib_info;
|
|
flags:Integer;
|
|
ptr:Pointer;
|
|
|
|
fsym:array[0..2560-1] of char;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_dlsym:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
Result:=copyinstr(symbol,@fsym,sizeof(fsym),nil);
|
|
if (Result<>0) then Exit;
|
|
|
|
Writeln('sys_dynlib_dlsym:',fsym);
|
|
|
|
dynlibs_lock;
|
|
|
|
obj:=find_obj_by_handle(handle);
|
|
if (obj=nil) then
|
|
begin
|
|
Result:=ESRCH;
|
|
goto _exit;
|
|
end;
|
|
|
|
flags:=0;
|
|
if (StrLComp(@fsym,'BaOKcng8g88',Length('BaOKcng8g88'))=0) or
|
|
(StrLComp(@fsym,'KpDMrPHvt3Q',Length('KpDMrPHvt3Q'))=0) then
|
|
begin
|
|
flags:=SYMLOOK_BASE64;
|
|
end;
|
|
|
|
ptr:=do_dlsym(obj,@fsym,nil,flags);
|
|
|
|
if (ptr=nil) then
|
|
begin
|
|
Result:=ESRCH;
|
|
goto _exit;
|
|
end;
|
|
|
|
Result:=copyout(@ptr,addrp,SizeOf(Pointer));
|
|
|
|
_exit:
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_process_needed_and_relocate():Integer;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_process_needed_and_relocate:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
dynlibs_lock;
|
|
|
|
Result:=dynlib_load_needed_shared_objects();
|
|
if (Result=0) then
|
|
begin
|
|
Result:=dynlib_load_relocate();
|
|
end;
|
|
|
|
if (Result=0) then
|
|
begin
|
|
Result:=dmem_process_relocated();
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_do_copy_relocations():Integer;
|
|
begin
|
|
dynlibs_lock;
|
|
|
|
Result:=check_copy_relocations(dynlibs_info.libprogram);
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_load_prx(moduleFileName:pchar;flags:DWORD;pRes:PInteger;unused:Pointer):Integer;
|
|
label
|
|
_exit;
|
|
var
|
|
len:ptruint;
|
|
fname:array[0..1024-1] of char;
|
|
|
|
obj:p_lib_info;
|
|
key:Integer;
|
|
allocs:Boolean;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_load_prx:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
//0x10000 //priv libs?
|
|
//0x20000 //set jmpslots_done?
|
|
//0x40000 //set not_get_proc?
|
|
if ((flags and $fff8ffff)<>0) then Exit(EINVAL);
|
|
|
|
len:=0;
|
|
Result:=copyinstr(moduleFileName,@fname,sizeof(fname),@len);
|
|
if (Result<>0) then Exit;
|
|
|
|
Writeln('sys_dynlib_load_prx("',fname,'",0x',HexStr(flags,6),')');
|
|
|
|
dynlibs_lock;
|
|
|
|
obj:=nil;
|
|
Result:=load_prx(@fname,flags or ord(p_proc.p_budget_ptype=PTYPE_BIG_APP),obj);
|
|
if (Result=0) then
|
|
begin
|
|
allocs:=(obj^.id<=0);
|
|
|
|
if (obj^.ref_count < 2) then
|
|
begin
|
|
if not alloc_obj_id(obj) then
|
|
begin
|
|
unload_prx(obj);
|
|
Result:=EAGAIN;
|
|
goto _exit;
|
|
end;
|
|
end;
|
|
key:=obj^.id;
|
|
|
|
Result:=copyout(@key,pRes,SizeOf(Integer));
|
|
if (Result<>0) then
|
|
begin
|
|
if allocs then
|
|
begin
|
|
free_obj_id(obj^.id);
|
|
obj^.id:=0;
|
|
end;
|
|
unload_prx(obj);
|
|
Result:=EFAULT;
|
|
end;
|
|
end;
|
|
|
|
_exit:
|
|
dynlibs_unlock;
|
|
|
|
//dynlib_notify_event(td,resid,0x40);
|
|
end;
|
|
|
|
function sys_dynlib_unload_prx(handle:Integer;args:QWORD;argp:Pointer):Integer;
|
|
var
|
|
obj:p_lib_info;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_unload_prx:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
//Writeln('sys_dynlib_unload_prx:',handle);
|
|
|
|
dynlibs_lock;
|
|
|
|
obj:=find_obj_id(handle);
|
|
if (obj=nil) then
|
|
begin
|
|
Result:=ESRCH;
|
|
end else
|
|
begin
|
|
id_acqure(obj);
|
|
//
|
|
Result:=unload_prx(obj);
|
|
//
|
|
id_release(obj); //<-id_acqure
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function kern_dynlib_get_info(handle,flags:Integer;dst:pSceKernelModuleInfo):Integer;
|
|
var
|
|
obj:p_lib_info;
|
|
lib_path:pchar;
|
|
lib_name:pchar;
|
|
begin
|
|
Result:=ESRCH;
|
|
|
|
dynlibs_lock;
|
|
|
|
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
|
while (obj<>nil) do
|
|
begin
|
|
if (obj^.id=handle) then
|
|
begin
|
|
dst^:=Default(SceKernelModuleInfo);
|
|
|
|
if ((flags and 1)=0) and (obj^.rtld_flags.is_system<>0) then
|
|
begin
|
|
Result:=EPERM;
|
|
Break;
|
|
end;
|
|
|
|
lib_path:=obj^.lib_path;
|
|
lib_name:=dynlib_basename(lib_path);
|
|
|
|
strlcopy(dst^.name,lib_name,SCE_DBG_MAX_NAME_LENGTH);
|
|
|
|
//if not is_webkit then
|
|
begin
|
|
dst^.segmentCount:=2;
|
|
dst^.segmentInfo[0].addr:=obj^.map_base;
|
|
dst^.segmentInfo[0].size:=obj^.text_size;
|
|
dst^.segmentInfo[0].prot:=VM_PROT_READ or VM_PROT_EXECUTE;
|
|
dst^.segmentInfo[1].addr:=obj^.data_addr;
|
|
dst^.segmentInfo[1].size:=obj^.data_size;
|
|
dst^.segmentInfo[1].prot:=VM_PROT_RW;
|
|
if (obj^.relro_addr<>nil) and (obj^.relro_size<>0) then
|
|
begin
|
|
dst^.segmentInfo[2].addr:=obj^.relro_addr;
|
|
dst^.segmentInfo[2].size:=obj^.relro_size;
|
|
dst^.segmentInfo[2].prot:=VM_PROT_READ;
|
|
dst^.segmentCount:=3;
|
|
end;
|
|
end;
|
|
|
|
Move(obj^.fingerprint,dst^.fingerprint,SCE_DBG_NUM_FINGERPRINT);
|
|
|
|
Result:=0;
|
|
Break;
|
|
end;
|
|
//
|
|
obj:=TAILQ_NEXT(obj,@obj^.link);
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_get_info(handle:Integer;info:Pointer):Integer;
|
|
var
|
|
size:QWORD;
|
|
dst:SceKernelModuleInfo;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_get_info:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
size:=0;
|
|
Result:=copyin(info,@size,SizeOf(QWORD));
|
|
if (Result<>0) then
|
|
begin
|
|
Exit(EFAULT);
|
|
end;
|
|
|
|
if (size<>SizeOf(SceKernelModuleInfo)) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
Result:=kern_dynlib_get_info(handle,1,@dst);
|
|
if (Result<>0) then Exit;
|
|
|
|
Result:=copyout(@dst,info,SizeOf(SceKernelModuleInfo));
|
|
end;
|
|
|
|
function sys_dynlib_get_info2(handle:Integer;info:Pointer):Integer;
|
|
var
|
|
size:QWORD;
|
|
dst:SceKernelModuleInfo;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_get_info2:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
size:=0;
|
|
Result:=copyin(info,@size,SizeOf(QWORD));
|
|
if (Result<>0) then
|
|
begin
|
|
Exit(EFAULT);
|
|
end;
|
|
|
|
if (size<>SizeOf(SceKernelModuleInfo)) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
Result:=kern_dynlib_get_info(handle,0,@dst);
|
|
if (Result<>0) then Exit;
|
|
|
|
Result:=copyout(@dst,info,SizeOf(SceKernelModuleInfo));
|
|
end;
|
|
|
|
function kern_dynlib_get_info_ex(handle,flags:Integer;dst:pSceKernelModuleInfoEx):Integer;
|
|
var
|
|
obj:p_lib_info;
|
|
lib_path:pchar;
|
|
lib_name:pchar;
|
|
tls_index:Integer;
|
|
begin
|
|
Result:=ESRCH;
|
|
|
|
dynlibs_lock;
|
|
|
|
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
|
while (obj<>nil) do
|
|
begin
|
|
if (obj^.id=handle) then
|
|
begin
|
|
dst^:=Default(SceKernelModuleInfoEx);
|
|
|
|
lib_path:=obj^.lib_path;
|
|
lib_name:=dynlib_basename(lib_path);
|
|
|
|
strlcopy(dst^.name,lib_name,SCE_DBG_MAX_NAME_LENGTH);
|
|
|
|
dst^.id:=obj^.id;
|
|
|
|
tls_index:=WORD(obj^.tls_index);
|
|
dst^.tls_index:=tls_index;
|
|
|
|
if ((flags and 1)<>0) then
|
|
begin
|
|
tls_index:=(
|
|
(obj^.rtld_flags.is_system or (obj^.rtld_flags.mainprog shl 1)) shl 16
|
|
) or tls_index;
|
|
dst^.tls_index:=tls_index;
|
|
end;
|
|
|
|
Writeln(' get_info_ex :',obj^.lib_path);
|
|
Writeln(' obj.id :',obj^.id);
|
|
Writeln(' tls_flags :0x',HexStr(tls_index shr 16,4));
|
|
Writeln(' tls_index :0x',HexStr(tls_index,4));
|
|
Writeln(' tls_init_addr:0x',HexStr(QWORD(obj^.tls_init_addr),11));
|
|
Writeln(' tls_init_size:0x',HexStr(obj^.tls_init_size,8));
|
|
Writeln(' tls_size :0x',HexStr(obj^.tls_size ,8));
|
|
Writeln(' tls_offset :0x',HexStr(obj^.tls_offset ,8));
|
|
Writeln(' tls_align :0x',HexStr(obj^.tls_align ,8));
|
|
|
|
if ((flags and 2)<>0) then
|
|
begin
|
|
if (obj^.rtld_flags.is_system<>0) {or (is_webkit)} then
|
|
begin
|
|
FillChar(dst^.name,SCE_DBG_MAX_NAME_LENGTH,0);
|
|
end;
|
|
end;
|
|
|
|
dst^.tls_init_addr :=obj^.tls_init_addr;
|
|
dst^.tls_init_size :=DWORD(obj^.tls_init_size);
|
|
dst^.tls_size :=DWORD(obj^.tls_size);
|
|
dst^.tls_offset :=DWORD(obj^.tls_offset);
|
|
dst^.tls_align :=DWORD(obj^.tls_align);
|
|
dst^.reserved1 :=0;
|
|
dst^.reserved2 :=0;
|
|
dst^.eh_frame_hdr_addr:=obj^.eh_frame_hdr_addr;
|
|
dst^.eh_frame_addr :=obj^.eh_frame_addr;
|
|
dst^.eh_frame_hdr_size:=DWORD(obj^.eh_frame_hdr_size);
|
|
dst^.eh_frame_size :=DWORD(obj^.eh_frame_size);
|
|
dst^.ref_count :=obj^.ref_count;
|
|
|
|
//if not webkit then
|
|
begin
|
|
if (obj^.rtld_flags.not_get_proc=0) then
|
|
begin
|
|
dst^.init_proc_addr:=obj^.init_proc_addr;
|
|
dst^.fini_proc_addr:=obj^.fini_proc_addr;
|
|
end;
|
|
|
|
dst^.segments[0].addr:=obj^.map_base;
|
|
dst^.segments[0].size:=obj^.text_size;
|
|
dst^.segments[0].prot:=VM_PROT_READ or VM_PROT_EXECUTE;
|
|
dst^.segments[1].addr:=obj^.data_addr;
|
|
dst^.segments[1].size:=obj^.data_size;
|
|
dst^.segments[1].prot:=VM_PROT_RW;
|
|
dst^.segment_count:=2;
|
|
end;
|
|
|
|
Result:=0;
|
|
Break;
|
|
end;
|
|
//
|
|
obj:=TAILQ_NEXT(obj,@obj^.link);
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_get_info_ex(handle,flags:Integer;info:Pointer):Integer;
|
|
var
|
|
size:QWORD;
|
|
dst:SceKernelModuleInfoEx;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_get_info_ex:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
size:=0;
|
|
Result:=copyin(info,@size,SizeOf(QWORD));
|
|
if (Result<>0) then
|
|
begin
|
|
Exit(EFAULT);
|
|
end;
|
|
|
|
if (size<>SizeOf(SceKernelModuleInfoEx)) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
Result:=kern_dynlib_get_info_ex(handle,flags,@dst);
|
|
if (Result<>0) then Exit;
|
|
|
|
Result:=copyout(@dst,info,SizeOf(SceKernelModuleInfoEx));
|
|
end;
|
|
|
|
function sys_dynlib_get_info_for_libdbg(handle:Integer;info:Pointer):Integer;
|
|
begin
|
|
Exit(EPERM); //sceKernelIsDevelopmentMode
|
|
end;
|
|
|
|
function copyout_module_handle_list(pArray:PInteger;numArray:QWORD;flags:DWORD;pActualNum:PQWORD):Integer;
|
|
var
|
|
i,w,count:QWORD;
|
|
src:PInteger;
|
|
obj:p_lib_info;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'copyout_module_handle_list:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
dynlibs_lock;
|
|
|
|
i:=0;
|
|
w:=0;
|
|
count:=dynlibs_info.obj_count;
|
|
|
|
if (((flags and 1)<>0) and (count > numArray)) then
|
|
begin
|
|
dynlibs_unlock;
|
|
Exit(ENOMEM);
|
|
end;
|
|
|
|
src:=AllocMem(count*SizeOf(Integer));
|
|
|
|
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
|
while (obj<>nil) and (i<count) do
|
|
begin
|
|
if ((flags and 1)<>0) or (obj^.rtld_flags.is_system=0) then
|
|
begin
|
|
if (w>=numArray) then
|
|
begin
|
|
dynlibs_unlock;
|
|
FreeMem(src);
|
|
Exit(ENOMEM);
|
|
end;
|
|
src[w]:=obj^.id;
|
|
Inc(w);
|
|
end;
|
|
//
|
|
Inc(i);
|
|
obj:=TAILQ_NEXT(obj,@obj^.link);
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
|
|
if (i<>count) and ((flags and 1)<>0) then
|
|
begin
|
|
Writeln(StdErr,'copyout_module_handle_list:','WARNING: num<>dp^.obj_count');
|
|
end;
|
|
|
|
Result:=copyout(src,pArray,w*SizeOf(Integer));
|
|
|
|
if (Result=0) then
|
|
begin
|
|
Result:=copyout(@w,pActualNum,8);
|
|
end;
|
|
|
|
FreeMem(src);
|
|
end;
|
|
|
|
function sys_dynlib_get_list(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
begin
|
|
Result:=copyout_module_handle_list(pArray,numArray,1,pActualNum);
|
|
end;
|
|
|
|
function sys_dynlib_get_list2(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
begin
|
|
Result:=copyout_module_handle_list(pArray,numArray,0,pActualNum);
|
|
end;
|
|
|
|
function sys_dynlib_get_list_for_libdbg(pArray:PInteger;numArray:QWORD;pActualNum:PQWORD):Integer;
|
|
begin
|
|
Exit(EPERM); //sceKernelIsDevelopmentMode
|
|
end;
|
|
|
|
function sys_dynlib_get_obj_member(handle:Integer;num:Byte;pout:PPointer):Integer;
|
|
var
|
|
obj:p_lib_info;
|
|
dst:Pointer;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_get_obj_member:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
dynlibs_lock;
|
|
|
|
Result:=ESRCH;
|
|
|
|
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
|
while (obj<>nil) do
|
|
begin
|
|
if (obj^.id=handle) then
|
|
begin
|
|
dst:=nil;
|
|
|
|
case num of
|
|
1:if (obj^.rtld_flags.not_get_proc=0) then
|
|
begin
|
|
dst:=obj^.init_proc_addr;
|
|
end;
|
|
2:if (obj^.rtld_flags.not_get_proc=0) then
|
|
begin
|
|
dst:=obj^.fini_proc_addr;
|
|
end;
|
|
3:begin
|
|
dst:=obj^.eh_frame_hdr_addr;
|
|
end;
|
|
4:begin
|
|
dst:=obj^.eh_frame_addr;
|
|
end;
|
|
7:begin
|
|
dst:=obj^.tls_init_addr;
|
|
end;
|
|
8:begin
|
|
dst:=obj^.module_param;
|
|
end;
|
|
else
|
|
begin
|
|
dynlibs_unlock;
|
|
Exit(EINVAL);
|
|
end;
|
|
end;
|
|
|
|
Result:=copyout(@dst,pout,SizeOf(Pointer));
|
|
|
|
Break;
|
|
end;
|
|
//
|
|
obj:=TAILQ_NEXT(obj,@obj^.link);
|
|
end;
|
|
|
|
dynlibs_unlock;
|
|
end;
|
|
|
|
function sys_dynlib_get_proc_param(pout:PPointer;psize:PQWORD):Integer;
|
|
begin
|
|
if not_dynamic then
|
|
begin
|
|
Writeln(StdErr,'sys_dynlib_get_proc_param:','this is not dynamic linked program.');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
Result:=copyout(@dynlibs_info.proc_param_addr,pout,SizeOf(Pointer));
|
|
if (Result=0) then
|
|
begin
|
|
Result:=copyout(@dynlibs_info.proc_param_size,psize,SizeOf(QWORD));
|
|
end;
|
|
end;
|
|
|
|
function sys_dl_get_info(pid,handle:Integer;pout:PPointer):Integer;
|
|
begin
|
|
Exit(EPERM); //sceSblACMgrIsDebuggerProcess || sceSblACMgrIsCoredumpProcess || sceSblACMgrIsSyscoreProcess
|
|
end;
|
|
|
|
function sys_dl_get_list(pid:Integer;pArray:PInteger;numArray:Integer;pActualNum:PInteger):Integer;
|
|
begin
|
|
Exit(EPERM); //sceSblACMgrIsDebuggerProcess || sceSblACMgrIsCoredumpProcess || sceSblACMgrIsSyscoreProcess
|
|
end;
|
|
|
|
function sys_dl_get_metadata(pid,handle:Integer;pout:Pointer;size:Integer;pactual_size:PInteger):Integer;
|
|
begin
|
|
//sce_comment_addr
|
|
//sce_comment_size
|
|
Exit(EPERM); //sceSblACMgrIsDebuggerProcess || sceSblACMgrIsCoredumpProcess || sceSblACMgrIsSyscoreProcess
|
|
end;
|
|
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|