⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debugger.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
*  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 + -