mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
5cf6bf9908
commit
798b0b2cce
|
@ -22,6 +22,7 @@ type
|
|||
|
||||
procedure add_patch_link (_obj,vaddr:Pointer;ptype:t_patch_type;stub:p_stub_chunk);
|
||||
procedure free_patch_link(_obj:Pointer;node:p_patch_node);
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
|
||||
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
|
||||
|
||||
|
@ -32,6 +33,7 @@ uses
|
|||
kern_rwlock,
|
||||
kern_thr,
|
||||
vm,
|
||||
vmparam,
|
||||
vm_map,
|
||||
vm_mmap,
|
||||
vm_object,
|
||||
|
@ -67,6 +69,33 @@ begin
|
|||
FreeMem(node);
|
||||
end;
|
||||
|
||||
function OFF_TO_IDX(x:Pointer):DWORD; inline;
|
||||
begin
|
||||
Result:=QWORD(x) shr PAGE_SHIFT;
|
||||
end;
|
||||
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
entry,next:p_patch_node;
|
||||
begin
|
||||
obj:=_obj;
|
||||
|
||||
entry:=TAILQ_FIRST(@obj^.patchq);
|
||||
while (entry<>nil) do
|
||||
begin
|
||||
next:=TAILQ_NEXT(entry,@entry^.link);
|
||||
//
|
||||
if ((start=0) or (OFF_TO_IDX(entry^.vaddr)>=start)) and
|
||||
((__end=0) or (OFF_TO_IDX(entry^.vaddr)<=__end)) then
|
||||
begin
|
||||
free_patch_link(_obj,entry);
|
||||
end;
|
||||
//
|
||||
entry:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
64 48 A1 [0000000000000000] mov rax,fs:[$0000000000000000] -> 65 48 A1 [0807000000000000] mov rax,gs:[$0000000000000708]
|
||||
64 48 8B 04 25 [00000000] mov rax,fs:[$00000000] -> 65 48 8B 04 25 [08070000] mov rax,gs:[$00000708]
|
||||
|
|
|
@ -443,6 +443,8 @@ end;
|
|||
|
||||
function relocate_one_object(obj:p_lib_info;jmpslots:Integer):Integer;
|
||||
begin
|
||||
Writeln(' relocate:',dynlib_basename(obj^.lib_path));
|
||||
|
||||
Result:=reloc_non_plt(obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
|
|
|
@ -524,6 +524,19 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function get_char_sep(path:pchar):char; inline;
|
||||
const
|
||||
c_host='/host/';
|
||||
begin
|
||||
if (StrLComp(path,c_host,Length(c_host))=0) then
|
||||
begin
|
||||
Result:='\';
|
||||
end else
|
||||
begin
|
||||
Result:='/';
|
||||
end;
|
||||
end;
|
||||
|
||||
function rtld_dirname(path,bname:pchar):Integer;
|
||||
var
|
||||
endp:pchar;
|
||||
|
@ -539,13 +552,7 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
if (StrLComp(path,'/host/',Length('/host/'))=0) then
|
||||
begin
|
||||
chr:='/';
|
||||
end else
|
||||
begin
|
||||
chr:='\';
|
||||
end;
|
||||
chr:=get_char_sep(path);
|
||||
|
||||
{ Strip trailing slashes }
|
||||
endp:=path + strlen(path) - 1;
|
||||
|
@ -1140,26 +1147,10 @@ begin
|
|||
end;
|
||||
|
||||
function is_system_path(path:pchar):Boolean;
|
||||
var
|
||||
f:RawByteString;
|
||||
begin
|
||||
f:='/'+p_proc.p_randomized_path;
|
||||
Result:=StrLComp(pchar(f),path,Length(f))=0;
|
||||
end;
|
||||
|
||||
function is_libc_or_fios(path:pchar):Boolean;
|
||||
var
|
||||
f:RawByteString;
|
||||
begin
|
||||
f:=ExtractFileName(path);
|
||||
f:=ChangeFileExt(f,'');
|
||||
case f of
|
||||
'libc',
|
||||
'libSceFios2':
|
||||
Result:=True;
|
||||
else
|
||||
Result:=False;
|
||||
end;
|
||||
if (path=nil) then Exit(False);
|
||||
if (path[0]<>'/') then Exit(False);
|
||||
Result:=StrLComp(p_proc.p_randomized_path,@path[1],Length(p_proc.p_randomized_path))=0;
|
||||
end;
|
||||
|
||||
function dynlib_basename(path:pchar):pchar;
|
||||
|
@ -1167,13 +1158,7 @@ var
|
|||
idx:pchar;
|
||||
chr:char;
|
||||
begin
|
||||
if (StrLComp(path,'/host/',Length('/host/'))=0) then
|
||||
begin
|
||||
chr:='/';
|
||||
end else
|
||||
begin
|
||||
chr:='\';
|
||||
end;
|
||||
chr:=get_char_sep(path);
|
||||
|
||||
idx:=strrscan(path,chr);
|
||||
if (idx=nil) then
|
||||
|
@ -1185,5 +1170,25 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function is_libc_or_fios(path:pchar):Boolean;
|
||||
const
|
||||
c_libc='libc.';
|
||||
c_libSceFios2='libSceFios2.';
|
||||
var
|
||||
f:pchar;
|
||||
begin
|
||||
f:=dynlib_basename(path);
|
||||
|
||||
if (StrLComp(f,c_libc,Length(c_libc))=0) or
|
||||
(StrLComp(f,c_libSceFios2,Length(c_libSceFios2))=0) then
|
||||
begin
|
||||
Result:=True;
|
||||
end else
|
||||
begin
|
||||
Result:=False;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -0,0 +1,440 @@
|
|||
unit kern_sysctl;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
|
||||
const
|
||||
CTL_MAXNAME=24; // largest number of components supported
|
||||
|
||||
//Top-level identifiers
|
||||
CTL_UNSPEC = 0; // unused
|
||||
CTL_KERN = 1; // "high kernel": proc, limits
|
||||
CTL_VM = 2; // virtual memory
|
||||
CTL_VFS = 3; // filesystem, mount type is next
|
||||
CTL_NET = 4; // network, see socket.h
|
||||
CTL_DEBUG = 5; // debugging parameters
|
||||
CTL_HW = 6; // generic cpu/io
|
||||
CTL_MACHDEP = 7; // machine dependent
|
||||
CTL_USER = 8; // user-level
|
||||
CTL_P1003_1B= 9; // POSIX 1003.1B
|
||||
CTL_MAXID =10; // number of valid top-level ids
|
||||
|
||||
|
||||
//CTL_KERN identifiers
|
||||
KERN_PROC =14;
|
||||
|
||||
KERN_ARND =37;
|
||||
|
||||
//KERN_PROC subtypes
|
||||
KERN_PROC_APPINFO =35; //Application information
|
||||
KERN_PROC_SDK_VERSION =36; //SDK version of the executable file
|
||||
KERN_PROC_IDTABLE =37; //ID table information
|
||||
|
||||
KERN_PROC_TEXT_SEGMENT=44; //kern_dynlib_get_libkernel_text_segment
|
||||
|
||||
|
||||
|
||||
|
||||
//SYSCTL_HANDLER_ARGS oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req
|
||||
|
||||
type
|
||||
p_sysctl_req=^t_sysctl_req;
|
||||
|
||||
t_sysctl_func=function(req:p_sysctl_req;p:Pointer;s:QWORD):Integer;
|
||||
|
||||
t_sysctl_req=record
|
||||
td :Pointer; //p_kthread
|
||||
lock :Integer;
|
||||
oldptr :Pointer;
|
||||
oldlen :QWORD;
|
||||
oldidx :QWORD;
|
||||
oldfunc :t_sysctl_func;
|
||||
newptr :Pointer;
|
||||
newlen :QWORD;
|
||||
newidx :QWORD;
|
||||
newfunc :t_sysctl_func;
|
||||
validlen:QWORD;
|
||||
flags :Integer;
|
||||
end;
|
||||
|
||||
p_sysctl_oid=^t_sysctl_oid;
|
||||
|
||||
t_oid_handler=function(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
|
||||
|
||||
t_sysctl_oid=record
|
||||
oid_handler:t_oid_handler;
|
||||
end;
|
||||
|
||||
function sys___sysctl(name :PInteger;
|
||||
namelen:DWORD;
|
||||
old :Pointer;
|
||||
oldlenp:PQWORD;
|
||||
new :Pointer;
|
||||
newlen :QWORD):Integer;
|
||||
|
||||
procedure sysctl_register_all(); //SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
systm,
|
||||
vmparam,
|
||||
kern_thr,
|
||||
kern_sx,
|
||||
md_arc4random;
|
||||
|
||||
var
|
||||
sysctllock :t_sx;
|
||||
sysctlmemlock:t_sx;
|
||||
|
||||
procedure sysctl_register_all();
|
||||
begin
|
||||
sx_init(@sysctlmemlock, 'sysctl mem');
|
||||
sx_init(@sysctllock , 'sysctl lock');
|
||||
end;
|
||||
|
||||
procedure SYSCTL_XLOCK(); inline;
|
||||
begin
|
||||
sx_xlock(@sysctllock)
|
||||
end;
|
||||
|
||||
procedure SYSCTL_XUNLOCK(); inline;
|
||||
begin
|
||||
sx_xunlock(@sysctllock);
|
||||
end;
|
||||
|
||||
procedure SYSCTL_ASSERT_XLOCKED(); inline;
|
||||
begin
|
||||
sx_assert(@sysctllock)
|
||||
end;
|
||||
|
||||
function SYSCTL_IN(req:p_sysctl_req;p:Pointer;s:QWORD):Integer; inline;
|
||||
begin
|
||||
Result:=req^.newfunc(req,p,s);
|
||||
end;
|
||||
|
||||
function SYSCTL_OUT(req:p_sysctl_req;p:Pointer;s:QWORD):Integer; inline;
|
||||
begin
|
||||
Result:=req^.oldfunc(req,p,s);
|
||||
end;
|
||||
|
||||
function SYSCTL_HANDLE(noid:p_sysctl_oid;func:Pointer):Integer; inline;
|
||||
begin
|
||||
noid^.oid_handler:=t_oid_handler(func);
|
||||
Result:=0
|
||||
end;
|
||||
|
||||
//Transfer function to/from user space.
|
||||
function sysctl_old_user(req:p_sysctl_req;p:Pointer;l:QWORD):Integer;
|
||||
var
|
||||
i,len,origidx:QWORD;
|
||||
error:Integer;
|
||||
begin
|
||||
origidx:=req^.oldidx;
|
||||
Inc(req^.oldidx,l);
|
||||
|
||||
if (req^.oldptr=nil) then
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
i:=l;
|
||||
len:=req^.validlen;
|
||||
if (len <= origidx) then
|
||||
begin
|
||||
i:=0;
|
||||
end else
|
||||
begin
|
||||
if (i > len - origidx) then
|
||||
begin
|
||||
i:=len - origidx;
|
||||
end;
|
||||
//if (req^.lock=REQ_WIRED) then
|
||||
//begin
|
||||
// error:=copyout_nofault(p, req^.oldptr + origidx, i);
|
||||
//end else
|
||||
begin
|
||||
error:=copyout(p, req^.oldptr + origidx, i);
|
||||
end;
|
||||
if (error<>0) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
end;
|
||||
if (i < l) then
|
||||
begin
|
||||
Exit(ENOMEM);
|
||||
end;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function sysctl_new_user(req:p_sysctl_req;p:Pointer;l:QWORD):Integer;
|
||||
var
|
||||
error:Integer;
|
||||
begin
|
||||
if (req^.newptr=nil) then
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
if ((req^.newlen - req^.newidx) < l) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
error:=copyin(req^.newptr + req^.newidx, p, l);
|
||||
|
||||
Inc(req^.newidx,l);
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
//Exit(ENOTDIR);
|
||||
//Exit(ENOENT);
|
||||
|
||||
function sysctl_kern_proc_idtable(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
|
||||
begin
|
||||
//get idtable key count
|
||||
Exit(ENOENT); //sceSblACMgrIsSystemUcred
|
||||
end;
|
||||
|
||||
function sysctl_kern_arandom(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
|
||||
var
|
||||
len:Integer;
|
||||
data:array[0..254] of Byte;
|
||||
begin
|
||||
len:=256;
|
||||
if (req^.oldlen < 256) then
|
||||
begin
|
||||
len:=req^.oldlen;
|
||||
end;
|
||||
|
||||
arc4rand(@data,len,0);
|
||||
|
||||
Result:=SYSCTL_OUT(req,@data,len);
|
||||
end;
|
||||
|
||||
function sysctl_kern_proc(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
|
||||
begin
|
||||
if (namelen=0) then Exit(ENOTDIR);
|
||||
Result:=ENOENT;
|
||||
|
||||
Writeln(StdErr,'sysctl_kern_proc:',name[0]);
|
||||
end;
|
||||
|
||||
function sysctl_kern(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
|
||||
begin
|
||||
if (namelen=0) then Exit(ENOTDIR);
|
||||
Result:=ENOENT;
|
||||
|
||||
case name[0] of
|
||||
KERN_PROC:Result:=sysctl_kern_proc(name+1,namelen-1,noid,req);
|
||||
|
||||
KERN_ARND:Result:=SYSCTL_HANDLE(noid,@sysctl_kern_arandom);
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled sysctl_kern:',name[0]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function sysctl_find_oid(name :PInteger;
|
||||
namelen:DWORD;
|
||||
noid :p_sysctl_oid;
|
||||
req :p_sysctl_req):Integer;
|
||||
begin
|
||||
if (namelen=0) then Exit(ENOENT);
|
||||
Result:=ENOENT;
|
||||
|
||||
case name[0] of
|
||||
CTL_KERN:Result:=sysctl_kern(name+1,namelen-1,noid,req);
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled sysctl_find_oid:',name[0]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function sysctl_root(oidp:p_sysctl_oid;
|
||||
arg1:PInteger;
|
||||
arg2:DWORD;
|
||||
req :p_sysctl_req):Integer;
|
||||
var
|
||||
oid:t_sysctl_oid;
|
||||
begin
|
||||
oid:=Default(t_sysctl_oid);
|
||||
|
||||
Result:=sysctl_find_oid(arg1, arg2, @oid, req);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
if (oid.oid_handler=nil) then Exit(EINVAL);
|
||||
|
||||
//if ((oid.oid_kind and CTLTYPE)=CTLTYPE_NODE) then
|
||||
//begin
|
||||
// arg1:=arg1 + indx;
|
||||
// arg2:=arg2 - indx;
|
||||
//end else
|
||||
//begin
|
||||
// arg1:=oid.oid_arg1;
|
||||
// arg2:=oid.oid_arg2;
|
||||
//end;
|
||||
|
||||
Result:=oid.oid_handler(@oid, arg1, arg2, req);
|
||||
|
||||
end;
|
||||
|
||||
function userland_sysctl(name :PInteger;
|
||||
namelen :DWORD;
|
||||
old :Pointer;
|
||||
oldlenp :PQWORD;
|
||||
inkernel:Integer;
|
||||
new :Pointer;
|
||||
newlen :QWORD;
|
||||
retval :PQWORD;
|
||||
flags :Integer):Integer;
|
||||
var
|
||||
error,memlocked:Integer;
|
||||
req:t_sysctl_req;
|
||||
begin
|
||||
error:=0;
|
||||
|
||||
req:=Default(t_sysctl_req);
|
||||
|
||||
req.td :=curkthread;
|
||||
req.flags:=flags;
|
||||
|
||||
if (oldlenp<>nil) then
|
||||
begin
|
||||
if (inkernel<>0) then
|
||||
begin
|
||||
req.oldlen:=oldlenp^;
|
||||
end else
|
||||
begin
|
||||
error:=copyin(oldlenp, @req.oldlen, sizeof(Pointer));
|
||||
if (error<>0) then Exit(error);
|
||||
end;
|
||||
end;
|
||||
req.validlen:=req.oldlen;
|
||||
|
||||
if (old<>nil) then
|
||||
begin
|
||||
//if (!useracc(old, req.oldlen, VM_PROT_WRITE))
|
||||
// Exit(EFAULT);
|
||||
req.oldptr:=old;
|
||||
end;
|
||||
|
||||
if (new<>nil) then
|
||||
begin
|
||||
//if (!useracc(new, newlen, VM_PROT_READ))
|
||||
// Exit(EFAULT);
|
||||
req.newlen:=newlen;
|
||||
req.newptr:=new;
|
||||
end;
|
||||
|
||||
req.oldfunc:=@sysctl_old_user;
|
||||
req.newfunc:=@sysctl_new_user;
|
||||
//req.lock:=REQ_UNWIRED;
|
||||
|
||||
if (req.oldlen > PAGE_SIZE) then
|
||||
begin
|
||||
memlocked:=1;
|
||||
sx_xlock(@sysctlmemlock);
|
||||
end else
|
||||
begin
|
||||
memlocked:=0;
|
||||
end;
|
||||
|
||||
repeat
|
||||
req.oldidx:=0;
|
||||
req.newidx:=0;
|
||||
SYSCTL_XLOCK();
|
||||
error:=sysctl_root(nil, name, namelen, @req);
|
||||
SYSCTL_XUNLOCK();
|
||||
if (error<>EAGAIN) then
|
||||
begin
|
||||
break;
|
||||
end;
|
||||
//kern_yield(PRI_USER);
|
||||
until false;
|
||||
|
||||
//if (req.lock=REQ_WIRED) and (req.validlen > 0) then
|
||||
//begin
|
||||
// vsunlock(req.oldptr, req.validlen);
|
||||
//end;
|
||||
|
||||
if (memlocked<>0) then
|
||||
begin
|
||||
sx_xunlock(@sysctlmemlock);
|
||||
end;
|
||||
|
||||
if (error<>0) and (error<>ENOMEM) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
if (retval<>nil) then
|
||||
begin
|
||||
if (req.oldptr<>nil) and (req.oldidx > req.validlen) then
|
||||
retval^:=req.validlen
|
||||
else
|
||||
retval^:=req.oldidx;
|
||||
end;
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function sys___sysctl(name :PInteger;
|
||||
namelen:DWORD;
|
||||
old :Pointer;
|
||||
oldlenp:PQWORD;
|
||||
new :Pointer;
|
||||
newlen :QWORD):Integer;
|
||||
var
|
||||
error,i:Integer;
|
||||
_name:array[0..CTL_MAXNAME-1] of Integer;
|
||||
j:QWORD;
|
||||
begin
|
||||
if (namelen > CTL_MAXNAME) or (namelen < 2) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
error:=copyin(name, @_name, namelen * sizeof(Integer));
|
||||
if (error<>0) then Exit(error);
|
||||
|
||||
error:=userland_sysctl(@_name,
|
||||
namelen,
|
||||
old,
|
||||
oldlenp,
|
||||
0,
|
||||
new,
|
||||
newlen,
|
||||
@j,
|
||||
0);
|
||||
|
||||
if (error<>0) and (error<>ENOMEM) then
|
||||
begin
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
if (oldlenp<>nil) then
|
||||
begin
|
||||
i:=copyout(@j, oldlenp, sizeof(j));
|
||||
if (i<>0) then
|
||||
begin
|
||||
Exit(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
|
@ -2044,6 +2044,8 @@ var
|
|||
begin
|
||||
Result:=nil;
|
||||
|
||||
Writeln(' do_load_object:',dynlib_basename(path));
|
||||
|
||||
new:=obj_new();
|
||||
|
||||
err:=self_load_shared_object(path,new,ord((flags and $20)<>0));
|
||||
|
@ -2158,6 +2160,8 @@ var
|
|||
begin
|
||||
Assert(root^.ref_count=0,'unload_object ref_count');
|
||||
|
||||
Writeln(' unload_object:',dynlib_basename(root^.lib_path));
|
||||
|
||||
{
|
||||
* Pass over the DAG removing unreferenced objects from
|
||||
* appropriate lists.
|
||||
|
@ -2225,7 +2229,7 @@ begin
|
|||
begin
|
||||
fname:='/'+fname;
|
||||
end;
|
||||
fname:=p_proc.p_randomized_path+fname;
|
||||
fname:='/'+p_proc.p_randomized_path+fname;
|
||||
|
||||
if rtld_file_exists(pchar(fname)) then goto _do_load;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
unit md_arc4random;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
procedure arc4rand(ptr:Pointer;len,reseed:Integer);
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG=2;
|
||||
|
||||
function BCryptGenRandom(hAlgorithm:Pointer;
|
||||
pbBuffer:PByte;
|
||||
cbBuffer:DWORD;
|
||||
dwFlags:DWORD):DWORD; stdcall; external 'Bcrypt';
|
||||
|
||||
procedure arc4rand(ptr:Pointer;len,reseed:Integer);
|
||||
begin
|
||||
BCryptGenRandom(nil,ptr,len,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
|
@ -13,6 +13,7 @@ uses
|
|||
time,
|
||||
kern_time,
|
||||
subr_sleepqueue,
|
||||
kern_sysctl,
|
||||
kern_thr,
|
||||
kern_thread,
|
||||
kern_sig,
|
||||
|
@ -74,6 +75,7 @@ procedure sys_init;
|
|||
begin
|
||||
timeinit;
|
||||
init_sleepqueues;
|
||||
sysctl_register_all;
|
||||
PROC_INIT;
|
||||
threadinit;
|
||||
siginit;
|
||||
|
|
|
@ -90,6 +90,7 @@ function _fpathconf(fd,name:Integer):Integer;
|
|||
function getrlimit(which:Integer;rlp:Pointer):Integer;
|
||||
function setrlimit(which:Integer;rlp:Pointer):Integer;
|
||||
function _getdirentries(fd:Integer;buf:Pointer;count:DWORD;basep:PInt64):Integer;
|
||||
function __sysctl(name:PInteger;namelen:DWORD;old:Pointer;oldlenp:PQWORD;new:Pointer;newlen:QWORD):Integer;
|
||||
function futimes(fd:Integer;tptr:Pointer):Integer;
|
||||
function getpgid(pid:Integer):Integer;
|
||||
function poll(fds:Pointer;nfds:DWORD;timeout:Integer):Integer;
|
||||
|
@ -813,6 +814,13 @@ asm
|
|||
jmp cerror
|
||||
end;
|
||||
|
||||
function __sysctl(name:PInteger;namelen:DWORD;old:Pointer;oldlenp:PQWORD;new:Pointer;newlen:QWORD):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $202,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function futimes(fd:Integer;tptr:Pointer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $206,%rax
|
||||
|
|
|
@ -28,6 +28,7 @@ uses
|
|||
kern_dynlib,
|
||||
kern_ksched,
|
||||
kern_rtprio,
|
||||
kern_sysctl,
|
||||
kern_thread,
|
||||
sys_machdep,
|
||||
kern_context,
|
||||
|
@ -1062,7 +1063,7 @@ const
|
|||
),
|
||||
(//[202]
|
||||
sy_narg:6;
|
||||
sy_call:nil;
|
||||
sy_call:@sys___sysctl;
|
||||
sy_name:'sys___sysctl'
|
||||
),
|
||||
(//[203]
|
||||
|
|
|
@ -597,6 +597,14 @@
|
|||
<Filename Value="..\kern\kern_stub.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\kern\kern_sysctl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\md\md_arc4random.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -91,7 +91,8 @@ uses
|
|||
kern_timeout,
|
||||
kern_exec,
|
||||
kern_dynlib,
|
||||
vmparam;
|
||||
vmparam,
|
||||
kern_sysctl;
|
||||
|
||||
const
|
||||
PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);
|
||||
|
|
|
@ -107,7 +107,8 @@ implementation
|
|||
uses
|
||||
vmparam,
|
||||
vnode,
|
||||
vfs_subr;
|
||||
vfs_subr,
|
||||
kern_patcher;
|
||||
|
||||
function IDX_TO_OFF(x:DWORD):QWORD; inline;
|
||||
begin
|
||||
|
@ -225,6 +226,8 @@ begin
|
|||
|
||||
Assert(obj^.paging_in_progress=0,'vm_object_terminate: pageout in progress');
|
||||
|
||||
vm_object_patch_remove(obj,0,0);
|
||||
|
||||
{
|
||||
* Clean and free the pages, as appropriate. All references to the
|
||||
* obj are gone, so we don't need to lock it.
|
||||
|
@ -385,9 +388,7 @@ procedure vm_object_page_remove(obj:vm_object_t;
|
|||
__end:vm_pindex_t;
|
||||
options:Integer);
|
||||
begin
|
||||
//OBJPR_CLEANONLY=$1; // Don't remove dirty pages.
|
||||
//OBJPR_NOTMAPPED=$2; // Don't unmap pages.
|
||||
//OBJPR_NOTWIRED =$4; // Don't remove wired pages.
|
||||
vm_object_patch_remove(obj,start,__end);
|
||||
end;
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue