mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
9f2c609271
commit
e203006e68
|
@ -5,23 +5,499 @@ unit kern_patcher;
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
|
||||||
vm;
|
|
||||||
|
|
||||||
procedure patcher_process_section(_obj:Pointer;data,vaddr:Pointer;filesz:QWORD);
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
vm_object;
|
windows,
|
||||||
|
|
||||||
procedure patcher_process_section(_obj:Pointer;data,vaddr:Pointer;filesz:QWORD);
|
mqueue,
|
||||||
|
hamt,
|
||||||
|
kern_rwlock,
|
||||||
|
kern_thr,
|
||||||
|
vm,
|
||||||
|
vm_map,
|
||||||
|
vm_mmap,
|
||||||
|
vm_object,
|
||||||
|
vm_pmap,
|
||||||
|
trap,
|
||||||
|
kern_stub;
|
||||||
|
|
||||||
|
{
|
||||||
|
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]
|
||||||
|
64 48 8B 0C 25 [00000000] mov rcx,fs:[$00000000] -> 65 48 8B 0C 25 [08070000] mov rcx,gs:[$00000708]
|
||||||
|
64 48 8B 14 25 [00000000] mov rdx,fs:[$00000000] -> 65 48 8B 14 25 [08070000] mov rdx,gs:[$00000708]
|
||||||
|
64 48 8B 1C 25 [00000000] mov rbx,fs:[$00000000] -> 65 48 8B 1C 25 [08070000] mov rbx,gs:[$00000708]
|
||||||
|
64 48 8B 24 25 [00000000] mov rsp,fs:[$00000000] -> 65 48 8B 24 25 [08070000] mov rsp,gs:[$00000708]
|
||||||
|
64 48 8B 2C 25 [00000000] mov rbp,fs:[$00000000] -> 65 48 8B 2C 25 [08070000] mov rbp,gs:[$00000708]
|
||||||
|
64 48 8B 34 25 [00000000] mov rsi,fs:[$00000000] -> 65 48 8B 34 25 [08070000] mov rsi,gs:[$00000708]
|
||||||
|
64 48 8B 3C 25 [00000000] mov rdi,fs:[$00000000] -> 65 48 8B 3C 25 [08070000] mov rdi,gs:[$00000708]
|
||||||
|
64 4C 8B 04 25 [00000000] mov r8 ,fs:[$00000000] -> 65 4C 8B 04 25 [08070000] mov r8 ,gs:[$00000708]
|
||||||
|
64 4C 8B 0C 25 [00000000] mov r9 ,fs:[$00000000] -> 65 4C 8B 0C 25 [08070000] mov r9 ,gs:[$00000708]
|
||||||
|
64 4C 8B 14 25 [00000000] mov r10,fs:[$00000000] -> 65 4C 8B 14 25 [08070000] mov r10,gs:[$00000708]
|
||||||
|
64 4C 8B 1C 25 [00000000] mov r11,fs:[$00000000] -> 65 4C 8B 1C 25 [08070000] mov r11,gs:[$00000708]
|
||||||
|
64 4C 8B 24 25 [00000000] mov r12,fs:[$00000000] -> 65 4C 8B 24 25 [08070000] mov r12,gs:[$00000708]
|
||||||
|
64 4C 8B 2C 25 [00000000] mov r13,fs:[$00000000] -> 65 4C 8B 2C 25 [08070000] mov r13,gs:[$00000708]
|
||||||
|
64 4C 8B 34 25 [00000000] mov r14,fs:[$00000000] -> 65 4C 8B 34 25 [08070000] mov r14,gs:[$00000708]
|
||||||
|
64 4C 8B 3C 25 [00000000] mov r15,fs:[$00000000] -> 65 4C 8B 3C 25 [08070000] mov r15,gs:[$00000708]
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
[48 b8 | 10 01 00 00 00 00 00 00]:MOV RAX,0x110
|
||||||
|
|
||||||
|
[49 89 ca]:MOV R10,RCX
|
||||||
|
|
||||||
|
[0f 05]:SYSCALL
|
||||||
|
|
||||||
|
[72 01]:JC LAB
|
||||||
|
|
||||||
|
[c3]:RET
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
[48 c7 c0 | dd 01 00 00]:MOV RAX,0x1dd
|
||||||
|
|
||||||
|
[49 89 ca]:MOV R10,RCX
|
||||||
|
|
||||||
|
[0f 05]:SYSCALL
|
||||||
|
|
||||||
|
[72 01]:JC LAB
|
||||||
|
|
||||||
|
[c3]:RET
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 01 | 00 00 00 MOV RAX,0x1
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
41 5c POP R12
|
||||||
|
5b POP RBX
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 41 5c]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 fb | 00 00 00 MOV RAX,0xfb
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 1f JC LAB_
|
||||||
|
83 fa 00 CMP EDX,0x0
|
||||||
|
75 04 JNZ LAB_
|
||||||
|
41 5c POP R12
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 72 1f]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 01 | 00 00 00 MOV RAX,0x1
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
41 5c POP R12
|
||||||
|
5b POP RBX
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 3b | 00 00 00 MOV RAX,0x3b
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
48 8d 15 c0 LEA RDX,[FUN_]
|
||||||
|
ff ff ff
|
||||||
|
ff e2 JMP RDX=>FUN_
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 48 8d]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 a5 | 01 00 00 MOV RAX,0x1a5
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 06 JC LAB_
|
||||||
|
48 83 c4 08 ADD RSP,0x8
|
||||||
|
ff e6 JMP RSI
|
||||||
|
|
||||||
|
[01 00 00 | 49 89 ca | 0f 05 | 72 06]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 2a | 00 00 00 MOV RAX,0x2a
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 0d JC LAB_
|
||||||
|
89 07 MOV dword ptr
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 72 0d]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 37 | 00 00 00 MOV RAX,0x37
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 02 JC LAB_
|
||||||
|
48 cf IRETQ
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 72 02]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 32 | 00 00 00 MOV RAX,0x32
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 0e JC LAB_
|
||||||
|
48 8d 15 a3 e1 08 00 LEA RDX,[DAT_]
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 72 0e]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 42 | 00 00 00 MOV RAX,0x42
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
72 02 JC LAB_
|
||||||
|
ff e6 JMP RSI
|
||||||
|
|
||||||
|
[00 00 00 | 49 89 ca | 0f 05 | 72 02]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 54 | 01 00 00 MOV RAX,0x154
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
5f POP RDI
|
||||||
|
48 81 bf 18 CMP qword ptr [RDI + 0x118],0x20001
|
||||||
|
01 00 00 01
|
||||||
|
00 02 00
|
||||||
|
|
||||||
|
[01 00 00 | 49 89 ca | 0f 05 | 5f 48]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
48 c7 c0 c6 | 01 00 00 MOV RAX,0x1c6
|
||||||
|
49 89 ca MOV R10,RCX
|
||||||
|
0f 05 SYSCALL
|
||||||
|
c3 RET
|
||||||
|
90 ?? 90h
|
||||||
|
|
||||||
|
[01 00 00 | 49 89 ca | 0f 05 | c3 90]
|
||||||
|
|
||||||
|
//////////
|
||||||
|
|
||||||
|
0 1 2 3 4 5 6 7 8 9
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 41 5c]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 01]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 1f]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 48 8d]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 06]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 0d]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 02]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 0e]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | 5f 48]
|
||||||
|
[0X 00 00 | 49 89 ca | 0f 05 | c3 90]
|
||||||
|
X=0,1,2
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
jmpq 0(%rip) -> [FF 25 | 00 00 00 00]
|
||||||
|
callq 0(%rip) -> [FF 15 | 00 00 00 00]
|
||||||
|
|
||||||
|
jmpl [32] -> [E9 | 00 00 00 00]
|
||||||
|
calll [32] -> [E8 | 00 00 00 00]
|
||||||
|
}
|
||||||
|
|
||||||
|
type
|
||||||
|
t_patch_base_long=packed record
|
||||||
|
len :Byte ; //12
|
||||||
|
inst:array[0..2] of Byte;
|
||||||
|
addr:QWORD; //teb_tcb/teb_gsbase
|
||||||
|
end;
|
||||||
|
|
||||||
|
t_patch_base_short=packed record
|
||||||
|
len :Byte ; //9
|
||||||
|
inst:array[0..4] of Byte;
|
||||||
|
addr:DWORD; //teb_tcb/teb_gsbase
|
||||||
|
end;
|
||||||
|
|
||||||
|
t_patch_inst=packed record
|
||||||
|
case Byte of
|
||||||
|
0:(A:t_patch_base_long);
|
||||||
|
1:(B:t_patch_base_short);
|
||||||
|
2:(C:array[0..11] of Byte);
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
patch_table:array[0..33] of t_patch_inst=(
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$04,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$0C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$14,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$1C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$24,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$2C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$34,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$3C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$04,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$0C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$14,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$1C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$24,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$2C,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$34,$25);addr:teb_tcb )),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$3C,$25);addr:teb_tcb )),
|
||||||
|
(A:(len:12;inst:($65,$48,$A1 );addr:teb_tcb )),
|
||||||
|
//
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$04,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$0C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$14,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$1C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$24,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$2C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$34,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$48,$8B,$3C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$04,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$0C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$14,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$1C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$24,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$2C,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$34,$25);addr:teb_gsbase)),
|
||||||
|
(B:(len: 9;inst:($65,$4C,$8B,$3C,$25);addr:teb_gsbase)),
|
||||||
|
(A:(len:12;inst:($65,$48,$A1 );addr:teb_gsbase))
|
||||||
|
);
|
||||||
|
|
||||||
|
function IndexInstr(var pbuf:Pointer;pend:Pointer):Integer;
|
||||||
|
var
|
||||||
|
psrc:Pointer;
|
||||||
|
W:DWORD;
|
||||||
|
begin
|
||||||
|
Result:=-1;
|
||||||
|
psrc:=pbuf;
|
||||||
|
while (psrc<pend) do
|
||||||
|
begin
|
||||||
|
W:=PDWORD(psrc)^;
|
||||||
|
|
||||||
|
Case W of
|
||||||
|
$048B4864:Result:= 0; //fs_rax
|
||||||
|
$0C8B4864:Result:= 1; //fs_rcx
|
||||||
|
$148B4864:Result:= 2; //fs_rdx
|
||||||
|
$1C8B4864:Result:= 3; //fs_rbx
|
||||||
|
$248B4864:Result:= 4; //fs_rsp
|
||||||
|
$2C8B4864:Result:= 5; //fs_rbp
|
||||||
|
$348B4864:Result:= 6; //fs_rsi
|
||||||
|
$3C8B4864:Result:= 7; //fs_rdi
|
||||||
|
$048B4C64:Result:= 8; //fs_r8
|
||||||
|
$0C8B4C64:Result:= 9; //fs_r9
|
||||||
|
$148B4C64:Result:=10; //fs_r10
|
||||||
|
$1C8B4C64:Result:=11; //fs_r11
|
||||||
|
$248B4C64:Result:=12; //fs_r12
|
||||||
|
$2C8B4C64:Result:=13; //fs_r13
|
||||||
|
$348B4C64:Result:=14; //fs_r14
|
||||||
|
$3C8B4C64:Result:=15; //fs_r15
|
||||||
|
$00A14864:Result:=16; //fs_rax64
|
||||||
|
|
||||||
|
$048B4865:Result:=17; //gs_rax
|
||||||
|
$0C8B4865:Result:=18; //gs_rcx
|
||||||
|
$148B4865:Result:=19; //gs_rdx
|
||||||
|
$1C8B4865:Result:=20; //gs_rbx
|
||||||
|
$248B4865:Result:=21; //gs_rsp
|
||||||
|
$2C8B4865:Result:=22; //gs_rbp
|
||||||
|
$348B4865:Result:=23; //gs_rsi
|
||||||
|
$3C8B4865:Result:=24; //gs_rdi
|
||||||
|
$048B4C65:Result:=25; //gs_r8
|
||||||
|
$0C8B4C65:Result:=26; //gs_r9
|
||||||
|
$148B4C65:Result:=27; //gs_r10
|
||||||
|
$1C8B4C65:Result:=28; //gs_r11
|
||||||
|
$248B4C65:Result:=29; //gs_r12
|
||||||
|
$2C8B4C65:Result:=30; //gs_r13
|
||||||
|
$348B4C65:Result:=31; //gs_r14
|
||||||
|
$3C8B4C65:Result:=32; //gs_r15
|
||||||
|
$00A14865:Result:=33; //gs_rax64
|
||||||
|
|
||||||
|
$49000000,
|
||||||
|
$49000001,
|
||||||
|
$49000002:Result:=34; //syscall
|
||||||
|
|
||||||
|
//shft 8
|
||||||
|
$8B486400..$8B4864FF, //fs
|
||||||
|
$8B4C6400..$8B4C64FF, //fs
|
||||||
|
$A1486400..$A14864FF, //fs
|
||||||
|
|
||||||
|
$8B486500..$8B4865FF, //gs
|
||||||
|
$8B4C6500..$8B4C65FF, //gs
|
||||||
|
$A1486500..$A14865FF, //gs
|
||||||
|
|
||||||
|
$00000000..$000002FF: //sv
|
||||||
|
begin
|
||||||
|
Inc(psrc,1);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//shft 16
|
||||||
|
$48640000..$4864FFFF, //fs
|
||||||
|
$4C640000..$4C64FFFF, //fs
|
||||||
|
|
||||||
|
$48650000..$4865FFFF, //gs
|
||||||
|
$4C650000..$4C65FFFF, //gs
|
||||||
|
|
||||||
|
$00000300..$0002FFFF: //sv
|
||||||
|
begin
|
||||||
|
Inc(psrc,2);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//shft 24
|
||||||
|
$64000000..$64FFFFFF, //fs
|
||||||
|
|
||||||
|
$65000000..$65FFFFFF, //gs
|
||||||
|
|
||||||
|
$00030000..$00A14863, //sv
|
||||||
|
$00A14866..$02FFFFFF: //sv
|
||||||
|
begin
|
||||||
|
Inc(psrc,3);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Inc(psrc,4);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Case Result of
|
||||||
|
0..15,
|
||||||
|
17..32:
|
||||||
|
begin
|
||||||
|
if (PBYTE(psrc)[4]<>$25) or
|
||||||
|
(PDWORD(@PBYTE(psrc)[5])^<>$00000000) then
|
||||||
|
begin
|
||||||
|
Inc(psrc,4);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
16,
|
||||||
|
33:
|
||||||
|
begin
|
||||||
|
if (PQWORD(@PBYTE(psrc)[3])^<>$0000000000000000) then
|
||||||
|
begin
|
||||||
|
Inc(psrc,4);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
34:
|
||||||
|
begin
|
||||||
|
if (PDWORD(@PBYTE(psrc)[4])^<>$050FCA89) then
|
||||||
|
begin
|
||||||
|
Inc(psrc,4);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Write(HexStr(PBYTE(psrc)[0],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[1],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[2],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[3],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[4],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[5],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[6],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[7],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[8],2),' ');
|
||||||
|
Write(HexStr(PBYTE(psrc)[9],2),' ');
|
||||||
|
|
||||||
|
Case PBYTE(psrc)[8] of
|
||||||
|
$41,
|
||||||
|
$48,
|
||||||
|
$5f,
|
||||||
|
$72,
|
||||||
|
$c3:Writeln('True');
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Writeln('False');
|
||||||
|
Inc(psrc,4);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (Result<>-1) then
|
||||||
|
begin
|
||||||
|
pbuf:=psrc;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Inc(psrc);
|
||||||
|
end;
|
||||||
|
Result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
|
||||||
var
|
var
|
||||||
obj:vm_object_t;
|
obj:vm_object_t;
|
||||||
|
addr:Pointer;
|
||||||
|
pend:Pointer;
|
||||||
|
i,len:Integer;
|
||||||
|
|
||||||
|
fs_count:Integer;
|
||||||
|
gs_count:Integer;
|
||||||
|
sv_count:Integer;
|
||||||
|
|
||||||
|
procedure do_patch_base(P:PByte;i:Integer); inline;
|
||||||
|
begin
|
||||||
|
Move(patch_table[i].C[1],P^,patch_table[i].C[0]);
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Assert(_obj<>nil,'patcher_process_section');
|
Assert(_obj<>nil,'patcher_process_section');
|
||||||
obj:=_obj;
|
obj:=_obj;
|
||||||
|
|
||||||
|
fs_count:=0;
|
||||||
|
gs_count:=0;
|
||||||
|
sv_count:=0;
|
||||||
|
|
||||||
|
addr:=data;
|
||||||
|
pend:=addr+filesz;
|
||||||
|
repeat
|
||||||
|
i:=IndexInstr(addr,pend);
|
||||||
|
|
||||||
|
if (i=-1) then Break;
|
||||||
|
|
||||||
|
Case i of
|
||||||
|
0..16:
|
||||||
|
begin
|
||||||
|
Inc(fs_count);
|
||||||
|
//
|
||||||
|
len:=patch_table[i].C[0];
|
||||||
|
do_patch_base(addr,i);
|
||||||
|
end;
|
||||||
|
17..33:
|
||||||
|
begin
|
||||||
|
Inc(gs_count);
|
||||||
|
//
|
||||||
|
len:=patch_table[i].C[0];
|
||||||
|
do_patch_base(addr,i);
|
||||||
|
end;
|
||||||
|
34:
|
||||||
|
begin
|
||||||
|
Inc(sv_count);
|
||||||
|
//
|
||||||
|
len:=9;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Assert(False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Inc(addr,len);
|
||||||
|
|
||||||
|
until false;
|
||||||
|
|
||||||
|
Writeln('[patcher_vaddr]:0x',HexStr(vaddr));
|
||||||
|
Writeln(' fs_count:',fs_count);
|
||||||
|
Writeln(' gs_count:',gs_count);
|
||||||
|
Writeln(' sv_count:',sv_count);
|
||||||
|
|
||||||
|
Writeln;
|
||||||
|
|
||||||
|
//readln;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,7 @@ uses
|
||||||
vmparam,
|
vmparam,
|
||||||
vm_map,
|
vm_map,
|
||||||
vm_mmap,
|
vm_mmap,
|
||||||
|
vm_pmap,
|
||||||
kern_patcher;
|
kern_patcher;
|
||||||
|
|
||||||
function maxInt64(a,b:Int64):Int64; inline;
|
function maxInt64(a,b:Int64):Int64; inline;
|
||||||
|
@ -1088,7 +1089,7 @@ begin
|
||||||
//remove prev if exist
|
//remove prev if exist
|
||||||
vm_map_delete(map,vaddr_lo,vaddr_hi);
|
vm_map_delete(map,vaddr_lo,vaddr_hi);
|
||||||
|
|
||||||
Result:=vm_map_insert(map,imgp^.obj,0,vaddr_lo,vaddr_hi,VM_PROT_RW,prot or VM_PROT_RW,0);
|
Result:=vm_map_insert(map,imgp^.obj,offset,vaddr_lo,vaddr_hi,VM_PROT_RW,prot or VM_PROT_RW,0);
|
||||||
if (Result<>0) then
|
if (Result<>0) then
|
||||||
begin
|
begin
|
||||||
vm_map_unlock(map);
|
vm_map_unlock(map);
|
||||||
|
@ -1102,20 +1103,21 @@ begin
|
||||||
memsz:=vaddr_hi-vaddr_lo;
|
memsz:=vaddr_hi-vaddr_lo;
|
||||||
cache:=ReAllocMem(cache,memsz);
|
cache:=ReAllocMem(cache,memsz);
|
||||||
FillChar(cache^,memsz,0);
|
FillChar(cache^,memsz,0);
|
||||||
Move(Pointer(vaddr_lo)^,cache^,filesz);
|
Move(base^,cache^,filesz);
|
||||||
|
|
||||||
if ((prot and VM_PROT_EXECUTE)<>0) then
|
if ((prot and VM_PROT_EXECUTE)<>0) then
|
||||||
begin
|
begin
|
||||||
|
Writeln('P_X:',HexStr(offset,8),' ',HexStr(memsz,8),' ',HexStr(filesz,8));
|
||||||
patcher_process_section(imgp^.obj,cache,Pointer(vaddr_lo),filesz);
|
patcher_process_section(imgp^.obj,cache,Pointer(vaddr_lo),filesz);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=copyout(base,cache,filesz);
|
Result:=copyout(Pointer(vaddr_lo),cache,memsz);
|
||||||
if (Result<>0) then
|
if (Result<>0) then
|
||||||
begin
|
begin
|
||||||
vm_map_unlock(map);
|
vm_map_unlock(map);
|
||||||
//
|
//
|
||||||
Writeln(StdErr,'[KERNEL] self_load_section: copyout failed ',
|
Writeln(StdErr,'[KERNEL] self_load_section: copyout failed ',
|
||||||
id,', ',HexStr(base),'->',HexStr(vaddr,8),':',HexStr(filesz,8));
|
id,', ',HexStr(base),'->',HexStr(vaddr_lo,8),':',HexStr(memsz,8));
|
||||||
readln;
|
readln;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
@ -1129,6 +1131,11 @@ begin
|
||||||
Exit(vm_mmap_to_errno(Result));
|
Exit(vm_mmap_to_errno(Result));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ((prot and VM_PROT_EXECUTE)<>0) then
|
||||||
|
begin
|
||||||
|
md_cacheflush(Pointer(vaddr_lo),memsz,ICACHE);
|
||||||
|
end;
|
||||||
|
|
||||||
vm_map_unlock(map);
|
vm_map_unlock(map);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
unit kern_stub;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
{$CALLING SysV_ABI_CDecl}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
mqueue;
|
||||||
|
|
||||||
|
const
|
||||||
|
m_header_alloc=Integer($C3C3C3C3);
|
||||||
|
m_header_free =Integer($C3C3C390);
|
||||||
|
|
||||||
|
segment_size =64*1024;
|
||||||
|
|
||||||
|
type
|
||||||
|
p_stub_chunk=^stub_chunk;
|
||||||
|
stub_chunk=packed record
|
||||||
|
head :Integer;
|
||||||
|
prev_size:Integer;
|
||||||
|
curr_size:Integer;
|
||||||
|
refs :Integer;
|
||||||
|
link :TAILQ_ENTRY;
|
||||||
|
body :record end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function p_alloc (vaddr:Pointer;size:Integer):p_stub_chunk;
|
||||||
|
procedure p_free (chunk:p_stub_chunk);
|
||||||
|
procedure p_inc_ref(chunk:p_stub_chunk);
|
||||||
|
procedure p_dec_ref(chunk:p_stub_chunk);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
hamt,
|
||||||
|
kern_rwlock,
|
||||||
|
vm,
|
||||||
|
vm_map,
|
||||||
|
vm_mmap,
|
||||||
|
vm_object;
|
||||||
|
|
||||||
|
var
|
||||||
|
chunk_alloc:TSTUB_HAMT64;
|
||||||
|
chunk_free :TAILQ_HEAD=(tqh_first:nil;tqh_last:@chunk_free .tqh_first);
|
||||||
|
|
||||||
|
chunk_lock :Pointer=nil;
|
||||||
|
|
||||||
|
function alloc_segment(start:Pointer):p_stub_chunk;
|
||||||
|
var
|
||||||
|
map:vm_map_t;
|
||||||
|
err:Integer;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
map:=@g_vmspace.vm_map;
|
||||||
|
|
||||||
|
err:=_vm_mmap(map,
|
||||||
|
@start,
|
||||||
|
segment_size,
|
||||||
|
VM_PROT_RWX,
|
||||||
|
VM_PROT_RWX,
|
||||||
|
MAP_ANON or MAP_PRIVATE or (16 shl MAP_ALIGNMENT_BIT),
|
||||||
|
OBJT_DEFAULT,
|
||||||
|
nil,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (err<>0) then Exit;
|
||||||
|
|
||||||
|
Result:=start;
|
||||||
|
|
||||||
|
Result^.head :=m_header_free;
|
||||||
|
Result^.prev_size :=0;
|
||||||
|
Result^.curr_size :=segment_size;
|
||||||
|
Result^.refs :=0;
|
||||||
|
Result^.link.tqe_next:=nil;
|
||||||
|
Result^.link.tqe_prev:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure free_segment(chunk:p_stub_chunk);
|
||||||
|
var
|
||||||
|
map:vm_map_t;
|
||||||
|
begin
|
||||||
|
map:=@g_vmspace.vm_map;
|
||||||
|
|
||||||
|
vm_map_lock (map);
|
||||||
|
vm_map_delete(map, qword(chunk), qword(chunk) + segment_size);
|
||||||
|
vm_map_unlock(map);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure split_chunk(chunk:p_stub_chunk;used_size:Integer);
|
||||||
|
var
|
||||||
|
chunk_size:Integer;
|
||||||
|
next:p_stub_chunk;
|
||||||
|
begin
|
||||||
|
chunk_size:=chunk^.curr_size;
|
||||||
|
|
||||||
|
if ((used_size+SizeOf(stub_chunk)*2)>chunk_size) then Exit;
|
||||||
|
|
||||||
|
used_size:=used_size+SizeOf(stub_chunk);
|
||||||
|
|
||||||
|
next:=Pointer(chunk)+used_size;
|
||||||
|
|
||||||
|
chunk^.curr_size:=used_size;
|
||||||
|
|
||||||
|
next^.head :=m_header_free;
|
||||||
|
next^.prev_size :=used_size;
|
||||||
|
next^.curr_size :=chunk_size-used_size;
|
||||||
|
next^.refs :=0;
|
||||||
|
next^.link.tqe_next:=nil;
|
||||||
|
next^.link.tqe_prev:=nil;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(@chunk_free,next,@next^.link);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure merge_chunk(var chunk:p_stub_chunk);
|
||||||
|
var
|
||||||
|
prev,next:p_stub_chunk;
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (chunk^.prev_size<>0) then
|
||||||
|
begin
|
||||||
|
prev:=Pointer(chunk)-chunk^.prev_size;
|
||||||
|
if (prev^.head=m_header_free) then
|
||||||
|
begin
|
||||||
|
Assert(prev^.curr_size=chunk^.prev_size,'invalid prev chunk curr_size');
|
||||||
|
Assert(prev^.refs=0 ,'invalid prev chunk refs');
|
||||||
|
|
||||||
|
prev^.curr_size:=prev^.curr_size+chunk^.curr_size;
|
||||||
|
chunk:=prev;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (chunk^.curr_size<segment_size) then
|
||||||
|
begin
|
||||||
|
next:=Pointer(chunk)+chunk^.curr_size;
|
||||||
|
if (next^.head=m_header_free) then
|
||||||
|
begin
|
||||||
|
Assert(next^.prev_size=chunk^.curr_size,'invalid next chunk prev_size');
|
||||||
|
Assert(next^.refs=0 ,'invalid next chunk refs');
|
||||||
|
|
||||||
|
TAILQ_REMOVE(@chunk_free,next,@next^.link);
|
||||||
|
|
||||||
|
chunk^.curr_size:=chunk^.curr_size+next^.curr_size;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function find_free_chunk(vaddr:Pointer;size:Integer):p_stub_chunk;
|
||||||
|
var
|
||||||
|
entry,next:p_stub_chunk;
|
||||||
|
delta:Int64;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
entry:=TAILQ_FIRST(@chunk_free);
|
||||||
|
|
||||||
|
while (entry<>nil) do
|
||||||
|
begin
|
||||||
|
next:=TAILQ_NEXT(entry,@entry^.link);
|
||||||
|
//
|
||||||
|
if (entry^.curr_size>=(size+SizeOf(stub_chunk))) then
|
||||||
|
begin
|
||||||
|
delta:=abs(Int64(vaddr)-Int64(@entry^.body));
|
||||||
|
if (delta<High(Integer)) then
|
||||||
|
begin
|
||||||
|
TAILQ_REMOVE(@chunk_free,entry,@entry^.link);
|
||||||
|
Exit(entry);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
//
|
||||||
|
entry:=next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function p_alloc(vaddr:Pointer;size:Integer):p_stub_chunk;
|
||||||
|
var
|
||||||
|
chunk:p_stub_chunk;
|
||||||
|
begin
|
||||||
|
Assert(size>(segment_size-SizeOf(stub_chunk)),'p_alloc to big');
|
||||||
|
|
||||||
|
rw_wlock(chunk_lock);
|
||||||
|
|
||||||
|
chunk:=find_free_chunk(vaddr,size);
|
||||||
|
|
||||||
|
if (chunk=nil) then
|
||||||
|
begin
|
||||||
|
chunk:=alloc_segment(vaddr);
|
||||||
|
Assert(chunk<>nil,'p_alloc NOMEM');
|
||||||
|
end;
|
||||||
|
|
||||||
|
split_chunk(chunk,size);
|
||||||
|
|
||||||
|
chunk^.head:=m_header_alloc;
|
||||||
|
HAMT_insert64(@chunk_alloc,QWORD(chunk),chunk);
|
||||||
|
|
||||||
|
rw_wunlock(chunk_lock);
|
||||||
|
|
||||||
|
Result:=chunk;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure p_free(chunk:p_stub_chunk);
|
||||||
|
begin
|
||||||
|
if (chunk=nil) then Exit;
|
||||||
|
|
||||||
|
rw_wlock(chunk_lock);
|
||||||
|
|
||||||
|
if (HAMT_search64(@chunk_alloc,QWORD(chunk))=nil) then
|
||||||
|
begin
|
||||||
|
rw_wunlock(chunk_lock);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
HAMT_delete64(@chunk_alloc,QWORD(chunk),nil);
|
||||||
|
chunk^.head:=m_header_free;
|
||||||
|
|
||||||
|
merge_chunk(chunk);
|
||||||
|
|
||||||
|
if (chunk^.curr_size>=segment_size) then
|
||||||
|
begin
|
||||||
|
free_segment(chunk);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
TAILQ_INSERT_TAIL(@chunk_free,chunk,@chunk^.link);
|
||||||
|
end;
|
||||||
|
|
||||||
|
rw_wunlock(chunk_lock);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure p_inc_ref(chunk:p_stub_chunk);
|
||||||
|
begin
|
||||||
|
if (chunk=nil) then Exit;
|
||||||
|
|
||||||
|
System.InterlockedIncrement(chunk^.refs);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure p_dec_ref(chunk:p_stub_chunk);
|
||||||
|
begin
|
||||||
|
if (chunk=nil) then Exit;
|
||||||
|
|
||||||
|
if (System.InterlockedDecrement(chunk^.refs)=0) then
|
||||||
|
begin
|
||||||
|
p_free(chunk);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
|
@ -62,26 +62,6 @@ procedure kthread_exit();
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{
|
|
||||||
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]
|
|
||||||
64 48 8B 0C 25 [00000000] mov rcx,fs:[$00000000] -> 65 48 8B 0C 25 [08070000] mov rcx,gs:[$00000708]
|
|
||||||
64 48 8B 14 25 [00000000] mov rdx,fs:[$00000000] -> 65 48 8B 14 25 [08070000] mov rdx,gs:[$00000708]
|
|
||||||
64 48 8B 1C 25 [00000000] mov rbx,fs:[$00000000] -> 65 48 8B 1C 25 [08070000] mov rbx,gs:[$00000708]
|
|
||||||
64 48 8B 24 25 [00000000] mov rsp,fs:[$00000000] -> 65 48 8B 24 25 [08070000] mov rsp,gs:[$00000708]
|
|
||||||
64 48 8B 2C 25 [00000000] mov rbp,fs:[$00000000] -> 65 48 8B 2C 25 [08070000] mov rbp,gs:[$00000708]
|
|
||||||
64 48 8B 34 25 [00000000] mov rsi,fs:[$00000000] -> 65 48 8B 34 25 [08070000] mov rsi,gs:[$00000708]
|
|
||||||
64 48 8B 3C 25 [00000000] mov rdi,fs:[$00000000] -> 65 48 8B 3C 25 [08070000] mov rdi,gs:[$00000708]
|
|
||||||
64 4C 8B 04 25 [00000000] mov r8 ,fs:[$00000000] -> 65 4C 8B 04 25 [08070000] mov r8 ,gs:[$00000708]
|
|
||||||
64 4C 8B 0C 25 [00000000] mov r9 ,fs:[$00000000] -> 65 4C 8B 0C 25 [08070000] mov r9 ,gs:[$00000708]
|
|
||||||
64 4C 8B 14 25 [00000000] mov r10,fs:[$00000000] -> 65 4C 8B 14 25 [08070000] mov r10,gs:[$00000708]
|
|
||||||
64 4C 8B 1C 25 [00000000] mov r11,fs:[$00000000] -> 65 4C 8B 1C 25 [08070000] mov r11,gs:[$00000708]
|
|
||||||
64 4C 8B 24 25 [00000000] mov r12,fs:[$00000000] -> 65 4C 8B 24 25 [08070000] mov r12,gs:[$00000708]
|
|
||||||
64 4C 8B 2C 25 [00000000] mov r13,fs:[$00000000] -> 65 4C 8B 2C 25 [08070000] mov r13,gs:[$00000708]
|
|
||||||
64 4C 8B 34 25 [00000000] mov r14,fs:[$00000000] -> 65 4C 8B 34 25 [08070000] mov r14,gs:[$00000708]
|
|
||||||
64 4C 8B 3C 25 [00000000] mov r15,fs:[$00000000] -> 65 4C 8B 3C 25 [08070000] mov r15,gs:[$00000708]
|
|
||||||
}
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
errno,
|
errno,
|
||||||
systm,
|
systm,
|
||||||
|
|
|
@ -54,6 +54,13 @@ procedure pmap_remove(pmap :pmap_t;
|
||||||
__end:vm_offset_t;
|
__end:vm_offset_t;
|
||||||
prot :vm_prot_t);
|
prot :vm_prot_t);
|
||||||
|
|
||||||
|
const
|
||||||
|
ICACHE=1; //Flush the instruction cache.
|
||||||
|
DCACHE=2; //Write back to memory and invalidate the affected valid cache lines.
|
||||||
|
BCACHE=ICACHE or DCACHE;
|
||||||
|
|
||||||
|
procedure md_cacheflush(addr:Pointer;nbytes,cache:Integer);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function atop(x:QWORD):DWORD; inline;
|
function atop(x:QWORD):DWORD; inline;
|
||||||
|
@ -387,6 +394,18 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure md_cacheflush(addr:Pointer;nbytes,cache:Integer);
|
||||||
|
begin
|
||||||
|
if ((cache and ICACHE)<>0) then
|
||||||
|
begin
|
||||||
|
FlushInstructionCache(NtCurrentProcess,addr,nbytes);
|
||||||
|
end;
|
||||||
|
if ((cache and DCACHE)<>0) then
|
||||||
|
begin
|
||||||
|
FlushViewOfFile(addr,nbytes);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -593,6 +593,10 @@
|
||||||
<Filename Value="..\kern\kern_patcher.pas"/>
|
<Filename Value="..\kern\kern_patcher.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="..\kern\kern_stub.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
|
|
@ -107,6 +107,8 @@ procedure insmntque_stddtr(vp:p_vnode;dtr_arg:Pointer);
|
||||||
function insmntque1(vp:p_vnode;mp:p_mount;dtr:t_insmntque1_dtr;dtr_arg:Pointer):Integer;
|
function insmntque1(vp:p_vnode;mp:p_mount;dtr:t_insmntque1_dtr;dtr_arg:Pointer):Integer;
|
||||||
function insmntque(vp:p_vnode;mp:p_mount):Integer;
|
function insmntque(vp:p_vnode;mp:p_mount):Integer;
|
||||||
|
|
||||||
|
function vinvalbuf(vp:p_vnode;flags,slpflag,slptimeo:Integer):Integer;
|
||||||
|
|
||||||
function __mnt_vnode_next_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
function __mnt_vnode_next_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
||||||
function __mnt_vnode_first_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
function __mnt_vnode_first_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
||||||
procedure __mnt_vnode_markerfree_all(mvp:pp_vnode;mp:p_mount);
|
procedure __mnt_vnode_markerfree_all(mvp:pp_vnode;mp:p_mount);
|
||||||
|
@ -725,7 +727,7 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
* Exitthe next vnode from the free list.
|
* Return the next vnode from the free list.
|
||||||
}
|
}
|
||||||
function getnewvnode(tag:PChar;mp:p_mount;vops:p_vop_vector;vpp:pp_vnode):Integer;
|
function getnewvnode(tag:PChar;mp:p_mount;vops:p_vop_vector;vpp:pp_vnode):Integer;
|
||||||
label
|
label
|
||||||
|
@ -868,7 +870,9 @@ begin
|
||||||
{ XXX non mp-safe fs may still call insmntque with vnode
|
{ XXX non mp-safe fs may still call insmntque with vnode
|
||||||
unlocked }
|
unlocked }
|
||||||
if (VOP_ISLOCKED(vp)=0) then
|
if (VOP_ISLOCKED(vp)=0) then
|
||||||
|
begin
|
||||||
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
|
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
|
||||||
|
end;
|
||||||
vgone(vp);
|
vgone(vp);
|
||||||
vput(vp);
|
vput(vp);
|
||||||
end;
|
end;
|
||||||
|
@ -895,8 +899,8 @@ begin
|
||||||
MNT_ILOCK(mp);
|
MNT_ILOCK(mp);
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
if ((mp^.mnt_kern_flag and MNTK_NOINSMNTQ)<>0) and
|
if ((mp^.mnt_kern_flag and MNTK_NOINSMNTQ)<>0) and
|
||||||
(((mp^.mnt_kern_flag and MNTK_UNMOUNTF)<>0) or
|
(((mp^.mnt_kern_flag and MNTK_UNMOUNTF)<>0) or
|
||||||
(mp^.mnt_nvnodelistsize=0)) then
|
(mp^.mnt_nvnodelistsize=0)) then
|
||||||
begin
|
begin
|
||||||
locked:=VOP_ISLOCKED(vp);
|
locked:=VOP_ISLOCKED(vp);
|
||||||
if (locked=0) or
|
if (locked=0) or
|
||||||
|
@ -906,7 +910,9 @@ begin
|
||||||
VI_UNLOCK(vp);
|
VI_UNLOCK(vp);
|
||||||
MNT_IUNLOCK(mp);
|
MNT_IUNLOCK(mp);
|
||||||
if (dtr<>nil) then
|
if (dtr<>nil) then
|
||||||
|
begin
|
||||||
dtr(vp, dtr_arg);
|
dtr(vp, dtr_arg);
|
||||||
|
end;
|
||||||
Exit(EBUSY);
|
Exit(EBUSY);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -1941,7 +1947,9 @@ begin
|
||||||
Assert((flags and LK_TYPE_MASK)<>0,'vget: invalid lock operation');
|
Assert((flags and LK_TYPE_MASK)<>0,'vget: invalid lock operation');
|
||||||
|
|
||||||
if ((flags and LK_INTERLOCK)=0) then
|
if ((flags and LK_INTERLOCK)=0) then
|
||||||
|
begin
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
|
end;
|
||||||
|
|
||||||
vholdl(vp);
|
vholdl(vp);
|
||||||
|
|
||||||
|
@ -1951,8 +1959,10 @@ begin
|
||||||
vdrop(vp);
|
vdrop(vp);
|
||||||
Exit(error);
|
Exit(error);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if ((vp^.v_iflag and VI_DOOMED)<>0) and ((flags and LK_RETRY)=0) then
|
if ((vp^.v_iflag and VI_DOOMED)<>0) and ((flags and LK_RETRY)=0) then
|
||||||
Assert(false,'vget: vn_lock failed to Exit ENOENT');
|
Assert(false,'vget: vn_lock failed to Exit ENOENT');
|
||||||
|
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
{ Upgrade our holdcnt to a usecount. }
|
{ Upgrade our holdcnt to a usecount. }
|
||||||
v_upgrade_usecount(vp);
|
v_upgrade_usecount(vp);
|
||||||
|
@ -1966,7 +1976,10 @@ begin
|
||||||
begin
|
begin
|
||||||
if (VOP_ISLOCKED(vp)=LK_EXCLUSIVE) and
|
if (VOP_ISLOCKED(vp)=LK_EXCLUSIVE) and
|
||||||
((flags and LK_NOWAIT)=0) then
|
((flags and LK_NOWAIT)=0) then
|
||||||
|
begin
|
||||||
vinactive(vp);
|
vinactive(vp);
|
||||||
|
end;
|
||||||
|
|
||||||
vp^.v_iflag:=vp^.v_iflag and (not VI_OWEINACT);
|
vp^.v_iflag:=vp^.v_iflag and (not VI_OWEINACT);
|
||||||
end;
|
end;
|
||||||
VI_UNLOCK(vp);
|
VI_UNLOCK(vp);
|
||||||
|
@ -3169,10 +3182,12 @@ procedure vop_rename_fail(ap:p_vop_rename_args);
|
||||||
begin
|
begin
|
||||||
if (ap^.a_tvp<>nil) then
|
if (ap^.a_tvp<>nil) then
|
||||||
vput(ap^.a_tvp);
|
vput(ap^.a_tvp);
|
||||||
|
|
||||||
if (ap^.a_tdvp=ap^.a_tvp) then
|
if (ap^.a_tdvp=ap^.a_tvp) then
|
||||||
vrele(ap^.a_tdvp)
|
vrele(ap^.a_tdvp)
|
||||||
else
|
else
|
||||||
vput(ap^.a_tdvp);
|
vput(ap^.a_tdvp);
|
||||||
|
|
||||||
vrele(ap^.a_fdvp);
|
vrele(ap^.a_fdvp);
|
||||||
vrele(ap^.a_fvp);
|
vrele(ap^.a_fvp);
|
||||||
end;
|
end;
|
||||||
|
@ -3181,9 +3196,12 @@ procedure vop_rename_pre(ap:p_vop_rename_args);
|
||||||
begin
|
begin
|
||||||
if (ap^.a_tdvp<>ap^.a_fdvp) then
|
if (ap^.a_tdvp<>ap^.a_fdvp) then
|
||||||
vhold(ap^.a_fdvp);
|
vhold(ap^.a_fdvp);
|
||||||
|
|
||||||
if (ap^.a_tvp<>ap^.a_fvp) then
|
if (ap^.a_tvp<>ap^.a_fvp) then
|
||||||
vhold(ap^.a_fvp);
|
vhold(ap^.a_fvp);
|
||||||
|
|
||||||
vhold(ap^.a_tdvp);
|
vhold(ap^.a_tdvp);
|
||||||
|
|
||||||
if (ap^.a_tvp<>nil) then
|
if (ap^.a_tvp<>nil) then
|
||||||
vhold(ap^.a_tvp);
|
vhold(ap^.a_tvp);
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -1598,7 +1598,9 @@ begin
|
||||||
MADV_CORE:
|
MADV_CORE:
|
||||||
begin
|
begin
|
||||||
if (start=__end) then
|
if (start=__end) then
|
||||||
|
begin
|
||||||
Exit(KERN_SUCCESS);
|
Exit(KERN_SUCCESS);
|
||||||
|
end;
|
||||||
modify_map:=1;
|
modify_map:=1;
|
||||||
vm_map_lock(map);
|
vm_map_lock(map);
|
||||||
end;
|
end;
|
||||||
|
@ -1607,7 +1609,9 @@ begin
|
||||||
MADV_FREE:
|
MADV_FREE:
|
||||||
begin
|
begin
|
||||||
if (start=__end) then
|
if (start=__end) then
|
||||||
|
begin
|
||||||
Exit(KERN_SUCCESS);
|
Exit(KERN_SUCCESS);
|
||||||
|
end;
|
||||||
vm_map_lock(map);
|
vm_map_lock(map);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
|
@ -1622,7 +1626,9 @@ begin
|
||||||
if (vm_map_lookup_entry(map,start,@entry)) then
|
if (vm_map_lookup_entry(map,start,@entry)) then
|
||||||
begin
|
begin
|
||||||
if (modify_map<>0) then
|
if (modify_map<>0) then
|
||||||
|
begin
|
||||||
vm_map_clip_start(map, entry, start);
|
vm_map_clip_start(map, entry, start);
|
||||||
|
end;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
entry:=entry^.next;
|
entry:=entry^.next;
|
||||||
|
|
|
@ -549,20 +549,27 @@ var
|
||||||
begin
|
begin
|
||||||
size:=len;
|
size:=len;
|
||||||
if (size=0) then
|
if (size=0) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
pageoff:=(vm_size_t(addr) and PAGE_MASK);
|
pageoff:=(vm_size_t(addr) and PAGE_MASK);
|
||||||
addr:=addr-pageoff;
|
addr:=addr-pageoff;
|
||||||
size:=size+pageoff;
|
size:=size+pageoff;
|
||||||
size:=round_page(size);
|
size:=round_page(size);
|
||||||
|
|
||||||
if (addr + size < addr) then
|
if (addr + size < addr) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
* Check for illegal addresses. Watch out for address wrap...
|
* Check for illegal addresses. Watch out for address wrap...
|
||||||
}
|
}
|
||||||
if (qword(addr) < vm_map_min(@g_vmspace.vm_map)) or (qword(addr) + size > vm_map_max(@g_vmspace.vm_map)) then
|
if (qword(addr) < vm_map_min(@g_vmspace.vm_map)) or (qword(addr) + size > vm_map_max(@g_vmspace.vm_map)) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
vm_map_lock(@g_vmspace.vm_map);
|
vm_map_lock(@g_vmspace.vm_map);
|
||||||
|
|
||||||
|
@ -585,8 +592,11 @@ begin
|
||||||
addr:=addr-pageoff;
|
addr:=addr-pageoff;
|
||||||
size:=size+pageoff;
|
size:=size+pageoff;
|
||||||
size:=round_page(size);
|
size:=round_page(size);
|
||||||
|
|
||||||
if (addr + size < addr) then
|
if (addr + size < addr) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
case (vm_map_protect(@g_vmspace.vm_map, QWORD(addr), QWORD(addr) + size, prot, FALSE)) of
|
case (vm_map_protect(@g_vmspace.vm_map, QWORD(addr), QWORD(addr) + size, prot, FALSE)) of
|
||||||
KERN_SUCCESS :Exit(0);
|
KERN_SUCCESS :Exit(0);
|
||||||
|
@ -621,9 +631,14 @@ begin
|
||||||
}
|
}
|
||||||
if (vm_offset_t(addr) < vm_map_min(@g_vmspace.vm_map)) or
|
if (vm_offset_t(addr) < vm_map_min(@g_vmspace.vm_map)) or
|
||||||
(vm_offset_t(addr) + len > vm_map_max(@g_vmspace.vm_map)) then
|
(vm_offset_t(addr) + len > vm_map_max(@g_vmspace.vm_map)) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
if (vm_offset_t(addr) + len) < vm_offset_t(addr) then
|
if (vm_offset_t(addr) + len) < vm_offset_t(addr) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
* Since this routine is only advisory, we default to conservative
|
* Since this routine is only advisory, we default to conservative
|
||||||
|
@ -633,7 +648,9 @@ begin
|
||||||
__end:=round_page(vm_offset_t(addr) + len);
|
__end:=round_page(vm_offset_t(addr) + len);
|
||||||
|
|
||||||
if (vm_map_madvise(@g_vmspace.vm_map, start, __end, behav))<>0 then
|
if (vm_map_madvise(@g_vmspace.vm_map, start, __end, behav))<>0 then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
Exit(0);
|
Exit(0);
|
||||||
end;
|
end;
|
||||||
|
@ -645,9 +662,14 @@ var
|
||||||
begin
|
begin
|
||||||
if (vm_offset_t(addr) < vm_map_min(@g_vmspace.vm_map)) or
|
if (vm_offset_t(addr) < vm_map_min(@g_vmspace.vm_map)) or
|
||||||
(vm_offset_t(addr) + len > vm_map_max(@g_vmspace.vm_map)) then
|
(vm_offset_t(addr) + len > vm_map_max(@g_vmspace.vm_map)) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
if (vm_offset_t(addr) + len) < vm_offset_t(addr) then
|
if (vm_offset_t(addr) + len) < vm_offset_t(addr) then
|
||||||
|
begin
|
||||||
Exit(EINVAL);
|
Exit(EINVAL);
|
||||||
|
end;
|
||||||
|
|
||||||
Result:=copyinstr(name,@_name,32,nil);
|
Result:=copyinstr(name,@_name,32,nil);
|
||||||
if (Result<>0) then Exit;
|
if (Result<>0) then Exit;
|
||||||
|
|
|
@ -61,14 +61,18 @@ const
|
||||||
OBJPR_NOTMAPPED=$2; // Don't unmap pages.
|
OBJPR_NOTMAPPED=$2; // Don't unmap pages.
|
||||||
OBJPR_NOTWIRED =$4; // Don't remove wired pages.
|
OBJPR_NOTWIRED =$4; // Don't remove wired pages.
|
||||||
|
|
||||||
procedure vm_object_reference (obj:vm_object_t);
|
procedure vm_object_reference (obj:vm_object_t);
|
||||||
function vm_object_allocate (t:objtype_t;size:vm_pindex_t):vm_object_t;
|
function vm_object_allocate (t:objtype_t;size:vm_pindex_t):vm_object_t;
|
||||||
procedure vm_object_deallocate(obj:vm_object_t);
|
procedure vm_object_deallocate (obj:vm_object_t);
|
||||||
procedure vm_object_clear_flag(obj:vm_object_t;bits:Word);
|
|
||||||
|
procedure vm_object_set_flag (obj:vm_object_t;bits:Word);
|
||||||
|
procedure vm_object_clear_flag (obj:vm_object_t;bits:Word);
|
||||||
|
|
||||||
procedure vm_object_pip_add (obj:vm_object_t;i:word);
|
procedure vm_object_pip_add (obj:vm_object_t;i:word);
|
||||||
procedure vm_object_pip_subtract(obj:vm_object_t;i:word);
|
procedure vm_object_pip_subtract(obj:vm_object_t;i:word);
|
||||||
procedure vm_object_pip_wakeup (obj:vm_object_t);
|
procedure vm_object_pip_wakeup (obj:vm_object_t);
|
||||||
|
procedure vm_object_pip_wakeupn (obj:vm_object_t;i:word);
|
||||||
|
procedure vm_object_pip_wait (obj:vm_object_t;waitid:pchar);
|
||||||
|
|
||||||
function vm_object_page_clean(obj:vm_object_t;
|
function vm_object_page_clean(obj:vm_object_t;
|
||||||
start,__end:vm_ooffset_t;
|
start,__end:vm_ooffset_t;
|
||||||
|
@ -79,8 +83,9 @@ procedure vm_object_page_remove(obj:vm_object_t;
|
||||||
__end:vm_pindex_t;
|
__end:vm_pindex_t;
|
||||||
options:Integer);
|
options:Integer);
|
||||||
|
|
||||||
procedure vm_object_collapse(obj:vm_object_t);
|
procedure vm_object_collapse (obj:vm_object_t);
|
||||||
|
|
||||||
|
function VM_OBJECT_MTX (obj:vm_object_t):p_mtx;
|
||||||
procedure VM_OBJECT_LOCK (obj:vm_object_t);
|
procedure VM_OBJECT_LOCK (obj:vm_object_t);
|
||||||
function VM_OBJECT_TRYLOCK (obj:vm_object_t):Boolean;
|
function VM_OBJECT_TRYLOCK (obj:vm_object_t):Boolean;
|
||||||
procedure VM_OBJECT_UNLOCK (obj:vm_object_t);
|
procedure VM_OBJECT_UNLOCK (obj:vm_object_t);
|
||||||
|
@ -99,7 +104,9 @@ function vm_object_coalesce(prev_object:vm_object_t;
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
vmparam;
|
vmparam,
|
||||||
|
vnode,
|
||||||
|
vfs_subr;
|
||||||
|
|
||||||
function IDX_TO_OFF(x:DWORD):QWORD; inline;
|
function IDX_TO_OFF(x:DWORD):QWORD; inline;
|
||||||
begin
|
begin
|
||||||
|
@ -111,6 +118,11 @@ begin
|
||||||
Result:=QWORD(x) shr PAGE_SHIFT;
|
Result:=QWORD(x) shr PAGE_SHIFT;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function VM_OBJECT_MTX(obj:vm_object_t):p_mtx;
|
||||||
|
begin
|
||||||
|
Result:=@obj^.mtx;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure VM_OBJECT_LOCK(obj:vm_object_t);
|
procedure VM_OBJECT_LOCK(obj:vm_object_t);
|
||||||
begin
|
begin
|
||||||
mtx_lock(obj^.mtx);
|
mtx_lock(obj^.mtx);
|
||||||
|
@ -136,6 +148,12 @@ begin
|
||||||
Assert(mtx_owned(obj^.mtx));
|
Assert(mtx_owned(obj^.mtx));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure vm_object_set_flag(obj:vm_object_t;bits:Word);
|
||||||
|
begin
|
||||||
|
VM_OBJECT_LOCK_ASSERT(obj);
|
||||||
|
obj^.flags:=obj^.flags or bits;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure vm_object_clear_flag(obj:vm_object_t;bits:Word);
|
procedure vm_object_clear_flag(obj:vm_object_t;bits:Word);
|
||||||
begin
|
begin
|
||||||
VM_OBJECT_LOCK_ASSERT(obj);
|
VM_OBJECT_LOCK_ASSERT(obj);
|
||||||
|
@ -154,9 +172,14 @@ begin
|
||||||
Result^.size :=size;
|
Result^.size :=size;
|
||||||
Result^.generation:=1;
|
Result^.generation:=1;
|
||||||
Result^.ref_count :=1;
|
Result^.ref_count :=1;
|
||||||
|
|
||||||
|
if (t=OBJT_DEFAULT) then
|
||||||
|
begin
|
||||||
|
Result^.flags:=OBJ_ONEMAPPING;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure _vm_object_deallocate(obj:vm_object_t);
|
procedure vm_object_destroy(obj:vm_object_t);
|
||||||
begin
|
begin
|
||||||
Case obj^.otype of
|
Case obj^.otype of
|
||||||
OBJT_DEFAULT:;
|
OBJT_DEFAULT:;
|
||||||
|
@ -175,19 +198,77 @@ begin
|
||||||
System.InterlockedIncrement(obj^.ref_count);
|
System.InterlockedIncrement(obj^.ref_count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
vm_object_terminate actually destroys the specified object, freeing
|
||||||
|
up all previously used resources.
|
||||||
|
|
||||||
|
The object must be locked.
|
||||||
|
This routine may block.
|
||||||
|
}
|
||||||
|
procedure vm_object_terminate(obj:vm_object_t);
|
||||||
|
var
|
||||||
|
vp:p_vnode;
|
||||||
|
begin
|
||||||
|
VM_OBJECT_LOCK_ASSERT(obj);
|
||||||
|
|
||||||
|
{
|
||||||
|
* Make sure no one uses us.
|
||||||
|
}
|
||||||
|
vm_object_set_flag(obj, OBJ_DEAD);
|
||||||
|
|
||||||
|
{
|
||||||
|
* wait for the pageout daemon to be done with the obj
|
||||||
|
}
|
||||||
|
vm_object_pip_wait(obj, 'objtrm');
|
||||||
|
|
||||||
|
Assert(obj^.paging_in_progress=0,'vm_object_terminate: pageout in progress');
|
||||||
|
|
||||||
|
{
|
||||||
|
* Clean and free the pages, as appropriate. All references to the
|
||||||
|
* obj are gone, so we don't need to lock it.
|
||||||
|
}
|
||||||
|
if (obj^.otype=OBJT_VNODE) then
|
||||||
|
begin
|
||||||
|
vp:=obj^.handle;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Clean pages and flush buffers.
|
||||||
|
}
|
||||||
|
vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
|
||||||
|
VM_OBJECT_UNLOCK(obj);
|
||||||
|
|
||||||
|
vinvalbuf(vp, V_SAVE, 0, 0);
|
||||||
|
|
||||||
|
VM_OBJECT_LOCK(obj);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Assert(obj^.ref_count=0,'vm_object_terminate: obj with references');
|
||||||
|
|
||||||
|
VM_OBJECT_UNLOCK(obj);
|
||||||
|
|
||||||
|
vm_object_destroy(obj);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure vm_object_deallocate(obj:vm_object_t);
|
procedure vm_object_deallocate(obj:vm_object_t);
|
||||||
|
var
|
||||||
|
ref:Integer;
|
||||||
begin
|
begin
|
||||||
if (obj=nil) then Exit;
|
if (obj=nil) then Exit;
|
||||||
|
|
||||||
if (System.InterlockedDecrement(obj^.ref_count)=0) then
|
ref:=System.InterlockedDecrement(obj^.ref_count);
|
||||||
begin
|
|
||||||
_vm_object_deallocate(obj);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure vm_object_destroy(obj:vm_object_t);
|
if (ref=1) then
|
||||||
begin
|
begin
|
||||||
vm_object_deallocate(obj);
|
VM_OBJECT_LOCK(obj);
|
||||||
|
vm_object_set_flag(obj, OBJ_ONEMAPPING);
|
||||||
|
VM_OBJECT_UNLOCK(obj);
|
||||||
|
end else
|
||||||
|
if (ref=0) then
|
||||||
|
if ((obj^.flags and OBJ_DEAD)=0) then
|
||||||
|
begin
|
||||||
|
VM_OBJECT_LOCK(obj);
|
||||||
|
vm_object_terminate(obj);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure vm_object_pip_add(obj:vm_object_t;i:word);
|
procedure vm_object_pip_add(obj:vm_object_t;i:word);
|
||||||
|
@ -219,6 +300,31 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure vm_object_pip_wakeupn(obj:vm_object_t;i:word);
|
||||||
|
begin
|
||||||
|
if (obj=nil) then Exit;
|
||||||
|
|
||||||
|
VM_OBJECT_LOCK_ASSERT(obj);
|
||||||
|
Dec(obj^.paging_in_progress,i);
|
||||||
|
if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.paging_in_progress=0) then
|
||||||
|
begin
|
||||||
|
vm_object_clear_flag(obj, OBJ_PIPWNT);
|
||||||
|
wakeup(obj);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure vm_object_pip_wait(obj:vm_object_t;waitid:pchar);
|
||||||
|
begin
|
||||||
|
if (obj=nil) then Exit;
|
||||||
|
|
||||||
|
VM_OBJECT_LOCK_ASSERT(obj);
|
||||||
|
while (obj^.paging_in_progress<>0) do
|
||||||
|
begin
|
||||||
|
obj^.flags:=obj^.flags or OBJ_PIPWNT;
|
||||||
|
msleep(obj, VM_OBJECT_MTX(obj), PVM, waitid, 0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
vm_object_page_clean
|
vm_object_page_clean
|
||||||
|
|
||||||
|
@ -277,7 +383,9 @@ procedure vm_object_page_remove(obj:vm_object_t;
|
||||||
__end:vm_pindex_t;
|
__end:vm_pindex_t;
|
||||||
options:Integer);
|
options:Integer);
|
||||||
begin
|
begin
|
||||||
|
//OBJPR_CLEANONLY=$1; // Don't remove dirty pages.
|
||||||
|
//OBJPR_NOTMAPPED=$2; // Don't unmap pages.
|
||||||
|
//OBJPR_NOTWIRED =$4; // Don't remove wired pages.
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -348,15 +456,6 @@ begin
|
||||||
Exit(FALSE);
|
Exit(FALSE);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
|
||||||
* Remove any pages that may still be in the object from a previous
|
|
||||||
* deallocation.
|
|
||||||
}
|
|
||||||
if (next_pindex<prev_object^.size) then
|
|
||||||
begin
|
|
||||||
vm_object_page_remove(prev_object,next_pindex,next_pindex+next_size,0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
* Extend the object if necessary.
|
* Extend the object if necessary.
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue