aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/loader/3dsx.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-07-09 22:52:15 -0300
committerGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-07-11 23:54:42 -0300
commit5c5cf2f8e000d1bf4fc12ff20351aa60367cb563 (patch)
tree2b233263cff7c001506f660373e2364c8e702637 /src/core/loader/3dsx.cpp
parent51820691e77b816da7d4d66de68e3c0b79f2781a (diff)
Core: Properly configure address space when loading a binary
The code now properly configures the process image to match the loaded binary segments (code, rodata, data) instead of just blindly allocating a large chunk of dummy memory.
Diffstat (limited to 'src/core/loader/3dsx.cpp')
-rw-r--r--src/core/loader/3dsx.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index e57d7274..05566136 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -101,7 +101,10 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets)
return loadinfo->seg_addrs[2] + addr - offsets[1];
}
-static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr)
+using Kernel::SharedPtr;
+using Kernel::CodeSet;
+
+static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset)
{
if (!file.IsOpen())
return ERROR_FILE;
@@ -201,13 +204,29 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr)
}
}
- // Write the data
- memcpy(Memory::GetPointer(base_addr), program_image.data(), program_image.size());
+ // Create the CodeSet
+ SharedPtr<CodeSet> code_set = CodeSet::Create("", 0);
+
+ code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data();
+ code_set->code.addr = loadinfo.seg_addrs[0];
+ code_set->code.size = loadinfo.seg_sizes[0];
+
+ code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data();
+ code_set->rodata.addr = loadinfo.seg_addrs[1];
+ code_set->rodata.size = loadinfo.seg_sizes[1];
+
+ code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data();
+ code_set->data.addr = loadinfo.seg_addrs[2];
+ code_set->data.size = loadinfo.seg_sizes[2];
+
+ code_set->entrypoint = code_set->code.addr;
+ code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]);
LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]);
LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size);
+ *out_codeset = code_set;
return ERROR_NONE;
}
@@ -230,17 +249,19 @@ ResultStatus AppLoader_THREEDSX::Load() {
if (!file->IsOpen())
return ResultStatus::Error;
- Kernel::g_current_process = Kernel::Process::Create(filename, 0);
+ SharedPtr<CodeSet> codeset;
+ if (Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR, &codeset) != ERROR_NONE)
+ return ResultStatus::Error;
+ codeset->name = filename;
+
+ Kernel::g_current_process = Kernel::Process::Create(std::move(codeset));
Kernel::g_current_process->svc_access_mask.set();
Kernel::g_current_process->address_mappings = default_address_mappings;
// Attach the default resource limit (APPLICATION) to the process
Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- if (Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR) != ERROR_NONE)
- return ResultStatus::Error;
-
- Kernel::g_current_process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE);
+ Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;