This commit is contained in:
red-prig 2022-10-05 22:16:42 +03:00
parent f07cdb2ca6
commit 6627735b2e
5 changed files with 307 additions and 74 deletions

View File

@ -80,10 +80,10 @@ end;
// eStopNotificationReason
procedure ps4_sceKernelDebugRaiseException(dwStopReason,dwStopId:DWORD); SysV_ABI_CDecl;
var
t:pthread;
//var
// t:pthread;
begin
t:=_get_curthread;
//t:=_get_curthread;
//if (t<>nil) then
// Writeln('RaiseThread=',t^.name);
Writeln(StdErr,'RaiseException:',HexStr(dwStopReason,8),':',HexStr(dwStopId,8),':',GetStopReasonInfo(dwStopReason));
@ -91,10 +91,10 @@ begin
end;
procedure ps4_sceKernelDebugRaiseExceptionOnReleaseMode(dwStopReason,dwStopId:DWORD); SysV_ABI_CDecl;
var
t:pthread;
//var
// t:pthread;
begin
t:=_get_curthread;
//t:=_get_curthread;
//if (t<>nil) then
// Writeln('RaiseThread=',t^.name);
Writeln(StdErr,'RaiseException:',HexStr(dwStopReason,8),':',HexStr(dwStopId,8),':',GetStopReasonInfo(dwStopReason));
@ -123,31 +123,6 @@ end;
// void *memblock
//);
type
pSceKernelModuleInfoEx=^SceKernelModuleInfoEx;
SceKernelModuleInfoEx=packed record
st_size:QWORD;
name:array[0..255] of AnsiChar;
id :Integer;
tls_index :DWORD;
tls_init_addr :QWORD;
tls_init_size :DWORD;
tls_size :DWORD;
tls_offset :DWORD;
tls_align :DWORD;
init_proc_addr :QWORD;
fini_proc_addr :QWORD;
reserved1 :QWORD;
reserved2 :QWORD;
eh_frame_hdr_addr:QWORD;
eh_frame_addr :QWORD;
eh_frame_hdr_size:DWORD;
eh_frame_size :DWORD;
segments:array[0..3] of TKernelModuleSegmentInfo;
segment_count:DWORD;
ref_count :DWORD;
end;
function ps4_sceKernelGetModuleInfoFromAddr(Addr:Pointer;flags:DWORD;info:pSceKernelModuleInfoEx):Integer; SysV_ABI_CDecl;
var
node:TElf_node;
@ -175,14 +150,13 @@ begin
Exit(-$7ffdfffd);
end;
info^.st_size:=424;
//info^:=node.GetModuleInfo;
info^:=node.GetModuleInfoEx;
node.Release;
_sig_unlock;
Result:=0;
end;
end else
begin
@ -191,7 +165,7 @@ begin
end;
end;
function ps4_sceKernelGetModuleInfo(handle:Integer;info:PKernelModuleInfo):Integer; SysV_ABI_CDecl;
function ps4_sceKernelGetModuleInfo(handle:Integer;info:pSceKernelModuleInfo):Integer; SysV_ABI_CDecl;
var
node:TElf_node;
begin
@ -210,20 +184,10 @@ begin
Result:=0;
end;
type
PSceModuleInfoForUnwind=^SceModuleInfoForUnwind;
SceModuleInfoForUnwind=packed record
st_size:qword; //304
name:array[0..255] of AnsiChar;
eh_frame_hdr_addr:qword;
eh_frame_addr:qword;
eh_frame_size:qword;
seg0_addr:qword;
seg0_size:qword;
end;
//nop nid:libkernel:4694092552938853:sceKernelGetModuleInfoForUnwind
function ps4_sceKernelGetModuleInfoForUnwind(addr:Pointer;flags:DWORD;info:PSceModuleInfoForUnwind):Integer; SysV_ABI_CDecl;
function ps4_sceKernelGetModuleInfoForUnwind(addr:Pointer;flags:DWORD;info:pSceModuleInfoForUnwind):Integer; SysV_ABI_CDecl;
var
node:TElf_node;
info_ex:SceKernelModuleInfoEx;
begin
if (info=nil) then Exit(SCE_KERNEL_ERROR_EFAULT);
if (flags - 1 < 2) then
@ -237,7 +201,33 @@ begin
if (info^.st_size > 303) then
begin
//Result:=-$7ffdfffd; //not found
_sig_lock;
Writeln('sceKernelGetModuleInfoForUnwind:',HexStr(Addr),':',flags,':',HexStr(info));
node:=ps4_app.AcqureFileByCodeAdr(Addr);
if (node=nil) then
begin
_sig_unlock;
info^:=Default(SceModuleInfoForUnwind);
Exit(-$7ffdfffd);
end;
info_ex:=node.GetModuleInfoEx;
node.Release;
_sig_unlock;
info^.name :=info_ex.name;
info^.eh_frame_hdr_addr:=info_ex.eh_frame_hdr_addr;
info^.eh_frame_addr :=info_ex.eh_frame_addr;
info^.eh_frame_size :=info_ex.eh_frame_size;
info^.seg0_addr :=info_ex.segments[0].address;
info^.seg0_size :=info_ex.segments[0].size;
Result:=0;
end;
end;
end else
@ -874,6 +864,7 @@ begin
lib^.set_proc($FD84D6FAA5DCDC24,@ps4_sceKernelInternalMemoryGetModuleSegmentInfo);
lib^.set_proc($7FB28139A7F2B17A,@ps4_sceKernelGetModuleInfoFromAddr);
lib^.set_proc($914A60AD722BCFB4,@ps4_sceKernelGetModuleInfo);
lib^.set_proc($4694092552938853,@ps4_sceKernelGetModuleInfoForUnwind);
lib^.set_proc($F79F6AADACCF22B8,@ps4_sceKernelGetProcParam);
lib^.set_proc($A7911C41E11E2401,@ps4_sceKernelRtldSetApplicationHeapAPI);
lib^.set_proc($ACD856CFE96F38C5,@ps4_sceKernelSetThreadDtors);

