mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
8319c4c0fc
commit
72f9d833ed
|
@ -0,0 +1,72 @@
|
|||
unit kern_bnet;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
function sys_netcontrol(fd,op:Integer;buf:Pointer;nbuf:DWORD):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
systm,
|
||||
md_arc4random;
|
||||
|
||||
function bnet_get_secure_seed():Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
arc4rand(@Result,SizeOf(Integer),0);
|
||||
end;
|
||||
|
||||
function sys_netcontrol(fd,op:Integer;buf:Pointer;nbuf:DWORD):Integer;
|
||||
var
|
||||
_kbuf:array[0..159] of Byte;
|
||||
kaddr:Pointer;
|
||||
begin
|
||||
if (buf=nil) then
|
||||
begin
|
||||
kaddr:=nil;
|
||||
end else
|
||||
begin
|
||||
if (160 < nbuf) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end else
|
||||
begin
|
||||
kaddr:=@_kbuf;
|
||||
end;
|
||||
|
||||
if ((op and QWORD($30000000))<>0) then
|
||||
begin
|
||||
Result:=copyin(buf,kaddr,nbuf);
|
||||
if (Result<>0) then Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
case op of
|
||||
$14: //bnet_get_secure_seed
|
||||
begin
|
||||
PInteger(kaddr)^:=bnet_get_secure_seed();
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled netcontrol:',op);
|
||||
Assert(False);
|
||||
Result:=EINVAL;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (buf<>nil) and (Result=0) and ((op and QWORD($30000000))<>QWORD($20000000)) then
|
||||
begin
|
||||
Result:=copyout(kaddr,buf,nbuf);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
|
@ -8,8 +8,6 @@ interface
|
|||
uses
|
||||
sysutils,
|
||||
mqueue,
|
||||
elf64,
|
||||
kern_thr,
|
||||
kern_rtld,
|
||||
subr_dynlib,
|
||||
kern_dlsym,
|
||||
|
|
|
@ -155,6 +155,7 @@ type
|
|||
|
||||
p_sym_hash_entry=^t_sym_hash_entry;
|
||||
t_sym_hash_entry=record
|
||||
link :TAILQ_ENTRY;
|
||||
nid :QWORD;
|
||||
mod_id:WORD;
|
||||
lib_id:WORD;
|
||||
|
@ -168,6 +169,7 @@ type
|
|||
attr :WORD;
|
||||
import:WORD;
|
||||
hamt :THAMT;
|
||||
syms :TAILQ_HEAD;
|
||||
end;
|
||||
|
||||
t_DoneList=record
|
||||
|
@ -2231,14 +2233,22 @@ begin
|
|||
if (Lib_Entry^.hamt=nil) then
|
||||
begin
|
||||
Lib_Entry^.hamt:=HAMT_create64;
|
||||
TAILQ_INIT(@Lib_Entry^.syms);
|
||||
end;
|
||||
//
|
||||
data:=HAMT_insert64(Lib_Entry^.hamt,nid,h_entry);
|
||||
Assert(data<>nil,'NOMEM');
|
||||
if (data^<>h_entry) then //is another exists
|
||||
//
|
||||
if (data^<>h_entry) then
|
||||
begin
|
||||
//is another exists
|
||||
FreeMem(h_entry);
|
||||
end else
|
||||
begin
|
||||
//new
|
||||
TAILQ_INSERT_TAIL(@Lib_Entry^.syms,h_entry,@h_entry^.link);
|
||||
end;
|
||||
//
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ interface
|
|||
|
||||
uses
|
||||
sysutils,
|
||||
mqueue,
|
||||
ucontext,
|
||||
kern_thr;
|
||||
|
||||
|
@ -116,11 +117,17 @@ implementation
|
|||
|
||||
uses
|
||||
errno,
|
||||
systm,
|
||||
vmparam,
|
||||
machdep,
|
||||
md_context,
|
||||
kern_sig,
|
||||
sysent;
|
||||
sysent,
|
||||
subr_dynlib,
|
||||
elf_nid_utils,
|
||||
ps4libdoc,
|
||||
kern_rtld,
|
||||
hamt;
|
||||
|
||||
const
|
||||
NOT_PCB_FULL_IRET=not PCB_FULL_IRET;
|
||||
|
@ -223,6 +230,253 @@ begin
|
|||
td^.pcb_flags:=f;
|
||||
end;
|
||||
|
||||
function fuptr(var base:Pointer):Pointer;
|
||||
begin
|
||||
Result:=nil;
|
||||
copyin(@base,@Result,SizeOf(Pointer));
|
||||
end;
|
||||
|
||||
function fuptr(var base:QWORD):QWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
copyin(@base,@Result,SizeOf(QWORD));
|
||||
end;
|
||||
|
||||
function CaptureBacktrace(rbp:PPointer;skipframes,count:sizeint;frames:PCodePointer):sizeint;
|
||||
var
|
||||
adr:Pointer;
|
||||
begin
|
||||
Result:=0;
|
||||
while (rbp<>nil) and
|
||||
(rbp<>Pointer(QWORD(-1))) do
|
||||
begin
|
||||
adr:=fuptr(rbp[1]);
|
||||
rbp:=fuptr(rbp[0]);
|
||||
|
||||
if (adr<>nil) then
|
||||
begin
|
||||
if (skipframes<>0) then
|
||||
begin
|
||||
Dec(skipframes);
|
||||
end else
|
||||
if (count<>0) then
|
||||
begin
|
||||
frames[0]:=adr;
|
||||
Dec(count);
|
||||
Inc(frames);
|
||||
Inc(Result);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
TLQRec=record
|
||||
Base :Pointer;
|
||||
Addr :Pointer;
|
||||
LastAdr:Pointer;
|
||||
LastNid:QWORD;
|
||||
end;
|
||||
|
||||
Function trav_proc(h_entry:p_sym_hash_entry;var r:TLQRec):Integer;
|
||||
var
|
||||
adr:Pointer;
|
||||
begin
|
||||
Result:=0;
|
||||
adr:=r.Base+fuptr(h_entry^.sym.st_value);
|
||||
if (adr<=r.Addr) then
|
||||
if (adr>r.LastAdr) then
|
||||
begin
|
||||
r.LastAdr:=adr;
|
||||
r.LastNid:=fuptr(h_entry^.nid);
|
||||
Result:=1;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function find_proc_lib_entry(lib_entry:p_Lib_Entry;var r:TLQRec):Integer;
|
||||
var
|
||||
h_entry:p_sym_hash_entry;
|
||||
begin
|
||||
Result:=0;
|
||||
h_entry:=fuptr(lib_entry^.syms.tqh_first);
|
||||
while (h_entry<>nil) do
|
||||
begin
|
||||
Result:=Result+trav_proc(h_entry,r);
|
||||
h_entry:=fuptr(h_entry^.link.tqe_next);
|
||||
end;
|
||||
end;
|
||||
|
||||
Function find_proc_obj(obj:p_lib_info;var r:TLQRec):Integer;
|
||||
var
|
||||
lib_entry:p_Lib_Entry;
|
||||
begin
|
||||
Result:=0;
|
||||
lib_entry:=fuptr(obj^.lib_table.tqh_first);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
Result:=Result+find_proc_lib_entry(lib_entry,r);
|
||||
lib_entry:=fuptr(lib_entry^.link.tqe_next);
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
TDynlibLineInfo=record
|
||||
func :shortstring;
|
||||
source :shortstring;
|
||||
base_addr:ptruint;
|
||||
func_addr:ptruint;
|
||||
end;
|
||||
|
||||
function GetDynlibLineInfo(addr:ptruint;var info:TDynlibLineInfo):boolean;
|
||||
var
|
||||
obj:p_lib_info;
|
||||
r:TLQRec;
|
||||
adr:QWORD;
|
||||
begin
|
||||
Result:=False;
|
||||
dynlibs_lock;
|
||||
|
||||
obj:=fuptr(dynlibs_info.obj_list.tqh_first);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if (Pointer(addr)>=obj^.map_base) and
|
||||
(Pointer(addr)<(obj^.map_base+obj^.map_size)) then
|
||||
begin
|
||||
r:=Default(TLQRec);
|
||||
r.Addr:=Pointer(addr);
|
||||
r.Base:=fuptr(obj^.map_base);
|
||||
|
||||
info.base_addr:=QWORD(r.Base);
|
||||
info.source:=dynlib_basename(obj^.lib_path);
|
||||
|
||||
if (find_proc_obj(obj,r)<>0) then
|
||||
begin
|
||||
info.func:=ps4libdoc.GetFunctName(r.LastNid);
|
||||
if (info.func='Unknow') then
|
||||
begin
|
||||
info.func:=EncodeValue64(r.LastNid);
|
||||
end;
|
||||
info.func_addr:=QWORD(r.LastAdr);
|
||||
Result:=True;
|
||||
end else
|
||||
begin
|
||||
info.func_addr:=0;
|
||||
|
||||
adr:=QWORD(obj^.init_proc_addr);
|
||||
if (adr<=QWORD(r.Addr)) then
|
||||
if (adr>info.func_addr) then
|
||||
begin
|
||||
info.func:='dtInit';
|
||||
info.func_addr:=adr;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
adr:=QWORD(obj^.fini_proc_addr);
|
||||
if (adr<=QWORD(r.Addr)) then
|
||||
if (adr>info.func_addr) then
|
||||
begin
|
||||
info.func:='dtFini';
|
||||
info.func_addr:=adr;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
adr:=QWORD(obj^.entry_addr);
|
||||
if (adr<=QWORD(r.Addr)) then
|
||||
if (adr>info.func_addr) then
|
||||
begin
|
||||
info.func:='Entry';
|
||||
info.func_addr:=adr;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
dynlibs_unlock;
|
||||
Exit;
|
||||
end;
|
||||
//
|
||||
obj:=fuptr(obj^.link.tqe_next);
|
||||
end;
|
||||
|
||||
dynlibs_unlock;
|
||||
end;
|
||||
|
||||
function find_obj_by_handle(id:Integer):p_lib_info;
|
||||
var
|
||||
obj:p_lib_info;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if (obj^.id=id) then
|
||||
begin
|
||||
Exit(obj);
|
||||
end;
|
||||
//
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure print_frame(var f:text;frame:Pointer);
|
||||
var
|
||||
info:TDynlibLineInfo;
|
||||
offset1:QWORD;
|
||||
offset2:QWORD;
|
||||
//line:longint;
|
||||
begin
|
||||
if is_guest_addr(ptruint(frame)) then
|
||||
begin
|
||||
info:=Default(TDynlibLineInfo);
|
||||
|
||||
if GetDynlibLineInfo(ptruint(frame),info) then
|
||||
begin
|
||||
offset1:=QWORD(frame)-QWORD(info.base_addr);
|
||||
offset2:=QWORD(frame)-QWORD(info.func_addr);
|
||||
|
||||
Writeln(f,' offset $',HexStr(offset1,6),' ',info.source,':',info.func,'+$',HexStr(offset2,6));
|
||||
|
||||
end else
|
||||
begin
|
||||
Writeln(f,' 0x',HexStr(frame),' ',info.source);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Writeln(f,BackTraceStrFunc(frame));
|
||||
end;
|
||||
|
||||
//if GetLineInfo(ptruint(frame),func,source,line) then
|
||||
//begin
|
||||
// Writeln(f,' 0x',HexStr(frame),':',func,':',source);
|
||||
//end};
|
||||
|
||||
//Writeln(f,BackTraceStrFunc(frame));
|
||||
end;
|
||||
|
||||
procedure print_backtrace(var f:text;rip,rbp:Pointer;skipframes:sizeint);
|
||||
var
|
||||
i,count:sizeint;
|
||||
frames:array [0..255] of codepointer;
|
||||
begin
|
||||
count:=max_frame_dump;
|
||||
count:=20;
|
||||
|
||||
print_frame(f,rip);
|
||||
|
||||
count:=CaptureBacktrace(rbp,skipframes,count,@frames[0]);
|
||||
|
||||
if (count<>0) then
|
||||
for i:=0 to count-1 do
|
||||
begin
|
||||
print_frame(f,frames[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
tsyscall=function(rdi,rsi,rdx,rcx,r8,r9:QWORD):Integer;
|
||||
|
||||
|
@ -257,6 +511,8 @@ begin
|
|||
Writeln(' [5]:0x',HexStr(td_frame^.tf_r8 ,16));
|
||||
Writeln(' [6]:0x',HexStr(td_frame^.tf_r9 ,16));
|
||||
|
||||
print_backtrace(StdErr,Pointer(td_frame^.tf_rip),Pointer(td_frame^.tf_rbp),0);
|
||||
|
||||
Assert(false,sysent_table[td_frame^.tf_rax].sy_name);
|
||||
end;
|
||||
end else
|
||||
|
@ -271,6 +527,8 @@ begin
|
|||
Writeln(' [5]:0x',HexStr(td_frame^.tf_r8 ,16));
|
||||
Writeln(' [6]:0x',HexStr(td_frame^.tf_r9 ,16));
|
||||
|
||||
print_backtrace(StdErr,Pointer(td_frame^.tf_rip),Pointer(td_frame^.tf_rbp),0);
|
||||
|
||||
Assert(false,IntToStr(td_frame^.tf_rax));
|
||||
end else
|
||||
begin
|
||||
|
@ -286,12 +544,12 @@ begin
|
|||
if is_guest_addr(td_frame^.tf_rip) then
|
||||
begin
|
||||
Writeln('Guest syscall:',sysent_table[td_frame^.tf_rax].sy_name);
|
||||
Writeln(' [1]:0x',HexStr(td_frame^.tf_rdi,16));
|
||||
Writeln(' [2]:0x',HexStr(td_frame^.tf_rsi,16));
|
||||
Writeln(' [3]:0x',HexStr(td_frame^.tf_rdx,16));
|
||||
Writeln(' [4]:0x',HexStr(td_frame^.tf_r10,16));
|
||||
Writeln(' [5]:0x',HexStr(td_frame^.tf_r8 ,16));
|
||||
Writeln(' [6]:0x',HexStr(td_frame^.tf_r9 ,16));
|
||||
//Writeln(' [1]:0x',HexStr(td_frame^.tf_rdi,16));
|
||||
//Writeln(' [2]:0x',HexStr(td_frame^.tf_rsi,16));
|
||||
//Writeln(' [3]:0x',HexStr(td_frame^.tf_rdx,16));
|
||||
//Writeln(' [4]:0x',HexStr(td_frame^.tf_r10,16));
|
||||
//Writeln(' [5]:0x',HexStr(td_frame^.tf_r8 ,16));
|
||||
//Writeln(' [6]:0x',HexStr(td_frame^.tf_r9 ,16));
|
||||
end;
|
||||
|
||||
error:=scall(td_frame^.tf_rdi,
|
||||
|
|
|
@ -58,6 +58,7 @@ function _fcntl(fd,cmd:Integer;arg:QWORD):Integer;
|
|||
function select(nd:Integer;uin,uou,uex,utv:Pointer):Integer;
|
||||
function fsync(fd:Integer):Integer;
|
||||
function setpriority(which,who,prio:Integer):Integer;
|
||||
function __sys_netcontrol(fd,op:Integer;buf:Pointer;nbuf:DWORD):Integer;
|
||||
function getpriority(which,who:Integer):Integer;
|
||||
function gettimeofday(tp,tzp:Pointer):Integer;
|
||||
function getrusage(who:Integer;rusage:Pointer):Integer;
|
||||
|
@ -605,6 +606,13 @@ asm
|
|||
jmp cerror
|
||||
end;
|
||||
|
||||
function __sys_netcontrol(fd,op:Integer;buf:Pointer;nbuf:DWORD):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $99,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function getpriority(which,who:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $100,%rax
|
||||
|
|
|
@ -13,6 +13,7 @@ uses
|
|||
kern_evf,
|
||||
kern_gpo,
|
||||
kern_sig,
|
||||
kern_bnet,
|
||||
kern_dmem,
|
||||
kern_exec,
|
||||
kern_exit,
|
||||
|
@ -552,7 +553,7 @@ const
|
|||
),
|
||||
(//[99]
|
||||
sy_narg:4;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_netcontrol;
|
||||
sy_name:'sys_netcontrol'
|
||||
),
|
||||
(//[100]
|
||||
|
|
|
@ -645,6 +645,10 @@
|
|||
<Filename Value="..\vm\dmem_map.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\kern\kern_bnet.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -655,7 +659,7 @@
|
|||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir);.."/>
|
||||
<OtherUnitFiles Value="..;..\..\rtl;..\..\kernel\libthr;..\kern;..\vm;..\vfs;..\fs\deadfs;..\fs\devfs;..\fs\fdescfs;..\fs\nullfs;..\fs\ufs;..\md;..\dev"/>
|
||||
<OtherUnitFiles Value="..;..\..\rtl;..\..\kernel\libthr;..\kern;..\vm;..\vfs;..\fs\deadfs;..\fs\devfs;..\fs\fdescfs;..\fs\nullfs;..\fs\ufs;..\md;..\dev;..\.."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
|
|
|
@ -96,7 +96,8 @@ uses
|
|||
kern_budget,
|
||||
kern_regmgr,
|
||||
kern_authinfo,
|
||||
kern_dmem;
|
||||
kern_dmem,
|
||||
kern_bnet;
|
||||
|
||||
const
|
||||
PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);
|
||||
|
|
Loading…
Reference in New Issue