From 42e6c1fd59272d0b08d5290ae8c9e11919b86fc8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 21 Feb 2023 09:16:15 -0700 Subject: [PATCH] kern: use variable-count parameter arrays for DebugEvents --- .../include/mesosphere/kern_k_debug_base.hpp | 8 +- .../include/mesosphere/kern_k_event_info.hpp | 2 +- .../arch/arm64/kern_exception_handlers.cpp | 84 ++++++------- .../source/arch/arm64/kern_k_debug.cpp | 3 +- .../arch/arm64/kern_k_thread_context.cpp | 4 +- .../source/kern_k_debug_base.cpp | 119 +++++++++++------- .../libmesosphere/source/kern_k_process.cpp | 3 +- 7 files changed, 125 insertions(+), 98 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp index 06fc19c6f..6c8fe54f7 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -74,7 +74,7 @@ namespace ams::kern { return m_process_holder.Get(); } private: - void PushDebugEvent(ams::svc::DebugEvent event, uintptr_t param0 = 0, uintptr_t param1 = 0, uintptr_t param2 = 0, uintptr_t param3 = 0, uintptr_t param4 = 0); + void PushDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params); void EnqueueDebugEventInfo(KEventInfo *info); template requires (std::same_as || std::same_as) @@ -85,13 +85,13 @@ namespace ams::kern { /* NOTE: This is public/virtual override in Nintendo's kernel. */ void OnFinalizeSynchronizationObject(); private: - static Result ProcessDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); + static Result ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params); public: - static Result OnDebugEvent(ams::svc::DebugEvent event, uintptr_t param0 = 0, uintptr_t param1 = 0, uintptr_t param2 = 0, uintptr_t param3 = 0, uintptr_t param4 = 0); + static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params); static Result OnExitProcess(KProcess *process); static Result OnTerminateProcess(KProcess *process); static Result OnExitThread(KThread *thread); - static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4, u64 thread_id); + static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, u64 thread_id, const uintptr_t *params, size_t num_params); }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_event_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_event_info.hpp index 23cb89746..98dbd5764 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_event_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_event_info.hpp @@ -38,7 +38,7 @@ namespace ams::kern { ams::svc::DebugException exception_type; s32 exception_data_count; uintptr_t exception_address; - uintptr_t exception_data[4]; + uintptr_t exception_data[std::max(4, cpu::NumCores)]; }; struct InfoSystemCall { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index cb14d2b93..ba44e7f2c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -229,73 +229,71 @@ namespace ams::kern::arch::arm64 { { /* Collect additional information based on the ec. */ - ams::svc::DebugException exception; - uintptr_t param2 = 0; - uintptr_t param3 = 0; + uintptr_t params[3] = {}; switch (ec) { case EsrEc_Unknown: case EsrEc_IllegalExecution: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: { - exception = ams::svc::DebugException_UndefinedInstruction; - param2 = far; - param3 = data; + params[0] = ams::svc::DebugException_UndefinedInstruction; + params[1] = far; + params[2] = data; } break; case EsrEc_PcAlignmentFault: case EsrEc_SpAlignmentFault: { - exception = ams::svc::DebugException_AlignmentFault; - param2 = far; + params[0] = ams::svc::DebugException_AlignmentFault; + params[1] = far; } break; case EsrEc_Svc32: case EsrEc_Svc64: { - exception = ams::svc::DebugException_UndefinedSystemCall; - param2 = far; - param3 = (esr & 0xFF); + params[0] = ams::svc::DebugException_UndefinedSystemCall; + params[1] = far; + params[2] = (esr & 0xFF); } break; case EsrEc_BreakPointEl0: case EsrEc_SoftwareStepEl0: { - exception = ams::svc::DebugException_BreakPoint; - param2 = far; - param3 = ams::svc::BreakPointType_HardwareInstruction; + params[0] = ams::svc::DebugException_BreakPoint; + params[1] = far; + params[2] = ams::svc::BreakPointType_HardwareInstruction; } break; case EsrEc_WatchPointEl0: { - exception = ams::svc::DebugException_BreakPoint; - param2 = far; - param3 = ams::svc::BreakPointType_HardwareData; + params[0] = ams::svc::DebugException_BreakPoint; + params[1] = far; + params[2] = ams::svc::BreakPointType_HardwareData; } break; case EsrEc_SErrorInterrupt: { - exception = ams::svc::DebugException_MemorySystemError; - param2 = far; + params[0] = ams::svc::DebugException_MemorySystemError; + params[1] = far; } break; case EsrEc_InstructionAbortEl0: { - exception = ams::svc::DebugException_InstructionAbort; - param2 = far; + params[0] = ams::svc::DebugException_InstructionAbort; + params[1] = far; } break; case EsrEc_DataAbortEl0: default: { - exception = ams::svc::DebugException_DataAbort; - param2 = far; + params[0] = ams::svc::DebugException_DataAbort; + params[1] = far; } break; } /* Process the debug event. */ - Result result = KDebug::OnDebugEvent(ams::svc::DebugEvent_Exception, exception, param2, param3); + Result result = KDebug::OnDebugEvent(ams::svc::DebugEvent_Exception, params, util::size(params)); /* If we should stop processing the exception, do so. */ if (svc::ResultStopProcessingException::Includes(result)) { @@ -340,7 +338,7 @@ namespace ams::kern::arch::arm64 { /* If the SVC is handled, handle it. */ if (!svc::ResultNotHandled::Includes(result)) { /* If we successfully enter jit debug, stop processing the exception. */ - if (cur_process.EnterJitDebug(ams::svc::DebugEvent_Exception, exception, param2, param3)) { + if (cur_process.EnterJitDebug(ams::svc::DebugEvent_Exception, static_cast(params[0]), params[1], params[2])) { return; } } @@ -420,58 +418,56 @@ namespace ams::kern::arch::arm64 { GetCurrentThread().RestoreDebugParams(std::addressof(far), std::addressof(esr), std::addressof(data)); /* Collect additional information based on the ec. */ - ams::svc::DebugException exception; - uintptr_t param2 = 0; - uintptr_t param3 = 0; + uintptr_t params[3] = {}; switch ((esr >> 26) & 0x3F) { case EsrEc_Unknown: case EsrEc_IllegalExecution: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: { - exception = ams::svc::DebugException_UndefinedInstruction; - param2 = far; - param3 = data; + params[0] = ams::svc::DebugException_UndefinedInstruction; + params[1] = far; + params[2] = data; } break; case EsrEc_PcAlignmentFault: case EsrEc_SpAlignmentFault: { - exception = ams::svc::DebugException_AlignmentFault; - param2 = far; + params[0] = ams::svc::DebugException_AlignmentFault; + params[1] = far; } break; case EsrEc_Svc32: case EsrEc_Svc64: { - exception = ams::svc::DebugException_UndefinedSystemCall; - param2 = far; - param3 = (esr & 0xFF); + params[0] = ams::svc::DebugException_UndefinedSystemCall; + params[1] = far; + params[2] = (esr & 0xFF); } break; case EsrEc_SErrorInterrupt: { - exception = ams::svc::DebugException_MemorySystemError; - param2 = far; + params[0] = ams::svc::DebugException_MemorySystemError; + params[1] = far; } break; case EsrEc_InstructionAbortEl0: { - exception = ams::svc::DebugException_InstructionAbort; - param2 = far; + params[0] = ams::svc::DebugException_InstructionAbort; + params[1] = far; } break; case EsrEc_DataAbortEl0: default: { - exception = ams::svc::DebugException_DataAbort; - param2 = far; + params[0] = ams::svc::DebugException_DataAbort; + params[1] = far; } break; } /* Process the debug event. */ - Result result = KDebug::OnDebugEvent(ams::svc::DebugEvent_Exception, exception, param2, param3); + Result result = KDebug::OnDebugEvent(ams::svc::DebugEvent_Exception, params, util::size(params)); /* If the SVC is handled, handle it. */ if (!svc::ResultNotHandled::Includes(result)) { @@ -481,7 +477,7 @@ namespace ams::kern::arch::arm64 { } /* If we successfully enter jit debug, restore. */ - if (cur_process.EnterJitDebug(ams::svc::DebugEvent_Exception, exception, param2, param3)) { + if (cur_process.EnterJitDebug(ams::svc::DebugEvent_Exception, static_cast(params[0]), params[1], params[2])) { svc::RestoreContext(reinterpret_cast(e_ctx)); } } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index fd2ee3821..3addd8da1 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -249,7 +249,8 @@ namespace ams::kern::arch::arm64 { } Result KDebug::BreakIfAttached(ams::svc::BreakReason break_reason, uintptr_t address, size_t size) { - R_RETURN(KDebugBase::OnDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_UserBreak, GetProgramCounter(GetCurrentThread()), break_reason, address, size)); + const uintptr_t params[5] = { ams::svc::DebugException_UserBreak, GetProgramCounter(GetCurrentThread()), break_reason, address, size }; + R_RETURN(KDebugBase::OnDebugEvent(ams::svc::DebugEvent_Exception, params, util::size(params))); } #define MESOSPHERE_SET_HW_BREAK_POINT(ID, FLAGS, VALUE) \ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp index 0e93d95eb..b3cef6755 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -26,7 +26,9 @@ namespace ams::kern::arch::arm64 { /* Send KDebug event for this thread's creation. */ { KScopedInterruptEnable ei; - KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress())); + + const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) }; + KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)); } /* Handle any pending dpc. */ diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index d10d1df86..3388e1ce3 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -289,7 +289,7 @@ namespace ams::kern { m_old_process_state = target->SetDebugObject(this); /* Send an event for our attaching to the process. */ - this->PushDebugEvent(ams::svc::DebugEvent_CreateProcess); + this->PushDebugEvent(ams::svc::DebugEvent_CreateProcess, nullptr, 0); /* Send events for attaching to each thread in the process. */ { @@ -304,7 +304,8 @@ namespace ams::kern { it->SetDebugAttached(); /* Send the event. */ - this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress())); + const uintptr_t params[2] = { it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()) }; + this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)); } } } @@ -315,7 +316,8 @@ namespace ams::kern { } /* Send an exception event to represent our attaching. */ - this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerAttached); + const uintptr_t params[1] = { static_cast(ams::svc::DebugException_DebuggerAttached) }; + this->PushDebugEvent(ams::svc::DebugEvent_Exception, params, util::size(params)); /* Signal. */ this->NotifyAvailable(); @@ -353,22 +355,22 @@ namespace ams::kern { /* Get the currently active threads. */ constexpr u64 ThreadIdNoThread = -1ll; constexpr u64 ThreadIdUnknownThread = -2ll; - u64 thread_ids[cpu::NumCores]; - for (size_t i = 0; i < util::size(thread_ids); ++i) { + uintptr_t debug_info_params[1 + cpu::NumCores] = { static_cast(ams::svc::DebugException_DebuggerBreak), }; + for (size_t i = 0; i < cpu::NumCores; ++i) { /* Get the currently running thread. */ KThread *thread = target->GetRunningThread(i); /* Check that the thread's idle count is correct. */ if (target->GetRunningThreadIdleCount(i) == Kernel::GetScheduler(i).GetIdleCount()) { if (thread != nullptr && static_cast(thread->GetActiveCore()) == i) { - thread_ids[i] = thread->GetId(); + debug_info_params[1 + i] = thread->GetId(); } else { /* We found an unknown thread. */ - thread_ids[i] = ThreadIdUnknownThread; + debug_info_params[1 + i] = ThreadIdUnknownThread; } } else { /* We didn't find a thread. */ - thread_ids[i] = ThreadIdNoThread; + debug_info_params[1 + i] = ThreadIdNoThread; } } @@ -382,11 +384,7 @@ namespace ams::kern { } /* Send an exception event to represent our breaking the process. */ - /* TODO: How should this be handled in the case of more than 4 physical cores? */ - static_assert(util::size(thread_ids) <= 4); - [&](std::index_sequence) ALWAYS_INLINE_LAMBDA { - this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerBreak, thread_ids[Ix]...); - }(std::make_index_sequence()); + this->PushDebugEvent(ams::svc::DebugEvent_Exception, debug_info_params, util::size(debug_info_params)); /* Signal. */ this->NotifyAvailable(); @@ -734,7 +732,7 @@ namespace ams::kern { R_SUCCEED(); } - KEventInfo *KDebugBase::CreateDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4, u64 cur_thread_id) { + KEventInfo *KDebugBase::CreateDebugEvent(ams::svc::DebugEvent event, u64 cur_thread_id, const uintptr_t *params, size_t num_params) { /* Allocate a new event. */ KEventInfo *info = KEventInfo::Allocate(); @@ -749,23 +747,33 @@ namespace ams::kern { switch (event) { case ams::svc::DebugEvent_CreateProcess: { - /* ... */ + /* Check parameters. */ + MESOSPHERE_ASSERT(params == nullptr); + MESOSPHERE_ASSERT(num_params == 0); } break; case ams::svc::DebugEvent_CreateThread: { + /* Check parameters. */ + MESOSPHERE_ASSERT(params != nullptr); + MESOSPHERE_ASSERT(num_params == 2); + /* Set the thread id. */ - info->thread_id = param0; + info->thread_id = params[0]; /* Set the thread creation info. */ - info->info.create_thread.thread_id = param0; - info->info.create_thread.tls_address = param1; + info->info.create_thread.thread_id = params[0]; + info->info.create_thread.tls_address = params[1]; } break; case ams::svc::DebugEvent_ExitProcess: { + /* Check parameters. */ + MESOSPHERE_ASSERT(params != nullptr); + MESOSPHERE_ASSERT(num_params == 1); + /* Set the exit reason. */ - info->info.exit_process.reason = static_cast(param0); + info->info.exit_process.reason = static_cast(params[0]); /* Clear the thread id and flags. */ info->thread_id = 0; @@ -774,30 +782,40 @@ namespace ams::kern { break; case ams::svc::DebugEvent_ExitThread: { + /* Check parameters. */ + MESOSPHERE_ASSERT(params != nullptr); + MESOSPHERE_ASSERT(num_params == 2); + /* Set the thread id. */ - info->thread_id = param0; + info->thread_id = params[0]; /* Set the exit reason. */ - info->info.exit_thread.reason = static_cast(param1); + info->info.exit_thread.reason = static_cast(params[1]); } break; case ams::svc::DebugEvent_Exception: { + /* Check parameters. */ + MESOSPHERE_ASSERT(params != nullptr); + MESOSPHERE_ASSERT(num_params >= 1); + /* Set the thread id. */ info->thread_id = cur_thread_id; /* Set the exception type, and clear the count. */ - info->info.exception.exception_type = static_cast(param0); + info->info.exception.exception_type = static_cast(params[0]); info->info.exception.exception_data_count = 0; - switch (static_cast(param0)) { + switch (static_cast(params[0])) { case ams::svc::DebugException_UndefinedInstruction: case ams::svc::DebugException_BreakPoint: case ams::svc::DebugException_UndefinedSystemCall: { - info->info.exception.exception_address = param1; + MESOSPHERE_ASSERT(num_params >= 3); + + info->info.exception.exception_address = params[1]; info->info.exception.exception_data_count = 1; - info->info.exception.exception_data[0] = param2; + info->info.exception.exception_data[0] = params[2]; } break; case ams::svc::DebugException_DebuggerAttached: @@ -809,12 +827,14 @@ namespace ams::kern { break; case ams::svc::DebugException_UserBreak: { - info->info.exception.exception_address = param1; + MESOSPHERE_ASSERT(num_params >= 2); - info->info.exception.exception_data_count = 3; - info->info.exception.exception_data[0] = param2; - info->info.exception.exception_data[1] = param3; - info->info.exception.exception_data[2] = param4; + info->info.exception.exception_address = params[1]; + + info->info.exception.exception_data_count = 0; + for (size_t i = 2; i < num_params; ++i) { + info->info.exception.exception_data[info->info.exception.exception_data_count++] = params[i]; + } } break; case ams::svc::DebugException_DebuggerBreak: @@ -823,11 +843,10 @@ namespace ams::kern { info->info.exception.exception_address = 0; - info->info.exception.exception_data_count = 4; - info->info.exception.exception_data[0] = param1; - info->info.exception.exception_data[1] = param2; - info->info.exception.exception_data[2] = param3; - info->info.exception.exception_data[3] = param4; + info->info.exception.exception_data_count = 0; + for (size_t i = 1; i < num_params; ++i) { + info->info.exception.exception_data[info->info.exception.exception_data_count++] = params[i]; + } } break; case ams::svc::DebugException_MemorySystemError: @@ -840,7 +859,9 @@ namespace ams::kern { case ams::svc::DebugException_AlignmentFault: default: { - info->info.exception.exception_address = param1; + MESOSPHERE_ASSERT(num_params >= 2); + + info->info.exception.exception_address = params[1]; } break; } @@ -852,9 +873,9 @@ namespace ams::kern { return info; } - void KDebugBase::PushDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) { + void KDebugBase::PushDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params) { /* Create and enqueue and event. */ - if (KEventInfo *new_info = CreateDebugEvent(event, param0, param1, param2, param3, param4, GetCurrentThread().GetId()); new_info != nullptr) { + if (KEventInfo *new_info = CreateDebugEvent(event, GetCurrentThread().GetId(), params, num_params); new_info != nullptr) { this->EnqueueDebugEventInfo(new_info); } } @@ -961,7 +982,10 @@ namespace ams::kern { break; case ams::svc::DebugException_DebuggerBreak: { - MESOSPHERE_ASSERT(info->info.exception.exception_data_count == 4); + /* TODO: How does this work with non-4 cpu count? */ + static_assert(cpu::NumCores <= 4); + + MESOSPHERE_ASSERT(info->info.exception.exception_data_count == cpu::NumCores); out->info.exception.specific.debugger_break.active_thread_ids[0] = info->info.exception.exception_data[0]; out->info.exception.specific.debugger_break.active_thread_ids[1] = info->info.exception.exception_data[1]; out->info.exception.specific.debugger_break.active_thread_ids[2] = info->info.exception.exception_data[2]; @@ -1075,7 +1099,7 @@ namespace ams::kern { return !empty || !m_is_attached || this->GetProcessUnsafe()->IsTerminated(); } - Result KDebugBase::ProcessDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) { + Result KDebugBase::ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params) { /* Get the current process. */ KProcess *process = GetCurrentProcessPointer(); @@ -1117,7 +1141,7 @@ namespace ams::kern { } /* Push the event. */ - debug->PushDebugEvent(event, param0, param1, param2, param3, param4); + debug->PushDebugEvent(event, params, num_params); debug->NotifyAvailable(); /* Set the process as breaked. */ @@ -1153,9 +1177,9 @@ namespace ams::kern { R_SUCCEED(); } - Result KDebugBase::OnDebugEvent(ams::svc::DebugEvent event, uintptr_t param0, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) { + Result KDebugBase::OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params) { if (KProcess *process = GetCurrentProcessPointer(); process != nullptr && process->IsAttachedToDebugger()) { - R_RETURN(ProcessDebugEvent(event, param0, param1, param2, param3, param4)); + R_RETURN(ProcessDebugEvent(event, params, num_params)); } R_SUCCEED(); } @@ -1170,7 +1194,8 @@ namespace ams::kern { /* Push the event. */ if (KDebugBase *debug = GetDebugObject(process); debug != nullptr) { - debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, ams::svc::ProcessExitReason_ExitProcess); + const uintptr_t params[1] = { static_cast(ams::svc::ProcessExitReason_ExitProcess) }; + debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, params, util::size(params)); debug->NotifyAvailable(); } } @@ -1188,7 +1213,8 @@ namespace ams::kern { /* Push the event. */ if (KDebugBase *debug = GetDebugObject(process); debug != nullptr) { - debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, ams::svc::ProcessExitReason_TerminateProcess); + const uintptr_t params[1] = { static_cast(ams::svc::ProcessExitReason_TerminateProcess) }; + debug->PushDebugEvent(ams::svc::DebugEvent_ExitProcess, params, util::size(params)); debug->NotifyAvailable(); } } @@ -1202,7 +1228,8 @@ namespace ams::kern { /* Check if we're attached to a debugger. */ if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) { /* If we are, submit the event. */ - R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, thread->GetId(), thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread)); + const uintptr_t params[2] = { thread->GetId(), static_cast(thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread) }; + R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params))); } R_SUCCEED(); diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 4389e3081..94b0a313f 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -1242,7 +1242,8 @@ namespace ams::kern { MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread()); if (m_is_jit_debug) { - return KDebugBase::CreateDebugEvent(m_jit_debug_event_type, m_jit_debug_exception_type, m_jit_debug_params[0], m_jit_debug_params[1], m_jit_debug_params[2], m_jit_debug_params[3], m_jit_debug_thread_id); + const uintptr_t params[5] = { m_jit_debug_exception_type, m_jit_debug_params[0], m_jit_debug_params[1], m_jit_debug_params[2], m_jit_debug_params[3] }; + return KDebugBase::CreateDebugEvent(m_jit_debug_event_type, m_jit_debug_thread_id, params, util::size(params)); } else { return nullptr; }