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