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