kern/strat: update for new DebugFlags capability semantics
This commit is contained in:
@@ -217,6 +217,9 @@ namespace ams::kern::svc {
|
||||
}
|
||||
|
||||
Result GetThreadList(int32_t *out_num_threads, KUserPointer<uint64_t *> out_thread_ids, int32_t max_out_count, ams::svc::Handle debug_handle) {
|
||||
/* Only allow invoking the svc on development hardware. */
|
||||
R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented());
|
||||
|
||||
/* Validate that the out count is valid. */
|
||||
R_UNLESS((0 <= max_out_count && max_out_count <= static_cast<int32_t>(std::numeric_limits<int32_t>::max() / sizeof(u64))), svc::ResultOutOfRange());
|
||||
|
||||
@@ -225,30 +228,34 @@ namespace ams::kern::svc {
|
||||
R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory());
|
||||
}
|
||||
|
||||
if (debug_handle == ams::svc::InvalidHandle) {
|
||||
/* If passed invalid handle, we should return the global thread list. */
|
||||
R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count));
|
||||
/* Get the handle table. */
|
||||
auto &handle_table = GetCurrentProcess().GetHandleTable();
|
||||
|
||||
/* Try to get as a debug object. */
|
||||
KScopedAutoObject debug = handle_table.GetObject<KDebug>(debug_handle);
|
||||
if (debug.IsNotNull()) {
|
||||
/* Check that the debug object has a process. */
|
||||
R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated());
|
||||
R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated());
|
||||
ON_SCOPE_EXIT { debug->CloseProcess(); };
|
||||
|
||||
/* Get the thread list. */
|
||||
R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count));
|
||||
} else {
|
||||
/* Get the handle table. */
|
||||
auto &handle_table = GetCurrentProcess().GetHandleTable();
|
||||
|
||||
/* Try to get as a debug object. */
|
||||
KScopedAutoObject debug = handle_table.GetObject<KDebug>(debug_handle);
|
||||
if (debug.IsNotNull()) {
|
||||
/* Check that the debug object has a process. */
|
||||
R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated());
|
||||
R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated());
|
||||
ON_SCOPE_EXIT { debug->CloseProcess(); };
|
||||
|
||||
/* Get the thread list. */
|
||||
R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count));
|
||||
} else {
|
||||
/* Try to get as a process. */
|
||||
KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle<KProcess>(debug_handle);
|
||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||
/* Only allow getting as a process (or global) if the caller does not have ForceDebugProd. */
|
||||
R_UNLESS(!GetCurrentProcess().CanForceDebugProd(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Try to get as a process. */
|
||||
KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle<KProcess>(debug_handle);
|
||||
if (process.IsNotNull()) {
|
||||
/* Get the thread list. */
|
||||
R_TRY(process->GetThreadList(out_num_threads, out_thread_ids, max_out_count));
|
||||
} else {
|
||||
/* If the object is not a process, the caller may want the global thread list. */
|
||||
R_UNLESS(debug_handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle());
|
||||
|
||||
/* If passed invalid handle, we should return the global thread list. */
|
||||
R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user