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.12 2006/09/11 06:35:10 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_A "/aD.rso"
26 #define MODULE_B "/bD.rso"
27 #define STATIC_RSO "/staticD.sel"
28 #else
29 #define MODULE_A "/a.rso"
30 #define MODULE_B "/b.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 // Load and link the static module
StaticRsoLoad(char * moduleName)69 static RSOObjectHeader* StaticRsoLoad(char* moduleName)
70 {
71 DVDFileInfo fileInfo;
72 s32 length;
73 BOOL result;
74 RSOObjectHeader* module;
75
76 result = DVDOpen(moduleName, &fileInfo);
77 if (!result)
78 return NULL;
79 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
80 module = OSAllocFromArenaLo((u32) length, 32);
81 result = DVDRead(&fileInfo, module, length, 0);
82 if (!result)
83 return NULL;
84 DVDClose(&fileInfo);
85
86 RSOListInit(module);
87
88 return module;
89 }
90
91 //
_unresolved()92 void _unresolved()
93 {
94 OSReport("_unresolved func.\n");
95 }
96
97
98 // Functions and variables to be accessed
99 void (*MainA)();
100 void (*IsAThere)();
101 int (*g_intA);
102
103 static RSOExportFuncTable exp_tbl[] =
104 {
105 {"MainA", (u32 *)&MainA},
106 {"IsAThere",(u32 *)&IsAThere},
107 {"g_intA", (u32 *)&g_intA},
108 };
109
110 //
RSOResolvedModuleA(const RSOObjectHeader * module)111 static void RSOResolvedModuleA(const RSOObjectHeader* module)
112 {
113 int i;
114 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
115 *(exp_tbl[i].symbol_ptr) =
116 (u32)RSOFindExportSymbolAddr(module, exp_tbl[i].symbol_name);
117 }
118 }
119
120 //
RSOUnresolvedModuleA(void)121 static void RSOUnresolvedModuleA(void)
122 {
123 int i;
124 for(i = 0; i < sizeof(exp_tbl)/sizeof(RSOExportFuncTable); i++) {
125 *(exp_tbl[i].symbol_ptr) = (u32)_unresolved;
126 }
127 }
128
129
130 //main
main(void)131 int main(void)
132 {
133 RSOObjectHeader* staticRso;
134 RSOObjectHeader* moduleA;
135 RSOObjectHeader* moduleB;
136
137 // Generate weak symbol 'InlineFunc'
138 DVDInit();
139
140 // Read data
141 // Load static rso file
142 OSReport("Loading static rso...\n");
143 staticRso = StaticRsoLoad(STATIC_RSO);
144 if (!staticRso)
145 return 1;
146
147 // Load and link module A
148 OSReport("Linking module A...\n");
149 moduleA = RsoLoad(MODULE_A);
150 if (!moduleA) {
151 return 1;
152 }
153
154 // Load and link module B
155 OSReport("Linking module B...\n");
156 moduleB = RsoLoad(MODULE_B);
157 if (!moduleB) {
158 return 1;
159 }
160
161 // Check whether all symbols are resolved
162 if (RSOIsImportSymbolResolvedAll(moduleA))
163 {
164 OSReport("moduleA's ImportSymbol is resolved all.\n");
165 }
166 if (RSOIsImportSymbolResolvedAll(moduleB))
167 {
168 OSReport("moduleB's ImportSymbol is resolved all.\n");
169 }
170
171 // Since A and B are mutually linked, resolve both and then call prolog.
172 OSReport("\nA prolog()\n");
173 ((u32 (*)(void)) moduleA->prolog)();
174 OSReport("\nB prolog()\n");
175 ((u32 (*)(void)) moduleB->prolog)();
176
177 //
178 RSOResolvedModuleA(moduleA);
179 //
180 OSReport("MainA = %x\n",MainA);
181 OSReport("g_intA = %x\n",g_intA);
182
183 MainA();
184 OSReport("g_intA = %d\n", *g_intA);
185 *g_intA += 5;
186 OSReport("g_intA + 5 = %d\n", *g_intA);
187 MainA();
188
189 //
190 OSReport("\nA epilog()\n");
191 ((u32 (*)(void)) moduleA->epilog)();
192 RSOUnresolvedModuleA();
193 //
194 OSReport("\nB epilog()\n");
195 ((u32 (*)(void)) moduleB->epilog)();
196
197 // Since A and B mutually refer to each other, unlink after the epilog for both
198 RSOUnLinkList(moduleA);
199 RSOUnLinkList(moduleB);
200
201 // Check whether MainA is unprocessed
202 OSReport("call MainA()\n");
203 MainA();
204 //
205 OSReport("\nRSOLink finish all!\n");
206
207 return 0;
208 }
209