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/Debugger/Breakpoints.h
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#pragma once1819#include <vector>2021#include "Core/Debugger/DebugInterface.h"2223enum BreakAction {24BREAK_ACTION_IGNORE = 0x00,25BREAK_ACTION_LOG = 0x01,26BREAK_ACTION_PAUSE = 0x02,27};2829static inline BreakAction &operator |= (BreakAction &lhs, const BreakAction &rhs) {30lhs = BreakAction(lhs | rhs);31return lhs;32}3334static inline BreakAction operator | (const BreakAction &lhs, const BreakAction &rhs) {35return BreakAction((u32)lhs | (u32)rhs);36}3738struct BreakPointCond {39DebugInterface *debug = nullptr;40PostfixExpression expression;41std::string expressionString;4243u32 Evaluate() {44u32 result;45if (debug->parseExpression(expression, result) == false)46return 0;47return result;48}49};5051struct BreakPoint {52u32 addr;53bool temporary;5455BreakAction result = BREAK_ACTION_IGNORE;56std::string logFormat;5758bool hasCond = false;59BreakPointCond cond;6061bool IsEnabled() const {62return (result & BREAK_ACTION_PAUSE) != 0;63}6465bool operator == (const BreakPoint &other) const {66return addr == other.addr;67}68bool operator < (const BreakPoint &other) const {69return addr < other.addr;70}71};7273enum MemCheckCondition {74MEMCHECK_READ = 0x01,75MEMCHECK_WRITE = 0x02,76MEMCHECK_WRITE_ONCHANGE = 0x04,7778MEMCHECK_READWRITE = 0x03,79};8081struct MemCheck {82u32 start;83u32 end;8485MemCheckCondition cond = MEMCHECK_READ;86BreakAction result = BREAK_ACTION_IGNORE;87std::string logFormat;8889bool hasCondition = false;90BreakPointCond condition;9192u32 numHits = 0;9394u32 lastPC = 0;95u32 lastAddr = 0;96int lastSize = 0;9798// Called on the stored memcheck (affects numHits, etc.)99BreakAction Apply(u32 addr, bool write, int size, u32 pc);100// Called on a copy.101BreakAction Action(u32 addr, bool write, int size, u32 pc, const char *reason);102103void Log(u32 addr, bool write, int size, u32 pc, const char *reason);104105bool IsEnabled() const {106return (result & BREAK_ACTION_PAUSE) != 0;107}108109bool operator == (const MemCheck &other) const {110return start == other.start && end == other.end;111}112};113114// BreakPoints cannot overlap, only one is allowed per address.115// MemChecks can overlap, as long as their ends are different.116// WARNING: MemChecks are not always tracked in HLE currently.117class CBreakPoints118{119public:120static const size_t INVALID_BREAKPOINT = -1;121static const size_t INVALID_MEMCHECK = -1;122123static bool IsAddressBreakPoint(u32 addr);124static bool IsAddressBreakPoint(u32 addr, bool* enabled);125static bool IsTempBreakPoint(u32 addr);126static bool RangeContainsBreakPoint(u32 addr, u32 size);127static void AddBreakPoint(u32 addr, bool temp = false);128static void RemoveBreakPoint(u32 addr);129static void ChangeBreakPoint(u32 addr, bool enable);130static void ChangeBreakPoint(u32 addr, BreakAction result);131static void ClearAllBreakPoints();132static void ClearTemporaryBreakPoints();133134// Makes a copy of the condition.135static void ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond);136static void ChangeBreakPointRemoveCond(u32 addr);137static BreakPointCond *GetBreakPointCondition(u32 addr);138139static void ChangeBreakPointLogFormat(u32 addr, const std::string &fmt);140141static BreakAction ExecBreakPoint(u32 addr);142143static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);144static void RemoveMemCheck(u32 start, u32 end);145static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);146static void ClearAllMemChecks();147148static void ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond);149static void ChangeMemCheckRemoveCond(u32 start, u32 end);150static BreakPointCond *GetMemCheckCondition(u32 start, u32 end);151152static void ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt);153154static bool GetMemCheck(u32 start, u32 end, MemCheck *check);155static bool GetMemCheckInRange(u32 address, int size, MemCheck *check);156static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason);157static BreakAction ExecOpMemCheck(u32 address, u32 pc);158159static void SetSkipFirst(u32 pc);160static u32 CheckSkipFirst();161162// Includes uncached addresses.163static std::vector<MemCheck> GetMemCheckRanges(bool write);164165static std::vector<MemCheck> GetMemChecks();166static std::vector<BreakPoint> GetBreakpoints();167168static bool HasBreakPoints();169static bool HasMemChecks();170171static void Update(u32 addr = 0);172173static bool ValidateLogFormat(DebugInterface *cpu, const std::string &fmt);174static bool EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result);175176private:177static size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false);178// Finds exactly, not using a range check.179static size_t FindMemCheck(u32 start, u32 end);180static MemCheck *GetMemCheckLocked(u32 address, int size);181static void UpdateCachedMemCheckRanges();182183static std::vector<BreakPoint> breakPoints_;184static u32 breakSkipFirstAt_;185static u64 breakSkipFirstTicks_;186187static std::vector<MemCheck> memChecks_;188static std::vector<MemCheck> memCheckRangesRead_;189static std::vector<MemCheck> memCheckRangesWrite_;190};191192193194195