mirror of https://github.com/red-prig/fpPS4.git
1641 lines
30 KiB
Plaintext
1641 lines
30 KiB
Plaintext
|
|
{
|
|
{$MAXSTACKSIZE $7FBE0000}
|
|
}
|
|
|
|
uses
|
|
windows,
|
|
dateutils,
|
|
atomic,
|
|
ntapi,
|
|
mqueue,
|
|
syscalls,
|
|
signal,
|
|
ucontext,
|
|
_umtx,
|
|
sys_umtx,
|
|
time,
|
|
kern_time,
|
|
md_time,
|
|
thr,
|
|
kern_thread,
|
|
md_thread,
|
|
kern_rwlock,
|
|
thr_private,
|
|
sys_cpuset,
|
|
trap,
|
|
kern_psl,
|
|
kern_umtx,
|
|
thr_init,
|
|
thr_error,
|
|
pthread_md,
|
|
sysutils,
|
|
errno,
|
|
md_context,
|
|
subr_sleepqueue,
|
|
kern_thr,
|
|
kern_condvar,
|
|
kern_osem,
|
|
kern_id,
|
|
kern_evf,
|
|
rtprio,
|
|
pthread,
|
|
thr_stack,
|
|
sys_mmap,
|
|
kern_synch,
|
|
murmurhash,
|
|
hamt,
|
|
vfs_subr,
|
|
vfs_mount,
|
|
vfs_default,
|
|
init_sysent,
|
|
vfs_syscalls,
|
|
vsys_generic,
|
|
vsocket,
|
|
vsocketvar,
|
|
vnode_if,
|
|
sys_sysinit,
|
|
sys_fnmatch,
|
|
dead_vnops,
|
|
devfs,
|
|
devfs_devs,
|
|
devfs_rule,
|
|
devfs_vfsops,
|
|
devfs_vnops,
|
|
vfs_mountroot,
|
|
vstat,
|
|
vfcntl,
|
|
vdirent,
|
|
fdesc_vfsops,
|
|
fdesc_vnops,
|
|
fdescfs,
|
|
kern_descrip,
|
|
vnode,
|
|
nullfs,
|
|
null_subr,
|
|
null_vnops,
|
|
null_vfsops,
|
|
ufs,
|
|
vmount,
|
|
kern_prot,
|
|
sys_resource,
|
|
kern_resource,
|
|
md_proc,
|
|
kern_ksched,
|
|
kern_uuid,
|
|
kern_gpo,
|
|
md_sleep,
|
|
sys_machdep,
|
|
kern_context,
|
|
kern_namedobj,
|
|
sys_event,
|
|
sys_eventvar,
|
|
kern_event,
|
|
kern_timeout,
|
|
kern_exec,
|
|
kern_dynlib,
|
|
vmparam,
|
|
kern_sysctl,
|
|
kern_budget,
|
|
kern_regmgr,
|
|
kern_authinfo,
|
|
kern_dmem,
|
|
kern_blockpool,
|
|
kern_bnet,
|
|
uipc_syscalls,
|
|
kern_ipmimgr,
|
|
kern_mdbg,
|
|
md_exception,
|
|
systm,
|
|
dev_tty,
|
|
sys_crt,
|
|
ps4_libSceSystemService,
|
|
ps4_libSceIpmi,
|
|
ps4_libSceDialogs,
|
|
ps4_libSceAvSetting;
|
|
|
|
var
|
|
mtx:umutex;
|
|
rwl:urwlock;
|
|
e:Integer;
|
|
|
|
event:Thandle;
|
|
|
|
//osem:Integer;
|
|
evf:Integer;
|
|
|
|
procedure trap_test;
|
|
var
|
|
td:p_kthread;
|
|
begin
|
|
td:=curkthread;
|
|
|
|
Writeln('trap_test: ',' curkthread:',HexStr(curkthread),' sptr:',HexStr(sptr),' ',HexStr(td^.td_frame.tf_rip,16));
|
|
end;
|
|
|
|
function _thread(parameter:pointer):ptrint;
|
|
var
|
|
td:p_kthread;
|
|
p:Pointer;
|
|
qr:t_query_memory_prot;
|
|
begin
|
|
Result:=0;
|
|
NtWaitForSingleObject(event,false,nil);
|
|
|
|
td:=thread_alloc;
|
|
|
|
td^.td_tid :=GetCurrentThreadId;
|
|
td^.td_handle:=GetCurrentThread;
|
|
td^.td_ref :=1;
|
|
|
|
//sched_priority(@td,700);
|
|
|
|
BaseQueryInfo(td);
|
|
|
|
set_curkthread(td);
|
|
|
|
|
|
p:=mmap(Pointer($700000000),16*1024,PROT_CPU_ALL,MAP_VOID or MAP_FIXED,-1,0);
|
|
Writeln(HexStr(p));
|
|
|
|
p:=mmap(Pointer($700000000),16*1024,PROT_CPU_ALL,MAP_ANON or MAP_FIXED,-1,0);
|
|
Writeln(HexStr(p));
|
|
|
|
Result:=query_memory_protection(Pointer($700000000),@qr);
|
|
Writeln(Result);
|
|
|
|
sceKernelSetVirtualRangeName(Pointer($700000000),16*1024,'test');
|
|
|
|
p:=mmap(Pointer($700000000+16*1024),16*1024,PROT_CPU_ALL,MAP_ANON {or MAP_VOID} or MAP_FIXED,-1,0);
|
|
Writeln(HexStr(p));
|
|
|
|
Result:=madvise(Pointer($00700000000),4*1024,MADV_FREE);
|
|
Writeln(Result);
|
|
|
|
Result:=madvise(Pointer($00700000000),4*1024,MADV_WILLNEED);
|
|
Writeln(Result);
|
|
|
|
Result:=munmap(Pointer($700000000),16*1024*2);
|
|
Writeln(Result);
|
|
|
|
e:=_umtx_op(nil,UMTX_OP_RW_WRLOCK,0,nil,nil);
|
|
Writeln(' e=',e);
|
|
|
|
repeat
|
|
|
|
//Writeln('before: sptr:',HexStr(sptr));
|
|
//asm
|
|
// Movq trap_test,%rax
|
|
// call fast_syscall
|
|
//end;
|
|
//Writeln('after: sptr:',HexStr(sptr));
|
|
|
|
//e:=_umtx_op(@mtx,{UMTX_OP_MUTEX_LOCK} UMTX_OP_LOCK,td.td_tid,nil,nil);
|
|
//e:=_umtx_op(@mtx,UMTX_OP_MUTEX_LOCK,td^.td_tid,nil,nil);
|
|
e:=_umtx_op(@rwl,UMTX_OP_RW_WRLOCK,0,nil,nil);
|
|
Writeln(' lock[',GetCurrentThreadId,'] ',e);
|
|
|
|
//e:=_do_lock_normal(GetCurrentThreadId,@mtx,0,NT_INFINITE,0);
|
|
//Writeln(' lock[',GetCurrentThreadId,'] ',e);
|
|
|
|
//sleep(100);
|
|
|
|
//Writeln('before: sptr:',HexStr(sptr));
|
|
|
|
//e:=_umtx_op(@mtx,{UMTX_OP_MUTEX_UNLOCK} UMTX_OP_UNLOCK,td.td_tid,nil,nil);
|
|
//e:=_umtx_op(@mtx,UMTX_OP_MUTEX_UNLOCK,td^.td_tid,nil,nil);
|
|
e:=_umtx_op(@rwl,UMTX_OP_RW_UNLOCK,0,nil,nil);
|
|
Writeln('unlock[',GetCurrentThreadId,'] ',e);
|
|
|
|
//Writeln('after: sptr:',HexStr(sptr));
|
|
|
|
//sleep(1000)
|
|
|
|
//_umtx_obj_done(@mtx);
|
|
|
|
until false;
|
|
end;
|
|
|
|
var
|
|
mem,mem2:Pointer;
|
|
mseg:Pointer;
|
|
|
|
lock:Integer;
|
|
|
|
procedure _writefsbase_u64(base:Pointer);
|
|
begin
|
|
asm
|
|
Mov base,%rax
|
|
|
|
//f3 48 0f ae d0 WRFSBASE RAX
|
|
.byte 0xF3
|
|
.byte 0x48
|
|
.byte 0x0F
|
|
.byte 0xAE
|
|
.byte 0xD0
|
|
end;
|
|
end;
|
|
|
|
function _readfsbase_u64:Pointer;
|
|
begin
|
|
asm
|
|
push %rsi
|
|
|
|
//f3 48 0f ae c6 RDFSBASE RSI
|
|
.byte 0xF3
|
|
.byte 0x48
|
|
.byte 0x0F
|
|
.byte 0xAE
|
|
.byte 0xC6
|
|
|
|
Mov %rsi,Result
|
|
|
|
pop %rsi
|
|
end;
|
|
end;
|
|
|
|
procedure SetTlsBase(p:Pointer); assembler; nostackframe;
|
|
asm
|
|
mov %rcx,%gs:(0x708)
|
|
end;
|
|
|
|
function GetTlsBase:Pointer; assembler; nostackframe;
|
|
asm
|
|
mov %gs:(0x708),%rax
|
|
end;
|
|
|
|
function Get_SEH:Pointer; assembler; nostackframe;
|
|
asm
|
|
mov %gs:(0),%rax
|
|
end;
|
|
|
|
threadvar
|
|
intr:Integer;
|
|
|
|
procedure __ex_handler(sig,code:Integer;ctx:p_ucontext_t); SysV_ABI_CDecl;
|
|
begin
|
|
intr:=1;
|
|
Writeln('__ex_handler:',sig,' ',code);
|
|
end;
|
|
|
|
var
|
|
tid,tid2:QWORD;
|
|
|
|
var
|
|
xmm0:array[0..15] of Byte=(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
|
|
xmm0_ptr:Pointer=@xmm0;
|
|
|
|
ymm0:array[0..31] of Byte=(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
|
|
ymm0_ptr:Pointer=@ymm0;
|
|
|
|
function ts_to_str(ts:timespec):RawByteString;
|
|
var
|
|
D:TDateTime;
|
|
begin
|
|
D:=UnixToDateTime(ts.tv_sec);
|
|
D:=UniversalTimeToLocal(D);
|
|
Result:=DateTimeToStr(D);
|
|
end;
|
|
|
|
function IncludeUnixTrailing(Const Path:RawByteString):RawByteString;
|
|
Var
|
|
L:Integer;
|
|
begin
|
|
Result:=Path;
|
|
L:=Length(Result);
|
|
If (L=0) or (Path[L]<>'/') then
|
|
begin
|
|
SetLength(Result,L+1);
|
|
Result[L+1]:='/';
|
|
end;
|
|
end;
|
|
|
|
procedure test_files;
|
|
var
|
|
td:p_kthread;
|
|
fs:t_statfs;
|
|
fd_1,fd_2:Integer;
|
|
i,err:Integer;
|
|
|
|
buf:PChar;
|
|
|
|
argv0:PChar;
|
|
begin
|
|
td:=curkthread;
|
|
|
|
{
|
|
Writeln('sys_open=',sys_open('/app0/test.txt',O_RDWR or O_CREAT or O_TRUNC{ or O_APPEND} or O_EXLOCK,&777));
|
|
fd_1:=td^.td_retval[0];
|
|
|
|
buf:=AllocMem(64*1024);
|
|
|
|
FillChar(buf^,64*1024,'0');
|
|
|
|
Writeln('sys_pwrite=',sys_pwrite(fd_1,buf,64*1024,0));
|
|
|
|
FillChar(buf^,64*1024,'1');
|
|
|
|
Writeln('sys_pwrite=',sys_pwrite(fd_1,buf,64*1024,0));
|
|
|
|
FillChar(buf^,64*1024,0);
|
|
|
|
Writeln('sys_pread=',sys_pread(fd_1,buf,64*1024,0));
|
|
|
|
FreeMem(buf);
|
|
|
|
//Writeln('sys_fstatfs=',sys_fstatfs(fd_1,@fs));
|
|
|
|
Writeln('sys_fsync=',sys_fsync(fd_1));
|
|
Writeln('sys_fdatasync=',sys_fdatasync(fd_1));
|
|
|
|
Writeln('sys_open=',sys_open('/app0/test.txt',O_RDWR{ or O_CREAT},&777));
|
|
fd_2:=td^.td_retval[0];
|
|
|
|
Writeln('sys_close=',sys_close(fd_2));
|
|
Writeln('sys_close=',sys_close(fd_1));
|
|
|
|
Writeln('sys_mkdir=',sys_mkdir('/test',&777));
|
|
Writeln('sys_mkdir=',sys_mkdir('/test/test',&777));
|
|
Writeln('sys_rmdir=',sys_rmdir('/test/test'));
|
|
Writeln('sys_symlink=',sys_symlink('/app0','/test/test2'));
|
|
Writeln('sys_unlink=',sys_unlink('/test/test2'));
|
|
|
|
Writeln('sys_mkdir=',sys_mkdir('/app0/new',&777));
|
|
Writeln('sys_link=',sys_link('/app0/test.txt','/app0/new/test_link.txt'));
|
|
Writeln('sys_rename=',sys_rename('/app0/new/test_link.txt','/app0/renamed'));
|
|
Writeln('sys_unlink=',sys_unlink('/app0/renamed'));
|
|
|
|
Writeln('sys_rename=',sys_rename('/app0/new','/app0/renamed'));
|
|
Writeln('sys_rmdir=',sys_rmdir('/app0/renamed'));
|
|
|
|
Writeln('sys_unlink=',sys_unlink('/app0/test.txt'));
|
|
|
|
Writeln('sys_rmdir=',sys_rmdir('/test'));
|
|
}
|
|
|
|
//readln;
|
|
|
|
//fs guest host
|
|
err:=vfs_mount_mkdir('ufs','/app0' ,'/' ,nil,0);
|
|
err:=vfs_mount_mkdir('ufs','/system','/system',nil,0);
|
|
err:=vfs_mount_mkdir('ufs','/data' ,'/data' ,nil,0);
|
|
|
|
//argv0:='/app0/basic-sample_debug.elf';
|
|
//argv0:='/app0/simple.elf';
|
|
//argv0:='/app0/videoout_basic.elf';
|
|
argv0:='/app0/videoout_basic.bin';
|
|
//argv0:='/app0/videoout_cursor.elf';
|
|
|
|
//argv0:='/app0/scene2.bin';
|
|
//argv0:='/app0/basic_quad_debug.elf';
|
|
|
|
//argv0:='/app0/hello_world9.bin';
|
|
|
|
err:=_execve(argv0,@argv0,nil);
|
|
end;
|
|
|
|
procedure test_dirs(const dirp,namep:RawByteString;s:Byte);
|
|
label
|
|
_next;
|
|
var
|
|
td:p_kthread;
|
|
|
|
sb:t_stat;
|
|
buf:array[0..511] of Byte;
|
|
dir:p_dirent;
|
|
fd:Integer;
|
|
err:Integer;
|
|
c:Integer;
|
|
begin
|
|
td:=curkthread;
|
|
|
|
case RawByteString(namep) of
|
|
'.',
|
|
'..':
|
|
begin
|
|
Writeln(Space(s),namep:20,' |');
|
|
Exit;
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
err:=sys_lstat(PChar(dirp+namep),@sb);
|
|
//err:=sys_stat(PChar(dirp+namep),@sb);
|
|
|
|
if (err<>0) then
|
|
begin
|
|
Writeln(Space(s),namep:20,' | (',err,')');
|
|
end else
|
|
begin
|
|
Write(Space(s),namep:20,' | ',ts_to_str(sb.st_birthtim {st_mtim}):19,' |');
|
|
_next:
|
|
|
|
if ((sb.st_mode and S_IFDIR)<>0) then
|
|
begin
|
|
Write(' DIR');
|
|
Assert(sb.st_size=512);
|
|
|
|
err:=sys_open(PChar(dirp+namep),O_RDONLY or O_DIRECTORY,0);
|
|
|
|
if (err<>0) then
|
|
begin
|
|
Write(' | (',err,')');
|
|
Exit;
|
|
end else
|
|
begin
|
|
Writeln;
|
|
end;
|
|
|
|
fd:=td^.td_retval[0];
|
|
|
|
Writeln(Space(s),'->');
|
|
|
|
repeat
|
|
FillChar(buf,512,0);
|
|
dir:=@buf;
|
|
err:=sys_getdents(fd,dir,512);
|
|
if (err<0) then Break;
|
|
|
|
c:=td^.td_retval[0];
|
|
if (c=0) then Break;
|
|
|
|
while (dir<(@buf+c)) do
|
|
begin
|
|
test_dirs(IncludeUnixTrailing(dirp+namep),RawByteString(dir^.d_name),s+2);
|
|
|
|
PByte(dir):=PByte(dir)+dir^.d_reclen;
|
|
end;
|
|
|
|
until false;
|
|
|
|
sys_close(fd);
|
|
|
|
Writeln(Space(s),'<-');
|
|
end else
|
|
begin
|
|
Case (sb.st_mode and S_IFMT) of
|
|
S_IFIFO :Write(' IFO');
|
|
S_IFCHR :Write(' CHR');
|
|
S_IFDIR :Write(' DIR');
|
|
S_IFBLK :Write(' BLK');
|
|
S_IFREG :Write(' REG');
|
|
S_IFLNK :Write(' LNK');
|
|
S_IFSOCK:Write(' SCK');
|
|
else
|
|
Write(' ',(sb.st_mode and S_IFMT));
|
|
end;
|
|
|
|
Writeln(' | ',sb.st_size);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure _timerexpire(arg:Pointer); sysv_abi_default;
|
|
var
|
|
calloutp:p_callout;
|
|
begin
|
|
calloutp:=arg;
|
|
|
|
writeln('_timerexpire');
|
|
|
|
callout_reset_curcpu(calloutp, 1000*1000*UNIT_PER_USEC-1, @_timerexpire, calloutp);
|
|
//callout_drain(calloutp);
|
|
end;
|
|
|
|
|
|
{
|
|
Type
|
|
TBacktraceStrFunc = Function (Addr: CodePointer): ShortString;
|
|
TErrorProc = Procedure (ErrNo : Longint; Address : CodePointer; Frame : Pointer);
|
|
TAbstractErrorProc = Procedure;
|
|
TAssertErrorProc = Procedure(const msg,fname:ShortString;lineno:longint;erroraddr:pointer);
|
|
TSafeCallErrorProc = Procedure(error : HResult;addr : pointer);
|
|
|
|
|
|
const
|
|
BacktraceStrFunc : TBacktraceStrFunc = @SysBacktraceStr;
|
|
ErrorProc : TErrorProc = nil;
|
|
AbstractErrorProc : TAbstractErrorProc = nil;
|
|
AssertErrorProc : TAssertErrorProc = @SysAssert;
|
|
SafeCallErrorProc : TSafeCallErrorProc = nil;
|
|
}
|
|
|
|
procedure test_thread; sysv_abi_default;
|
|
var
|
|
rax:qword;
|
|
act:sigaction_t;
|
|
_sig:Integer;
|
|
oset:sigset_t;
|
|
i,t:Integer;
|
|
|
|
uctx:ucontext_t;
|
|
|
|
calloutp:p_callout;
|
|
begin
|
|
writeln('Get_SEH:0x',HexStr(Get_SEH));
|
|
|
|
//writeln('copyin:',copyin(mem2+64*1024*4-(sizeof(ucontext_t) div 2),@uctx,sizeof(ucontext_t)));
|
|
|
|
//PPointer(nil)^:=nil;
|
|
|
|
//Assert(false,'test assert');
|
|
|
|
//if (tid<>curkthread^.td_tid) then
|
|
//begin
|
|
// calloutp:=AllocMem(SizeOf(t_callout));
|
|
// callout_init(calloutp, CALLOUT_MPSAFE);
|
|
// callout_reset_curcpu(calloutp, 1000*1000*UNIT_PER_USEC, @_timerexpire, calloutp);
|
|
//end;
|
|
|
|
//SetTlsBase(Pointer(qword(1)));
|
|
|
|
if (tid<>curkthread^.td_tid) then
|
|
begin
|
|
test_files;
|
|
Writeln('[--test_dirs--]');
|
|
test_dirs('','/',1);
|
|
Writeln('[--test_dirs--]');
|
|
|
|
//readln;
|
|
|
|
tid2:=curkthread^.td_tid;
|
|
|
|
evf:=evf_create('evf test',EVF_ATTR_TH_PRIO,0);
|
|
Writeln('evf=',evf,' _errno:',__error^);
|
|
|
|
//osem:=osem_create('osem test',1,1,10);
|
|
//Writeln('osem=',osem,' _errno:',__error^);
|
|
|
|
act:=Default(sigaction_t);
|
|
act.u.sa_handler:=sa_handler(@__ex_handler);
|
|
act.sa_flags:=SA_RESTART;
|
|
|
|
_sigaction(SIGUSR1,@act,nil);
|
|
|
|
|
|
i:=syscalls.thr_suspend_ucontext(tid);
|
|
Writeln('thr_suspend_ucontext:',i);
|
|
|
|
i:=syscalls.thr_get_ucontext(tid,@uctx);
|
|
Writeln('thr_get_ucontext:',i);
|
|
|
|
i:=syscalls.thr_resume_ucontext(tid);
|
|
Writeln('thr_resume_ucontext:',i);
|
|
|
|
thr_kill(tid,SIGUSR1);
|
|
//thr_wake(tid);
|
|
|
|
thr_kill(tid,SIGUSR1);
|
|
|
|
i:=evf_trywait(evf,1,EVF_WAITMODE_OR,nil);
|
|
Writeln('_evf_trywait_err=',i,' _errno:',__error^);
|
|
|
|
i:=evf_wait(evf,2,EVF_WAITMODE_OR,nil,nil);
|
|
Writeln('_evf_wait_err=',i,' _errno:',__error^);
|
|
|
|
//i:=_osem_wait_err(osem,1,nil);
|
|
//Writeln('_osem_wait_err=',i,' _errno:',__error^);
|
|
//
|
|
//t:=400;
|
|
//i:=_osem_wait_err(osem,1,nil);
|
|
//Writeln('_osem_wait_err=',i,' _errno:',__error^);
|
|
//
|
|
//i:=_osem_delete_err(osem);
|
|
//Writeln('_osem_delete_err=',i,' _errno:',__error^);
|
|
|
|
writeln;
|
|
end else
|
|
begin
|
|
//Writeln('thr_suspend:',thr_suspend(nil));
|
|
|
|
{
|
|
oset.qwords[0]:=QWORD(-1);
|
|
oset.qwords[1]:=QWORD(-1);
|
|
Writeln('sigwait:',sigwait(@oset,@_sig));
|
|
Writeln('intr:',_sig);
|
|
}
|
|
|
|
Writeln('before: sptr:',HexStr(sptr));
|
|
|
|
asm
|
|
movqq xmm0_ptr,%rax
|
|
movdqu (%rax),%xmm0
|
|
|
|
movqq ymm0_ptr,%rax
|
|
vmovdqu (%rax),%ymm0
|
|
end;
|
|
|
|
syscalls.getcontext(@uctx);
|
|
|
|
oset.qwords[0]:=QWORD(-1);
|
|
oset.qwords[1]:=QWORD(-1);
|
|
Writeln('sigwait:',sigwait(@oset,@_sig));
|
|
Writeln('_errno:',__error^);
|
|
|
|
//repeat
|
|
// asm
|
|
// pause
|
|
// end;
|
|
//until (intr<>0);
|
|
|
|
asm
|
|
movqq xmm0_ptr,%rax
|
|
movdqu %xmm0,(%rax)
|
|
|
|
movqq ymm0_ptr,%rax
|
|
vmovdqu %ymm0,(%rax)
|
|
end;
|
|
|
|
Writeln('intr');
|
|
Writeln('after: sptr:',HexStr(sptr));
|
|
end;
|
|
|
|
sleep(500);
|
|
//_osem_post_err(osem,1);
|
|
thr_kill(tid2,SIGUSR1);
|
|
|
|
i:=evf_set(evf,2);
|
|
|
|
i:=evf_set(evf,1);
|
|
Writeln('_evf_set_err=',i,' _errno:',__error^);
|
|
|
|
//_osem_post_err(osem,1);
|
|
|
|
sig_lock;
|
|
sig_lock;
|
|
sleep(1);
|
|
sig_unlock;
|
|
sig_unlock;
|
|
|
|
{
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x1C0),%rax
|
|
end;
|
|
Writeln('SpareBytes1[0]:',HexStr(rax,16));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x1C8),%rax
|
|
end;
|
|
Writeln('SpareBytes1[1]:',HexStr(rax,16));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x1D0),%rax
|
|
end;
|
|
Writeln('SpareBytes1[2]:',HexStr(rax,16));
|
|
|
|
Writeln('GetTlsBase:',HexStr(GetTlsBase));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x10),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('FiberData:',HexStr(rax,16));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x14),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('ArbitraryData:',HexStr(rax,16));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0xC0),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('Wow64:',HexStr(rax,16));
|
|
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x1A8),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('ActivationContextStack:',HexStr(rax,16));
|
|
|
|
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x700),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('UserData[0]:',HexStr(rax,16));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x708),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('UserData[1]:',HexStr(rax,16));
|
|
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0x710),%eax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('UserData[2]:',HexStr(rax,8));
|
|
|
|
rax:=0;
|
|
asm
|
|
mov %gs:(0xE0C),%rax
|
|
mov %rax,rax
|
|
end;
|
|
Writeln('DeallocationStack:',HexStr(rax,16));
|
|
|
|
Writeln('mseg:',HexStr(mseg));
|
|
|
|
FillChar(mseg^,64*1024,$11);
|
|
|
|
PQWORD(mseg)^:=$0102030405060708;
|
|
|
|
Writeln('_readfsbase_u64:',HexStr(_readfsbase_u64));
|
|
|
|
_writefsbase_u64(mseg);
|
|
|
|
//Writeln('_readfsbase_u64:',HexStr(_readfsbase_u64));
|
|
|
|
//rax:=qword(mseg);
|
|
|
|
asm
|
|
// Mov rax,%rax
|
|
//
|
|
// .byte 0xF3
|
|
// .byte 0x48
|
|
// .byte 0x0F
|
|
// .byte 0xAE
|
|
// .byte 0xD0
|
|
//
|
|
// //F3 0F AE
|
|
//
|
|
//f3 48 0f ae d0 WRFSBASE RAX
|
|
//
|
|
// movq %fs:(0),%rax
|
|
|
|
//f3 48 0f ae d0 WRFSBASE RAX
|
|
|
|
end;
|
|
|
|
//sleep(1);
|
|
|
|
//Writeln('_readfsbase_u64:',HexStr(_readfsbase_u64));
|
|
|
|
//While (XCHG(lock,1)<>0) do spin_pause;
|
|
|
|
rax:=0;
|
|
|
|
asm
|
|
movq %fs:(0),%rax
|
|
|
|
Mov %rax,rax
|
|
end;
|
|
|
|
writeln(HexStr(rax,16));
|
|
writeln;
|
|
}
|
|
|
|
thr_exit(nil);
|
|
end;
|
|
|
|
function _VirtualQuery(addr:Pointer):Integer;
|
|
var
|
|
Info:TMemoryBasicInformation;
|
|
begin
|
|
Writeln('-----');
|
|
|
|
|
|
Info:=Default(TMemoryBasicInformation);
|
|
|
|
Result:=NtQueryVirtualMemory(
|
|
NtCurrentProcess,
|
|
@addr,
|
|
MemoryBasicInformation,
|
|
@Info,
|
|
SizeOf(TMemoryBasicInformation),
|
|
nil);
|
|
|
|
//Result:=VirtualQuery(addr,Info,SizeOf(TMemoryBasicInformation));
|
|
|
|
//if (Result=0) then
|
|
//begin
|
|
// Result:=GetLastError;
|
|
//end else
|
|
|
|
if (Result=0) then
|
|
begin
|
|
//Result:=0;
|
|
|
|
Writeln('Q:BaseAddress :',HexStr(Info.BaseAddress));
|
|
Writeln('Q:AllocationBase:',HexStr(Info.AllocationBase));
|
|
|
|
//AllocationProtect : DWORD;
|
|
|
|
Writeln('Q:RegionSize :',HexStr(Info.RegionSize,16));
|
|
|
|
Write ('Q:State :');
|
|
|
|
Case Info.State of
|
|
MEM_COMMIT :Writeln('MEM_COMMIT ');
|
|
MEM_RESERVE:Writeln('MEM_RESERVE');
|
|
MEM_FREE :Writeln('MEM_FREE ');
|
|
end;
|
|
|
|
Write ('Q:Protect :');
|
|
|
|
Case Info.Protect of
|
|
0 :Writeln('0');
|
|
PAGE_NOACCESS :Writeln('PAGE_NOACCESS ');
|
|
PAGE_READONLY :Writeln('PAGE_READONLY ');
|
|
PAGE_READWRITE :Writeln('PAGE_READWRITE ');
|
|
PAGE_EXECUTE :Writeln('PAGE_EXECUTE ');
|
|
PAGE_EXECUTE_READ :Writeln('PAGE_EXECUTE_READ ');
|
|
PAGE_EXECUTE_READWRITE:Writeln('PAGE_EXECUTE_READWRITE');
|
|
else;
|
|
end;
|
|
|
|
Write ('Q:Type :');
|
|
|
|
Case Info._Type of
|
|
0 :Writeln('0');
|
|
MEM_PRIVATE:Writeln('MEM_PRIVATE');
|
|
MEM_MAPPED :Writeln('MEM_MAPPED ');
|
|
MEM_IMAGE :Writeln('MEM_IMAGE ');
|
|
end;
|
|
|
|
end;
|
|
|
|
Writeln('-----');
|
|
end;
|
|
|
|
procedure test_map2;
|
|
var
|
|
hSection:THandle;
|
|
place_base:Pointer;
|
|
base:Pointer;
|
|
size:ULONG_PTR;
|
|
SectionOffset:ULONG_PTR;
|
|
R:DWORD;
|
|
old:Integer;
|
|
begin
|
|
exit;
|
|
|
|
place_base:=nil;
|
|
size:=4*1024*1024;
|
|
|
|
R:=NtAllocateVirtualMemoryEx(
|
|
NtCurrentProcess,
|
|
@place_base,
|
|
@size,
|
|
MEM_RESERVE or MEM_RESERVE_PLACEHOLDER,
|
|
PAGE_NOACCESS,
|
|
nil,
|
|
0
|
|
);
|
|
|
|
Writeln('NtAllocateVirtualMemoryEx:',HexStr(R,8));
|
|
|
|
Writeln('place_base:',HexStr(place_base));
|
|
|
|
base:=place_base;
|
|
size:=4*1024;
|
|
|
|
//split region
|
|
R:=NtFreeVirtualMemory(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
MEM_RELEASE or MEM_PRESERVE_PLACEHOLDER
|
|
);
|
|
|
|
Writeln('NtFreeVirtualMemory:',HexStr(R,8));
|
|
|
|
size:=1*1024*1024*1024; //create page file
|
|
|
|
hSection:=0;
|
|
R:=NtCreateSection(
|
|
@hSection,
|
|
SECTION_MAP_WRITE or SECTION_MAP_READ{ or SECTION_MAP_EXECUTE},
|
|
nil,
|
|
@size,
|
|
PAGE_READWRITE,
|
|
SEC_COMMIT,
|
|
THandle(0)
|
|
);
|
|
|
|
Writeln('NtCreateSection:',HexStr(R,8));
|
|
|
|
{
|
|
HANDLE CreateFileMappingA(
|
|
[in] HANDLE hFile,
|
|
[in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
|
[in] DWORD flProtect,
|
|
[in] DWORD dwMaximumSizeHigh,
|
|
[in] DWORD dwMaximumSizeLow,
|
|
[in, optional] LPCSTR lpName
|
|
);
|
|
}
|
|
|
|
base:=place_base;
|
|
SectionOffset:=4*1024;
|
|
size:=4*1024;
|
|
|
|
R:=NtMapViewOfSectionEx(
|
|
hSection,
|
|
NtCurrentProcess,
|
|
@base,
|
|
@SectionOffset,
|
|
@size,
|
|
MEM_REPLACE_PLACEHOLDER,
|
|
PAGE_READWRITE,
|
|
nil,
|
|
0
|
|
);
|
|
|
|
Writeln('NtMapViewOfSectionEx:',HexStr(R,8));
|
|
|
|
old:=0;
|
|
R:=NtProtectVirtualMemory(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
PAGE_READONLY,
|
|
@old
|
|
);
|
|
|
|
Writeln('NtProtectVirtualMemory:',HexStr(R,8));
|
|
|
|
old:=0;
|
|
R:=NtProtectVirtualMemory(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
PAGE_READWRITE,
|
|
@old
|
|
);
|
|
|
|
Writeln('NtProtectVirtualMemory:',HexStr(R,8));
|
|
|
|
//private
|
|
|
|
base:=place_base+4*1024;
|
|
size:=4*1024;
|
|
|
|
//split region
|
|
R:=NtFreeVirtualMemory(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
MEM_RELEASE or MEM_PRESERVE_PLACEHOLDER
|
|
);
|
|
|
|
Writeln('NtFreeVirtualMemory:',HexStr(R,8));
|
|
|
|
base:=place_base+4*1024;
|
|
SectionOffset:=4*1024;
|
|
size:=4*1024;
|
|
|
|
R:=NtMapViewOfSectionEx(
|
|
hSection,
|
|
NtCurrentProcess,
|
|
@base,
|
|
@SectionOffset,
|
|
@size,
|
|
MEM_REPLACE_PLACEHOLDER,
|
|
PAGE_READWRITE,
|
|
nil,
|
|
0
|
|
);
|
|
|
|
Writeln('NtMapViewOfSectionEx:',HexStr(R,8));
|
|
|
|
{
|
|
base:=place_base+4*1024;
|
|
size:=4*1024;
|
|
|
|
R:=NtAllocateVirtualMemoryEx(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
MEM_RESERVE or MEM_COMMIT,
|
|
PAGE_READWRITE,
|
|
nil,
|
|
0
|
|
);
|
|
|
|
Writeln('NtAllocateVirtualMemoryEx:',HexStr(R,8));
|
|
}
|
|
|
|
PByte(place_base)^:=$FF;
|
|
|
|
Writeln(PByte(base)^);
|
|
|
|
base:=place_base+4*1024;
|
|
|
|
R:=NtUnmapViewOfSectionEx(
|
|
NtCurrentProcess,
|
|
base,
|
|
MEM_PRESERVE_PLACEHOLDER
|
|
);
|
|
|
|
Writeln('NtUnmapViewOfSectionEx:',HexStr(R,8));
|
|
|
|
base:=place_base+4*1024;
|
|
size:=4*1024*1024-4*1024;
|
|
|
|
//union region
|
|
R:=NtFreeVirtualMemory(
|
|
NtCurrentProcess,
|
|
@base,
|
|
@size,
|
|
MEM_RELEASE or MEM_COALESCE_PLACEHOLDERS
|
|
);
|
|
|
|
Writeln('NtFreeVirtualMemory:',HexStr(R,8));
|
|
|
|
readln;
|
|
end;
|
|
|
|
procedure test_map;
|
|
var
|
|
F:THandle;
|
|
n:Integer;
|
|
SectionSize:LARGE_INTEGER;
|
|
start:ULONG_PTR;
|
|
CommitSize:ULONG_PTR;
|
|
ViewSize:ULONG_PTR;
|
|
hSection:THandle;
|
|
Base1,Base2:Pointer;
|
|
//dev:TVkDeviceMemory;
|
|
begin
|
|
|
|
{
|
|
Base1:=nil;
|
|
ViewSize:=438*1024*1024*1024;
|
|
|
|
n:=NtAllocateVirtualMemory(
|
|
NtCurrentProcess,
|
|
@Base1,
|
|
0,
|
|
@ViewSize,
|
|
MEM_RESERVE,
|
|
PAGE_NOACCESS
|
|
);
|
|
|
|
Writeln('NtAllocateVirtualMemory:',HexStr(n,8));
|
|
Writeln('Base1:',HexStr(Base1));
|
|
|
|
_VirtualQuery(Base1);
|
|
|
|
readln;
|
|
|
|
}
|
|
|
|
F:=0; //page file
|
|
|
|
F:=FileCreate('pagefile');
|
|
|
|
FileTruncate(F,64*1024-10);
|
|
|
|
SectionSize.QuadPart:={64*1024} {428*1024*1024*1024} 64*1024-10 { $FFFFFFFFFF};
|
|
|
|
n:=NtCreateSection(
|
|
@hSection,
|
|
//{SECTION_EXTEND_SIZE or} SECTION_MAP_READ or SECTION_MAP_WRITE or SECTION_MAP_EXECUTE,
|
|
//SECTION_EXTEND_SIZE or SECTION_ALL_ACCESS,
|
|
SECTION_MAP_READ,
|
|
nil,
|
|
@SectionSize,
|
|
//PAGE_READWRITE,
|
|
PAGE_READONLY,
|
|
//PAGE_EXECUTE_READWRITE,
|
|
SEC_COMMIT,
|
|
//SEC_RESERVE,
|
|
F
|
|
);
|
|
|
|
Writeln('NtCreateSection:',HexStr(n,8));
|
|
|
|
//0123456789ABCDEF0123456789ABCDEF01234567 16+16+7=39 39-11-28 48-39=9
|
|
//1111111111111111111111111111111111111111
|
|
//0000000000000000000000000001000000000000
|
|
// BA9876543210
|
|
|
|
//SectionSize.QuadPart:={64*1024} {428*1024*1024*1024} $FFFFFFFFFF;
|
|
//n:=NtExtendSection(
|
|
// hSection,
|
|
// @SectionSize
|
|
// );
|
|
//
|
|
//Writeln('NtExtendSection:',HexStr(n,8));
|
|
|
|
Base1:=nil;
|
|
Base2:=nil;
|
|
ViewSize:={64*1024} 16*1024*1024*1024;
|
|
start:=0;
|
|
|
|
//
|
|
|
|
CommitSize:=64*1024;
|
|
ViewSize:=64*1024-10;
|
|
|
|
n:=NtMapViewOfSection(hSection,
|
|
NtCurrentProcess,
|
|
@Base1,
|
|
0,
|
|
CommitSize,
|
|
nil,
|
|
@ViewSize,
|
|
ViewUnmap,
|
|
0
|
|
{MEM_RESERVE},
|
|
{PAGE_READWRITE}
|
|
PAGE_READONLY
|
|
);
|
|
|
|
Writeln('NtMapViewOfSection:',HexStr(n,8));
|
|
|
|
Writeln('Base1:',HexStr(Base1));
|
|
|
|
_VirtualQuery(Base1);
|
|
|
|
//
|
|
|
|
ViewSize:=64*1024;
|
|
|
|
n:=NtMapViewOfSection(hSection,
|
|
NtCurrentProcess,
|
|
@Base2,
|
|
0,
|
|
0,
|
|
nil,
|
|
@ViewSize,
|
|
ViewUnmap,
|
|
0
|
|
{MEM_RESERVE},
|
|
PAGE_READWRITE);
|
|
|
|
Writeln('NtMapViewOfSection:',HexStr(n,8));
|
|
|
|
Writeln('Base2:',HexStr(Base2));
|
|
|
|
//
|
|
|
|
ViewSize:=64*1024;
|
|
|
|
n:=NtAllocateVirtualMemory(
|
|
NtCurrentProcess,
|
|
@Base1,
|
|
0,
|
|
@ViewSize,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
|
|
Writeln('NtAllocateVirtualMemory:',HexStr(n,8));
|
|
|
|
Writeln('Base1:',HexStr(Base1));
|
|
|
|
_VirtualQuery(Base1);
|
|
|
|
//
|
|
|
|
ViewSize:=64*1024;
|
|
|
|
n:=NtAllocateVirtualMemory(
|
|
NtCurrentProcess,
|
|
@Base2,
|
|
0,
|
|
@ViewSize,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
|
|
Writeln('NtAllocateVirtualMemory:',HexStr(n,8));
|
|
|
|
Writeln('Base2:',HexStr(Base2));
|
|
|
|
//
|
|
|
|
PQWORD(Base1)^:=12345;
|
|
|
|
Writeln(PQWORD(Base2)^);
|
|
|
|
//InitVulkan;
|
|
//dev:=vkAllocHostPointer(Device.FHandle,ViewSize,0,Base1);
|
|
//
|
|
//n:=NtUnmapViewOfSection(
|
|
// NtCurrentProcess,
|
|
// Base1
|
|
// );
|
|
//
|
|
//Writeln('NtUnmapViewOfSection:',HexStr(n,8));
|
|
|
|
//n:=NtFreeVirtualMemory(
|
|
// NtCurrentProcess,
|
|
// @Base1,
|
|
// @ViewSize,
|
|
// MEM_RESET
|
|
// );
|
|
//
|
|
//Writeln('NtFreeVirtualMemory:',HexStr(n,8));
|
|
|
|
|
|
n:=NtProtectVirtualMemory(
|
|
NtCurrentProcess,
|
|
@Base1,
|
|
@ViewSize,
|
|
PAGE_NOACCESS,
|
|
@start
|
|
);
|
|
|
|
Writeln('NtProtectVirtualMemory:',HexStr(n,8));
|
|
|
|
Writeln('Base1:',HexStr(Base1));
|
|
|
|
_VirtualQuery(Base1);
|
|
|
|
Writeln(PQWORD(Base2)^);
|
|
PQWORD(Base2)^:=6789;
|
|
|
|
end;
|
|
|
|
procedure id_test;
|
|
var
|
|
table:t_id_desc_table;
|
|
desc :t_id_desc;
|
|
key :Integer;
|
|
res :Boolean;
|
|
|
|
procedure print_table;
|
|
begin
|
|
Writeln('table.FCount=',table.FCount);
|
|
Writeln('table.FSpace=',table.FSpace);
|
|
Writeln('table.FLast =',table.FLast );
|
|
Writeln('table.FPos =',table.FPos );
|
|
end;
|
|
|
|
begin
|
|
id_table_init(@table,1,5);
|
|
|
|
desc:=Default(t_id_desc);
|
|
key:=0;
|
|
|
|
//
|
|
|
|
res:=id_new(@table,@desc,@key);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
res:=id_new(@table,@desc,@key);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
res:=id_new(@table,@desc,@key);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
res:=id_new(@table,@desc,@key);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
key:=3;
|
|
res:=id_del(@table,key,nil);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
key:=4;
|
|
res:=id_del(@table,key,nil);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
//
|
|
|
|
res:=id_new(@table,@desc,@key);
|
|
|
|
Writeln(res,' ',key);
|
|
|
|
print_table;
|
|
|
|
id_table_fini(@table);
|
|
end;
|
|
|
|
type
|
|
p_test_tailq=^test_tailq;
|
|
test_tailq=packed record
|
|
stub:array[0..2] of qword;
|
|
entry:TAILQ_ENTRY;
|
|
name:PChar;
|
|
end;
|
|
|
|
procedure tailq;
|
|
var
|
|
list:TAILQ_HEAD;
|
|
e,n:p_test_tailq;
|
|
begin
|
|
TAILQ_INIT(@list);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='one';
|
|
//TAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
TAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='two';
|
|
//TAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
TAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='thr';
|
|
//TAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
TAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
Writeln('TAILQ_FIRST');
|
|
e:=TAILQ_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
Writeln(e^.name);
|
|
e:=TAILQ_NEXT(e,@e^.entry);
|
|
end;
|
|
|
|
Writeln('TAILQ_LAST');
|
|
e:=TAILQ_LAST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
Writeln(e^.name);
|
|
e:=TAILQ_PREV(e,@e^.entry);
|
|
end;
|
|
|
|
Writeln('TAILQ_REMOVE');
|
|
e:=TAILQ_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
n:=TAILQ_NEXT(e,@e^.entry);
|
|
//
|
|
TAILQ_REMOVE(@list,e,@e^.entry);
|
|
Writeln(e^.name);
|
|
FreeMem(e);
|
|
//
|
|
e:=n;
|
|
end;
|
|
|
|
//
|
|
|
|
LIST_INIT(@list);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='one';
|
|
LIST_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='two';
|
|
LIST_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='thr';
|
|
LIST_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
Writeln('LIST_FIRST');
|
|
e:=LIST_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
Writeln(e^.name);
|
|
e:=LIST_NEXT(e,@e^.entry);
|
|
end;
|
|
|
|
//REMOVE
|
|
Writeln('LIST_REMOVE');
|
|
e:=LIST_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
n:=LIST_NEXT(e,@e^.entry);
|
|
//
|
|
LIST_REMOVE(e,@e^.entry);
|
|
Writeln(e^.name);
|
|
FreeMem(e);
|
|
//
|
|
e:=n;
|
|
end;
|
|
|
|
//
|
|
|
|
STAILQ_INIT(@list);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='one';
|
|
STAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
//STAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='two';
|
|
STAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
//STAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
e:=AllocMem(SizeOf(test_tailq));
|
|
e^.name:='thr';
|
|
STAILQ_INSERT_TAIL(@list,e,@e^.entry);
|
|
//STAILQ_INSERT_HEAD(@list,e,@e^.entry);
|
|
|
|
Writeln('STAILQ_FIRST');
|
|
e:=STAILQ_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
Writeln(e^.name);
|
|
e:=STAILQ_NEXT(e,@e^.entry);
|
|
end;
|
|
writeln;
|
|
|
|
Writeln('STAILQ_LAST');
|
|
e:=STAILQ_LAST(@list,@p_test_tailq(nil)^.entry);
|
|
Writeln(e^.name);
|
|
|
|
Writeln('STAILQ_REMOVE');
|
|
e:=STAILQ_FIRST(@list);
|
|
while (e<>nil) do
|
|
begin
|
|
n:=STAILQ_NEXT(e,@e^.entry);
|
|
//
|
|
STAILQ_REMOVE(@list,e,@e^.entry);
|
|
Writeln(e^.name);
|
|
FreeMem(e);
|
|
//
|
|
e:=n;
|
|
end;
|
|
|
|
//
|
|
|
|
writeln;
|
|
end;
|
|
|
|
var
|
|
ThreadHandle:THandle;
|
|
v:Integer;
|
|
n:Integer;
|
|
|
|
prio:t_rtprio;
|
|
|
|
ktd:p_kthread;
|
|
|
|
_time:Int64;
|
|
_tv:timeval;
|
|
|
|
_thr_param:thr_param;
|
|
_uctx:ucontext_t;
|
|
|
|
ru:t_rusage;
|
|
|
|
begin
|
|
//tailq;
|
|
id_test;
|
|
|
|
//test_map;
|
|
test_map2;
|
|
sys_init;
|
|
|
|
//Writeln(get_proc_prio());
|
|
//Writeln(set_proc_prio(14));
|
|
//Writeln(get_proc_prio());
|
|
|
|
//Writeln(sys_getrusage(RUSAGE_SELF,@ru));
|
|
//Writeln(sys_getrusage(RUSAGE_THREAD,@ru));
|
|
|
|
e:=_umtx_op(nil,UMTX_OP_RW_WRLOCK,0,nil,nil);
|
|
Writeln('me=',e,' _errno:',__error^);
|
|
|
|
//kern_clock_gettime_unit(CLOCK_PROCTIME,@_time);
|
|
//writeln(_time/10000000:0:3);
|
|
|
|
sys_adjtime(nil,@_tv);
|
|
writeln(_tv.tv_sec,',',_tv.tv_usec);
|
|
|
|
e:=NtCreateEvent(
|
|
@event,
|
|
EVENT_ALL_ACCESS,
|
|
nil,
|
|
NotificationEvent,
|
|
False);
|
|
|
|
_umutex_init(@mtx);
|
|
|
|
//mtx.m_flags:=UMUTEX_PRIO_INHERIT;
|
|
mtx.m_flags:=UMUTEX_PRIO_PROTECT;
|
|
|
|
mseg:=VirtualAlloc(nil,64*1024,MEM_COMMIT,PAGE_READWRITE);
|
|
mem:=VirtualAlloc(nil,64*1024,MEM_COMMIT,PAGE_READWRITE);
|
|
|
|
mem2:=VirtualAlloc(nil,64*1024,MEM_COMMIT,PAGE_READWRITE);
|
|
|
|
prio._type:=RTP_PRIO_NORMAL;
|
|
prio._prio:=700;
|
|
|
|
_thr_param:=Default(thr_param);
|
|
|
|
_thr_param.start_func:=@test_thread;
|
|
_thr_param.arg :=nil;
|
|
_thr_param.stack_base:=mem;
|
|
_thr_param.stack_size:=64*1024;
|
|
_thr_param.tls_base :=mem;
|
|
_thr_param.child_tid :=@tid;
|
|
_thr_param.parent_tid:=nil;
|
|
_thr_param.rtp :=@prio;
|
|
_thr_param.name :='test';
|
|
|
|
thr_new(@_thr_param,SizeOf(_thr_param));
|
|
|
|
_thr_param.start_func:=@test_thread;
|
|
_thr_param.arg :=nil;
|
|
_thr_param.stack_base:=mem2;
|
|
_thr_param.stack_size:=64*1024;
|
|
_thr_param.tls_base :=mem2;
|
|
_thr_param.child_tid :=nil;
|
|
_thr_param.parent_tid:=nil;
|
|
_thr_param.rtp :=@prio;
|
|
_thr_param.name :='test2';
|
|
|
|
thr_new(@_thr_param,SizeOf(_thr_param));
|
|
|
|
//_uctx:=Default(ucontext_t);
|
|
//_uctx.uc_mcontext.mc_len:=sizeof(mcontext_t);
|
|
//
|
|
//_uctx.uc_mcontext.mc_rsp:=qword(_thr_param.stack_base)+_thr_param.stack_size-8;
|
|
//_uctx.uc_mcontext.mc_rip:=qword(@test_thread);
|
|
//
|
|
//thr_create(@_uctx,nil,0);
|
|
|
|
//readln;
|
|
|
|
sleep(500);
|
|
|
|
ktd:=tdfind(tid);
|
|
|
|
//NtSuspendThread(ktd^.td_handle,nil);
|
|
//NtResumeThread(ktd^.td_handle,nil);
|
|
|
|
sleep(-1);
|
|
//readln;
|
|
|
|
FillChar(mseg^,64*1024,$11);
|
|
|
|
ThreadHandle:=BeginThread(@_thread);
|
|
|
|
{
|
|
For v:=-16 to 16 do
|
|
begin
|
|
n:=NtSetInformationThread(ThreadHandle,ThreadBasePriority,@v,SizeOf(Integer));
|
|
if (n=0) then
|
|
Writeln('v:',v,' ',HexStr(n,8));
|
|
end;
|
|
|
|
readln;
|
|
}
|
|
|
|
BeginThread(@_thread);
|
|
//BeginThread(@_thread);
|
|
//BeginThread(@_thread);
|
|
|
|
NtSetEvent(event,nil);
|
|
|
|
//e:=_do_lock_umtx(@mtx,GetCurrentThreadId);
|
|
//Writeln(' lock[',GetCurrentThreadId,'] ',e);
|
|
|
|
//e:=do_unlock_umtx(@mtx,GetCurrentThreadId);
|
|
//Writeln('unlock[',GetCurrentThreadId,'] ',e);
|
|
//
|
|
//e:=_do_lock_umtx(@mtx,GetCurrentThreadId);
|
|
//Writeln(' lock[',GetCurrentThreadId,'] ',e);
|
|
//
|
|
//e:=do_unlock_umtx(@mtx,GetCurrentThreadId);
|
|
//Writeln('unlock[',GetCurrentThreadId,'] ',e);
|
|
|
|
//_umutex_done(@mtx);
|
|
|
|
readln;
|
|
end.
|
|
|