📄 debugger.cpp
字号:
/*
* Copyright (c) 2005 Zhejiang University, P.R.China
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//=============================================================================
/**
* \file Arch/ARMDebugger/Debugger.cpp
*
* $Id: Debugger.cpp,v 1.12 2005/04/20 06:15:20 shengj Exp $
*
* \author dragon <dragonsn@163.com>
*/
//=============================================================================
#include "stdafx.h"
#include <Core/processor.h>
#include <Core/memory.h>
#include "./Debugger.h"
namespace ARM {
const char * Debugger::hexchars = "0123456789abcdef";
const int Debugger::BUFMAX = 2048;
Debugger::Debugger(void)
{
iscont_ = false;
}
Debugger::~Debugger(void)
{
}
void Debugger::debug(Core::Part & part)
{
assert(thread_);
thread_->Create();
thread_->Run();
}
void Debugger::stop()
{
if (!thread_) return;
if (thread_->IsAlive())
{
thread_->Delete();
thread_ = NULL;
}
}
void Debugger::on_create()
{
name_ = "ARM_Debugger";
// detached thread should be create on the heap but not the stack
// by default, the wxThread is created detached. Using a new method
// is necessary
thread_ = new DebuggerThread(this);
}
void Debugger::on_destroy()
{
if (!thread_) return;
if (thread_->IsAlive())
thread_->Delete();
// else
// delete thread_;
thread_ = NULL;
}
void Debugger::debug_run()
{
while (1)
{
if (thread_->test_destroy())
break;
wxIPV4address addr;
addr.Service(888);
wxSocketServer ssock(addr);
if (!ssock.WaitForAccept(0,200))
continue;
::wxSocketBase *csock = ssock.Accept(false);
/*
int tmp = 1;
csock->SetOption(SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
tmp = 1;
csock->SetOption(IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof (tmp));
*/
csock->SetFlags(wxSOCKET_NOWAIT);
Core::u8 inbuf[2048];
Core::u8 outbuf[2048];
while (TRUE)
{
if (thread_->test_destroy())
break;
csock->Read((void *)inbuf, sizeof(inbuf));
wxUint32 ret = csock->LastCount();
inbuf[ret] = 0;
if (ret == 0) continue;
ret = compose_packet_from_sock(csock, inbuf, ret, outbuf);
if (-1 == ret)
break;
else if ( 0 == ret )
continue;
put_packet(csock,outbuf);
}
csock->Close();
csock->Destroy();
return;
}
}
void Debugger::set_debug_thread(DebuggerThread *thread)
{
assert(thread);
thread_ = thread;
}
bool Debugger::get_stop_simulator()
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
return !cpu->is_running();
}
bool Debugger::get_debug()
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
return cpu->is_break();
}
Core::s32 Debugger::con(Core::u32 addr, Core::s32 sig)
{
iscont_ = true;
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
cpu->con();
// cpu->set_break(false);
//Core::Wukong_Get_System().get_cpu(0).set_debug(false);
return 0;
}
Core::s32 Debugger::step(Core::u32 address, Core::s32 sig)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
cpu->step_info();
// cpu->set_single_step(true);
cpu->set_break(false);
return 0;
}
Core::s32 Debugger::get_registers(Core::s32 *regbuf)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
Core::s32 *tmp = regbuf;
memset((void *) regbuf, 0, sizeof(Core::s32)*32);
for (int i = 0; i < 16; ++i )
{
cpu->read_register(i,(Core::Register_Int &)regbuf[i]);
}
return 25;
}
Core::s32 Debugger::write_registers(Core::s32 *regbuf)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
for (int i = 0; i < 16; ++i)
{
cpu->write_register(i,regbuf[i]);
}
return 25;
}
size_t Debugger::get_register(size_t regnum, Core::Register_Int &value)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
//if (regnum > 15) regnum = 16;
cpu->read_register(regnum,value);
// reverse_4((char *)value,1);
return 0;
}
size_t Debugger::write_register(size_t regnum, Core::Register_Int value)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
reverse_4((char *)&value,1);
//if (regnum > 15) regnum = 16;
cpu->write_register(regnum,value);
return sizeof(regnum);
}
size_t Debugger::read_memory(Core::u32 addr, size_t len, Core::Bytecode_Type &buffer)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
cpu->get_mmu().access(Core::Memory<Core::u32>::MEMORY_READ,addr,len,buffer);
return len;
}
size_t Debugger::write_memory(Core::u32 addr, size_t len, Core::Bytecode_Type &buffer)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
cpu->get_mmu().access(Core::Memory<Core::u32>::MEMORY_WRITE,addr,len,buffer);
return len;
}
Core::s32 Debugger::remote_restart()
{
return 0;
}
Core::s32 Debugger::insert_BPWP(Breakpoint_Type type, Core::u32 addr, size_t len)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
return cpu->insert_breakpoint(type,addr,len);
return 0;
}
Core::s32 Debugger::remove_BPWP(Breakpoint_Type type, Core::u32 addr, size_t len)
{
Core::CPU_32Bit * cpu = (Core::CPU_32Bit *)(Core::Wukong_Get_System().get_cpu(0));
return cpu->remove_breakpoint(type,addr,len);
return 0;
}
Core::s32 Debugger::search(Core::s32 addr, Core::s32 pattern, Core::s32 mask)
{
return 0;
}
Core::s32 Debugger::compose_packet_from_sock(wxSocketBase *csock, Core::u8 *buf, size_t len, Core::u8 *outbuf)
{
Core::u8 checksum = 0;
Core::u8 xmitcsum = -1;
size_t i = 0;
size_t count = 0;
Core::u8 ch;
Core::u8 buffer[2048];
Core::u8* input_buffer = (Core::u8 *)buffer;
outbuf[0] = 0;
while (((ch = (buf[i++] & 0x7f)) != '$') && (i < len));
if ( i == len ) return 0;
while (count < BUFMAX && i < len)
{
//ch = buf[i++] & 0x7f;
ch = buf[i++];
if (ch == '#')
break;
checksum = checksum + ch;
buffer[count++] = ch;
}
buffer[count] = 0;
if (ch == '#')
{
// xmitcsum = hex(buf[i++] & 0x7f) << 4;
// xmitcsum |= hex(buf[i++] & 0x7f);
xmitcsum = hex(buf[i++]) << 4;
xmitcsum |= hex(buf[i++]);
if (checksum != xmitcsum)
{
csock->Write("-",1);
return 0;
}
else
{
csock->Write("+",1);
if (buffer[2] == ':')
{
csock->Write((char *)buffer,1);
csock->Write((char *)buffer+1,1);
size_t buflen = strlen((char *)buffer);
for (i=3; i <= buflen; i++)
buffer[i-3] = buffer[i];
}
}
Core::Bytecode_Type mval;
Core::u8* p = &input_buffer[1];
Core::s32 addri = 0;
Core::s32 newaddri = 0;
Core::s32 number = 0;
Core::s32 bptypeint = 0;
Core::s32 tid = 0;
Core::s32 sig = 0;
Core::Register_Int gvalue = 0;;
switch (input_buffer[0])
{
case 'X':
hex2int(&p,&addri,',');
if(*p++ != ',')
break;
hex2int(&p,&number,':');
if (*p++ != ':')
break;
if ( number > 0 )
{
mval.resize(number);
// specific char such as 0x7d, '$', '#' should be disposed
// the result is XORed with 0x20, then add 0x7d
// example 0x7d 0x2d represent 0x7d.
do_with_special_char(p, count - (size_t)(p - input_buffer));
memcpy((Core::u8*)(&mval[0]),p,number);
write_memory((Core::u32)(addri),number,mval);
}
write_ok(outbuf);
break;
case 'm':
hex2int(&p,&addri,',');
if(*p++ != ',')
break;
hex2int(&p,&number,0);
read_memory(addri,number,mval);
mem2hex((Core::u8*)(&mval[0]),outbuf,number,0);
break;
// MAA..AA,LLLL:XX..XX, where AA..AA is address,LLLL is number of bytes,XX..XX is the data
case 'M':
hex2int(&p,&addri,',');
if (*p++ != ',')
break;
hex2int(&p,&number,':');
if (*p++ != ':')
break;
if (number > 0)
{
mval.resize(number*2);
hex2mem(p,(Core::u8*)(&mval[0]),number*2,0);
write_memory((Core::u32)(addri),number,mval);
}
write_ok(outbuf);
break;
case 'z'://ztype,addr,length -- remove breakpoint or watchpoint
hex2int(&p,&bptypeint,0);
if (*p++ != ',')
break;
hex2int(&p,&addri,',');
if(*p++ != ',')
break;
hex2int(&p,&number,0);
if (*p!=0)
break;
remove_BPWP((Breakpoint_Type)(bptypeint),(Core::u32)(addri),(size_t)(number));
write_ok(outbuf);//?不知是否要回复
break;
case 'Z'://Ztype,addr,length -- insert breakpoint or watchpoint
hex2int(&p,&bptypeint,0);
if (*p++ != ',')
break;
hex2int(&p,&addri,',');
if(*p++ != ',')
break;
hex2int(&p,&number,0);
if (*p!=0)
break;
insert_BPWP((Breakpoint_Type)(bptypeint),(Core::u32)(addri),(size_t)(number));
write_ok(outbuf);//?不知是否要回复
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -