nn_sl: Stub GetDefaultWhiteListAccessor__Q2_2nn2slFv to avoid crash in Wii U Menu when an online account is used (#1159)

This commit is contained in:
Maschell 2024-04-08 19:15:49 +02:00 committed by GitHub
parent 74e8d205b0
commit efbf712305
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 121 additions and 0 deletions

View File

@ -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

View File

@ -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();

View File

@ -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<void> 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<typename T>
MEMPTR<T> 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<void> 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<void> vTablePtr{}; // 0x00
struct VTable
{
VTableEntry rtti;
VTableEntry dtor;
VTableEntry get;
};
static inline SysAllocator<VTable> s_titleVTable;
static WhiteListAccessor* ctor(WhiteListAccessor* _this)
{
if (!_this)
_this = sl_new<WhiteListAccessor>();
*_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<WhiteListAccessor>(hCPU->gpr[3]), MEMPTR<WhiteList>(hCPU->gpr[4])); osLib_returnFromFunction(hCPU, 0); });
}
};
static_assert(sizeof(WhiteListAccessor) == 0x04);
SysAllocator<WhiteListAccessor> 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);
}

View File

@ -0,0 +1 @@
void nnSL_load();

View File

@ -36,6 +36,7 @@ enum class LogType : sint32
NN_NFP = 13,
NN_FP = 24,
NN_BOSS = 25,
NN_SL = 26,
TextureReadback = 29,