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