mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
7e736eab78
commit
59368f3b13
|
@ -1462,6 +1462,15 @@
|
|||
<Filename Value="src\audio\audioout_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="src\ps4_libsceappcontent.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceAppContent"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="sys\sockopt.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -208,7 +208,7 @@ var
|
|||
),
|
||||
(//[30]
|
||||
sy_narg:3;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_accept;
|
||||
sy_name:'sys_accept'
|
||||
),
|
||||
(//[31]
|
||||
|
@ -578,17 +578,17 @@ var
|
|||
),
|
||||
(//[104]
|
||||
sy_narg:3;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_bind;
|
||||
sy_name:'sys_bind'
|
||||
),
|
||||
(//[105]
|
||||
sy_narg:5;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_setsockopt;
|
||||
sy_name:'sys_setsockopt'
|
||||
),
|
||||
(//[106]
|
||||
sy_narg:2;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_listen;
|
||||
sy_name:'sys_listen'
|
||||
),
|
||||
(//[107]
|
||||
|
|
|
@ -698,10 +698,10 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
Writeln('DMEM_LIMIT =0x',HexStr(DMEM_LIMIT,16));
|
||||
Writeln('FMEM_LIMIT =0x',HexStr(FMEM_LIMIT,16));
|
||||
Writeln('BigAppMem =0x',HexStr(BigAppMemory,16));
|
||||
Writeln('game_fmem_size =0x',HexStr(game_fmem_size,16));
|
||||
Writeln('DMEM_LIMIT =0x',HexStr(DMEM_LIMIT,16));
|
||||
Writeln('FMEM_LIMIT =0x',HexStr(FMEM_LIMIT,16));
|
||||
Writeln('BigAppMem =0x',HexStr(BigAppMemory,16));
|
||||
Writeln('game_fmem_size =0x',HexStr(game_fmem_size,16));
|
||||
//
|
||||
Writeln('vm_budget_dmem_alloc=0x',HexStr(vm_budget_limit(PTYPE_BIG_APP,field_dmem_alloc),16));
|
||||
Writeln('vm_budget_mlock =0x',HexStr(vm_budget_limit(PTYPE_BIG_APP,field_mlock ),16));
|
||||
|
|
|
@ -8,22 +8,65 @@ interface
|
|||
function sys_socket(domain,stype,protocol:Integer):Integer;
|
||||
function sys_socketex(name:pchar;domain,stype,protocol:Integer):Integer;
|
||||
function sys_socketclose(fd:Integer):Integer;
|
||||
function sys_bind(s:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
function sys_listen(s,backlog:Integer):Integer;
|
||||
function sys_accept(s:Integer;aname,anamelen:Pointer):Integer;
|
||||
function sys_connect(fd:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
function sys_setsockopt(s,level,name:Integer;val:Pointer;valsize:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
mqueue,
|
||||
systm,
|
||||
kern_thr,
|
||||
kern_descrip,
|
||||
sys_conf,
|
||||
vsocket,
|
||||
sockopt,
|
||||
vsocketvar,
|
||||
vuio,
|
||||
vfile,
|
||||
vfcntl,
|
||||
vcapability,
|
||||
subr_backtrace;
|
||||
|
||||
{
|
||||
Convert a user file descriptor to a kernel file entry and check that, if
|
||||
it is a capability, the right rights are present. A reference on the file
|
||||
entry is held upon returning.
|
||||
}
|
||||
function getsock_cap(fd :Integer;
|
||||
rights:cap_rights_t;
|
||||
fpp :pp_file;
|
||||
fflagp:PDWORD):Integer;
|
||||
var
|
||||
fp:p_file;
|
||||
begin
|
||||
fp:=fget_unlocked(fd);
|
||||
|
||||
if (fp=nil) then
|
||||
begin
|
||||
Exit(EBADF);
|
||||
end;
|
||||
|
||||
if (fp^.f_type<>DTYPE_SOCKET) and
|
||||
(fp^.f_type<>DTYPE_IPCSOCKET) then
|
||||
begin
|
||||
fdrop(fp);
|
||||
Exit(ENOTSOCK);
|
||||
end;
|
||||
|
||||
if (fflagp<>nil) then
|
||||
begin
|
||||
fflagp^:=fp^.f_flag;
|
||||
end;
|
||||
|
||||
fpp^:=fp;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function soo_ioctl(fp:p_file;com:QWORD;data:Pointer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -124,41 +167,6 @@ begin
|
|||
Result:=kern_close(fd);
|
||||
end;
|
||||
|
||||
{
|
||||
Convert a user file descriptor to a kernel file entry and check that, if
|
||||
it is a capability, the right rights are present. A reference on the file
|
||||
entry is held upon returning.
|
||||
}
|
||||
function getsock_cap(fd :Integer;
|
||||
rights:cap_rights_t;
|
||||
fpp :pp_file;
|
||||
fflagp:PDWORD):Integer;
|
||||
var
|
||||
fp:p_file;
|
||||
begin
|
||||
fp:=fget_unlocked(fd);
|
||||
|
||||
if (fp=nil) then
|
||||
begin
|
||||
Exit(EBADF);
|
||||
end;
|
||||
|
||||
if (fp^.f_type<>DTYPE_SOCKET) and
|
||||
(fp^.f_type<>DTYPE_IPCSOCKET) then
|
||||
begin
|
||||
fdrop(fp);
|
||||
Exit(ENOTSOCK);
|
||||
end;
|
||||
|
||||
if (fflagp<>nil) then
|
||||
begin
|
||||
fflagp^:=fp^.f_flag;
|
||||
end;
|
||||
|
||||
fpp^:=fp;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function getsockaddr(namp:pp_sockaddr;uaddr:Pointer;len:size_t):Integer;
|
||||
var
|
||||
sa:p_sockaddr;
|
||||
|
@ -189,6 +197,42 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function kern_bind(fd:Integer;sa:p_sockaddr):Integer;
|
||||
var
|
||||
//so:p_socket;
|
||||
fp:p_file;
|
||||
error:Integer;
|
||||
begin
|
||||
error:=getsock_cap(fd, CAP_BIND, @fp, nil);
|
||||
if (error<>0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
//so:=fp^.f_data;
|
||||
//error:=sobind(so, sa, td);
|
||||
fdrop(fp);
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function sys_bind(s:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
var
|
||||
sa:p_sockaddr;
|
||||
error:Integer;
|
||||
begin
|
||||
error:=getsockaddr(@sa, name, namelen);
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
error:=kern_bind(s, sa);
|
||||
|
||||
FreeMem(sa);
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function kern_connect(fd:Integer;sa:p_sockaddr):Integer;
|
||||
var
|
||||
fp:p_file;
|
||||
|
@ -202,6 +246,307 @@ begin
|
|||
fdrop(fp);
|
||||
end;
|
||||
|
||||
function sys_listen(s,backlog:Integer):Integer;
|
||||
var
|
||||
//so:p_socket;
|
||||
fp:p_file;
|
||||
error:Integer;
|
||||
begin
|
||||
error:=getsock_cap(s, CAP_LISTEN, @fp, nil);
|
||||
if (error=0) then
|
||||
begin
|
||||
//so:=fp^.f_data;
|
||||
//error:=solisten(so, uap^.backlog, td);
|
||||
fdrop(fp);
|
||||
end;
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function kern_accept(s:Integer;name:pp_sockaddr;
|
||||
namelen:p_socklen_t;fp:pp_file):Integer;
|
||||
label
|
||||
done,
|
||||
noconnection;
|
||||
var
|
||||
td:p_kthread;
|
||||
headfp,nfp:p_file;
|
||||
sa:p_sockaddr;
|
||||
error:Integer;
|
||||
//so,head:p_socket;
|
||||
fd:Integer;
|
||||
fflag:DWORD;
|
||||
pgid:Integer; //pid_t
|
||||
tmp:Integer;
|
||||
begin
|
||||
td:=curkthread;
|
||||
headfp:=nil;
|
||||
nfp :=nil;
|
||||
sa :=nil;
|
||||
|
||||
if (name<>nil) then
|
||||
begin
|
||||
name^:=nil;
|
||||
if (namelen^ < 0) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
end;
|
||||
|
||||
error:=getsock_cap(s, CAP_ACCEPT, @headfp, @fflag);
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
{
|
||||
head:=headfp^.f_data;
|
||||
if ((head^.so_options and SO_ACCEPTCONN)=0) then
|
||||
begin
|
||||
error:=EINVAL;
|
||||
goto done;
|
||||
end;
|
||||
}
|
||||
|
||||
error:=falloc(@nfp, @fd, 0);
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
goto done;
|
||||
end;
|
||||
|
||||
//////////////////
|
||||
error:=EWOULDBLOCK;
|
||||
goto noconnection;
|
||||
//////////////////
|
||||
|
||||
ACCEPT_LOCK();
|
||||
|
||||
{
|
||||
if (((head^.so_state and SS_NBIO)<>0) and TAILQ_EMPTY(@head^.so_comp)) then
|
||||
begin
|
||||
ACCEPT_UNLOCK();
|
||||
error:=EWOULDBLOCK;
|
||||
goto noconnection;
|
||||
end;
|
||||
}
|
||||
|
||||
{
|
||||
while ((TAILQ_EMPTY(@head^.so_comp)) and (head^.so_error=0)) do
|
||||
begin
|
||||
if (head^.so_rcv.sb_state & SBS_CANTRCVMORE) then
|
||||
begin
|
||||
head^.so_error:=ECONNABORTED;
|
||||
break;
|
||||
end;
|
||||
error:=msleep(@head^.so_timeo, @accept_mtx, PSOCK or PCATCH, 'accept', 0);
|
||||
if (error) then
|
||||
begin
|
||||
ACCEPT_UNLOCK();
|
||||
goto noconnection;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
|
||||
{
|
||||
if (head^.so_error<>0) then
|
||||
begin
|
||||
error:=head^.so_error;
|
||||
head^.so_error:=0;
|
||||
ACCEPT_UNLOCK();
|
||||
goto noconnection;
|
||||
end;
|
||||
}
|
||||
|
||||
{
|
||||
so:=TAILQ_FIRST(@head^.so_comp);
|
||||
Assert(not (so^.so_qstate and SQ_INCOMP), 'accept1: so SQ_INCOMP');
|
||||
Assert(so^.so_qstate and SQ_COMP, 'accept1: so not SQ_COMP');
|
||||
}
|
||||
|
||||
{
|
||||
* Before changing the flags on the socket, we have to bump the
|
||||
* reference count. Otherwise, if the protocol calls sofree(),
|
||||
* the socket will be released due to a zero refcount.
|
||||
}
|
||||
|
||||
{
|
||||
SOCK_LOCK(so); { soref() and so_state update }
|
||||
soref(so); { file descriptor reference }
|
||||
|
||||
TAILQ_REMOVE(@head^.so_comp, so, so_list);
|
||||
Dec(head^.so_qlen);
|
||||
so^.so_state :=so^.so_state or (head^.so_state and SS_NBIO);
|
||||
so^.so_qstate:=so^.so_qstate and (not SQ_COMP);
|
||||
so^.so_head :=nil;
|
||||
|
||||
SOCK_UNLOCK(so);
|
||||
}
|
||||
|
||||
ACCEPT_UNLOCK();
|
||||
|
||||
|
||||
{ An extra reference on `nfp' has been held for us by falloc(). }
|
||||
td^.td_retval[0]:=fd;
|
||||
|
||||
{
|
||||
{ connection has been removed from the listen queue }
|
||||
KNOTE_UNLOCKED(@head^.so_rcv.sb_sel.si_note, 0);
|
||||
|
||||
pgid:=fgetown(@head^.so_sigio);
|
||||
if (pgid<>0) then
|
||||
begin
|
||||
fsetown(pgid, @so^.so_sigio);
|
||||
end;
|
||||
|
||||
finit(nfp, fflag, DTYPE_SOCKET, so, @socketops);
|
||||
|
||||
{ Sync socket nonblocking/async state with file flags }
|
||||
tmp:=fflag and FNONBLOCK;
|
||||
fo_ioctl(nfp, FIONBIO, @tmp, td^.td_ucred, td);
|
||||
|
||||
tmp:=fflag and FASYNC;
|
||||
fo_ioctl(nfp, FIOASYNC, @tmp, td^.td_ucred, td);
|
||||
|
||||
sa:=0;
|
||||
error:=soaccept(so, @sa);
|
||||
}
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
{
|
||||
* Exit a namelen of zero for older code which might
|
||||
* ignore the Exit value from accept.
|
||||
}
|
||||
if (name<>nil) then
|
||||
begin
|
||||
namelen^:=0;
|
||||
end;
|
||||
goto noconnection;
|
||||
end;
|
||||
|
||||
if (sa=nil) then
|
||||
begin
|
||||
if (name<>nil) then
|
||||
begin
|
||||
namelen^:=0;
|
||||
end;
|
||||
goto done;
|
||||
end;
|
||||
|
||||
if (name<>nil) then
|
||||
begin
|
||||
{ check sa_len before it is destroyed }
|
||||
if (namelen^ > sa^.sa_len) then
|
||||
begin
|
||||
namelen^:=sa^.sa_len;
|
||||
end;
|
||||
|
||||
name^:=sa;
|
||||
sa:=nil;
|
||||
end;
|
||||
|
||||
noconnection:
|
||||
if (sa<>nil) then
|
||||
begin
|
||||
FreeMem(sa);
|
||||
end;
|
||||
|
||||
{
|
||||
* close the new descriptor, assuming someone hasn't ripped it
|
||||
* out from under us.
|
||||
}
|
||||
if (error<>0) then
|
||||
begin
|
||||
fdclose(nfp, fd);
|
||||
end;
|
||||
|
||||
{
|
||||
* Release explicitly held references before Exiting. We Exit
|
||||
* a reference on nfp to the caller on success if they request it.
|
||||
}
|
||||
done:
|
||||
if (fp<>nil) then
|
||||
begin
|
||||
if (error=0) then
|
||||
begin
|
||||
fp^:=nfp;
|
||||
nfp:=nil;
|
||||
end else
|
||||
begin
|
||||
fp^:=nil;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
if (nfp<>nil) then
|
||||
begin
|
||||
fdrop(nfp);
|
||||
end;
|
||||
fdrop(headfp);
|
||||
//
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function accept1(s:Integer;aname:p_sockaddr;anamelen:p_socklen_t):Integer;
|
||||
var
|
||||
td:p_kthread;
|
||||
name:p_sockaddr;
|
||||
namelen:socklen_t;
|
||||
fp:p_file;
|
||||
error:Integer;
|
||||
begin
|
||||
td:=curkthread;
|
||||
|
||||
if (aname=nil) then
|
||||
begin
|
||||
Exit(kern_accept(s, nil, nil, nil));
|
||||
end;
|
||||
|
||||
error:=copyin(anamelen, @namelen, sizeof(namelen));
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
error:=kern_accept(s, @name, @namelen, @fp);
|
||||
|
||||
{
|
||||
* Exit a namelen of zero for older code which might
|
||||
* ignore the Exit value from accept.
|
||||
}
|
||||
if (error<>0) then
|
||||
begin
|
||||
copyout(@namelen, anamelen, sizeof(anamelen^));
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
if (error=0) and (name<>nil) then
|
||||
begin
|
||||
error:=copyout(name, name, namelen);
|
||||
end;
|
||||
|
||||
if (error=0) then
|
||||
begin
|
||||
error:=copyout(@namelen,anamelen,sizeof(namelen));
|
||||
end;
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
fdclose(fp, td^.td_retval[0]);
|
||||
end;
|
||||
|
||||
fdrop(fp);
|
||||
FreeMem(name);
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function sys_accept(s:Integer;aname,anamelen:Pointer):Integer;
|
||||
begin
|
||||
Exit(accept1(s,aname,anamelen));
|
||||
end;
|
||||
|
||||
function sys_connect(fd:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
var
|
||||
sa:p_sockaddr;
|
||||
|
@ -215,5 +560,52 @@ begin
|
|||
FreeMem(sa);
|
||||
end;
|
||||
|
||||
function kern_setsockopt(s,level,name:Integer;val:Pointer;valseg:uio_seg;valsize:Integer):Integer;
|
||||
var
|
||||
error:Integer;
|
||||
//so:p_socket;
|
||||
fp:p_file;
|
||||
sopt:t_sockopt;
|
||||
begin
|
||||
if (val=nil) and (valsize<>0) then
|
||||
begin
|
||||
Exit(EFAULT);
|
||||
end;
|
||||
|
||||
if (valsize < 0) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
sopt.sopt_dir :=SOPT_SET;
|
||||
sopt.sopt_level :=level;
|
||||
sopt.sopt_name :=name;
|
||||
sopt.sopt_val :=val;
|
||||
sopt.sopt_valsize:=valsize;
|
||||
|
||||
case (valseg) of
|
||||
UIO_USERSPACE:sopt.sopt_td:=curkthread;
|
||||
UIO_SYSSPACE :sopt.sopt_td:=nil;
|
||||
else
|
||||
Assert(false,'kern_setsockopt called with bad valseg');
|
||||
end;
|
||||
|
||||
error:=getsock_cap(s, CAP_SETSOCKOPT, @fp, nil);
|
||||
if (error=0) then
|
||||
begin
|
||||
//so:=fp->f_data;
|
||||
//error:=sosetopt(so, @sopt);
|
||||
fdrop(fp);
|
||||
end;
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function sys_setsockopt(s,level,name:Integer;val:Pointer;valsize:Integer):Integer;
|
||||
begin
|
||||
Result:=kern_setsockopt(s,level,name,val,UIO_USERSPACE,valsize);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
unit sockopt;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
t_sopt_dir=(SOPT_GET,SOPT_SET);
|
||||
|
||||
t_sockopt=record
|
||||
sopt_dir :t_sopt_dir;
|
||||
sopt_level :Integer;
|
||||
sopt_name :Integer;
|
||||
sopt_val :Pointer;
|
||||
sopt_valsize:QWORD;
|
||||
sopt_td :Pointer; //p_kthread;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -26,6 +26,7 @@ function unmount(path:PChar;flags:Integer):Integer;
|
|||
function setuid(uid:Integer):Integer;
|
||||
function getuid():Integer;
|
||||
function geteuid():Integer;
|
||||
function _accept(s:Integer;aname,anamelen:Pointer):Integer;
|
||||
function access(path:PChar;flags:Integer):Integer;
|
||||
function chflags(path:PChar;flags:Integer):Integer;
|
||||
function fchflags(fd,flags:Integer):Integer;
|
||||
|
@ -63,6 +64,9 @@ function socket(domain,stype,protocol:Integer):Integer;
|
|||
function _connect(fd:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
function __sys_netcontrol(fd,op:Integer;buf:Pointer;nbuf:DWORD):Integer;
|
||||
function getpriority(which,who:Integer):Integer;
|
||||
function _bind(s:Integer;name:Pointer;namelen:Integer):Integer;
|
||||
function _setsockopt(s,level,name:Integer;val:Pointer;valsize:Integer):Integer;
|
||||
function _listen(s,backlog:Integer):Integer;
|
||||
function __sys_socketex(name:pchar;domain,stype,protocol:Integer):Integer;
|
||||
function __sys_socketclose(fd:Integer):Integer;
|
||||
function gettimeofday(tp,tzp:Pointer):Integer;
|
||||
|
@ -395,6 +399,13 @@ asm
|
|||
jmp cerror
|
||||
end;
|
||||
|
||||
function _accept(s:Integer;aname,anamelen:Pointer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $30,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function access(path:PChar;flags:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $33,%rax
|
||||
|
@ -654,6 +665,27 @@ asm
|
|||
jmp cerror
|
||||
end;
|
||||
|
||||
function _bind(s:Integer;name:Pointer;namelen:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $104,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function _setsockopt(s,level,name:Integer;val:Pointer;valsize:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $105,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function _listen(s,backlog:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $106,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function __sys_socketex(name:pchar;domain,stype,protocol:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $113,%rax
|
||||
|
|
|
@ -17,7 +17,9 @@ uses
|
|||
}
|
||||
type
|
||||
sa_family_t=Byte;
|
||||
socklen_t =DWORD;
|
||||
|
||||
p_socklen_t=^socklen_t;
|
||||
socklen_t =Integer;
|
||||
|
||||
const
|
||||
//socket types
|
||||
|
|
Loading…
Reference in New Issue