1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
4<LINK rel="stylesheet" type="text/css" href="../CSS/revolution.css">
5<base target="main">
6<title>RSO Function Introduction</title>
7</head>
8
9<body>
10
11<h1>RSO Function Description</h1>
12
13<h2>Introduction</h2>
14<p>
15The RSO Library is a dynamic module system.<BR><BR> It uses main memory efficiently by dynamically reading and releasing the program module in the game application.<BR> Unlike the dynamic link libraries of other operating systems, with this library the game application is responsible for allocating and deallocating main memory and loading modules from discs.<BR> <BR>The RSO library consists of one static module (the <CODE>.elf</CODE> file), one static information module (the <CODE>.sel</CODE> file), and multiple dynamic (that is, relocatable) modules (the <CODE>.rso</CODE> files). After the boot ROM loads the static module of the program, the static module controls the memory location of the dynamic module. The static module is built as a normal <CODE> .elf</CODE> file. The static module contains common functions and common variables referenced by the dynamic modules.<BR><BR>Dynamic modules can call functions and refer to the variables defined in static modules.&nbsp;In addition, dynamic modules can call functions and refer to variables in other dynamic modules loaded into main memory. Referencing among modules can be resolved by directly editing the code and data sections when the module is loaded.<BR><BR> Functions and variables of the dynamic module can be accessed by specifying the symbol name from the static module.<BR> Accordingly, the program must be aware of the dynamic modules that it uses, unlike when calling functions within static modules.<BR> <BR>A dynamic module (RSO) application is written in the same manner as the main C/C++ code, except that the dynamic module is built from a partially-linked <CODE>.elf</CODE> file (<CODE>PLF</CODE>). A <CODE>PLF</CODE> file contains unresolved external symbols and debug information. The <CODE>.plf</CODE> file is then converted to a Wii-specific dynamic module format by using the <CODE>makerso</CODE> tool provided in the Revolution SDK. These Wii-specific dynamic modules include, in addition to the standard application code and data section, a relocation instruction list, import information, and export information.<BR><BR><BR> Import information is used to reference external elements, while export information allows referencing by external elements.<BR><BR>
16
17<h2>Differences from REL</h2>
18<H3>Advantages</H3>
19<p>
20- The dynamic module functions and variables can be accessed from the static module by specifying symbol names.<br>- As long as there are <CODE>.rso</CODE> files, the library can run, even if all the dynamic module <CODE>.plf </CODE>files have not been prepared first. (For example, you can run RSO files that have been pre-stored in NAND memory or other areas and update dynamic modules through downloading, etc.)<br> - The user can specify the links.<br>
21</p>
22<H3>Drawbacks</H3>
23<p>
24- Modules include symbol information, so they are larger than REL files (by about the character count in bytes).<br>- The user must manage access to dynamic modules from static modules.<br>- Since dynamic modules can be accessed from static modules, it is hard to eliminate code by optimizing compilation.<br>- Since resolution is done using symbol names, more processing is required for linking than with REL.<br>
25</p>
26<H3>Procedural Differences</H3>
27<p>
28- The static module information (the <CODE>.sel</CODE> file) is required for initializing the link list.
29</p>
30
31<h2>Making Dynamic Modules</h2>
32<p>
33<H3>1.&nbsp;&nbsp;&nbsp; Create the partially linked <CODE>.elf</CODE> files.</H3>
34<P>The RSO library uses the static linker <B>partial link</B> option. Each dynamic module is made from a separate set of partially linked files. Using the partial link option (<CODE>-r</CODE>), the linker can create an <CODE>.elf</CODE> file that includes unresolved external reference symbols. The unresolved symbols of the dynamic module are resolved when the application is run.</P>
35<P>Three functions can be defined for a dynamic module: <code>_prolog</code>, <code>_epilog</code>, and <code>_unresolved</code>.&nbsp;The <code>_prolog</code> and <code>_epilog</code> functions can be called from the static module or from the other dynamic modules loaded into main memory.&nbsp;The <code>_unresolved</code> function is called when the module makes a function call to an external function that is not yet loaded into main memory.</P>
36<p>The linker command file for the dynamic module is the sum of the <CODE>&lt;revolution/eppc.$(PLATFORM)&gt;</CODE> file with <CODE>FORCEFILES</CODE> and <CODE>FORCEACTIVE</CODE>. <CODE>FORCEFILES</CODE> includes the target files, and <CODE>FORCEACTIVE</CODE> includes the <CODE>__global_destructor_chain</CODE>.
37</p>
38<p>The sample is output in <CODE>.plf</CODE> format.
39</p>
40<P><strong>Note:</strong>The dynamic module must not have small data sections. Small data section anchor registers (<code>r2</code> and <code>r13</code>) are reserved for the static portion of the program. To prevent the compiler from generating small data sections, use the <code>-sdata 0 -sdata2 0</code> compiler option when compiling a dynamic module.</P>
41
42<H3>2.   Create a dynamic module file from the partially linked <CODE>.elf</CODE> files.</H3>
43<p>
44Run the <CODE><a href="./tools/makerso.html">makerso</a></CODE> tool to create a dynamic module file (<code>.rso</code>) from a partially linked <CODE>.plf</CODE> file.
45</p>
46<TABLE border="1" width="100%">
47  <TBODY>
48    <TR>
49      <TD width="100%">
50      <PRE><CODE>
51% makerso.exe a.plf -a</CODE></PRE>
52      </TD>
53    </TR>
54  </TBODY>
55</TABLE>
56
57<H3>3.   Create a static module linker command file and symbol list from all dynamic module files.</H3>
58<p>Run the <CODE><a href="./tools/makelcf.html">makelcf</a></CODE> tool to create a static module linker command file and symbol list from all dynamic module files.<br>The linker command file is generated by attaching the <CODE>FORCEACTIVE</CODE> list to the <code>&lt;Revolution/eppc.$(PLATFORM).lcf&gt;</code> file.&nbsp;<br>
59</p>
60<p>The following shows how to generate a static module linker command file as <CODE>static.lcf</CODE> and a symbol list as <CODE>symbol.lst</CODE>.
61</p>
62<TABLE border="1" width="100%">
63  <TBODY>
64    <TR>
65      <TD width="100%">
66      <PRE><CODE>
67% makelcf.exe -o static.lcf -s symbol.lst -t eppc.RVL.lcf a.rso b.rso
68</CODE></PRE>
69      </TD>
70    </TR>
71  </TBODY>
72</TABLE>
73<H3>4.&nbsp;&nbsp;&nbsp; Build the program static modules.</H3>
74<p>Link the static modules of the program with the linker command file generated in the previous section. All the static libraries should be linked with the static module.
75</p>
76</p>
77<H3>5.   Generate static module information from the static <CODE>.elf</CODE> file.</H3>
78<p>Use the <CODE><a href="./tools/makerso.html">makerso</a></CODE> tool to create static module information from the static <CODE>.elf</CODE> file and the symbol list generated in section 3.
79</p>
80<p>
81The following shows how to generate a static module information as a <CODE>static.sel</CODE> file.
82</p>
83<TABLE border="1" width="100%">
84  <TBODY>
85    <TR>
86      <TD width="100%">
87      <PRE><CODE>
88% makerso.exe static.elf -e symbol.lst
89</CODE></PRE>
90      </TD>
91    </TR>
92  </TBODY>
93</TABLE>
94
95</p>
96
97<h2>Using Dynamic Modules</h2>
98<p><B>Note:</B> Memory allocation/deallocation for loading dynamic modules and loading dynamic modules from game discs is performed by the game application.<br>The dynamic module loaded into main memory has type <code>RSOObjectHeade</code> data, followed by the module code and data sections.<br>Static module information has the same data structure as dynamic modules, but without the code, the import information, or the internal processing information.
99</p>
100<H3>Loading Individual Modules</H3>
101<p>The following is an example of loading modules:
102</p>
103<TABLE border="1" width="100%">
104  <TBODY>
105    <TR>
106      <TD width="100%">
107      <PRE><CODE>
108DVDFileInfo     fileInfo;
109s32             length;
110RSOObjectHeader* module;
111
112DVDOpen(&quot;a.rso&quot;, &amp;fileInfo);
113length = (s32) OSRoundUp32B(DVDGetLength(&amp;fileInfo));
114module = OSAllocFromArenaLo((u32) length, 32);
115DVDRead(&amp;fileInfo, module, length, 0);
116DVDClose(&amp;fileInfo);</CODE></PRE>
117      </TD>
118    </TR>
119  </TBODY>
120</TABLE>
121<H3>Initializing the Linked List</H3>
122<p>Initialize the linked list, using <code><a href="./RSOListInit.html">RSOListInit</a></code>.<br>Static module information is set at this time.<br>The static module information is used to obtain the function and variable addresses of the static module referenced by the dynamic module.
123</p>
124<TABLE border="1" width="100%">
125  <TBODY>
126    <TR>
127      <TD width="100%">
128      <PRE><CODE>
129RSOListInit(staticModule);</CODE></PRE>
130      </TD>
131    </TR>
132  </TBODY>
133</TABLE>
134<H3>Registering the Dynamic Module to the Linked List</H3>
135<p>
136Link the dynamic module, using <code><a href="./RSOLinkList.html">RSOLinkList</a></code>.<br>The <code>bss</code> argument is a pointer to the section used as a <code>bss</code> section (section initialized by 0), and which the programmer allocates and specifies.<br>The required size for the <code>bss</code> section is defined vy <CODE>RSOObjectHeader.bssSize</CODE>.<br>You must call the <code>prolog</code> function (a member of the <code>RSOObjectHeader</code> structure) after the module is linked (optional).&nbsp;
137</p>
138<TABLE border="1" width="100%">
139  <TBODY>
140    <TR>
141      <TD width="100%">
142      <PRE><CODE>
143void *bss;
144// Allocate BSS section
145bss = OSAllocFromArenaLo(module-&gt;bssSize, 32);
146RSOLinkList(module, bss);
147((u32 (*)(void)) module-&gt;prolog)();</CODE></PRE>
148      </TD>
149    </TR>
150  </TBODY>
151</TABLE>
152<H3>Removing the Dynamic Module from the Linked List</H3>
153<p>
154If the loaded module becomes unnecessary, call <code><a href="./RSOUnLinkList.html">RSOUnLinkList</a></code> to free the memory space for another purpose.<br>You must call the <code>epilog</code> function (a member of the <code>RSOObjectHeader</code> structure) before unlinking the module (optional).
155</p>
156<TABLE border="1" width="100%">
157  <TBODY>
158    <TR>
159      <TD width="100%">
160      <PRE><CODE>
161((void (*)(void)) module-&gt;epilog)();
162RSOUnLinkList(module);</CODE></PRE>
163      </TD>
164    </TR>
165  </TBODY>
166</TABLE>
167
168<h2>Partial Memory Deallocation of the Dynamic Module</h2>
169<p>The <code><a href="./RSOLinkList.html">RSOLinkListFixed</a></code> function links the specified module and deallocates part of the memory occupied by the dynamic module.<br>Once the module is linked using <code><a href="./RSOLinkList.html">RSOLinkListFixed</a></code>, the remaining memory that comes after (specified by <code><a href="./RSOGetFixedSize.html">RSOGetFixedSize</a></code>) can be used for any purpose (for example, for the <CODE>bss</CODE> area).<br>However, several restrictions may apply, depending on the deallocation timing. (See <code><a href="./RSOLinkList.html">RSOLinkListFixed</a></code> for details)<br>Also note that the location specified by <code><a href="./RSOGetFixedSize.html">RSOGetFixedSize</a></code> is converted from the file offset to the virtual address when the module is linked.&nbsp;<br>
170</p>
171<p>
172The following is an example of partial deallocation of module memory and its reuse as a <CODE>bss</CODE> area:
173</p>
174<TABLE border="1" width="100%">
175  <TBODY>
176    <TR>
177      <TD width="100%">
178      <PRE><CODE>
179int             fixed_level     // deallocation stage
180RSOObjectHeader* module;        // Target dynamic module
181u32             fixed_size;
182u32             new_arenaLo;
183u32             old_arenaLo;
184
185//
186fixed_size = RSOGetFixedSize(module,fixed_level);
187//
188bss = (u8 *)((u32)module + fixed_size);
189// 32 byte alignment
190bss = (u8*) OSRoundUp32B(bss);
191
192new_arenaLo = ((u32)bss + (u32)module-&gt;bssSize);
193new_arenaLo = OSRoundUp32B(new_arenaLo);
194old_arenaLo = (u32)OSGetMEM1ArenaLo();
195//
196if (module-&gt;bssSize &gt; 0) {
197if(old_arenaLo &lt; new_arenaLo) {
198// If the area increase, increase before RSOLocateObjectFixed
199        OSSetMEM1ArenaLo((void*)new_arenaLo);
200    }
201} else {
202    bss = NULL;
203}
204// Link process
205RSOLinkListFixed(module,bss,i_fixed_level);
206// If the area decrease, decrease after RSOLocateObjectFixed
207if(bss == NULL || old_arenaLo &gt; new_arenaLo) {
208    OSSetMEM1ArenaLo((void*)new_arenaLo);
209}</CODE></PRE>
210      </TD>
211    </TR>
212  </TBODY>
213</TABLE>
214
215<h2>Required Alignment for Dynamic Modules</h2>
216<p>
217Dynamic modules and <CODE>bss</CODE> sections both have address-alignment constraints. The dynamic module must be aligned at the maximum alignment value required by the <CODE>.init</CODE>, <CODE>.text</CODE>, <CODE>.ctor</CODE>, <CODE>.dtor</CODE>, <CODE>.rodata</CODE>, and <CODE>.data</CODE> sections. A <CODE>bss</CODE> section must be aligned at the maximum alignment value required by the data item within the <CODE>bss</CODE> section. Typically, both dynamic modules and <CODE>bss</CODE> sections require 8-byte alignment.
218</p>
219<h2>Accessing Functions and Variables of Dynamic Module from Static Module</h2>
220<p>
221To access dynamic module functions and variables from the static module, the address is acquired by using <code><a href="./RSOFindExportSymbolAddr.html">RSOFindExportSymbolAddr</a></code> based on the linked module information and label name.<br>
222</p>
223<p>
224The following example acquires and uses the addresses of the <code>int foo(int a);</code> function and the <code>int g_int;</code> variable from the dynamic module.<br>
225</p>
226<TABLE border="1" width="100%">
227  <TBODY>
228    <TR>
229      <TD width="100%">
230      <PRE><CODE>
231int (*foo)(int);
232int *g_int;
233
234foo = (int (*)(int)) RSOFindExportSymbolAddr(module,&quot;foo&quot;);
235g_int = (int *)RSOFindExportSymbolAddr(module,&quot;g_int&quot;);
236
237*g_int += foo(3);
238</CODE></PRE>
239      </TD>
240    </TR>
241  </TBODY>
242</TABLE>
243<h2>Notes</h2>
244<p>
245
246</p>
247<h2>Caution: Using C++ Global Constructors in Dynamic Modules</h2>
248<p>
249If using C++ global constructors in dynamic modules, global constructors and destructors must be called manually from <CODE>_prolog</CODE> and <CODE>_epilog</CODE>, respectively, as shown in the following code:&nbsp;
250</p>
251<TABLE border="1" width="100%">
252  <TBODY>
253    <TR>
254      <TD width="100%">
255      <PRE><CODE>#ifdef __cplusplus
256extern &quot;C&quot; {
257#endif
258
259typedef void (*voidfunctionptr) (void); /* ptr to function returning void */
260__declspec(section &quot;.init&quot;) extern voidfunctionptr _ctors[];
261__declspec(section &quot;.init&quot;) extern voidfunctionptr _dtors[];
262
263void _prolog(void);
264void _epilog(void);
265void _unresolved(void);
266
267#ifdef __cplusplus
268}
269#endif
270
271void _prolog(void)
272{
273    voidfunctionptr *constructor;
274
275    /*
276     *  call static initializers
277     */
278    for (constructor = _ctors; *constructor; constructor++) {
279        (*constructor)();
280    }
281}
282
283void _epilog(void)
284{
285    voidfunctionptr *destructor;
286
287    /*
288     *  call destructors
289     */
290    for (destructor = _dtors; *destructor; destructor++) {
291        (*destructor)();
292    }
293}</CODE></PRE>
294      </TD>
295    </TR>
296  </TBODY>
297</TABLE>
298<P>In addition, make sure that each dynamic module is linked to <code>global_destructor_chain.c</code> (in the <code>$(CWFOLDER)/PowerPC_EABI_Support/Runtime/Src</code> folder). Linking to this file guarantees that each global destructor is called every time the <code>_epilog</code> function of the module is called. Otherwise, module global variables in each module are linked to the global destructor chain in the static module, and unless the static module exists, destructors are never called.Be aware that since <code>Runtime.PPCEABI.H.a</code> uses small data sections and contains unnecessary functions, dynamic modules cannot be linked to it.</P>
299
300<h2>Caution: Use caution when placing a dynamic module in external main memory (the <CODE>MEM2</CODE> region).</h2>
301<p>
302Typically, the branch instructions (<CODE>bx</CODE>) have only the 28-bit offset (&plusmn; 32 MB). Therefore, when a relocatable module is placed in external main memory (<CODE>MEM2</CODE>), functions in internal main memory (<CODE>MEM1</CODE>) cannot be accessed.<br>This issue can be avoided by using <CODE>pragma</CODE>, or by using <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code> and <code><a href="./RSOLinkJump.html">RSOLinkJump</a></code>.<BR>
303</p>
304<H3>Using Pragma</H3>
305<p>
306Indicate to the compiler that the module needs to be branched in a 32-bit absolute address, using <CODE>pragma</CODE>.<BR>For example, the <CODE>MyFunction</CODE> function (located in <CODE>MEM1</CODE>), must be branched in the absolute address. This applies, whether the target function is a static module or a dynamic module.<BR>Also take similar precautions when calling functions in <CODE>MEM2</CODE> from a dynamic module in <CODE>MEM1</CODE>.
307</p>
308<TABLE border="1" width="100%">
309  <TBODY>
310    <TR>
311      <TD width="100%">
312      <PRE><CODE>
313#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=far_abs
314#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=far_abs
315
316void foo(void);
317
318#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=pc_rel
319#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=pc_rel
320</CODE></PRE>
321      </TD>
322    </TR>
323  </TBODY>
324</TABLE>
325<p>
326<B>Note</B> as of 6/15/2006:<br>Certain runtime codes may not be properly called in 32-bit codes in the release version.<br>As a temporary remedy, apply <CODE>use_lmw_stmw pragma</CODE> to avoid using those runtime codes.<br>The <CODE>pragma</CODE> directive should be applied to the source of modules placed in <CODE>MEM2</CODE>.<br>This is also true for the compile option <code>-use_lmw_stmw on</code>.<br>
327</p>
328<TABLE border="1" width="100%">
329  <TBODY>
330    <TR>
331      <TD width="100%">
332      <PRE><CODE>
333// Tentatively set <CODE>use_lmw_stmw</CODE> to <CODE>ON</CODE>.
334#pragma use_lmw_stmw on
335</CODE></PRE>
336      </TD>
337    </TR>
338  </TBODY>
339</TABLE>
340<H3>Using RSOLinkFar</H3>
341<p>
342Because using just the standard <code><a href="./RSOLink.html">RSOLink</a></code> causes this issue, re-link the modules located in main memory (both <CODE>MEM1</CODE> and <CODE>MEM2</CODE>) using <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code>. <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code> places relay jump codes in <code>buff</code>. The linking modules then link to these jump codes to access the referenced modules in <CODE>MEM2</CODE>.<br>In the following example function <code>LinkFar</code>, the linked module (<code>i_rsoImp</code>) and the referenced module (<code>i_rsoEx</code>) are linked using a relay jump code. The return value is a pointer to the allocated buffer. <br>The required buffer size is obtained using <code><a href="./RSOGetFarCodeSize.html">RSOGetFarCodeSize</a></code>, and then allocated. This is then linked using <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code>.
343</p>
344<TABLE border="1" width="100%">
345  <TBODY>
346    <TR>
347      <TD width="100%">
348      <PRE><CODE>
349static void LinkFar(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp)
350{
351    int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp);
352    u32 *a_buff;
353
354    //
355    if(a_size == 0) {
356        // not needed
357        return NULL;
358    }
359    //
360    a_buff = OSAllocFromArenaLo((u32)a_size,4);
361    //
362    RSOLinkFar(i_rsoImp,i_rsoExp,a_buff);
363}
364</CODE></PRE>
365      </TD>
366    </TR>
367  </TBODY>
368</TABLE>
369<p>
370<B>Note:</B> Allocate the buffer from the same main memory (<CODE>MEM2</CODE> or <CODE>MEM1</CODE>) as the linking module (<CODE>i_rsoImp</CODE>).<br>In addition, the code in the module is overwritten normally after linking. Thus, when using <code><a href="./RSOLinkList.html">RSOLinkListFixed</a></code>, proceed to <code><a href="./RSOFixedLevel.html">RSO_FL_INTERNAL</a></code> at the release stage.
371</p>
372
373<H3>Using RSOLinkJump</H3>
374<p>
375<code><a href="./RSOLinkJump.html">RSOLinkJump</a></code> creates a relay code to the module being referenced. The referencing side then uses this to link.<br>To create a relay code, obtain the necessary buffer size, using <code><a href="./RSOGetJumpCodeSize.html">RSOGetJumpCodeSize</a></code>, and then create the relay code, using <code><a href="./RSOMakeJumpCode.html">RSOMakeJumpCode</a></code>.<br>
376
377</p>
378<TABLE border="1" width="100%">
379  <TBODY>
380    <TR>
381      <TD width="100%">
382      <PRE><CODE>
383static u32 *MakeJumpCode(RSOObjectHeader *i_rsoExp)
384{
385    int a_size = RSOGetJumpCodeSize(i_rsoExp);
386    u32 *a_buff;
387
388    //
389    if(a_size == 0) {
390        // not needed
391        return NULL;
392    }
393    //
394    a_buff = OSAllocFromArenaLo((u32)a_size,4);
395    //
396    RSOMakeJumpCode(i_rsoExp,a_buff);
397    return a_buff;
398}
399</CODE></PRE>
400      </TD>
401    </TR>
402  </TBODY>
403</TABLE>
404<p>
405Link with the created buffer and <code><a href="./RSOLinkJump.html">RSOLinkJump</a></code>.
406</p>
407<TABLE border="1" width="100%">
408  <TBODY>
409    <TR>
410      <TD width="100%">
411      <PRE><CODE>
412{
413    u32 *buff = MakeJumpCode(rsoExp);
414    RSOLinkJump(rsoImp,rsoExp,buff);
415}
416</CODE></PRE>
417      </TD>
418    </TR>
419  </TBODY>
420</TABLE>
421<H2>Revision History</H2>
422<p>
42312/19/2006   Added description for <code>RSOLinkJump</code>.<br> 10/25/2006   Added description for <code>RSOLinkFar</code>.<br> 6/14/2006   Initial version.<br>
424</p>
425<HR>
426<P>CONFIDENTIAL</P>
427</BODY>
428</HTML>
429