/*---------------------------------------------------------------------------* 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.4 12/19/2006 05:19:03 srd_nisiwaki Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include "static.h" #ifdef _DEBUG #define MODULE_I "/iD.rso" #define MODULE_J "/jD.rso" #define STATIC_RSO "/staticD.sel" #else #define MODULE_I "/i.rso" #define MODULE_J "/j.rso" #define STATIC_RSO "/static.sel" #endif // void _unresolved(); /*---------------------------------------------------------------------------* RsoLinkJump *---------------------------------------------------------------------------*/ // static u32 *makeCodeMem2(RSOObjectHeader *i_rso) { int a_size = RSOGetJumpCodeSize(i_rso); void *r_buff; if(a_size == 0) return NULL; r_buff = OSAllocFromMEM2ArenaLo((u32)a_size,4); // RSOMakeJumpCode(i_rso,r_buff); // return r_buff; } /*---------------------------------------------------------------------------* 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 (*MainI)(); // static RSOExportFuncTable exp_tblI[] = { {"MainI", (u32 *)&MainI}, }; // static void RSOResolvedModuleI(const RSOObjectHeader* module) { int i; for(i = 0; i < sizeof(exp_tblI)/sizeof(RSOExportFuncTable); i++) { *(exp_tblI[i].symbol_ptr) = (u32)RSOFindExportSymbolAddr(module, exp_tblI[i].symbol_name); } } // static void RSOUnresolvedModuleI(void) { int i; for(i = 0; i < sizeof(exp_tblI)/sizeof(RSOExportFuncTable); i++) { *(exp_tblI[i].symbol_ptr) = (u32)_unresolved; } } // Functions and variables to be accessed void (*MainJ)(); // static RSOExportFuncTable exp_tblJ[] = { {"MainJ", (u32 *)&MainJ}, }; // static void RSOResolvedModuleJ(const RSOObjectHeader* module) { int i; for(i = 0; i < sizeof(exp_tblJ)/sizeof(RSOExportFuncTable); i++) { *(exp_tblJ[i].symbol_ptr) = (u32)RSOFindExportSymbolAddr(module, exp_tblJ[i].symbol_name); } } // static void RSOUnresolvedModuleJ(void) { int i; for(i = 0; i < sizeof(exp_tblJ)/sizeof(RSOExportFuncTable); i++) { *(exp_tblJ[i].symbol_ptr) = (u32)_unresolved; } } //main int main(void) { RSOObjectHeader* staticRso; RSOObjectHeader* moduleI; RSOObjectHeader* moduleJ; u32 *buff_static; // Generate weak symbol 'InlineFunc' DVDInit(); //Read data // Load static rso file OSReport("Loading static rso...\n"); staticRso = StaticRsoLoad(STATIC_RSO); if (!staticRso) return 1; // Create relay code buff_static = makeCodeMem2(staticRso); // Load and link module I OSReport("Linking module I...\n"); moduleI = RsoLoadMem2(MODULE_I); if (!moduleI) { return 1; } // Load and link module J OSReport("Linking module J...\n"); moduleJ = RsoLoadMem2(MODULE_J); if (!moduleJ) { return 1; } // Link using relay code RSOLinkJump(moduleI,staticRso,buff_static); RSOLinkJump(moduleJ,staticRso,buff_static); //Check whether all symbols are resolved if (RSOIsImportSymbolResolvedAll(moduleI)) { OSReport("moduleI's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleJ)) { OSReport("moduleJ's ImportSymbol is resolved all.\n"); } // OSReport("\nI prolog()\n"); ((u32 (*)(void)) moduleI->prolog)(); RSOResolvedModuleI(moduleI); // OSReport("\nJ prolog()\n"); ((u32 (*)(void)) moduleJ->prolog)(); RSOResolvedModuleJ(moduleJ); // OSReport("\ncall MainI = %p\n",MainI); MainI(); // OSReport("\ncall MainJ = %p\n",MainJ); MainJ(); // OSReport("\nI epilog()\n"); ((u32 (*)(void)) moduleI->epilog)(); RSOUnresolvedModuleI(); // OSReport("\nJ epilog()\n"); ((u32 (*)(void)) moduleJ->epilog)(); RSOUnresolvedModuleJ(); // RSOUnLinkList(moduleI); RSOUnLinkList(moduleJ); // OSReport("\nRSOLink finish all!\n"); // Release buff_static memory only after RSOUnLinkList. return 0; } extern void staticFuncA(void) { OSReport("\nstaticFuncA!\n"); } extern void staticFuncB(void) { OSReport("\nstaticFuncB!\n"); } extern void staticFuncC(void) { OSReport("\nstaticFuncC!\n"); }