Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/Cafe/OS/RPL/rpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/Cafe/OS/RPL/rpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
81 changes: 81 additions & 0 deletions src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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();
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}
15 changes: 14 additions & 1 deletion src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ namespace coreinit
uint32be readSize;
};

using OSDynLoadNotifyFunc = void (*)(uint32be* module, void *userContext, sint32 notifyReason, OSDynLoad_NotifyData *infos);

struct NotifyCallbackEntry
{
MEMPTR<OSDynLoadNotifyFunc> callback;
MEMPTR<void> userContext;

NotifyCallbackEntry(MEMPTR<OSDynLoadNotifyFunc> func, MEMPTR<void> context) : callback(func), userContext(context) {}
};

uint32 OSDynLoad_SetAllocator(MPTR allocFunc, MPTR freeFunc);
void OSDynLoad_SetTLSAllocator(MPTR allocFunc, MPTR freeFunc);
uint32 OSDynLoad_GetAllocator(betype<MPTR>* funcAlloc, betype<MPTR>* funcFree);
Expand All @@ -35,5 +45,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();
}
}