@@ -12,6 +12,8 @@ namespace coreinit
1212 MPTR _osDynLoadTLSFuncAlloc = MPTR_NULL ;
1313 MPTR _osDynLoadTLSFuncFree = MPTR_NULL ;
1414
15+ static std::vector<NotifyCallbackEntry> notifyCallbacks;
16+
1517 uint32 OSDynLoad_SetAllocator (MPTR allocFunc, MPTR freeFunc)
1618 {
1719 _osDynLoadFuncAlloc = allocFunc;
@@ -109,6 +111,34 @@ namespace coreinit
109111 cemuLog_logDebug (LogType::Force, " OSDynLoad_Acquire() failed to load module '{}'" , libName);
110112 return 0xFFFCFFE9 ; // module not found
111113 }
114+
115+ for (const auto & cb : notifyCallbacks)
116+ {
117+ MEMPTR <OSDynLoad_NotifyData> notifyData;
118+ notifyData = (OSDynLoad_NotifyData*)OSDynLoad_AllocatorAlloc (sizeof (OSDynLoad_NotifyData), 4 );
119+ RPLModule* module = RPLLoader_GetModuleByName (tempLibName);
120+
121+ if (!module )
122+ break ;
123+
124+ notifyData->name = module ->ppcName .GetMPTR ();
125+
126+ notifyData->textAddr = module ->regionMappingBase_text .GetBEValue ();
127+ notifyData->textOffset = module ->regionMappingBase_text .GetMPTR () - module ->regionOrigAddr_text ;
128+ notifyData->textSize = module ->regionSize_text ;
129+
130+ notifyData->dataAddr = module ->regionMappingBase_data ;
131+ notifyData->dataOffset = module ->regionMappingBase_data - module ->regionOrigAddr_data ;
132+ notifyData->dataSize = module ->regionSize_data ;
133+
134+ notifyData->readAddr = module ->regionMappingBase_data ;
135+ notifyData->readOffset = module ->regionMappingBase_data - module ->regionOrigAddr_data ;
136+ notifyData->readSize = module ->regionSize_data ;
137+
138+ PPCCoreCallback (cb.callback , moduleHandleOut, cb.userContext .GetMPTR (), 1 , notifyData.GetMPTR ());
139+ OSDynLoad_AllocatorFree (notifyData);
140+
141+ }
112142 return 0 ;
113143 }
114144
@@ -121,6 +151,35 @@ namespace coreinit
121151 {
122152 if (moduleHandle == RPL_INVALID_HANDLE )
123153 return ;
154+
155+ for (const auto & cb : notifyCallbacks)
156+ {
157+ MEMPTR <OSDynLoad_NotifyData> notifyData;
158+ notifyData = (OSDynLoad_NotifyData*)OSDynLoad_AllocatorAlloc (sizeof (OSDynLoad_NotifyData), 4 );
159+ RPLModule* module = RPLLoader_GetModuleByName (RPLLoader_GetModuleNameByHandle (moduleHandle));
160+
161+ if (!module )
162+ break ;
163+
164+ notifyData->name = module ->ppcName .GetMPTR ();
165+
166+ notifyData->textAddr = module ->regionMappingBase_text .GetBEValue ();
167+ notifyData->textOffset = module ->regionMappingBase_text .GetMPTR () - module ->regionOrigAddr_text ;
168+ notifyData->textSize = module ->regionSize_text ;
169+
170+ notifyData->dataAddr = module ->regionMappingBase_data ;
171+ notifyData->dataOffset = module ->regionMappingBase_data - module ->regionOrigAddr_data ;
172+ notifyData->dataSize = module ->regionSize_data ;
173+
174+ notifyData->readAddr = module ->regionMappingBase_data ;
175+ notifyData->readOffset = module ->regionMappingBase_data - module ->regionOrigAddr_data ;
176+ notifyData->readSize = module ->regionSize_data ;
177+
178+ PPCCoreCallback (cb.callback , moduleHandle, cb.userContext .GetMPTR (), 2 , notifyData.GetMPTR ());
179+ OSDynLoad_AllocatorFree (notifyData);
180+
181+ }
182+
124183 RPLLoader_RemoveDependency (moduleHandle);
125184 RPLLoader_UpdateDependencies ();
126185 }
@@ -195,6 +254,25 @@ namespace coreinit
195254 return 1 ;
196255 }
197256
257+ uint32 OSDynLoad_AddNotifyCallback (MEMPTR <OSDynLoadNotifyFunc> notifyFn, MEMPTR <void > userContext)
258+ {
259+ if (!notifyFn)
260+ return 0xBAD1000E ; // notify function pointer is null
261+
262+ notifyCallbacks.emplace_back (notifyFn, userContext);
263+ return 0 ;
264+ }
265+
266+ uint32 OSDynLoad_DelNotifyCallback (MEMPTR <OSDynLoadNotifyFunc> notifyFn, MEMPTR <void > userContext)
267+ {
268+ std::erase_if (notifyCallbacks, [&](const NotifyCallbackEntry& entry)
269+ {
270+ return entry.callback .GetMPTR () == notifyFn.GetMPTR () && entry.userContext == userContext;
271+ });
272+
273+ return 0 ;
274+ }
275+
198276 void InitializeDynLoad ()
199277 {
200278 cafeExportRegister (" coreinit" , OSDynLoad_SetAllocator, LogType::Placeholder);
@@ -209,5 +287,8 @@ namespace coreinit
209287 cafeExportRegister (" coreinit" , OSDynLoad_GetModuleName, LogType::Placeholder);
210288 cafeExportRegister (" coreinit" , OSDynLoad_GetNumberOfRPLs, LogType::Placeholder);
211289 cafeExportRegister (" coreinit" , OSDynLoad_GetRPLInfo, LogType::Placeholder);
290+
291+ cafeExportRegister (" coreinit" , OSDynLoad_AddNotifyCallback, LogType::Placeholder);
292+ cafeExportRegister (" coreinit" , OSDynLoad_DelNotifyCallback, LogType::Placeholder);
212293 }
213294}
0 commit comments