CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Windows/Debugger/BreakpointWindow.cpp
Views: 1401
#include <cstdio>12#include "Common/Data/Encoding/Utf8.h"3#include "Common/Math/expression_parser.h"45#include "BreakpointWindow.h"6#include "../resource.h"78INT_PTR CALLBACK BreakpointWindow::StaticDlgFunc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {9BreakpointWindow *thiz;10if (iMsg == WM_INITDIALOG) {11SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)lParam);12thiz = (BreakpointWindow *)lParam;13}14else {15thiz = (BreakpointWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);16}1718if (!thiz)19return FALSE;20return thiz->DlgFunc(hWnd, iMsg, wParam, lParam);21}2223INT_PTR BreakpointWindow::DlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)24{25char str[128];2627switch (iMsg)28{29case WM_INITDIALOG:30SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_EXECUTE), BM_SETCHECK, memory ? BST_UNCHECKED : BST_CHECKED, 0);31SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_MEMORY), BM_SETCHECK, memory ? BST_CHECKED : BST_UNCHECKED, 0);32SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_READ), BM_SETCHECK, read ? BST_CHECKED : BST_UNCHECKED, 0);33SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_WRITE), BM_SETCHECK, write ? BST_CHECKED : BST_UNCHECKED, 0);34SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_ONCHANGE), BM_SETCHECK, onChange ? BST_CHECKED : BST_UNCHECKED, 0);35SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_ENABLED), BM_SETCHECK, enabled ? BST_CHECKED : BST_UNCHECKED, 0);36SendMessage(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG), BM_SETCHECK, log ? BST_CHECKED : BST_UNCHECKED, 0);3738EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_READ), memory);39EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_WRITE), memory);40EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_ONCHANGE), memory);41EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE), memory);42EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), log);4344if (address != -1) {45snprintf(str, sizeof(str), "0x%08X", address);46SetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_ADDRESS), str);47}4849snprintf(str, sizeof(str), "0x%08X", size);50SetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE), str);5152SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), ConvertUTF8ToWString(condition).c_str());53SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), ConvertUTF8ToWString(logFormat).c_str());54return TRUE;55case WM_COMMAND:56switch (LOWORD(wParam))57{58case IDC_BREAKPOINT_EXECUTE:59switch (HIWORD(wParam))60{61case BN_CLICKED:62memory = false;63EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_READ), memory);64EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_WRITE), memory);65EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_ONCHANGE), memory);66EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE), memory);67break;68}69break;70case IDC_BREAKPOINT_MEMORY:71switch (HIWORD(wParam))72{73case BN_CLICKED:74memory = true;75EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_READ), memory);76EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_WRITE), memory);77EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_ONCHANGE), memory);78EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE), memory);79break;80}81break;82case IDC_BREAKPOINT_LOG:83switch (HIWORD(wParam))84{85case BN_CLICKED:86EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), GetCheckState(hwnd, IDC_BREAKPOINT_LOG));87break;88}89break;90case IDC_BREAKPOINT_OK:91switch (HIWORD(wParam))92{93case BN_CLICKED:94if (fetchDialogData(hwnd)) {95EndDialog(hwnd, true);96}97break;98};99break;100case IDC_BREAKPOINT_CANCEL:101switch (HIWORD(wParam))102{103case BN_CLICKED:104EndDialog(hwnd, false);105break;106};107break;108case IDOK:109if (fetchDialogData(hwnd)) {110EndDialog(hwnd, true);111}112break;113case IDCANCEL:114EndDialog(hwnd, false);115break;116}117}118119return FALSE;120}121122bool BreakpointWindow::fetchDialogData(HWND hwnd)123{124char str[256], errorMessage[512];125PostfixExpression exp;126127memory = GetCheckState(hwnd, IDC_BREAKPOINT_MEMORY);128read = GetCheckState(hwnd, IDC_BREAKPOINT_READ);129write = GetCheckState(hwnd, IDC_BREAKPOINT_WRITE);130enabled = GetCheckState(hwnd, IDC_BREAKPOINT_ENABLED);131log = GetCheckState(hwnd, IDC_BREAKPOINT_LOG);132onChange = GetCheckState(hwnd, IDC_BREAKPOINT_ONCHANGE);133134// parse address135GetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_ADDRESS), str, 256);136if (cpu->initExpression(str, exp) == false)137{138snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError());139MessageBoxA(hwnd, errorMessage, "Error", MB_OK);140return false;141}142143if (cpu->parseExpression(exp, address) == false)144{145snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError());146MessageBoxA(hwnd, errorMessage, "Error", MB_OK);147return false;148}149150if (memory)151{152// parse size153GetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE), str, 256);154if (cpu->initExpression(str, exp) == false)155{156snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError());157MessageBoxA(hwnd, errorMessage, "Error", MB_OK);158return false;159}160161if (cpu->parseExpression(exp, size) == false)162{163snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError());164MessageBoxA(hwnd, errorMessage, "Error", MB_OK);165return false;166}167}168169// condition170wchar_t tempCond[512];171GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), tempCond, 512);172condition = ConvertWStringToUTF8(tempCond);173compiledCondition.clear();174if (!condition.empty())175{176if (cpu->initExpression(condition.c_str(), compiledCondition) == false)177{178snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", condition.c_str(), getExpressionError());179MessageBoxA(hwnd, errorMessage, "Error", MB_OK);180return false;181}182}183184wchar_t tempLogFormat[512];185GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), tempLogFormat, 512);186logFormat = ConvertWStringToUTF8(tempLogFormat);187if (!CBreakPoints::ValidateLogFormat(cpu, logFormat)) {188snprintf(errorMessage, sizeof(errorMessage), "Invalid log format (example: \"{a1}\").");189MessageBoxA(hwnd, errorMessage, "Error", MB_OK);190return false;191}192193return true;194}195196bool BreakpointWindow::GetCheckState(HWND hwnd, int dlgItem) {197return SendMessage(GetDlgItem(hwnd, dlgItem), BM_GETCHECK, 0, 0) != 0;198}199200bool BreakpointWindow::exec() {201return DialogBoxParam(GetModuleHandle(0), MAKEINTRESOURCE(IDD_BREAKPOINT), parentHwnd, StaticDlgFunc, (LPARAM)this) != 0;202}203204void BreakpointWindow::addBreakpoint() {205BreakAction result = BREAK_ACTION_IGNORE;206if (log)207result |= BREAK_ACTION_LOG;208if (enabled)209result |= BREAK_ACTION_PAUSE;210211if (memory) {212// add memcheck213int cond = 0;214if (read)215cond |= MEMCHECK_READ;216if (write)217cond |= MEMCHECK_WRITE;218if (onChange)219cond |= MEMCHECK_WRITE_ONCHANGE;220221CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, result);222223if (!condition.empty()) {224BreakPointCond cond;225cond.debug = cpu;226cond.expressionString = condition;227cond.expression = compiledCondition;228CBreakPoints::ChangeMemCheckAddCond(address, address + size, cond);229}230231CBreakPoints::ChangeMemCheckLogFormat(address, address + size, logFormat);232}233else {234// add breakpoint235CBreakPoints::AddBreakPoint(address, false);236237if (!condition.empty()) {238BreakPointCond cond;239cond.debug = cpu;240cond.expressionString = condition;241cond.expression = compiledCondition;242CBreakPoints::ChangeBreakPointAddCond(address, cond);243}244245CBreakPoints::ChangeBreakPoint(address, result);246CBreakPoints::ChangeBreakPointLogFormat(address, logFormat);247}248}249250void BreakpointWindow::loadFromMemcheck(const MemCheck &memcheck) {251memory = true;252253read = (memcheck.cond & MEMCHECK_READ) != 0;254write = (memcheck.cond & MEMCHECK_WRITE) != 0;255onChange = (memcheck.cond & MEMCHECK_WRITE_ONCHANGE) != 0;256257log = (memcheck.result & BREAK_ACTION_LOG) != 0;258enabled = (memcheck.result & BREAK_ACTION_PAUSE) != 0;259260address = memcheck.start;261size = memcheck.end - address;262263if (memcheck.hasCondition) {264condition = memcheck.condition.expressionString;265}266else {267condition.clear();268}269270logFormat = memcheck.logFormat;271}272273void BreakpointWindow::loadFromBreakpoint(const BreakPoint& breakpoint) {274memory = false;275276log = (breakpoint.result & BREAK_ACTION_LOG) != 0;277enabled = (breakpoint.result & BREAK_ACTION_PAUSE) != 0;278address = breakpoint.addr;279size = 1;280281if (breakpoint.hasCond) {282condition = breakpoint.cond.expressionString;283}284else {285condition.clear();286}287288logFormat = breakpoint.logFormat;289}290291void BreakpointWindow::initBreakpoint(u32 _address) {292memory = false;293enabled = true;294address = _address;295size = 1;296condition.clear();297}298299300