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 2008/06/16 02:47:48 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_G "/gD.rso"
25 #define MODULE_H "/hD.rso"
26 #define STATIC_RSO "/staticD.sel"
27 #else
28 #define MODULE_G "/g.rso"
29 #define MODULE_H "/h.rso"
30 #define STATIC_RSO "/static.sel"
31 #endif
32
33 //
34 void _unresolved();
35
36 /*---------------------------------------------------------------------------*
37 RsoLinkFar
38 *---------------------------------------------------------------------------*/
LinkFar(RSOObjectHeader * i_rsoImp,RSOObjectHeader * i_rsoExp)39 static u32 *LinkFar(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp)
40 {
41 int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp);
42 u32 *a_buff;
43
44 //
45 if(a_size == 0) {
46 // not needed
47 return NULL;
48 }
49 //
50 a_buff = OSAllocFromArenaHi((u32)a_size,4);
51 //
52 if(RSOLinkFar(i_rsoImp,i_rsoExp,a_buff) == -1)
53 {
54 OSHalt("i_rsoImp and a_buff are too away.\n");
55 }
56 //
57 #if 0
58 {
59 int i,j;
60 OSReport("buff = %p\n",a_buff);
61 for(i = 0,j = 0;
62 i < a_size;
63 i+=16,j+=4) {
64 OSReport("%p\n%p\n%p\n%p\n",
65 a_buff[j],a_buff[j+1],a_buff[j+2],a_buff[j+3]);
66 }
67 }
68 #endif
69 //
70 return a_buff;
71 }
LinkFarMem2(RSOObjectHeader * i_rsoImp,RSOObjectHeader * i_rsoExp)72 static u32 *LinkFarMem2(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp)
73 {
74 int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp);
75 u32 *a_buff;
76
77 //
78 if(a_size == 0) {
79 // not needed
80 return NULL;
81 }
82 //
83 a_buff = OSAllocFromMEM2ArenaLo((u32)a_size,4);
84 //
85 if(RSOLinkFar(i_rsoImp,i_rsoExp,a_buff) == -1)
86 {
87 OSHalt("i_rsoImp and a_buff are too away.\n");
88 }
89 //
90 #if 0
91 {
92 int i,j;
93 OSReport("buff = %p\n",a_buff);
94 for(i = 0,j = 0;
95 i < a_size;
96 i+=16,j+=4) {
97 OSReport("%p\n%p\n%p\n%p\n",
98 a_buff[j],a_buff[j+1],a_buff[j+2],a_buff[j+3]);
99 }
100 }
101 #endif
102 //
103 return a_buff;
104 }
105
106 /*---------------------------------------------------------------------------*
107 Load
108 *---------------------------------------------------------------------------*/
109 // Load and link the specified module
RsoLoad(char * moduleName)110 static RSOObjectHeader* RsoLoad(char* moduleName)
111 {
112 DVDFileInfo fileInfo;
113 s32 length;
114 BOOL result;
115 RSOObjectHeader* module;
116 u8* bss;
117
118 result = DVDOpen(moduleName, &fileInfo);
119 if (!result)
120 return NULL;
121 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
122 module = OSAllocFromArenaLo((u32) length, 32);
123 result = DVDRead(&fileInfo, module, length, 0);
124 if (!result)
125 return NULL;
126 DVDClose(&fileInfo);
127
128 if (module->bssSize > 0)
129 {
130 bss = OSAllocFromArenaLo(module->bssSize, 32); // Alloc bss area
131 }
132 RSOLinkList(module, bss);
133
134 return module;
135 }
136
137 //
RsoLoadMem2(char * moduleName)138 static RSOObjectHeader* RsoLoadMem2(char* moduleName)
139 {
140 DVDFileInfo fileInfo;
141 s32 length;
142 BOOL result;
143 RSOObjectHeader* module;
144 u8* bss;
145
146 result = DVDOpen(moduleName, &fileInfo);
147 if (!result)
148 return NULL;
149 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
150 module = OSAllocFromMEM2ArenaLo((u32) length, 32);
151 result = DVDRead(&fileInfo, module, length, 0);
152 if (!result)
153 return NULL;
154 DVDClose(&fileInfo);
155
156 if (module->bssSize > 0)
157 {
158 bss = OSAllocFromMEM2ArenaLo(module->bssSize, 32); // Alloc bss area
159 }
160 RSOLinkList(module, bss);
161
162 return module;
163 }
164
165 // Load and link the static module
StaticRsoLoad(char * moduleName)166 static RSOObjectHeader* StaticRsoLoad(char* moduleName)
167 {
168 DVDFileInfo fileInfo;
169 s32 length;
170 BOOL result;
171 RSOObjectHeader* module;
172
173 result = DVDOpen(moduleName, &fileInfo);
174 if (!result)
175 return NULL;
176 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
177 module = OSAllocFromArenaLo((u32) length, 32);
178 result = DVDRead(&fileInfo, module, length, 0);
179 if (!result)
180 return NULL;
181 DVDClose(&fileInfo);
182
183 RSOListInit(module);
184
185 return module;
186 }
187
188 //
_unresolved()189 void _unresolved()
190 {
191 OSReport("_unresolved func.\n");
192 }
193
194
195 // Functions and variables we want to access
196 void (*MainG)();
197
198 //
199 static RSOExportFuncTable exp_tbl[] =
200 {
201 {"MainG", (u32 *)&MainG},
202 };
203 //
RSOResolvedModuleG(const RSOObjectHeader * module)204 static void RSOResolvedModuleG(const RSOObjectHeader* module)
205 {
206 int i;
207 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
208 *(exp_tbl[i].symbol_ptr) =
209 (u32)RSOFindExportSymbolAddr(module, exp_tbl[i].symbol_name);
210
211 }
212 }
213
214 //
RSOUnresolvedModuleG(void)215 static void RSOUnresolvedModuleG(void)
216 {
217 int i;
218 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
219 *(exp_tbl[i].symbol_ptr) = (u32)_unresolved;
220 }
221 }
222
223 //Main
main(void)224 int main(void)
225 {
226 RSOObjectHeader* staticRso;
227 RSOObjectHeader* moduleG;
228 RSOObjectHeader* moduleH;
229 u32* buff_gh; // Buffer necessary when H is LinkFar-ed to G
230 u32* buff_hg; // Buffer necessary when G is LinkFar-ed to H
231 u32* buff_sg; // Buffer necessary when G is LinkFar-ed to H
232
233 OSEnableCodeExecOnMEM2Lo8MB();
234
235 // Generate weak symbol 'InlineFunc'
236 DVDInit();
237
238 //Read
239 // Load static rso file
240 OSReport("Loading static rso...\n");
241 staticRso = StaticRsoLoad(STATIC_RSO);
242 if (!staticRso)
243 return 1;
244
245 // Load and link module G
246 OSReport("Linking module G...\n");
247 moduleG = RsoLoadMem2(MODULE_G);
248 if (!moduleG) {
249 return 1;
250 }
251
252 // Load and link module H
253 OSReport("Linking module H...\n");
254 moduleH = RsoLoad(MODULE_H);
255 if (!moduleH) {
256 return 1;
257 }
258
259 // When linking from H, get region from MEM1 where H is located
260 buff_gh = LinkFar(moduleH,moduleG);
261 // When linking from G, get region from MEM2 where G is located
262 buff_hg = LinkFarMem2(moduleG,moduleH);
263 buff_sg = LinkFarMem2(moduleG,staticRso);
264
265 //Check whether everything has been resolved
266 if (RSOIsImportSymbolResolvedAll(moduleG))
267 {
268 OSReport("moduleG's ImportSymbol is resolved all.\n");
269 }
270 if (RSOIsImportSymbolResolvedAll(moduleH))
271 {
272 OSReport("moduleH's ImportSymbol is resolved all.\n");
273 }
274 //
275 OSReport("\nG prolog()\n");
276 ((u32 (*)(void)) moduleG->prolog)();
277 RSOResolvedModuleG(moduleG);
278 //
279 OSReport("\nH prolog()\n");
280 ((u32 (*)(void)) moduleH->prolog)();
281 //
282 OSReport("\ncall MainG = %p\n",MainG);
283 //
284 MainG();
285
286 //
287 OSReport("\nG epilog()\n");
288 ((u32 (*)(void)) moduleG->epilog)();
289 RSOUnresolvedModuleG();
290 //
291 OSReport("\nH epilog()\n");
292 ((u32 (*)(void)) moduleH->epilog)();
293 //
294 RSOUnLinkList(moduleG);
295 RSOUnLinkList(moduleH);
296 //
297 OSReport("\nRSOLink finish all!\n");
298 // Release buff_gh and other memory after RSOUnLinkList.
299
300 return 0;
301 }
302
303