diff --git a/inc/dmod_sal.h b/inc/dmod_sal.h index 771d6c0..7658b30 100644 --- a/inc/dmod_sal.h +++ b/inc/dmod_sal.h @@ -99,6 +99,21 @@ DMOD_BUILTIN_API(Dmod, 1.0, bool, _RetagEx, ( void* Ptr, const char* DMOD_BUILTIN_API(Dmod, 1.0, bool, _RenameTag, ( const char* OldTag, const char* NewTag ) ); DMOD_BUILTIN_API(Dmod, 1.0, size_t, _ReadMemory, ( uintptr_t Address, void* Buffer, size_t Size ) ); DMOD_BUILTIN_API(Dmod, 1.0, size_t, _WriteMemory, ( uintptr_t Address, const void* Buffer, size_t Size ) ); + +/** + * @brief Make code just written to memory safe to execute + * + * Called by the module loader once a module is loaded and relocated: on a + * core with caches, the code may still sit in the data cache, and the + * instruction cache may hold what was at these addresses before (a module + * unloaded from there). The system cleans the data cache for the range and + * invalidates the instruction cache. The default weak implementation does + * nothing - right for cores without caches and for hosts. + * + * @param Address Start of the code + * @param Size Its size in bytes + */ +DMOD_BUILTIN_API(Dmod, 1.0, void, _SyncCode, ( const void* Address, size_t Size ) ); //! @} /** diff --git a/src/system/if/dmod_if_rawmem.c b/src/system/if/dmod_if_rawmem.c index 2d6ecb9..0e7e480 100644 --- a/src/system/if/dmod_if_rawmem.c +++ b/src/system/if/dmod_if_rawmem.c @@ -182,6 +182,13 @@ DMOD_INPUT_WEAK_API_DECLARATION(Dmod, 1.0, size_t, _ReadMemory, ( uintptr_t Addr * * @return Number of bytes successfully written */ +DMOD_INPUT_WEAK_API_DECLARATION(Dmod, 1.0, void, _SyncCode, ( const void* Address, size_t Size )) +{ + /* No caches to keep coherent - see dmod_sal.h */ + (void)Address; + (void)Size; +} + DMOD_INPUT_WEAK_API_DECLARATION(Dmod, 1.0, size_t, _WriteMemory, ( uintptr_t Address, const void* Buffer, size_t Size )) { if (Buffer == NULL || Size == 0) diff --git a/src/system/private/dmod_ldr.c b/src/system/private/dmod_ldr.c index 0fb8c09..5091a36 100644 --- a/src/system/private/dmod_ldr.c +++ b/src/system/private/dmod_ldr.c @@ -607,11 +607,19 @@ bool Dmod_Ldr_Load( Dmod_Context_t* Context ) return false; } - return Dmod_Ldr_LoadHeader( Context ) - && Dmod_Ldr_LoadFooter( Context ) - && Dmod_Ldr_LoadOutput( Context ) - && Dmod_Ldr_LoadInput( Context ) - && Dmod_Ldr_LoadGot( Context ) - && Dmod_Ldr_LoadBss( Context ) - && Dmod_RMod_ReadRequiredModules( Context ); + if( !Dmod_Ldr_LoadHeader( Context ) + || !Dmod_Ldr_LoadFooter( Context ) + || !Dmod_Ldr_LoadOutput( Context ) + || !Dmod_Ldr_LoadInput( Context ) + || !Dmod_Ldr_LoadGot( Context ) + || !Dmod_Ldr_LoadBss( Context ) ) + { + return false; + } + + /* The module is in place and relocated: what was written must reach + * the instruction fetch before any of it runs */ + Dmod_SyncCode( Context->Data, Context->Size ); + + return Dmod_RMod_ReadRequiredModules( Context ); }