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