2020-04-28 14:43:07 +02:00
# include <coreinit/cache.h>
# include "ModuleDataPersistence.h"
# include "DynamicLinkingHelper.h"
# include "common/module_defines.h"
# include "ModuleData.h"
# include "RelocationData.h"
2020-05-17 19:05:51 +02:00
bool ModuleDataPersistence : : saveModuleData ( module_information_t * moduleInformation , const ModuleData & module ) {
2020-04-28 14:43:07 +02:00
int32_t module_count = moduleInformation - > number_used_modules ;
2020-05-17 19:05:51 +02:00
if ( module_count > = MAXIMUM_MODULES ) {
2020-04-29 12:06:47 +02:00
DEBUG_FUNCTION_LINE ( " Reached maximum module count of %d " , MAXIMUM_MODULES ) ;
2020-04-28 14:43:07 +02:00
return false ;
}
// Copy data to global struct.
2020-05-17 19:05:51 +02:00
module_information_single_t * module_data = & ( moduleInformation - > module_data [ module_count ] ) ;
2020-04-28 14:43:07 +02:00
2020-05-17 13:11:52 +02:00
DEBUG_FUNCTION_LINE ( " Saving reloation data for module at %08X " , module . getEntrypoint ( ) ) ;
2020-04-28 14:43:07 +02:00
// Relocation
2020-05-17 13:11:52 +02:00
std : : vector < RelocationData > relocationData = module . getRelocationDataList ( ) ;
2020-05-17 19:05:51 +02:00
for ( auto const & reloc : relocationData ) {
if ( ! DynamicLinkingHelper : : addReloationEntry ( & ( moduleInformation - > linking_data ) , module_data - > linking_entries , DYN_LINK_RELOCATION_LIST_LENGTH , reloc ) ) {
2020-04-29 12:06:47 +02:00
DEBUG_FUNCTION_LINE ( " Failed to add relocation entry \n " ) ;
2020-04-28 14:43:07 +02:00
return false ;
}
}
2020-05-17 21:14:27 +02:00
std : : vector < ExportData > exportData = module . getExportDataList ( ) ;
for ( auto const & curExport : exportData ) {
bool found = false ;
for ( uint32_t j = 0 ; j < EXPORT_ENTRY_LIST_LENGTH ; j + + ) {
export_data_t * export_entry = & ( module_data - > export_entries [ j ] ) ;
if ( export_entry - > address = = NULL ) {
export_entry - > type = curExport . getType ( ) ;
strncpy ( export_entry - > name , curExport . getName ( ) . c_str ( ) , EXPORT_MAXIMUM_NAME_LENGTH ) ;
export_entry - > address = ( uint32_t ) curExport . getAddress ( ) ;
found = true ;
break ;
}
}
if ( ! found ) {
DEBUG_FUNCTION_LINE ( " Failed to found enough exports slots " ) ;
2020-05-29 17:36:10 +02:00
break ;
}
}
std : : vector < HookData > hookData = module . getHookDataList ( ) ;
for ( auto const & curHook : hookData ) {
bool found = false ;
for ( uint32_t j = 0 ; j < HOOK_ENTRY_LIST_LENGTH ; j + + ) {
hook_data_t * hook_entry = & ( module_data - > hook_entries [ j ] ) ;
if ( hook_entry - > target = = NULL ) {
hook_entry - > type = curHook . getType ( ) ;
hook_entry - > target = ( uint32_t ) curHook . getTarget ( ) ;
found = true ;
break ;
}
}
if ( ! found ) {
DEBUG_FUNCTION_LINE ( " Failed to found enough hook slots " ) ;
break ;
2020-05-17 21:14:27 +02:00
}
}
strncpy ( module_data - > module_export_name , module . getExportName ( ) . c_str ( ) , MAXIMUM_EXPORT_MODULE_NAME_LENGTH ) ;
2020-05-17 13:11:52 +02:00
module_data - > bssAddr = module . getBSSAddr ( ) ;
module_data - > bssSize = module . getBSSSize ( ) ;
module_data - > sbssAddr = module . getSBSSAddr ( ) ;
module_data - > sbssSize = module . getSBSSSize ( ) ;
module_data - > startAddress = module . getStartAddress ( ) ;
module_data - > endAddress = module . getEndAddress ( ) ;
2020-04-28 14:43:07 +02:00
2020-05-17 13:11:52 +02:00
module_data - > entrypoint = module . getEntrypoint ( ) ;
2020-04-28 14:43:07 +02:00
moduleInformation - > number_used_modules + + ;
2020-05-17 19:05:51 +02:00
DCFlushRange ( ( void * ) moduleInformation , sizeof ( module_information_t ) ) ;
ICInvalidateRange ( ( void * ) moduleInformation , sizeof ( module_information_t ) ) ;
2020-04-28 14:43:07 +02:00
return true ;
}
2020-05-17 19:05:51 +02:00
std : : vector < ModuleData > ModuleDataPersistence : : loadModuleData ( module_information_t * moduleInformation ) {
2020-05-17 13:11:52 +02:00
std : : vector < ModuleData > result ;
2020-05-17 19:05:51 +02:00
if ( moduleInformation = = NULL ) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE ( " moduleInformation == NULL \n " ) ;
return result ;
}
2020-05-17 19:05:51 +02:00
DCFlushRange ( ( void * ) moduleInformation , sizeof ( module_information_t ) ) ;
ICInvalidateRange ( ( void * ) moduleInformation , sizeof ( module_information_t ) ) ;
2020-04-28 14:43:07 +02:00
int32_t module_count = moduleInformation - > number_used_modules ;
2020-05-17 19:05:51 +02:00
if ( module_count > MAXIMUM_MODULES ) {
DEBUG_FUNCTION_LINE ( " moduleInformation->module_count was bigger then allowed. %d > %d. Limiting to %d \n " , module_count , MAXIMUM_MODULES , MAXIMUM_MODULES ) ;
2020-04-28 14:43:07 +02:00
module_count = MAXIMUM_MODULES ;
}
2020-05-17 19:05:51 +02:00
for ( int32_t i = 0 ; i < module_count ; i + + ) {
2020-04-28 14:43:07 +02:00
// Copy data from struct.
2020-05-17 19:05:51 +02:00
module_information_single_t * module_data = & ( moduleInformation - > module_data [ i ] ) ;
2020-05-17 13:11:52 +02:00
ModuleData moduleData ;
moduleData . setBSSLocation ( module_data - > bssAddr , module_data - > bssSize ) ;
moduleData . setSBSSLocation ( module_data - > sbssAddr , module_data - > sbssSize ) ;
moduleData . setEntrypoint ( module_data - > entrypoint ) ;
moduleData . setStartAddress ( module_data - > startAddress ) ;
moduleData . setEndAddress ( module_data - > endAddress ) ;
2020-04-28 14:43:07 +02:00
2020-05-29 17:30:10 +02:00
moduleData . setExportName ( module_data - > module_export_name ) ;
2020-05-29 17:29:17 +02:00
for ( uint32_t j = 0 ; j < EXPORT_ENTRY_LIST_LENGTH ; j + + ) {
2020-05-17 21:14:27 +02:00
export_data_t * export_entry = & ( module_data - > export_entries [ j ] ) ;
if ( export_entry - > address = = NULL ) {
continue ;
}
moduleData . addExportData ( ExportData ( static_cast < wums_entry_type_t > ( export_entry - > type ) , export_entry - > name , reinterpret_cast < const void * > ( export_entry - > address ) ) ) ;
}
2020-05-29 17:36:10 +02:00
for ( uint32_t j = 0 ; j < HOOK_ENTRY_LIST_LENGTH ; j + + ) {
hook_data_t * hook_entry = & ( module_data - > hook_entries [ j ] ) ;
if ( hook_entry - > target = = NULL ) {
continue ;
}
moduleData . addHookData ( HookData ( static_cast < wums_hook_type_t > ( hook_entry - > type ) , reinterpret_cast < const void * > ( hook_entry - > target ) ) ) ;
}
2020-05-17 19:05:51 +02:00
for ( uint32_t j = 0 ; j < DYN_LINK_RELOCATION_LIST_LENGTH ; j + + ) {
dyn_linking_relocation_entry_t * linking_entry = & ( module_data - > linking_entries [ j ] ) ;
if ( linking_entry - > destination = = NULL ) {
2020-04-28 14:43:07 +02:00
break ;
}
2020-05-17 19:05:51 +02:00
dyn_linking_import_t * importEntry = linking_entry - > importEntry ;
if ( importEntry = = NULL ) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE ( " importEntry was NULL, skipping relocation entry \n " ) ;
continue ;
}
2020-05-17 19:05:51 +02:00
if ( importEntry - > importName = = NULL ) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE ( " importEntry->importName was NULL, skipping relocation entry \n " ) ;
continue ;
}
2020-05-17 19:05:51 +02:00
dyn_linking_function_t * functionEntry = linking_entry - > functionEntry ;
2020-04-28 14:43:07 +02:00
2020-05-17 19:05:51 +02:00
if ( functionEntry = = NULL ) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE ( " functionEntry was NULL, skipping relocation entry \n " ) ;
continue ;
}
2020-05-17 19:05:51 +02:00
if ( functionEntry - > functionName = = NULL ) {
2020-04-28 14:43:07 +02:00
DEBUG_FUNCTION_LINE ( " functionEntry->functionName was NULL, skipping relocation entry \n " ) ;
continue ;
}
2020-05-17 13:11:52 +02:00
ImportRPLInformation rplInfo ( importEntry - > importName , importEntry - > isData ) ;
RelocationData reloc ( linking_entry - > type , linking_entry - > offset , linking_entry - > addend , linking_entry - > destination , functionEntry - > functionName , rplInfo ) ;
moduleData . addRelocationData ( reloc ) ;
2020-04-28 14:43:07 +02:00
}
result . push_back ( moduleData ) ;
}
return result ;
}