1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin OS relocatable module demo
3   File:     static.c
4 
5   Copyright 2000-2002 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: static.c,v $
14   Revision 1.2  02/20/2006 04:13:12  mitu
15   changed include path from dolphin/ to revolution/.
16 
17   Revision 1.1  01/26/2006 08:01:00  hiratsu
18   Relocatable module demo.
19 
20 
21     12     4/09/04 11:43 Shiki
22     Added check code for sdata and sdata2.
23 
24     11    9/25/02 20:16 Shiki
25     Added call to OSLinkFixed().
26 
27     10     8/23/02 17:43 Shiki
28     Added call to InlineFunc().
29 
30     9     5/13/02 9:22 Shiki
31     Added more OSReport()s to see program behavior more clearly.
32 
33     8     11/27/01 21:49 Shiki
34     Modified to include <dolphin.h> only.
35 
36     7     6/09/01 5:25p Shiki
37     Fixed to load .rel files from lower arena to support 48MB ORCA.
38 
39     6     01/04/02 13:44:00 Shiki
40     Separated OSModuleInfo into OSModuleInfo and OSModuleHeader.
41 
42     5     01/03/01 12:55 Shiki
43     Clean up.
44 
45     4     01/02/27 13:11 Shiki
46     Modified to load string table with non-debug build as well.
47 
48     3     10/31/00 3:51p Shiki
49     Modified to call OSUnlink().
50 
51     2     6/14/01 11:37a Shiki
52     Added a call to unlinked function to test.
53 
54     1     4/14/00 11:37p Shiki
55     Initial check-in.
56   $NoKeywords: $
57  *---------------------------------------------------------------------------*/
58 
59 #include <revolution.h>
60 #include "inline.h"
61 
62 #ifdef _DEBUG
63 #define MODULE_A     "/aD.rel"
64 #define MODULE_B     "/bD.rel"
65 #define STRING_TABLE "/staticD.str"
66 #else
67 #define MODULE_A     "/a.rel"
68 #define MODULE_B     "/b.rel"
69 #define STRING_TABLE "/static.str"
70 #endif
71 
72 __declspec(section ".sdata")  int SDVar;
73 __declspec(section ".sdata2") int SD2Var;
74 
DumpModuleInfo(OSModuleInfo * moduleInfo)75 static void DumpModuleInfo(OSModuleInfo* moduleInfo)
76 {
77     OSReport("id                %d\n",         moduleInfo->id);
78     OSReport("numSections       %d\n",         moduleInfo->numSections);
79     OSReport("sectionInfoOffset %08xh\n",      moduleInfo->sectionInfoOffset);
80     OSReport("nameOffset        %08xh [%s]\n", moduleInfo->nameOffset, moduleInfo->nameOffset);
81     OSReport("nameSize          %d\n",         moduleInfo->nameSize);
82     OSReport("version           %d\n",         moduleInfo->version);
83     OSReport("\n");
84 }
85 
DumpModuleHeader(OSModuleHeader * module)86 static void DumpModuleHeader(OSModuleHeader* module)
87 {
88     DumpModuleInfo(&module->info);
89     OSReport("bssSize           %d\n",         module->bssSize);
90     OSReport("relOffset         %08xh\n",      module->relOffset);
91     OSReport("impOffset         %08xh\n",      module->impOffset);
92     OSReport("impSize           %08xh\n",      module->impSize);
93     OSReport("prolog            %08xh\n",      module->prolog);
94     OSReport("epilog            %08xh\n",      module->epilog);
95     OSReport("unresolved        %08xh\n",      module->unresolved);
96     if (2 <= module->info.version)
97     {
98         OSReport("align             %08xh\n",      module->align);
99         OSReport("bssAlign          %08xh\n",      module->bssAlign);
100     }
101     if (3 <= module->info.version)
102     {
103         OSReport("fixSize           %08xh\n",      module->fixSize);
104     }
105     OSReport("\n");
106 }
107 
108 // Load and link the specified module
Load(char * moduleName)109 static OSModuleHeader* Load(char* moduleName)
110 {
111     DVDFileInfo     fileInfo;
112     s32             length;
113     BOOL            result;
114     OSModuleHeader* module;
115     u8*             bss;
116 
117     result = DVDOpen(moduleName, &fileInfo);
118     if (!result)
119         return NULL;
120     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
121     module = OSAllocFromArenaLo((u32) length, 32);
122     result = DVDRead(&fileInfo, module, length, 0);
123     if (!result)
124         return NULL;
125     DVDClose(&fileInfo);
126 
127     if (3 <= module->info.version)
128     {
129         bss = (u8*) module + module->fixSize;
130         bss = (u8*) OSRoundUp32B(bss);
131         if (bss + module->bssSize < OSGetArenaLo())
132         {
133             OSSetArenaLo((void*) OSRoundUp32B(bss + module->bssSize));
134         }
135         else
136         {
137             OSAllocFromArenaLo(module->bssSize - ((u8*) OSGetArenaLo() - bss), 32);
138         }
139         OSLinkFixed(&module->info, bss);
140     }
141     else
142     {
143         bss = OSAllocFromArenaLo(module->bssSize, 32); // alloc bss area
144         OSLink(&module->info, bss);
145     }
146     DumpModuleHeader(module);
147     return module;
148 }
149 
main(void)150 int main(void)
151 {
152     BOOL            result;
153     DVDFileInfo     fileInfo;
154     u32             length;
155     OSModuleHeader* moduleA;
156     OSModuleHeader* moduleB;
157     void*           ptr;
158 
159     // Generate weak symbol 'InlineFunc'
160     InlineFunc(1, 2);
161 
162     DVDInit();
163 
164     // Load string table to use debugger
165     result = DVDOpen(STRING_TABLE, &fileInfo);
166     if (!result)
167         return 1;
168     length = OSRoundUp32B(DVDGetLength(&fileInfo));
169     ptr = OSAllocFromArenaLo(length, 32);
170     result = DVDRead(&fileInfo, ptr, (s32) length, 0);
171     if (!result)
172         return 1;
173     OSSetStringTable(ptr);
174 
175     OSReport("SDVar(%p) %d  SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var);
176 
177     // Load and link module A
178     OSReport("Linking module A...\n");
179     moduleA = Load(MODULE_A);
180     if (!moduleA)
181         return 1;
182     ((u32 (*)(void)) moduleA->prolog)();
183 
184     // Load and link module B
185     OSReport("Linking module B...\n");
186     moduleB = Load(MODULE_B);
187     if (!moduleB)
188         return 1;
189     ((u32 (*)(void)) moduleB->prolog)();
190 
191     // Unlink module B
192     OSReport("Unlinking module B...\n");
193     ((u32 (*)(void)) moduleB->epilog)();
194     OSUnlink(&moduleB->info);
195 
196     // Unlink module A
197     OSReport("Unlinking module A...\n");
198     ((u32 (*)(void)) moduleA->epilog)();
199     OSUnlink(&moduleA->info);
200 
201     OSReport("SDVar(%p) %d  SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var);
202 
203     return 0;
204 }
205