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