Пример #1
0
void CtrlBreakpointList::handleNotify(LPARAM lParam)
{
	const LPNMHDR header = (LPNMHDR)lParam;
	if (header->code == NM_DBLCLK)
	{
		const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
		gotoBreakpointAddress(item->iItem);
		return;
	}
	if (header->code == NM_RCLICK)
	{
		const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
		showBreakpointMenu(item->iItem, item->ptAction);
		return;
	}

	if (header->code == LVN_GETDISPINFO)
	{
		NMLVDISPINFO *dispInfo = (NMLVDISPINFO *)lParam;
		
		bool isMemory;
		int index = getBreakpointIndex(dispInfo->item.iItem,isMemory);
		if (index == -1) return;
		
		breakpointText = L"";
		switch (dispInfo->item.iSubItem)
		{
		case BPL_TYPE:
			{
				if (isMemory) {
					switch (displayedMemChecks_[index].cond) {
					case MEMCHECK_READ:
						breakpointText = L"Read";
						break;
					case MEMCHECK_WRITE:
						breakpointText = L"Write";
						break;
					case MEMCHECK_READWRITE:
						breakpointText = L"Read/Write";
						break;
					}
				} else {
					breakpointText = L"Execute";
				}
			}
			break;
		case BPL_OFFSET:
			{
				wchar_t temp[256];
				if (isMemory) {
					wsprintf(temp,L"0x%08X",displayedMemChecks_[index].start);
				} else {
					wsprintf(temp,L"0x%08X",displayedBreakPoints_[index].addr);
				}
				breakpointText = temp;
			}
			break;
		case BPL_SIZELABEL:
			{
				if (isMemory) {
					auto mc = displayedMemChecks_[index];
					wchar_t temp[256];
					if (mc.end == 0)
						wsprintf(temp,L"0x%08X",1);
					else
						wsprintf(temp,L"0x%08X",mc.end-mc.start);
					breakpointText = temp;
				} else {
					const char* sym = cpu->findSymbolForAddress(displayedBreakPoints_[index].addr);
					if (sym != NULL)
					{
						breakpointText = ConvertUTF8ToWString(sym);
					} else {
						breakpointText = L"-";
					}
				}
			}
			break;
		case BPL_OPCODE:
			{
				if (isMemory) {
					breakpointText = L"-";
				} else {
					char temp[256];
					disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp);
					breakpointText = ConvertUTF8ToWString(temp);
				}
			}
			break;
		case BPL_CONDITION:
			{
				if (isMemory || displayedBreakPoints_[index].hasCond == false) {
					breakpointText = L"-";
				} else {
					breakpointText = ConvertUTF8ToWString(displayedBreakPoints_[index].cond.expressionString);
				}
			}
			break;
		case BPL_HITS:
			{
				if (isMemory) {
					wchar_t temp[256];
					wsprintf(temp,L"%d",displayedMemChecks_[index].numHits);
					breakpointText = temp;
				} else {
					breakpointText = L"-";
				}
			}
			break;
		case BPL_ENABLED:
			{
				if (isMemory) {
					breakpointText = displayedMemChecks_[index].result & MEMCHECK_BREAK ? L"True" : L"False";
				} else {
					breakpointText = displayedBreakPoints_[index].enabled ? L"True" : L"False";
				}
			}
			break;
		default:
			return;
		}
				
		if (breakpointText.empty())
			breakpointText = L"Invalid";
		dispInfo->item.pszText = &breakpointText[0];
	}
}
Пример #2
0
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	//if (!m_hDlg) return FALSE;
	switch(message)
	{
	case WM_INITDIALOG:
		{
			return TRUE;
		}
		break;

	case WM_TIMER:
		{
			int iPage = TabCtrl_GetCurSel (GetDlgItem(m_hDlg, IDC_LEFTTABS));
			ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
			ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST),      iPage?SW_HIDE:SW_NORMAL);
		}
		break;

	case WM_NOTIFY:
		switch (wParam)
		{
		case IDC_LEFTTABS:
			{
				HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
				NMHDR* pNotifyMessage = NULL;
				pNotifyMessage = (LPNMHDR)lParam; 		
				if (pNotifyMessage->hwndFrom == tabs)
				{
					int iPage = TabCtrl_GetCurSel (tabs);
					ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
					ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST),      iPage?SW_HIDE:SW_NORMAL);
				}
			}
			break;
		case IDC_BREAKPOINTLIST:
			handleBreakpointNotify(lParam);
			break;
		case IDC_THREADLIST:
			threadList->handleNotify(lParam);
			break;
		}
		break;
	case WM_COMMAND:
		{
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
			switch(LOWORD(wParam))
			{
			case IDC_SHOWVFPU:
				vfpudlg->Show(true);
				break;

			case IDC_FUNCTIONLIST: 
				switch (HIWORD(wParam))
				{
				case CBN_DBLCLK:
					{
						HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ListBox_GetCurSel(lb);
						if (n!=-1)
						{
							unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_GOTOINT:
				switch (HIWORD(wParam))
				{
				case LBN_SELCHANGE:
					{
						HWND lb =GetDlgItem(m_hDlg,LOWORD(wParam));
						int n = ComboBox_GetCurSel(lb);
						unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n);
						if (addr != 0xFFFFFFFF)
						{
							ptr->gotoAddr(addr);
							SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
						}
					}
					break;
				};
				break;

			case IDC_GO:
				{
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					SetDebugMode(false);
					Core_EnableStepping(false);
				}
				break;

			case IDC_STEP:
				{
					if (Core_IsActive()) break;
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					Core_DoSingleStep();		
					Sleep(1);
					_dbg_update_();
					ptr->gotoPC();
					UpdateDialog();
					vfpudlg->Update();

					CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW))->redraw();
					threadList->reloadThreads();
					updateThreadLabel(false);
				}
				break;

			case IDC_STEPOVER:
				{
					if (Core_IsActive()) break;
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					const char* dis = cpu->disasm(cpu->GetPC(),4);
					const char* pos = strstr(dis,"->$");
					const char* reg = strstr(dis,"->");
					
					ptr->setDontRedraw(true);
					u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0);
					if (memcmp(dis,"jal\t",4) == 0 || memcmp(dis,"jalr\t",5) == 0)
					{
						// it's a function call with a delay slot - skip that too
						breakpointAddress += cpu->getInstructionSize(0);
					} else if (memcmp(dis,"j\t",2) == 0 || memcmp(dis,"b\t",2) == 0)
					{
						// in case of absolute branches, set the breakpoint at the branch target
						sscanf(pos+3,"%08x",&breakpointAddress);
					} else if (memcmp(dis,"jr\t",3) == 0)
					{
						// the same for jumps to registers
						int regNum = -1;
						for (int i = 0; i < 32; i++)
						{
							if (strcasecmp(reg+2,cpu->GetRegName(0,i)) == 0)
							{
								regNum = i;
								break;
							}
						}
						if (regNum == -1) break;
						breakpointAddress = cpu->GetRegValue(0,regNum);
					} else if (pos != NULL)
					{
						// get branch target
						sscanf(pos+3,"%08x",&breakpointAddress);
						CBreakPoints::AddBreakPoint(breakpointAddress,true);

						// also add a breakpoint after the delay slot
						breakpointAddress = cpu->GetPC()+2*cpu->getInstructionSize(0);						
					}

					SetDebugMode(false);
					CBreakPoints::AddBreakPoint(breakpointAddress,true);
					_dbg_update_();
					Core_EnableStepping(false);
					Sleep(1);
					ptr->gotoAddr(breakpointAddress);
					UpdateDialog();
				}
				break;
				
			case IDC_STEPHLE:
				{
					if (Core_IsActive())
						break;
					lastTicks = CoreTiming::GetTicks();

					// If the current PC is on a breakpoint, the user doesn't want to do nothing.
					CBreakPoints::SetSkipFirst(currentMIPS->pc);

					hleDebugBreak();
					SetDebugMode(false);
					_dbg_update_();
					Core_EnableStepping(false);
				}
				break;

			case IDC_STOP:
				{				
					ptr->setDontRedraw(false);
					SetDebugMode(true);
					Core_EnableStepping(true);
					_dbg_update_();
					Sleep(1); //let cpu catch up
					ptr->gotoPC();
					UpdateDialog();
					vfpudlg->Update();
				}
				break;

			case IDC_SKIP:
				{
					cpu->SetPC(cpu->GetPC() + cpu->getInstructionSize(0));
					Sleep(1);
					ptr->gotoPC();
					UpdateDialog();
				}
				break;

			case IDC_MEMCHECK:
				{
					bool isRunning = Core_IsActive();
					if (isRunning)
					{
						SetDebugMode(true);
						Core_EnableStepping(true);
						Core_WaitInactive(200);
					}

					BreakpointWindow bpw(m_hDlg,cpu);
					if (bpw.exec()) bpw.addBreakpoint();

					if (isRunning)
					{
						SetDebugMode(false);
						Core_EnableStepping(false);
					}
				}
				break;
			case IDC_UPDATECALLSTACK:
				{
					HWND hDlg = m_hDlg;
					HWND list = GetDlgItem(hDlg,IDC_CALLSTACK);
					ComboBox_ResetContent(list);
					
					u32 pc = currentMIPS->pc;
					u32 ra = currentMIPS->r[MIPS_REG_RA];
					DWORD addr = Memory::ReadUnchecked_U32(pc);
					int count=1;
					ComboBox_SetItemData(list,ComboBox_AddString(list,symbolMap.GetDescription(pc)),pc);
					if (symbolMap.GetDescription(pc) != symbolMap.GetDescription(ra))
					{
						ComboBox_SetItemData(list,ComboBox_AddString(list,symbolMap.GetDescription(ra)),ra);
						count++;
					}
					//walk the stack chain
					while (addr != 0xFFFFFFFF && addr!=0 && count++<20)
					{
						DWORD fun = Memory::ReadUnchecked_U32(addr+4);
						const char *str = symbolMap.GetDescription(fun);
						if (strlen(str)==0)
							str = "(unknown)";
						ComboBox_SetItemData(list, ComboBox_AddString(list,str), fun);
						addr = Memory::ReadUnchecked_U32(addr);
					}
					ComboBox_SetCurSel(list,0);
				}
				break;

			case IDC_GOTOPC:
				{
					ptr->gotoPC();	
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
					UpdateDialog();
				}
				break;
			case IDC_GOTOLR:
				{
					ptr->gotoAddr(cpu->GetLR());
					SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
				}
				break;

			case IDC_BACKWARDLINKS:
				{
					HWND box = GetDlgItem(m_hDlg, IDC_FUNCTIONLIST); 
					int funcnum = symbolMap.GetSymbolNum(ListBox_GetItemData(box,ListBox_GetCurSel(box)));
					if (funcnum!=-1)
						symbolMap.FillListBoxBLinks(box,funcnum);
					break;
				}

			case IDC_ALLFUNCTIONS:
				{
					symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION);
					break;
				}
			default:
				return FALSE;
			}
			return TRUE;
		}

	case WM_DEB_MAPLOADED:
		NotifyMapLoaded();
		break;
	case WM_DEB_RUNTOWPARAM:
	{
		lastTicks = CoreTiming::GetTicks();
		CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		ptr->setDontRedraw(true);
		SetDebugMode(false);
		CBreakPoints::AddBreakPoint(wParam,true);
		_dbg_update_();
		Core_EnableStepping(false);
		break;
	}
	case WM_DEB_GOTOWPARAM:
	{
		CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		ptr->gotoAddr(wParam);
		SetFocus(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
		break;
	}
	case WM_DEB_GOTOBREAKPOINT:
		gotoBreakpointAddress(wParam);
		break;
	case WM_DEB_REMOVEBREAKPOINT:
		removeBreakpoint(wParam);
		break;
	case WM_DEB_GOTOADDRESSEDIT:
		{
			char szBuffer[256];
			CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
			GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),szBuffer,256);

			u32 addr;
			if (parseExpression(szBuffer,cpu,addr) == false)
			{
				displayExpressionError(GetDlgItem(m_hDlg,IDC_ADDRESS));
			} else {
				ptr->gotoAddr(addr);
				SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
			}
			UpdateDialog();
		}
		break;

	case WM_DEB_SETDEBUGLPARAM:
		SetDebugMode(lParam != 0);
		return TRUE;

	case WM_DEB_UPDATE:
		Update();
		return TRUE;

	case WM_DEB_TABPRESSED:
		{
			HWND bp = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
			HWND mem = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW);
			HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST);
			
			if (IsWindowVisible(bp))
			{
				ShowWindow(bp,SW_HIDE);
				ShowWindow(mem,SW_HIDE);
				ShowWindow(threads,SW_NORMAL);
				SetFocus(threads);
			} else if (IsWindowVisible(threads))
			{
				ShowWindow(bp,SW_HIDE);
				ShowWindow(mem,SW_NORMAL);
				ShowWindow(threads,SW_HIDE);
				SetFocus(mem);
			} else {
				ShowWindow(bp,SW_NORMAL);
				ShowWindow(mem,SW_HIDE);
				ShowWindow(threads,SW_HIDE);
				SetFocus(bp);
			}
		}
		break;
	case WM_SIZE:
		{
			UpdateSize(LOWORD(lParam), HIWORD(lParam));
			SavePosition();
			return TRUE;
		}

	case WM_MOVE:
		SavePosition();
		break;
	case WM_GETMINMAXINFO:
		{
			MINMAXINFO *m = (MINMAXINFO *)lParam;
			// Reduce the minimum size slightly, so they can size it however they like.
			m->ptMinTrackSize.x = defaultRect.right - defaultRect.left - 100;
			//m->ptMaxTrackSize.x = m->ptMinTrackSize.x;
			m->ptMinTrackSize.y = defaultRect.bottom - defaultRect.top - 200;
		}
		return TRUE;
	case WM_CLOSE:
		Show(false);
		return TRUE;
	}
	return FALSE;
}
Пример #3
0
void CtrlBreakpointList::OnDoubleClick(int itemIndex, int column)
{
	gotoBreakpointAddress(itemIndex);
}
Пример #4
0
void CDisasm::handleBreakpointNotify(LPARAM lParam)
{
	if (((LPNMHDR)lParam)->code == NM_DBLCLK)
	{
		LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
		gotoBreakpointAddress(item->iItem);
		return;
	}

	if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
	{
		NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
		
		bool isMemory;
		int index = getBreakpointIndex(dispInfo->item.iItem,isMemory);
		if (index == -1) return;
		
		breakpointText[0] = 0;
		switch (dispInfo->item.iSubItem)
		{
		case BPL_TYPE:
			{
				if (isMemory)
				{
					switch (displayedMemChecks_[index].cond)
					{
					case MEMCHECK_READ:
						strcpy(breakpointText, "Read");
						break;
					case MEMCHECK_WRITE:
						strcpy(breakpointText, "Write");
						break;
					case MEMCHECK_READWRITE:
						strcpy(breakpointText, "Read/Write");
						break;
					}
				} else {
					strcpy(breakpointText,"Execute");
				}
			}
			break;
		case BPL_OFFSET:
			{
				if (isMemory)
				{
					sprintf(breakpointText,"0x%08X",displayedMemChecks_[index].start);
				} else {
					sprintf(breakpointText,"0x%08X",displayedBreakPoints_[index].addr);
				}
			}
			break;
		case BPL_SIZELABEL:
			{
				if (isMemory)
				{
					auto mc = displayedMemChecks_[index];
					if (mc.end == 0) sprintf(breakpointText,"0x%08X",1);
					else sprintf(breakpointText,"0x%08X",mc.end-mc.start);
				} else {
					const char* sym = cpu->findSymbolForAddress(displayedBreakPoints_[index].addr);
					if (sym != NULL)
					{
						strcpy(breakpointText,sym);
					} else {
						strcpy(breakpointText,"-");
					}
				}
			}
			break;
		case BPL_OPCODE:
			{
				if (isMemory)
				{
					strcpy(breakpointText,"-");
				} else {
					CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
					ptr->getOpcodeText(displayedBreakPoints_[index].addr,breakpointText);
				}
			}
			break;
		case BPL_HITS:
			{
				if (isMemory)
				{
					sprintf(breakpointText,"%d",displayedMemChecks_[index].numHits);
				} else {
					strcpy(breakpointText,"-");
				}
			}
			break;
		case BPL_ENABLED:
			{
				if (isMemory)
				{
					strcpy(breakpointText,displayedMemChecks_[index].result & MEMCHECK_BREAK ? "True" : "False");
				} else {
					strcpy(breakpointText,displayedBreakPoints_[index].enabled ? "True" : "False");
				}
			}
			break;
		default:
			return;
		}
				
		if (breakpointText[0] == 0) strcat(breakpointText,"Invalid");
		dispInfo->item.pszText = breakpointText;
	}
}