Przeglądaj źródła

nso: Add framework to support patching of uncompressed NSOs

Zach Hilman 7 lat temu
rodzic
commit
003b44822a
2 zmienionych plików z 17 dodań i 2 usunięć
  1. 14 1
      src/core/loader/nso.cpp
  2. 3 1
      src/core/loader/nso.h

+ 14 - 1
src/core/loader/nso.cpp

@@ -10,6 +10,7 @@
 #include "common/logging/log.h"
 #include "common/swap.h"
 #include "core/core.h"
+#include "core/file_sys/patch_manager.h"
 #include "core/gdbstub/gdbstub.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
@@ -92,7 +93,8 @@ static constexpr u32 PageAlignSize(u32 size) {
     return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
 }
 
-VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
+VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
+                                std::shared_ptr<FileSys::PatchManager> pm) {
     if (file == nullptr)
         return {};
 
@@ -141,6 +143,17 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
     const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
     program_image.resize(image_size);
 
+    // Apply patches if necessary
+    if (pm != nullptr && pm->HasNSOPatch(nso_header.build_id)) {
+        std::vector<u8> pi_header(program_image.size() + 0x100);
+        std::memcpy(pi_header.data(), &nso_header, sizeof(NsoHeader));
+        std::memcpy(pi_header.data() + 0x100, program_image.data(), program_image.size());
+
+        pi_header = pm->PatchNSO(pi_header);
+
+        std::memcpy(program_image.data(), pi_header.data() + 0x100, program_image.size());
+    }
+
     // Load codeset for current process
     codeset->name = file->GetName();
     codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image));

+ 3 - 1
src/core/loader/nso.h

@@ -5,6 +5,7 @@
 #pragma once
 
 #include "common/common_types.h"
+#include "core/file_sys/patch_manager.h"
 #include "core/loader/linker.h"
 #include "core/loader/loader.h"
 
@@ -26,7 +27,8 @@ public:
         return IdentifyType(file);
     }
 
-    static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base);
+    static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base,
+                            std::shared_ptr<FileSys::PatchManager> pm = nullptr);
 
     ResultStatus Load(Kernel::Process& process) override;
 };