This commit is contained in:
Pavel 2024-04-08 11:24:00 +03:00
parent f8fbc405f8
commit 1fa7194321
9 changed files with 403 additions and 188 deletions

View File

@ -141,9 +141,12 @@ begin
//g_appinfo.debug_level:=1;
//budget init
kern_app_state_change(as_start);
kern_app_state_change(as_begin_game_app_mount);
p_proc.p_budget_ptype:=PTYPE_BIG_APP;
p_proc.p_self_fixed :=1;
p_proc.p_mode_2mb :=M2MB_DISABLE;
g_mode_2mb:=M2MB_DEFAULT;
///
Writeln(Item.FGameInfo.Exec);

View File

@ -3298,7 +3298,7 @@ var
),
(//[648]
sy_narg:1;
sy_call:nil;
sy_call:@sys_app_state_change;
sy_name:'sys_app_state_change'
),
(//[649]

View File

@ -5,10 +5,6 @@ unit kern_budget;
interface
uses
vm,
sys_vm_object;
type
p_budget_resource=^t_budget_resource;
t_budget_resource=packed record
@ -34,9 +30,9 @@ const
SCE_KERNEL_BUDGET_FD_IPCSOCKET=11;
//budget proc_type
PTYPE_BIG_APP = 0;
PTYPE_MINI_APP = 1;
PTYPE_SYSTEM = 2;
PTYPE_BIG_APP = 0; //SCE_APPLICATION_TYPE_GAME
PTYPE_MINI_APP = 1; //SCE_APPLICATION_TYPE_MINI
PTYPE_SYSTEM = 2; //SCE_APPLICATION_TYPE_DAEMON
PTYPE_NONGAME_MINI_APP = 3;
function sys_budget_create(name:pchar;ptype:DWORD;new:Pointer;count:DWORD;prev:Pointer):Integer;
@ -62,25 +58,39 @@ const
field_malloc =3;
const
FMEM_BASE =$4000000;
bigapp_size =$4000000;
bigapp_max_exe_size=$20000000;
FMEM_BASE =$4000000;
bigapp_size =$4000000;
bigapp_max_fmem_size=$20000000;
var
FMEM_LIMIT :QWORD=0;
DMEM_LIMIT :QWORD=$180000000;
EXE_FILE_SIZE:QWORD=FMEM_BASE+0;
ExtendedSize :QWORD=0;
FMEM_LIMIT :QWORD=0;
DMEM_LIMIT :QWORD=$180000000;
game_fmem_size:QWORD=FMEM_BASE+0;
ExtendedSize :QWORD=0;
ext_game_fmem_addr:Integer=0;
BigAppMemory :QWORD=$170000000; //148000000,170000000,124000000
g_self_loading:Integer=0;
ext_game_fmem :Integer=0;
IGNORE_EXTENDED_DMEM_BASE:Integer=0;
procedure set_budget_limit (ptype,field:Integer;value:QWORD);
const
M2MB_DEFAULT =0; //Default =0 (ATTRIBUTE2:0x00000)
M2MB_DISABLE =1; //NotUsed =32768 (ATTRIBUTE2:0x08000)
M2MB_READONLY=2; //Text_rodata=65536 (ATTRIBUTE2:0x10000)
M2MB_ENABLE =3; //All_section=98304 (ATTRIBUTE2:0x18000)
var
g_mode_2mb :Integer=M2MB_DEFAULT;
g_mode_2mb_size:Integer=0;
g_mode_2mb_rsrv:Integer=0;
function vm_budget_limit (ptype,field:Integer):QWORD;
function vm_budget_used (ptype,field:Integer):QWORD;
function vm_budget_reserve(ptype,field:Integer;len:QWORD):Integer;
procedure vm_budget_release(ptype,field:Integer;len:QWORD);
procedure init_bigapp_limits;
procedure set_bigapp_cred_limits;
procedure set_bigapp_limits(size,unknow:QWORD);
@ -89,6 +99,20 @@ function dmem_process_relocated():Integer;
function get_mlock_avail():QWORD;
function get_mlock_total():QWORD;
const
//app_state
as_start =1;
as_stop =2;
as_begin_game_app_mount =3;
as___end_game_app_mount =4;
as_begin_mini_app_mount =5;
as___end_mini_app_mount =6;
as__enable_ext_game_fmem=7;
as_disable_ext_game_fmem=8;
function kern_app_state_change(state:Integer):Integer;
function sys_app_state_change(state:Integer):Integer;
implementation
uses
@ -108,7 +132,7 @@ var
budget_lock :Pointer;
procedure set_budget_limit(ptype,field:Integer;value:QWORD);
procedure vm_set_budget_limit(ptype,field:Integer;value:QWORD);
begin
rw_wlock(budget_lock);
@ -199,6 +223,37 @@ begin
end;
end;
procedure init_bigapp_limits;
var
size :QWORD;
value:QWORD;
m_256:QWORD;
begin
if (p_neomode<>0) then
begin
BigAppMemory:=$170000000;
end else
begin
BigAppMemory:=$148000000;
end;
size:=BigAppMemory - game_fmem_size;
m_256:=QWORD(ext_game_fmem<>0) * $10000000;
value:=size;
if (FMEM_LIMIT <= size) then
begin
value:=FMEM_LIMIT;
end;
DMEM_LIMIT:=size;
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
end;
procedure set_bigapp_cred_limits;
var
size :QWORD;
@ -224,7 +279,7 @@ begin
end;
m_256:=QWORD(ext_game_fmem_addr<>0) * $10000000;
m_256:=QWORD(ext_game_fmem<>0) * $10000000;
value:=size;
if (DMEM_LIMIT < size) then
@ -234,9 +289,9 @@ begin
FMEM_LIMIT:=size;
set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
set_budget_limit(PTYPE_BIG_APP,field_mlock ,(EXE_FILE_SIZE + m_256) - FMEM_BASE);
set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + EXE_FILE_SIZE);
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
end;
procedure set_bigapp_limits(size,unknow:QWORD);
@ -244,12 +299,28 @@ var
m_256:QWORD;
value:QWORD;
begin
if (EXE_FILE_SIZE<>size) then
if (game_fmem_size<>size) then
begin
//reserve dmem
EXE_FILE_SIZE:=size;
m_256:=QWORD(ext_game_fmem_addr<>0) * $10000000;
if (size < game_fmem_size) then
begin
value:=BigAppMemory - size;
game_fmem_size:=size;
DMEM_LIMIT :=value;
end else
begin
if (unknow<>0) and
((game_fmem_size and $1fffff)<>0) then
begin
Writeln(stderr,'game_fmem_size is not multiple of 2MB: 0x',HexStr(game_fmem_size,8));
end;
value:=BigAppMemory - size;
game_fmem_size:=size;
DMEM_LIMIT :=value;
end;
m_256:=QWORD(ext_game_fmem<>0) * $10000000;
value:=FMEM_LIMIT;
if (DMEM_LIMIT < FMEM_LIMIT) then
@ -257,19 +328,19 @@ begin
value:=DMEM_LIMIT;
end;
set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
set_budget_limit(PTYPE_BIG_APP,field_mlock ,(EXE_FILE_SIZE + m_256) - FMEM_BASE);
set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + EXE_FILE_SIZE);
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
end;
end;
function expand_and_reserve_game_fmem(size:QWORD):QWORD;
begin
if (size <= QWORD(bigapp_max_exe_size - EXE_FILE_SIZE)) then
if (size <= QWORD(bigapp_max_fmem_size - game_fmem_size)) then
begin
EXE_FILE_SIZE:=EXE_FILE_SIZE + size;
DMEM_LIMIT :=DMEM_LIMIT - size;
Exit(DMEM_LIMIT + size);
DMEM_LIMIT :=BigAppMemory - (game_fmem_size + size);
game_fmem_size:=game_fmem_size + size;
Exit(BigAppMemory - game_fmem_size);
end;
Writeln(stderr,'expand_and_reserve_game_fmem=',size);
@ -283,7 +354,7 @@ var
begin
Result:=expand_and_reserve_game_fmem(size);
m_256:=QWORD(ext_game_fmem_addr<>0) * $10000000;
m_256:=QWORD(ext_game_fmem<>0) * $10000000;
value:=FMEM_LIMIT;
if (DMEM_LIMIT < FMEM_LIMIT) then
@ -291,9 +362,9 @@ begin
value:=DMEM_LIMIT;
end;
set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
set_budget_limit(PTYPE_BIG_APP,field_mlock ,(EXE_FILE_SIZE + m_256) - FMEM_BASE);
set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + EXE_FILE_SIZE);
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,value);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
if (vm_budget_reserve(PTYPE_BIG_APP,field_mlock,size)<>0) then
begin
@ -319,14 +390,16 @@ begin
if ((GpuPagesSize or CpuPages)<> 0) then
begin
size:=0;
if (param_3=0) then
begin
size:=(QWORD(ord(p_neomode=0)) * $800000) + GpuPagesSize + (CpuPages * $1000);
if (QWORD(bigapp_max_exe_size - EXE_FILE_SIZE) < size) then
if (QWORD(bigapp_max_fmem_size - game_fmem_size) < size) then
begin
Writeln('[KERNEL] WARNING: Failed to allocate extended page table pool. shortage = '
,(EXE_FILE_SIZE - bigapp_max_exe_size) + $fffff + (size shr 20),
,(game_fmem_size - bigapp_max_fmem_size) + $fffff + (size shr 20),
'MiB');
Exit(ENOMEM);
end;
@ -335,6 +408,8 @@ begin
end;
//reserved physical pages
ExtendedSize:=size;
end;
end;
@ -412,9 +487,9 @@ begin
_next:
if (Byte((mmap_flags xor 1) or ord(p_proc.p_self_fixed=0))=0) then
if (Byte((mmap_flags xor 1) or ord(g_self_loading=0))=0) then
begin
p_proc.p_self_fixed:=0;
g_self_loading:=0;
ExtendedMemory1:=true;
if (p_proc.p_sdk_version < $5000000) then
@ -422,12 +497,14 @@ begin
ExtendedMemory1:=fubyte(mem_param.sceKernelExtendedMemory1^)=1;
end;
m_256:=QWORD(ext_game_fmem_addr<>0) * $10000000;
m_256:=QWORD(ext_game_fmem<>0) * $10000000;
if (p_neomode<>0) and
((not ExtendedMemory1) or (IGNORE_EXTENDED_DMEM_BASE<>0)) then
begin
FMEM_SIZE:=$10000000 - EXE_FILE_SIZE;
BigAppMemory:=BigAppMemory + (-$10000000) {+ ((ret or $10)=$19) * (-0x10000000)};
FMEM_SIZE:=BigAppMemory - game_fmem_size;
size:=FMEM_SIZE;
if (FMEM_LIMIT <= FMEM_SIZE) then
@ -437,9 +514,9 @@ begin
DMEM_LIMIT:=FMEM_SIZE;
set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,size);
set_budget_limit(PTYPE_BIG_APP,field_mlock ,(EXE_FILE_SIZE + m_256) - FMEM_BASE);
set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + EXE_FILE_SIZE);
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,size);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
end;
ExtendedMemory2:=true;
@ -456,10 +533,11 @@ begin
Writeln('[System] : SCE_KERNEL_EXTENDED_DMEM_BASE_128 was ignored');
end else
begin
FMEM_SIZE:=$8000000 - EXE_FILE_SIZE;
BigAppMemory:=BigAppMemory + (-$8000000) {+ ((ret and $ffffffe7)=1) * (-$8000000)};
FMEM_SIZE:=BigAppMemory - game_fmem_size;
size:=FMEM_SIZE;
if (FMEM_LIMIT <= FMEM_SIZE) then
begin
size:=FMEM_LIMIT;
@ -467,9 +545,9 @@ begin
DMEM_LIMIT:=FMEM_SIZE;
set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,size);
set_budget_limit(PTYPE_BIG_APP,field_mlock ,(EXE_FILE_SIZE + m_256) - FMEM_BASE);
set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + EXE_FILE_SIZE);
vm_set_budget_limit(PTYPE_BIG_APP,field_dmem_alloc,size);
vm_set_budget_limit(PTYPE_BIG_APP,field_mlock ,(game_fmem_size + m_256) - FMEM_BASE);
vm_set_budget_limit(PTYPE_BIG_APP,field_malloc ,m_256 + game_fmem_size);
end;
end;
@ -497,13 +575,13 @@ begin
if (ExtendedGpuPageTable < $1000000001) then
begin
ExtendedSize:=0;
FMEM_SIZE:=bigapp_max_exe_size;
FMEM_SIZE:=bigapp_max_fmem_size;
if (Result=0) then
begin
Result:=allocate_extended_page_table_pool(ExtendedCpuPageTable,ExtendedGpuPageTable,0);
FMEM_SIZE:=bigapp_max_exe_size;
FMEM_SIZE:=bigapp_max_fmem_size;
if (Result=0) then
begin
@ -515,19 +593,19 @@ begin
FlexibleMemorySize:=fuword64(mem_param.sceKernelFlexibleMemorySize^);
Result:=0;
FMEM_SIZE:=bigapp_max_exe_size;
FMEM_SIZE:=bigapp_max_fmem_size;
if (FlexibleMemorySize<>QWORD($ffffffffffffffff)) then
begin
FMEM_SIZE:=FMEM_BASE + FlexibleMemorySize;
if (bigapp_max_exe_size < FMEM_SIZE) or
if (bigapp_max_fmem_size < FMEM_SIZE) or
(FMEM_SIZE < bigapp_size) or
((FMEM_SIZE and QWORD($ffffffffffffc000))<>FMEM_SIZE) then
begin
Writeln(stderr,'[KERNEL] ERROR: invalid FMEM size (0x',HexStr(FlexibleMemorySize,16),') is specified.');
Result:=EINVAL;
FMEM_SIZE:=bigapp_max_exe_size;
FMEM_SIZE:=bigapp_max_fmem_size;
end;
end;
end;
@ -539,12 +617,12 @@ begin
Writeln('[KERNEL] ERROR: The extended GPU page table pool must be smaller than 64GiB');
Result:=ENOMEM;
ExtendedSize:=0;
FMEM_SIZE:=bigapp_max_exe_size;
FMEM_SIZE:=bigapp_max_fmem_size;
end;
if (FMEM_SIZE < EXE_FILE_SIZE) then
if (FMEM_SIZE < game_fmem_size) then
begin
Writeln(stderr,'[KERNEL] ERROR: The executable file size (= 0x',HexStr(EXE_FILE_SIZE,16),
Writeln(stderr,'[KERNEL] ERROR: The executable file size (= 0x',HexStr(game_fmem_size,16),
') < specified FMEM size (=0x',HexStr(FMEM_SIZE,16),')');
if (Result=0) then
begin
@ -662,6 +740,77 @@ begin
Exit(ENOSYS); //sceSblACMgrIsSystemUcred
end;
//
function kern_app_state_change(state:Integer):Integer;
var
used:QWORD;
begin
Result:=0;
case state of
as_start:
begin
g_self_loading:=1;
//app_state_counter+1
end;
as_stop:
begin
g_self_loading:=0;
//app_state_counter-1
end;
as_begin_game_app_mount:
begin
used:=vm_budget_used(PTYPE_BIG_APP,field_mlock);
if (used<>0) then
begin
Writeln(stderr,'BUDGET_MEMORY_MLOCK of game is being used: ',used,' bytes');
Assert(false,'BUDGET_MEMORY_MLOCK');
end;
end;
as___end_game_app_mount:
begin
//game_mounts_exist
//reset_2mb_mode
vm_budget_release(PTYPE_BIG_APP,field_mlock,ExtendedSize);
ExtendedSize:=0;
used:=vm_budget_used(PTYPE_BIG_APP,field_mlock);
if (used<>0) then
begin
Writeln(stderr,'BUDGET_MEMORY_MLOCK of game is being used: ',used,' bytes');
Assert(false,'BUDGET_MEMORY_MLOCK');
end;
set_bigapp_limits(bigapp_size,0);
end;
as_begin_mini_app_mount:; //nothing
as___end_mini_app_mount:; //nothing
as__enable_ext_game_fmem:
begin
if (ext_game_fmem<>0) then
begin
Writeln(stderr,'ext_game_fmem is already enabled');
Assert(false,'ext_game_fmem is already enabled');
end;
ext_game_fmem:=1;
end;
as_disable_ext_game_fmem:
begin
ext_game_fmem:=0;
end;
else;
end;
end;
//sceKernelNotifyAppStateChanged
function sys_app_state_change(state:Integer):Integer;
begin
//sceSblACMgrIsSyscoreProcess
Exit(EPERM);
end;
end.

View File

@ -293,14 +293,14 @@ begin
//budget
ssiz:=MAXSSIZ;
if (p_proc.p_self_fixed<>0) and
if (g_self_loading<>0) and
(p_proc.p_budget_ptype=PTYPE_BIG_APP) and
((g_appinfo.mmap_flags and 1)<>0) then
begin
limit:=EXE_FILE_SIZE + ssiz;
if (bigapp_max_exe_size < limit) then
limit:=game_fmem_size + ssiz;
if (bigapp_max_fmem_size < limit) then
begin
limit:=bigapp_max_exe_size;
limit:=bigapp_max_fmem_size;
end;
set_bigapp_limits(limit,0);
end;
@ -373,6 +373,11 @@ begin
Exit(error);
end;
//if (params->proc->vm_container == 1) {
// ret1 = vm_map_wire(vmspace,stack_addr,QWORD(vmspace^.sv_usrstack),9);
// if (ret1 != 0) goto __exit;
//}
vm_map_set_name(map,stack_addr,QWORD(vmspace^.sv_usrstack),'main stack');
{ vm_ssize and vm_maxsaddr are somewhat antiquated concepts in the
@ -618,73 +623,6 @@ begin
Exit(error);
end;
procedure scan_max_size(imgp:p_image_params;phdr:p_elf64_phdr;count:Integer;
var max_size1,max_size2:QWORD);
var
i:Integer;
hdr:p_elf64_hdr;
p_memsz:QWORD;
p_vaddr:QWORD;
size:QWORD;
base:QWORD;
p_type:Elf64_Word;
used_mode_2m:Boolean;
begin
max_size1:=0;
max_size2:=0;
hdr:=imgp^.image_header;
if (count<>0) then
begin
For i:=0 to count-1 do
begin
p_type :=phdr^.p_type;
p_memsz:=phdr^.p_memsz;
if ((p_type=PT_SCE_RELRO) or (p_type=PT_LOAD)) and (p_memsz<>0) then
begin
p_vaddr:=phdr^.p_vaddr;
if (hdr^.e_type=ET_SCE_DYNEXEC) then
begin
p_vaddr:=p_vaddr + QWORD(imgp^.reloc_base);
end;
p_memsz:=p_vaddr and $ffffffffffffc000;
p_vaddr:=(phdr^.p_memsz + p_vaddr - p_memsz + $3fff) and $ffffffffffffc000;
max_size1:=max_size1+p_vaddr;
used_mode_2m:=is_used_mode_2mb(phdr,0,p_proc.p_budget_ptype);
if (used_mode_2m) then
begin
size :=(p_vaddr + p_memsz) and $ffffffffffe00000;
p_vaddr:=(p_memsz + $1fffff) and $ffffffffffe00000;
base:=0;
if (p_vaddr<=size) then
begin
base:=size-p_vaddr;
end;
max_size2:=max_size2+base;
end;
end;
Inc(phdr);
end;
end;
end;
function scan_load_sections(imgp:p_image_params;phdr:p_elf64_phdr;count:Integer):Integer;
var
i:Integer;
@ -709,6 +647,9 @@ var
addr:QWORD;
size:QWORD;
used :QWORD;
limit:QWORD;
p_type :Elf64_Word;
p_flags :Byte;
_2mb_mode:Boolean;
@ -734,9 +675,9 @@ begin
if (p_proc.p_budget_ptype=PTYPE_BIG_APP) then
begin
//M2MB_READONLY,M2MB_ENABLE
_2mb_mode:=((p_proc.p_mode_2mb or 1)=3) or
((p_proc.p_self_fixed<>0) and (p_proc.p_mode_2mb=M2MB_NOTDYN_FIXED));
_2mb_mode:=((g_mode_2mb or 1)=3) or //M2MB_READONLY,M2MB_ENABLE
((g_self_loading<>0) and (g_mode_2mb=M2MB_DEFAULT));
end else
begin
_2mb_mode:=False;
@ -752,41 +693,41 @@ begin
scan_max_size(imgp,phdr,count,max_size1,max_size2);
if ((g_appinfo.mmap_flags and 1)<>0) and
(p_proc.p_self_fixed<>0) then
(g_self_loading<>0) then
begin
size:=p_proc.p_mode_2mb_size;
if (max_size2 < p_proc.p_mode_2mb_size) then
size:=g_mode_2mb_size;
if (max_size2 < g_mode_2mb_size) then
begin
size:=max_size2;
end;
p_offset:=0;
if ((p_proc.p_mode_2mb or 1)=3) then
if ((g_mode_2mb or 1)=3) then //M2MB_READONLY,M2MB_ENABLE
begin
p_offset:=size;
end;
p_memsz:=EXE_FILE_SIZE + max_size1;
p_memsz:=game_fmem_size + max_size1;
if (bigapp_max_exe_size < (p_memsz - p_offset)) then
if (bigapp_max_fmem_size < (p_memsz - p_offset)) then
begin
Writeln(stderr,'vm_budget ENOMEM');
Exit(ENOMEM);
end;
if ((DWORD(p_proc.p_mode_2mb) - 2) < 2) then
if ((DWORD(g_mode_2mb) - 2) < 2) then
begin
p_memsz:=p_memsz - size;
size:=0;
end else
begin
if (p_proc.p_mode_2mb=M2MB_DISABLE) then
if (g_mode_2mb=M2MB_DISABLE) then
begin
size:=0;
end else
begin
size:=max_size2;
if (p_proc.p_mode_2mb<>M2MB_NOTDYN_FIXED) then
if (g_mode_2mb<>M2MB_DEFAULT) then
begin
Writeln(stderr,'unknown 2mb mode');
Assert(false,'unknown 2mb mode');
@ -794,26 +735,26 @@ begin
end;
end;
if (bigapp_max_exe_size < p_memsz) then
if (bigapp_max_fmem_size < p_memsz) then
begin
p_memsz:=bigapp_max_exe_size;
p_memsz:=bigapp_max_fmem_size;
end;
set_bigapp_limits(p_memsz,size);
end;
if ((p_proc.p_mode_2mb and $fffffffe)=M2MB_READONLY) then
if ((g_mode_2mb and $fffffffe)=2) then //M2MB_READONLY,M2MB_ENABLE
begin
size:=p_proc.p_mode_2mb_rsrv;
size:=g_mode_2mb_rsrv;
if (size<=max_size2) then
begin
max_size2:=p_proc.p_mode_2mb_rsrv;
max_size2:=g_mode_2mb_rsrv;
end;
p_vaddr :=vm_budget_used (PTYPE_BIG_APP,field_mlock);
p_offset:=vm_budget_limit(PTYPE_BIG_APP,field_mlock);
used :=vm_budget_used (PTYPE_BIG_APP,field_mlock);
limit:=vm_budget_limit(PTYPE_BIG_APP,field_mlock);
if (p_offset < (p_vaddr + (max_size1 - max_size2))) then
if (limit < (used + (max_size1 - max_size2))) then
begin
Writeln(stderr,'vm_budget ENOMEM');
Exit(ENOMEM);
@ -862,6 +803,7 @@ begin
p_memsz,
p_filesz,
p_flags,
0,
used_mode_2m,
'executable',
cache);
@ -884,6 +826,7 @@ begin
p_memsz,
p_filesz,
p_flags,
0,
used_mode_2m,
'executable',
cache);
@ -1514,6 +1457,15 @@ begin
imgp:=@image_params;
image_params:=Default(t_image_params);
if (p_proc.p_budget_ptype=PTYPE_BIG_APP) then
if ((g_appinfo.mmap_flags and 1)<>0) then
begin
if (g_self_loading<>0) then
begin
init_bigapp_limits;
end;
end;
p_proc.p_flag:=p_proc.p_flag or P_INEXEC;
{

View File

@ -59,13 +59,8 @@ var
p_vmspace:Pointer;
p_self_fixed :Integer;
p_budget_ptype :Integer;
p_dmem_aliasing:Integer;
p_mode_2mb :Integer;
p_mode_2mb_size:Integer;
p_mode_2mb_rsrv:Integer;
end;
function pargs_alloc(len:Integer):p_pargs;

View File

@ -148,16 +148,10 @@ type
hdr_e_type:Integer;
end;
const
M2MB_NOTDYN_FIXED=0; //Default =0 (ATTRIBUTE2:0x00000)
M2MB_DISABLE =1; //NotUsed =32768 (ATTRIBUTE2:0x08000)
M2MB_READONLY =2; //Text_rodata=65536 (ATTRIBUTE2:0x10000)
M2MB_ENABLE =3; //All_section=98304 (ATTRIBUTE2:0x18000)
function maxInt64(a,b:Int64):Int64; inline;
function minInt64(a,b:Int64):Int64; inline;
function get_elf_phdr(elf_hdr:p_elf64_hdr):p_elf64_phdr; inline;
function get_elf_phdr(elf_hdr:p_elf64_hdr):p_elf64_phdr;
procedure rtld_free_self(imgp:p_image_params);
function rtld_load_self(imgp:p_image_params):Integer;
@ -188,6 +182,7 @@ function scan_dyn_offset(imgp:p_image_params;phdr:p_elf64_phdr;count:Integer):I
function self_load_section(imgp:p_image_params;
id,vaddr,offset,memsz,filesz:QWORD;
prot:Byte;
wire:Byte;
use_mode_2mb:Boolean;
name:pchar;
var cache:Pointer):Integer;
@ -511,10 +506,10 @@ begin
flag_write:=phdr^.p_flags and 2;
end;
case p_proc.p_mode_2mb of
M2MB_NOTDYN_FIXED:Result:=(is_dynlib=0) and (p_proc.p_self_fixed<>0);
M2MB_READONLY :Result:=(flag_write=0);
M2MB_ENABLE :Result:=True;
case g_mode_2mb of
M2MB_DEFAULT :Result:=(is_dynlib=0) and (g_self_loading<>0);
M2MB_READONLY:Result:=(flag_write=0);
M2MB_ENABLE :Result:=True;
else;
end;
@ -1044,6 +1039,7 @@ end;
function self_load_section(imgp:p_image_params;
id,vaddr,offset,memsz,filesz:QWORD;
prot:Byte;
wire:Byte;
use_mode_2mb:Boolean;
name:pchar;
var cache:Pointer):Integer;
@ -1051,6 +1047,7 @@ var
map:vm_map_t;
vaddr_lo:QWORD;
vaddr_hi:QWORD;
size :QWORD;
base :Pointer;
begin
Result:=0;
@ -1073,15 +1070,29 @@ begin
Exit(ENOEXEC);
end;
vaddr_lo:=vaddr and $ffffffffffffc000;
vaddr_hi:=(memsz + vaddr + $3fff) and $ffffffffffffc000;
if (use_mode_2mb) then
if (filesz < memsz) then
begin
vaddr_lo:=(vaddr + $1fffff) and $ffffffffffe00000;
vaddr_hi:=(vaddr + memsz + $3fff) and $ffffffffffe00000;
if (use_mode_2mb) then
begin
size:=QWORD($ffffffffffe00000);
end else
begin
size:=QWORD($ffffffffffffc000);
end;
size:=size and filesz;
end else
begin
size:=(filesz + $3fff) and QWORD($ffffffffffffc000);
end;
if (size>memsz) then
begin
memsz:=size;
end;
vaddr_lo:=vaddr and QWORD($ffffffffffffc000);
vaddr_hi:=(vaddr + memsz + $3fff) and QWORD($ffffffffffffc000);
base:=Pointer(imgp^.image_header)+offset;
map:=p_proc.p_vmspace;
@ -1100,22 +1111,19 @@ begin
//
vm_object_deallocate(imgp^.obj);
//
Writeln(StdErr,'[',HexStr(vaddr_lo,8),'..',HexStr(vaddr_hi,8),']');
Writeln(StdErr,'[KERNEL] self_load_section: vm_map_insert failed ',id,', ',HexStr(vaddr,8));
Exit(vm_mmap_to_errno(Result));
end;
vm_map_set_name_locked(map,vaddr_lo,vaddr_hi,name);
//wire
memsz:=vaddr_hi-vaddr_lo;
cache:=ReAllocMem(cache,memsz);
if ((prot and VM_PROT_EXECUTE)<>0) then
begin
FillChar(cache^,memsz,$90);
end else
begin
FillChar(cache^,memsz,0);
end;
FillChar(cache^,memsz,0);
Move(base^,cache^,filesz);

View File

@ -275,14 +275,14 @@ begin
offset1:=QWORD(frame)-QWORD(info.base_addr);
offset2:=QWORD(frame)-QWORD(info.func_addr);
Writeln(f,' offset $',HexStr(offset1 shr 48,5),'|',HexStr(offset1,6),' ',info.source,':',info.func,'+$',HexStr(offset2,6));
Writeln(f,' offset $',HexStr(offset1 shr 24,5),'|',HexStr(offset1,6),' ',info.source,':',info.func,'+$',HexStr(offset2,6));
end else
begin
if (info.base_addr<>0) then
begin
offset1:=QWORD(frame)-QWORD(info.base_addr);
Writeln(f,' offset $',HexStr(offset1 shr 48,5),'|',HexStr(offset1,6),' ',info.source);
Writeln(f,' offset $',HexStr(offset1 shr 24,5),'|',HexStr(offset1,6),' ',info.source);
end else
begin
Writeln(f,' $',HexStr(frame),' ',info.source);

View File

@ -302,6 +302,10 @@ function check_relo_bits(obj:p_lib_info;i:Integer):Boolean;
procedure set_relo_bits (obj:p_lib_info;i:Integer);
procedure reset_relo_bits(obj:p_lib_info;i:Integer);
procedure scan_max_size(imgp:p_image_params;
phdr:p_elf64_phdr;count:Integer;
var max_size1,max_size2:QWORD);
procedure donelist_init(var dlp:t_DoneList);
function donelist_check(var dlp:t_DoneList;obj:p_lib_info):Boolean;
@ -1716,7 +1720,7 @@ begin
p^:=p^ and (not (1 shl (i and 7)));
end;
function dynlib_load_sections(imgp:p_image_params;new:p_lib_info;phdr:p_elf64_phdr;count:Integer;delta:QWORD):Integer;
function dynlib_load_sections(imgp:p_image_params;new:p_lib_info;phdr:p_elf64_phdr;count:Integer;delta:QWORD;wire:Integer):Integer;
var
i:Integer;
@ -1757,7 +1761,7 @@ begin
if (p_proc.p_budget_ptype=PTYPE_BIG_APP) then
begin
_2mb_mode:=((p_proc.p_mode_2mb or 1)=3);
_2mb_mode:=((g_mode_2mb or 1)=3); //M2MB_READONLY,M2MB_ENABLE
end else
begin
_2mb_mode:=False;
@ -1803,6 +1807,7 @@ begin
p_memsz,
p_filesz,
p_flags,
wire,
used_mode_2m,
fname,
cache);
@ -1825,6 +1830,7 @@ begin
p_memsz,
p_filesz,
p_flags,
wire,
used_mode_2m,
fname,
cache);
@ -1915,6 +1921,74 @@ begin
new^.relro_size :=imgp^.relro_size;
end;
procedure scan_max_size(imgp:p_image_params;
phdr:p_elf64_phdr;count:Integer;
var max_size1,max_size2:QWORD);
var
i:Integer;
hdr:p_elf64_hdr;
p_memsz:QWORD;
p_vaddr:QWORD;
size:QWORD;
base:QWORD;
p_type:Elf64_Word;
used_mode_2m:Boolean;
begin
max_size1:=0;
max_size2:=0;
hdr:=imgp^.image_header;
if (count<>0) then
begin
For i:=0 to count-1 do
begin
p_type :=phdr^.p_type;
p_memsz:=phdr^.p_memsz;
if ((p_type=PT_SCE_RELRO) or (p_type=PT_LOAD)) and (p_memsz<>0) then
begin
p_vaddr:=phdr^.p_vaddr;
if (hdr^.e_type=ET_SCE_DYNEXEC) then
begin
p_vaddr:=p_vaddr + QWORD(imgp^.reloc_base);
end;
p_memsz:=p_vaddr and QWORD($ffffffffffffc000);
p_vaddr:=(phdr^.p_memsz + p_vaddr - p_memsz + $3fff) and QWORD($ffffffffffffc000);
max_size1:=max_size1+p_vaddr;
used_mode_2m:=is_used_mode_2mb(phdr,0,p_proc.p_budget_ptype);
if (used_mode_2m) then
begin
size :=(p_vaddr + p_memsz) and QWORD($ffffffffffe00000);
p_vaddr:=(p_memsz + $1fffff) and QWORD($ffffffffffe00000);
base:=0;
if (p_vaddr<=size) then
begin
base:=size-p_vaddr;
end;
max_size2:=max_size2+base;
end;
end;
Inc(phdr);
end;
end;
end;
function self_load_shared_object(path:pchar;new:p_lib_info;wire:Integer):Integer;
label
_fail_dealloc;
@ -1932,6 +2006,11 @@ var
phdr:p_elf64_phdr;
addr,delta:QWORD;
max_size1:QWORD;
max_size2:QWORD;
used :QWORD;
limit :QWORD;
begin
Result:=-1;
if (path=nil) then Exit;
@ -2075,6 +2154,27 @@ begin
addr:=ET_DYN_LOAD_ADDR_SYS;
end;
if ((g_mode_2mb and DWORD($fffffffe))=2) then //M2MB_READONLY,M2MB_ENABLE
begin
max_size1:=0;
max_size2:=0;
scan_max_size(imgp,phdr,hdr^.e_phnum,max_size1,max_size2);
if (max_size2 > g_mode_2mb_rsrv) then
begin
max_size2:=g_mode_2mb_rsrv;
end;
used :=vm_budget_used (PTYPE_BIG_APP,field_mlock);
limit:=vm_budget_limit(PTYPE_BIG_APP,field_mlock);
if ((used + (max_size1 - max_size2)) > limit) then
begin
error:=ENOMEM;
goto _fail_dealloc;
end;
end;
error:=rtld_mmap(@addr,imgp^.max_addr-imgp^.min_addr);
if (error<>0) then
begin
@ -2097,7 +2197,7 @@ begin
1,
0);
error:=dynlib_load_sections(imgp,new,phdr,hdr^.e_phnum,delta);
error:=dynlib_load_sections(imgp,new,phdr,hdr^.e_phnum,delta,wire);
if (error<>0) then
begin
goto _fail_dealloc;

