/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2013 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_DEBUG_DEBUGGER_H_ #define XENIA_DEBUG_DEBUGGER_H_ #include #include #include #include #include #include "xenia/base/delegate.h" #include "xenia/base/mapped_memory.h" #include "xenia/cpu/thread_state.h" #include "xenia/debug/breakpoint.h" namespace xe { namespace cpu { class Function; class FunctionInfo; class Processor; } // namespace cpu } // namespace xe namespace xe { namespace debug { class Debugger; class DebugEvent { public: DebugEvent(Debugger* debugger) : debugger_(debugger) {} virtual ~DebugEvent() = default; Debugger* debugger() const { return debugger_; } protected: Debugger* debugger_; }; class BreakpointHitEvent : public DebugEvent { public: BreakpointHitEvent(Debugger* debugger, cpu::ThreadState* thread_state, Breakpoint* breakpoint) : DebugEvent(debugger), thread_state_(thread_state), breakpoint_(breakpoint) {} ~BreakpointHitEvent() override = default; cpu::ThreadState* thread_state() const { return thread_state_; } Breakpoint* breakpoint() const { return breakpoint_; } protected: cpu::ThreadState* thread_state_; Breakpoint* breakpoint_; }; class Debugger { public: Debugger(cpu::Processor* processor); ~Debugger(); cpu::Processor* processor() const { return processor_; } bool StartSession(); void StopSession(); void FlushSession(); uint8_t* AllocateTraceFunctionData(size_t size); int SuspendAllThreads(uint32_t timeout_ms = UINT_MAX); int ResumeThread(uint32_t thread_id); int ResumeAllThreads(bool force = false); void ForEachThread(std::function callback); int AddBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint); void FindBreakpoints(uint32_t address, std::vector& out_breakpoints); // TODO(benvanik): utility functions for modification (make function ignored, // etc). void OnThreadCreated(cpu::ThreadState* thread_state); void OnThreadDestroyed(cpu::ThreadState* thread_state); void OnFunctionDefined(cpu::FunctionInfo* symbol_info, cpu::Function* function); void OnBreakpointHit(cpu::ThreadState* thread_state, Breakpoint* breakpoint); public: Delegate breakpoint_hit; private: cpu::Processor* processor_; std::unique_ptr trace_functions_; std::mutex threads_lock_; std::unordered_map threads_; std::mutex breakpoints_lock_; std::multimap breakpoints_; }; } // namespace debug } // namespace xe #endif // XENIA_DEBUG_DEBUGGER_H_