diff options
| author | 2016-09-18 09:38:01 +0900 | |
|---|---|---|
| committer | 2016-09-18 09:38:01 +0900 | |
| commit | dc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch) | |
| tree | 569a7f13128450bbab973236615587ff00bced5f /src/core/loader/3dsx.cpp | |
| parent | Travis: Import Dolphin’s clang-format hook. (diff) | |
| download | yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip | |
Sources: Run clang-format on everything.
Diffstat (limited to 'src/core/loader/3dsx.cpp')
| -rw-r--r-- | src/core/loader/3dsx.cpp | 85 |
1 files changed, 43 insertions, 42 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index a16411e14..c2e87f592 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -37,20 +37,14 @@ namespace Loader { | |||
| 37 | * The BSS section must be cleared manually by the application. | 37 | * The BSS section must be cleared manually by the application. |
| 38 | */ | 38 | */ |
| 39 | 39 | ||
| 40 | enum THREEDSX_Error { | 40 | enum THREEDSX_Error { ERROR_NONE = 0, ERROR_READ = 1, ERROR_FILE = 2, ERROR_ALLOC = 3 }; |
| 41 | ERROR_NONE = 0, | ||
| 42 | ERROR_READ = 1, | ||
| 43 | ERROR_FILE = 2, | ||
| 44 | ERROR_ALLOC = 3 | ||
| 45 | }; | ||
| 46 | 41 | ||
| 47 | static const u32 RELOCBUFSIZE = 512; | 42 | static const u32 RELOCBUFSIZE = 512; |
| 48 | static const unsigned int NUM_SEGMENTS = 3; | 43 | static const unsigned int NUM_SEGMENTS = 3; |
| 49 | 44 | ||
| 50 | // File header | 45 | // File header |
| 51 | #pragma pack(1) | 46 | #pragma pack(1) |
| 52 | struct THREEDSX_Header | 47 | struct THREEDSX_Header { |
| 53 | { | ||
| 54 | u32 magic; | 48 | u32 magic; |
| 55 | u16 header_size, reloc_hdr_size; | 49 | u16 header_size, reloc_hdr_size; |
| 56 | u32 format_ver; | 50 | u32 format_ver; |
| @@ -66,11 +60,11 @@ struct THREEDSX_Header | |||
| 66 | }; | 60 | }; |
| 67 | 61 | ||
| 68 | // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. | 62 | // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. |
| 69 | struct THREEDSX_RelocHdr | 63 | struct THREEDSX_RelocHdr { |
| 70 | { | ||
| 71 | // # of absolute relocations (that is, fix address to post-relocation memory layout) | 64 | // # of absolute relocations (that is, fix address to post-relocation memory layout) |
| 72 | u32 cross_segment_absolute; | 65 | u32 cross_segment_absolute; |
| 73 | // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched) | 66 | // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be |
| 67 | // patched) | ||
| 74 | u32 cross_segment_relative; | 68 | u32 cross_segment_relative; |
| 75 | // more? | 69 | // more? |
| 76 | 70 | ||
| @@ -80,21 +74,18 @@ struct THREEDSX_RelocHdr | |||
| 80 | }; | 74 | }; |
| 81 | 75 | ||
| 82 | // Relocation entry: from the current pointer, skip X words and patch Y words | 76 | // Relocation entry: from the current pointer, skip X words and patch Y words |
| 83 | struct THREEDSX_Reloc | 77 | struct THREEDSX_Reloc { |
| 84 | { | ||
| 85 | u16 skip, patch; | 78 | u16 skip, patch; |
| 86 | }; | 79 | }; |
| 87 | #pragma pack() | 80 | #pragma pack() |
| 88 | 81 | ||
| 89 | struct THREEloadinfo | 82 | struct THREEloadinfo { |
| 90 | { | ||
| 91 | u8* seg_ptrs[3]; // code, rodata & data | 83 | u8* seg_ptrs[3]; // code, rodata & data |
| 92 | u32 seg_addrs[3]; | 84 | u32 seg_addrs[3]; |
| 93 | u32 seg_sizes[3]; | 85 | u32 seg_sizes[3]; |
| 94 | }; | 86 | }; |
| 95 | 87 | ||
| 96 | static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) | 88 | static u32 TranslateAddr(u32 addr, const THREEloadinfo* loadinfo, u32* offsets) { |
| 97 | { | ||
| 98 | if (addr < offsets[0]) | 89 | if (addr < offsets[0]) |
| 99 | return loadinfo->seg_addrs[0] + addr; | 90 | return loadinfo->seg_addrs[0] + addr; |
| 100 | if (addr < offsets[1]) | 91 | if (addr < offsets[1]) |
| @@ -105,8 +96,8 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) | |||
| 105 | using Kernel::SharedPtr; | 96 | using Kernel::SharedPtr; |
| 106 | using Kernel::CodeSet; | 97 | using Kernel::CodeSet; |
| 107 | 98 | ||
| 108 | static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset) | 99 | static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, |
| 109 | { | 100 | SharedPtr<CodeSet>* out_codeset) { |
| 110 | if (!file.IsOpen()) | 101 | if (!file.IsOpen()) |
| 111 | return ERROR_FILE; | 102 | return ERROR_FILE; |
| 112 | 103 | ||
| @@ -118,13 +109,14 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 118 | return ERROR_READ; | 109 | return ERROR_READ; |
| 119 | 110 | ||
| 120 | THREEloadinfo loadinfo; | 111 | THREEloadinfo loadinfo; |
| 121 | //loadinfo segments must be a multiple of 0x1000 | 112 | // loadinfo segments must be a multiple of 0x1000 |
| 122 | loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) &~0xFFF; | 113 | loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) & ~0xFFF; |
| 123 | loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) &~0xFFF; | 114 | loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) & ~0xFFF; |
| 124 | loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) &~0xFFF; | 115 | loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) & ~0xFFF; |
| 125 | u32 offsets[2] = { loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] }; | 116 | u32 offsets[2] = {loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1]}; |
| 126 | u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32); | 117 | u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32); |
| 127 | std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); | 118 | std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + |
| 119 | loadinfo.seg_sizes[2]); | ||
| 128 | 120 | ||
| 129 | loadinfo.seg_addrs[0] = base_addr; | 121 | loadinfo.seg_addrs[0] = base_addr; |
| 130 | loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; | 122 | loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; |
| @@ -149,7 +141,8 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 149 | return ERROR_READ; | 141 | return ERROR_READ; |
| 150 | if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size) | 142 | if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size) |
| 151 | return ERROR_READ; | 143 | return ERROR_READ; |
| 152 | if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != hdr.data_seg_size - hdr.bss_size) | 144 | if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != |
| 145 | hdr.data_seg_size - hdr.bss_size) | ||
| 153 | return ERROR_READ; | 146 | return ERROR_READ; |
| 154 | 147 | ||
| 155 | // BSS clear | 148 | // BSS clear |
| @@ -157,11 +150,12 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 157 | 150 | ||
| 158 | // Relocate the segments | 151 | // Relocate the segments |
| 159 | for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) { | 152 | for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) { |
| 160 | for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { | 153 | for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; |
| 154 | current_segment_reloc_table++) { | ||
| 161 | u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; | 155 | u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; |
| 162 | if (current_segment_reloc_table >= 2) { | 156 | if (current_segment_reloc_table >= 2) { |
| 163 | // We are not using this table - ignore it because we don't know what it dose | 157 | // We are not using this table - ignore it because we don't know what it dose |
| 164 | file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); | 158 | file.Seek(n_relocs * sizeof(THREEDSX_Reloc), SEEK_CUR); |
| 165 | continue; | 159 | continue; |
| 166 | } | 160 | } |
| 167 | THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; | 161 | THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; |
| @@ -173,17 +167,20 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 173 | u32 remaining = std::min(RELOCBUFSIZE, n_relocs); | 167 | u32 remaining = std::min(RELOCBUFSIZE, n_relocs); |
| 174 | n_relocs -= remaining; | 168 | n_relocs -= remaining; |
| 175 | 169 | ||
| 176 | if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != remaining * sizeof(THREEDSX_Reloc)) | 170 | if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != |
| 171 | remaining * sizeof(THREEDSX_Reloc)) | ||
| 177 | return ERROR_READ; | 172 | return ERROR_READ; |
| 178 | 173 | ||
| 179 | for (unsigned current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { | 174 | for (unsigned current_inprogress = 0; |
| 175 | current_inprogress < remaining && pos < end_pos; current_inprogress++) { | ||
| 180 | const auto& table = reloc_table[current_inprogress]; | 176 | const auto& table = reloc_table[current_inprogress]; |
| 181 | LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)", current_segment_reloc_table, | 177 | LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)", current_segment_reloc_table, |
| 182 | static_cast<u32>(table.skip), static_cast<u32>(table.patch)); | 178 | static_cast<u32>(table.skip), static_cast<u32>(table.patch)); |
| 183 | pos += table.skip; | 179 | pos += table.skip; |
| 184 | s32 num_patches = table.patch; | 180 | s32 num_patches = table.patch; |
| 185 | while (0 < num_patches && pos < end_pos) { | 181 | while (0 < num_patches && pos < end_pos) { |
| 186 | u32 in_addr = static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); | 182 | u32 in_addr = |
| 183 | static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); | ||
| 187 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); | 184 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); |
| 188 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", | 185 | LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", |
| 189 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); | 186 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); |
| @@ -195,7 +192,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 195 | *pos = static_cast<u32>(addr - in_addr); | 192 | *pos = static_cast<u32>(addr - in_addr); |
| 196 | break; | 193 | break; |
| 197 | default: | 194 | default: |
| 198 | break; //this should never happen | 195 | break; // this should never happen |
| 199 | } | 196 | } |
| 200 | pos++; | 197 | pos++; |
| 201 | num_patches--; | 198 | num_patches--; |
| @@ -209,23 +206,24 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 209 | SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); | 206 | SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); |
| 210 | 207 | ||
| 211 | code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); | 208 | code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); |
| 212 | code_set->code.addr = loadinfo.seg_addrs[0]; | 209 | code_set->code.addr = loadinfo.seg_addrs[0]; |
| 213 | code_set->code.size = loadinfo.seg_sizes[0]; | 210 | code_set->code.size = loadinfo.seg_sizes[0]; |
| 214 | 211 | ||
| 215 | code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); | 212 | code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); |
| 216 | code_set->rodata.addr = loadinfo.seg_addrs[1]; | 213 | code_set->rodata.addr = loadinfo.seg_addrs[1]; |
| 217 | code_set->rodata.size = loadinfo.seg_sizes[1]; | 214 | code_set->rodata.size = loadinfo.seg_sizes[1]; |
| 218 | 215 | ||
| 219 | code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); | 216 | code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); |
| 220 | code_set->data.addr = loadinfo.seg_addrs[2]; | 217 | code_set->data.addr = loadinfo.seg_addrs[2]; |
| 221 | code_set->data.size = loadinfo.seg_sizes[2]; | 218 | code_set->data.size = loadinfo.seg_sizes[2]; |
| 222 | 219 | ||
| 223 | code_set->entrypoint = code_set->code.addr; | 220 | code_set->entrypoint = code_set->code.addr; |
| 224 | code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | 221 | code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); |
| 225 | 222 | ||
| 226 | LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); | 223 | LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); |
| 227 | LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); | 224 | LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); |
| 228 | LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size); | 225 | LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], |
| 226 | hdr.bss_size); | ||
| 229 | 227 | ||
| 230 | *out_codeset = code_set; | 228 | *out_codeset = code_set; |
| 231 | return ERROR_NONE; | 229 | return ERROR_NONE; |
| @@ -260,17 +258,20 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 260 | Kernel::g_current_process->address_mappings = default_address_mappings; | 258 | Kernel::g_current_process->address_mappings = default_address_mappings; |
| 261 | 259 | ||
| 262 | // Attach the default resource limit (APPLICATION) to the process | 260 | // Attach the default resource limit (APPLICATION) to the process |
| 263 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | 261 | Kernel::g_current_process->resource_limit = |
| 262 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||
| 264 | 263 | ||
| 265 | Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); | 264 | Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); |
| 266 | 265 | ||
| 267 | Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS); | 266 | Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), |
| 267 | Service::FS::ArchiveIdCode::RomFS); | ||
| 268 | 268 | ||
| 269 | is_loaded = true; | 269 | is_loaded = true; |
| 270 | return ResultStatus::Success; | 270 | return ResultStatus::Success; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { | 273 | ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, |
| 274 | u64& offset, u64& size) { | ||
| 274 | if (!file.IsOpen()) | 275 | if (!file.IsOpen()) |
| 275 | return ResultStatus::Error; | 276 | return ResultStatus::Error; |
| 276 | 277 | ||