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