This commit is contained in:
Pavel 2023-08-04 12:06:48 +03:00
parent 8319c4c0fc
commit 72f9d833ed
8 changed files with 365 additions and 13 deletions

72
sys/kern/kern_bnet.pas Normal file
View File

@ -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.

View File

@ -8,8 +8,6 @@ interface
uses
sysutils,
mqueue,
elf64,
kern_thr,
kern_rtld,
subr_dynlib,
kern_dlsym,

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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]

View File

@ -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>

View File

@ -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);