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/Core/MIPS/MIPSDebugInterface.cpp
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include <string>18#include <cstring>1920#ifndef _MSC_VER21#include <strings.h>22#endif2324#include "Common/StringUtils.h"25#include "Core/CoreTiming.h"26#include "Core/Debugger/Breakpoints.h"27#include "Core/Debugger/SymbolMap.h"28#include "Core/Debugger/DebugInterface.h"29#include "Core/MIPS/MIPSDebugInterface.h"30#include "Core/MIPS/MIPSVFPUUtils.h"31#include "Core/HLE/sceKernelThread.h"32#include "Core/MemMap.h"33#include "Core/MIPS/MIPSTables.h"34#include "Core/MIPS/MIPS.h"35#include "Core/System.h"3637enum ReferenceIndexType {38REF_INDEX_PC = 32,39REF_INDEX_HI = 33,40REF_INDEX_LO = 34,41REF_INDEX_FPU = 0x1000,42REF_INDEX_FPU_INT = 0x2000,43REF_INDEX_VFPU = 0x4000,44REF_INDEX_VFPU_INT = 0x8000,45REF_INDEX_IS_FLOAT = REF_INDEX_FPU | REF_INDEX_VFPU,46REF_INDEX_HLE = 0x10000,47REF_INDEX_THREAD = REF_INDEX_HLE | 0,48REF_INDEX_MODULE = REF_INDEX_HLE | 1,49REF_INDEX_USEC = REF_INDEX_HLE | 2,50REF_INDEX_TICKS = REF_INDEX_HLE | 3,51};525354class MipsExpressionFunctions: public IExpressionFunctions55{56public:57MipsExpressionFunctions(DebugInterface* cpu): cpu(cpu) { }5859bool parseReference(char* str, uint32_t& referenceIndex) override60{61for (int i = 0; i < 32; i++)62{63char reg[8];64snprintf(reg, sizeof(reg), "r%d", i);6566if (strcasecmp(str, reg) == 0 || strcasecmp(str, cpu->GetRegName(0, i).c_str()) == 0)67{68referenceIndex = i;69return true;70}71else if (strcasecmp(str, cpu->GetRegName(1, i).c_str()) == 0)72{73referenceIndex = REF_INDEX_FPU | i;74return true;75}7677snprintf(reg, sizeof(reg), "fi%d", i);78if (strcasecmp(str, reg) == 0)79{80referenceIndex = REF_INDEX_FPU_INT | i;81return true;82}83}8485for (int i = 0; i < 128; i++)86{87if (strcasecmp(str, cpu->GetRegName(2, i).c_str()) == 0)88{89referenceIndex = REF_INDEX_VFPU | i;90return true;91}9293char reg[8];94snprintf(reg, sizeof(reg), "vi%d", i);95if (strcasecmp(str, reg) == 0)96{97referenceIndex = REF_INDEX_VFPU_INT | i;98return true;99}100}101102if (strcasecmp(str, "pc") == 0)103{104referenceIndex = REF_INDEX_PC;105return true;106}107108if (strcasecmp(str, "hi") == 0)109{110referenceIndex = REF_INDEX_HI;111return true;112}113114if (strcasecmp(str, "lo") == 0)115{116referenceIndex = REF_INDEX_LO;117return true;118}119120if (strcasecmp(str, "threadid") == 0) {121referenceIndex = REF_INDEX_THREAD;122return true;123}124if (strcasecmp(str, "moduleid") == 0) {125referenceIndex = REF_INDEX_MODULE;126return true;127}128if (strcasecmp(str, "usec") == 0) {129referenceIndex = REF_INDEX_USEC;130return true;131}132if (strcasecmp(str, "ticks") == 0) {133referenceIndex = REF_INDEX_TICKS;134return true;135}136137return false;138}139140bool parseSymbol(char* str, uint32_t& symbolValue) override141{142return g_symbolMap->GetLabelValue(str,symbolValue);143}144145uint32_t getReferenceValue(uint32_t referenceIndex) override146{147if (referenceIndex < 32)148return cpu->GetRegValue(0, referenceIndex);149if (referenceIndex == REF_INDEX_PC)150return cpu->GetPC();151if (referenceIndex == REF_INDEX_HI)152return cpu->GetHi();153if (referenceIndex == REF_INDEX_LO)154return cpu->GetLo();155if (referenceIndex == REF_INDEX_THREAD)156return __KernelGetCurThread();157if (referenceIndex == REF_INDEX_MODULE)158return __KernelGetCurThreadModuleId();159if (referenceIndex == REF_INDEX_USEC)160return (uint32_t)CoreTiming::GetGlobalTimeUs(); // Loses information161if (referenceIndex == REF_INDEX_TICKS)162return (uint32_t)CoreTiming::GetTicks();163if ((referenceIndex & ~(REF_INDEX_FPU | REF_INDEX_FPU_INT)) < 32)164return cpu->GetRegValue(1, referenceIndex & ~(REF_INDEX_FPU | REF_INDEX_FPU_INT));165if ((referenceIndex & ~(REF_INDEX_VFPU | REF_INDEX_VFPU_INT)) < 128)166return cpu->GetRegValue(2, referenceIndex & ~(REF_INDEX_VFPU | REF_INDEX_VFPU_INT));167return -1;168}169170ExpressionType getReferenceType(uint32_t referenceIndex) override {171if (referenceIndex & REF_INDEX_IS_FLOAT) {172return EXPR_TYPE_FLOAT;173}174return EXPR_TYPE_UINT;175}176177bool getMemoryValue(uint32_t address, int size, uint32_t& dest, std::string *error) override {178// We allow, but ignore, bad access.179// If we didn't, log/condition statements that reference registers couldn't be configured.180uint32_t valid = Memory::ValidSize(address, size);181uint8_t buf[4]{};182if (valid != 0)183memcpy(buf, Memory::GetPointerUnchecked(address), valid);184185switch (size) {186case 1:187dest = buf[0];188return true;189case 2:190dest = (buf[1] << 8) | buf[0];191return true;192case 4:193dest = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];194return true;195}196197*error = StringFromFormat("Unexpected memory access size %d", size);198return false;199}200201private:202DebugInterface* cpu;203};204205206207void MIPSDebugInterface::DisAsm(u32 pc, char *out, size_t outSize) {208if (Memory::IsValidAddress(pc))209MIPSDisAsm(Memory::Read_Opcode_JIT(pc), pc, out, outSize);210else211truncate_cpy(out, outSize, "-");212}213214unsigned int MIPSDebugInterface::readMemory(unsigned int address) {215if (Memory::IsValidRange(address, 4))216return Memory::ReadUnchecked_Instruction(address).encoding;217return 0;218}219220bool MIPSDebugInterface::isAlive()221{222return PSP_IsInited() && coreState != CORE_BOOT_ERROR && coreState != CORE_RUNTIME_ERROR && coreState != CORE_POWERDOWN;223}224225bool MIPSDebugInterface::isBreakpoint(unsigned int address)226{227return CBreakPoints::IsAddressBreakPoint(address);228}229230void MIPSDebugInterface::setBreakpoint(unsigned int address)231{232CBreakPoints::AddBreakPoint(address);233}234void MIPSDebugInterface::clearBreakpoint(unsigned int address)235{236CBreakPoints::RemoveBreakPoint(address);237}238void MIPSDebugInterface::clearAllBreakpoints() {}239void MIPSDebugInterface::toggleBreakpoint(unsigned int address)240{241CBreakPoints::IsAddressBreakPoint(address)?CBreakPoints::RemoveBreakPoint(address):CBreakPoints::AddBreakPoint(address);242}243244245int MIPSDebugInterface::getColor(unsigned int address)246{247int colors[6] = {0xe0FFFF,0xFFe0e0,0xe8e8FF,0xFFe0FF,0xe0FFe0,0xFFFFe0};248int n=g_symbolMap->GetFunctionNum(address);249if (n==-1) return 0xFFFFFF;250return colors[n%6];251}252std::string MIPSDebugInterface::getDescription(unsigned int address)253{254return g_symbolMap->GetDescription(address);255}256257bool MIPSDebugInterface::initExpression(const char* exp, PostfixExpression& dest)258{259MipsExpressionFunctions funcs(this);260return initPostfixExpression(exp,&funcs,dest);261}262263bool MIPSDebugInterface::parseExpression(PostfixExpression& exp, u32& dest)264{265MipsExpressionFunctions funcs(this);266return parsePostfixExpression(exp,&funcs,dest);267}268269void MIPSDebugInterface::runToBreakpoint()270{271272}273274const char *MIPSDebugInterface::GetName()275{276return ("R4");277}278279std::string MIPSDebugInterface::GetRegName(int cat, int index) {280static const char * const regName[32] = {281"zero", "at", "v0", "v1",282"a0", "a1", "a2", "a3",283"t0", "t1", "t2", "t3",284"t4", "t5", "t6", "t7",285"s0", "s1", "s2", "s3",286"s4", "s5", "s6", "s7",287"t8", "t9", "k0", "k1",288"gp", "sp", "fp", "ra"289};290static const char * const fpRegName[32] = {291"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",292"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",293"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",294"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",295};296297if (cat == 0 && (unsigned)index < sizeof(regName)) {298return regName[index];299} else if (cat == 1 && (unsigned)index < sizeof(fpRegName)) {300return fpRegName[index];301} else if (cat == 2) {302return GetVectorNotation(index, V_Single);303}304return "???";305}306307308309