strat: use ams::Main() instead of main(argc, argv)

This commit is contained in:
Michael Scire 2021-10-07 17:44:54 -07:00
parent 6a53726833
commit ffc143860b
47 changed files with 2972 additions and 3609 deletions

View file

@ -26,7 +26,7 @@ CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
endif endif
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g -gdwarf-4 $(CXXFLAGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \ -Wl,--wrap,__cxa_throw \

View file

@ -12,7 +12,7 @@ export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g -gdwarf-4 $(CXXFLAGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \ -Wl,--wrap,__cxa_throw \

View file

@ -21,6 +21,15 @@ export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)
export CXXREQUIRED := -Wl,--require-defined,__libnx_initheap \
-Wl,--require-defined,__libnx_exception_handler \
-Wl,--require-defined,__libnx_alloc \
-Wl,--require-defined,__libnx_aligned_alloc \
-Wl,--require-defined,__libnx_free \
-Wl,--require-defined,__appInit \
-Wl,--require-defined,__appExit \
-Wl,--require-defined,argvSetup
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \ -Wl,--wrap,__cxa_throw \
-Wl,--wrap,__cxa_rethrow \ -Wl,--wrap,__cxa_rethrow \
@ -37,7 +46,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc \ -Wl,--wrap,_ZNSt11logic_errorC2EPKc \
-Wl,--wrap,exit -Wl,--wrap,exit
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $*.map)
export LIBS = -lstratosphere -lnx export LIBS = -lstratosphere -lnx

View file

@ -126,6 +126,9 @@ ams_environment_weak.o: CXXFLAGS += -fno-lto
pm_info_api_weak.o: CXXFLAGS += -fno-lto pm_info_api_weak.o: CXXFLAGS += -fno-lto
hos_stratosphere_api.o: CXXFLAGS += -fno-lto hos_stratosphere_api.o: CXXFLAGS += -fno-lto
init_operator_new.o: CXXFLAGS += -fno-lto
init_libnx_shim.os.horizon.o: CXXFLAGS += -fno-lto
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin %_bin.h %.bin.o : %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View file

@ -62,6 +62,7 @@
#include <stratosphere/htclow.hpp> #include <stratosphere/htclow.hpp>
#include <stratosphere/htcs.hpp> #include <stratosphere/htcs.hpp>
#include <stratosphere/i2c.hpp> #include <stratosphere/i2c.hpp>
#include <stratosphere/init.hpp>
#include <stratosphere/kvdb.hpp> #include <stratosphere/kvdb.hpp>
#include <stratosphere/ldr.hpp> #include <stratosphere/ldr.hpp>
#include <stratosphere/lr.hpp> #include <stratosphere/lr.hpp>

View file

