diff options
Diffstat (limited to 'src/core/loader/nso.cpp')
-rw-r--r-- | src/core/loader/nso.cpp | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 2186b02af..ba57db9bf 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -12,11 +12,11 @@ #include "core/core.h" #include "core/file_sys/patch_manager.h" #include "core/gdbstub/gdbstub.h" -#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/vm_manager.h" #include "core/loader/nso.h" #include "core/memory.h" +#include "core/settings.h" namespace Loader { @@ -94,6 +94,7 @@ static constexpr u32 PageAlignSize(u32 size) { } VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, + bool should_pass_arguments, boost::optional<FileSys::PatchManager> pm) { if (file == nullptr) return {}; @@ -109,8 +110,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, return {}; // Build program image - auto& kernel = Core::System::GetInstance().Kernel(); - Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, ""); + Kernel::CodeSet codeset; std::vector<u8> program_image; for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { std::vector<u8> data = @@ -120,9 +120,22 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, } program_image.resize(nso_header.segments[i].location); program_image.insert(program_image.end(), data.begin(), data.end()); - codeset->segments[i].addr = nso_header.segments[i].location; - codeset->segments[i].offset = nso_header.segments[i].location; - codeset->segments[i].size = PageAlignSize(static_cast<u32>(data.size())); + codeset.segments[i].addr = nso_header.segments[i].location; + codeset.segments[i].offset = nso_header.segments[i].location; + codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); + } + + if (should_pass_arguments && !Settings::values.program_args.empty()) { + const auto arg_data = Settings::values.program_args; + codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; + NSOArgumentHeader args_header{ + NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; + const auto end_offset = program_image.size(); + program_image.resize(static_cast<u32>(program_image.size()) + + NSO_ARGUMENT_DATA_ALLOCATION_SIZE); + std::memcpy(program_image.data() + end_offset, &args_header, sizeof(NSOArgumentHeader)); + std::memcpy(program_image.data() + end_offset + sizeof(NSOArgumentHeader), arg_data.data(), + arg_data.size()); } // MOD header pointer is at .text offset + 4 @@ -139,7 +152,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, // Resize program image to include .bss section and page align each section bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); } - codeset->DataSegment().size += bss_size; + codeset.DataSegment().size += bss_size; const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; program_image.resize(image_size); @@ -155,12 +168,11 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, } // Load codeset for current process - codeset->name = file->GetName(); - codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); - Core::CurrentProcess()->LoadModule(codeset, load_base); + codeset.memory = std::make_shared<std::vector<u8>>(std::move(program_image)); + Core::CurrentProcess()->LoadModule(std::move(codeset), load_base); // Register module with GDBStub - GDBStub::RegisterModule(codeset->name, load_base, load_base); + GDBStub::RegisterModule(file->GetName(), load_base, load_base); return load_base + image_size; } @@ -172,7 +184,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) { // Load module const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); - LoadModule(file, base_address); + LoadModule(file, base_address, true); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); |