mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-08-20 00:55:05 -05:00
coreinit_Dynload: Implement notify callbacks
Implements the following coreinit functions: - OSDynLoad_AddNotifyCallback - OSDynLoad_DelNotifyCallback
This commit is contained in:
@@ -2400,6 +2400,20 @@ RPLModule** RPLLoader_GetModuleList()
|
||||
return rplModuleList;
|
||||
}
|
||||
|
||||
RPLModule* RPLLoader_GetModuleByName(std::string_view name)
|
||||
{
|
||||
std::string normalizedName = _RPLLoader_ExtractModuleNameFromPath(name);
|
||||
RPLModule** modules = RPLLoader_GetModuleList();
|
||||
|
||||
for (uint32 i = 0; i < RPLLoader_GetModuleCount(); i++)
|
||||
{
|
||||
if (modules[i]->moduleName == normalizedName)
|
||||
return modules[i];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sint32 RPLLoader_GetModuleCount()
|
||||
{
|
||||
return rplModuleCount;
|
||||
|
||||
@@ -47,6 +47,7 @@ uint32 RPLLoader_GetSDA2Base();
|
||||
|
||||
sint32 RPLLoader_GetModuleCount();
|
||||
RPLModule** RPLLoader_GetModuleList();
|
||||
RPLModule* RPLLoader_GetModuleByName(std::string_view name);
|
||||
|
||||
MEMPTR<void> RPLLoader_AllocateCodeCaveMem(uint32 alignment, uint32 size);
|
||||
void RPLLoader_ReleaseCodeCaveMem(MEMPTR<void> addr);
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace coreinit
|
||||
MPTR _osDynLoadTLSFuncAlloc = MPTR_NULL;
|
||||
MPTR _osDynLoadTLSFuncFree = MPTR_NULL;
|
||||
|
||||
static std::vector<NotifyCallbackEntry> notifyCallbacks;
|
||||
|
||||
uint32 OSDynLoad_SetAllocator(MPTR allocFunc, MPTR freeFunc)
|
||||
{
|
||||
_osDynLoadFuncAlloc = allocFunc;
|
||||
@@ -109,6 +111,34 @@ namespace coreinit
|
||||
cemuLog_logDebug(LogType::Force, "OSDynLoad_Acquire() failed to load module '{}'", libName);
|
||||
return 0xFFFCFFE9; // module not found
|
||||
}
|
||||
|
||||
for (const auto& cb : notifyCallbacks)
|
||||
{
|
||||
MEMPTR<OSDynLoad_NotifyData> notifyData;
|
||||
notifyData = (OSDynLoad_NotifyData*)OSDynLoad_AllocatorAlloc(sizeof(OSDynLoad_NotifyData), 4);
|
||||
RPLModule* module = RPLLoader_GetModuleByName(tempLibName);
|
||||
|
||||
if (!module)
|
||||
break;
|
||||
|
||||
notifyData->name = module->ppcName.GetMPTR();
|
||||
|
||||
notifyData->textAddr = module->regionMappingBase_text.GetBEValue();
|
||||
notifyData->textOffset = module->regionMappingBase_text.GetMPTR() - module->regionOrigAddr_text;
|
||||
notifyData->textSize = module->regionSize_text;
|
||||
|
||||
notifyData->dataAddr = module->regionMappingBase_data;
|
||||
notifyData->dataOffset = module->regionMappingBase_data - module->regionOrigAddr_data;
|
||||
notifyData->dataSize = module->regionSize_data;
|
||||
|
||||
notifyData->readAddr = module->regionMappingBase_data;
|
||||
notifyData->readOffset = module->regionMappingBase_data - module->regionOrigAddr_data;
|
||||
notifyData->readSize = module->regionSize_data;
|
||||
|
||||
PPCCoreCallback(cb.callback, moduleHandleOut, cb.userContext.GetMPTR(), 1, notifyData.GetMPTR());
|
||||
OSDynLoad_AllocatorFree(notifyData);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -121,6 +151,35 @@ namespace coreinit
|
||||
{
|
||||
if (moduleHandle == RPL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
for (const auto& cb : notifyCallbacks)
|
||||
{
|
||||
MEMPTR<OSDynLoad_NotifyData> notifyData;
|
||||
notifyData = (OSDynLoad_NotifyData*)OSDynLoad_AllocatorAlloc(sizeof(OSDynLoad_NotifyData), 4);
|
||||
RPLModule* module = RPLLoader_GetModuleByName(RPLLoader_GetModuleNameByHandle(moduleHandle));
|
||||
|
||||
if (!module)
|
||||
break;
|
||||
|
||||
notifyData->name = module->ppcName.GetMPTR();
|
||||
|
||||
notifyData->textAddr = module->regionMappingBase_text.GetBEValue();
|
||||
notifyData->textOffset = module->regionMappingBase_text.GetMPTR() - module->regionOrigAddr_text;
|
||||
notifyData->textSize = module->regionSize_text;
|
||||
|
||||
notifyData->dataAddr = module->regionMappingBase_data;
|
||||
notifyData->dataOffset = module->regionMappingBase_data - module->regionOrigAddr_data;
|
||||
notifyData->dataSize = module->regionSize_data;
|
||||
|
||||
notifyData->readAddr = module->regionMappingBase_data;
|
||||
notifyData->readOffset = module->regionMappingBase_data - module->regionOrigAddr_data;
|
||||
notifyData->readSize = module->regionSize_data;
|
||||
|
||||
PPCCoreCallback(cb.callback, moduleHandle, cb.userContext.GetMPTR(), 2, notifyData.GetMPTR());
|
||||
OSDynLoad_AllocatorFree(notifyData);
|
||||
|
||||
}
|
||||
|
||||
RPLLoader_RemoveDependency(moduleHandle);
|
||||
RPLLoader_UpdateDependencies();
|
||||
}
|
||||
@@ -195,6 +254,25 @@ namespace coreinit
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 OSDynLoad_AddNotifyCallback(MEMPTR<OSDynLoadNotifyFunc> notifyFn, MEMPTR<void> userContext)
|
||||
{
|
||||
if (!notifyFn)
|
||||
return 0xBAD1000E; // notify function pointer is null
|
||||
|
||||
notifyCallbacks.emplace_back(notifyFn, userContext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 OSDynLoad_DelNotifyCallback(MEMPTR<OSDynLoadNotifyFunc> notifyFn, MEMPTR<void> userContext)
|
||||
{
|
||||
std::erase_if(notifyCallbacks, [&](const NotifyCallbackEntry& entry)
|
||||
{
|
||||
return entry.callback.GetMPTR() == notifyFn.GetMPTR() && entry.userContext == userContext;
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitializeDynLoad()
|
||||
{
|
||||
cafeExportRegister("coreinit", OSDynLoad_SetAllocator, LogType::Placeholder);
|
||||
@@ -209,5 +287,8 @@ namespace coreinit
|
||||
cafeExportRegister("coreinit", OSDynLoad_GetModuleName, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSDynLoad_GetNumberOfRPLs, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSDynLoad_GetRPLInfo, LogType::Placeholder);
|
||||
|
||||
cafeExportRegister("coreinit", OSDynLoad_AddNotifyCallback, LogType::Placeholder);
|
||||
cafeExportRegister("coreinit", OSDynLoad_DelNotifyCallback, LogType::Placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,14 @@ namespace coreinit
|
||||
uint32be readSize;
|
||||
};
|
||||
|
||||
using OSDynLoadNotifyFunc = void (*)(uint32be* module, void *userContext, sint32 notifyReason, OSDynLoad_NotifyData *infos);
|
||||
|
||||
struct NotifyCallbackEntry
|
||||
{
|
||||
MEMPTR<OSDynLoadNotifyFunc> callback;
|
||||
MEMPTR<void> userContext;
|
||||
};
|
||||
|
||||
uint32 OSDynLoad_SetAllocator(MPTR allocFunc, MPTR freeFunc);
|
||||
void OSDynLoad_SetTLSAllocator(MPTR allocFunc, MPTR freeFunc);
|
||||
uint32 OSDynLoad_GetAllocator(betype<MPTR>* funcAlloc, betype<MPTR>* funcFree);
|
||||
@@ -35,5 +43,8 @@ namespace coreinit
|
||||
sint32 OSDynLoad_GetNumberOfRPLs();
|
||||
uint32 OSDynLoad_GetRPLInfo(uint32 first, uint32 count, OSDynLoad_NotifyData* outInfos);
|
||||
|
||||
uint32 OSDynLoad_AddNotifyCallback(MEMPTR<OSDynLoadNotifyFunc> notifyFn, MEMPTR<void> userContext);
|
||||
uint32 OSDynLoad_DelNotifyCallback(MEMPTR<OSDynLoadNotifyFunc> notifyFn, MEMPTR<void> userContext);
|
||||
|
||||
void InitializeDynLoad();
|
||||
}
|
||||
Reference in New Issue
Block a user