1 /*---------------------------------------------------------------------------*
2 Project: rsodemo
3 File: static.c
4
5 Copyright 2006 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 @version $Id: static.c,v 1.3 2008/06/13 04:43:51 mitu Exp $
14
15 $NoKeywords: $
16 *---------------------------------------------------------------------------*/
17
18 #include <revolution.h>
19
20 #include <revolution/rso.h>
21
22
23 #ifdef _DEBUG
24 #define MODULE_A "/aD.rso"
25 #define MODULE_B "/bD.rso"
26 #define MODULE_C "/cD.rso"
27 #define STATIC_RSO "/staticD.sel"
28 #else
29 #define MODULE_A "/a.rso"
30 #define MODULE_B "/b.rso"
31 #define MODULE_C "/c.rso"
32 #define STATIC_RSO "/static.sel"
33 #endif
34
35 //
36 void _unresolved();
37
38 /*---------------------------------------------------------------------------*
39 Load
40 *---------------------------------------------------------------------------*/
41 // Load and link the specified module
RsoLoad(char * moduleName)42 static RSOObjectHeader* RsoLoad(char* moduleName)
43 {
44 DVDFileInfo fileInfo;
45 s32 length;
46 BOOL result;
47 RSOObjectHeader* module;
48 u8* bss;
49
50 result = DVDOpen(moduleName, &fileInfo);
51 if (!result)
52 return NULL;
53 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
54 module = OSAllocFromArenaLo((u32) length, 32);
55 result = DVDRead(&fileInfo, module, length, 0);
56 if (!result)
57 return NULL;
58 DVDClose(&fileInfo);
59
60 if (module->bssSize > 0)
61 {
62 bss = OSAllocFromArenaLo(module->bssSize, 32); // Alloc bss area
63 }
64 //
65 // Perform internal reference processing.
66 RSOLocateObject(&module->info, bss);
67
68 return module;
69 }
70
71 // Load and link the static module
StaticRsoLoad(char * moduleName)72 static RSOObjectHeader* StaticRsoLoad(char* moduleName)
73 {
74 DVDFileInfo fileInfo;
75 s32 length;
76 BOOL result;
77 RSOObjectHeader* module;
78
79 result = DVDOpen(moduleName, &fileInfo);
80 if (!result)
81 return NULL;
82 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
83 module = OSAllocFromArenaLo((u32) length, 32);
84 result = DVDRead(&fileInfo, module, length, 0);
85 if (!result)
86 return NULL;
87 DVDClose(&fileInfo);
88
89 // Perform internal processing.
90 RSOStaticLocateObject(module);
91
92 return module;
93 }
94
95 //
_unresolved()96 void _unresolved()
97 {
98 OSReport("_unresolved func.\n");
99 }
100
101
102 // Functions and variables we want to access
103 void (*MainA)();
104 void (*IsAThere)();
105 int (*g_intA);
106
107 static RSOExportFuncTable exp_tbl[] =
108 {
109 {"MainA", (u32 *)&MainA},
110 {"IsAThere",(u32 *)&IsAThere},
111 {"g_intA", (u32 *)&g_intA},
112 };
113
114 //
RSOResolvedModuleA(const RSOObjectHeader * module)115 static void RSOResolvedModuleA(const RSOObjectHeader* module)
116 {
117 int i;
118 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
119 *(exp_tbl[i].symbol_ptr) =
120 (u32)RSOFindExportSymbolAddr(module, exp_tbl[i].symbol_name);
121 }
122 }
123
124 //
RSOUnresolvedModuleA(void)125 static void RSOUnresolvedModuleA(void)
126 {
127 int i;
128 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
129 *(exp_tbl[i].symbol_ptr) = (u32)_unresolved;
130 }
131 }
132
133
134 //
135 // Functions and variables we want to access
136 void (*MainC)();
137
138 static RSOExportFuncTable exp_tblC[] =
139 {
140 {"MainC", (u32 *)&MainC},
141 };
142 //
RSOResolvedModuleC(const RSOObjectHeader * module)143 static void RSOResolvedModuleC(const RSOObjectHeader* module)
144 {
145 int i;
146 for(i = 0; i < sizeof(exp_tblC)/sizeof(RSOExportFuncTable); i++) {
147 *(exp_tblC[i].symbol_ptr) =
148 (u32)RSOFindExportSymbolAddr(module, exp_tblC[i].symbol_name);
149 }
150 }
151 //
RSOUnresolvedModuleC(void)152 static void RSOUnresolvedModuleC(void)
153 {
154 int i;
155 for(i = 0; i < sizeof(exp_tblC)/sizeof(RSOExportFuncTable); i++) {
156 *(exp_tblC[i].symbol_ptr) = (u32)_unresolved;
157 }
158 }
159
160
161 //Main
main(void)162 int main(void)
163 {
164 RSOObjectHeader* staticRso;
165 RSOObjectHeader* moduleA;
166 RSOObjectHeader* moduleB;
167 RSOObjectHeader* moduleC;
168 int resolved;
169 // Generate weak symbol 'InlineFunc'
170 DVDInit();
171
172 //Read
173 // Load static rso file
174 OSReport("Loading static rso...\n");
175 staticRso = StaticRsoLoad(STATIC_RSO);
176 if (!staticRso)
177 return 1;
178
179 // Load and link module A
180 OSReport("Linking module A...\n");
181 moduleA = RsoLoad(MODULE_A);
182 if (!moduleA) {
183 return 1;
184 }
185
186 // Load and link module B
187 OSReport("Linking module B...\n");
188 moduleB = RsoLoad(MODULE_B);
189 if (!moduleB) {
190 return 1;
191 }
192
193 // Load and link module C
194 OSReport("Linking module C...\n");
195 moduleC = RsoLoad(MODULE_C);
196 if (!moduleC) {
197 return 1;
198 }
199
200 //Check whether all are resolved (unresolved at this point)
201 if (RSOIsImportSymbolResolvedAll(moduleA))
202 {
203 OSReport("moduleA's ImportSymbol is resolved all.\n");
204 }
205 if (RSOIsImportSymbolResolvedAll(moduleB))
206 {
207 OSReport("moduleB's ImportSymbol is resolved all.\n");
208 }
209 if (RSOIsImportSymbolResolvedAll(moduleC))
210 {
211 OSReport("moduleC's ImportSymbol is resolved all.\n");
212 }
213
214 // Resolve
215 // Reference to static module
216 // Module A references a static module
217 resolved = RSOLink(moduleA, staticRso);
218 OSReport("A,S resolved %d\n", resolved);
219 // Module B references a static module
220 resolved = RSOLink(moduleB, staticRso);
221 OSReport("B,S resolved %d\n", resolved);
222 // Module C references a static module
223 resolved = RSOLink(moduleC, staticRso);
224 OSReport("C,S resolved %d\n", resolved);
225
226 // Reference to Module A
227 // Module B references Module A
228 resolved = RSOLink(moduleB, moduleA);
229 OSReport("B,A resolved %d\n", resolved);
230
231 // Reference to Module B
232 // Module A references Module B
233 resolved = RSOLink(moduleA, moduleB);
234 OSReport("A,B resolved %d\n", resolved);
235
236 //Check whether all symbols are resolved (they should be resolved)
237 if (RSOIsImportSymbolResolvedAll(moduleA))
238 {
239 OSReport("moduleA's ImportSymbol is resolved all.\n");
240 }
241 if (RSOIsImportSymbolResolvedAll(moduleB))
242 {
243 OSReport("moduleB's ImportSymbol is resolved all.\n");
244 }
245 if (RSOIsImportSymbolResolvedAll(moduleC))
246 {
247 OSReport("moduleC's ImportSymbol is resolved all.\n");
248 }
249
250 //
251 OSReport("\nA prolog()\n");
252 ((u32 (*)(void)) moduleA->prolog)();
253 OSReport("\nB prolog()\n");
254 ((u32 (*)(void)) moduleB->prolog)();
255 OSReport("\nC prolog()\n");
256 ((u32 (*)(void)) moduleC->prolog)();
257
258 //
259 RSOResolvedModuleA(moduleA);
260 //
261 OSReport("MainA = %x\n",MainA);
262 OSReport("g_intA = %x\n",g_intA);
263
264 MainA();
265 OSReport("g_intA = %d\n", *g_intA);
266 *g_intA += 5;
267 OSReport("g_intA + 5 = %d\n", *g_intA);
268 MainA();
269
270 //
271 RSOResolvedModuleC(moduleC);
272 //
273 MainC();
274
275 //
276 OSReport("\nA epilog()\n");
277 ((u32 (*)(void)) moduleA->epilog)();
278 RSOUnresolvedModuleA();
279 //
280 OSReport("\nB epilog()\n");
281 ((u32 (*)(void)) moduleB->epilog)();
282
283 // Release all links associated with A before executing RSOUnLocateObject on Module A
284 RSOUnLink(moduleA, staticRso);
285 RSOUnLink(moduleA, moduleB);
286 RSOUnLink(moduleB, moduleA);
287 RSOUnLocateObject(moduleA);
288
289 // Do the same with Module B
290 RSOUnLink(moduleB, staticRso);
291 RSOUnLocateObject(moduleB);
292
293 // Module C
294 OSReport("\nC epilog()\n");
295 ((u32 (*)(void)) moduleC->epilog)();
296 RSOUnresolvedModuleC();
297 //
298 RSOUnLink(moduleC, staticRso);
299
300
301 return 0;
302 }
303