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 2008/06/13 04:43:42 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_E     "/eD.rso"
25 #define MODULE_F     "/fD.rso"
26 #define STATIC_RSO   "/staticD.sel"
27 #else
28 #define MODULE_E     "/e.rso"
29 #define MODULE_F     "/f.rso"
30 #define STATIC_RSO   "/static.sel"
31 #endif
32 
33 //
34 void _unresolved();
35 
36 /*---------------------------------------------------------------------------*
37    Load
38  *---------------------------------------------------------------------------*/
39 // Load and link the specified module
RsoLoad(char * moduleName)40 static RSOObjectHeader* RsoLoad(char* moduleName)
41 {
42     DVDFileInfo     fileInfo;
43     s32             length;
44     BOOL            result;
45     RSOObjectHeader* module;
46     u8*             bss;
47 
48     result = DVDOpen(moduleName, &fileInfo);
49     if (!result)
50         return NULL;
51     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
52     module = OSAllocFromArenaLo((u32) length, 32);
53     result = DVDRead(&fileInfo, module, length, 0);
54     if (!result)
55         return NULL;
56     DVDClose(&fileInfo);
57 
58     if (module->bssSize > 0)
59     {
60         bss = OSAllocFromArenaLo(module->bssSize, 32); // Alloc bss area
61     }
62     RSOLinkList(module, bss);
63 
64     return module;
65 }
66 
67 //
RsoLoadMem2(char * moduleName)68 static RSOObjectHeader* RsoLoadMem2(char* moduleName)
69 {
70     DVDFileInfo     fileInfo;
71     s32             length;
72     BOOL            result;
73     RSOObjectHeader* module;
74     u8*             bss;
75 
76     result = DVDOpen(moduleName, &fileInfo);
77     if (!result)
78         return NULL;
79     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
80     module = OSAllocFromMEM2ArenaLo((u32) length, 32);
81     result = DVDRead(&fileInfo, module, length, 0);
82     if (!result)
83         return NULL;
84     DVDClose(&fileInfo);
85 
86     if (module->bssSize > 0)
87     {
88         bss = OSAllocFromMEM2ArenaLo(module->bssSize, 32); // Alloc bss area
89     }
90     RSOLinkList(module, bss);
91 
92     return module;
93 }
94 
95 // Load and link the static module
StaticRsoLoad(char * moduleName)96 static RSOObjectHeader* StaticRsoLoad(char* moduleName)
97 {
98     DVDFileInfo     fileInfo;
99     s32             length;
100     BOOL            result;
101     RSOObjectHeader* module;
102 
103     result = DVDOpen(moduleName, &fileInfo);
104     if (!result)
105         return NULL;
106     length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
107     module = OSAllocFromArenaLo((u32) length, 32);
108     result = DVDRead(&fileInfo, module, length, 0);
109     if (!result)
110         return NULL;
111     DVDClose(&fileInfo);
112 
113     RSOListInit(module);
114 
115     return module;
116 }
117 
118 //
_unresolved()119 void _unresolved()
120 {
121     OSReport("_unresolved func.\n");
122 }
123 
124 
125 // Functions and variables we want to access
126 void (*MainE)();
127 void (*IsEThere)();
128 int  (*g_intE);
129 
130 //
131 static RSOExportFuncTable exp_tbl[] =
132 {
133     {"MainE",   (u32 *)&MainE},
134     {"IsEThere",(u32 *)&IsEThere},
135     {"g_intE",  (u32 *)&g_intE},
136 };
137 //
RSOResolvedModuleE(const RSOObjectHeader * module)138 static void RSOResolvedModuleE(const RSOObjectHeader* module)
139 {
140     int i;
141     for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
142         *(exp_tbl[i].symbol_ptr) =
143             (u32)RSOFindExportSymbolAddr(module, exp_tbl[i].symbol_name);
144 
145     }
146 }
147 
148 //
RSOUnresolvedModuleE(void)149 static void RSOUnresolvedModuleE(void)
150 {
151     int i;
152     for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
153         *(exp_tbl[i].symbol_ptr) = (u32)_unresolved;
154     }
155 }
156 
157 //Main
main(void)158 int main(void)
159 {
160     RSOObjectHeader* staticRso;
161     RSOObjectHeader* moduleE;
162     RSOObjectHeader* moduleF;
163 
164     OSEnableCodeExecOnMEM2Lo8MB();
165 
166     // Generate weak symbol 'InlineFunc'
167     DVDInit();
168 
169     //Read
170     // Load static rso file
171     OSReport("Loading static rso...\n");
172     staticRso = StaticRsoLoad(STATIC_RSO);
173     if (!staticRso)
174         return 1;
175 
176     // Load and link module E
177     OSReport("Linking module E...\n");
178     moduleE = RsoLoadMem2(MODULE_E);
179     if (!moduleE) {
180         return 1;
181     }
182 
183     // Load and link module F
184     OSReport("Linking module F...\n");
185     moduleF = RsoLoad(MODULE_F);
186     if (!moduleF) {
187         return 1;
188     }
189 
190     //Check whether everything has been resolved
191     if (RSOIsImportSymbolResolvedAll(moduleE))
192     {
193         OSReport("moduleE's ImportSymbol is resolved all.\n");
194     }
195     if (RSOIsImportSymbolResolvedAll(moduleF))
196     {
197         OSReport("moduleF's ImportSymbol is resolved all.\n");
198     }
199     //
200     OSReport("\nE prolog()\n");
201     ((u32 (*)(void)) moduleE->prolog)();
202     RSOResolvedModuleE(moduleE);
203     //
204     OSReport("\nF prolog()\n");
205     ((u32 (*)(void)) moduleF->prolog)();
206     //
207     MainE();
208     *g_intE += 5;
209     MainE();
210 
211     //
212     OSReport("\nE epilog()\n");
213     ((u32 (*)(void)) moduleE->epilog)();
214     RSOUnresolvedModuleE();
215     //
216     OSReport("\nF epilog()\n");
217     ((u32 (*)(void)) moduleF->epilog)();
218     //
219     RSOUnLinkList(moduleE);
220     RSOUnLinkList(moduleF);
221     //
222     OSReport("\nRSOLink finish all!\n");
223 
224     return 0;
225 }
226