View File

@ -183,11 +183,12 @@ function pthread_rwlock_init(m:p_pthread_rwlock;a:p_pthread_rwlockattr;str:PChar
var
mi:pthread_rwlock;
begin
Result:=0;
mi:=m^;
mi:=rwlock_impl_init(m,mi);
if (mi=nil) then Exit(ENOMEM);
if (Result<>0) then Exit;
if (str<>nil) then MoveChar0(str^,mi^.name,32);
end;

View File

@ -158,7 +158,7 @@ type
mElf:TMemChunk;
mMap:TMemChunk;
ModuleInfo:TKernelModuleInfo;
ModuleInfo:SceKernelModuleInfo;
ro_segments:array[0..3] of TMemChunk;
@ -181,6 +181,7 @@ type
end;
dtInit:QWORD;
dtFini:QWORD;
pInit:packed record
dt_preinit_array,
@ -189,7 +190,15 @@ type
dt_init_array_count:QWORD;
end;
dtFini:QWORD;
eh_frame_hdr:packed record
addr:QWORD;
size:QWORD;
end;
eh_frame:packed record
addr:QWORD;
size:QWORD;
end;
pSceDynLib:TMemChunk; //mElf
@ -250,7 +259,8 @@ type
function module_start(argc:size_t;argp,param:PPointer):Integer; override;
function GetCodeFrame:TMemChunk; override;
function GetEntryPoint:Pointer; override;
Function GetModuleInfo:TKernelModuleInfo; override;
Function GetModuleInfo:SceKernelModuleInfo; override;
Function GetModuleInfoEx:SceKernelModuleInfoEx; override;
procedure mapCodeEntry;
end;
@ -585,6 +595,94 @@ begin
if (p_flags and PF_R)<>0 then Result:=Result+' PF_R';
end;
function read_encoded_value(hdr:p_eh_frame_hdr;hdr_size,hdr_vaddr:Int64;enc:Byte;var P:Pointer;var res:Int64):Boolean;
var
value:Int64;
endp:Pointer;
begin
Result:=False;
res:=0;
Case (enc and $70) of
DW_EH_PE_absptr:;
DW_EH_PE_pcrel:
begin
res:=(hdr_vaddr + (P - hdr));
end;
DW_EH_PE_datarel:
begin
res:=hdr_vaddr;
end;
else
Exit(True);
end;
value:=0;
endp:=Pointer(hdr) + hdr_size;
Case (enc and $0f) of
DW_EH_PE_udata2:
begin
if (p + 2 > endp) then Exit(True);
value:=PWORD(p)^;
p:=p + 2;
end;
DW_EH_PE_sdata2:
begin
if (p + 2 > endp) then Exit(True);
value:=PSmallint(p)^;
p:=p + 2;
end;
DW_EH_PE_udata4:
begin
if (p + 4 > endp) then Exit(True);
value:=PDWORD(p)^;
p:=p + 4;
end;
DW_EH_PE_sdata4:
begin
if (p + 4 > endp) then Exit(True);
value:=PInteger(p)^;
p:=p + 4;
end;
DW_EH_PE_udata8,
DW_EH_PE_sdata8:
begin
if (p + 8 > endp) then Exit(True);
value:=PInteger(p)^;
p:=p + 8;
end;
DW_EH_PE_absptr:
begin
value:=0;
end;
else
Exit(True);
end;
res:=res+value;
Result:=False;
end;
function parse_eh_frame_hdr(hdr:p_eh_frame_hdr;hdr_size,hdr_vaddr:Int64;var eh_frame_ptr:Int64):Boolean;
var
p:Pointer;
begin
if (hdr^.eh_frame_ptr_enc=DW_EH_PE_omit) then Exit(False);
p:=@hdr^.encoded;
if read_encoded_value(hdr,hdr_size,
hdr_vaddr,
hdr^.eh_frame_ptr_enc,
p,
eh_frame_ptr) then Exit(False);
Result:=True;
end;
function Telf_file.PreparePhdr:Boolean;
Var
i:SizeInt;
@ -594,8 +692,8 @@ Var
begin
Result:=False;
ModuleInfo:=Default(TKernelModuleInfo);
ModuleInfo.size:=SizeOf(TKernelModuleInfo);
ModuleInfo:=Default(SceKernelModuleInfo);
ModuleInfo.size:=SizeOf(SceKernelModuleInfo);
elf_hdr:=mElf.pAddr;
if (elf_hdr=nil) then Exit;
@ -698,7 +796,8 @@ begin
end;
PT_GNU_EH_FRAME:
begin
eh_frame_hdr.addr:=elf_phdr[i].p_vaddr;
eh_frame_hdr.size:=elf_phdr[i].p_filesz;
end;
else
@ -1026,7 +1125,7 @@ begin
end;
end;
procedure _add_seg(MI:PKernelModuleInfo;adr:Pointer;size:DWORD;prot:Integer); inline;
procedure _add_seg(MI:pSceKernelModuleInfo;adr:Pointer;size:DWORD;prot:Integer); inline;
var
i:DWORD;
begin
@ -1240,6 +1339,9 @@ var
i:SizeInt;
elf_hdr:Pelf64_hdr;
elf_phdr:Pelf64_phdr;
hdr:p_eh_frame_hdr;
eh_frame_ptr:Int64;
begin
Result:=False;
if (Self=nil) then Exit;
@ -1293,18 +1395,55 @@ begin
begin
_addSegment(@elf_phdr[i],'.DYNM');
end;
PT_SCE_PROCPARAM,
PT_TLS,
PT_GNU_EH_FRAME:
if (elf_phdr[i].p_flags=PF_R) then
PT_TLS:
begin
_add_ro_seg(@elf_phdr[i]);
if (elf_phdr[i].p_flags=PF_R) then
begin
_add_ro_seg(@elf_phdr[i]);
end;
end;
PT_GNU_EH_FRAME:
begin
if (elf_phdr[i].p_flags=PF_R) then
begin
_add_ro_seg(@elf_phdr[i]);
end;
eh_frame_hdr.addr:=elf_phdr[i].p_vaddr;
eh_frame_hdr.size:=elf_phdr[i].p_filesz;
hdr:=mMap.pAddr+eh_frame_hdr.addr;
eh_frame_ptr:=0;
if parse_eh_frame_hdr(hdr,
eh_frame_hdr.size,
Int64(hdr),
eh_frame_ptr) then
begin
eh_frame.addr:=eh_frame_ptr-QWORD(mMap.pAddr);
if (eh_frame_hdr.addr>eh_frame.addr) then
begin
eh_frame.size:=(eh_frame_hdr.addr-eh_frame.addr);
end else
begin
eh_frame.size:=(mMap.nSize-eh_frame_hdr.addr)
end;
end;
end;
end;
end;
_print_rdol;
pEntryPoint:=Pelf64_hdr(mElf.pAddr)^.e_entry;
Result:=True;
@ -2681,7 +2820,7 @@ begin
end;
end;
Function Telf_file.GetModuleInfo:TKernelModuleInfo;
Function Telf_file.GetModuleInfo:SceKernelModuleInfo;
begin
if (ModuleInfo.name[0]=#0) then
begin
@ -2690,6 +2829,36 @@ begin
Result:=ModuleInfo;
end;
Function Telf_file.GetModuleInfoEx:SceKernelModuleInfoEx;
begin
Result:=inherited;
if (ModuleInfo.name[0]=#0) then
begin
MoveChar0(PChar(pFileName)^,ModuleInfo.name,SCE_DBG_MAX_NAME_LENGTH);
end;
Result.name:=ModuleInfo.name;
Result.tls_index :=pTls.index;
Result.tls_init_addr :=mMap.pAddr+pTls.tmpl_start;
Result.tls_init_size :=pTls.tmpl_size;
Result.tls_size :=pTls.full_size;
Result.tls_offset :=pTls.offset;
Result.tls_align :=pTls.align;
Result.init_proc_addr :=mMap.pAddr+dtInit;
Result.fini_proc_addr :=mMap.pAddr+dtFini;
Result.eh_frame_hdr_addr:=mMap.pAddr+eh_frame_hdr.addr;
Result.eh_frame_addr :=mMap.pAddr+eh_frame.addr;
Result.eh_frame_hdr_size:=eh_frame_hdr.size;
Result.eh_frame_size :=eh_frame.size;
Result.segments :=ModuleInfo.segmentInfo;
Result.segment_count:=ModuleInfo.segmentCount;
end;
procedure Telf_file.mapCodeEntry;
var
P:TEntryPoint;

View File

@ -89,7 +89,8 @@ type
function module_start(argc:size_t;argp,param:PPointer):Integer; virtual;
function GetCodeFrame:TMemChunk; virtual;
function GetEntryPoint:Pointer; virtual;
Function GetModuleInfo:TKernelModuleInfo; virtual;
Function GetModuleInfo:SceKernelModuleInfo; virtual;
Function GetModuleInfoEx:SceKernelModuleInfoEx; virtual;
Function get_proc(nid:QWORD):Pointer;
Function get_proc_by_name(const name:RawByteString):Pointer;
end;
@ -948,16 +949,23 @@ begin
Result:=nil;
end;
Function TElf_node.GetModuleInfo:TKernelModuleInfo;
Function TElf_node.GetModuleInfo:SceKernelModuleInfo;
begin
Result:=Default(TKernelModuleInfo);
Result.size:=SizeOf(TKernelModuleInfo);
Result:=Default(SceKernelModuleInfo);
Result.size:=SizeOf(SceKernelModuleInfo);
MoveChar0(PChar(pFileName)^,Result.name,SCE_DBG_MAX_NAME_LENGTH);
end;
Function TElf_node.GetModuleInfoEx:SceKernelModuleInfoEx;
begin
Result:=Default(SceKernelModuleInfoEx);
Result.st_size:=SizeOf(SceKernelModuleInfoEx);
MoveChar0(PChar(pFileName)^,Result.name,SCE_DBG_MAX_NAME_LENGTH);
//segmentInfo:array[0..SCE_DBG_MAX_SEGMENTS-1] of TKernelModuleSegmentInfo;
//segmentCount:DWORD;
//fingerprint:array[0..SCE_DBG_NUM_FINGERPRINT-1] of Byte;
Result.id:=FHandle;
Result.ref_count:=1;
end;
Function TElf_node.get_proc(nid:QWORD):Pointer;

View File

@ -316,21 +316,85 @@ const
SCE_DBG_NUM_FINGERPRINT = 20;
type
TKernelModuleSegmentInfo=packed record
SceKernelModuleSegmentInfo=packed record
address:Pointer;
size:DWORD;
prot:Integer; //PF_
end;
PKernelModuleInfo=^TKernelModuleInfo;
TKernelModuleInfo=packed record
pSceKernelModuleInfo=^SceKernelModuleInfo;
SceKernelModuleInfo=packed record
size:QWORD; //Size of this structure
name:array[0..SCE_DBG_MAX_NAME_LENGTH-1] of AnsiChar; //module name
segmentInfo:array[0..SCE_DBG_MAX_SEGMENTS-1] of TKernelModuleSegmentInfo;
segmentInfo:array[0..SCE_DBG_MAX_SEGMENTS-1] of SceKernelModuleSegmentInfo;
segmentCount:DWORD;
fingerprint:array[0..SCE_DBG_NUM_FINGERPRINT-1] of Byte;
end;
pSceKernelModuleInfoEx=^SceKernelModuleInfoEx;
SceKernelModuleInfoEx=packed record
st_size:QWORD; //424
name:array[0..SCE_DBG_MAX_NAME_LENGTH-1] of AnsiChar;
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:QWORD;
eh_frame_size :DWORD;
segments:array[0..SCE_DBG_MAX_SEGMENTS-1] of SceKernelModuleSegmentInfo;
segment_count:DWORD;
ref_count :DWORD;
end;
pSceModuleInfoForUnwind=^SceModuleInfoForUnwind;
SceModuleInfoForUnwind=packed record
st_size:qword; //304
name:array[0..SCE_DBG_MAX_NAME_LENGTH-1] of AnsiChar;
eh_frame_hdr_addr:Pointer;
eh_frame_addr:Pointer;
eh_frame_size:qword;
seg0_addr:Pointer;
seg0_size:qword;
end;
type
p_eh_frame_hdr=^eh_frame_hdr;
eh_frame_hdr=packed record
version:Byte;
eh_frame_ptr_enc:Byte;
fde_count_enc:Byte;
table_enc:Byte;
encoded:record end;
//encoded eh_frame_ptr
//encoded fde_count
end;
const
DW_EH_PE_omit =$ff; // no data follows
DW_EH_PE_absptr =$00;
DW_EH_PE_pcrel =$10;
DW_EH_PE_datarel=$30;
DW_EH_PE_uleb128=$01;
DW_EH_PE_udata2 =$02;
DW_EH_PE_udata4 =$03;
DW_EH_PE_udata8 =$04;
DW_EH_PE_sleb128=$09;
DW_EH_PE_sdata2 =$0A;
DW_EH_PE_sdata4 =$0B;
DW_EH_PE_sdata8 =$0C;
type
TModuleValue=packed record
case Byte of
0:(value:Int64);