@ -62,3 +62,4 @@
#include <stratosphere/fs/fs_system_data.hpp> #include <stratosphere/fs/fs_system_data.hpp>
#include <stratosphere/fs/fs_program_index_map_info.hpp> #include <stratosphere/fs/fs_program_index_map_info.hpp>
#include <stratosphere/fs/impl/fs_access_log_impl.hpp> #include <stratosphere/fs/impl/fs_access_log_impl.hpp>
#include <stratosphere/fs/fs_api.hpp>

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::fs {
void InitializeForSystem();
void InitializeWithMultiSessionForSystem();
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/init/init_malloc.hpp>

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::mem {
class StandardAllocator;
}
namespace ams::init {
void InitializeAllocator(void *address, size_t size, bool cache_enabled);
void InitializeAllocator(void *address, size_t size);
mem::StandardAllocator *GetAllocator();
}

View file

@ -52,3 +52,4 @@
#include <stratosphere/os/os_barrier.hpp> #include <stratosphere/os/os_barrier.hpp>
#include <stratosphere/os/os_io_region.hpp> #include <stratosphere/os/os_io_region.hpp>
#include <stratosphere/os/os_multiple_wait.hpp> #include <stratosphere/os/os_multiple_wait.hpp>
#include <stratosphere/os/os_argument.hpp>

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::os {
int GetHostArgc();
char **GetHostArgv();
}

View file

@ -75,7 +75,9 @@ namespace ams::erpt::srv {
g_heap_handle = lmem::CreateExpHeap(mem, mem_size, lmem::CreateOption_ThreadSafe); g_heap_handle = lmem::CreateExpHeap(mem, mem_size, lmem::CreateOption_ThreadSafe);
AMS_ABORT_UNLESS(g_heap_handle != nullptr); AMS_ABORT_UNLESS(g_heap_handle != nullptr);
fs::InitializeForSystem();
fs::SetAllocator(Allocate, DeallocateWithSize); fs::SetAllocator(Allocate, DeallocateWithSize);
fs::SetEnabledAutoAbort(false);
R_ABORT_UNLESS(fs::MountSdCardErrorReportDirectoryForAtmosphere(ReportOnSdStoragePath)); R_ABORT_UNLESS(fs::MountSdCardErrorReportDirectoryForAtmosphere(ReportOnSdStoragePath));

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
extern "C" {
extern u32 __nx_fs_num_sessions;
}
namespace ams::fs {
/* TODO: FileSystemProxySessionSetting */
void InitializeForSystem() {
__nx_fs_num_sessions = 1;
R_ABORT_UNLESS(::fsInitialize());
}
void InitializeWithMultiSessionForSystem() {
__nx_fs_num_sessions = 2;
R_ABORT_UNLESS(::fsInitialize());
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
extern "C" {
constinit u32 __nx_fs_num_sessions = 1;
constinit u32 __nx_applet_type = AppletType_None;
extern int __system_argc;
extern char** __system_argv;
alignas(16) constinit u8 __nx_exception_stack[::ams::os::MemoryPageSize];
constinit u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
}
namespace ams {
namespace hos {
void InitializeForStratosphere();
}
namespace init {
void InitializeSystemModule();
void FinalizeSystemModule();
void Startup();
}
void Main();
}
namespace {
constinit char *g_empty_argv = nullptr;
}
extern "C" void __libnx_exception_handler(ThreadExceptionDump *ctx) {
::ams::CrashHandler(ctx);
}
extern "C" void __libnx_initheap(void) {
/* Stratosphere system modules do not support newlib heap. */
}
extern "C" void __appInit(void) {
/* The very first thing all stratosphere code must do is initialize the os library. */
::ams::hos::InitializeForStratosphere();
}
extern "C" void __appExit(void) {
/* ... */
}
extern "C" void argvSetup(void) {
/* We don't use newlib argc/argv, so we can clear these. */
__system_argc = 0;
__system_argv = std::addressof(g_empty_argv);
}
extern "C" int main(int argc, char **argv) {
/* We don't use newlib argc/argv. */
AMS_UNUSED(argc, argv);
/* Perform remainder of logic with system module initialized. */
{
::ams::init::InitializeSystemModule();
ON_SCOPE_EXIT { ::ams::init::FinalizeSystemModule(); };
/* Perform miscellaneous startup. */
::ams::init::Startup();
/* Invoke ams main. */
::ams::Main();
}
}
extern "C" WEAK_SYMBOL void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
extern "C" WEAK_SYMBOL void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
extern "C" WEAK_SYMBOL void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}

View file

@ -0,0 +1,147 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
namespace ams::init {
namespace {
constinit void *g_malloc_region_address = nullptr;
constinit size_t g_malloc_region_size = 0;
constinit util::TypedStorage<mem::StandardAllocator> g_malloc_allocator;
}
void InitializeAllocator(void *address, size_t size, bool cache_enabled) {
/* Check pre-conditions. */
AMS_ABORT_UNLESS(g_malloc_region_size == 0);
AMS_ABORT_UNLESS(size > 0);
/* Construct malloc allocator. */
util::ConstructAt(g_malloc_allocator);
/* Initialize allocator. */
util::GetReference(g_malloc_allocator).Initialize(address, size, cache_enabled);
/* Set malloc globals. */
g_malloc_region_address = address;
g_malloc_region_size = size;
}
void InitializeAllocator(void *address, size_t size) {
return InitializeAllocator(address, size, false);
}
mem::StandardAllocator *GetAllocator() {
/* Check pre-conditions. */
AMS_ASSERT(g_malloc_region_size > 0);
return util::GetPointer(g_malloc_allocator);
}
}
extern "C" void *malloc(size_t size) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return nullptr;
}
/* Try to allocate. */
void *ptr = ::ams::util::GetReference(::ams::init::g_malloc_allocator).Allocate(size);
if (ptr == nullptr) {
errno = ENOMEM;
}
return ptr;
}
extern "C" void free(void *ptr) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return;
}
if (ptr != nullptr) {
::ams::util::GetReference(::ams::init::g_malloc_allocator).Free(ptr);
}
}
extern "C" void *calloc(size_t num, size_t size) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return nullptr;
}
/* Allocate the total needed space. */
const size_t total = num * size;
void *ptr = std::malloc(total);
/* Zero the memory if needed. */
if (ptr != nullptr) {
std::memset(ptr, 0, total);
} else {
errno = ENOMEM;
}
return ptr;
}
extern "C" void *realloc(void *ptr, size_t new_size) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return nullptr;
}
/* Try to reallocate. */
void *r = ::ams::util::GetReference(::ams::init::g_malloc_allocator).Reallocate(ptr, new_size);
if (r == nullptr) {
errno = ENOMEM;
}
return r;
}
extern "C" void *aligned_alloc(size_t align, size_t size) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return nullptr;
}
/* Try to allocate. */
void *ptr = ::ams::util::GetReference(::ams::init::g_malloc_allocator).Allocate(size, align);
if (ptr == nullptr) {
errno = ENOMEM;
}
return ptr;
}
extern "C" size_t malloc_usable_size(void *ptr) {
/* We require that an allocator region exists. */
if (::ams::init::g_malloc_region_size == 0) {
return 0;
}
/* Try to get the usable size. */
if (ptr == nullptr) {
errno = ENOMEM;
return 0;
}
return ::ams::util::GetReference(::ams::init::g_malloc_allocator).GetSizeOf(ptr);
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
WEAK_SYMBOL void *operator new(size_t size) {
return std::malloc(size);
}
WEAK_SYMBOL void *operator new(size_t size, const std::nothrow_t &) {
return std::malloc(size);
}
WEAK_SYMBOL void operator delete(void *p) {
return std::free(p);
}
WEAK_SYMBOL void operator delete(void *p, size_t) {
return std::free(p);
}
WEAK_SYMBOL void *operator new[](size_t size) {
return std::malloc(size);
}
WEAK_SYMBOL void *operator new[](size_t size, const std::nothrow_t &) {
return std::malloc(size);
}
WEAK_SYMBOL void operator delete[](void *p) {
return std::free(p);
}
WEAK_SYMBOL void operator delete[](void *p, size_t) {
return std::free(p);
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
namespace ams::init {
WEAK_SYMBOL void InitializeSystemModule() {
/* TODO: What should we do here, if anything? */
/* Nintendo does nndiagStartup(); nn::diag::InitializeSystemProcessAbortObserver(); */
}
WEAK_SYMBOL void FinalizeSystemModule() {
/* Do nothing by default. */
}
WEAK_SYMBOL void Startup() {
/* TODO: What should we do here, if anything? */
/* Nintendo determines heap size and does init::InitializeAllocator, as relevant. */
}
}

View file

@ -103,14 +103,15 @@ namespace ams::lm::srv {
} }
void FlushThreadFunction(void *) { void FlushThreadFunction(void *) {
/* Disable abort. */ /* Initialize fs. */
fs::InitializeWithMultiSessionForSystem();
fs::SetEnabledAutoAbort(false); fs::SetEnabledAutoAbort(false);
/* Create fs heap. */ /* Create fs heap. */
g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap, sizeof(g_fs_heap), lmem::CreateOption_None); g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap, sizeof(g_fs_heap), lmem::CreateOption_None);
AMS_ABORT_UNLESS(g_fs_heap_handle != nullptr); AMS_ABORT_UNLESS(g_fs_heap_handle != nullptr);
/* Set fs allocation functions. */ /* Set fs allocator functions. */
fs::SetAllocator(AllocateForFs, DeallocateForFs); fs::SetAllocator(AllocateForFs, DeallocateForFs);
/* Create SD card detection event notifier. */ /* Create SD card detection event notifier. */

View file

@ -353,7 +353,7 @@ namespace ams::mem::impl::heap {
std::scoped_lock lk(this->lock); std::scoped_lock lk(this->lock);
if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) { if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) {
*out = (span->aux.large.color[0] << 0) | (span->aux.large.color[1] << 0) | (span->aux.large.color[2] << 16); *out = (span->aux.large.color[0] << 0) | (span->aux.large.color[1] << 8) | (span->aux.large.color[2] << 16);
return 0; return 0;
} else { } else {
return EINVAL; return EINVAL;
@ -387,7 +387,7 @@ namespace ams::mem::impl::heap {
errno_t GetName(const void *ptr, char *dst, size_t dst_size) { errno_t GetName(const void *ptr, char *dst, size_t dst_size) {
std::scoped_lock lk(this->lock); std::scoped_lock lk(this->lock);
if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) { if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) {
strlcpy(dst, span->aux.large.name, dst_size); util::Strlcpy(dst, span->aux.large.name, dst_size);
return 0; return 0;
} else { } else {
return EINVAL; return EINVAL;
@ -397,7 +397,7 @@ namespace ams::mem::impl::heap {
errno_t SetName(const void *ptr, const char *name) { errno_t SetName(const void *ptr, const char *name) {
std::scoped_lock lk(this->lock); std::scoped_lock lk(this->lock);
if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) { if (Span *span = GetSpanFromPointer(std::addressof(this->span_table), ptr); span != nullptr && !span->page_class) {
strlcpy(span->aux.large.name, name, sizeof(span->aux.large.name)); util::Strlcpy(span->aux.large.name, name, sizeof(span->aux.large.name));
return 0; return 0;
} else { } else {
return EINVAL; return EINVAL;

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
namespace ams::os {
namespace {
struct CommandLineParameter {
int argc;
char **argv;
};
constinit const char *g_command_line_parameter_argv[2] = { "", nullptr };
constinit CommandLineParameter g_command_line_parameter = {
1,
const_cast<char **>(g_command_line_parameter_argv),
};
}
void SetHostArgc(int argc) {
g_command_line_parameter.argc = argc;
}
void SetHostArgv(char **argv) {
g_command_line_parameter.argv = argv;
}
int GetHostArgc() {
return g_command_line_parameter.argc;
}
char **GetHostArgv() {
return g_command_line_parameter.argv;
}
}

View file

@ -0,0 +1,172 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "impl/os_resource_manager.hpp"
extern "C" { extern u8 __argdata__[]; }
namespace ams::os {
namespace {
class MemoryArranger {
private:
uintptr_t m_address;
public:
constexpr MemoryArranger(uintptr_t address) : m_address(address) { /* ... */ }
template<typename T>
T *Arrange() {
this->Align(alignof(T));
return static_cast<T *>(this->Arrange(sizeof(T)));
}
void *Arrange(size_t size) {
const auto address = m_address;
m_address += size;
return reinterpret_cast<void *>(address);
}
void Align(size_t align) {
m_address = util::AlignUp(m_address, align);
}
char *ArrangeCharArray(size_t size) {
return reinterpret_cast<char *>(Arrange(size));
}
};
bool HasArguments(uintptr_t args_region) {
/* Check that the arguments region is read-write. */
svc::MemoryInfo mi;
svc::PageInfo pi;
if (R_FAILED(svc::QueryMemory(std::addressof(mi), std::addressof(pi), args_region))) {
return false;
}
return mi.permission == svc::MemoryPermission_ReadWrite;
}
const char *SkipSpace(const char *p, const char *end) {
while (p < end && std::isspace(*p)) { ++p; }
return p;
}
const char *GetTokenEnd(const char *p, const char *end) {
while (p < end && !std::isspace(*p)) { ++p; }
return p;
}
const char *GetQuotedTokenEnd(const char *p, const char *end) {
while (p < end && *p != '"') { ++p; }
return p;
}
int MakeArgv(char **out_argv_buf, char *arg_buf, const char *cmd_line, size_t cmd_line_size, int arg_max) {
/* Prepare to parse arguments. */
auto idx = 0;
auto src = cmd_line;
auto dst = arg_buf;
const auto end = src + cmd_line_size;
/* Parse all tokens. */
while (true) {
/* Advance past any spaces. */
src = SkipSpace(src, end);
if (src >= end) {
break;
}
/* Check that we don't have too many arguments. */
if (idx >= arg_max) {
break;
}
/* Find the start/end of the current argument token. */
const char *arg_end;
const char *src_next;
if (*src == '"') {
++src;
arg_end = GetQuotedTokenEnd(src, end);
src_next = arg_end + 1;
} else {
arg_end = GetTokenEnd(src, end);
src_next = arg_end;
}
/* Determine token size. */
const auto arg_size = arg_end - src;
/* Set the argv pointer. */
out_argv_buf[idx++] = dst;
/* Copy the argument. */
std::memcpy(dst, src, arg_size);
dst += arg_size;
/* Null-terminate the argument token. */
*(dst++) = '\x00';
/* Advance to next token. */
src = src_next;
}
/* Null terminate the final token. */
*(dst++) = '\x00';
/* Null terminate argv. */
out_argv_buf[idx] = nullptr;
return idx;
}
}
void SetHostArgc(int argc);
void SetHostArgv(char **argv);
void InitializeForStratosphereInternal() {
/* Initialize the global os resource manager. */
os::impl::ResourceManagerHolder::InitializeResourceManagerInstance();
/* Setup host argc/argv as needed. */
const uintptr_t args_region = reinterpret_cast<uintptr_t>(__argdata__);
if (HasArguments(args_region)) {
/* Create arguments memory arranger. */
MemoryArranger arranger(args_region);
/* Arrange. */
const auto &header = *arranger.Arrange<ldr::ProgramArguments>();
const char *cmd_line = arranger.ArrangeCharArray(header.arguments_size);
char *arg_buf = arranger.ArrangeCharArray(header.arguments_size + 2);
char **argv_buf = arranger.Arrange<char *>();
/* Determine extents. */
const auto arg_buf_size = reinterpret_cast<uintptr_t>(argv_buf) - args_region;
const auto arg_max = (header.allocated_size - arg_buf_size) / sizeof(char *);
/* Make argv. */
const auto arg_count = MakeArgv(argv_buf, arg_buf, cmd_line, header.arguments_size, arg_max);
/* Set host argc/argv. */
os::SetHostArgc(arg_count);
os::SetHostArgv(argv_buf);
}
}
}

View file

@ -15,111 +15,9 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 2;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
#define AMS_LM_USE_FATAL_ERROR 1
#if AMS_LM_USE_FATAL_ERROR
extern "C" {
/* Exception handling. */
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_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
#endif
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(::fsInitialize());
R_ABORT_UNLESS(::setsysInitialize());
R_ABORT_UNLESS(::pscmInitialize());
ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
}
namespace ams { namespace ams {
void *Malloc(size_t) { namespace lm::srv {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
namespace ams::lm::srv {
void StartLogServerProxy(); void StartLogServerProxy();
void StopLogServerProxy(); void StopLogServerProxy();
@ -131,12 +29,29 @@ namespace ams::lm::srv {
void LoopIpcServer(); void LoopIpcServer();
void FinalizeIpcServer(); void FinalizeIpcServer();
} }
int main(int argc, char **argv) namespace init {
{
AMS_UNUSED(argc, argv);
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize services we need. */
R_ABORT_UNLESS(::setsysInitialize());
R_ABORT_UNLESS(::pscmInitialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void Main() {
/* Check thread priority. */ /* Check thread priority. */
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(LogManager, MainThread)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(LogManager, MainThread));
@ -160,6 +75,6 @@ int main(int argc, char **argv)
/* Stop log server proxy. */ /* Stop log server proxy. */
lm::srv::StopLogServerProxy(); lm::srv::StopLogServerProxy();
}
return 0;
} }

View file

@ -16,47 +16,9 @@
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "tio_file_server.hpp" #include "tio_file_server.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace tio {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
#define AMS_TIO_SERVER_USE_FATAL_ERROR 1
#if AMS_TIO_SERVER_USE_FATAL_ERROR
extern "C" {
/* Exception handling. */
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_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
#endif
namespace ams::tio {
namespace { namespace {
@ -81,82 +43,33 @@ namespace ams::tio {
} }
} }
void __libnx_initheap(void) { namespace init {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */ void InitializeSystemModule() {
extern char* fake_heap_start; /* Initialize heap. */
extern char* fake_heap_end; tio::InitializeFsHeap();
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
ams::tio::InitializeFsHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
/* Initialize FS heap. */
fs::SetAllocator(tio::AllocateForFs, tio::DeallocateForFs);
/* Disable FS auto-abort. */
fs::SetEnabledAutoAbort(false);
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); /* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(tio::AllocateForFs, tio::DeallocateForFs);
fs::SetEnabledAutoAbort(false);
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void Main() {
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(TioServer, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(TioServer, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(TioServer, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(TioServer, Main));
@ -175,6 +88,6 @@ int main(int argc, char **argv)
/* Wait for the file server to finish. */ /* Wait for the file server to finish. */
tio::WaitFileServer(); tio::WaitFileServer();
}
return 0;
} }

View file

@ -19,108 +19,56 @@
#include "bpc_mitm/bpc_ams_power_utils.hpp" #include "bpc_mitm/bpc_ams_power_utils.hpp"
#include "sysupdater/sysupdater_fs_utils.hpp" #include "sysupdater/sysupdater_fs_utils.hpp"
extern "C" {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x1000000
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
namespace ams { namespace ams {
/* Override. */ namespace {
void ExceptionHandler(FatalErrorContext *ctx) {
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */ /* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */
mitm::bpc::RebootForFatalError(ctx); constexpr size_t MallocBufferSize = 16_MB;
alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize];
} }
} namespace init {
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); /* Initialize fs. */
fs::InitializeForSystem();
fs::SetEnabledAutoAbort(false);
/* Initialize other services. */
R_ABORT_UNLESS(pmdmntInitialize()); R_ABORT_UNLESS(pmdmntInitialize());
R_ABORT_UNLESS(pminfoInitialize()); R_ABORT_UNLESS(pminfoInitialize());
ncm::Initialize(); ncm::Initialize();
spl::InitializeForFs(); spl::InitializeForFs();
/* Disable auto-abort in fs operations. */ /* Verify that we can sanely execute. */
fs::SetEnabledAutoAbort(false);
/* Initialize fssystem library. */
fssystem::InitializeForFileSystemProxy();
/* Configure ncm to use fssystem library to mount content from the sd card. */
ncm::SetMountContentMetaFunction(mitm::sysupdater::MountSdCardContentMeta);
ams::CheckApiVersion(); ams::CheckApiVersion();
} }
void __appExit(void) { void FinalizeSystemModule() { /* ... */ }
/* Cleanup services. */
spl::Finalize();
ncm::Finalize();
pminfoExit();
pmdmntExit();
fsExit();
}
void *__libnx_alloc(size_t size) { void Startup() {
AMS_UNUSED(size); /* Initialize the global malloc allocator. */
AMS_ABORT("__libnx_alloc was called"); init::InitializeAllocator(g_malloc_buffer, sizeof(g_malloc_buffer));
} }
void *__libnx_aligned_alloc(size_t alignment, size_t size) { }
AMS_UNUSED(alignment, size);
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *mem) { void ExceptionHandler(FatalErrorContext *ctx) {
AMS_UNUSED(mem); /* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
AMS_ABORT("__libnx_free was called"); mitm::bpc::RebootForFatalError(ctx);
} }
int main(int argc, char **argv) { void NORETURN Exit(int rc) {
AMS_UNUSED(argc, argv); AMS_UNUSED(rc);
AMS_ABORT("Exit called by immortal process");
}
void Main() {
/* Register "ams" port, use up its session. */ /* Register "ams" port, use up its session. */
{ {
svc::Handle ams_port; svc::Handle ams_port;
@ -130,12 +78,17 @@ int main(int argc, char **argv) {
R_ABORT_UNLESS(svc::ConnectToNamedPort(std::addressof(ams_session), "ams")); R_ABORT_UNLESS(svc::ConnectToNamedPort(std::addressof(ams_session), "ams"));
} }
/* Initialize fssystem library. */
fssystem::InitializeForFileSystemProxy();
/* Configure ncm to use fssystem library to mount content from the sd card. */
ncm::SetMountContentMetaFunction(mitm::sysupdater::MountSdCardContentMeta);
/* Launch all mitm modules in sequence. */ /* Launch all mitm modules in sequence. */
mitm::LaunchAllModules(); mitm::LaunchAllModules();
/* Wait for all mitm modules to end. */ /* Wait for all mitm modules to end. */
mitm::WaitAllModules(); mitm::WaitAllModules();
}
return 0;
} }

View file

@ -324,11 +324,11 @@ namespace ams::mitm::fs {
AMS_ABORT_UNLESS(num_child_dirs >= 0); AMS_ABORT_UNLESS(num_child_dirs >= 0);
{ {
BuildDirectoryContext **child_dirs = reinterpret_cast<BuildDirectoryContext **>(std::malloc(sizeof(BuildDirectoryContext *) * num_child_dirs)); BuildDirectoryContext **child_dirs = num_child_dirs != 0 ? reinterpret_cast<BuildDirectoryContext **>(std::malloc(sizeof(BuildDirectoryContext *) * num_child_dirs)) : nullptr;
AMS_ABORT_UNLESS(num_child_dirs == 0 || child_dirs != nullptr);
ON_SCOPE_EXIT { std::free(child_dirs); }; ON_SCOPE_EXIT { std::free(child_dirs); };
AMS_ABORT_UNLESS(child_dirs != nullptr);
s64 cur_child_dir_ind = 0;
s64 cur_child_dir_ind = 0;
{ {
OpenFileSystemRomfsDirectory(&dir, this->program_id, parent, OpenDirectoryMode_All, fs); OpenFileSystemRomfsDirectory(&dir, this->program_id, parent, OpenDirectoryMode_All, fs);
ON_SCOPE_EXIT { fsDirClose(&dir); }; ON_SCOPE_EXIT { fsDirClose(&dir); };
@ -342,6 +342,8 @@ namespace ams::mitm::fs {
AMS_ABORT_UNLESS(this->dir_entry.type == FsDirEntryType_Dir || this->dir_entry.type == FsDirEntryType_File); AMS_ABORT_UNLESS(this->dir_entry.type == FsDirEntryType_Dir || this->dir_entry.type == FsDirEntryType_File);
if (this->dir_entry.type == FsDirEntryType_Dir) { if (this->dir_entry.type == FsDirEntryType_Dir) {
AMS_ABORT_UNLESS(child_dirs != nullptr);
BuildDirectoryContext *real_child = nullptr; BuildDirectoryContext *real_child = nullptr;
this->AddDirectory(&real_child, parent, std::make_unique<BuildDirectoryContext>(this->dir_entry.name, strlen(this->dir_entry.name))); this->AddDirectory(&real_child, parent, std::make_unique<BuildDirectoryContext>(this->dir_entry.name, strlen(this->dir_entry.name)));
AMS_ABORT_UNLESS(real_child != nullptr); AMS_ABORT_UNLESS(real_child != nullptr);

View file

@ -24,48 +24,13 @@
#include "boot_pinmux_initial_configuration.hpp" #include "boot_pinmux_initial_configuration.hpp"
#include "boot_repair_boot_images.hpp" #include "boot_repair_boot_images.hpp"
#include "boot_splash_screen.hpp" #include "boot_splash_screen.hpp"
#include "boot_power_utils.hpp" #include "boot_power_utils.hpp"
using namespace ams;
extern "C" {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
/* TODO: Evaluate to what extent this can be reduced further. */
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
namespace ams { namespace ams {
void ExceptionHandler(FatalErrorContext *ctx) { namespace boot {
/* We're boot sysmodule, so manually reboot to fatal error. */
boot::RebootForFatalError(ctx);
}
} namespace {
using namespace ams;
namespace {
constinit u8 g_exp_heap_memory[20_KB]; constinit u8 g_exp_heap_memory[20_KB];
constinit u8 g_unit_heap_memory[5_KB]; constinit u8 g_unit_heap_memory[5_KB];
@ -99,108 +64,42 @@ namespace {
ddsf::SetDeviceCodeEntryHolderMemoryResource(std::addressof(g_unit_heap_memory_resource)); ddsf::SetDeviceCodeEntryHolderMemoryResource(std::addressof(g_unit_heap_memory_resource));
} }
} }
void __libnx_exception_handler(ThreadExceptionDump *ctx) { }
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) { namespace init {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */ void InitializeSystemModule() {
extern char* fake_heap_start; /* Initialize heaps. */
extern char* fake_heap_end; boot::InitializeHeaps();
fake_heap_start = (char*)addr; /* Set fs allocator. */
fake_heap_end = (char*)addr + size; fs::SetAllocator(boot::Allocate, boot::Deallocate);
InitializeHeaps();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(Allocate, Deallocate);
/* Initialize services we need. */ /* Initialize services we need. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); fs::InitializeForSystem();
spl::Initialize(); spl::Initialize();
R_ABORT_UNLESS(pmshellInitialize()); R_ABORT_UNLESS(pmshellInitialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
/* Cleanup services. */
pmshellExit();
spl::Finalize();
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void ExceptionHandler(FatalErrorContext *ctx) {
/* We're boot sysmodule, so manually reboot to fatal error. */
void *__libnx_alloc(size_t) { boot::RebootForFatalError(ctx);
AMS_ABORT("__libnx_alloc was called"); }
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
void *operator new(size_t size) {
return Allocate(size);
}
void *operator new(size_t size, const std::nothrow_t &) {
return Allocate(size);
}
void operator delete(void *p) {
return Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return Deallocate(p, size);
}
void *operator new[](size_t size) {
return Allocate(size);
}
void *operator new[](size_t size, const std::nothrow_t &) {
return Allocate(size);
}
void operator delete[](void *p) {
return Deallocate(p, 0);
}
void operator delete[](void *p, size_t size) {
return Deallocate(p, size);
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(boot, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(boot, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(boot, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(boot, Main));
@ -276,6 +175,39 @@ int main(int argc, char **argv)
/* Tell PM to start boot2. */ /* Tell PM to start boot2. */
R_ABORT_UNLESS(pmshellNotifyBootFinished()); R_ABORT_UNLESS(pmshellNotifyBootFinished());
}
return 0; }
/* Override operator new. */
void *operator new(size_t size) {
return ams::boot::Allocate(size);
}
void *operator new(size_t size, const std::nothrow_t &) {
return ams::boot::Allocate(size);
}
void operator delete(void *p) {
return ams::boot::Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return ams::boot::Deallocate(p, size);
}
void *operator new[](size_t size) {
return ams::boot::Allocate(size);
}
void *operator new[](size_t size, const std::nothrow_t &) {
return ams::boot::Allocate(size);
}
void operator delete[](void *p) {
return ams::boot::Deallocate(p, 0);
}
void operator delete[](void *p, size_t size) {
return ams::boot::Deallocate(p, size);
} }

View file

@ -15,53 +15,14 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace boot2 {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
namespace {
namespace {
constinit u8 g_fs_heap_memory[2_KB]; constinit u8 g_fs_heap_memory[2_KB];
lmem::HeapHandle g_fs_heap_handle; constinit lmem::HeapHandle g_fs_heap_handle;
void *AllocateForFs(size_t size) { void *AllocateForFs(size_t size) {
return lmem::AllocateFromExpHeap(g_fs_heap_handle, size); return lmem::AllocateFromExpHeap(g_fs_heap_handle, size);
@ -76,18 +37,25 @@ namespace {
g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None); g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None);
} }
} }
void __appInit(void) { }
hos::InitializeForStratosphere();
InitializeFsHeap(); namespace init {
fs::SetAllocator(AllocateForFs, DeallocateForFs);
/* Initialize services we need. */ void InitializeSystemModule() {
/* Initialize heap. */
boot2::InitializeFsHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); /* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(boot2::AllocateForFs, boot2::DeallocateForFs);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(pmbmInitialize()); R_ABORT_UNLESS(pmbmInitialize());
R_ABORT_UNLESS(pminfoInitialize()); R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(pmshellInitialize()); R_ABORT_UNLESS(pmshellInitialize());
@ -97,66 +65,23 @@ void __appInit(void) {
/* Mount the SD card. */ /* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc")); R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
fs::Unmount("sdmc");
gpio::Finalize();
setsysExit();
pmshellExit();
pminfoExit();
pmbmExit();
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void Main() {
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(boot2, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(boot2, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(boot2, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(boot2, Main));
/* Launch all programs off of SYSTEM/the SD. */ /* Launch all programs off of SYSTEM/the SD. */
boot2::LaunchPostSdCardBootPrograms(); boot2::LaunchPostSdCardBootPrograms();
}
return 0;
} }

View file

@ -17,51 +17,11 @@
#include "creport_crash_report.hpp" #include "creport_crash_report.hpp"
#include "creport_utils.hpp" #include "creport_utils.hpp"
namespace ams {
extern "C" { namespace creport {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
namespace {
namespace {
constinit u8 g_fs_heap_memory[4_KB]; constinit u8 g_fs_heap_memory[4_KB];
lmem::HeapHandle g_fs_heap_handle; lmem::HeapHandle g_fs_heap_handle;
@ -79,88 +39,65 @@ namespace {
g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None); g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None);
} }
} }
void __appInit(void) { }
hos::InitializeForStratosphere();
InitializeFsHeap(); namespace init {
fs::SetAllocator(AllocateForFs, DeallocateForFs);
void InitializeSystemModule() {
/* Initialize heap. */
creport::InitializeFsHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); /* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(creport::AllocateForFs, creport::DeallocateForFs);
fs::SetEnabledAutoAbort(false);
/* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc")); R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
}
void __appExit(void) {
/* Cleanup services. */
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} namespace {
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
namespace {
constinit creport::CrashReport g_crash_report; constinit creport::CrashReport g_crash_report;
} }
int main(int argc, char **argv) { void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(creport, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(creport, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(creport, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(creport, Main));
/* Get arguments. */
const int num_args = os::GetHostArgc();
char ** const args = os::GetHostArgv();
/* Validate arguments. */ /* Validate arguments. */
if (argc < 2) { if (num_args < 2) {
return EXIT_FAILURE; return;
} }
for (int i = 0; i < argc; i++) {
if (argv[i] == NULL) { for (auto i = 0; i < num_args; ++i) {
return EXIT_FAILURE; if (args[i] == nullptr) {
return;
} }
} }
/* Parse arguments. */ /* Parse arguments. */
const os::ProcessId crashed_pid = creport::ParseProcessIdArgument(argv[0]); const os::ProcessId crashed_pid = creport::ParseProcessIdArgument(args[0]);
const bool has_extra_info = argv[1][0] == '1'; const bool has_extra_info = args[1][0] == '1';
const bool enable_screenshot = argc >= 3 && argv[2][0] == '1'; const bool enable_screenshot = num_args >= 3 && args[2][0] == '1';
const bool enable_jit_debug = argc >= 4 && argv[3][0] == '1'; const bool enable_jit_debug = num_args >= 4 && args[3][0] == '1';
/* Initialize the crash report. */ /* Initialize the crash report. */
g_crash_report.Initialize(); g_crash_report.Initialize();
@ -168,47 +105,52 @@ int main(int argc, char **argv) {
/* Try to debug the crashed process. */ /* Try to debug the crashed process. */
g_crash_report.BuildReport(crashed_pid, has_extra_info); g_crash_report.BuildReport(crashed_pid, has_extra_info);
if (!g_crash_report.IsComplete()) { if (!g_crash_report.IsComplete()) {
return EXIT_FAILURE; return;
} }
/* Save report to file. */ /* Save report to file. */
g_crash_report.SaveReport(enable_screenshot); g_crash_report.SaveReport(enable_screenshot);
/* If we should, try to terminate the process. */ /* Try to terminate the process, if we should. */
if (hos::GetVersion() < hos::Version_11_0_0 || !enable_jit_debug) { const auto fw_ver = hos::GetVersion();
if (hos::GetVersion() >= hos::Version_10_0_0) { if (fw_ver < hos::Version_11_0_0 || !enable_jit_debug) {
/* On 10.0.0+, use pgl to terminate. */ if (fw_ver >= hos::Version_10_0_0) {
/* Use pgl to terminate. */
if (R_SUCCEEDED(pgl::Initialize())) { if (R_SUCCEEDED(pgl::Initialize())) {
ON_SCOPE_EXIT { pgl::Finalize(); }; ON_SCOPE_EXIT { pgl::Finalize(); };
pgl::TerminateProcess(crashed_pid); pgl::TerminateProcess(crashed_pid);
} }
} else { } else {
/* On < 10.0.0, use ns:dev to terminate. */ /* Use ns to terminate. */
if (R_SUCCEEDED(::nsdevInitialize())) { if (R_SUCCEEDED(::nsdevInitialize())) {
ON_SCOPE_EXIT { ::nsdevExit(); }; ON_SCOPE_EXIT { ::nsdevExit(); };
nsdevTerminateProcess(static_cast<u64>(crashed_pid)); nsdevTerminateProcess(crashed_pid.value);
} }
} }
} }
/* Don't fatal if we have extra info, or if we're 5.0.0+ and an application crashed. */ /* If we're on 5.0.0+ and an application crashed, or if we have extra info, we don't need to fatal. */
if (hos::GetVersion() >= hos::Version_5_0_0) { if (fw_ver >= hos::Version_5_0_0) {
if (g_crash_report.IsApplication()) { if (g_crash_report.IsApplication()) {
return EXIT_SUCCESS; return;
} }
} else if (has_extra_info) { } else if (has_extra_info) {
return EXIT_SUCCESS; return;
} }
/* Also don't fatal if we're a user break. */ /* We also don't need to fatal on user break. */
if (g_crash_report.IsUserBreak()) { if (g_crash_report.IsUserBreak()) {
return EXIT_SUCCESS; return;
} }
/* Throw fatal error. */ /* Throw fatal error. */
{
::FatalCpuContext ctx; ::FatalCpuContext ctx;
g_crash_report.GetFatalContext(&ctx); g_crash_report.GetFatalContext(std::addressof(ctx));
fatalThrowWithContext(g_crash_report.GetResult().GetValue(), FatalPolicy_ErrorScreen, &ctx); fatalThrowWithContext(g_crash_report.GetResult().GetValue(), FatalPolicy_ErrorScreen, std::addressof(ctx));
}
}
} }

View file

@ -15,47 +15,9 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace cs {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
#define AMS_CS_SERVER_USE_FATAL_ERROR 1
#if AMS_CS_SERVER_USE_FATAL_ERROR
extern "C" {
/* Exception handling. */
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_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
#endif
namespace ams::cs {
namespace { namespace {
@ -89,86 +51,6 @@ namespace ams::cs {
} }
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
cs::InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(cs::Allocate, cs::Deallocate);
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize());
lr::Initialize();
R_ABORT_UNLESS(ldr::InitializeForShell());
R_ABORT_UNLESS(pgl::Initialize());
R_ABORT_UNLESS(setsysInitialize());
/* TODO: Other services? */
ams::CheckApiVersion();
}
void __appExit(void) {
/* TODO: Other services? */
setsysExit();
pgl::Finalize();
ldr::FinalizeForShell();
lr::Finalize();
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
namespace ams::cs {
namespace { namespace {
constinit ::ams::cs::CommandProcessor g_command_processor; constinit ::ams::cs::CommandProcessor g_command_processor;
@ -178,16 +60,53 @@ namespace ams::cs {
constinit sf::UnmanagedServiceObject<htc::tenv::IServiceManager, htc::tenv::ServiceManager> g_tenv_service_manager; constinit sf::UnmanagedServiceObject<htc::tenv::IServiceManager, htc::tenv::ServiceManager> g_tenv_service_manager;
void InitializeCommandProcessor() {
g_command_processor.Initialize();
} }
} void InitializeShellServers() {
g_shell_server.Initialize("iywys@$cs", g_shell_stack, sizeof(g_shell_stack), std::addressof(g_command_processor));
g_shell_server.Start();
int main(int argc, char **argv) g_runner_server.Initialize("iywys@$csForRunnerTools", g_runner_stack, sizeof(g_runner_stack), std::addressof(g_command_processor));
{ g_runner_server.Start();
AMS_UNUSED(argc, argv); }
using namespace ams::cs; }
}
namespace init {
void InitializeSystemModule() {
/* Initialize heap. */
cs::InitializeHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(cs::Allocate, cs::Deallocate);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
lr::Initialize();
R_ABORT_UNLESS(ldr::InitializeForShell());
R_ABORT_UNLESS(pgl::Initialize());
R_ABORT_UNLESS(setsysInitialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(cs, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(cs, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(cs, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(cs, Main));
@ -195,8 +114,8 @@ int main(int argc, char **argv)
/* Initialize htcs. */ /* Initialize htcs. */
constexpr auto HtcsSocketCountMax = 6; constexpr auto HtcsSocketCountMax = 6;
const size_t buffer_size = htcs::GetWorkingMemorySize(2 * HtcsSocketCountMax); const size_t buffer_size = htcs::GetWorkingMemorySize(2 * HtcsSocketCountMax);
AMS_ABORT_UNLESS(sizeof(g_htcs_buffer) >= buffer_size); AMS_ABORT_UNLESS(sizeof(cs::g_htcs_buffer) >= buffer_size);
htcs::InitializeForSystem(g_htcs_buffer, buffer_size, HtcsSocketCountMax); htcs::InitializeForSystem(cs::g_htcs_buffer, buffer_size, HtcsSocketCountMax);
/* Initialize audio server. */ /* Initialize audio server. */
cs::InitializeAudioServer(); cs::InitializeAudioServer();
@ -211,7 +130,7 @@ int main(int argc, char **argv)
cs::InitializeTargetIoServer(); cs::InitializeTargetIoServer();
/* Initialize command processor. */ /* Initialize command processor. */
g_command_processor.Initialize(); cs::InitializeCommandProcessor();
/* Setup scs. */ /* Setup scs. */
scs::InitializeShell(); scs::InitializeShell();
@ -220,17 +139,13 @@ int main(int argc, char **argv)
scs::InitializeTenvServiceManager(); scs::InitializeTenvServiceManager();
/* Initialize the shell servers. */ /* Initialize the shell servers. */
g_shell_server.Initialize("iywys@$cs", g_shell_stack, sizeof(g_shell_stack), std::addressof(g_command_processor)); cs::InitializeShellServers();
g_shell_server.Start();
g_runner_server.Initialize("iywys@$csForRunnerTools", g_runner_stack, sizeof(g_runner_stack), std::addressof(g_command_processor));
g_runner_server.Start();
/* Register htc:tenv. */ /* Register htc:tenv. */
R_ABORT_UNLESS(scs::GetServerManager()->RegisterObjectForServer(g_tenv_service_manager.GetShared(), htc::tenv::ServiceName, scs::SessionCount[scs::Port_HtcTenv])); R_ABORT_UNLESS(scs::GetServerManager()->RegisterObjectForServer(cs::g_tenv_service_manager.GetShared(), htc::tenv::ServiceName, scs::SessionCount[scs::Port_HtcTenv]));
/* Start the scs ipc server. */ /* Start the scs ipc server. */
scs::StartServer(); scs::StartServer();
}
return 0;
} }

View file

@ -17,47 +17,9 @@
#include "dmnt2_debug_log.hpp" #include "dmnt2_debug_log.hpp"
#include "dmnt2_gdb_server.hpp" #include "dmnt2_gdb_server.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace dmnt {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
#define AMS_DMNT2_SERVER_USE_FATAL_ERROR 1
#if AMS_DMNT2_SERVER_USE_FATAL_ERROR
extern "C" {
/* Exception handling. */
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_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
#endif
namespace ams::dmnt {
namespace { namespace {
@ -65,75 +27,28 @@ namespace ams::dmnt {
} }
} }
void __libnx_initheap(void) { namespace init {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
/* TODO */ /* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
/* TODO */
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void Main() {
/* Set thread name. */
void *operator new(size_t) { os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(dmnt, Main));
AMS_ABORT("operator new(size_t) was called"); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main));
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* TODO ThreadName */
/* Initialize htcs. */ /* Initialize htcs. */
constexpr auto HtcsSocketCountMax = 8; constexpr auto HtcsSocketCountMax = 8;
@ -151,6 +66,6 @@ int main(int argc, char **argv)
while (true) { while (true) {
os::SleepThread(TimeSpan::FromDays(1)); os::SleepThread(TimeSpan::FromDays(1));
} }
}
return 0;
} }

View file

@ -17,41 +17,11 @@
#include "cheat/dmnt_cheat_service.hpp" #include "cheat/dmnt_cheat_service.hpp"
#include "cheat/impl/dmnt_cheat_api.hpp" #include "cheat/impl/dmnt_cheat_api.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace dmnt {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
namespace {
namespace {
constinit u8 g_fs_heap_memory[4_KB]; constinit u8 g_fs_heap_memory[4_KB];
lmem::HeapHandle g_fs_heap_handle; lmem::HeapHandle g_fs_heap_handle;
@ -69,47 +39,9 @@ namespace {
g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None); g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None);
} }
} }
void __appInit(void) { namespace {
hos::InitializeForStratosphere();
InitializeFsHeap();
fs::SetAllocator(AllocateForFs, DeallocateForFs);
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(pmdmntInitialize());
R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(ldrDmntInitialize());
R_ABORT_UNLESS(roDmntInitialize());
R_ABORT_UNLESS(nsdevInitialize());
lr::Initialize();
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(hidInitialize());
R_ABORT_UNLESS(fsInitialize());
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
ams::CheckApiVersion();
}
void __appExit(void) {
/* Cleanup services. */
fsExit();
hidExit();
setsysExit();
setExit();
lr::Finalize();
nsdevExit();
roDmntExit();
ldrDmntExit();
pminfoExit();
pmdmntExit();
}
namespace {
using ServerOptions = sf::hipc::DefaultServerManagerOptions; using ServerOptions = sf::hipc::DefaultServerManagerOptions;
@ -131,6 +63,7 @@ namespace {
g_server_manager.LoopProcess(); g_server_manager.LoopProcess();
} }
/* NOTE: Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */
constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1; constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1;
static_assert(TotalThreads >= 1, "TotalThreads"); static_assert(TotalThreads >= 1, "TotalThreads");
constexpr size_t NumExtraThreads = TotalThreads - 1; constexpr size_t NumExtraThreads = TotalThreads - 1;
@ -139,64 +72,12 @@ namespace {
os::ThreadType g_extra_threads[NumExtraThreads]; os::ThreadType g_extra_threads[NumExtraThreads];
} void InitializeIpcServer() {
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(dmnt, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main));
/* Initialize the cheat manager. */
ams::dmnt::cheat::impl::InitializeCheatManager();
/* Create services. */ /* Create services. */
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_cheat_service.GetShared(), CheatServiceName, CheatMaxSessions)); R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_cheat_service.GetShared(), CheatServiceName, CheatMaxSessions));
}
/* Loop forever, servicing our services. */ void LoopProcessIpcServer() {
/* Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */
{
/* Initialize threads. */ /* Initialize threads. */
if constexpr (NumExtraThreads > 0) { if constexpr (NumExtraThreads > 0) {
static_assert(AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Ipc)); static_assert(AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Ipc));
@ -224,6 +105,61 @@ int main(int argc, char **argv)
} }
} }
return 0; }
}
}
namespace init {
void InitializeSystemModule() {
/* Initialize heap. */
dmnt::InitializeFsHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(dmnt::AllocateForFs, dmnt::DeallocateForFs);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(pmdmntInitialize());
R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(ldrDmntInitialize());
R_ABORT_UNLESS(roDmntInitialize());
R_ABORT_UNLESS(nsdevInitialize());
lr::Initialize();
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(hidInitialize());
/* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void Main() {
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(dmnt, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main));
/* Initialize the cheat manager. */
dmnt::cheat::impl::InitializeCheatManager();
/* Initialize ipc server. */
dmnt::InitializeIpcServer();
/* Loop processing ipc server. */
dmnt::LoopProcessIpcServer();
}
}

View file

@ -15,54 +15,21 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace init {
#define INNER_HEAP_SIZE 0x2000 void InitializeSystemModule() { /* ... */ }
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void); void FinalizeSystemModule() { /* ... */ }
void __appInit(void);
void __appExit(void); void Startup() { /* ... */ }
}
void Main() {
/* ... */
}
/* Exception handling. */
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
void __libnx_exception_handler(ThreadExceptionDump *ctx);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
/* nothing to do */
}
void __appExit(void) {
/* nothing to do */
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
return 0;
} }

View file

@ -15,74 +15,9 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace erpt {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(pscmInitialize());
R_ABORT_UNLESS(time::Initialize());
if (hos::GetVersion() >= hos::Version_11_0_0) {
R_ABORT_UNLESS(ectxrInitialize());
}
R_ABORT_UNLESS(fsInitialize());
ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
time::Finalize();
pscmExit();
setsysExit();
setExit();
}
namespace ams::erpt {
namespace { namespace {
@ -111,48 +46,34 @@ namespace ams::erpt {
} }
} }
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { namespace init {
AMS_ABORT("ams::Free was called");
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize services we need (which won't be initialized later). */
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(pscmInitialize());
R_ABORT_UNLESS(time::Initialize());
if (hos::GetVersion() >= hos::Version_11_0_0) {
R_ABORT_UNLESS(ectxrInitialize());
} }
} /* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void *operator new(size_t) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) { void Startup() { /* ... */ }
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) { }
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(erpt, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(erpt, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(erpt, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(erpt, Main));
@ -215,8 +136,6 @@ int main(int argc, char **argv)
/* Wait forever. */ /* Wait forever. */
erpt::srv::Wait(); erpt::srv::Wait();
}
/* Cleanup */
return 0;
} }

View file

@ -21,7 +21,24 @@ namespace ams::fatal::srv {
namespace { namespace {
/* Global config. */ /* Global config. */
FatalConfig g_config; constinit os::SdkMutex g_config_mutex;
constinit bool g_initialized_config;
constinit util::TypedStorage<FatalConfig> g_config;
FatalConfig &GetFatalConfigImpl() {
if (AMS_UNLIKELY(!g_initialized_config)) {
std::scoped_lock lk(g_config_mutex);
if (AMS_LIKELY(!g_initialized_config)) {
util::ConstructAt(g_config);
g_initialized_config = true;
}
}
return util::GetReference(g_config);
}
/* Event creator. */ /* Event creator. */
os::NativeHandle GetFatalDirtyEventReadableHandle() { os::NativeHandle GetFatalDirtyEventReadableHandle() {
@ -31,18 +48,18 @@ namespace ams::fatal::srv {
} }
/* Global event. */ /* Global event. */
os::SystemEventType g_fatal_dirty_event; constinit os::SystemEventType g_fatal_dirty_event;
os::MultiWaitHolderType g_fatal_dirty_multi_wait_holder; constinit os::MultiWaitHolderType g_fatal_dirty_multi_wait_holder;
bool g_initialized; constinit bool g_initialized_fatal_dirty_event;
} }
os::MultiWaitHolderType *GetFatalDirtyMultiWaitHolder() { os::MultiWaitHolderType *GetFatalDirtyMultiWaitHolder() {
if (AMS_UNLIKELY(!g_initialized)) { if (AMS_UNLIKELY(!g_initialized_fatal_dirty_event)) {
os::AttachReadableHandleToSystemEvent(std::addressof(g_fatal_dirty_event), GetFatalDirtyEventReadableHandle(), true, os::EventClearMode_ManualClear); os::AttachReadableHandleToSystemEvent(std::addressof(g_fatal_dirty_event), GetFatalDirtyEventReadableHandle(), true, os::EventClearMode_ManualClear);
os::InitializeMultiWaitHolder(std::addressof(g_fatal_dirty_multi_wait_holder), std::addressof(g_fatal_dirty_event)); os::InitializeMultiWaitHolder(std::addressof(g_fatal_dirty_multi_wait_holder), std::addressof(g_fatal_dirty_event));
os::SetMultiWaitHolderUserData(std::addressof(g_fatal_dirty_multi_wait_holder), reinterpret_cast<uintptr_t>(std::addressof(g_fatal_dirty_multi_wait_holder))); os::SetMultiWaitHolderUserData(std::addressof(g_fatal_dirty_multi_wait_holder), reinterpret_cast<uintptr_t>(std::addressof(g_fatal_dirty_multi_wait_holder)));
g_initialized = true; g_initialized_fatal_dirty_event = true;
} }
return std::addressof(g_fatal_dirty_multi_wait_holder); return std::addressof(g_fatal_dirty_multi_wait_holder);
} }
@ -52,7 +69,7 @@ namespace ams::fatal::srv {
u64 flags_0, flags_1; u64 flags_0, flags_1;
if (R_SUCCEEDED(setsysGetFatalDirtyFlags(&flags_0, &flags_1)) && (flags_0 & 1)) { if (R_SUCCEEDED(setsysGetFatalDirtyFlags(&flags_0, &flags_1)) && (flags_0 & 1)) {
g_config.UpdateLanguageCode(); GetFatalConfigImpl().UpdateLanguageCode();
} }
} }
@ -103,7 +120,7 @@ namespace ams::fatal::srv {
} }
const FatalConfig &GetFatalConfig() { const FatalConfig &GetFatalConfig() {
return g_config; return GetFatalConfigImpl();
} }
} }

View file

@ -19,36 +19,17 @@
#include "fatal_repair.hpp" #include "fatal_repair.hpp"
#include "fatal_font.hpp" #include "fatal_font.hpp"
/* Set libnx graphics globals. */
extern "C" { extern "C" {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
u32 __nx_nv_transfermem_size = 0x40000; u32 __nx_nv_transfermem_size = 0x40000;
ViLayerFlags __nx_vi_stray_layer_flags = (ViLayerFlags)0; ViLayerFlags __nx_vi_stray_layer_flags = (ViLayerFlags)0;
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
} }
using namespace ams; namespace ams {
namespace ams::fatal { namespace fatal::srv {
namespace { namespace {
@ -70,77 +51,7 @@ namespace ams::fatal {
} }
} namespace {
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
fatal::InitializeFsHeap();
fs::SetAllocator(fatal::AllocateForFs, fatal::DeallocateForFs);
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(i2cInitialize());
R_ABORT_UNLESS(bpcInitialize());
if (hos::GetVersion() >= hos::Version_8_0_0) {
R_ABORT_UNLESS(clkrstInitialize());
} else {
R_ABORT_UNLESS(pcvInitialize());
}
R_ABORT_UNLESS(lblInitialize());
R_ABORT_UNLESS(psmInitialize());
R_ABORT_UNLESS(spsmInitialize());
R_ABORT_UNLESS(plInitialize(::PlServiceType_User));
gpio::Initialize();
R_ABORT_UNLESS(fsInitialize());
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
/* fatal cannot throw fatal, so don't do: ams::CheckApiVersion(); */
}
void __appExit(void) {
/* Cleanup services. */
fsExit();
plExit();
gpio::Finalize();
spsmExit();
psmExit();
lblExit();
if (hos::GetVersion() >= hos::Version_8_0_0) {
clkrstExit();
} else {
pcvExit();
}
bpcExit();
i2cExit();
pminfoExit();
setsysExit();
setExit();
}
namespace {
using ServerOptions = sf::hipc::DefaultServerManagerOptions; using ServerOptions = sf::hipc::DefaultServerManagerOptions;
@ -159,67 +70,13 @@ namespace {
constinit sf::UnmanagedServiceObject<fatal::impl::IService, fatal::srv::Service> g_user_service_object; constinit sf::UnmanagedServiceObject<fatal::impl::IService, fatal::srv::Service> g_user_service_object;
constinit sf::UnmanagedServiceObject<fatal::impl::IPrivateService, fatal::srv::Service> g_private_service_object; constinit sf::UnmanagedServiceObject<fatal::impl::IPrivateService, fatal::srv::Service> g_private_service_object;
} void InitializeAndLoopIpcServer() {
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main));
/* Load shared font. */
R_ABORT_UNLESS(fatal::srv::font::InitializeSharedFont());
/* Check whether we should throw fatal due to repair process. */
fatal::srv::CheckRepairStatus();
/* Create services. */ /* Create services. */
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_user_service_object.GetShared(), UserServiceName, UserMaxSessions)); R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_user_service_object.GetShared(), UserServiceName, UserMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_private_service_object.GetShared(), PrivateServiceName, PrivateMaxSessions)); R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_private_service_object.GetShared(), PrivateServiceName, PrivateMaxSessions));
/* Add dirty event holder. */ /* Add dirty event holder. */
auto *dirty_event_holder = ams::fatal::srv::GetFatalDirtyMultiWaitHolder(); auto *dirty_event_holder = fatal::srv::GetFatalDirtyMultiWaitHolder();
g_server_manager.AddUserMultiWaitHolder(dirty_event_holder); g_server_manager.AddUserMultiWaitHolder(dirty_event_holder);
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
@ -234,7 +91,68 @@ int main(int argc, char **argv)
R_ABORT_UNLESS(g_server_manager.Process(signaled_holder)); R_ABORT_UNLESS(g_server_manager.Process(signaled_holder));
} }
} }
}
}
}
namespace init {
void InitializeSystemModule() {
/* Initialize heap. */
fatal::srv::InitializeFsHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(fatal::srv::AllocateForFs, fatal::srv::DeallocateForFs);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(pminfoInitialize());
R_ABORT_UNLESS(i2cInitialize());
R_ABORT_UNLESS(bpcInitialize());
if (hos::GetVersion() >= hos::Version_8_0_0) {
R_ABORT_UNLESS(clkrstInitialize());
} else {
R_ABORT_UNLESS(pcvInitialize());
}
R_ABORT_UNLESS(lblInitialize());
R_ABORT_UNLESS(psmInitialize());
R_ABORT_UNLESS(spsmInitialize());
R_ABORT_UNLESS(plInitialize(::PlServiceType_User));
gpio::Initialize();
/* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void Main() {
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main));
/* Load shared font. */
R_ABORT_UNLESS(fatal::srv::font::InitializeSharedFont());
/* Check whether we should throw fatal due to repair process. */
fatal::srv::CheckRepairStatus();
/* Loop processing the IPC server. */
fatal::srv::InitializeAndLoopIpcServer();
}
return 0;
} }

