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