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