mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
PPU: correct behaviour under external debugger
May require setting "Assume External Debugger" to true.
This commit is contained in:
parent
e66d6a9399
commit
0a617a05d0
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user