/*---------------------------------------------------------------------------* 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.3 2006/09/25 06:13:47 srd_nisiwaki Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #ifdef _DEBUG #define MODULE_G "/gD.rso" #define MODULE_H "/hD.rso" #define STATIC_RSO "/staticD.sel" #else #define MODULE_G "/g.rso" #define MODULE_H "/h.rso" #define STATIC_RSO "/static.sel" #endif // void _unresolved(); /*---------------------------------------------------------------------------* RsoLinkFar *---------------------------------------------------------------------------*/ static u32 *LinkFar(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp) { int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp); u32 *a_buff; // if(a_size == 0) { // Not essential return NULL; } // a_buff = OSAllocFromArenaLo((u32)a_size,4); // RSOLinkFar(i_rsoImp,i_rsoExp,a_buff); // #if 0 { int i,j; OSReport("buff = %p\n",a_buff); for(i = 0,j = 0; i < a_size; i+=16,j+=4) { OSReport("%p\n%p\n%p\n%p\n", a_buff[j],a_buff[j+1],a_buff[j+2],a_buff[j+3]); } } #endif // return a_buff; } static u32 *LinkFarMem2(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp) { int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp); u32 *a_buff; // if(a_size == 0) { // Not essential return NULL; } // a_buff = OSAllocFromMEM2ArenaLo((u32)a_size,4); // RSOLinkFar(i_rsoImp,i_rsoExp,a_buff); // #if 0 { int i,j; OSReport("buff = %p\n",a_buff); for(i = 0,j = 0; i < a_size; i+=16,j+=4) { OSReport("%p\n%p\n%p\n%p\n", a_buff[j],a_buff[j+1],a_buff[j+2],a_buff[j+3]); } } #endif // return a_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 or variables to access void (*MainG)(); // static RSOExportFuncTable exp_tbl[] = { {"MainG", (u32 *)&MainG}, }; // static void RSOResolvedModuleG(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 RSOUnresolvedModuleG(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* moduleG; RSOObjectHeader* moduleH; u32* buff_gh; // Buffer necessary when H is LinkFar-ed to G u32* buff_hg; // Buffer necessary when G is LinkFar-ed to H u32* buff_sg; // Buffer necessary when G is LinkFar-ed to H // Generate weak symbol 'InlineFunc' DVDInit(); //Read // Load static rso file OSReport("Loading static rso...\n"); staticRso = StaticRsoLoad(STATIC_RSO); if (!staticRso) return 1; // Load and link module G OSReport("Linking module G...\n"); moduleG = RsoLoadMem2(MODULE_G); if (!moduleG) { return 1; } // Load and link module H OSReport("Linking module H...\n"); moduleH = RsoLoad(MODULE_H); if (!moduleH) { return 1; } // When linking from H, get region from MEM1 where H is located buff_gh = LinkFar(moduleH,moduleG); // When linking from G, get region from MEM2 where G is located buff_hg = LinkFarMem2(moduleG,moduleH); buff_sg = LinkFarMem2(moduleG,staticRso); //Check whether everything has been resolved if (RSOIsImportSymbolResolvedAll(moduleG)) { OSReport("moduleG's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleH)) { OSReport("moduleH's ImportSymbol is resolved all.\n"); } // OSReport("\nG prolog()\n"); ((u32 (*)(void)) moduleG->prolog)(); RSOResolvedModuleG(moduleG); // OSReport("\nH prolog()\n"); ((u32 (*)(void)) moduleH->prolog)(); // OSReport("\ncall MainG = %p\n",MainG); // MainG(); // OSReport("\nG epilog()\n"); ((u32 (*)(void)) moduleG->epilog)(); RSOUnresolvedModuleG(); // OSReport("\nH epilog()\n"); ((u32 (*)(void)) moduleH->epilog)(); // RSOUnLinkList(moduleG); RSOUnLinkList(moduleH); // OSReport("\nRSOLink finish all!\n"); // Release buff_gh and other memory after RSOUnLinkList. return 0; }