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