/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2015 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_CPU_STACK_WALKER_H_ #define XENIA_CPU_STACK_WALKER_H_ #include #include #include "xenia/base/x64_context.h" #include "xenia/cpu/function.h" namespace xe { namespace cpu { namespace backend { class CodeCache; } // namespace backend } // namespace cpu } // namespace xe namespace xe { namespace cpu { struct StackFrame { enum class Type { // Host frame, likely in kernel or emulator code. kHost, // Guest frame, somewhere in PPC code. kGuest, }; Type type; // Always valid, indicating the address in a backend-defined range. uint64_t host_pc; // Only valid for kGuest frames, indicating the PPC address. uint32_t guest_pc; union { // Contains symbol information for kHost frames. struct { // TODO(benvanik): better name, displacement, etc. uint64_t address; char name[256]; } host_symbol; // Contains symbol information for kGuest frames. struct { Function* function; } guest_symbol; }; }; class StackWalker { public: // Creates a stack walker. Only one should exist within a process. // May fail if another process has mucked with ours (like RenderDoc). static std::unique_ptr Create(backend::CodeCache* code_cache); // Dumps all thread stacks to the log. void Dump(); // Captures up to the given number of stack frames from the current thread. // Use ResolveStackTrace to populate additional information. // Returns the number of frames captured, or 0 if an error occurred. // Optionally provides a hash value for the stack that can be used for // deduping. virtual size_t CaptureStackTrace(uint64_t* frame_host_pcs, size_t frame_offset, size_t frame_count, uint64_t* out_stack_hash = nullptr) = 0; // Captures up to the given number of stack frames from the given thread, // referenced by native thread handle. The thread must be suspended. // This does not populate any information other than host_pc. // Use ResolveStackTrace to populate additional information. // Returns the number of frames captured, or 0 if an error occurred. // Optionally provides a hash value for the stack that can be used for // deduping. virtual size_t CaptureStackTrace(void* thread_handle, uint64_t* frame_host_pcs, size_t frame_offset, size_t frame_count, const X64Context* in_host_context, X64Context* out_host_context, uint64_t* out_stack_hash = nullptr) = 0; // Resolves symbol information for the given stack frames. // Each frame provided must have host_pc set, and all other fields will be // populated. virtual bool ResolveStack(uint64_t* frame_host_pcs, StackFrame* frames, size_t frame_count) = 0; }; } // namespace cpu } // namespace xe #endif // XENIA_CPU_STACK_WALKER_H_