2020-02-15 22:25:33 +00:00
|
|
|
|
Bool CheckPtr(U8 *ptr)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Check if addr is valid ptr.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (mem_heap_base <= ptr <= mem_mapped_space)
|
|
|
|
|
return *MemPageTable(ptr) & 1;
|
|
|
|
|
else
|
|
|
|
|
return mem_boot_base < ptr < VGAM_GRAPHICS;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
Bool CheckCodePtr(U8 *ptr)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Check if addr is valid code addr.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (mem_heap_base <= ptr <= mem_heap_limit)
|
|
|
|
|
return *MemPageTable(ptr) & 1;
|
|
|
|
|
else
|
|
|
|
|
return mem_boot_base < ptr < VGAM_GRAPHICS;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
|
Bool CheckOnStack(U8 *ptr,CTask *task=NULL)
|
|
|
|
|
{//Check if addr is valid stack addr.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
Bool res = FALSE;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if(task) {
|
|
|
|
|
if (&task->stack->stack_base <= ptr <= (&task->stack->stack_base)(U8 *) + task->stack->stack_size)
|
|
|
|
|
res=TRUE;
|
|
|
|
|
}
|
|
|
|
|
else if (mem_heap_base <= ptr <= mem_heap_limit)
|
|
|
|
|
res = TRUE;
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
|
I64 UnusedStack(CTask *task=NULL)
|
|
|
|
|
{//Count of usused bytes in task's stack.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 res;
|
|
|
|
|
if (!task)
|
|
|
|
|
task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (task == Fs)
|
2020-03-19 20:59:53 +00:00
|
|
|
|
res = RSPGet()(U8 *) - (&task->stack->stack_base)(U8 *);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
else
|
|
|
|
|
res = task->rsp(U8 *) - (&task->stack->stack_base)(U8 *);
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U8 *Caller(I64 num=1)
|
|
|
|
|
{//Returns the addr of the fun which called this one,
|
|
|
|
|
//or the caller of the caller, etc.
|
2020-03-19 20:59:53 +00:00
|
|
|
|
U8 **rbp=RBPGet,**ptr;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
while (num--) {
|
|
|
|
|
if (rbp>=*rbp)
|
|
|
|
|
return NULL;
|
|
|
|
|
rbp=*rbp;
|
|
|
|
|
if (!CheckOnStack(rbp,Fs))
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ptr=rbp+1;
|
|
|
|
|
return *ptr;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U8 *TaskCaller(CTask *task=NULL,I64 num=0,Bool saved_context=FALSE)
|
2020-02-16 01:19:05 +00:00
|
|
|
|
{//Fetches addr of Nth caller on task's stack.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
U8 **ptr,**rbp,**rsp;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
if (!saved_context && task==Fs)
|
|
|
|
|
return Caller(num+1);
|
|
|
|
|
if (!TaskValidate(task))
|
|
|
|
|
return NULL;
|
|
|
|
|
rbp=task->rbp;
|
|
|
|
|
rsp=task->rsp;
|
|
|
|
|
if (num) {
|
|
|
|
|
while (CheckOnStack(rbp,task)) {
|
|
|
|
|
ptr=rbp+1;
|
|
|
|
|
if (! --num)
|
|
|
|
|
return *ptr;
|
|
|
|
|
if (rbp>=*rbp)
|
|
|
|
|
break;
|
|
|
|
|
rbp=*rbp;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
} else {
|
|
|
|
|
if (task->rip==_RET)
|
|
|
|
|
return *rsp;
|
|
|
|
|
else
|
|
|
|
|
return task->rip;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#define STACK_REP_LEN 32
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
|
U0 StackRep(CTask *task=NULL)
|
|
|
|
|
{//Reports whats on the stack.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i,j,addr,
|
|
|
|
|
**rbp,**rsp,*my_rsp[STACK_REP_LEN];
|
|
|
|
|
CHashTable *old_hash=Fs->hash_table;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
if (!TaskValidate(task))
|
|
|
|
|
return;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (task==Fs) {
|
2020-03-19 20:59:53 +00:00
|
|
|
|
rbp=RBPGet;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
rsp=rbp+3;
|
|
|
|
|
rbp=*rbp;
|
|
|
|
|
} else {
|
|
|
|
|
rsp=task->rsp;
|
|
|
|
|
rbp=task->rbp;
|
|
|
|
|
}
|
|
|
|
|
if (task->rip==_RET)
|
|
|
|
|
addr=*rsp;
|
|
|
|
|
else
|
|
|
|
|
addr=task->rip;
|
|
|
|
|
MemCopy(my_rsp,rsp,STACK_REP_LEN*sizeof(U8 *));
|
|
|
|
|
POPFD
|
|
|
|
|
Fs->hash_table=task->hash_table;
|
|
|
|
|
for (i=0;i<STACK_REP_LEN;i++) {
|
|
|
|
|
"%08X [RSP+%04X]: %016X ",rsp+i,
|
|
|
|
|
i*sizeof(U8 *),my_rsp[i];
|
|
|
|
|
while (TRUE) {
|
|
|
|
|
if (!(&task->stack->stack_base<=rbp<
|
|
|
|
|
(&task->stack->stack_base)(U8 *)+task->stack->stack_size))
|
|
|
|
|
break;
|
|
|
|
|
j=rbp-rsp;
|
|
|
|
|
if (j>=i)
|
|
|
|
|
break;
|
|
|
|
|
addr=my_rsp[j+1];
|
|
|
|
|
if (rbp>=my_rsp[j])
|
|
|
|
|
break;
|
|
|
|
|
rbp=my_rsp[j];
|
|
|
|
|
}
|
|
|
|
|
if (my_rsp[i]==addr)
|
|
|
|
|
"$$RED$$";
|
|
|
|
|
"%P$$FG$$\n",my_rsp[i];
|
|
|
|
|
}
|
|
|
|
|
'\n';
|
|
|
|
|
Fs->hash_table=old_hash;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL)
|
|
|
|
|
{//Prints a report of calling routines.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 **ptr;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
if (!rbp) {
|
|
|
|
|
if (task==Fs)
|
2020-03-19 20:59:53 +00:00
|
|
|
|
rbp=RBPGet;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
else
|
|
|
|
|
rbp=task->rbp;
|
|
|
|
|
}
|
|
|
|
|
"CallerRep:\n";
|
|
|
|
|
while (CheckOnStack(rbp,task)) {
|
|
|
|
|
ptr=rbp+1;
|
|
|
|
|
"%08X:%08tX:%P\n",ptr,*ptr,*ptr;
|
|
|
|
|
if (rbp>=*rbp)
|
|
|
|
|
break;
|
|
|
|
|
rbp=*rbp;
|
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
U0 D(U8 *addr,I64 count=0x80,Bool show_offset=TRUE)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Dump mem, showing offsets.
|
|
|
|
|
//See $LK,"DocD",A="MN:DocD"$() for a live dump.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i,j,ch;
|
|
|
|
|
U8 *ptr=addr;
|
|
|
|
|
while (count) {
|
|
|
|
|
if (show_offset)
|
2020-03-01 01:59:50 +00:00
|
|
|
|
"%08X ",ptr-addr;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
else
|
2020-03-01 01:59:50 +00:00
|
|
|
|
"%010X ",ptr;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (count>16)
|
|
|
|
|
j=16;
|
|
|
|
|
else
|
|
|
|
|
j=count;
|
|
|
|
|
for (i=0;i<j;i++)
|
|
|
|
|
"%02X ",ptr[i];
|
|
|
|
|
for (;i<16;i++)
|
2020-03-01 01:59:50 +00:00
|
|
|
|
" ";
|
2020-03-13 02:59:08 +00:00
|
|
|
|
for (i=0;i<j;i++) {
|
2020-02-20 23:40:10 +00:00
|
|
|
|
ch=ptr[i];
|
2020-03-13 02:59:08 +00:00
|
|
|
|
if (ch < CH_SPACE || ch==CH_BACKSPACE)
|
2020-02-20 23:40:10 +00:00
|
|
|
|
ch='.';
|
|
|
|
|
'' ch;
|
|
|
|
|
if (ch=='$$')
|
|
|
|
|
'' ch;
|
|
|
|
|
}
|
|
|
|
|
'\n';
|
|
|
|
|
count-=j;
|
|
|
|
|
ptr+=j;
|
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
U0 Dm(U8 *addr,I64 count=0x80)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Show mem addr, not offsets.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
D(addr,count,FALSE);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
U0 Da(U8 **addr,I64 count=0x10)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Dump mem, showing symbolic addresses.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
while (count-->0) {
|
|
|
|
|
"%08X:%08X,%P\n",addr,*addr,*addr;
|
|
|
|
|
addr++;
|
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 03:06:00 +00:00
|
|
|
|
U0 RawPrint(I64 mS=100,U8 *format,...)
|
2020-02-16 04:57:03 +00:00
|
|
|
|
{//Print using $LK,"Raw",A="MN:Raw"$ screen output for a length of time.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
//$BK,1$Your heap must be good.$BK,0$
|
2020-02-20 23:40:10 +00:00
|
|
|
|
U8 *buf=StrPrintJoin(NULL,format,argc,argv);
|
|
|
|
|
Bool old_raw,old_input_filter;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
old_raw=Raw(ON);
|
|
|
|
|
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
|
|
|
|
"%s",buf;
|
|
|
|
|
Busy(mS<<10);
|
|
|
|
|
POPFD
|
|
|
|
|
LBEqual(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
|
|
|
|
Raw(old_raw);
|
|
|
|
|
Free(buf);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
U0 RawD(I64 mS=100,U8 *addr,I64 count=0x80)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Dumps a block of mem using $LK,"Raw",A="MN:Raw"$
|
2020-02-16 04:57:03 +00:00
|
|
|
|
//screen output for a fixed length
|
2020-02-20 23:40:10 +00:00
|
|
|
|
//of time.
|
|
|
|
|
Bool old_raw,old_input_filter;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
old_raw=Raw(ON);
|
|
|
|
|
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
|
|
|
|
D(addr,count);
|
|
|
|
|
Busy(mS<<10);
|
|
|
|
|
POPFD
|
|
|
|
|
LBEqual(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
|
|
|
|
Raw(old_raw);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
U0 RawDm(I64 mS=100,U8 *addr,I64 count=0x80)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Dumps a block of mem using $LK,"Raw",A="MN:Raw"$
|
2020-02-16 04:57:03 +00:00
|
|
|
|
//screen output for a fixed length
|
2020-02-20 23:40:10 +00:00
|
|
|
|
//of time.
|
|
|
|
|
Bool old_raw,old_input_filter;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
old_raw=Raw(ON);
|
|
|
|
|
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
|
|
|
|
Dm(addr,count);
|
|
|
|
|
Busy(mS<<10);
|
|
|
|
|
POPFD
|
|
|
|
|
LBEqual(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
|
|
|
|
Raw(old_raw);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 *TaskRegAddr(CTask *task,I64 reg_num)
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
switch (reg_num) {
|
|
|
|
|
case REG_RAX: return &task->rax;
|
|
|
|
|
case REG_RCX: return &task->rcx;
|
|
|
|
|
case REG_RDX: return &task->rdx;
|
|
|
|
|
case REG_RBX: return &task->rbx;
|
|
|
|
|
case REG_RSP: return &task->rsp;
|
|
|
|
|
case REG_RBP: return &task->rbp;
|
|
|
|
|
case REG_RSI: return &task->rsi;
|
|
|
|
|
case REG_RDI: return &task->rdi;
|
|
|
|
|
case 8 : return &task->r8;
|
|
|
|
|
case 9 : return &task->r9;
|
|
|
|
|
case 10: return &task->r10;
|
|
|
|
|
case 11: return &task->r11;
|
|
|
|
|
case 12: return &task->r12;
|
|
|
|
|
case 13: return &task->r13;
|
|
|
|
|
case 14: return &task->r14;
|
|
|
|
|
case 15: return &task->r15;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define RAWDR_COL (text.cols-40)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
|
|
U0 RawDr(CTask *task=NULL)
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i,j,old_col=text.raw_col;
|
|
|
|
|
Bool old_raw=Raw(ON);
|
|
|
|
|
U8 buf[200];
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (!task) task=Fs;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
for (i=0;i<16;i++) {
|
|
|
|
|
text.raw_col=i*text.cols+RAWDR_COL;
|
|
|
|
|
"<EFBFBD>%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
|
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_col=i++*text.cols+RAWDR_COL;
|
|
|
|
|
"<EFBFBD>RIP:%016X\n",task->rip;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_col=i++*text.cols+RAWDR_COL;
|
|
|
|
|
"<EFBFBD>%-*tp\n",text.cols-(RAWDR_COL+1)-1,Fs->rip;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_col=i++*text.cols+RAWDR_COL;
|
|
|
|
|
'<EFBFBD>';
|
|
|
|
|
if (Bt(&sys_run_level,RLf_COMPILER)) {
|
|
|
|
|
j=Fs->rip;
|
|
|
|
|
Ui(buf,&j,,,TRUE);
|
|
|
|
|
"%s",buf;
|
|
|
|
|
} else
|
|
|
|
|
'\n';
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_col=i*text.cols+RAWDR_COL;
|
|
|
|
|
'<EFBFBD>';
|
|
|
|
|
for (j=0;j<text.cols-RAWDR_COL-1;j++)
|
|
|
|
|
'<EFBFBD>';
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_col=old_col;
|
|
|
|
|
Raw(old_raw);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Dr(CTask *task=NULL)
|
|
|
|
|
{//Dump regs
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
for (i=0;i<16;i++)
|
|
|
|
|
"%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
|
|
|
|
|
"RIP:%016X\n",task->rip;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U8 *SysGetStr2(I64)
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
U8 buf[512];
|
2020-03-19 20:59:53 +00:00
|
|
|
|
StrNGet(buf,512,FALSE);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
return StrNew(buf);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE)
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
CBpt *res=NULL,*tmpb,*tmpb1,*tmpb2;
|
|
|
|
|
if (!haystack_task) haystack_task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
tmpb1=&haystack_task->bpt_list;
|
|
|
|
|
tmpb=haystack_task->bpt_list;
|
|
|
|
|
while (tmpb) {
|
|
|
|
|
tmpb2=tmpb->next;
|
|
|
|
|
if (tmpb->addr==needle_addr) {
|
|
|
|
|
res=tmpb;
|
|
|
|
|
if (rem)
|
|
|
|
|
tmpb1->next=tmpb2;
|
|
|
|
|
else
|
|
|
|
|
tmpb1=&tmpb->next;
|
|
|
|
|
} else
|
|
|
|
|
tmpb1=&tmpb->next;
|
|
|
|
|
tmpb=tmpb2;
|
|
|
|
|
}
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE)
|
|
|
|
|
{//Set breakpoint.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
CBpt *tmpb;
|
|
|
|
|
Bool res=TRUE;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (!(tmpb=BptFind(addr,task,FALSE))) {
|
|
|
|
|
tmpb=CAlloc(sizeof(CBpt),task);
|
|
|
|
|
tmpb->addr=addr;
|
|
|
|
|
tmpb->val=*addr;
|
|
|
|
|
res=FALSE;
|
|
|
|
|
tmpb->next=task->bpt_list;
|
|
|
|
|
task->bpt_list=tmpb;
|
|
|
|
|
if (task==Fs && live)
|
|
|
|
|
*addr=OC_BPT;
|
|
|
|
|
}
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE)
|
2020-02-15 23:13:27 +00:00
|
|
|
|
{//Remove breakpoint.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
CBpt *tmpb;
|
|
|
|
|
Bool res=FALSE;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (tmpb=BptFind(addr,task,rem)) {
|
|
|
|
|
if (task==Fs && live)
|
|
|
|
|
*tmpb->addr=tmpb->val;
|
|
|
|
|
res=TRUE;
|
|
|
|
|
if (rem)
|
|
|
|
|
Free(tmpb);
|
|
|
|
|
}
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE)
|
|
|
|
|
{//Toggle breakpoint.
|
|
|
|
|
//Return: TRUE if removed.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
Bool res=FALSE;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (BptFind(addr,task,FALSE)) {
|
|
|
|
|
BptR(addr,task,live,TRUE);
|
|
|
|
|
res=TRUE;
|
|
|
|
|
} else
|
|
|
|
|
BptS(addr,task,live);
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 B2(CTask *task=NULL,Bool live=TRUE)
|
2020-02-15 23:13:27 +00:00
|
|
|
|
{//Remove all breakpoints.
|
2020-02-16 00:20:04 +00:00
|
|
|
|
//Return: count of removed.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 res=0;
|
|
|
|
|
CBpt *tmpb,*tmpb1;
|
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
tmpb=task->bpt_list;
|
|
|
|
|
task->bpt_list=NULL;
|
|
|
|
|
while (tmpb) {
|
|
|
|
|
tmpb1=tmpb->next;
|
|
|
|
|
if (task==Fs && live)
|
|
|
|
|
*tmpb->addr=tmpb->val;
|
|
|
|
|
Free(tmpb);
|
|
|
|
|
tmpb=tmpb1;
|
|
|
|
|
res++;
|
|
|
|
|
}
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL)
|
|
|
|
|
{//Go
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
if (ip!=INVALID_PTR) task->rip=ip;
|
|
|
|
|
if (BptFind(task->rip,task))
|
|
|
|
|
"\nDo one of the following, first:\n"
|
|
|
|
|
">S;\t\t\t//Single step\n"
|
|
|
|
|
">B2;\t\t\t//Clear all break points\n"
|
|
|
|
|
">G2;\t\t\t//Clear all break points and Go\n\n"
|
|
|
|
|
"After resuming, <CTRL-ALT-n> next focus task\n"
|
|
|
|
|
"After resuming, <CTRL-ALT-v> flushes screen VGA cache\n";
|
|
|
|
|
else {
|
|
|
|
|
LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
|
|
|
|
|
LBtr(&task->rflags,RFLAGf_TRAP);//No single step
|
|
|
|
|
Suspend(task,FALSE);
|
|
|
|
|
if (task==Fs) {
|
|
|
|
|
if (IsDebugMode && task->next_cc!=&task->next_cc) {
|
|
|
|
|
"Exit Debug\n";
|
|
|
|
|
Btr(&task->last_cc->flags,CCf_PROMPT);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
Exit;
|
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 G2(U8 *ip=INVALID_PTR,CTask *task=NULL)
|
2020-02-15 23:13:27 +00:00
|
|
|
|
{//Remove all breakpoints and Go.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
B2(task);
|
|
|
|
|
if (ext[EXT_WIN_FOCUS])
|
|
|
|
|
CallExtNum(EXT_WIN_FOCUS,debug.focus_task);
|
2020-02-23 02:13:59 +00:00
|
|
|
|
LFBFlush;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
G(ip,task);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public U0 S(U8 *ip=INVALID_PTR,CTask *task=NULL) //Single-step.
|
|
|
|
|
{//Single step.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (!task) task=Fs;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (ip!=INVALID_PTR) task->rip=ip;
|
|
|
|
|
LBts(&task->task_flags,TASKf_DISABLE_BPTS);
|
|
|
|
|
LBts(&task->rflags,RFLAGf_TRAP);
|
|
|
|
|
Suspend(task,FALSE);
|
|
|
|
|
if (task==Fs) {
|
|
|
|
|
if (IsDebugMode) {
|
|
|
|
|
if (task->next_cc!=&task->next_cc)
|
|
|
|
|
Btr(&task->last_cc->flags,CCf_PROMPT);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
Exit;
|
|
|
|
|
POPFD
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
U0 DebugHelp()
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
"\n"
|
|
|
|
|
"The cmd line is basically the same as normal. Here are some common\n"
|
|
|
|
|
"debugging commands.\n\n"
|
|
|
|
|
">EdLite(\"FileName\");\t\t//Edit file.\n"
|
|
|
|
|
">D(0x100000);\t\t\t//Dump page tables.\n"
|
|
|
|
|
">Dm(0x100000);\t\t\t//Dump page tables.\n"
|
|
|
|
|
">Dm(Fs,sizeof(CTask));\t\t//Dump current task record.\n"
|
|
|
|
|
">ClassRep(Fs,\"CTask\",1);\t//Dump current task record.\n"
|
|
|
|
|
">ClassRep(Fs,,1);\t\t//(It knows lastclass.)\n"
|
|
|
|
|
">CallerRep;\t\t\t//Stack trace report.\n"
|
|
|
|
|
">Da(_RSP);\t\t\t//Dump stack.\n"
|
|
|
|
|
">Dr;\t\t\t\t//Dump Regs.\n"
|
|
|
|
|
">1+2*3+&Print;\t\t\t//Show calculation res.\n"
|
|
|
|
|
">*(0x70000)(I64 *)=0x123456789;\t//Assign value to 0x70000-0x70007.\n"
|
|
|
|
|
">_RAX=0x1234;\t\t\t//Set RAX to 0x1234.\n"
|
|
|
|
|
">_RIP=&Break;\t\t//Set RIP.\n"
|
|
|
|
|
">I64 i;\t\t\t\t//Declare variable.\n"
|
|
|
|
|
">i=_RCX+_RDX;\t\t\t//Assign to variable.\n"
|
|
|
|
|
">U(&Print+0x8);\t\t\t//Unassemble Print.\n"
|
|
|
|
|
">Uf(\"Print\");\t\t\t//Unassembler function \"Print\".\n"
|
|
|
|
|
">Man(\"Print\");\t\t\t//Edit Src for \"Print\".\n"
|
|
|
|
|
">E(_RIP);\t\t\t//Edit Src Code.\n"
|
|
|
|
|
">Fix;\t\t\t\t//Edit Last Err Src Code.\n"
|
|
|
|
|
">B(&Main+0x20);\t\t\t//Toggle break point.\n"
|
|
|
|
|
">B2;\t\t\t\t//Clear all break points.\n"
|
|
|
|
|
">S;\t\t\t\t//Single step.\n"
|
|
|
|
|
">G;\t\t\t\t//Resume execution.\n"
|
2020-02-23 02:13:59 +00:00
|
|
|
|
">G2;\t\t\t\t//B2;LFBFlush;WinFocus;G;\n"
|
2020-02-20 23:40:10 +00:00
|
|
|
|
">Exit;\t\t\t\t//Exit (kill) task.\n\n"
|
|
|
|
|
"After resuming, <CTRL-ALT-n> next focus task.\n"
|
|
|
|
|
"After resuming, <CTRL-ALT-v> flushes screen VGA cache.\n\n";
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
U0 Debug2()
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
Bool old_win_inhibit,old_waiting_message,old_single;
|
|
|
|
|
I64 i,old_getstr2;
|
|
|
|
|
U8 buf[200];
|
|
|
|
|
if (debug.panic) {
|
|
|
|
|
if (IsRaw) {
|
|
|
|
|
i=Fs->rip;
|
|
|
|
|
Ui(buf,&i);
|
|
|
|
|
"%s",buf;
|
|
|
|
|
} else
|
|
|
|
|
U(Fs->rip,1);
|
|
|
|
|
} else
|
|
|
|
|
debug.panic=TRUE;
|
|
|
|
|
old_waiting_message=LBtr(&Fs->task_flags,TASKf_AWAITING_MESSAGE);
|
|
|
|
|
old_win_inhibit=Fs->win_inhibit;
|
|
|
|
|
Fs->win_inhibit=WIG_USER_TASK_DEFAULT;
|
|
|
|
|
sys_focus_task=Fs;
|
|
|
|
|
kbd.scan_code=0;
|
|
|
|
|
old_getstr2=fp_getstr2;
|
|
|
|
|
fp_getstr2=&SysGetStr2;
|
|
|
|
|
old_single=SingleUser(OFF);
|
|
|
|
|
while (!mouse_hard.install_attempts)
|
|
|
|
|
Yield;
|
|
|
|
|
SingleUser(old_single);
|
|
|
|
|
UserTaskCont;
|
|
|
|
|
fp_getstr2=old_getstr2;
|
|
|
|
|
Fs->win_inhibit=old_win_inhibit;
|
|
|
|
|
LBEqual(&Fs->task_flags,TASKf_AWAITING_MESSAGE,old_waiting_message);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Fault3(I64 fault_num,I64 fault_err_code)
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
no_warn fault_err_code;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (Gs->num && debug.mp_crash) {
|
|
|
|
|
mp_count=1;
|
|
|
|
|
debug.mp_crash->cpu_num=Gs->num;
|
|
|
|
|
debug.mp_crash->task=Fs;
|
|
|
|
|
debug.mp_crash->rip=Fs->rip;
|
|
|
|
|
debug.mp_crash->message=debug.message;
|
|
|
|
|
debug.mp_crash->message_num=debug.message_num;
|
|
|
|
|
MPInt(I_MP_CRASH,0);
|
|
|
|
|
SysHlt;
|
|
|
|
|
}
|
|
|
|
|
"\n\tZenithOS Debugger\n\n"
|
|
|
|
|
">Help;\t//For help.\n\n";
|
|
|
|
|
Beep(62,TRUE);
|
|
|
|
|
if (fault_num==I_DEBUG) {
|
|
|
|
|
if (debug.message) {
|
2020-03-01 01:59:50 +00:00
|
|
|
|
"\n!!! %s",debug.message;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (debug.message_num)
|
|
|
|
|
"%016X",debug.message_num;
|
2020-03-01 01:59:50 +00:00
|
|
|
|
" !!!\n\n";
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (debug.panic)
|
|
|
|
|
CallerRep;
|
|
|
|
|
Debug2;
|
|
|
|
|
POPFD
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Fault2(I64 fault_num,I64 fault_err_code)
|
2020-02-16 08:00:07 +00:00
|
|
|
|
{//Called from $LK,"Fault2",A="FF:::/Kernel/KInterrupts.CC,Fault2"$.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
//$BK,1$Be careful not to swap-out and ruin the saved context$BK,0$
|
2020-02-20 23:40:10 +00:00
|
|
|
|
Bool was_raw,was_single_user,was_silent,was_in_debug,was_mouse_enabled;
|
|
|
|
|
I64 i,old_raw_flags=text.raw_flags;
|
|
|
|
|
was_single_user=SingleUser(ON);
|
|
|
|
|
if (!IsDebugMode)
|
|
|
|
|
debug.focus_task=sys_focus_task;
|
|
|
|
|
sys_focus_task=NULL;
|
|
|
|
|
if (fault_num==I_BPT)
|
|
|
|
|
Fs->rip--;
|
|
|
|
|
if (Fs->debug_task)
|
|
|
|
|
CallExtNum(EXT_DEBUG_RESUME,fault_num,fault_err_code);
|
|
|
|
|
else {
|
2020-02-21 23:30:17 +00:00
|
|
|
|
was_mouse_enabled = CallExtStr("MouseHardEnable", FALSE);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
was_raw=Raw(ON);
|
|
|
|
|
was_silent=Silent(OFF);
|
|
|
|
|
text.raw_flags|=RAWF_SHOW_DOLLAR|RAWF_SCROLL;
|
|
|
|
|
|
|
|
|
|
"Task \"";
|
|
|
|
|
"%s",Fs->task_title;
|
|
|
|
|
"\"\n";
|
|
|
|
|
"Fault:0x%02X %Z\t\tErr Code:%08X\n",
|
|
|
|
|
fault_num,fault_num,"ST_INT_NAMES",fault_err_code;
|
|
|
|
|
was_in_debug=DebugMode(ON);
|
|
|
|
|
"RIP:%08X",Fs->rip; //Sometimes crashes on %p, so do this first
|
2020-03-01 01:59:50 +00:00
|
|
|
|
":%p RSP:%08X\n",Fs->rip,Fs->rsp;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
if (fault_num==I_PAGE_FAULT) {
|
|
|
|
|
MOV_RAX_CR2
|
2020-03-19 20:59:53 +00:00
|
|
|
|
i=RAXGet;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
"Fault Addr:%08X:%p\n",i,i;
|
|
|
|
|
}
|
|
|
|
|
Fault3(fault_num,fault_err_code);
|
|
|
|
|
DebugMode(was_in_debug);
|
|
|
|
|
Silent(was_silent);
|
|
|
|
|
Raw(was_raw);
|
2020-02-21 23:30:17 +00:00
|
|
|
|
CallExtStr("MouseHardEnable", was_mouse_enabled);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
text.raw_flags=old_raw_flags;
|
|
|
|
|
}
|
|
|
|
|
SingleUser(was_single_user);
|
|
|
|
|
if (LBtr(&Fs->task_flags,TASKf_KILL_AFTER_DEBUG))
|
|
|
|
|
Exit;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 23:56:05 +00:00
|
|
|
|
U0 Panic(U8 *message=NULL,I64 message_num=0,Bool panic=TRUE)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Enter the debugger with panic?
|
2020-02-20 23:40:10 +00:00
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
debug.message=message;
|
|
|
|
|
debug.message_num=message_num;
|
|
|
|
|
debug.panic=panic;
|
|
|
|
|
INT I_DEBUG
|
|
|
|
|
POPFD
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 23:56:05 +00:00
|
|
|
|
U0 Debug(U8 *message=NULL,I64 message_num=0)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Enter debugger, no panic.
|
2020-02-20 23:40:10 +00:00
|
|
|
|
Panic(message,message_num,FALSE);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|