View file

@ -15,47 +15,9 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace htc {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
#define AMS_HTC_USE_FATAL_ERROR 1
#if AMS_HTC_USE_FATAL_ERROR
extern "C" {
/* Exception handling. */
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_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
#endif
namespace ams::htc {
namespace { namespace {
@ -79,96 +41,6 @@ namespace ams::htc {
} }
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
ams::htc::InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(htc::Allocate, htc::Deallocate);
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(setcalInitialize());
R_ABORT_UNLESS(pscmInitialize());
R_ABORT_UNLESS(fsInitialize());
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
setsysExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
void *MallocForRapidJson(size_t) {
AMS_ABORT("ams::MallocForRapidJson was called");
}
void *ReallocForRapidJson(void *, size_t) {
AMS_ABORT("ams::ReallocForRapidJson was called");
}
void FreeForRapidJson(void *ptr) {
if (ptr != nullptr) {
AMS_ABORT("ams::FreeForRapidJson was called");
}
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
namespace ams::htc {
namespace { namespace {
constexpr htclow::impl::DriverType DefaultHtclowDriverType = htclow::impl::DriverType::Usb; constexpr htclow::impl::DriverType DefaultHtclowDriverType = htclow::impl::DriverType::Usb;
@ -239,18 +111,47 @@ namespace ams::htc {
} }
} }
namespace ams::htclow::driver { namespace htclow::driver {
void InitializeSocketApiForSocketDriver(); void InitializeSocketApiForSocketDriver();
} }
int main(int argc, char **argv) namespace init {
{
AMS_UNUSED(argc, argv);
void InitializeSystemModule() {
/* Initialize heap. */
htc::InitializeHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(htc::Allocate, htc::Deallocate);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(setcalInitialize());
R_ABORT_UNLESS(pscmInitialize());
/* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(htc, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(htc, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(htc, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(htc, Main));
@ -317,6 +218,7 @@ int main(int argc, char **argv)
os::WaitThread(std::addressof(htcs_ipc_threads[i])); os::WaitThread(std::addressof(htcs_ipc_threads[i]));
os::DestroyThread(std::addressof(htcs_ipc_threads[i])); os::DestroyThread(std::addressof(htcs_ipc_threads[i]));
} }
os::WaitThread(std::addressof(htcfs_ipc_thread)); os::WaitThread(std::addressof(htcfs_ipc_thread));
os::DestroyThread(std::addressof(htcfs_ipc_thread)); os::DestroyThread(std::addressof(htcfs_ipc_thread));
os::WaitThread(std::addressof(htc_ipc_thread)); os::WaitThread(std::addressof(htc_ipc_thread));
@ -324,6 +226,6 @@ int main(int argc, char **argv)
/* Finalize psc monitor. */ /* Finalize psc monitor. */
htc::server::FinalizePowerStateMonitor(); htc::server::FinalizePowerStateMonitor();
}
return 0;
} }

View file

@ -4,10 +4,18 @@
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# jpegdec uses libjpeg. # jpegdec uses libjpeg-turbo.
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS += -ljpeg LIBS += -ljpeg
#---------------------------------------------------------------------------------
# jpegdec overrides libjpeg-turbo's memory allocation routines.
#---------------------------------------------------------------------------------
CXXWRAPS += -Wl,--wrap,jpeg_get_small
CXXWRAPS += -Wl,--wrap,jpeg_get_large
CXXWRAPS += -Wl,--wrap,jpeg_free_small
CXXWRAPS += -Wl,--wrap,jpeg_free_large
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
# rules for different file extensions # rules for different file extensions

View file

@ -14,61 +14,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "jpegdec_memory_management.hpp"
/* TODO: Update libjpeg-turbo to include Nintendo's changes (support for work buffer, rather than malloc) */ namespace ams {
extern "C" { namespace init {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; void InitializeSystemModule() {
/* Initialize heap. */
#define INNER_HEAP_SIZE 0x18000 jpegdec::InitializeJpegHeap();
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
void __libnx_exception_handler(ThreadExceptionDump *ctx);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
ams::CheckApiVersion();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
}
void __appExit(void) { /* Verify that we can sanely execute. */
/* ... */ ams::CheckApiVersion();
} }
int main(int argc, char **argv) void FinalizeSystemModule() { /* ... */ }
{
AMS_UNUSED(argc, argv);
void Startup() { /* ... */ }
}
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(jpegdec, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(jpegdec, Main));
@ -85,7 +54,6 @@ int main(int argc, char **argv)
/* Finalize the capsrv library. */ /* Finalize the capsrv library. */
capsrv::server::FinalizeForDecoderServer(); capsrv::server::FinalizeForDecoderServer();
}
/* Cleanup */
return 0;
} }

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "jpegdec_memory_management.hpp"
namespace ams::jpegdec {
namespace {
/* TODO: Update libjpeg-turbo to include Nintendo's changes (support for work buffer, rather than malloc) */
constexpr size_t JpegHeapSize = 96_KB;
alignas(0x10) constinit u8 g_jpeg_heap_memory[JpegHeapSize];
constinit lmem::HeapHandle g_jpeg_heap_handle;
}
void InitializeJpegHeap() {
g_jpeg_heap_handle = lmem::CreateExpHeap(g_jpeg_heap_memory, sizeof(g_jpeg_heap_memory), lmem::CreateOption_None);
}
}
extern "C" void *__wrap_jpeg_get_small(void *cinfo, size_t size) {
AMS_UNUSED(cinfo);
return ::ams::lmem::AllocateFromExpHeap(::ams::jpegdec::g_jpeg_heap_handle, size);
}
extern "C" void __wrap_jpeg_free_small(void *cinfo, void *ptr, size_t size) {
AMS_UNUSED(cinfo, size);
return ::ams::lmem::FreeToExpHeap(::ams::jpegdec::g_jpeg_heap_handle, ptr);
}
extern "C" void *__wrap_jpeg_get_large(void *cinfo, size_t size) {
AMS_UNUSED(cinfo);
return ::ams::lmem::AllocateFromExpHeap(::ams::jpegdec::g_jpeg_heap_handle, size);
}
extern "C" void __wrap_jpeg_free_large(void *cinfo, void *ptr, size_t size) {
AMS_UNUSED(cinfo, size);
return ::ams::lmem::FreeToExpHeap(::ams::jpegdec::g_jpeg_heap_handle, ptr);
}

View file

@ -14,13 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "impl/os_resource_manager.hpp"
namespace ams::os { namespace ams::jpegdec {
void InitializeForStratosphereInternal() { void InitializeJpegHeap();
/* Initialize the global os resource manager. */
os::impl::ResourceManagerHolder::InitializeResourceManagerInstance();
}
} }

View file

@ -17,37 +17,9 @@
#include "ldr_development_manager.hpp" #include "ldr_development_manager.hpp"
#include "ldr_loader_service.hpp" #include "ldr_loader_service.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace ldr {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
namespace ams::ldr {
namespace { namespace {
@ -118,86 +90,41 @@ namespace ams::ldr {
} }
} }
void __libnx_initheap(void) { namespace init {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */ void InitializeSystemModule() {
extern char* fake_heap_start; /* Initialize heap. */
extern char* fake_heap_end; ldr::InitializeHeap();
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
ams::ldr::InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
/* Set fs allocator. */
fs::SetAllocator(ldr::Allocate, ldr::Deallocate); fs::SetAllocator(ldr::Allocate, ldr::Deallocate);
/* Initialize services we need. */ /* Initialize services we need. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize()); fs::InitializeForSystem();
lr::Initialize(); lr::Initialize();
R_ABORT_UNLESS(fsldrInitialize()); R_ABORT_UNLESS(fsldrInitialize());
spl::Initialize(); spl::Initialize();
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
/* Cleanup services. */
spl::Finalize();
fsldrExit();
lr::Finalize();
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void NORETURN Exit(int rc) {
AMS_UNUSED(rc);
void *operator new(size_t size) { AMS_ABORT("Exit called by immortal process");
return ldr::Allocate(size); }
}
void operator delete(void *p) {
return ldr::Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return ldr::Deallocate(p, size);
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
void Main() {
/* Disable auto-abort in fs operations. */ /* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false); fs::SetEnabledAutoAbort(false);
@ -217,6 +144,25 @@ int main(int argc, char **argv)
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
ldr::LoopProcess(); ldr::LoopProcess();
return 0; /* This can never be reached. */
AMS_ASSUME(false);
}
} }
/* Override operator new. */
void *operator new(size_t size) {
return ams::ldr::Allocate(size);
}
void *operator new(size_t size, const std::nothrow_t &) {
return ams::ldr::Allocate(size);
}
void operator delete(void *p) {
return ams::ldr::Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return ams::ldr::Deallocate(p, size);
}

View file

@ -15,33 +15,11 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace ncm {
u32 __nx_fs_num_sessions = 2;
#define INNER_HEAP_SIZE 0x0 namespace {
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
namespace {
u8 g_heap_memory[1_MB]; u8 g_heap_memory[1_MB];
lmem::HeapHandle g_heap_handle; lmem::HeapHandle g_heap_handle;
@ -62,103 +40,9 @@ namespace {
ncm::GetHeapState().Initialize(g_heap_handle); ncm::GetHeapState().Initialize(g_heap_handle);
} }
}
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void * addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char *fake_heap_start;
extern char *fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(Allocate, Deallocate);
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsInitialize());
spl::Initialize();
ams::CheckApiVersion();
}
void __appExit(void) {
/* Cleanup services. */
spl::Finalize();
fsExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { namespace {
AMS_ABORT("ams::Free was called");
}
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
void *operator new(size_t size) {
return Allocate(size);
}
void *operator new(size_t size, const std::nothrow_t &) {
return Allocate(size);
}
void operator delete(void *p) {
return Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return Deallocate(p, size);
}
void *operator new[](size_t size) {
return Allocate(size);
}
void *operator new[](size_t size, const std::nothrow_t &) {
return Allocate(size);
}
void operator delete[](void *p) {
return Deallocate(p, 0);
}
void operator delete[](void *p, size_t size) {
return Deallocate(p, size);
}
namespace {
struct ContentManagerServerOptions { struct ContentManagerServerOptions {
static constexpr size_t PointerBufferSize = 0x400; static constexpr size_t PointerBufferSize = 0x400;
@ -254,35 +138,34 @@ namespace {
LocationResolverServerManager g_lr_server_manager(g_lr_manager_service_object.GetShared()); LocationResolverServerManager g_lr_server_manager(g_lr_manager_service_object.GetShared());
/* Compile-time configuration. */ /* Compile-time configuration. */
#ifdef NCM_BUILD_FOR_INTITIALIZE #ifdef NCM_BUILD_FOR_INTITIALIZE
constexpr inline bool BuildSystemDatabase = true; constexpr inline bool BuildSystemDatabase = true;
#else #else
constexpr inline bool BuildSystemDatabase = false; constexpr inline bool BuildSystemDatabase = false;
#endif #endif
#ifdef NCM_BUILD_FOR_SAFEMODE #ifdef NCM_BUILD_FOR_SAFEMODE
constexpr inline bool ImportSystemDatabaseFromSignedSystemPartitionOnSdCard = true; constexpr inline bool ImportSystemDatabaseFromSignedSystemPartitionOnSdCard = true;
#else #else
constexpr inline bool ImportSystemDatabaseFromSignedSystemPartitionOnSdCard = false; constexpr inline bool ImportSystemDatabaseFromSignedSystemPartitionOnSdCard = false;
#endif #endif
static_assert(!(BuildSystemDatabase && ImportSystemDatabaseFromSignedSystemPartitionOnSdCard), "Invalid NCM build configuration!"); static_assert(!(BuildSystemDatabase && ImportSystemDatabaseFromSignedSystemPartitionOnSdCard), "Invalid NCM build configuration!");
constexpr inline ncm::ContentManagerConfig ManagerConfig = { BuildSystemDatabase, ImportSystemDatabaseFromSignedSystemPartitionOnSdCard }; constexpr inline ncm::ContentManagerConfig ManagerConfig = { BuildSystemDatabase, ImportSystemDatabaseFromSignedSystemPartitionOnSdCard };
} }
int main(int argc, char **argv) void NcmMain() {
{ /* Initialize spl. */
AMS_UNUSED(argc, argv); spl::Initialize();
ON_SCOPE_EXIT { spl::Finalize(); };
/* Disable auto-abort in fs operations. */ /* Initialize fs. */
fs::InitializeWithMultiSessionForSystem();
fs::SetAllocator(Allocate, Deallocate);
fs::SetEnabledAutoAbort(false); fs::SetEnabledAutoAbort(false);
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));
/* Create and initialize the content manager. */ /* Create and initialize the content manager. */
R_ABORT_UNLESS(g_ncm_manager_service_object.GetImpl().Initialize(ManagerConfig)); R_ABORT_UNLESS(g_ncm_manager_service_object.GetImpl().Initialize(ManagerConfig));
@ -300,6 +183,77 @@ int main(int argc, char **argv)
/* Wait indefinitely. */ /* Wait indefinitely. */
g_ncm_server_manager.Wait(); g_ncm_server_manager.Wait();
g_lr_server_manager.Wait(); g_lr_server_manager.Wait();
}
}
namespace init {
void InitializeSystemModule() {
/* Initialize heap. */
ncm::InitializeHeap();
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void NORETURN Exit(int rc) {
AMS_UNUSED(rc);
AMS_ABORT("Exit called by immortal process");
}
void Main() {
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));
/* Invoke NCM main. */
ncm::NcmMain();
/* This can never be reached. */
AMS_ASSUME(false);
}
return 0; }
/* Override operator new. */
void *operator new(size_t size) {
return ams::ncm::Allocate(size);
}
void *operator new(size_t size, const std::nothrow_t &) {
return ams::ncm::Allocate(size);
}
void operator delete(void *p) {
return ams::ncm::Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return ams::ncm::Deallocate(p, size);
}
void *operator new[](size_t size) {
return ams::ncm::Allocate(size);
}
void *operator new[](size_t size, const std::nothrow_t &) {
return ams::ncm::Allocate(size);
}
void operator delete[](void *p) {
return ams::ncm::Deallocate(p, 0);
}
void operator delete[](void *p, size_t size) {
return ams::ncm::Deallocate(p, size);
} }

View file

@ -15,127 +15,46 @@
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace init {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0 void InitializeSystemModule() {
size_t nx_inner_heap_size = INNER_HEAP_SIZE; /* Initialize heap. */
char nx_inner_heap[INNER_HEAP_SIZE]; pgl::srv::InitializeHeap();
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
ams::pgl::srv::InitializeHeap();
fs::SetAllocator(pgl::srv::Allocate, pgl::srv::Deallocate);
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(pgl::srv::Allocate, pgl::srv::Deallocate);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(setInitialize()); R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize()); R_ABORT_UNLESS(setsysInitialize());
R_ABORT_UNLESS(pmshellInitialize()); R_ABORT_UNLESS(pmshellInitialize());
R_ABORT_UNLESS(ldrShellInitialize()); R_ABORT_UNLESS(ldrShellInitialize());
R_ABORT_UNLESS(lrInitialize()); R_ABORT_UNLESS(lrInitialize());
R_ABORT_UNLESS(fsInitialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
lrExit();
ldrShellExit();
pmshellExit();
setsysExit();
setExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void Main() {
void *operator new(size_t size) {
return pgl::srv::Allocate(size);
}
void operator delete(void *p) {
return pgl::srv::Deallocate(p, 0);
}
void operator delete(void *p, size_t size) {
return pgl::srv::Deallocate(p, size);
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main));
/* Initialize and start the server. */ /* Initialize and start the server. */
pgl::srv::StartServer(); pgl::srv::StartServer();
}
/* Cleanup */
return 0;
} }

View file

@ -18,51 +18,13 @@
#include "pm_debug_monitor_service.hpp" #include "pm_debug_monitor_service.hpp"
#include "pm_info_service.hpp" #include "pm_info_service.hpp"
#include "pm_shell_service.hpp" #include "pm_shell_service.hpp"
#include "impl/pm_process_manager.hpp" #include "impl/pm_process_manager.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace pm {
#define INNER_HEAP_SIZE 0x0 namespace {
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
namespace {
constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000}; constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}; constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
@ -116,38 +78,9 @@ namespace {
} }
} }
} }
void __appInit(void) { namespace {
hos::InitializeForStratosphere();
R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(fsprInitialize());
R_ABORT_UNLESS(smManagerInitialize());
/* This works around a bug with process permissions on < 4.0.0. */
/* It also informs SM of privileged process information. */
RegisterPrivilegedProcesses();
/* Use AMS manager extension to tell SM that FS has been worked around. */
R_ABORT_UNLESS(sm::manager::EndInitialDefers());
R_ABORT_UNLESS(ldrPmInitialize());
spl::Initialize();
ams::CheckApiVersion();
}
void __appExit(void) {
/* Cleanup services. */
spl::Finalize();
ldrPmExit();
smManagerExit();
fsprExit();
}
namespace {
/* pm:shell, pm:dmnt, pm:bm, pm:info. */ /* pm:shell, pm:dmnt, pm:bm, pm:info. */
enum PortIndex { enum PortIndex {
@ -216,48 +149,59 @@ namespace {
} }
} }
} void RegisterServices() {
/* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */
namespace ams { R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Shell, ShellServiceName, ShellMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_DebugMonitor, DebugMonitorServiceName, DebugMonitorMaxSessions));
void *Malloc(size_t) { R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_BootMode, BootModeServiceName, BootModeMaxSessions));
AMS_ABORT("ams::Malloc was called"); R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Information, InformationServiceName, InformationMaxSessions));
} }
void Free(void *) { void LoopProcess() {
AMS_ABORT("ams::Free was called"); g_server_manager.LoopProcess();
} }
} }
void *operator new(size_t) { }
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) { namespace init {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) { void InitializeSystemModule() {
AMS_ABORT("operator delete(void *, size_t) was called"); /* Initialize our connection to sm. */
} R_ABORT_UNLESS(sm::Initialize());
void *__libnx_alloc(size_t) { /* Initialize manager interfaces for fs and sm. */
AMS_ABORT("__libnx_alloc was called"); R_ABORT_UNLESS(fsprInitialize());
} R_ABORT_UNLESS(smManagerInitialize());
void *__libnx_aligned_alloc(size_t, size_t) { /* Work around a bug with process permissions on < 4.0.0. */
AMS_ABORT("__libnx_aligned_alloc was called"); /* This registers all initial processes explicitly with both fs and sm. */
} pm::RegisterPrivilegedProcesses();
void __libnx_free(void *) { /* Use our manager extension to tell SM that the FS bug has been worked around. */
AMS_ABORT("__libnx_free was called"); R_ABORT_UNLESS(sm::manager::EndInitialDefers());
}
int main(int argc, char **argv) /* Initialize remaining services we need. */
{ R_ABORT_UNLESS(ldrPmInitialize());
AMS_UNUSED(argc, argv); spl::Initialize();
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void NORETURN Exit(int rc) {
AMS_UNUSED(rc);
AMS_ABORT("Exit called by immortal process");
}
void Main() {
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pm, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pm, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pm, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pm, Main));
@ -266,15 +210,13 @@ int main(int argc, char **argv)
R_ABORT_UNLESS(pm::impl::InitializeProcessManager()); R_ABORT_UNLESS(pm::impl::InitializeProcessManager());
/* Create Services. */ /* Create Services. */
/* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */ pm::RegisterServices();
R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Shell, ShellServiceName, ShellMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_DebugMonitor, DebugMonitorServiceName, DebugMonitorMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_BootMode, BootModeServiceName, BootModeMaxSessions));
R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Information, InformationServiceName, InformationMaxSessions));
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
g_server_manager.LoopProcess(); pm::LoopProcess();
/* This can never be reached. */
AMS_ASSUME(false);
}
return 0;
} }

