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