diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 1d6c309621..43169bf9f4 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -51,6 +51,17 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { return Loader::ResultStatus::Success; } +/*static*/ ProgramMetadata ProgramMetadata::GetDefault() { + ProgramMetadata result; + + result.LoadManual( + true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/, + 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x00100000 /*main_thread_stack_size*/, + {}, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, {} /*capabilities*/); + + return result; +} + void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index f8759a3968..35069972b1 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -44,9 +44,13 @@ public: ProgramMetadata(); ~ProgramMetadata(); + /// Gets a default ProgramMetadata configuration, should only be used for homebrew formats where + /// we do not have an NPDM file + static ProgramMetadata GetDefault(); + Loader::ResultStatus Load(VirtualFile file); - // Load from parameters instead of NPDM file, used for KIP + /// Load from parameters instead of NPDM file, used for KIP void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, u64 filesystem_permissions, KernelCapabilityDescriptors capabilities); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 1e9ed28373..8f76151150 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -398,6 +398,11 @@ AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::Process& process) { Kernel::CodeSet codeset = elf_reader.LoadInto(base_address); const VAddr entry_point = codeset.entrypoint; + // Setup the process code layout + if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), buffer.size()).IsError()) { + return {ResultStatus::ErrorNotInitialized, {}}; + } + process.LoadModule(std::move(codeset), entry_point); is_loaded = true; diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 5d7e8136e7..906544bc95 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -131,7 +131,7 @@ static constexpr u32 PageAlignSize(u32 size) { } static bool LoadNroImpl(Kernel::Process& process, const std::vector& data, - const std::string& name, VAddr load_base) { + const std::string& name) { if (data.size() < sizeof(NroHeader)) { return {}; } @@ -187,19 +187,25 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector& data, codeset.DataSegment().size += bss_size; program_image.resize(static_cast(program_image.size()) + bss_size); + // Setup the process code layout + if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size()) + .IsError()) { + return false; + } + // Load codeset for current process codeset.memory = std::move(program_image); - process.LoadModule(std::move(codeset), load_base); + process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart()); // Register module with GDBStub - GDBStub::RegisterModule(name, load_base, load_base); + GDBStub::RegisterModule(name, process.PageTable().GetCodeRegionStart(), + process.PageTable().GetCodeRegionEnd()); return true; } -bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& file, - VAddr load_base) { - return LoadNroImpl(process, file.ReadAllBytes(), file.GetName(), load_base); +bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& file) { + return LoadNroImpl(process, file.ReadAllBytes(), file.GetName()); } AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process) { @@ -207,10 +213,7 @@ AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } - // Load NRO - const VAddr base_address = process.PageTable().GetCodeRegionStart(); - - if (!LoadNro(process, *file, base_address)) { + if (!LoadNro(process, *file)) { return {ResultStatus::ErrorLoadingNRO, {}}; } diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 71811bc29c..4593d48fb0 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -47,7 +47,7 @@ public: bool IsRomFSUpdatable() const override; private: - bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& file, VAddr load_base); + bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& file); std::vector icon_data; std::unique_ptr nacp;