View file

@ -17,28 +17,9 @@
#include "ro_debug_monitor_service.hpp" #include "ro_debug_monitor_service.hpp"
#include "ro_ro_service.hpp" #include "ro_ro_service.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace ro {
u32 __nx_fs_num_sessions = 1;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
void *__libnx_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
namespace ams::ro {
namespace { namespace {
@ -120,84 +101,39 @@ namespace ams::ro {
} }
} }
void __libnx_initheap(void) { namespace init {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */ void InitializeSystemModule() {
extern char* fake_heap_start; /* Initialize heap. */
extern char* fake_heap_end; ro::InitializeHeap();
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
ams::ro::InitializeHeap();
}
void __appInit(void) {
hos::InitializeForStratosphere();
fs::SetAllocator(ro::Allocate, ro::Deallocate);
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize()); R_ABORT_UNLESS(sm::Initialize());
R_ABORT_UNLESS(setsysInitialize()); /* Initialize fs. */
R_ABORT_UNLESS(fsInitialize()); fs::InitializeForSystem();
spl::Initialize(); fs::SetAllocator(ro::Allocate, ro::Deallocate);
fs::SetEnabledAutoAbort(false);
/* Initialize other services we need. */
R_ABORT_UNLESS(setsysInitialize());
/* Mount the SD card. */
R_ABORT_UNLESS(fs::MountSdCard("sdmc")); R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
/* Verify that we can sanely execute. */
ams::CheckApiVersion(); ams::CheckApiVersion();
}
void __appExit(void) {
fsExit();
setsysExit();
}
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
} }
void Free(void *) { void FinalizeSystemModule() { /* ... */ }
AMS_ABORT("ams::Free was called");
void Startup() { /* ... */ }
} }
} void Main() {
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ro, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ro, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ro, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ro, Main));
@ -205,11 +141,9 @@ int main(int argc, char **argv)
/* Attach the server allocator. */ /* Attach the server allocator. */
ro::g_server_allocator.Attach(ro::g_server_heap_handle); ro::g_server_allocator.Attach(ro::g_server_heap_handle);
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Initialize Debug config. */ /* Initialize Debug config. */
{ {
spl::Initialize();
ON_SCOPE_EXIT { spl::Finalize(); }; ON_SCOPE_EXIT { spl::Finalize(); };
ro::SetDevelopmentHardware(spl::IsDevelopment()); ro::SetDevelopmentHardware(spl::IsDevelopment());
@ -218,8 +152,6 @@ int main(int argc, char **argv)
/* Run the ro server. */ /* Run the ro server. */
ro::LoopServer(); ro::LoopServer();
}
/* Cleanup */
return 0;
} }

