/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2016 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_CPU_THREAD_DEBUG_INFO_H_ #define XENIA_CPU_THREAD_DEBUG_INFO_H_ #include #include "xenia/base/x64_context.h" #include "xenia/cpu/thread.h" #include "xenia/cpu/thread_state.h" namespace xe { namespace cpu { class Breakpoint; class Function; // Per-thread structure holding debugger state and a cache of the sampled call // stack. // // In most cases debug consumers should rely only on data in this structure as // it is never removed (even when a thread is destroyed) and always available // even when running. struct ThreadDebugInfo { ThreadDebugInfo() = default; ~ThreadDebugInfo() = default; enum class State { // Thread is alive and running. kAlive, // Thread is in a wait state. kWaiting, // Thread has exited but not yet been killed. kExited, // Thread has been killed. kZombie, }; // XThread::thread_id(), unique to the thread for the run of the emulator. uint32_t thread_id = 0; // XThread::handle() of the thread. // This will be invalidated when the thread dies. uint32_t thread_handle = 0; // Thread object. Only valid when the thread is alive. Thread* thread = nullptr; // Current state of the thread. State state = State::kAlive; // Whether the debugger has forcefully suspended this thread. bool suspended = false; // A breakpoint managed by the stepping system, installed as required to // trigger a break at the next instruction. std::unique_ptr step_breakpoint; // A breakpoint managed by the stepping system, installed as required to // trigger after a step over a disabled breakpoint. // When this breakpoint is hit the breakpoint referenced in // restore_original_breakpoint will be reinstalled. // Breakpoint restore_step_breakpoint; // If the thread is stepping over a disabled breakpoint this will point to // that breakpoint so it can be restored. // Breakpoint* restore_original_breakpoint = nullptr; // Last-sampled PPC context. // This is updated whenever the debugger stops. ppc::PPCContext guest_context; // Last-sampled host x64 context. // This is updated whenever the debugger stops and must be used instead of any // value taken from the StackWalker as it properly respects exception stacks. X64Context host_context; // A single frame in a call stack. struct Frame { // PC of the current instruction in host code. uint64_t host_pc = 0; // Base of the function the current host_pc is located within. uint64_t host_function_address = 0; // PC of the current instruction in guest code. // 0 if not a guest address or not known. uint32_t guest_pc = 0; // Base of the function the current guest_pc is located within. uint32_t guest_function_address = 0; // Function the current guest_pc is located within. Function* guest_function = nullptr; // Name of the function, if known. // TODO(benvanik): string table? char name[256] = {0}; }; // Last-sampled call stack. // This is updated whenever the debugger stops. std::vector frames; }; } // namespace cpu } // namespace xe #endif // XENIA_CPU_THREAD_DEBUG_INFO_H_