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