Debugger: Add some error pop-ups for invalid operations

* Show error window when setting breakpoints on these conditions:
- SPU/RSX are selected. (not supported)
- When using non-interpreters decoders.
- Non-executable memory is specified.
* Do not allow instruction stepping for non-interpreters decoders.
* Clear breakpoints when the game is stopped.
* Fix setting breakpoints on HLE functions.
This commit is contained in:
Eladash 2021-07-30 21:30:29 +03:00 committed by Megamouse
parent a06a93d5ba
commit f39a0a5fbe
6 changed files with 111 additions and 63 deletions

View file

@ -513,57 +513,45 @@ static bool ppu_break(ppu_thread& ppu, ppu_opcode_t)
}
// Set or remove breakpoint
extern void ppu_breakpoint(u32 addr, bool is_adding)
extern bool ppu_breakpoint(u32 addr, bool is_adding)
{
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
if (!vm::check_addr(addr, vm::page_executable) || g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
{
return;
return false;
}
const u64 _break = reinterpret_cast<uptr>(&ppu_break);
// Remove breakpoint parameters
u64 to_set = 0;
u64 expected = _break;
if (u32 hle_addr{}; g_fxo->is_init<ppu_function_manager>() && (hle_addr = g_fxo->get<ppu_function_manager>().addr))
{
// HLE function index
const u32 index = (addr - hle_addr) / 8;
if (addr % 8 == 4 && index < ppu_function_manager::get().size())
{
// HLE function placement
to_set = reinterpret_cast<uptr>(ppu_function_manager::get()[index]);
}
}
if (!to_set)
{
// If not an HLE function use regular instruction function
to_set = ppu_cache(addr);
}
if (is_adding)
{
// Set breakpoint
ppu_ref(addr) = _break;
}
else
{
// Remove breakpoint
ppu_ref(addr) = ppu_cache(addr);
}
}
//sets breakpoint, does nothing if there is a breakpoint there already
extern void ppu_set_breakpoint(u32 addr)
{
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
{
return;
// Swap if adding
std::swap(to_set, expected);
}
const u64 _break = reinterpret_cast<uptr>(&ppu_break);
if (ppu_ref(addr) != _break)
{
ppu_ref(addr) = _break;
}
}
//removes breakpoint, does nothing if there is no breakpoint at location
extern void ppu_remove_breakpoint(u32 addr)
{
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
{
return;
}
const auto _break = reinterpret_cast<uptr>(&ppu_break);
if (ppu_ref(addr) == _break)
{
ppu_ref(addr) = ppu_cache(addr);
}
auto& ref = reinterpret_cast<atomic_t<u64>&>(ppu_ref(addr));
return ref.compare_and_swap_test(expected, to_set);
}
extern bool ppu_patch(u32 addr, u32 value)