View File

@ -146,7 +146,7 @@ function setcontext(ucp:Pointer):Integer;
function swapcontext(oucp,ucp:Pointer):Integer;
Function sigwait(oset:Pointer;sig:PInteger):Integer;
function thr_create(ctx:Pointer;id:PDWORD;flags:Integer):Integer;
procedure thr_exit(state:PQWORD);
procedure thr_exit(state:PDWORD);
function thr_self(id:PDWORD):Integer;
function thr_kill(id,sig:Integer):Integer;
function _umtx_lock(mtx:Pointer):Integer;
@ -243,6 +243,7 @@ function set_timezone_info(data_ptr:Pointer;data_count_dw:Integer):Integer;
function utc_to_localtime(time:QWORD;local_time,tsec:Pointer;dstsec:PInteger):Integer;
function localtime_to_utc(time:QWORD;tz_type:Integer;utc_time,tsec:Pointer;dstsec:PInteger):Integer;
function set_chicken_switches(flags:Integer):Integer;
function app_state_change(state:Integer):Integer;
function dynlib_get_obj_member(handle:Integer;num:Byte;pout:PPointer):Integer;
function budget_get_ptype_of_budget(key:Integer):Integer;
function blockpool_open(flags:Integer):Integer;
@ -1233,7 +1234,7 @@ asm
jmp cerror
end;
procedure thr_exit(state:PQWORD); assembler; nostackframe;
procedure thr_exit(state:PDWORD); assembler; nostackframe;
asm
movq $431,%rax
call fast_syscall
@ -1912,6 +1913,13 @@ asm
jmp cerror
end;
function app_state_change(state:Integer):Integer; assembler; nostackframe;
asm
movq $648,%rax
call fast_syscall
jmp cerror
end;
function dynlib_get_obj_member(handle:Integer;num:Byte;pout:PPointer):Integer; assembler; nostackframe;
asm
movq $649,%rax