1 /*---------------------------------------------------------------------------*
2 Project: Dolphin OS relocatable module demo
3 File: static.c
4
5 Copyright 2000-2002 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 $Log: static.c,v $
14 Revision 1.4 2007/05/30 16:56:07 dante.treglia
15 Fixed casting (long) -> (unsigned long) warning
16
17 Revision 1.3 2007/03/20 20:58:37 dante.treglia
18 Added a check to ensure we allocate memory for 'bss' that is aligned to module->bssAlign.
19
20 Revision 1.2 2006/02/20 04:13:12 mitu
21 changed include path from dolphin/ to revolution/.
22
23 Revision 1.1 2006/01/26 08:01:00 hiratsu
24 Relocatable module demo.
25
26
27 12 4/09/04 11:43 Shiki
28 Added check code for sdata and sdata2.
29
30 11 9/25/02 20:16 Shiki
31 Added call to OSLinkFixed().
32
33 10 8/23/02 17:43 Shiki
34 Added call to InlineFunc().
35
36 9 5/13/02 9:22 Shiki
37 Added more OSReport()s to see program behavior more clearly.
38
39 8 11/27/01 21:49 Shiki
40 Modified to include <dolphin.h> only.
41
42 7 6/09/01 5:25p Shiki
43 Fixed to load .rel files from lower arena to support 48MB ORCA.
44
45 6 01/04/02 13:44 Shiki
46 Separated OSModuleInfo into OSModuleInfo and OSModuleHeader.
47
48 5 01/03/01 12:55 Shiki
49 Clean up.
50
51 4 01/02/27 13:11 Shiki
52 Modified to load string table with non-debug build as well.
53
54 3 10/31/00 3:51p Shiki
55 Modified to call OSUnlink().
56
57 2 4/19/00 12:47a Shiki
58 Added a call to unlinked function to test.
59
60 1 4/14/00 11:37p Shiki
61 Initial check-in.
62 $NoKeywords: $
63 *---------------------------------------------------------------------------*/
64
65 #include <revolution.h>
66 #include "inline.h"
67
68 #ifdef _DEBUG
69 #define MODULE_A "/aD.rel"
70 #define MODULE_B "/bD.rel"
71 #define STRING_TABLE "/staticD.str"
72 #else
73 #define MODULE_A "/a.rel"
74 #define MODULE_B "/b.rel"
75 #define STRING_TABLE "/static.str"
76 #endif
77
78 __declspec(section ".sdata") int SDVar;
79 __declspec(section ".sdata2") int SD2Var;
80
DumpModuleInfo(OSModuleInfo * moduleInfo)81 static void DumpModuleInfo(OSModuleInfo* moduleInfo)
82 {
83 OSReport("id %d\n", moduleInfo->id);
84 OSReport("numSections %d\n", moduleInfo->numSections);
85 OSReport("sectionInfoOffset %08xh\n", moduleInfo->sectionInfoOffset);
86 OSReport("nameOffset %08xh [%s]\n", moduleInfo->nameOffset, moduleInfo->nameOffset);
87 OSReport("nameSize %d\n", moduleInfo->nameSize);
88 OSReport("version %d\n", moduleInfo->version);
89 OSReport("\n");
90 }
91
DumpModuleHeader(OSModuleHeader * module)92 static void DumpModuleHeader(OSModuleHeader* module)
93 {
94 DumpModuleInfo(&module->info);
95 OSReport("bssSize %d\n", module->bssSize);
96 OSReport("relOffset %08xh\n", module->relOffset);
97 OSReport("impOffset %08xh\n", module->impOffset);
98 OSReport("impSize %08xh\n", module->impSize);
99 OSReport("prolog %08xh\n", module->prolog);
100 OSReport("epilog %08xh\n", module->epilog);
101 OSReport("unresolved %08xh\n", module->unresolved);
102 if (2 <= module->info.version)
103 {
104 OSReport("align %08xh\n", module->align);
105 OSReport("bssAlign %08xh\n", module->bssAlign);
106 }
107 if (3 <= module->info.version)
108 {
109 OSReport("fixSize %08xh\n", module->fixSize);
110 }
111 OSReport("\n");
112 }
113
114 // Load and link the specified module
Load(char * moduleName)115 static OSModuleHeader* Load(char* moduleName)
116 {
117 DVDFileInfo fileInfo;
118 s32 length;
119 BOOL result;
120 OSModuleHeader* module;
121 u8* bss;
122 u32 bssAddress;
123
124 result = DVDOpen(moduleName, &fileInfo);
125 if (!result)
126 return NULL;
127 length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
128 module = OSAllocFromArenaLo((u32) length, 32);
129 result = DVDRead(&fileInfo, module, length, 0);
130 if (!result)
131 return NULL;
132 DVDClose(&fileInfo);
133
134 if (3 <= module->info.version)
135 {
136 bss = (u8*) module + module->fixSize;
137
138 // Make sure that we allocate memory for 'bss' that is aligned to
139 // module->bssAlign. In other words, the address of 'bss'
140 // must be a multiple of module->bssAlign.
141 bssAddress = (u32) bss;
142 if ( bssAddress % module->bssAlign != 0)
143 {
144 bssAddress = (bssAddress & (~(module->bssAlign - 1))) +
145 module->bssAlign;
146 bss = (u8*)bssAddress;
147 }
148 if (bss + module->bssSize < OSGetArenaLo())
149 {
150 OSSetArenaLo((void*) OSRoundUp32B(bss + module->bssSize));
151 }
152 else
153 {
154 OSAllocFromArenaLo(module->bssSize - ((u8*) OSGetArenaLo() - bss),
155 module->bssAlign);
156 }
157 OSLinkFixed(&module->info, bss);
158 }
159 else
160 {
161 bss = OSAllocFromArenaLo(module->bssSize, 32); // alloc bss area
162 OSLink(&module->info, bss);
163 }
164 DumpModuleHeader(module);
165 return module;
166 }
167
main(void)168 int main(void)
169 {
170 BOOL result;
171 DVDFileInfo fileInfo;
172 u32 length;
173 OSModuleHeader* moduleA;
174 OSModuleHeader* moduleB;
175 void* ptr;
176
177 // Generate weak symbol 'InlineFunc'
178 InlineFunc(1, 2);
179
180 DVDInit();
181
182 // Load string table to use debugger
183 result = DVDOpen(STRING_TABLE, &fileInfo);
184 if (!result)
185 return 1;
186 length = OSRoundUp32B(DVDGetLength(&fileInfo));
187 ptr = OSAllocFromArenaLo(length, 32);
188 result = DVDRead(&fileInfo, ptr, (s32) length, 0);
189 if (!result)
190 return 1;
191 OSSetStringTable(ptr);
192
193 OSReport("SDVar(%p) %d SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var);
194
195 // Load and link module A
196 OSReport("Linking module A...\n");
197 moduleA = Load(MODULE_A);
198 if (!moduleA)
199 return 1;
200 ((u32 (*)(void)) moduleA->prolog)();
201
202 // Load and link module B
203 OSReport("Linking module B...\n");
204 moduleB = Load(MODULE_B);
205 if (!moduleB)
206 return 1;
207 ((u32 (*)(void)) moduleB->prolog)();
208
209 // Unlink module B
210 OSReport("Unlinking module B...\n");
211 ((u32 (*)(void)) moduleB->epilog)();
212 OSUnlink(&moduleB->info);
213
214 // Unlink module A
215 OSReport("Unlinking module A...\n");
216 ((u32 (*)(void)) moduleA->epilog)();
217 OSUnlink(&moduleA->info);
218
219 OSReport("SDVar(%p) %d SD2Var(%p) %d\n", &SDVar, SDVar, &SD2Var, SD2Var);
220
221 return 0;
222 }
223