/*---------------------------------------------------------------------------* Project: Dolphin OS relocatable module demo File: static.c Copyright 2000-2002 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. $Log: static.c,v $ Revision 1.2 02/20/2006 04:13:12 mitu changed include path from dolphin/ to revolution/. Revision 1.1 01/26/2006 08:01:00 hiratsu Relocatable module demo. 12 4/09/04 11:43 Shiki Added check code for sdata and sdata2. 11 9/25/02 20:16 Shiki Added call to OSLinkFixed(). 10 8/23/02 17:43 Shiki Added call to InlineFunc(). 9 5/13/02 9:22 Shiki Added more OSReport()s to see program behavior more clearly. 8 11/27/01 21:49 Shiki Modified to include only. 7 6/09/01 5:25p Shiki Fixed to load .rel files from lower arena to support 48MB ORCA. 6 01/04/02 13:44:00 Shiki Separated OSModuleInfo into OSModuleInfo and OSModuleHeader. 5 01/03/01 12:55 Shiki Clean up. 4 01/02/27 13:11 Shiki Modified to load string table with non-debug build as well. 3 10/31/00 3:51p Shiki Modified to call OSUnlink(). 2 6/14/01 11:37a Shiki Added a call to unlinked function to test. 1 4/14/00 11:37p Shiki Initial check-in. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include "inline.h" #ifdef _DEBUG #define MODULE_A "/aD.rel" #define MODULE_B "/bD.rel" #define STRING_TABLE "/staticD.str" #else #define MODULE_A "/a.rel" #define MODULE_B "/b.rel" #define STRING_TABLE "/static.str" #endif __declspec(section ".sdata") int SDVar; __declspec(section ".sdata2") int SD2Var; static void DumpModuleInfo(OSModuleInfo* moduleInfo) { OSReport("id %d\n", moduleInfo->id); OSReport("numSections %d\n", moduleInfo->numSections); OSReport("sectionInfoOffset %08xh\n", moduleInfo->sectionInfoOffset); OSReport("nameOffset %08xh [%s]\n", moduleInfo->nameOffset, moduleInfo->nameOffset); OSReport("nameSize %d\n", moduleInfo->nameSize); OSReport("version %d\n", moduleInfo->version); OSReport("\n"); } static void DumpModuleHeader(OSModuleHeader* module) { DumpModuleInfo(&module->info); OSReport("bssSize %d\n", module->bssSize); OSReport("relOffset %08xh\n", module->relOffset); OSReport("impOffset %08xh\n", module->impOffset); OSReport("impSize %08xh\n", module->impSize); OSReport("prolog %08xh\n", module->prolog); OSReport("epilog %08xh\n", module->epilog); OSReport("unresolved %08xh\n", module->unresolved); if (2 <= module->info.version) { OSReport("align %08xh\n", module->align); OSReport("bssAlign %08xh\n", module->bssAlign); } if (3 <= module->info.version) { OSReport("fixSize %08xh\n", module->fixSize); } OSReport("\n"); } // Load and link the specified module static OSModuleHeader* Load(char* moduleName) { DVDFileInfo fileInfo; s32 length; BOOL result; OSModuleHeader* 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 (3 <= module->info.version) { bss = (u8*) module + module->fixSize; bss = (u8*) OSRoundUp32B(bss); if (bss + module->bssSize < OSGetArenaLo()) { OSSetArenaLo((void*) OSRoundUp32B(bss + module->bssSize)); } else { OSAllocFromArenaLo(module->bssSize - ((u8*) OSGetArenaLo() - bss), 32); } OSLinkFixed(&module->info, bss); } else { bss = OSAllocFromArenaLo(module->bssSize, 32); // alloc bss area OSLink(&module->info, bss); } DumpModuleHeader(module); return module; } int main(void) { BOOL result; DVDFileInfo fileInfo; u32 length; OSModuleHeader* moduleA; OSModuleHeader* moduleB; void* ptr; // Generate weak symbol 'InlineFunc' InlineFunc(1, 2); DVDInit(); // Load string table to use debugger result = DVDOpen(STRING_TABLE, &fileInfo); if (!result) return 1; length = OSRoundUp32B(DVDGetLength(&fileInfo)); ptr = OSAllocFromArenaLo(length, 32); result = DVDRead(&fileInfo, ptr, (s32) length, 0); if (!result) return 1; OSSetStringTable(ptr); OSReport("SDVar(%p) %d SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var); // Load and link module A OSReport("Linking module A...\n"); moduleA = Load(MODULE_A); if (!moduleA) return 1; ((u32 (*)(void)) moduleA->prolog)(); // Load and link module B OSReport("Linking module B...\n"); moduleB = Load(MODULE_B); if (!moduleB) return 1; ((u32 (*)(void)) moduleB->prolog)(); // Unlink module B OSReport("Unlinking module B...\n"); ((u32 (*)(void)) moduleB->epilog)(); OSUnlink(&moduleB->info); // Unlink module A OSReport("Unlinking module A...\n"); ((u32 (*)(void)) moduleA->epilog)(); OSUnlink(&moduleA->info); OSReport("SDVar(%p) %d SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var); return 0; }