From 7fed8a4428b6cec29ed5b9a55e8bcde0dbad8c5b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Apr 2018 16:24:40 -0600 Subject: [PATCH] Stratosphere: Add debugging to loader, it can now be talked to on console successfully. --- stratosphere/loader/source/iwaitable.hpp | 7 ++++++ .../loader/source/ldr_debug_monitor.cpp | 9 ++++--- .../loader/source/ldr_launch_queue.cpp | 6 ++++- stratosphere/loader/source/ldr_main.cpp | 6 +++-- stratosphere/loader/source/serviceserver.hpp | 7 +++++- stratosphere/loader/source/servicesession.hpp | 25 ++++++++++++------- .../loader/source/waitablemanager.cpp | 2 ++ 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/stratosphere/loader/source/iwaitable.hpp b/stratosphere/loader/source/iwaitable.hpp index b14d62b91..f124ae696 100644 --- a/stratosphere/loader/source/iwaitable.hpp +++ b/stratosphere/loader/source/iwaitable.hpp @@ -18,6 +18,13 @@ class IWaitable { return this->parent_waitable != NULL; } + void set_parent(IWaitable *p) { + if (has_parent()) { + /* TODO: Panic? */ + } + this->parent_waitable = p; + } + IWaitable *get_parent() { return this->parent_waitable; } diff --git a/stratosphere/loader/source/ldr_debug_monitor.cpp b/stratosphere/loader/source/ldr_debug_monitor.cpp index a19006c30..c614e04a5 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.cpp +++ b/stratosphere/loader/source/ldr_debug_monitor.cpp @@ -1,4 +1,5 @@ #include +#include #include "ldr_debug_monitor.hpp" #include "ldr_launch_queue.hpp" @@ -6,6 +7,8 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 Result rc = 0xF601; + fprintf(stderr, "TLS: %p\n", armGetTls()); + /* TODO: Prepare SFCO. */ switch ((DebugMonitorServiceCmd)cmd_id) { @@ -17,8 +20,8 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 rc = add_title_to_launch_queue(((u64 *)in_rawdata)[0], (const char *)r->Statics[0], r->StaticSizes[0]); - *out_raw_data_count = 0; - + *out_raw_data_count = 4; + break; case Dmnt_Cmd_ClearLaunchQueue: if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) { @@ -26,7 +29,7 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 } rc = clear_launch_queue(); - *out_raw_data_count = 0; + *out_raw_data_count = 4; break; case Dmnt_Cmd_GetNsoInfo: diff --git a/stratosphere/loader/source/ldr_launch_queue.cpp b/stratosphere/loader/source/ldr_launch_queue.cpp index 49736d10b..38e51a170 100644 --- a/stratosphere/loader/source/ldr_launch_queue.cpp +++ b/stratosphere/loader/source/ldr_launch_queue.cpp @@ -1,6 +1,6 @@ #include #include - +#include #include "ldr_launch_queue.hpp" @@ -18,6 +18,10 @@ namespace LaunchQueue { g_launch_queue[idx].tid = tid; g_launch_queue[idx].arg_size = arg_size; + + fprintf(stderr, "TID: %016llx, args: %p, size: %016llx\n", tid, args, arg_size); + fprintf(stderr, "Args: %s\n", args); + std::copy(args, args + arg_size, g_launch_queue[idx].args); return 0x0; } diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index bf3673240..58ccc3212 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -33,12 +33,14 @@ void __libnx_initheap(void) int main(int argc, char **argv) { + consoleDebugInit(debugDevice_SVC); + /* TODO: What's a good timeout value to use here? */ WaitableManager *server_manager = new WaitableManager(U64_MAX); /* Add services to manager. */ - server_manager->add_waitable(new ServiceServer("ldr:shel", 3)); - server_manager->add_waitable(new ServiceServer("ldr:dmnt", 2)); + server_manager->add_waitable(new ServiceServer("dbg:shel", 3)); + server_manager->add_waitable(new ServiceServer("dbg:dmnt", 2)); /* Loop forever, servicing our services. */ server_manager->process(); diff --git a/stratosphere/loader/source/serviceserver.hpp b/stratosphere/loader/source/serviceserver.hpp index 151023cbc..f1896fea0 100644 --- a/stratosphere/loader/source/serviceserver.hpp +++ b/stratosphere/loader/source/serviceserver.hpp @@ -19,7 +19,7 @@ class ServiceServer : public IWaitable { ServiceSession **sessions; public: - ServiceServer(const char *service_name, unsigned int max_s) { + ServiceServer(const char *service_name, unsigned int max_s) : max_sessions(max_s) { if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) { /* TODO: Panic. */ } @@ -91,8 +91,12 @@ class ServiceServer : public IWaitable { /* If this server's port was signaled, accept a new session. */ Handle session_h; svcAcceptSession(&session_h, this->port_handle); + + fprintf(stderr, "Accept %08X -> %08X\n", this->port_handle, session_h); + fprintf(stderr, "Sessions: %08X/%08X\n", this->num_sessions, this->max_sessions); if (this->num_sessions >= this->max_sessions) { + fprintf(stderr, "Closing because of max sessions...\n"); svcCloseHandle(session_h); return 0x10601; } @@ -105,6 +109,7 @@ class ServiceServer : public IWaitable { } this->sessions[i] = new ServiceSession(this, session_h, 0); + this->sessions[i]->set_parent(this); this->num_sessions++; return 0; } diff --git a/stratosphere/loader/source/servicesession.hpp b/stratosphere/loader/source/servicesession.hpp index c6b0bcd4e..19c1a522b 100644 --- a/stratosphere/loader/source/servicesession.hpp +++ b/stratosphere/loader/source/servicesession.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "iserviceobject.hpp" #include "iwaitable.hpp" @@ -70,6 +71,8 @@ class ServiceSession : public IWaitable { IpcParsedCommand r; IpcCommand c; + fprintf(stderr, "Doing ServiceSession parse...\n"); + ipcInitialize(&c); retval = ipcParse(&r); @@ -81,17 +84,21 @@ class ServiceSession : public IWaitable { out_words += extra_rawdata_count; } - struct { - u64 magic; - u64 retval; - } *raw; + if (retval != 0xF601) { + struct { + u64 magic; + u64 retval; + } *raw; - raw = (decltype(raw))ipcPrepareHeader(&c, out_words); + raw = (decltype(raw))ipcPrepareHeader(&c, out_words); - raw->magic = SFCO_MAGIC; - raw->retval = retval; - - rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0); + raw->magic = SFCO_MAGIC; + raw->retval = retval; + + rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0); + } else { + rc = retval; + } } return rc; diff --git a/stratosphere/loader/source/waitablemanager.cpp b/stratosphere/loader/source/waitablemanager.cpp index de9479b13..733740b36 100644 --- a/stratosphere/loader/source/waitablemanager.cpp +++ b/stratosphere/loader/source/waitablemanager.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "waitablemanager.hpp" @@ -44,6 +45,7 @@ void WaitableManager::process() { if (R_SUCCEEDED(rc)) { /* Handle a signaled waitable. */ /* TODO: What timeout should be passed here? */ + rc = signalables[handle_index]->handle_signaled(0); for (int i = 0; i < handle_index; i++) {