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:28 mitu Exp $
14 
15   $NoKeywords: $
16  *---------------------------------------------------------------------------*/
17 
18 #include <revolution.h>
19 
20 #include <revolution/rso.h>
21 
22 
23 #include "static.h"
24 
25 #ifdef _DEBUG
26 #define MODULE_I     "/iD.rso"
27 #define MODULE_J     "/jD.rso"
28 #define STATIC_RSO   "/staticD.sel"
29 #else
30 #define MODULE_I     "/i.rso"
31 #define MODULE_J     "/j.rso"
32 #define STATIC_RSO   "/static.sel"
33 #endif
34 
35 //
36 void _unresolved();
37 
38 /*---------------------------------------------------------------------------*
39    RsoLinkJump
40  *---------------------------------------------------------------------------*/
41 //
makeCodeMem2(RSOObjectHeader * i_rso)42 static u32 *makeCodeMem2(RSOObjectHeader *i_rso)
43 {
44     int a_size = RSOGetJumpCodeSize(i_rso);
45     void *r_buff;
46 
47     if(a_size == 0) return NULL;
48     r_buff = OSAllocFromMEM2ArenaLo((u32)a_size,4);
49 
50     //
51     RSOMakeJumpCode(i_rso,r_buff);
52     //
53     return r_buff;
54 }
55 
56 
57 /*---------------------------------------------------------------------------*
58    Load
59  *---------------------------------------------------------------------------*/
60 // Load and link the specified module
RsoLoad(char * moduleName)61 static RSOObjectHeader* RsoLoad(char* moduleName)
62 {
63     DVDFileInfo     fileInfo;
64     s32             length;
65     BOOL            result;
66     RSOObjectHeader* module;
67     u8*             bss;
68 
69     result = DVDOpen(moduleName, &fileInfo);
70     if (!result)
71         return NULL;
72     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
73     module = OSAllocFromArenaLo((u32) length, 32);
74     result = DVDRead(&fileInfo, module, length, 0);
75     if (!result)
76         return NULL;
77     DVDClose(&fileInfo);
78 
79     if (module->bssSize > 0)
80     {
81         bss = OSAllocFromArenaLo(module->bssSize, 32); // Alloc bss area
82     }
83     RSOLinkList(module, bss);
84 
85     return module;
86 }
87 
88 //
RsoLoadMem2(char * moduleName)89 static RSOObjectHeader* RsoLoadMem2(char* moduleName)
90 {
91     DVDFileInfo     fileInfo;
92     s32             length;
93     BOOL            result;
94     RSOObjectHeader* module;
95     u8*             bss;
96 
97     result = DVDOpen(moduleName, &fileInfo);
98     if (!result)
99         return NULL;
100     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
101     module = OSAllocFromMEM2ArenaLo((u32) length, 32);
102 
103     result = DVDRead(&fileInfo, module, length, 0);
104     if (!result)
105         return NULL;
106     DVDClose(&fileInfo);
107 
108     if (module->bssSize > 0)
109     {
110         bss = OSAllocFromMEM2ArenaLo(module->bssSize, 32); // Alloc bss area
111     }
112     RSOLinkList(module, bss);
113 
114     return module;
115 }
116 
117 // Load and link the static module
StaticRsoLoad(char * moduleName)118 static RSOObjectHeader* StaticRsoLoad(char* moduleName)
119 {
120     DVDFileInfo     fileInfo;
121     s32             length;
122     BOOL            result;
123     RSOObjectHeader* module;
124 
125     result = DVDOpen(moduleName, &fileInfo);
126     if (!result)
127         return NULL;
128     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
129     module = OSAllocFromArenaLo((u32) length, 32);
130     result = DVDRead(&fileInfo, module, length, 0);
131     if (!result)
132         return NULL;
133     DVDClose(&fileInfo);
134 
135     RSOListInit(module);
136 
137     return module;
138 }
139 
140 //
_unresolved()141 void _unresolved()
142 {
143     OSReport("_unresolved func.\n");
144 }
145 
146 
147 // Functions and variables we want to access
148 void (*MainI)();
149 
150 //
151 static RSOExportFuncTable exp_tblI[] =
152 {
153     {"MainI",   (u32 *)&MainI},
154 };
155 //
RSOResolvedModuleI(const RSOObjectHeader * module)156 static void RSOResolvedModuleI(const RSOObjectHeader* module)
157 {
158     int i;
159     for(i = 0; i < sizeof(exp_tblI)/sizeof(RSOExportFuncTable); i++) {
160         *(exp_tblI[i].symbol_ptr) =
161             (u32)RSOFindExportSymbolAddr(module, exp_tblI[i].symbol_name);
162     }
163 }
164 
165 //
RSOUnresolvedModuleI(void)166 static void RSOUnresolvedModuleI(void)
167 {
168     int i;
169     for(i = 0; i < sizeof(exp_tblI)/sizeof(RSOExportFuncTable); i++) {
170         *(exp_tblI[i].symbol_ptr) = (u32)_unresolved;
171     }
172 }
173 // Functions and variables we want to access
174 void (*MainJ)();
175 
176 //
177 static RSOExportFuncTable exp_tblJ[] =
178 {
179     {"MainJ",   (u32 *)&MainJ},
180 };
181 //
RSOResolvedModuleJ(const RSOObjectHeader * module)182 static void RSOResolvedModuleJ(const RSOObjectHeader* module)
183 {
184     int i;
185     for(i = 0; i < sizeof(exp_tblJ)/sizeof(RSOExportFuncTable); i++) {
186         *(exp_tblJ[i].symbol_ptr) =
187             (u32)RSOFindExportSymbolAddr(module, exp_tblJ[i].symbol_name);
188 
189     }
190 }
191 
192 //
RSOUnresolvedModuleJ(void)193 static void RSOUnresolvedModuleJ(void)
194 {
195     int i;
196     for(i = 0; i < sizeof(exp_tblJ)/sizeof(RSOExportFuncTable); i++) {
197         *(exp_tblJ[i].symbol_ptr) = (u32)_unresolved;
198     }
199 }
200 
201 
202 //Main
main(void)203 int main(void)
204 {
205     RSOObjectHeader* staticRso;
206     RSOObjectHeader* moduleI;
207     RSOObjectHeader* moduleJ;
208     u32 *buff_static;
209 
210     OSEnableCodeExecOnMEM2Lo8MB();
211 
212     // Generate weak symbol 'InlineFunc'
213     DVDInit();
214 
215     //Read
216     // Load static rso file
217     OSReport("Loading static rso...\n");
218     staticRso = StaticRsoLoad(STATIC_RSO);
219     if (!staticRso)
220         return 1;
221     // Create relay code
222     buff_static = makeCodeMem2(staticRso);
223 
224     // Load and link module I
225     OSReport("Linking module I...\n");
226     moduleI = RsoLoadMem2(MODULE_I);
227     if (!moduleI) {
228         return 1;
229     }
230 
231     // Load and link module J
232     OSReport("Linking module J...\n");
233     moduleJ = RsoLoadMem2(MODULE_J);
234     if (!moduleJ) {
235         return 1;
236     }
237 
238     // Use relay code to link
239     if(RSOLinkJump(moduleI,staticRso,buff_static) == -1)
240     {
241         OSHalt("moduleI and buff_static are too away.\n");
242     }
243     if(RSOLinkJump(moduleJ,staticRso,buff_static) == -1)
244     {
245         OSHalt("moduleJ and buff_static are too away.\n");
246     }
247 
248     //Check whether everything has been resolved
249     if (RSOIsImportSymbolResolvedAll(moduleI))
250     {
251         OSReport("moduleI's ImportSymbol is resolved all.\n");
252     }
253     if (RSOIsImportSymbolResolvedAll(moduleJ))
254     {
255         OSReport("moduleJ's ImportSymbol is resolved all.\n");
256     }
257     //
258     OSReport("\nI prolog()\n");
259     ((u32 (*)(void)) moduleI->prolog)();
260     RSOResolvedModuleI(moduleI);
261     //
262     OSReport("\nJ prolog()\n");
263     ((u32 (*)(void)) moduleJ->prolog)();
264     RSOResolvedModuleJ(moduleJ);
265     //
266     OSReport("\ncall MainI = %p\n",MainI);
267     MainI();
268     //
269     OSReport("\ncall MainJ = %p\n",MainJ);
270     MainJ();
271 
272     //
273     OSReport("\nI epilog()\n");
274     ((u32 (*)(void)) moduleI->epilog)();
275     RSOUnresolvedModuleI();
276     //
277     OSReport("\nJ epilog()\n");
278     ((u32 (*)(void)) moduleJ->epilog)();
279     RSOUnresolvedModuleJ();
280     //
281     RSOUnLinkList(moduleI);
282     RSOUnLinkList(moduleJ);
283     //
284     OSReport("\nRSOLink finish all!\n");
285     // Release buff_static memory only after RSOUnLinkList.
286 
287     return 0;
288 }
289 
staticFuncA(void)290 extern void staticFuncA(void)
291 {
292     OSReport("\nstaticFuncA!\n");
293 }
294 
staticFuncB(void)295 extern void staticFuncB(void)
296 {
297     OSReport("\nstaticFuncB!\n");
298 }
299 
staticFuncC(void)300 extern void staticFuncC(void)
301 {
302     OSReport("\nstaticFuncC!\n");
303 }
304 
305