From efbf712305fe59081d90d566e0ec310ae68c969c Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 Apr 2024 19:15:49 +0200 Subject: [PATCH] nn_sl: Stub GetDefaultWhiteListAccessor__Q2_2nn2slFv to avoid crash in Wii U Menu when an online account is used (#1159) --- src/Cafe/CMakeLists.txt | 2 + src/Cafe/OS/common/OSCommon.cpp | 2 + src/Cafe/OS/libs/nn_sl/nn_sl.cpp | 115 +++++++++++++++++++++++++++++++ src/Cafe/OS/libs/nn_sl/nn_sl.h | 1 + src/Cemu/Logging/CemuLogging.h | 1 + 5 files changed, 121 insertions(+) create mode 100644 src/Cafe/OS/libs/nn_sl/nn_sl.cpp create mode 100644 src/Cafe/OS/libs/nn_sl/nn_sl.h diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 20853789..d64a5998 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -404,6 +404,8 @@ add_library(CemuCafe OS/libs/nn_ndm/nn_ndm.h OS/libs/nn_spm/nn_spm.cpp OS/libs/nn_spm/nn_spm.h + OS/libs/nn_sl/nn_sl.cpp + OS/libs/nn_sl/nn_sl.h OS/libs/nn_nfp/AmiiboCrypto.h OS/libs/nn_nfp/nn_nfp.cpp OS/libs/nn_nfp/nn_nfp.h diff --git a/src/Cafe/OS/common/OSCommon.cpp b/src/Cafe/OS/common/OSCommon.cpp index 5aedd197..a4410028 100644 --- a/src/Cafe/OS/common/OSCommon.cpp +++ b/src/Cafe/OS/common/OSCommon.cpp @@ -13,6 +13,7 @@ #include "Cafe/OS/libs/nn_spm/nn_spm.h" #include "Cafe/OS/libs/nn_ec/nn_ec.h" #include "Cafe/OS/libs/nn_boss/nn_boss.h" +#include "Cafe/OS/libs/nn_sl/nn_sl.h" #include "Cafe/OS/libs/nn_fp/nn_fp.h" #include "Cafe/OS/libs/nn_olv/nn_olv.h" #include "Cafe/OS/libs/nn_idbe/nn_idbe.h" @@ -208,6 +209,7 @@ void osLib_load() nn::ndm::load(); nn::spm::load(); nn::save::load(); + nnSL_load(); nsysnet_load(); nn::fp::load(); nn::olv::load(); diff --git a/src/Cafe/OS/libs/nn_sl/nn_sl.cpp b/src/Cafe/OS/libs/nn_sl/nn_sl.cpp new file mode 100644 index 00000000..b25a91bc --- /dev/null +++ b/src/Cafe/OS/libs/nn_sl/nn_sl.cpp @@ -0,0 +1,115 @@ +#include "Cafe/OS/common/OSCommon.h" +#include "Cafe/OS/libs/coreinit/coreinit_IOS.h" +#include "Cafe/OS/libs/coreinit/coreinit_MEM.h" +#include "config/ActiveSettings.h" +#include "Cafe/CafeSystem.h" + +namespace nn +{ + typedef uint32 Result; + namespace sl + { + struct VTableEntry + { + uint16be offsetA{0}; + uint16be offsetB{0}; + MEMPTR ptr; + }; + static_assert(sizeof(VTableEntry) == 8); + + constexpr uint32 SL_MEM_MAGIC = 0xCAFE4321; + +#define DTOR_WRAPPER(__TYPE) RPLLoader_MakePPCCallable([](PPCInterpreter_t* hCPU) { dtor(MEMPTR<__TYPE>(hCPU->gpr[3]), hCPU->gpr[4]); osLib_returnFromFunction(hCPU, 0); }) + + template + MEMPTR sl_new() + { + uint32 objSize = sizeof(T); + uint32be* basePtr = (uint32be*)coreinit::_weak_MEMAllocFromDefaultHeapEx(objSize + 8, 0x8); + basePtr[0] = SL_MEM_MAGIC; + basePtr[1] = objSize; + return (T*)(basePtr + 2); + } + + void sl_delete(MEMPTR mem) + { + if (!mem) + return; + uint32be* basePtr = (uint32be*)mem.GetPtr() - 2; + if (basePtr[0] != SL_MEM_MAGIC) + { + cemuLog_log(LogType::Force, "nn_sl: Detected memory corruption"); + cemu_assert_suspicious(); + } + coreinit::_weak_MEMFreeToDefaultHeap(basePtr); + } + +#pragma pack(1) + struct WhiteList + { + uint32be titleTypes[50]; + uint32be titleTypesCount; + uint32be padding; + uint64be titleIds[50]; + uint32be titleIdCount; + }; + static_assert(sizeof(WhiteList) == 0x264); +#pragma pack() + + struct WhiteListAccessor + { + MEMPTR vTablePtr{}; // 0x00 + + struct VTable + { + VTableEntry rtti; + VTableEntry dtor; + VTableEntry get; + }; + static inline SysAllocator s_titleVTable; + + static WhiteListAccessor* ctor(WhiteListAccessor* _this) + { + if (!_this) + _this = sl_new(); + *_this = {}; + _this->vTablePtr = s_titleVTable; + return _this; + } + + static void dtor(WhiteListAccessor* _this, uint32 options) + { + if (_this && (options & 1)) + sl_delete(_this); + } + + static void Get(WhiteListAccessor* _this, nn::sl::WhiteList* outWhiteList) + { + *outWhiteList = {}; + } + + static void InitVTable() + { + s_titleVTable->rtti.ptr = nullptr; // todo + s_titleVTable->dtor.ptr = DTOR_WRAPPER(WhiteListAccessor); + s_titleVTable->get.ptr = RPLLoader_MakePPCCallable([](PPCInterpreter_t* hCPU) { Get(MEMPTR(hCPU->gpr[3]), MEMPTR(hCPU->gpr[4])); osLib_returnFromFunction(hCPU, 0); }); + } + }; + static_assert(sizeof(WhiteListAccessor) == 0x04); + + SysAllocator s_defaultWhiteListAccessor; + + WhiteListAccessor* GetDefaultWhiteListAccessor() + { + return s_defaultWhiteListAccessor; + } + } // namespace sl +} // namespace nn + +void nnSL_load() +{ + nn::sl::WhiteListAccessor::InitVTable(); + nn::sl::WhiteListAccessor::ctor(nn::sl::s_defaultWhiteListAccessor); + + cafeExportRegisterFunc(nn::sl::GetDefaultWhiteListAccessor, "nn_sl", "GetDefaultWhiteListAccessor__Q2_2nn2slFv", LogType::NN_SL); +} diff --git a/src/Cafe/OS/libs/nn_sl/nn_sl.h b/src/Cafe/OS/libs/nn_sl/nn_sl.h new file mode 100644 index 00000000..08d936cb --- /dev/null +++ b/src/Cafe/OS/libs/nn_sl/nn_sl.h @@ -0,0 +1 @@ +void nnSL_load(); \ No newline at end of file diff --git a/src/Cemu/Logging/CemuLogging.h b/src/Cemu/Logging/CemuLogging.h index fe74a6bc..e789c2ea 100644 --- a/src/Cemu/Logging/CemuLogging.h +++ b/src/Cemu/Logging/CemuLogging.h @@ -36,6 +36,7 @@ enum class LogType : sint32 NN_NFP = 13, NN_FP = 24, NN_BOSS = 25, + NN_SL = 26, TextureReadback = 29,