View file

@ -16,111 +16,24 @@
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "sm_tipc_server.hpp" #include "sm_tipc_server.hpp"
extern "C" {
extern u32 __start__;
extern int __system_argc;
extern char** __system_argv;
u32 __nx_applet_type = AppletType_None;
#define INNER_HEAP_SIZE 0x0
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void argvSetup(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
namespace {
constinit char *g_empty_argv = nullptr;
}
namespace ams { namespace ams {
namespace init {
void InitializeSystemModule() { /* ... */ }
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void NORETURN Exit(int rc) { void NORETURN Exit(int rc) {
AMS_UNUSED(rc); AMS_UNUSED(rc);
AMS_ABORT("Exit called by immortal process"); AMS_ABORT("Exit called by immortal process");
} }
} void Main() {
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void argvSetup(void) {
/* We don't need argc/argv, so set them to empty defaults. */
__system_argc = 0;
__system_argv = std::addressof(g_empty_argv);
}
void __appInit(void) {
hos::InitializeForStratosphere();
/* We must do no service setup here, because we are sm. */
}
void __appExit(void) {
/* Nothing to clean up, because we're sm. */
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(sm, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(sm, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(sm, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(sm, Main));
@ -133,4 +46,6 @@ int main(int argc, char **argv)
/* This can never be reached. */ /* This can never be reached. */
AMS_ASSUME(false); AMS_ASSUME(false);
}
} }

View file

@ -26,61 +26,11 @@
#include "spl_deprecated_service.hpp" #include "spl_deprecated_service.hpp"
extern "C" { namespace ams {
extern u32 __start__;
u32 __nx_applet_type = AppletType_None; namespace spl {
#define INNER_HEAP_SIZE 0x0 namespace {
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void);
void __appInit(void);
void __appExit(void);
/* Exception handling. */
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_alloc(size_t size);
void *__libnx_aligned_alloc(size_t alignment, size_t size);
void __libnx_free(void *mem);
}
using namespace ams;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx);
}
void __libnx_initheap(void) {
void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size;
/* Newlib */
extern char* fake_heap_start;
extern char* fake_heap_end;
fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size;
}
void __appInit(void) {
hos::InitializeForStratosphere();
/* SPL doesn't really access any services... */
R_ABORT_UNLESS(sm::Initialize());
ams::CheckApiVersion();
}
void __appExit(void) {
/* SPL doesn't really access any services... */
}
namespace {
struct SplServerOptions { struct SplServerOptions {
static constexpr size_t PointerBufferSize = 0x800; static constexpr size_t PointerBufferSize = 0x800;
@ -173,52 +123,7 @@ namespace {
} }
} }
} void SplMain() {
namespace ams {
void *Malloc(size_t) {
AMS_ABORT("ams::Malloc was called");
}
void Free(void *) {
AMS_ABORT("ams::Free was called");
}
}
void *operator new(size_t) {
AMS_ABORT("operator new(size_t) was called");
}
void operator delete(void *) {
AMS_ABORT("operator delete(void *) was called");
}
void operator delete(void *, size_t) {
AMS_ABORT("operator delete(void *, size_t) was called");
}
void *__libnx_alloc(size_t) {
AMS_ABORT("__libnx_alloc was called");
}
void *__libnx_aligned_alloc(size_t, size_t) {
AMS_ABORT("__libnx_aligned_alloc was called");
}
void __libnx_free(void *) {
AMS_ABORT("__libnx_free was called");
}
int main(int argc, char **argv)
{
AMS_UNUSED(argc, argv);
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(spl, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(spl, Main));
/* Setup server allocator. */ /* Setup server allocator. */
g_server_allocator.Attach(lmem::CreateExpHeap(g_server_allocator_buffer, sizeof(g_server_allocator_buffer), lmem::CreateOption_None)); g_server_allocator.Attach(lmem::CreateExpHeap(g_server_allocator_buffer, sizeof(g_server_allocator_buffer), lmem::CreateOption_None));
@ -241,6 +146,43 @@ int main(int argc, char **argv)
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
g_server_manager.LoopProcess(); g_server_manager.LoopProcess();
}
}
}
namespace init {
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }
void Startup() { /* ... */ }
}
void NORETURN Exit(int rc) {
AMS_UNUSED(rc);
AMS_ABORT("Exit called by immortal process");
}
void Main() {
/* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(spl, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(spl, Main));
/* Invoke SPL main. */
spl::SplMain();
/* This can never be reached. */
AMS_ASSUME(false);
}
return 0;
} }