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