mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
kern: SvcGetDebugThreadParam
This commit is contained in:
parent
e1f3bb10a5
commit
3afd723b92
6 changed files with 140 additions and 3 deletions
|
@ -23,7 +23,7 @@ namespace ams::kern {
|
||||||
class KAutoObjectWithListContainer {
|
class KAutoObjectWithListContainer {
|
||||||
NON_COPYABLE(KAutoObjectWithListContainer);
|
NON_COPYABLE(KAutoObjectWithListContainer);
|
||||||
NON_MOVEABLE(KAutoObjectWithListContainer);
|
NON_MOVEABLE(KAutoObjectWithListContainer);
|
||||||
private:
|
public:
|
||||||
using ListType = util::IntrusiveRedBlackTreeMemberTraits<&KAutoObjectWithList::list_node>::TreeType<KAutoObjectWithList>;
|
using ListType = util::IntrusiveRedBlackTreeMemberTraits<&KAutoObjectWithList::list_node>::TreeType<KAutoObjectWithList>;
|
||||||
public:
|
public:
|
||||||
class ListAccessor : public KScopedLightLock {
|
class ListAccessor : public KScopedLightLock {
|
||||||
|
|
|
@ -522,6 +522,7 @@ namespace ams::kern {
|
||||||
return ConditionVariableThreadTreeTraits::IsValid();
|
return ConditionVariableThreadTreeTraits::IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static KThread *GetThreadFromId(u64 thread_id);
|
||||||
static Result GetThreadList(s32 *out_num_threads, ams::kern::svc::KUserPointer<u64 *> out_thread_ids, s32 max_out_count);
|
static Result GetThreadList(s32 *out_num_threads, ams::kern::svc::KUserPointer<u64 *> out_thread_ids, s32 max_out_count);
|
||||||
|
|
||||||
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
|
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace ams::kern::svc {
|
||||||
/* 260 */ using ::ams::svc::ResultMessageTooLarge;
|
/* 260 */ using ::ams::svc::ResultMessageTooLarge;
|
||||||
|
|
||||||
/* 517 */ using ::ams::svc::ResultInvalidProcessId;
|
/* 517 */ using ::ams::svc::ResultInvalidProcessId;
|
||||||
|
/* 518 */ using ::ams::svc::ResultInvalidThreadId;
|
||||||
/* 520 */ using ::ams::svc::ResultProcessTerminated;
|
/* 520 */ using ::ams::svc::ResultProcessTerminated;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1190,6 +1190,41 @@ namespace ams::kern {
|
||||||
return std::addressof(this->GetContext());
|
return std::addressof(this->GetContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KThread *KThread::GetThreadFromId(u64 thread_id) {
|
||||||
|
/* Lock the list. */
|
||||||
|
KThread::ListAccessor accessor;
|
||||||
|
const auto end = accessor.end();
|
||||||
|
|
||||||
|
/* Define helper object to find the thread. */
|
||||||
|
class IdObjectHelper : public KAutoObjectWithListContainer::ListType::value_type {
|
||||||
|
private:
|
||||||
|
u64 id;
|
||||||
|
public:
|
||||||
|
constexpr explicit IdObjectHelper(u64 id) : id(id) { /* ... */ }
|
||||||
|
virtual u64 GetId() const override { return this->id; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Find the object with the right id. */
|
||||||
|
const auto it = accessor.find(IdObjectHelper(thread_id));
|
||||||
|
|
||||||
|
/* Check to make sure we found the thread. */
|
||||||
|
if (it == end) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the thread. */
|
||||||
|
KThread *thread = static_cast<KThread *>(std::addressof(*it));
|
||||||
|
|
||||||
|
/* Open the thread. */
|
||||||
|
if (AMS_LIKELY(thread->Open())) {
|
||||||
|
MESOSPHERE_ASSERT(thread->GetId() == thread_id);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We failed to find the thread. */
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Result KThread::GetThreadList(s32 *out_num_threads, ams::kern::svc::KUserPointer<u64 *> out_thread_ids, s32 max_out_count) {
|
Result KThread::GetThreadList(s32 *out_num_threads, ams::kern::svc::KUserPointer<u64 *> out_thread_ids, s32 max_out_count) {
|
||||||
/* Lock the list. */
|
/* Lock the list. */
|
||||||
KThread::ListAccessor accessor;
|
KThread::ListAccessor accessor;
|
||||||
|
|
|
@ -246,6 +246,105 @@ namespace ams::kern::svc {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result GetDebugThreadParam(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) {
|
||||||
|
/* Get the debug object. */
|
||||||
|
KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject<KDebug>(debug_handle);
|
||||||
|
R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
|
/* Get the thread from its id. */
|
||||||
|
KScopedAutoObject thread = KThread::GetThreadFromId(thread_id);
|
||||||
|
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidThreadId());
|
||||||
|
|
||||||
|
/* Get the process from the debug object. */
|
||||||
|
KScopedAutoObject process = debug->GetProcess();
|
||||||
|
R_UNLESS(process.IsNotNull(), svc::ResultProcessTerminated());
|
||||||
|
|
||||||
|
/* Verify that the process is the thread's parent. */
|
||||||
|
R_UNLESS(process.GetPointerUnsafe() == thread->GetOwnerProcess(), svc::ResultInvalidThreadId());
|
||||||
|
|
||||||
|
/* Get the parameter. */
|
||||||
|
switch (param) {
|
||||||
|
case ams::svc::DebugThreadParam_Priority:
|
||||||
|
{
|
||||||
|
/* Get the priority. */
|
||||||
|
*out_32 = thread->GetPriority();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ams::svc::DebugThreadParam_State:
|
||||||
|
{
|
||||||
|
/* Get the thread state and suspend status. */
|
||||||
|
KThread::ThreadState state;
|
||||||
|
bool suspended_user;
|
||||||
|
bool suspended_debug;
|
||||||
|
{
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
state = thread->GetState();
|
||||||
|
suspended_user = thread->IsSuspendRequested(KThread::SuspendType_Thread);
|
||||||
|
suspended_debug = thread->IsSuspendRequested(KThread::SuspendType_Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the suspend flags. */
|
||||||
|
*out_32 = 0;
|
||||||
|
if (suspended_user) {
|
||||||
|
*out_32 |= ams::svc::ThreadSuspend_User;
|
||||||
|
}
|
||||||
|
if (suspended_debug) {
|
||||||
|
*out_32 |= ams::svc::ThreadSuspend_Debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the state. */
|
||||||
|
switch (state) {
|
||||||
|
case KThread::ThreadState_Initialized:
|
||||||
|
{
|
||||||
|
*out_64 = ams::svc::ThreadState_Initializing;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KThread::ThreadState_Waiting:
|
||||||
|
{
|
||||||
|
*out_64 = ams::svc::ThreadState_Waiting;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KThread::ThreadState_Runnable:
|
||||||
|
{
|
||||||
|
*out_64 = ams::svc::ThreadState_Running;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KThread::ThreadState_Terminated:
|
||||||
|
{
|
||||||
|
*out_64 = ams::svc::ThreadState_Terminated;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return svc::ResultInvalidState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ams::svc::DebugThreadParam_IdealCore:
|
||||||
|
{
|
||||||
|
/* Get the ideal core. */
|
||||||
|
*out_32 = thread->GetIdealCore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ams::svc::DebugThreadParam_CurrentCore:
|
||||||
|
{
|
||||||
|
/* Get the current core. */
|
||||||
|
*out_32 = thread->GetActiveCore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ams::svc::DebugThreadParam_AffinityMask:
|
||||||
|
{
|
||||||
|
/* Get the affinity mask. */
|
||||||
|
*out_32 = thread->GetAffinityMask().GetAffinityMask();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ams::svc::ResultInvalidEnumValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
@ -299,7 +398,7 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetDebugThreadParam64(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) {
|
Result GetDebugThreadParam64(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcGetDebugThreadParam64 was called.");
|
return GetDebugThreadParam(out_64, out_32, debug_handle, thread_id, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
@ -353,7 +452,7 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetDebugThreadParam64From32(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) {
|
Result GetDebugThreadParam64From32(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcGetDebugThreadParam64From32 was called.");
|
return GetDebugThreadParam(out_64, out_32, debug_handle, thread_id, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace ams::svc {
|
||||||
R_DEFINE_ERROR_RESULT(MessageTooLarge, 260);
|
R_DEFINE_ERROR_RESULT(MessageTooLarge, 260);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidProcessId, 517);
|
R_DEFINE_ERROR_RESULT(InvalidProcessId, 517);
|
||||||
|
R_DEFINE_ERROR_RESULT(InvalidThreadId, 518);
|
||||||
R_DEFINE_ERROR_RESULT(ProcessTerminated, 520);
|
R_DEFINE_ERROR_RESULT(ProcessTerminated, 520);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue