1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

PPU: correct behaviour under external debugger

May require setting "Assume External Debugger" to true.
This commit is contained in:
Nekotekina 2022-03-25 20:51:55 +03:00
parent e66d6a9399
commit 0a617a05d0
3 changed files with 25 additions and 6 deletions

View File

@ -189,6 +189,13 @@ bool IsDebuggerPresent()
} }
#endif #endif
bool is_debugger_present()
{
if (g_cfg.core.external_debugger)
return true;
return IsDebuggerPresent();
}
#if defined(ARCH_X64) #if defined(ARCH_X64)
enum x64_reg_t : u32 enum x64_reg_t : u32
{ {
@ -1630,7 +1637,7 @@ static void append_thread_name(std::string& msg)
static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
{ {
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && IsDebuggerPresent()) if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
{ {
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }

View File

@ -25,6 +25,8 @@
#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wold-style-cast"
#endif #endif
extern bool is_debugger_present();
extern const ppu_decoder<ppu_itype> g_ppu_itype; extern const ppu_decoder<ppu_itype> g_ppu_itype;
extern const ppu_decoder<ppu_iname> g_ppu_iname; extern const ppu_decoder<ppu_iname> g_ppu_iname;
@ -109,10 +111,17 @@ struct ppu_exec_select
#define RETURN_(...) \ #define RETURN_(...) \
if constexpr (Build == 0) { \ if constexpr (Build == 0) { \
static_cast<void>(exec); \ static_cast<void>(exec); \
return +[](ppu_thread& ppu, ppu_opcode_t op, be_t<u32>* this_op, ppu_intrp_func* next_fn) { \ if (is_debugger_present()) return +[](ppu_thread& ppu, ppu_opcode_t op, be_t<u32>* this_op, ppu_intrp_func* next_fn) { \
const auto fn = atomic_storage<ppu_intrp_func_t>::observe(next_fn->fn); \
exec(__VA_ARGS__); \ exec(__VA_ARGS__); \
const auto next_op = this_op + 1; \ const auto next_op = this_op + 1; \
const auto fn = atomic_storage<ppu_intrp_func_t>::load(next_fn->fn); \
ppu.cia = vm::get_addr(next_op); \
return fn(ppu, {*next_op}, next_op, next_fn + 1); \
}; \
return +[](ppu_thread& ppu, ppu_opcode_t op, be_t<u32>* this_op, ppu_intrp_func* next_fn) { \
exec(__VA_ARGS__); \
const auto next_op = this_op + 1; \
const auto fn = atomic_storage<ppu_intrp_func_t>::observe(next_fn->fn); \
return fn(ppu, {*next_op}, next_op, next_fn + 1); \ return fn(ppu, {*next_op}, next_op, next_fn + 1); \
}; \ }; \
} }
@ -145,8 +154,6 @@ namespace asmjit
ppu_builder(CodeHolder* ch) ppu_builder(CodeHolder* ch)
: base(ch) : base(ch)
{ {
// Initialize pointer to next function
base::mov(x86::r11, x86::qword_ptr(arg_next_fn));
} }
// Indexed offset to ppu.member // Indexed offset to ppu.member
@ -222,11 +229,15 @@ namespace asmjit
void ppu_ret(bool last = true) void ppu_ret(bool last = true)
{ {
// Initialize pointer to next function
base::mov(x86::rax, x86::qword_ptr(arg_next_fn));
base::add(arg_this_op, 4); base::add(arg_this_op, 4);
if (is_debugger_present())
base::mov(ppu_mem<&ppu_thread::cia>(), arg_this_op.r32());
base::mov(arg_op, x86::dword_ptr(arg_this_op)); base::mov(arg_op, x86::dword_ptr(arg_this_op));
base::bswap(arg_op); base::bswap(arg_op);
base::add(arg_next_fn, 8); base::add(arg_next_fn, 8);
base::jmp(x86::r11); base::jmp(x86::rax);
// Embed constants (TODO: after last return) // Embed constants (TODO: after last return)
if (last) if (last)

View File

@ -82,6 +82,7 @@ struct cfg_root : cfg::node
cfg::uint64 perf_report_threshold{this, "Performance Report Threshold", 500, true}; // In µs, 0.5ms = default, 0 = everything cfg::uint64 perf_report_threshold{this, "Performance Report Threshold", 500, true}; // In µs, 0.5ms = default, 0 = everything
cfg::_bool perf_report{this, "Enable Performance Report", false, true}; // Show certain perf-related logs cfg::_bool perf_report{this, "Enable Performance Report", false, true}; // Show certain perf-related logs
cfg::_bool external_debugger{this, "Assume External Debugger"};
} core{ this }; } core{ this };
struct node_vfs : cfg::node struct node_vfs : cfg::node