diff options
| author | 2018-10-04 09:42:37 -0400 | |
|---|---|---|
| committer | 2018-10-04 09:42:37 -0400 | |
| commit | f85f2b372807b9785bfe30b2b1e2f342d58bddf6 (patch) | |
| tree | 90fbcbdc532c106407503531e38c736471272e1e /src/core/loader | |
| parent | Merge pull request #1434 from DarkLordZach/dlc-edge-case (diff) | |
| parent | nso: Optimize loading of IPS patches (diff) | |
| download | yuzu-f85f2b372807b9785bfe30b2b1e2f342d58bddf6.tar.gz yuzu-f85f2b372807b9785bfe30b2b1e2f342d58bddf6.tar.xz yuzu-f85f2b372807b9785bfe30b2b1e2f342d58bddf6.zip | |
Merge pull request #1415 from DarkLordZach/ips
file_sys: Add support for loading IPS patches
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 3 | ||||
| -rw-r--r-- | src/core/loader/nso.cpp | 18 | ||||
| -rw-r--r-- | src/core/loader/nso.h | 4 |
3 files changed, 20 insertions, 5 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index c1824b9c3..9a86e5824 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -130,6 +130,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | process.LoadFromMetadata(metadata); | 132 | process.LoadFromMetadata(metadata); |
| 133 | const FileSys::PatchManager pm(metadata.GetTitleID()); | ||
| 133 | 134 | ||
| 134 | // Load NSO modules | 135 | // Load NSO modules |
| 135 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | 136 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); |
| @@ -139,7 +140,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 139 | const FileSys::VirtualFile module_file = dir->GetFile(module); | 140 | const FileSys::VirtualFile module_file = dir->GetFile(module); |
| 140 | if (module_file != nullptr) { | 141 | if (module_file != nullptr) { |
| 141 | const VAddr load_addr = next_load_addr; | 142 | const VAddr load_addr = next_load_addr; |
| 142 | next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); | 143 | next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr, pm); |
| 143 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); | 144 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); |
| 144 | // Register module with GDBStub | 145 | // Register module with GDBStub |
| 145 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); | 146 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index cbe2a3e53..2186b02af 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "core/file_sys/patch_manager.h" | ||
| 13 | #include "core/gdbstub/gdbstub.h" | 14 | #include "core/gdbstub/gdbstub.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 15 | #include "core/hle/kernel/process.h" | 16 | #include "core/hle/kernel/process.h" |
| @@ -36,8 +37,7 @@ struct NsoHeader { | |||
| 36 | INSERT_PADDING_WORDS(1); | 37 | INSERT_PADDING_WORDS(1); |
| 37 | u8 flags; | 38 | u8 flags; |
| 38 | std::array<NsoSegmentHeader, 3> segments; // Text, RoData, Data (in that order) | 39 | std::array<NsoSegmentHeader, 3> segments; // Text, RoData, Data (in that order) |
| 39 | u32_le bss_size; | 40 | std::array<u8, 0x20> build_id; |
| 40 | INSERT_PADDING_BYTES(0x1c); | ||
| 41 | std::array<u32_le, 3> segments_compressed_size; | 41 | std::array<u32_le, 3> segments_compressed_size; |
| 42 | 42 | ||
| 43 | bool IsSegmentCompressed(size_t segment_num) const { | 43 | bool IsSegmentCompressed(size_t segment_num) const { |
| @@ -93,7 +93,8 @@ static constexpr u32 PageAlignSize(u32 size) { | |||
| 93 | return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; | 93 | return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) { | 96 | VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, |
| 97 | boost::optional<FileSys::PatchManager> pm) { | ||
| 97 | if (file == nullptr) | 98 | if (file == nullptr) |
| 98 | return {}; | 99 | return {}; |
| 99 | 100 | ||
| @@ -142,6 +143,17 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) { | |||
| 142 | const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; | 143 | const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; |
| 143 | program_image.resize(image_size); | 144 | program_image.resize(image_size); |
| 144 | 145 | ||
| 146 | // Apply patches if necessary | ||
| 147 | if (pm != boost::none && pm->HasNSOPatch(nso_header.build_id)) { | ||
| 148 | std::vector<u8> pi_header(program_image.size() + 0x100); | ||
| 149 | std::memcpy(pi_header.data(), &nso_header, sizeof(NsoHeader)); | ||
| 150 | std::memcpy(pi_header.data() + 0x100, program_image.data(), program_image.size()); | ||
| 151 | |||
| 152 | pi_header = pm->PatchNSO(pi_header); | ||
| 153 | |||
| 154 | std::memcpy(program_image.data(), pi_header.data() + 0x100, program_image.size()); | ||
| 155 | } | ||
| 156 | |||
| 145 | // Load codeset for current process | 157 | // Load codeset for current process |
| 146 | codeset->name = file->GetName(); | 158 | codeset->name = file->GetName(); |
| 147 | codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | 159 | codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); |
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 7f142405b..05353d4d9 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/file_sys/patch_manager.h" | ||
| 8 | #include "core/loader/linker.h" | 9 | #include "core/loader/linker.h" |
| 9 | #include "core/loader/loader.h" | 10 | #include "core/loader/loader.h" |
| 10 | 11 | ||
| @@ -26,7 +27,8 @@ public: | |||
| 26 | return IdentifyType(file); | 27 | return IdentifyType(file); |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base); | 30 | static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base, |
| 31 | boost::optional<FileSys::PatchManager> pm = boost::none); | ||
| 30 | 32 | ||
| 31 | ResultStatus Load(Kernel::Process& process) override; | 33 | ResultStatus Load(Kernel::Process& process) override; |
| 32 | }; | 34 | }; |