util::unique_lock, update loader to new sf semantics

This commit is contained in:
Michael Scire 2021-01-18 06:18:14 -08:00 committed by SciresM
parent 3761f80592
commit e4e278bb3d
9 changed files with 262 additions and 39 deletions

View file

@ -18,7 +18,7 @@
namespace ams::ldr {
class LoaderService final {
class LoaderService {
public:
/* Official commands. */
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);

View file

@ -23,7 +23,7 @@ extern "C" {
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x8000
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
@ -35,6 +35,9 @@ extern "C" {
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
void __libnx_exception_handler(ThreadExceptionDump *ctx);
void *__libnx_thread_alloc(size_t size);
void __libnx_thread_free(void *mem);
}
namespace ams {
@ -55,6 +58,78 @@ void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
namespace ams::ldr {
namespace {
constinit u8 g_heap_memory[16_KB];
lmem::HeapHandle g_server_heap_handle;
constinit ams::sf::ExpHeapAllocator g_server_allocator;
void *Allocate(size_t size) {
return lmem::AllocateFromExpHeap(g_server_heap_handle, size);
}
void Deallocate(void *p, size_t size) {
return lmem::FreeToExpHeap(g_server_heap_handle, p);
}
void InitializeHeap() {
g_server_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_None);
g_server_allocator.Attach(g_server_heap_handle);
}
}
namespace {
struct ServerOptions {
static constexpr size_t PointerBufferSize = 0x400;
static constexpr size_t MaxDomains = 0;
static constexpr size_t MaxDomainObjects = 0;
};
/* ldr:pm, ldr:shel, ldr:dmnt. */
enum PortIndex {
PortIndex_ProcessManager,
PortIndex_Shell,
PortIndex_DebugMonitor,
PortIndex_Count,
};
constexpr sm::ServiceName ProcessManagerServiceName = sm::ServiceName::Encode("ldr:pm");
constexpr size_t ProcessManagerMaxSessions = 1;
constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("ldr:shel");
constexpr size_t ShellMaxSessions = 3;
constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ldr:dmnt");
constexpr size_t DebugMonitorMaxSessions = 3;
constinit sf::UnmanagedServiceObject<impl::IProcessManagerInterface, LoaderService> g_pm_service;
constinit sf::UnmanagedServiceObject<impl::IShellInterface, LoaderService> g_shell_service;
constinit sf::UnmanagedServiceObject<impl::IDebugMonitorInterface, LoaderService> g_dmnt_service;
constexpr size_t MaxSessions = ProcessManagerMaxSessions + ShellMaxSessions + DebugMonitorMaxSessions + 1;
using ServerManager = ams::sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions>;
ServerManager g_server_manager;
void RegisterServiceSessions() {
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_pm_service.GetShared(), ProcessManagerServiceName, ProcessManagerMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_shell_service.GetShared(), ShellServiceName, ShellMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_dmnt_service.GetShared(), DebugMonitorServiceName, DebugMonitorMaxSessions));
}
void LoopProcess() {
g_server_manager.LoopProcess();
}
}
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
@ -65,11 +140,15 @@ void __libnx_initheap(void) {
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
ams::ldr::InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(ldr::Allocate, ldr::Deallocate);
/* Initialize services we need. */
sm::DoWithSession([&]() {
R_ABORT_UNLESS(fsInitialize());
@ -89,28 +168,32 @@ void __appExit(void) {
fsExit();
}
namespace {
namespace ams {
struct ServerOptions {
static constexpr size_t PointerBufferSize = 0x400;
static constexpr size_t MaxDomains = 0;
static constexpr size_t MaxDomainObjects = 0;
};
void *Malloc(size_t size) {
AMS_ABORT("ams::Malloc was called");
}
constexpr sm::ServiceName ProcessManagerServiceName = sm::ServiceName::Encode("ldr:pm");
constexpr size_t ProcessManagerMaxSessions = 1;
void Free(void *ptr) {
AMS_ABORT("ams::Free was called");
}
constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("ldr:shel");
constexpr size_t ShellMaxSessions = 3;
}
constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ldr:dmnt");
constexpr size_t DebugMonitorMaxSessions = 3;
void *operator new(size_t size) {
return ldr::Allocate(size);
}
/* ldr:pm, ldr:shel, ldr:dmnt. */
constexpr size_t NumServers = 3;
constexpr size_t MaxSessions = ProcessManagerMaxSessions + ShellMaxSessions + DebugMonitorMaxSessions + 1;
sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions> g_server_manager;
void operator delete(void *p) {
return ldr::Deallocate(p, 0);
}
void *__libnx_thread_alloc(size_t size) {
AMS_ABORT("__libnx_thread_alloc was called");
}
void __libnx_thread_free(void *mem) {
AMS_ABORT("__libnx_thread_free was called");
}
int main(int argc, char **argv)
@ -128,13 +211,11 @@ int main(int argc, char **argv)
ldr::SetDevelopmentForAntiDowngradeCheck(spl::IsDevelopment());
ldr::SetDevelopmentForAcidSignatureCheck(spl::IsDevelopment());
/* Add services to manager. */
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IProcessManagerInterface, ldr::LoaderService>(ProcessManagerServiceName, ProcessManagerMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IShellInterface, ldr::LoaderService>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IDebugMonitorInterface, ldr::LoaderService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
/* Register the loader services. */
ldr::RegisterServiceSessions();
/* Loop forever, servicing our services. */
g_server_manager.LoopProcess();
ldr::LoopProcess();
return 0;
}

View file

@ -654,7 +654,7 @@ namespace ams::ldr {
fssystem::DestroyExternalCode(loc.program_id);
/* Note that we've created the program. */
SetLaunchedProgram(loc.program_id);
SetLaunchedBootProgram(loc.program_id);
/* Move the process handle to output. */
*out = info.process_handle.Move();