Skip to content

Commit

Permalink
nn_sl: Stub GetDefaultWhiteListAccessor__Q2_2nn2slFv to avoid crash i…
Browse files Browse the repository at this point in the history
…n Wii U Menu when an online account is used (cemu-project#1159)
  • Loading branch information
Maschell authored Apr 8, 2024
1 parent 74e8d20 commit efbf712
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Cafe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/Cafe/OS/common/OSCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down
115 changes: 115 additions & 0 deletions src/Cafe/OS/libs/nn_sl/nn_sl.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
1 change: 1 addition & 0 deletions src/Cafe/OS/libs/nn_sl/nn_sl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void nnSL_load();
1 change: 1 addition & 0 deletions src/Cemu/Logging/CemuLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum class LogType : sint32
NN_NFP = 13,
NN_FP = 24,
NN_BOSS = 25,
NN_SL = 26,

TextureReadback = 29,

Expand Down

0 comments on commit efbf712

Please sign in to comment.