mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-25 10:36:55 +01:00
coreinit: Handle non-existing modules in OSDynLoad_Acquire
Fixes Togabito crashing on boot coreinit: Handle non-existing modules in OSDynLoad_Acquire
This commit is contained in:
parent
c168cf536a
commit
f04c7575d7
@ -165,7 +165,7 @@ void LoadMainExecutable()
|
|||||||
{
|
{
|
||||||
// RPX
|
// RPX
|
||||||
RPLLoader_AddDependency(_pathToExecutable.c_str());
|
RPLLoader_AddDependency(_pathToExecutable.c_str());
|
||||||
applicationRPX = rpl_loadFromMem(rpxData, rpxSize, (char*)_pathToExecutable.c_str());
|
applicationRPX = RPLLoader_LoadFromMemory(rpxData, rpxSize, (char*)_pathToExecutable.c_str());
|
||||||
if (!applicationRPX)
|
if (!applicationRPX)
|
||||||
{
|
{
|
||||||
wxMessageBox(_("Failed to run this title because the executable is damaged"));
|
wxMessageBox(_("Failed to run this title because the executable is damaged"));
|
||||||
|
@ -325,6 +325,8 @@ void PPCRecompiler_thread()
|
|||||||
PPCRecompilerState.recompilerSpinlock.unlock();
|
PPCRecompilerState.recompilerSpinlock.unlock();
|
||||||
|
|
||||||
PPCRecompiler_recompileAtAddress(enterAddress);
|
PPCRecompiler_recompileAtAddress(enterAddress);
|
||||||
|
if(s_recompilerThreadStopSignal)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,20 +39,22 @@ VHeap rplLoaderHeap_workarea(nullptr, MEMORY_RPLLOADER_AREA_SIZE);
|
|||||||
PPCCodeHeap rplLoaderHeap_lowerAreaCodeMem2(nullptr, MEMORY_CODE_TRAMPOLINE_AREA_SIZE);
|
PPCCodeHeap rplLoaderHeap_lowerAreaCodeMem2(nullptr, MEMORY_CODE_TRAMPOLINE_AREA_SIZE);
|
||||||
PPCCodeHeap rplLoaderHeap_codeArea2(nullptr, MEMORY_CODEAREA_SIZE);
|
PPCCodeHeap rplLoaderHeap_codeArea2(nullptr, MEMORY_CODEAREA_SIZE);
|
||||||
|
|
||||||
bool rplLoader_applicationHasMemoryControl = false;
|
|
||||||
uint32 rplLoader_maxCodeAddress = 0; // highest used code address
|
|
||||||
|
|
||||||
ChunkedFlatAllocator<64 * 1024> g_heapTrampolineArea;
|
ChunkedFlatAllocator<64 * 1024> g_heapTrampolineArea;
|
||||||
|
|
||||||
std::vector<rplDependency_t*> rplDependencyList = std::vector<rplDependency_t*>();
|
std::vector<RPLDependency*> rplDependencyList;
|
||||||
|
|
||||||
RPLModule* rplModuleList[256];
|
RPLModule* rplModuleList[256];
|
||||||
sint32 rplModuleCount = 0;
|
sint32 rplModuleCount = 0;
|
||||||
|
|
||||||
uint32 _currentTLSModuleIndex = 1; // value 0 is reserved
|
bool rplLoader_applicationHasMemoryControl = false;
|
||||||
|
uint32 rplLoader_maxCodeAddress = 0; // highest used code address
|
||||||
|
uint32 rplLoader_currentTLSModuleIndex = 1; // value 0 is reserved
|
||||||
|
uint32 rplLoader_currentHandleCounter = 0x00001000;
|
||||||
|
sint16 rplLoader_currentTlsModuleIndex = 0x0001;
|
||||||
|
RPLModule* rplLoader_mainModule = nullptr;
|
||||||
uint32 rplLoader_sdataAddr = MPTR_NULL; // r13
|
uint32 rplLoader_sdataAddr = MPTR_NULL; // r13
|
||||||
uint32 rplLoader_sdata2Addr = MPTR_NULL; // r2
|
uint32 rplLoader_sdata2Addr = MPTR_NULL; // r2
|
||||||
|
uint32 rplLoader_currentDataAllocatorAddr = 0x10000000;
|
||||||
|
|
||||||
std::map<void(*)(PPCInterpreter_t* hCPU), uint32> g_map_callableExports;
|
std::map<void(*)(PPCInterpreter_t* hCPU), uint32> g_map_callableExports;
|
||||||
|
|
||||||
@ -110,8 +112,6 @@ MPTR RPLLoader_AllocateCodeSpace(uint32 size, uint32 alignment)
|
|||||||
return codeAddr;
|
return codeAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 rpl3_currentDataAllocatorAddr = 0x10000000;
|
|
||||||
|
|
||||||
uint32 RPLLoader_AllocateDataSpace(RPLModule* rpl, uint32 size, uint32 alignment)
|
uint32 RPLLoader_AllocateDataSpace(RPLModule* rpl, uint32 size, uint32 alignment)
|
||||||
{
|
{
|
||||||
if (rplLoader_applicationHasMemoryControl)
|
if (rplLoader_applicationHasMemoryControl)
|
||||||
@ -121,9 +121,9 @@ uint32 RPLLoader_AllocateDataSpace(RPLModule* rpl, uint32 size, uint32 alignment
|
|||||||
PPCCoreCallback(rpl->funcAlloc.value(), size, alignment, memPtr.GetPointer());
|
PPCCoreCallback(rpl->funcAlloc.value(), size, alignment, memPtr.GetPointer());
|
||||||
return (uint32)*(memPtr.GetPointer());
|
return (uint32)*(memPtr.GetPointer());
|
||||||
}
|
}
|
||||||
rpl3_currentDataAllocatorAddr = (rpl3_currentDataAllocatorAddr + alignment - 1)&~(alignment-1);
|
rplLoader_currentDataAllocatorAddr = (rplLoader_currentDataAllocatorAddr + alignment - 1) & ~(alignment - 1);
|
||||||
uint32 mem = rpl3_currentDataAllocatorAddr;
|
uint32 mem = rplLoader_currentDataAllocatorAddr;
|
||||||
rpl3_currentDataAllocatorAddr += size;
|
rplLoader_currentDataAllocatorAddr += size;
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ void RPLLoader_FreeData(RPLModule* rpl, void* ptr)
|
|||||||
|
|
||||||
uint32 RPLLoader_GetDataAllocatorAddr()
|
uint32 RPLLoader_GetDataAllocatorAddr()
|
||||||
{
|
{
|
||||||
return (rpl3_currentDataAllocatorAddr + 0xFFF)&(~0xFFF);
|
return (rplLoader_currentDataAllocatorAddr + 0xFFF) & (~0xFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 RPLLoader_GetMaxCodeOffset()
|
uint32 RPLLoader_GetMaxCodeOffset()
|
||||||
@ -1385,12 +1385,11 @@ bool RPLLoader_HandleRelocs(RPLModule* rplLoaderContext, std::span<RPLSharedImpo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _RPLLoader_ExtractModuleNameFromPath(char* output, const char* input)
|
void _RPLLoader_ExtractModuleNameFromPath(char* output, std::string_view input)
|
||||||
{
|
{
|
||||||
// scan to last '/'
|
// scan to last '/'
|
||||||
sint32 inputLen = (sint32)strlen(input);
|
cemu_assert(!input.empty());
|
||||||
cemu_assert(inputLen > 0);
|
size_t startIndex = input.size() - 1;
|
||||||
sint32 startIndex = inputLen - 1;
|
|
||||||
while (startIndex > 0)
|
while (startIndex > 0)
|
||||||
{
|
{
|
||||||
if (input[startIndex] == '/')
|
if (input[startIndex] == '/')
|
||||||
@ -1401,23 +1400,20 @@ void _RPLLoader_ExtractModuleNameFromPath(char* output, const char* input)
|
|||||||
startIndex--;
|
startIndex--;
|
||||||
}
|
}
|
||||||
// cut off after '.'
|
// cut off after '.'
|
||||||
sint32 endIndex = startIndex;
|
size_t endIndex = startIndex;
|
||||||
while (endIndex <= inputLen)
|
while (endIndex < input.size())
|
||||||
{
|
{
|
||||||
if (input[endIndex] == '.')
|
if (input[endIndex] == '.')
|
||||||
break;
|
break;
|
||||||
endIndex++;
|
endIndex++;
|
||||||
}
|
}
|
||||||
sint32 nameLen = endIndex - startIndex;
|
size_t nameLen = endIndex - startIndex;
|
||||||
cemu_assert(nameLen != 0);
|
cemu_assert(nameLen != 0);
|
||||||
nameLen = std::min(nameLen, RPL_MODULE_NAME_LENGTH-1);
|
nameLen = std::min<size_t>(nameLen, RPL_MODULE_NAME_LENGTH-1);
|
||||||
memcpy(output, input + startIndex, nameLen);
|
memcpy(output, input.data() + startIndex, nameLen);
|
||||||
output[nameLen] = '\0';
|
output[nameLen] = '\0';
|
||||||
// convert to lower case
|
// convert to lower case
|
||||||
for (sint32 i = 0; i < nameLen; i++)
|
std::for_each(output, output + nameLen, [](char& c) {c = _ansiToLower(c);});
|
||||||
{
|
|
||||||
output[i] = _ansiToLower(output[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPLLoader_InitState()
|
void RPLLoader_InitState()
|
||||||
@ -1432,27 +1428,6 @@ void RPLLoader_InitState()
|
|||||||
RPLLoader_ResetState();
|
RPLLoader_ResetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPLLoader_ResetState()
|
|
||||||
{
|
|
||||||
// unload all RPL modules
|
|
||||||
while (rplModuleCount > 0)
|
|
||||||
RPLLoader_UnloadModule(rplModuleList[0]);
|
|
||||||
rplDependencyList.clear();
|
|
||||||
// unload all remaining symbols
|
|
||||||
rplSymbolStorage_unloadAll();
|
|
||||||
// free all code imports
|
|
||||||
g_heapTrampolineArea.releaseAll();
|
|
||||||
list_mappedFunctionImports.clear();
|
|
||||||
g_map_callableExports.clear();
|
|
||||||
|
|
||||||
rplLoader_applicationHasMemoryControl = false;
|
|
||||||
rplLoader_maxCodeAddress = 0;
|
|
||||||
rpl3_currentDataAllocatorAddr = 0x10000000;
|
|
||||||
_currentTLSModuleIndex = 1;
|
|
||||||
rplLoader_sdataAddr = MPTR_NULL;
|
|
||||||
rplLoader_sdata2Addr = MPTR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RPLLoader_BeginCemuhookCRC(RPLModule* rpl)
|
void RPLLoader_BeginCemuhookCRC(RPLModule* rpl)
|
||||||
{
|
{
|
||||||
// calculate some values required for CRC
|
// calculate some values required for CRC
|
||||||
@ -1610,7 +1585,7 @@ void RPLLoader_InitModuleAllocator(RPLModule* rpl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map rpl into memory, but do not resolve relocs and imports yet
|
// map rpl into memory, but do not resolve relocs and imports yet
|
||||||
RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name)
|
RPLModule* RPLLoader_LoadFromMemory(uint8* rplData, sint32 size, char* name)
|
||||||
{
|
{
|
||||||
char moduleName[RPL_MODULE_NAME_LENGTH];
|
char moduleName[RPL_MODULE_NAME_LENGTH];
|
||||||
_RPLLoader_ExtractModuleNameFromPath(moduleName, name);
|
_RPLLoader_ExtractModuleNameFromPath(moduleName, name);
|
||||||
@ -1699,7 +1674,7 @@ RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name)
|
|||||||
return rpl;
|
return rpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPLLoader_flushMemory(RPLModule* rpl)
|
void RPLLoader_FlushMemory(RPLModule* rpl)
|
||||||
{
|
{
|
||||||
// invalidate recompiler cache
|
// invalidate recompiler cache
|
||||||
PPCRecompiler_invalidateRange(rpl->regionMappingBase_text.GetMPTR(), rpl->regionMappingBase_text.GetMPTR() + rpl->regionSize_text);
|
PPCRecompiler_invalidateRange(rpl->regionMappingBase_text.GetMPTR(), rpl->regionMappingBase_text.GetMPTR() + rpl->regionSize_text);
|
||||||
@ -1755,7 +1730,7 @@ void RPLLoader_LinkSingleModule(RPLModule* rplLoaderContext, bool resolveOnlyExp
|
|||||||
else
|
else
|
||||||
RPLLoader_HandleRelocs(rplLoaderContext, sharedImportTracking, 0);
|
RPLLoader_HandleRelocs(rplLoaderContext, sharedImportTracking, 0);
|
||||||
|
|
||||||
RPLLoader_flushMemory(rplLoaderContext);
|
RPLLoader_FlushMemory(rplLoaderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPLLoader_LoadSectionDebugSymbols(RPLModule* rplLoaderContext, rplSectionEntryNew_t* section, int symtabSectionIndex)
|
void RPLLoader_LoadSectionDebugSymbols(RPLModule* rplLoaderContext, rplSectionEntryNew_t* section, int symtabSectionIndex)
|
||||||
@ -1919,8 +1894,24 @@ uint32 RPLLoader_GetModuleEntrypoint(RPLModule* rplLoaderContext)
|
|||||||
return rplLoaderContext->entrypoint;
|
return rplLoaderContext->entrypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 rplLoader_currentHandleCounter = 0x00001000;
|
// takes a module name without extension, returns true if the RPL module is a known Cafe OS module
|
||||||
sint16 rplLoader_currentTlsModuleIndex = 0x0001;
|
bool RPLLoader_IsKnownCafeOSModule(std::string_view name)
|
||||||
|
{
|
||||||
|
static std::unordered_set<std::string> s_systemModules556 = {
|
||||||
|
"avm","camera","coreinit","dc","dmae","drmapp","erreula",
|
||||||
|
"gx2","h264","lzma920","mic","nfc","nio_prof","nlibcurl",
|
||||||
|
"nlibnss","nlibnss2","nn_ac","nn_acp","nn_act","nn_aoc","nn_boss",
|
||||||
|
"nn_ccr","nn_cmpt","nn_dlp","nn_ec","nn_fp","nn_hai","nn_hpad",
|
||||||
|
"nn_idbe","nn_ndm","nn_nets2","nn_nfp","nn_nim","nn_olv","nn_pdm",
|
||||||
|
"nn_save","nn_sl","nn_spm","nn_temp","nn_uds","nn_vctl","nsysccr",
|
||||||
|
"nsyshid","nsyskbd","nsysnet","nsysuhs","nsysuvd","ntag","padscore",
|
||||||
|
"proc_ui","sndcore2","snduser2","snd_core","snd_user","swkbd","sysapp",
|
||||||
|
"tcl","tve","uac","uac_rpl","usb_mic","uvc","uvd","vpad","vpadbase",
|
||||||
|
"zlib125"};
|
||||||
|
std::string nameLower{name};
|
||||||
|
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), _ansiToLower);
|
||||||
|
return s_systemModules556.contains(nameLower);
|
||||||
|
}
|
||||||
|
|
||||||
// increment reference counter for module
|
// increment reference counter for module
|
||||||
void RPLLoader_AddDependency(const char* name)
|
void RPLLoader_AddDependency(const char* name)
|
||||||
@ -1946,18 +1937,18 @@ void RPLLoader_AddDependency(const char* name)
|
|||||||
{
|
{
|
||||||
if (strcmp(moduleName, dep->modulename) == 0)
|
if (strcmp(moduleName, dep->modulename) == 0)
|
||||||
{
|
{
|
||||||
// entry already exists, increment reference counter
|
|
||||||
dep->referenceCount++;
|
dep->referenceCount++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add new entry
|
// add new entry
|
||||||
rplDependency_t* newDependency = new rplDependency_t();
|
RPLDependency* newDependency = new RPLDependency();
|
||||||
strcpy(newDependency->modulename, moduleName);
|
strcpy(newDependency->modulename, moduleName);
|
||||||
newDependency->referenceCount = 1;
|
newDependency->referenceCount = 1;
|
||||||
newDependency->coreinitHandle = rplLoader_currentHandleCounter;
|
newDependency->coreinitHandle = rplLoader_currentHandleCounter;
|
||||||
newDependency->tlsModuleIndex = rplLoader_currentTlsModuleIndex;
|
newDependency->tlsModuleIndex = rplLoader_currentTlsModuleIndex;
|
||||||
rplLoader_currentTlsModuleIndex++;
|
newDependency->isCafeOSModule = RPLLoader_IsKnownCafeOSModule(moduleName);
|
||||||
|
rplLoader_currentTlsModuleIndex++; // todo - delay handle and tls allocation until the module is actually loaded. It may not exist
|
||||||
rplLoader_currentHandleCounter++;
|
rplLoader_currentHandleCounter++;
|
||||||
if (rplLoader_currentTlsModuleIndex == 0x7FFF)
|
if (rplLoader_currentTlsModuleIndex == 0x7FFF)
|
||||||
cemuLog_log(LogType::Force, "RPLLoader: Exhausted TLS module indices pool");
|
cemuLog_log(LogType::Force, "RPLLoader: Exhausted TLS module indices pool");
|
||||||
@ -2005,6 +1996,18 @@ void RPLLoader_RemoveDependency(const char* name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RPLLoader_HasDependency(std::string_view name)
|
||||||
|
{
|
||||||
|
char moduleName[RPL_MODULE_NAME_LENGTH];
|
||||||
|
_RPLLoader_ExtractModuleNameFromPath(moduleName, name);
|
||||||
|
for (const auto& dep : rplDependencyList)
|
||||||
|
{
|
||||||
|
if (strcmp(moduleName, dep->modulename) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// decrement reference counter for dependency by module handle
|
// decrement reference counter for dependency by module handle
|
||||||
void RPLLoader_RemoveDependency(uint32 handle)
|
void RPLLoader_RemoveDependency(uint32 handle)
|
||||||
{
|
{
|
||||||
@ -2030,6 +2033,9 @@ uint32 RPLLoader_GetHandleByModuleName(const char* name)
|
|||||||
{
|
{
|
||||||
if (strcmp(moduleName, dep->modulename) == 0)
|
if (strcmp(moduleName, dep->modulename) == 0)
|
||||||
{
|
{
|
||||||
|
cemu_assert_debug(dep->loadAttempted);
|
||||||
|
if (!dep->isCafeOSModule && !dep->rplLoaderContext)
|
||||||
|
return RPL_INVALID_HANDLE; // module not found
|
||||||
return dep->coreinitHandle;
|
return dep->coreinitHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2062,21 +2068,21 @@ bool RPLLoader_GetTLSDataByTLSIndex(sint16 tlsModuleIndex, uint8** tlsData, sint
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RPLLoader_LoadFromVirtualPath(rplDependency_t* dependency, char* filePath)
|
bool RPLLoader_LoadFromVirtualPath(RPLDependency* dependency, char* filePath)
|
||||||
{
|
{
|
||||||
uint32 rplSize = 0;
|
uint32 rplSize = 0;
|
||||||
uint8* rplData = fsc_extractFile(filePath, &rplSize);
|
uint8* rplData = fsc_extractFile(filePath, &rplSize);
|
||||||
if (rplData)
|
if (rplData)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "Loading: {}", filePath);
|
cemuLog_logDebug(LogType::Force, "Loading: {}", filePath);
|
||||||
dependency->rplLoaderContext = rpl_loadFromMem(rplData, rplSize, filePath);
|
dependency->rplLoaderContext = RPLLoader_LoadFromMemory(rplData, rplSize, filePath);
|
||||||
free(rplData);
|
free(rplData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPLLoader_LoadDependency(rplDependency_t* dependency)
|
void RPLLoader_LoadDependency(RPLDependency* dependency)
|
||||||
{
|
{
|
||||||
dependency->loadAttempted = true;
|
dependency->loadAttempted = true;
|
||||||
// check if module is already loaded
|
// check if module is already loaded
|
||||||
@ -2084,11 +2090,9 @@ void RPLLoader_LoadDependency(rplDependency_t* dependency)
|
|||||||
{
|
{
|
||||||
if(!boost::iequals(rplModuleList[i]->moduleName2, dependency->modulename))
|
if(!boost::iequals(rplModuleList[i]->moduleName2, dependency->modulename))
|
||||||
continue;
|
continue;
|
||||||
// already loaded
|
|
||||||
dependency->rplLoaderContext = rplModuleList[i];
|
dependency->rplLoaderContext = rplModuleList[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// attempt to load rpl from various locations
|
|
||||||
char filePath[RPL_MODULE_PATH_LENGTH];
|
char filePath[RPL_MODULE_PATH_LENGTH];
|
||||||
// check if path is absolute
|
// check if path is absolute
|
||||||
if (dependency->filepath[0] == '/')
|
if (dependency->filepath[0] == '/')
|
||||||
@ -2097,7 +2101,7 @@ void RPLLoader_LoadDependency(rplDependency_t* dependency)
|
|||||||
RPLLoader_LoadFromVirtualPath(dependency, filePath);
|
RPLLoader_LoadFromVirtualPath(dependency, filePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// attempt to load rpl from internal folder
|
// attempt to load rpl from code directory of current title
|
||||||
strcpy_s(filePath, "/internal/current_title/code/");
|
strcpy_s(filePath, "/internal/current_title/code/");
|
||||||
strcat_s(filePath, dependency->filepath);
|
strcat_s(filePath, dependency->filepath);
|
||||||
// except if it is blacklisted
|
// except if it is blacklisted
|
||||||
@ -2119,7 +2123,8 @@ void RPLLoader_LoadDependency(rplDependency_t* dependency)
|
|||||||
if (fileData)
|
if (fileData)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Loading RPL: /cafeLibs/{}", dependency->filepath);
|
cemuLog_log(LogType::Force, "Loading RPL: /cafeLibs/{}", dependency->filepath);
|
||||||
dependency->rplLoaderContext = rpl_loadFromMem(fileData->data(), fileData->size(), dependency->filepath);
|
dependency->rplLoaderContext = RPLLoader_LoadFromMemory(fileData->data(), fileData->size(),
|
||||||
|
dependency->filepath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2168,8 +2173,6 @@ void RPLLoader_UpdateDependencies()
|
|||||||
RPLLoader_Link();
|
RPLLoader_Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
RPLModule* rplLoader_mainModule = nullptr;
|
|
||||||
|
|
||||||
void RPLLoader_SetMainModule(RPLModule* rplLoaderContext)
|
void RPLLoader_SetMainModule(RPLModule* rplLoaderContext)
|
||||||
{
|
{
|
||||||
rplLoaderContext->entrypointCalled = true;
|
rplLoaderContext->entrypointCalled = true;
|
||||||
@ -2250,7 +2253,7 @@ uint32 RPLLoader_FindModuleOrHLEExport(uint32 moduleHandle, bool isData, const c
|
|||||||
{
|
{
|
||||||
// find dependency from handle
|
// find dependency from handle
|
||||||
RPLModule* rplLoaderContext = nullptr;
|
RPLModule* rplLoaderContext = nullptr;
|
||||||
rplDependency_t* dependency = nullptr;
|
RPLDependency* dependency = nullptr;
|
||||||
for (auto& dep : rplDependencyList)
|
for (auto& dep : rplDependencyList)
|
||||||
{
|
{
|
||||||
if (dep->coreinitHandle == moduleHandle)
|
if (dep->coreinitHandle == moduleHandle)
|
||||||
@ -2379,3 +2382,24 @@ void RPLLoader_ReleaseCodeCaveMem(MEMPTR<void> addr)
|
|||||||
{
|
{
|
||||||
heapCodeCaveArea.free(addr.GetMPTR());
|
heapCodeCaveArea.free(addr.GetMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RPLLoader_ResetState()
|
||||||
|
{
|
||||||
|
// unload all RPL modules
|
||||||
|
while (rplModuleCount > 0)
|
||||||
|
RPLLoader_UnloadModule(rplModuleList[0]);
|
||||||
|
rplDependencyList.clear();
|
||||||
|
// unload all remaining symbols
|
||||||
|
rplSymbolStorage_unloadAll();
|
||||||
|
// free all code imports
|
||||||
|
g_heapTrampolineArea.releaseAll();
|
||||||
|
list_mappedFunctionImports.clear();
|
||||||
|
g_map_callableExports.clear();
|
||||||
|
rplLoader_applicationHasMemoryControl = false;
|
||||||
|
rplLoader_maxCodeAddress = 0;
|
||||||
|
rplLoader_currentDataAllocatorAddr = 0x10000000;
|
||||||
|
rplLoader_currentTLSModuleIndex = 1;
|
||||||
|
rplLoader_sdataAddr = MPTR_NULL;
|
||||||
|
rplLoader_sdata2Addr = MPTR_NULL;
|
||||||
|
rplLoader_mainModule = nullptr;
|
||||||
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
struct RPLModule;
|
struct RPLModule;
|
||||||
|
|
||||||
#define RPL_INVALID_HANDLE (0xFFFFFFFF)
|
#define RPL_INVALID_HANDLE 0xFFFFFFFF
|
||||||
|
|
||||||
void RPLLoader_InitState();
|
void RPLLoader_InitState();
|
||||||
void RPLLoader_ResetState();
|
void RPLLoader_ResetState();
|
||||||
@ -14,7 +14,7 @@ MPTR RPLLoader_AllocateCodeSpace(uint32 size, uint32 alignment);
|
|||||||
uint32 RPLLoader_GetMaxCodeOffset();
|
uint32 RPLLoader_GetMaxCodeOffset();
|
||||||
uint32 RPLLoader_GetDataAllocatorAddr();
|
uint32 RPLLoader_GetDataAllocatorAddr();
|
||||||
|
|
||||||
RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name);
|
RPLModule* RPLLoader_LoadFromMemory(uint8* rplData, sint32 size, char* name);
|
||||||
uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const char* funcName, bool functionMustExist);
|
uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const char* funcName, bool functionMustExist);
|
||||||
void RPLLoader_Link();
|
void RPLLoader_Link();
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ void RPLLoader_NotifyControlPassedToApplication();
|
|||||||
|
|
||||||
void RPLLoader_AddDependency(const char* name);
|
void RPLLoader_AddDependency(const char* name);
|
||||||
void RPLLoader_RemoveDependency(uint32 handle);
|
void RPLLoader_RemoveDependency(uint32 handle);
|
||||||
|
bool RPLLoader_HasDependency(std::string_view name);
|
||||||
void RPLLoader_UpdateDependencies();
|
void RPLLoader_UpdateDependencies();
|
||||||
|
|
||||||
uint32 RPLLoader_GetHandleByModuleName(const char* name);
|
uint32 RPLLoader_GetHandleByModuleName(const char* name);
|
||||||
|
@ -225,17 +225,17 @@ struct RPLModule
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
struct RPLDependency
|
||||||
{
|
{
|
||||||
char modulename[RPL_MODULE_NAME_LENGTH];
|
char modulename[RPL_MODULE_NAME_LENGTH];
|
||||||
char filepath[RPL_MODULE_PATH_LENGTH];
|
char filepath[RPL_MODULE_PATH_LENGTH];
|
||||||
bool loadAttempted;
|
bool loadAttempted;
|
||||||
//bool isHLEModule; // determined to be a HLE module
|
bool isCafeOSModule; // name is a known Cafe OS RPL
|
||||||
RPLModule* rplLoaderContext; // context of loaded module
|
RPLModule* rplLoaderContext; // context of loaded module, can be nullptr for HLE COS modules
|
||||||
sint32 referenceCount;
|
sint32 referenceCount;
|
||||||
uint32 coreinitHandle; // fake handle for coreinit
|
uint32 coreinitHandle; // fake handle for coreinit
|
||||||
sint16 tlsModuleIndex; // tls module index assigned to this dependency
|
sint16 tlsModuleIndex; // tls module index assigned to this dependency
|
||||||
}rplDependency_t;
|
};
|
||||||
|
|
||||||
RPLModule* RPLLoader_FindModuleByCodeAddr(uint32 addr);
|
RPLModule* RPLLoader_FindModuleByCodeAddr(uint32 addr);
|
||||||
RPLModule* RPLLoader_FindModuleByDataAddr(uint32 addr);
|
RPLModule* RPLLoader_FindModuleByDataAddr(uint32 addr);
|
||||||
|
@ -86,8 +86,7 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
// search for loaded modules with matching name
|
// search for loaded modules with matching name
|
||||||
uint32 rplHandle = RPLLoader_GetHandleByModuleName(libName);
|
uint32 rplHandle = RPLLoader_GetHandleByModuleName(libName);
|
||||||
|
if (rplHandle == RPL_INVALID_HANDLE && !RPLLoader_HasDependency(libName))
|
||||||
if (rplHandle == RPL_INVALID_HANDLE)
|
|
||||||
{
|
{
|
||||||
RPLLoader_AddDependency(libName);
|
RPLLoader_AddDependency(libName);
|
||||||
RPLLoader_UpdateDependencies();
|
RPLLoader_UpdateDependencies();
|
||||||
@ -100,7 +99,10 @@ namespace coreinit
|
|||||||
else
|
else
|
||||||
*moduleHandleOut = rplHandle;
|
*moduleHandleOut = rplHandle;
|
||||||
if (rplHandle == RPL_INVALID_HANDLE)
|
if (rplHandle == RPL_INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
cemuLog_logDebug(LogType::Force, "OSDynLoad_Acquire() failed to load module '{}'", libName);
|
||||||
return 0xFFFCFFE9; // module not found
|
return 0xFFFCFFE9; // module not found
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,6 @@ void swkbdExport_SwkbdDisappearKeyboard(PPCInterpreter_t* hCPU)
|
|||||||
|
|
||||||
void swkbdExport_SwkbdGetInputFormString(PPCInterpreter_t* hCPU)
|
void swkbdExport_SwkbdGetInputFormString(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
debug_printf("SwkbdGetInputFormString__3RplFv LR: %08x\n", hCPU->spr.LR);
|
|
||||||
for(sint32 i=0; i<swkbdInternalState->formStringLength; i++)
|
for(sint32 i=0; i<swkbdInternalState->formStringLength; i++)
|
||||||
{
|
{
|
||||||
swkbdInternalState->formStringBufferBE[i] = _swapEndianU16(swkbdInternalState->formStringBuffer[i]);
|
swkbdInternalState->formStringBufferBE[i] = _swapEndianU16(swkbdInternalState->formStringBuffer[i]);
|
||||||
@ -287,7 +286,6 @@ void swkbdExport_SwkbdGetInputFormString(PPCInterpreter_t* hCPU)
|
|||||||
|
|
||||||
void swkbdExport_SwkbdIsDecideOkButton(PPCInterpreter_t* hCPU)
|
void swkbdExport_SwkbdIsDecideOkButton(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
debug_printf("SwkbdIsDecideOkButton__3RplFPb LR: %08x\n", hCPU->spr.LR);
|
|
||||||
if (swkbdInternalState->decideButtonWasPressed)
|
if (swkbdInternalState->decideButtonWasPressed)
|
||||||
osLib_returnFromFunction(hCPU, 1);
|
osLib_returnFromFunction(hCPU, 1);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user