diff options
| author | 2015-07-09 22:52:15 -0300 | |
|---|---|---|
| committer | 2015-07-11 23:54:42 -0300 | |
| commit | 5c5cf2f8e000d1bf4fc12ff20351aa60367cb563 (patch) | |
| tree | 2b233263cff7c001506f660373e2364c8e702637 /src/core/loader/3dsx.cpp | |
| parent | Memory: Fix unmapping of pages (diff) | |
| download | yuzu-5c5cf2f8e000d1bf4fc12ff20351aa60367cb563.tar.gz yuzu-5c5cf2f8e000d1bf4fc12ff20351aa60367cb563.tar.xz yuzu-5c5cf2f8e000d1bf4fc12ff20351aa60367cb563.zip | |
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.cpp | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index e57d7274c..055661363 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) | |||
| 101 | return loadinfo->seg_addrs[2] + addr - offsets[1]; | 101 | return loadinfo->seg_addrs[2] + addr - offsets[1]; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | 104 | using Kernel::SharedPtr; |
| 105 | using Kernel::CodeSet; | ||
| 106 | |||
| 107 | static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset) | ||
| 105 | { | 108 | { |
| 106 | if (!file.IsOpen()) | 109 | if (!file.IsOpen()) |
| 107 | return ERROR_FILE; | 110 | return ERROR_FILE; |
| @@ -201,13 +204,29 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
| 201 | } | 204 | } |
| 202 | } | 205 | } |
| 203 | 206 | ||
| 204 | // Write the data | 207 | // Create the CodeSet |
| 205 | memcpy(Memory::GetPointer(base_addr), program_image.data(), program_image.size()); | 208 | SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); |
| 209 | |||
| 210 | code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); | ||
| 211 | code_set->code.addr = loadinfo.seg_addrs[0]; | ||
| 212 | code_set->code.size = loadinfo.seg_sizes[0]; | ||
| 213 | |||
| 214 | code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); | ||
| 215 | code_set->rodata.addr = loadinfo.seg_addrs[1]; | ||
| 216 | code_set->rodata.size = loadinfo.seg_sizes[1]; | ||
| 217 | |||
| 218 | code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); | ||
| 219 | code_set->data.addr = loadinfo.seg_addrs[2]; | ||
| 220 | code_set->data.size = loadinfo.seg_sizes[2]; | ||
| 221 | |||
| 222 | code_set->entrypoint = code_set->code.addr; | ||
| 223 | code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||
| 206 | 224 | ||
| 207 | LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); | 225 | LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); |
| 208 | LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); | 226 | LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); |
| 209 | LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size); | 227 | LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size); |
| 210 | 228 | ||
| 229 | *out_codeset = code_set; | ||
| 211 | return ERROR_NONE; | 230 | return ERROR_NONE; |
| 212 | } | 231 | } |
| 213 | 232 | ||
| @@ -230,17 +249,19 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 230 | if (!file->IsOpen()) | 249 | if (!file->IsOpen()) |
| 231 | return ResultStatus::Error; | 250 | return ResultStatus::Error; |
| 232 | 251 | ||
| 233 | Kernel::g_current_process = Kernel::Process::Create(filename, 0); | 252 | SharedPtr<CodeSet> codeset; |
| 253 | if (Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR, &codeset) != ERROR_NONE) | ||
| 254 | return ResultStatus::Error; | ||
| 255 | codeset->name = filename; | ||
| 256 | |||
| 257 | Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); | ||
| 234 | Kernel::g_current_process->svc_access_mask.set(); | 258 | Kernel::g_current_process->svc_access_mask.set(); |
| 235 | Kernel::g_current_process->address_mappings = default_address_mappings; | 259 | Kernel::g_current_process->address_mappings = default_address_mappings; |
| 236 | 260 | ||
| 237 | // Attach the default resource limit (APPLICATION) to the process | 261 | // Attach the default resource limit (APPLICATION) to the process |
| 238 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | 262 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); |
| 239 | 263 | ||
| 240 | if (Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR) != ERROR_NONE) | 264 | Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); |
| 241 | return ResultStatus::Error; | ||
| 242 | |||
| 243 | Kernel::g_current_process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE); | ||
| 244 | 265 | ||
| 245 | is_loaded = true; | 266 | is_loaded = true; |
| 246 | return ResultStatus::Success; | 267 | return ResultStatus::Success; |