/*---------------------------------------------------------------------------* Project: rsodemo File: static.c Copyright 2006 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. @version $Id: static.c,v 1.8 2006/09/11 06:35:03 srd_komatu Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #ifdef _DEBUG #define MODULE_E "/eD.rso" #define MODULE_F "/fD.rso" #define STATIC_RSO "/staticD.sel" #else #define MODULE_E "/e.rso" #define MODULE_F "/f.rso" #define STATIC_RSO "/static.sel" #endif // void _unresolved(); /*---------------------------------------------------------------------------* Load *---------------------------------------------------------------------------*/ // Load and link the specified module static RSOObjectHeader* RsoLoad(char* moduleName) { DVDFileInfo fileInfo; s32 length; BOOL result; RSOObjectHeader* module; u8* bss; result = DVDOpen(moduleName, &fileInfo); if (!result) return NULL; length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo)); module = OSAllocFromArenaLo((u32) length, 32); result = DVDRead(&fileInfo, module, length, 0); if (!result) return NULL; DVDClose(&fileInfo); if (module->bssSize > 0) { bss = OSAllocFromArenaLo(module->bssSize, 32); // alloc bss area } RSOLinkList(module, bss); return module; } // static RSOObjectHeader* RsoLoadMem2(char* moduleName) { DVDFileInfo fileInfo; s32 length; BOOL result; RSOObjectHeader* module; u8* bss; result = DVDOpen(moduleName, &fileInfo); if (!result) return NULL; length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo)); module = OSAllocFromMEM2ArenaLo((u32) length, 32); result = DVDRead(&fileInfo, module, length, 0); if (!result) return NULL; DVDClose(&fileInfo); if (module->bssSize > 0) { bss = OSAllocFromMEM2ArenaLo(module->bssSize, 32); // alloc bss area } RSOLinkList(module, bss); return module; } // Load and link the static module static RSOObjectHeader* StaticRsoLoad(char* moduleName) { DVDFileInfo fileInfo; s32 length; BOOL result; RSOObjectHeader* module; result = DVDOpen(moduleName, &fileInfo); if (!result) return NULL; length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo)); module = OSAllocFromArenaLo((u32) length, 32); result = DVDRead(&fileInfo, module, length, 0); if (!result) return NULL; DVDClose(&fileInfo); RSOListInit(module); return module; } // void _unresolved() { OSReport("_unresolved func.\n"); } // Functions and variables to be accessed void (*MainE)(); void (*IsEThere)(); int (*g_intE); // static RSOExportFuncTable exp_tbl[] = { {"MainE", (u32 *)&MainE}, {"IsEThere",(u32 *)&IsEThere}, {"g_intE", (u32 *)&g_intE}, }; // static void RSOResolvedModuleE(const RSOObjectHeader* module) { int i; for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) { *(exp_tbl[i].symbol_ptr) = (u32)RSOFindExportSymbolAddr(module, exp_tbl[i].symbol_name); } } // static void RSOUnresolvedModuleE(void) { int i; for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) { *(exp_tbl[i].symbol_ptr) = (u32)_unresolved; } } //main int main(void) { RSOObjectHeader* staticRso; RSOObjectHeader* moduleE; RSOObjectHeader* moduleF; // Generate weak symbol 'InlineFunc' DVDInit(); // Read data // Load static rso file OSReport("Loading static rso...\n"); staticRso = StaticRsoLoad(STATIC_RSO); if (!staticRso) return 1; // Load and link module E OSReport("Linking module E...\n"); moduleE = RsoLoadMem2(MODULE_E); if (!moduleE) { return 1; } // Load and link module F OSReport("Linking module F...\n"); moduleF = RsoLoad(MODULE_F); if (!moduleF) { return 1; } // Check whether all symbols are resolved if (RSOIsImportSymbolResolvedAll(moduleE)) { OSReport("moduleE's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleF)) { OSReport("moduleF's ImportSymbol is resolved all.\n"); } // OSReport("\nE prolog()\n"); ((u32 (*)(void)) moduleE->prolog)(); RSOResolvedModuleE(moduleE); // OSReport("\nF prolog()\n"); ((u32 (*)(void)) moduleF->prolog)(); // MainE(); *g_intE += 5; MainE(); // OSReport("\nE epilog()\n"); ((u32 (*)(void)) moduleE->epilog)(); RSOUnresolvedModuleE(); // OSReport("\nF epilog()\n"); ((u32 (*)(void)) moduleF->epilog)(); // RSOUnLinkList(moduleE); RSOUnLinkList(moduleF); // OSReport("\nRSOLink finish all!\n"); return 0; }