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