mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-24 11:46:58 -04:00
kern: implement SvcDebugActiveProcess, svcGetDebugEvent, SvcWaitProcessWideKeyAtomic
This commit is contained in:
parent
1c5b58ce66
commit
36eb78a3ce
17 changed files with 728 additions and 24 deletions
|
@ -30,6 +30,11 @@ namespace ams::kern::arch::arm64 {
|
|||
class KDebug final : public KAutoObjectWithSlabHeapAndContainer<KDebug, KDebugBase> {
|
||||
MESOSPHERE_AUTOOBJECT_TRAITS(KDebug, KSynchronizationObject);
|
||||
public:
|
||||
explicit KDebug() { /* ... */ }
|
||||
virtual ~KDebug() { /* ... */ }
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { /* ... */ }
|
||||
|
||||
/* TODO: This is a placeholder definition. */
|
||||
};
|
||||
|
||||
|
|
|
@ -283,6 +283,14 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
|
||||
constexpr bool IsPermittedDebug() const {
|
||||
return this->debug_capabilities.Get<DebugFlags::AllowDebug>();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebug() const {
|
||||
return this->debug_capabilities.Get<DebugFlags::ForceDebug>();
|
||||
}
|
||||
|
||||
/* TODO: Member functions. */
|
||||
};
|
||||
|
||||
|
|
|
@ -16,12 +16,42 @@
|
|||
#pragma once
|
||||
#include <mesosphere/kern_common.hpp>
|
||||
#include <mesosphere/kern_k_synchronization_object.hpp>
|
||||
#include <mesosphere/kern_k_process.hpp>
|
||||
#include <mesosphere/kern_k_event_info.hpp>
|
||||
#include <mesosphere/kern_k_light_lock.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
|
||||
class KDebugBase : public KSynchronizationObject {
|
||||
protected:
|
||||
using DebugEventList = util::IntrusiveListBaseTraits<KEventInfo>::ListType;
|
||||
private:
|
||||
DebugEventList event_info_list;
|
||||
u32 continue_flags;
|
||||
KProcess *process;
|
||||
KLightLock lock;
|
||||
KProcess::State old_process_state;
|
||||
public:
|
||||
explicit KDebugBase() { /* ... */ }
|
||||
virtual ~KDebugBase() { /* ... */ }
|
||||
public:
|
||||
void Initialize();
|
||||
Result Attach(KProcess *process);
|
||||
|
||||
Result GetDebugEventInfo(ams::svc::lp64::DebugEventInfo *out);
|
||||
Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out);
|
||||
|
||||
/* TODO: This is a placeholder definition. */
|
||||
private:
|
||||
KScopedAutoObject<KProcess> GetProcess();
|
||||
|
||||
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 EnqueueDebugEventInfo(KEventInfo *info);
|
||||
public:
|
||||
virtual void OnFinalizeSynchronizationObject() override;
|
||||
virtual bool IsSignaled() const override;
|
||||
public:
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,50 @@ namespace ams::kern {
|
|||
|
||||
class KEventInfo : public KSlabAllocated<KEventInfo>, public util::IntrusiveListBaseNode<KEventInfo> {
|
||||
public:
|
||||
/* TODO: This is a placeholder definition. */
|
||||
struct InfoCreateThread {
|
||||
u32 thread_id;
|
||||
uintptr_t tls_address;
|
||||
uintptr_t entrypoint;
|
||||
};
|
||||
|
||||
struct InfoExitProcess {
|
||||
ams::svc::ProcessExitReason reason;
|
||||
};
|
||||
|
||||
struct InfoExitThread {
|
||||
ams::svc::ThreadExitReason reason;
|
||||
};
|
||||
|
||||
struct InfoException {
|
||||
ams::svc::DebugException exception_type;
|
||||
s32 exception_data_count;
|
||||
uintptr_t exception_address;
|
||||
uintptr_t exception_data[4];
|
||||
};
|
||||
|
||||
struct InfoSystemCall {
|
||||
s64 tick;
|
||||
s32 id;
|
||||
};
|
||||
public:
|
||||
ams::svc::DebugEvent event;
|
||||
u32 thread_id;
|
||||
u32 flags;
|
||||
bool is_attached;
|
||||
bool continue_flag;
|
||||
bool ignore_continue;
|
||||
bool close_once;
|
||||
union {
|
||||
InfoCreateThread create_thread;
|
||||
InfoExitProcess exit_process;
|
||||
InfoExitThread exit_thread;
|
||||
InfoException exception;
|
||||
InfoSystemCall system_call;
|
||||
} info;
|
||||
KThread *debug_thread;
|
||||
public:
|
||||
explicit KEventInfo() : is_attached(), continue_flag(), ignore_continue() { /* ... */ }
|
||||
~KEventInfo() { /* ... */ }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -131,6 +131,8 @@ namespace ams::kern {
|
|||
|
||||
constexpr u64 GetProcessId() const { return this->process_id; }
|
||||
|
||||
constexpr State GetState() const { return this->state; }
|
||||
|
||||
constexpr u64 GetCoreMask() const { return this->capabilities.GetCoreMask(); }
|
||||
constexpr u64 GetPriorityMask() const { return this->capabilities.GetPriorityMask(); }
|
||||
|
||||
|
@ -139,6 +141,8 @@ namespace ams::kern {
|
|||
|
||||
constexpr bool CheckThreadPriority(s32 prio) const { return ((1ul << prio) & this->GetPriorityMask()) != 0; }
|
||||
|
||||
constexpr u32 GetCreateProcessFlags() const { return this->flags; }
|
||||
|
||||
constexpr bool Is64Bit() const { return this->flags & ams::svc::CreateProcessFlag_Is64Bit; }
|
||||
|
||||
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
|
||||
|
@ -147,10 +151,32 @@ namespace ams::kern {
|
|||
return this->is_suspended;
|
||||
}
|
||||
|
||||
constexpr bool IsTerminated() const {
|
||||
return this->state == State_Terminated;
|
||||
}
|
||||
|
||||
constexpr bool IsAttachedToDebugger() const {
|
||||
return this->attached_object != nullptr;
|
||||
}
|
||||
|
||||
constexpr bool IsPermittedInterrupt(int32_t interrupt_id) const {
|
||||
return this->capabilities.IsPermittedInterrupt(interrupt_id);
|
||||
}
|
||||
|
||||
constexpr bool IsPermittedDebug() const {
|
||||
return this->capabilities.IsPermittedDebug();
|
||||
}
|
||||
|
||||
constexpr bool CanForceDebug() const {
|
||||
return this->capabilities.CanForceDebug();
|
||||
}
|
||||
|
||||
ThreadList &GetThreadList() { return this->thread_list; }
|
||||
const ThreadList &GetThreadList() const { return this->thread_list; }
|
||||
|
||||
KProcess::State SetDebugObject(void *debug_object);
|
||||
KEventInfo *GetJitDebugInfo();
|
||||
|
||||
bool EnterUserException();
|
||||
bool LeaveUserException();
|
||||
bool ReleaseUserException(KThread *thread);
|
||||
|
|
|
@ -311,10 +311,21 @@ namespace ams::kern {
|
|||
this->priority = priority;
|
||||
}
|
||||
|
||||
constexpr void ClearConditionVariableTree() {
|
||||
constexpr void SetConditionVariable(ConditionVariableThreadTree *tree, KProcessAddress address, uintptr_t cv_key, u32 value) {
|
||||
this->condvar_tree = tree;
|
||||
this->condvar_key = cv_key;
|
||||
this->address_key = address;
|
||||
this->address_key_value = value;
|
||||
}
|
||||
|
||||
constexpr void ClearConditionVariable() {
|
||||
this->condvar_tree = nullptr;
|
||||
}
|
||||
|
||||
constexpr bool IsWaitingForConditionVariable() const {
|
||||
return this->condvar_tree != nullptr;
|
||||
}
|
||||
|
||||
constexpr void SetupForAddressArbiterCompare(uintptr_t address, int priority) {
|
||||
this->condvar_key = address;
|
||||
this->priority = priority;
|
||||
|
@ -394,6 +405,8 @@ namespace ams::kern {
|
|||
constexpr KProcess *GetOwnerProcess() const { return this->parent; }
|
||||
constexpr bool IsUserThread() const { return this->parent != nullptr; }
|
||||
|
||||
constexpr uintptr_t GetEntrypoint() const { return this->entrypoint; }
|
||||
|
||||
constexpr KProcessAddress GetThreadLocalRegionAddress() const { return this->tls_address; }
|
||||
constexpr void *GetThreadLocalRegionHeapAddress() const { return this->tls_heap_address; }
|
||||
|
||||
|
@ -403,6 +416,9 @@ namespace ams::kern {
|
|||
constexpr u16 GetUserPreemptionState() const { return *GetPointer<u16>(this->tls_address + 0x100); }
|
||||
constexpr void SetKernelPreemptionState(u16 state) const { *GetPointer<u16>(this->tls_address + 0x100 + sizeof(u16)) = state; }
|
||||
|
||||
constexpr void SetDebugAttached() { this->debug_attached = true; }
|
||||
constexpr bool IsAttachedToDebugger() const { return this->debug_attached; }
|
||||
|
||||
void AddCpuTime(s64 amount) {
|
||||
this->cpu_time += amount;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace ams::kern::svc {
|
|||
/* 259 */ using ::ams::svc::ResultOutOfAddressSpace;
|
||||
/* 260 */ using ::ams::svc::ResultMessageTooLarge;
|
||||
|
||||
/* 517 */ using ::ams::svc::ResultInvalidProcessId;
|
||||
/* 520 */ using ::ams::svc::ResultProcessTerminated;
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue