mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: clean up majority of TODOs
This commit is contained in:
parent
bea550ebce
commit
e1f3bb10a5
30 changed files with 112 additions and 85 deletions
|
@ -222,8 +222,6 @@ namespace ams::kern::arch::arm64 {
|
||||||
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
|
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
|
||||||
return (0 <= irq && irq < num_interrupts);
|
return (0 <= irq && irq < num_interrupts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Implement more KInterruptController functionality. */
|
|
||||||
public:
|
public:
|
||||||
static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
|
static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
|
||||||
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
|
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
|
||||||
|
|
|
@ -266,7 +266,6 @@ namespace ams::kern::arch::arm64 {
|
||||||
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
||||||
|
|
||||||
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
||||||
/* TODO: Better way to convert address type? */
|
|
||||||
return this->page_table.GetHeapPhysicalAddress(address);
|
return this->page_table.GetHeapPhysicalAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,8 @@ namespace ams::kern::arch::arm64 {
|
||||||
void CloneFpuStatus();
|
void CloneFpuStatus();
|
||||||
|
|
||||||
const u128 *GetFpuRegisters() const { return this->fpu_registers; }
|
const u128 *GetFpuRegisters() const { return this->fpu_registers; }
|
||||||
|
public:
|
||||||
/* TODO: More methods (especially FPU management) */
|
static void OnThreadTerminating(const KThread *thread);
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread);
|
void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread);
|
||||||
|
|
|
@ -328,8 +328,6 @@ namespace ams::kern {
|
||||||
constexpr bool CanForceDebug() const {
|
constexpr bool CanForceDebug() const {
|
||||||
return this->debug_capabilities.Get<DebugFlags::ForceDebug>();
|
return this->debug_capabilities.Get<DebugFlags::ForceDebug>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Member functions. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace ams::kern {
|
||||||
virtual void Destroy() override;
|
virtual void Destroy() override;
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
/* TODO: More of KClientPort. */
|
|
||||||
Result CreateSession(KClientSession **out);
|
Result CreateSession(KClientSession **out);
|
||||||
Result CreateLightSession(KLightClientSession **out);
|
Result CreateLightSession(KLightClientSession **out);
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,8 +53,6 @@ namespace ams::kern {
|
||||||
Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out);
|
Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out);
|
||||||
|
|
||||||
KScopedAutoObject<KProcess> GetProcess();
|
KScopedAutoObject<KProcess> GetProcess();
|
||||||
|
|
||||||
/* TODO: This is a placeholder definition. */
|
|
||||||
private:
|
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, uintptr_t param0 = 0, uintptr_t param1 = 0, uintptr_t param2 = 0, uintptr_t param3 = 0, uintptr_t param4 = 0);
|
||||||
void EnqueueDebugEventInfo(KEventInfo *info);
|
void EnqueueDebugEventInfo(KEventInfo *info);
|
||||||
|
|
|
@ -49,8 +49,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
NOINLINE void Initialize();
|
NOINLINE void Initialize();
|
||||||
void EnqueueTask(KInterruptTask *task);
|
void EnqueueTask(KInterruptTask *task);
|
||||||
|
|
||||||
/* TODO: Actually implement KInterruptTaskManager. This is a placeholder. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,6 +281,11 @@ namespace ams::kern {
|
||||||
return this->dynamic_page_manager.GetUsed() * PageSize;
|
return this->dynamic_page_manager.GetUsed() * PageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetRunningThread(s32 core, KThread *thread, u64 idle_count) {
|
||||||
|
this->running_threads[core] = thread;
|
||||||
|
this->running_thread_idle_counts[core] = idle_count;
|
||||||
|
}
|
||||||
|
|
||||||
void ClearRunningThread(KThread *thread) {
|
void ClearRunningThread(KThread *thread) {
|
||||||
for (size_t i = 0; i < util::size(this->running_threads); ++i) {
|
for (size_t i = 0; i < util::size(this->running_threads); ++i) {
|
||||||
if (this->running_threads[i] == thread) {
|
if (this->running_threads[i] == thread) {
|
||||||
|
|
|
@ -51,11 +51,8 @@ namespace ams::kern {
|
||||||
/* Overridden virtual functions. */
|
/* Overridden virtual functions. */
|
||||||
virtual void Destroy() override;
|
virtual void Destroy() override;
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
/* TODO: More of KServerPort. */
|
|
||||||
private:
|
private:
|
||||||
void CleanupSessions();
|
void CleanupSessions();
|
||||||
/* TODO: This is a placeholder definition. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
/* TODO: More of KServerSession. */
|
|
||||||
Result OnRequest(KSessionRequest *request);
|
Result OnRequest(KSessionRequest *request);
|
||||||
|
|
||||||
Result ReceiveRequest(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);
|
Result ReceiveRequest(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);
|
||||||
|
|
|
@ -203,7 +203,6 @@ namespace ams::kern {
|
||||||
constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ }
|
constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ }
|
||||||
|
|
||||||
virtual ~KThread() { /* ... */ }
|
virtual ~KThread() { /* ... */ }
|
||||||
/* TODO: Is a constexpr KThread() possible? */
|
|
||||||
|
|
||||||
Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type);
|
Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type);
|
||||||
|
|
||||||
|
@ -497,8 +496,6 @@ namespace ams::kern {
|
||||||
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(this->kernel_stack_top) - 1; }
|
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(this->kernel_stack_top) - 1; }
|
||||||
ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; }
|
ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; }
|
||||||
|
|
||||||
/* TODO: This is kind of a placeholder definition. */
|
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsTerminationRequested() const {
|
ALWAYS_INLINE bool IsTerminationRequested() const {
|
||||||
return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
|
return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,8 +124,6 @@ namespace ams::kern {
|
||||||
return this->address != rhs;
|
return this->address != rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: <, <=, >, >= against uintptr_t? would need to be declared outside of class. Maybe worth it. */
|
|
||||||
|
|
||||||
/* Allow getting the address explicitly, for use in accessors. */
|
/* Allow getting the address explicitly, for use in accessors. */
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetValue() const {
|
constexpr ALWAYS_INLINE uintptr_t GetValue() const {
|
||||||
return this->address;
|
return this->address;
|
||||||
|
@ -244,6 +242,5 @@ namespace ams::kern {
|
||||||
/* Accessors. */
|
/* Accessors. */
|
||||||
static_assert(15 == GetInteger(KPhysicalAddress(15)));
|
static_assert(15 == GetInteger(KPhysicalAddress(15)));
|
||||||
static_assert(0 == GetInteger(Null<KPhysicalAddress>));
|
static_assert(0 == GetInteger(Null<KPhysicalAddress>));
|
||||||
/* TODO: reinterpret_cast<> not valid in a constant expression, can't test get pointers. */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
/* Send KDebug event for this thread's creation. */
|
/* Send KDebug event for this thread's creation. */
|
||||||
{
|
{
|
||||||
KScopedInterruptEnable ei;
|
KScopedInterruptEnable ei;
|
||||||
/* TODO */
|
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()), GetCurrentThread().GetEntrypoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle any pending dpc. */
|
/* Handle any pending dpc. */
|
||||||
|
@ -263,4 +263,8 @@ namespace ams::kern::arch::arm64 {
|
||||||
out->fpsr = t_ctx->GetFpsr();
|
out->fpsr = t_ctx->GetFpsr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KThreadContext::OnThreadTerminating(const KThread *thread) {
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,8 +129,7 @@ namespace ams::kern::init {
|
||||||
|
|
||||||
/* NOTE: This can't be used right now because we don't have all these types implemented. */
|
/* NOTE: This can't be used right now because we don't have all these types implemented. */
|
||||||
/* Once we do, uncomment the following and stop using the hardcoded size. */
|
/* Once we do, uncomment the following and stop using the hardcoded size. */
|
||||||
/* TODO: FOREACH_SLAB_TYPE(ADD_SLAB_SIZE) */
|
FOREACH_SLAB_TYPE(ADD_SLAB_SIZE)
|
||||||
size = 0x647000;
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KClientPort::IsSignaled() const {
|
bool KClientPort::IsSignaled() const {
|
||||||
/* TODO: Check preconditions later. */
|
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
return this->num_sessions < this->max_sessions;
|
return this->num_sessions < this->max_sessions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,7 @@ namespace ams::kern {
|
||||||
this->old_process_state = this->process->SetDebugObject(this);
|
this->old_process_state = this->process->SetDebugObject(this);
|
||||||
|
|
||||||
/* Send an event for our attaching to the process. */
|
/* Send an event for our attaching to the process. */
|
||||||
this->PushDebugEvent(ams::svc::DebugEvent_AttachProcess);
|
this->PushDebugEvent(ams::svc::DebugEvent_CreateProcess);
|
||||||
|
|
||||||
/* Send events for attaching to each thread in the process. */
|
/* Send events for attaching to each thread in the process. */
|
||||||
{
|
{
|
||||||
|
@ -320,7 +320,7 @@ namespace ams::kern {
|
||||||
it->SetDebugAttached();
|
it->SetDebugAttached();
|
||||||
|
|
||||||
/* Send the event. */
|
/* Send the event. */
|
||||||
this->PushDebugEvent(ams::svc::DebugEvent_AttachThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()), it->GetEntrypoint());
|
this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()), it->GetEntrypoint());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,12 +561,12 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Set event specific fields. */
|
/* Set event specific fields. */
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case ams::svc::DebugEvent_AttachProcess:
|
case ams::svc::DebugEvent_CreateProcess:
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_AttachThread:
|
case ams::svc::DebugEvent_CreateThread:
|
||||||
{
|
{
|
||||||
/* Set the thread id. */
|
/* Set the thread id. */
|
||||||
info->thread_id = param0;
|
info->thread_id = param0;
|
||||||
|
@ -584,7 +584,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Clear the thread id and flags. */
|
/* Clear the thread id and flags. */
|
||||||
info->thread_id = 0;
|
info->thread_id = 0;
|
||||||
info->flags = 0 /* TODO: enum this in ams::svc */;
|
info->flags = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_ExitThread:
|
case ams::svc::DebugEvent_ExitThread:
|
||||||
|
@ -720,21 +720,21 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Set event specific fields. */
|
/* Set event specific fields. */
|
||||||
switch (info->event) {
|
switch (info->event) {
|
||||||
case ams::svc::DebugEvent_AttachProcess:
|
case ams::svc::DebugEvent_CreateProcess:
|
||||||
{
|
{
|
||||||
out->info.attach_process.program_id = process->GetProgramId();
|
out->info.create_process.program_id = process->GetProgramId();
|
||||||
out->info.attach_process.process_id = process->GetId();
|
out->info.create_process.process_id = process->GetId();
|
||||||
out->info.attach_process.flags = process->GetCreateProcessFlags();
|
out->info.create_process.flags = process->GetCreateProcessFlags();
|
||||||
out->info.attach_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress());
|
out->info.create_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress());
|
||||||
|
|
||||||
std::memcpy(out->info.attach_process.name, process->GetName(), sizeof(out->info.attach_process.name));
|
std::memcpy(out->info.create_process.name, process->GetName(), sizeof(out->info.create_process.name));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_AttachThread:
|
case ams::svc::DebugEvent_CreateThread:
|
||||||
{
|
{
|
||||||
out->info.attach_thread.thread_id = info->info.create_thread.thread_id;
|
out->info.create_thread.thread_id = info->info.create_thread.thread_id;
|
||||||
out->info.attach_thread.tls_address = info->info.create_thread.tls_address;
|
out->info.create_thread.tls_address = info->info.create_thread.tls_address;
|
||||||
out->info.attach_thread.entrypoint = info->info.create_thread.entrypoint;
|
out->info.create_thread.entrypoint = info->info.create_thread.entrypoint;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_ExitProcess:
|
case ams::svc::DebugEvent_ExitProcess:
|
||||||
|
@ -882,8 +882,8 @@ namespace ams::kern {
|
||||||
/* Get the current process. */
|
/* Get the current process. */
|
||||||
KProcess *process = GetCurrentProcessPointer();
|
KProcess *process = GetCurrentProcessPointer();
|
||||||
|
|
||||||
/* If the event is AttachThread and we've already attached, there's nothing to do. */
|
/* If the event is CreateThread and we've already attached, there's nothing to do. */
|
||||||
if (event == ams::svc::DebugEvent_AttachThread) {
|
if (event == ams::svc::DebugEvent_CreateThread) {
|
||||||
R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger());
|
R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ namespace ams::kern {
|
||||||
constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores);
|
constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores);
|
||||||
constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize;
|
constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize;
|
||||||
constexpr size_t CoreLocalRegionBoundsAlign = 1_GB;
|
constexpr size_t CoreLocalRegionBoundsAlign = 1_GB;
|
||||||
/* TODO: static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion)); */
|
static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion));
|
||||||
|
|
||||||
KVirtualAddress GetCoreLocalRegionVirtualAddress() {
|
KVirtualAddress GetCoreLocalRegionVirtualAddress() {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
@ -999,8 +999,8 @@ namespace ams::kern {
|
||||||
if (address == Null<KProcessAddress>) {
|
if (address == Null<KProcessAddress>) {
|
||||||
/* NOTE: Nintendo does not account for guard pages here. */
|
/* NOTE: Nintendo does not account for guard pages here. */
|
||||||
/* This may theoretically cause an offset to be chosen that cannot be mapped. */
|
/* This may theoretically cause an offset to be chosen that cannot be mapped. */
|
||||||
/* TODO: Should we account for guard pages? */
|
/* We will account for guard pages. */
|
||||||
const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages);
|
const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages);
|
||||||
address = this->memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages);
|
address = this->memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,9 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
if (this->state.should_count_idle) {
|
if (this->state.should_count_idle) {
|
||||||
if (AMS_LIKELY(highest_thread != nullptr)) {
|
if (AMS_LIKELY(highest_thread != nullptr)) {
|
||||||
/* TODO: Set parent process's idle count if it exists. */
|
if (KProcess *process = highest_thread->GetOwnerProcess(); process != nullptr) {
|
||||||
|
process->SetRunningThread(this->core_id, highest_thread, this->state.idle_count);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this->state.idle_count++;
|
this->state.idle_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KServerPort::IsSignaled() const {
|
bool KServerPort::IsSignaled() const {
|
||||||
/* TODO: Check preconditions later. */
|
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
if (this->IsLight()) {
|
if (this->IsLight()) {
|
||||||
return !this->light_session_list.empty();
|
return !this->light_session_list.empty();
|
||||||
|
|
|
@ -32,6 +32,19 @@ namespace ams::kern {
|
||||||
void KSynchronizationObject::Finalize() {
|
void KSynchronizationObject::Finalize() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* If auditing, ensure that the object has no waiters. */
|
||||||
|
#if defined(MESOSPHERE_BUILD_FOR_AUDITING)
|
||||||
|
{
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
auto end = this->end();
|
||||||
|
for (auto it = this->begin(); it != end; ++it) {
|
||||||
|
KThread *thread = std::addressof(*it);
|
||||||
|
MESOSPHERE_LOG("KSynchronizationObject::Finalize(%p) with %p (id=%ld) waiting.\n", this, thread, thread->GetId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
this->OnFinalizeSynchronizationObject();
|
this->OnFinalizeSynchronizationObject();
|
||||||
KAutoObject::Finalize();
|
KAutoObject::Finalize();
|
||||||
}
|
}
|
||||||
|
@ -39,7 +52,33 @@ namespace ams::kern {
|
||||||
void KSynchronizationObject::DebugWaiters() {
|
void KSynchronizationObject::DebugWaiters() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
MESOSPHERE_TODO("Do useful debug operation here.");
|
/* If debugging, dump the list of waiters. */
|
||||||
|
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
|
||||||
|
{
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
MESOSPHERE_RELEASE_LOG("Threads waiting on %p:\n", this);
|
||||||
|
|
||||||
|
bool has_waiters = false;
|
||||||
|
auto end = this->end();
|
||||||
|
for (auto it = this->begin(); it != end; ++it) {
|
||||||
|
KThread *thread = std::addressof(*it);
|
||||||
|
|
||||||
|
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr) {
|
||||||
|
MESOSPHERE_RELEASE_LOG(" %p tid=%ld pid=%ld (%s)\n", thread, thread->GetId(), process->GetId(), process->GetName());
|
||||||
|
} else {
|
||||||
|
MESOSPHERE_RELEASE_LOG(" %p tid=%ld (Kernel)\n", thread, thread->GetId());
|
||||||
|
}
|
||||||
|
|
||||||
|
has_waiters = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't have any waiters, print so. */
|
||||||
|
if (!has_waiters) {
|
||||||
|
MESOSPHERE_RELEASE_LOG(" None\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
KSynchronizationObject::iterator KSynchronizationObject::RegisterWaitingThread(KThread *thread) {
|
KSynchronizationObject::iterator KSynchronizationObject::RegisterWaitingThread(KThread *thread) {
|
||||||
|
|
|
@ -344,7 +344,8 @@ namespace ams::kern {
|
||||||
this->signaled = true;
|
this->signaled = true;
|
||||||
this->NotifyAvailable();
|
this->NotifyAvailable();
|
||||||
|
|
||||||
/* TODO: On Thread Termination handler */
|
/* Call the on thread termination handler. */
|
||||||
|
KThreadContext::OnThreadTerminating(this);
|
||||||
|
|
||||||
/* Clear previous thread in KScheduler. */
|
/* Clear previous thread in KScheduler. */
|
||||||
KScheduler::ClearPreviousThread(this);
|
KScheduler::ClearPreviousThread(this);
|
||||||
|
|
|
@ -396,8 +396,8 @@ namespace ams::svc {
|
||||||
|
|
||||||
/* Debug types. */
|
/* Debug types. */
|
||||||
enum DebugEvent : u32 {
|
enum DebugEvent : u32 {
|
||||||
DebugEvent_AttachProcess = 0,
|
DebugEvent_CreateProcess = 0,
|
||||||
DebugEvent_AttachThread = 1,
|
DebugEvent_CreateThread = 1,
|
||||||
DebugEvent_ExitProcess = 2,
|
DebugEvent_ExitProcess = 2,
|
||||||
DebugEvent_ExitThread = 3,
|
DebugEvent_ExitThread = 3,
|
||||||
DebugEvent_Exception = 4,
|
DebugEvent_Exception = 4,
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ams::svc {
|
||||||
|
|
||||||
namespace lp64 {
|
namespace lp64 {
|
||||||
|
|
||||||
struct DebugInfoAttachProcess {
|
struct DebugInfoCreateProcess {
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
u64 process_id;
|
u64 process_id;
|
||||||
char name[0xC];
|
char name[0xC];
|
||||||
|
@ -28,7 +28,7 @@ namespace ams::svc {
|
||||||
u64 user_exception_context_address; /* 5.0.0+ */
|
u64 user_exception_context_address; /* 5.0.0+ */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DebugInfoAttachThread {
|
struct DebugInfoCreateThread {
|
||||||
u64 thread_id;
|
u64 thread_id;
|
||||||
u64 tls_address;
|
u64 tls_address;
|
||||||
u64 entrypoint;
|
u64 entrypoint;
|
||||||
|
@ -91,8 +91,8 @@ namespace ams::svc {
|
||||||
};
|
};
|
||||||
|
|
||||||
union DebugInfo {
|
union DebugInfo {
|
||||||
DebugInfoAttachProcess attach_process;
|
DebugInfoCreateProcess create_process;
|
||||||
DebugInfoAttachThread attach_thread;
|
DebugInfoCreateThread create_thread;
|
||||||
DebugInfoExitProcess exit_process;
|
DebugInfoExitProcess exit_process;
|
||||||
DebugInfoExitThread exit_thread;
|
DebugInfoExitThread exit_thread;
|
||||||
DebugInfoException exception;
|
DebugInfoException exception;
|
||||||
|
@ -110,7 +110,7 @@ namespace ams::svc {
|
||||||
|
|
||||||
namespace ilp32 {
|
namespace ilp32 {
|
||||||
|
|
||||||
struct DebugInfoAttachProcess {
|
struct DebugInfoCreateProcess {
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
u64 process_id;
|
u64 process_id;
|
||||||
char name[0xC];
|
char name[0xC];
|
||||||
|
@ -118,7 +118,7 @@ namespace ams::svc {
|
||||||
u32 user_exception_context_address; /* 5.0.0+ */
|
u32 user_exception_context_address; /* 5.0.0+ */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DebugInfoAttachThread {
|
struct DebugInfoCreateThread {
|
||||||
u64 thread_id;
|
u64 thread_id;
|
||||||
u32 tls_address;
|
u32 tls_address;
|
||||||
u32 entrypoint;
|
u32 entrypoint;
|
||||||
|
@ -181,8 +181,8 @@ namespace ams::svc {
|
||||||
};
|
};
|
||||||
|
|
||||||
union DebugInfo {
|
union DebugInfo {
|
||||||
DebugInfoAttachProcess attach_process;
|
DebugInfoCreateProcess create_process;
|
||||||
DebugInfoAttachThread attach_thread;
|
DebugInfoCreateThread create_thread;
|
||||||
DebugInfoExitProcess exit_process;
|
DebugInfoExitProcess exit_process;
|
||||||
DebugInfoExitThread exit_thread;
|
DebugInfoExitThread exit_thread;
|
||||||
DebugInfoException exception;
|
DebugInfoException exception;
|
||||||
|
|
|
@ -55,7 +55,6 @@ namespace ams::kern::init::loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout) {
|
void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout) {
|
||||||
/* TODO: Proper secure monitor call. */
|
|
||||||
KPhysicalAddress correct_base = KSystemControl::Init::GetKernelPhysicalBaseAddress(base_address);
|
KPhysicalAddress correct_base = KSystemControl::Init::GetKernelPhysicalBaseAddress(base_address);
|
||||||
if (correct_base != base_address) {
|
if (correct_base != base_address) {
|
||||||
const uintptr_t diff = GetInteger(correct_base) - base_address;
|
const uintptr_t diff = GetInteger(correct_base) - base_address;
|
||||||
|
|
|
@ -163,11 +163,11 @@ namespace ams::creport {
|
||||||
svc::DebugEventInfo d;
|
svc::DebugEventInfo d;
|
||||||
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), this->debug_handle))) {
|
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), this->debug_handle))) {
|
||||||
switch (d.type) {
|
switch (d.type) {
|
||||||
case svc::DebugEvent_AttachProcess:
|
case svc::DebugEvent_CreateProcess:
|
||||||
this->HandleDebugEventInfoAttachProcess(d);
|
this->HandleDebugEventInfoCreateProcess(d);
|
||||||
break;
|
break;
|
||||||
case svc::DebugEvent_AttachThread:
|
case svc::DebugEvent_CreateThread:
|
||||||
this->HandleDebugEventInfoAttachThread(d);
|
this->HandleDebugEventInfoCreateThread(d);
|
||||||
break;
|
break;
|
||||||
case svc::DebugEvent_Exception:
|
case svc::DebugEvent_Exception:
|
||||||
this->HandleDebugEventInfoException(d);
|
this->HandleDebugEventInfoException(d);
|
||||||
|
@ -182,8 +182,8 @@ namespace ams::creport {
|
||||||
this->crashed_thread.ReadFromProcess(this->debug_handle, this->thread_tls_map, this->crashed_thread_id, this->Is64Bit());
|
this->crashed_thread.ReadFromProcess(this->debug_handle, this->thread_tls_map, this->crashed_thread_id, this->Is64Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashReport::HandleDebugEventInfoAttachProcess(const svc::DebugEventInfo &d) {
|
void CrashReport::HandleDebugEventInfoCreateProcess(const svc::DebugEventInfo &d) {
|
||||||
this->process_info = d.info.attach_process;
|
this->process_info = d.info.create_process;
|
||||||
|
|
||||||
/* On 5.0.0+, we want to parse out a dying message from application crashes. */
|
/* On 5.0.0+, we want to parse out a dying message from application crashes. */
|
||||||
if (hos::GetVersion() < hos::Version_5_0_0 || !IsApplication()) {
|
if (hos::GetVersion() < hos::Version_5_0_0 || !IsApplication()) {
|
||||||
|
@ -217,9 +217,9 @@ namespace ams::creport {
|
||||||
this->dying_message_size = userdata_size;
|
this->dying_message_size = userdata_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashReport::HandleDebugEventInfoAttachThread(const svc::DebugEventInfo &d) {
|
void CrashReport::HandleDebugEventInfoCreateThread(const svc::DebugEventInfo &d) {
|
||||||
/* Save info on the thread's TLS address for later. */
|
/* Save info on the thread's TLS address for later. */
|
||||||
this->thread_tls_map[d.info.attach_thread.thread_id] = d.info.attach_thread.tls_address;
|
this->thread_tls_map[d.info.create_thread.thread_id] = d.info.create_thread.tls_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
|
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace ams::creport {
|
||||||
std::map<u64, u64> thread_tls_map;
|
std::map<u64, u64> thread_tls_map;
|
||||||
|
|
||||||
/* Attach process info. */
|
/* Attach process info. */
|
||||||
svc::DebugInfoAttachProcess process_info = {};
|
svc::DebugInfoCreateProcess process_info = {};
|
||||||
u64 dying_message_address = 0;
|
u64 dying_message_address = 0;
|
||||||
u64 dying_message_size = 0;
|
u64 dying_message_size = 0;
|
||||||
u8 *dying_message = nullptr;
|
u8 *dying_message = nullptr;
|
||||||
|
@ -95,8 +95,8 @@ namespace ams::creport {
|
||||||
private:
|
private:
|
||||||
void ProcessExceptions();
|
void ProcessExceptions();
|
||||||
void ProcessDyingMessage();
|
void ProcessDyingMessage();
|
||||||
void HandleDebugEventInfoAttachProcess(const svc::DebugEventInfo &d);
|
void HandleDebugEventInfoCreateProcess(const svc::DebugEventInfo &d);
|
||||||
void HandleDebugEventInfoAttachThread(const svc::DebugEventInfo &d);
|
void HandleDebugEventInfoCreateThread(const svc::DebugEventInfo &d);
|
||||||
void HandleDebugEventInfoException(const svc::DebugEventInfo &d);
|
void HandleDebugEventInfoException(const svc::DebugEventInfo &d);
|
||||||
|
|
||||||
void SaveToFile(ScopedFile &file);
|
void SaveToFile(ScopedFile &file);
|
||||||
|
|
|
@ -56,11 +56,11 @@ namespace ams::dmnt::cheat::impl {
|
||||||
size_t target_core = NumCores - 1;
|
size_t target_core = NumCores - 1;
|
||||||
|
|
||||||
/* Retrieve correct core for new thread event. */
|
/* Retrieve correct core for new thread event. */
|
||||||
if (dbg_event.type == svc::DebugEvent_AttachThread) {
|
if (dbg_event.type == svc::DebugEvent_CreateThread) {
|
||||||
u64 out64 = 0;
|
u64 out64 = 0;
|
||||||
u32 out32 = 0;
|
u32 out32 = 0;
|
||||||
|
|
||||||
R_TRY_CATCH(svcGetDebugThreadParam(&out64, &out32, debug_handle, dbg_event.info.attach_thread.thread_id, DebugThreadParam_CurrentCore)) {
|
R_TRY_CATCH(svcGetDebugThreadParam(&out64, &out32, debug_handle, dbg_event.info.create_thread.thread_id, DebugThreadParam_CurrentCore)) {
|
||||||
R_CATCH_RETHROW(svc::ResultProcessTerminated)
|
R_CATCH_RETHROW(svc::ResultProcessTerminated)
|
||||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
svc::DebugEventInfo d;
|
svc::DebugEventInfo d;
|
||||||
size_t target_core = NumCores - 1;
|
size_t target_core = NumCores - 1;
|
||||||
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), cheat_dbg_hnd))) {
|
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), cheat_dbg_hnd))) {
|
||||||
if (d.type == svc::DebugEvent_AttachThread) {
|
if (d.type == svc::DebugEvent_CreateThread) {
|
||||||
R_TRY(GetTargetCore(std::addressof(target_core), d, cheat_dbg_hnd));
|
R_TRY(GetTargetCore(std::addressof(target_core), d, cheat_dbg_hnd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,17 +178,17 @@ namespace ams::fatal::srv {
|
||||||
/* First things first, check if process is 64 bits, and get list of thread infos. */
|
/* First things first, check if process is 64 bits, and get list of thread infos. */
|
||||||
std::unordered_map<u64, u64> thread_id_to_tls;
|
std::unordered_map<u64, u64> thread_id_to_tls;
|
||||||
{
|
{
|
||||||
bool got_attach_process = false;
|
bool got_create_process = false;
|
||||||
svc::DebugEventInfo d;
|
svc::DebugEventInfo d;
|
||||||
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()))) {
|
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()))) {
|
||||||
switch (d.type) {
|
switch (d.type) {
|
||||||
case svc::DebugEvent_AttachProcess:
|
case svc::DebugEvent_CreateProcess:
|
||||||
ctx->cpu_ctx.architecture = (d.info.attach_process.flags & 1) ? CpuContext::Architecture_Aarch64 : CpuContext::Architecture_Aarch32;
|
ctx->cpu_ctx.architecture = (d.info.create_process.flags & 1) ? CpuContext::Architecture_Aarch64 : CpuContext::Architecture_Aarch32;
|
||||||
std::memcpy(ctx->proc_name, d.info.attach_process.name, sizeof(d.info.attach_process.name));
|
std::memcpy(ctx->proc_name, d.info.create_process.name, sizeof(d.info.create_process.name));
|
||||||
got_attach_process = true;
|
got_create_process = true;
|
||||||
break;
|
break;
|
||||||
case svc::DebugEvent_AttachThread:
|
case svc::DebugEvent_CreateThread:
|
||||||
thread_id_to_tls[d.info.attach_thread.thread_id] = d.info.attach_thread.tls_address;
|
thread_id_to_tls[d.info.create_thread.thread_id] = d.info.create_thread.tls_address;
|
||||||
break;
|
break;
|
||||||
case svc::DebugEvent_Exception:
|
case svc::DebugEvent_Exception:
|
||||||
case svc::DebugEvent_ExitProcess:
|
case svc::DebugEvent_ExitProcess:
|
||||||
|
@ -197,7 +197,7 @@ namespace ams::fatal::srv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!got_attach_process) {
|
if (!got_create_process) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,8 @@ namespace {
|
||||||
svc::DebugEventInfo d;
|
svc::DebugEventInfo d;
|
||||||
while (true) {
|
while (true) {
|
||||||
R_ABORT_UNLESS(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
|
R_ABORT_UNLESS(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
|
||||||
if (d.type == svc::DebugEvent_AttachProcess) {
|
if (d.type == svc::DebugEvent_CreateProcess) {
|
||||||
return ncm::ProgramId{d.info.attach_process.program_id};
|
return ncm::ProgramId{d.info.create_process.program_id};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue