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