/*---------------------------------------------------------------------------* 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 2008/06/13 04:43:51 mitu Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #ifdef _DEBUG #define MODULE_A "/aD.rso" #define MODULE_B "/bD.rso" #define MODULE_C "/cD.rso" #define STATIC_RSO "/staticD.sel" #else #define MODULE_A "/a.rso" #define MODULE_B "/b.rso" #define MODULE_C "/c.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 } // // Perform internal reference processing. RSOLocateObject(&module->info, 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); // Perform internal processing. RSOStaticLocateObject(module); return module; } // void _unresolved() { OSReport("_unresolved func.\n"); } // Functions and variables we want to access void (*MainA)(); void (*IsAThere)(); int (*g_intA); static RSOExportFuncTable exp_tbl[] = { {"MainA", (u32 *)&MainA}, {"IsAThere",(u32 *)&IsAThere}, {"g_intA", (u32 *)&g_intA}, }; // static void RSOResolvedModuleA(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 RSOUnresolvedModuleA(void) { int i; for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) { *(exp_tbl[i].symbol_ptr) = (u32)_unresolved; } } // // Functions and variables we want to access void (*MainC)(); static RSOExportFuncTable exp_tblC[] = { {"MainC", (u32 *)&MainC}, }; // static void RSOResolvedModuleC(const RSOObjectHeader* module) { int i; for(i = 0; i < sizeof(exp_tblC)/sizeof(RSOExportFuncTable); i++) { *(exp_tblC[i].symbol_ptr) = (u32)RSOFindExportSymbolAddr(module, exp_tblC[i].symbol_name); } } // static void RSOUnresolvedModuleC(void) { int i; for(i = 0; i < sizeof(exp_tblC)/sizeof(RSOExportFuncTable); i++) { *(exp_tblC[i].symbol_ptr) = (u32)_unresolved; } } //Main int main(void) { RSOObjectHeader* staticRso; RSOObjectHeader* moduleA; RSOObjectHeader* moduleB; RSOObjectHeader* moduleC; int resolved; // 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 A OSReport("Linking module A...\n"); moduleA = RsoLoad(MODULE_A); if (!moduleA) { return 1; } // Load and link module B OSReport("Linking module B...\n"); moduleB = RsoLoad(MODULE_B); if (!moduleB) { return 1; } // Load and link module C OSReport("Linking module C...\n"); moduleC = RsoLoad(MODULE_C); if (!moduleC) { return 1; } //Check whether all are resolved (unresolved at this point) if (RSOIsImportSymbolResolvedAll(moduleA)) { OSReport("moduleA's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleB)) { OSReport("moduleB's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleC)) { OSReport("moduleC's ImportSymbol is resolved all.\n"); } // Resolve // Reference to static module // Module A references a static module resolved = RSOLink(moduleA, staticRso); OSReport("A,S resolved %d\n", resolved); // Module B references a static module resolved = RSOLink(moduleB, staticRso); OSReport("B,S resolved %d\n", resolved); // Module C references a static module resolved = RSOLink(moduleC, staticRso); OSReport("C,S resolved %d\n", resolved); // Reference to Module A // Module B references Module A resolved = RSOLink(moduleB, moduleA); OSReport("B,A resolved %d\n", resolved); // Reference to Module B // Module A references Module B resolved = RSOLink(moduleA, moduleB); OSReport("A,B resolved %d\n", resolved); //Check whether all symbols are resolved (they should be resolved) if (RSOIsImportSymbolResolvedAll(moduleA)) { OSReport("moduleA's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleB)) { OSReport("moduleB's ImportSymbol is resolved all.\n"); } if (RSOIsImportSymbolResolvedAll(moduleC)) { OSReport("moduleC's ImportSymbol is resolved all.\n"); } // OSReport("\nA prolog()\n"); ((u32 (*)(void)) moduleA->prolog)(); OSReport("\nB prolog()\n"); ((u32 (*)(void)) moduleB->prolog)(); OSReport("\nC prolog()\n"); ((u32 (*)(void)) moduleC->prolog)(); // RSOResolvedModuleA(moduleA); // OSReport("MainA = %x\n",MainA); OSReport("g_intA = %x\n",g_intA); MainA(); OSReport("g_intA = %d\n", *g_intA); *g_intA += 5; OSReport("g_intA + 5 = %d\n", *g_intA); MainA(); // RSOResolvedModuleC(moduleC); // MainC(); // OSReport("\nA epilog()\n"); ((u32 (*)(void)) moduleA->epilog)(); RSOUnresolvedModuleA(); // OSReport("\nB epilog()\n"); ((u32 (*)(void)) moduleB->epilog)(); // Release all links associated with A before executing RSOUnLocateObject on Module A RSOUnLink(moduleA, staticRso); RSOUnLink(moduleA, moduleB); RSOUnLink(moduleB, moduleA); RSOUnLocateObject(moduleA); // Do the same with Module B RSOUnLink(moduleB, staticRso); RSOUnLocateObject(moduleB); // Module C OSReport("\nC epilog()\n"); ((u32 (*)(void)) moduleC->epilog)(); RSOUnresolvedModuleC(); // RSOUnLink(moduleC, staticRso); return 0; }