mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-01 07:18:22 -04:00
kern: Add real SvcBreak implementation
This commit is contained in:
parent
4c3c910774
commit
325802e29d
5 changed files with 160 additions and 11 deletions
|
@ -21,25 +21,54 @@ namespace ams::kern::svc {
|
|||
|
||||
namespace {
|
||||
|
||||
void Break(ams::svc::BreakReason break_reason, uintptr_t address, size_t size) {
|
||||
/* Log for debug that Break was called. */
|
||||
MESOSPHERE_LOG("%s: Break(%08x, %016lx, %zu)\n", GetCurrentProcess().GetName(), static_cast<u32>(break_reason), address, size);
|
||||
[[maybe_unused]] void PrintBreak(ams::svc::BreakReason break_reason) {
|
||||
/* Print that break was called. */
|
||||
MESOSPHERE_RELEASE_LOG("%s: svc::Break(%d) was called, pid=%ld, tid=%ld\n", GetCurrentProcess().GetName(), static_cast<s32>(break_reason), GetCurrentProcess().GetId(), GetCurrentThread().GetId());
|
||||
|
||||
/* If the current process is attached to debugger, notify it. */
|
||||
/* Print the current thread's registers. */
|
||||
/* TODO: KDebug::PrintRegisters(); */
|
||||
|
||||
/* Print a backtrace. */
|
||||
/* TODO: KDebug::PrintBacktrace(); */
|
||||
}
|
||||
|
||||
void Break(ams::svc::BreakReason break_reason, uintptr_t address, size_t size) {
|
||||
/* Determine whether the break is only a notification. */
|
||||
const bool is_notification = (break_reason & ams::svc::BreakReason_NotificationOnlyFlag) != 0;
|
||||
|
||||
/* If the break isn't a notification, print it. */
|
||||
if (!is_notification) {
|
||||
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
|
||||
PrintBreak(break_reason);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If the current process is attached to debugger, try to notify it. */
|
||||
if (GetCurrentProcess().IsAttachedToDebugger()) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
if (R_SUCCEEDED(KDebug::BreakIfAttached(break_reason, address, size))) {
|
||||
/* If we attached, set the pc to the instruction before the current one and return. */
|
||||
KDebug::SetPreviousProgramCounter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the break is only a notification, we're done. */
|
||||
if ((break_reason & ams::svc::BreakReason_NotificationOnlyFlag) != 0) {
|
||||
if (is_notification) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
if (size == sizeof(u32)) {
|
||||
MESOSPHERE_LOG("DEBUG: %08x\n", *reinterpret_cast<u32 *>(address));
|
||||
/* Print that break was called. */
|
||||
MESOSPHERE_RELEASE_LOG("Break() called. %016lx\n", GetCurrentProcess().GetProgramId());
|
||||
|
||||
/* Try to enter JIT debug state. */
|
||||
if (GetCurrentProcess().EnterJitDebug(ams::svc::DebugEvent_Exception, ams::svc::DebugException_UserBreak, KDebug::GetProgramCounter(GetCurrentThread()), break_reason, address, size)) {
|
||||
/* We entered JIT debug, so set the pc to the instruction before the current one and return. */
|
||||
KDebug::SetPreviousProgramCounter();
|
||||
return;
|
||||
}
|
||||
MESOSPHERE_PANIC("Break was called\n");
|
||||
|
||||
/* Exit the current process. */
|
||||
GetCurrentProcess().Exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue