diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h index 7f54608e3f..53a923138c 100644 --- a/src/core/arm/nce/patcher.h +++ b/src/core/arm/nce/patcher.h @@ -16,24 +16,6 @@ #include "core/hle/kernel/physical_memory.h" #include "lru_cache.h" #include -using ModuleID = std::array; // NSO build ID -struct PatchCacheKey { - ModuleID module_id; - uintptr_t offset; - bool operator==(const PatchCacheKey&) const = default; -}; - -template <> -struct std::hash { - size_t operator()(const PatchCacheKey& key) const { - // Simple XOR hash of first few bytes - size_t hash = 0; - for (size_t i = 0; i < key.module_id.size(); ++i) { - hash ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); - } - return hash ^ std::hash{}(key.offset); - } -}; namespace Core::NCE { @@ -49,15 +31,13 @@ using EntryTrampolines = std::unordered_map class Patcher { public: - void SetModuleID(const ModuleID& id) { - module_id = id; - } Patcher(const Patcher&) = delete; Patcher& operator=(const Patcher&) = delete; Patcher(Patcher&& other) noexcept; Patcher& operator=(Patcher&&) noexcept = delete; explicit Patcher(); ~Patcher(); + bool PatchText(const Kernel::PhysicalMemory& program_image, const Kernel::CodeSet::Segment& code); bool RelocateAndCopy(Common::ProcessAddress load_base, const Kernel::CodeSet::Segment& code, @@ -70,7 +50,7 @@ public: private: using ModuleDestLabel = uintptr_t; - ModuleID module_id{}; + struct Trampoline { ptrdiff_t patch_offset; uintptr_t module_offset; @@ -88,25 +68,26 @@ private: private: static constexpr size_t CACHE_SIZE = 16384; // Cache size for patch entries - LRUCache patch_cache{CACHE_SIZE, Settings::values.lru_cache_enabled.GetValue()}; + LRUCache patch_cache{CACHE_SIZE, Settings::values.lru_cache_enabled.GetValue()}; void BranchToPatch(uintptr_t module_dest) { if (patch_cache.isEnabled()) { - PatchCacheKey key{module_id, module_dest}; - LOG_DEBUG(Core_ARM, "LRU cache lookup for module={}, offset={:#x}", fmt::ptr(module_id.data()), module_dest); + LOG_DEBUG(Core_ARM, "LRU cache lookup for address {:#x}", module_dest); // Try to get existing patch entry from cache - if (auto* cached_patch = patch_cache.get(key)) { - LOG_WARNING(Core_ARM, "LRU cache hit for module offset {:#x}", module_dest); + if (auto* cached_patch = patch_cache.get(module_dest)) { + LOG_WARNING(Core_ARM, "LRU cache hit for address {:#x}", module_dest); curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), *cached_patch}); return; } - LOG_DEBUG(Core_ARM, "LRU cache miss for module offset {:#x}, creating new patch", module_dest); - // Not in cache: create and store + LOG_DEBUG(Core_ARM, "LRU cache miss for address {:#x}, creating new patch", module_dest); + + // If not in cache, create new entry and cache it const auto patch_addr = c.offset(); curr_patch->m_branch_to_patch_relocations.push_back({patch_addr, module_dest}); - patch_cache.put(key, patch_addr); + patch_cache.put(module_dest, patch_addr); } else { - LOG_DEBUG(Core_ARM, "LRU cache disabled - direct patch for offset {:#x}", module_dest); + LOG_DEBUG(Core_ARM, "LRU cache disabled - creating direct patch for address {:#x}", module_dest); + // LRU disabled - use pre-LRU approach curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), module_dest}); } } diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 92370f115b..583b7e9270 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -166,8 +166,6 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: const auto& code = codeset.CodeSegment(); auto* patch = patches ? &patches->operator[](patch_index) : nullptr; if (patch && !load_into_process) { - //Set module ID using build_id from the NSO header - patch->SetModuleID(nso_header.build_id); // Patch SVCs and MRS calls in the guest code while (!patch->PatchText(program_image, code)) { patch = &patches->emplace_back();