Skip to content
Snippets Groups Projects
Commit d3e63e42 authored by gdkchan's avatar gdkchan
Browse files

Fix NRO loading

parent e2f06dbc
No related branches found
No related tags found
No related merge requests found
......@@ -62,20 +62,6 @@ static constexpr u32 PageAlignSize(u32 size) {
return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
}
static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NroSegmentHeader& header) {
std::vector<u8> data;
data.resize(header.size);
file.Seek(header.offset + sizeof(NroHeader), SEEK_SET);
size_t bytes_read{file.ReadBytes(data.data(), header.size)};
if (header.size != PageAlignSize(static_cast<u32>(bytes_read))) {
LOG_CRITICAL(Loader, "Failed to read NRO segment bytes", header.size);
return {};
}
return data;
}
bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) {
FileUtil::IOFile file(path, "rb");
if (!file.IsOpen()) {
......@@ -95,7 +81,7 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) {
// Build program image
Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create("", 0);
std::vector<u8> program_image;
program_image.resize(PageAlignSize(nro_header.file_size + nro_header.bss_size));
program_image.resize(PageAlignSize(nro_header.file_size));
file.Seek(0, SEEK_SET);
file.ReadBytes(program_image.data(), nro_header.file_size);
......@@ -107,15 +93,16 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) {
// Read MOD header
ModHeader mod_header{};
u32 bss_size{Memory::PAGE_SIZE}; // Default .bss to page size if MOD0 section doesn't exist
// Default .bss to NRO header bss size if MOD0 section doesn't exist
u32 bss_size{PageAlignSize(nro_header.bss_size)};
std::memcpy(&mod_header, program_image.data() + nro_header.module_header_offset,
sizeof(ModHeader));
const bool has_mod_header{mod_header.magic == Common::MakeMagic('M', 'O', 'D', '0')};
if (has_mod_header) {
// 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->data.size += bss_size;
}
codeset->data.size += bss_size;
program_image.resize(PageAlignSize(static_cast<u32>(program_image.size()) + bss_size));
// Load codeset for current process
......@@ -134,9 +121,11 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::Error;
}
// Load and relocate "main" and "sdk" NSO
static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
process = Kernel::Process::Create("main");
// Load NRO
static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
if (!LoadNro(filepath, base_addr)) {
return ResultStatus::ErrorInvalidFormat;
}
......@@ -145,7 +134,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(base_addr, 48, Kernel::DEFAULT_STACK_SIZE);
process->Run(base_addr + sizeof(NroHeader), 48, Kernel::DEFAULT_STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment