1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
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 API</h1>
12
13<h2>Introduction</h2>
14<p>
15The RSO Library is a relocatable module system.<BR><BR><BR> It can use main memory efficiently by dynamically reading and deallocating program modules in the game application.<BR><BR> In this library, unlike the dynamic link library of other operating systems, the game application is responsible for main memory allocation and deallocation and loading modules from the disk.<BR><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 (relocatable) modules can call functions and refer to the variables defined in static modules. In addition, dynamic modules can call functions and refer to variables in other dynamic modules loaded into main memory. Referencing across modules is resolved by directly revising the code and data sections of a module when it is loaded.<BR><BR> Functions and variables of the dynamic (relocatable) 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 (PLF). A PLF file contains unresolved external symbols and debug information. The <CODE><a href="./tools/makerso.html">makerso</a></CODE> tool, provided with the Revolution SDK, will convert a PLF file into a dynamic module file used exclusively by the Wii console. 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, and export information allows referencing by external elements.<BR><BR>
16
17<h2>Differences from REL</h2>
18<H3>Advantages</H3>
19<UL>
20<LI>The dynamic module functions and variables can be accessed from the static module by specifying symbol names.
21<LI>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.)
22<LI>The user can specify links.
23</UL>
24<H3>Drawbacks</H3>
25<UL>
26<LI>Because the module includes symbol information, it is larger than REL. (By approximately the same number of bytes as the character count.)
27<LI>The user must manage access to dynamic modules from static modules.
28<LI>Because dynamic modules can be accessed from static modules, it is harder to delete code by optimizing compilation.
29<LI>Because resolution is done using symbol names, more processing is required for linking than with REL.
30</UL>
31<H3>Procedural Differences</H3>
32<UL>
33<LI>The static module information (the <CODE>.sel</CODE> file) is required for initializing the link list.
34</UL>
35
36<h2>Making Relocatable Modules</h2>
37<p>
38<H3>1. Create the partially linked ELF files.</H3>
39<P>The RSO library uses the static linker <B>partial link</B> option. Each dynamic (relocatable) 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>
40<P>Three functions can be defined for a dynamic module: <CODE>_prolog</CODE>, <CODE>_epilog</CODE>, and <CODE>_unresolved</CODE>. <CODE>_prolog</CODE> and <CODE>_epilog</CODE> can be called from static modules or from other dynamic modules loaded in main memory. <CODE>_unresolved</CODE> is automatically called when the module makes a function call to an external function that has not been linked into the main memory.</P>
41<p>The linker command file for the dynamic modules consists of the <CODE>&lt;dolphin/eppc.lcf&gt;</CODE> file with <CODE>FORCEFILES</CODE> and <CODE>FORCEACTIVE</CODE> added to it. <CODE>FORCEFILES</CODE> includes the target files, and <CODE>FORCEACTIVE</CODE> includes <CODE>__global_destructor_chain</CODE>.
42</p>
43<p>In the sample this file is output in <CODE>.plf</CODE> format.
44</p>
45<P><STRONG><EM>Note: </EM></STRONG> A relocatable module cannot have a small data section. The small data section base registers (r2 and r13) are reserved for the static module. To prevent the compiler from generating small data sections, specify the compiler options <CODE>-sdata 0 -sdata2 0</CODE> when compiling the relocatable modules.</P>
46<P>The RSO file is large when it is made from a PLF file with debugging information. If you want a smaller file size make the RSO file from a PLF file with no debugging information (for example, built using <CODE>NDEBUG</CODE>).</P>
47
48<H3>2. Create a dynamic module file from the partially linked ELF files.</H3>
49<p>
50Run 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.
51</p>
52<TABLE border="1" width="95%">
53  <TBODY>
54    <TR>
55      <TD width="100%">
56      <PRE><CODE>
57% makerso.exe a.plf -a</CODE></PRE>
58      </TD>
59    </TR>
60  </TBODY>
61</TABLE>
62
63<H3>3. Create a static module linker command file and symbol list from all dynamic module files.</H3>
64<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 adding the <CODE>FORCEACTIVE</CODE> list to the <CODE>&lt;dolphin/eppc.lcf&gt;</CODE> file.<br>
65</p>
66<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>.
67</p>
68<TABLE border="1" width="95%">
69  <TBODY>
70    <TR>
71      <TD width="100%">
72      <PRE><CODE>
73% makelcf.exe -o static.lcf -s symbol.lst -t eppc.lcf a.rso b.rso
74</CODE></PRE>
75      </TD>
76    </TR>
77  </TBODY>
78</TABLE>
79<H3>4. Build the program static modules.</H3>
80<p>Link the static modules of the program with the linker command file generated in the previous section. Link all static libraries to the static module.
81</p>
82</p>
83<H3>5. Generate static module information from the static ELF file.</H3>
84<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.
85</p>
86<p>
87The following shows how to generate a static module information as a <CODE>static.sel</CODE> file.
88</p>
89<TABLE border="1" width="95%">
90  <TBODY>
91    <TR>
92      <TD width="100%">
93      <PRE><CODE>
94% makerso.exe static.elf -e symbol.lst
95</CODE></PRE>
96      </TD>
97    </TR>
98  </TBODY>
99</TABLE>
100
101</p>
102
103<h2>Using Dynamic Modules</h2>
104<p><B>Note:</B> The game application performs memory allocation and deallocation for loading dynamic modules and loading dynamic modules from game discs.<br>The dynamic module loaded into main memory has type <code>RSOObjectHeader</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.
105</p>
106<H3>1. Loading Individual Modules</H3>
107<p>The following is an example of loading modules.
108</p>
109<TABLE border="1" width="95%">
110  <TBODY>
111    <TR>
112      <TD width="100%">
113      <PRE><CODE>
114DVDFileInfo     fileInfo;
115s32             length;
116RSOObjectHeader* module;
117
118DVDOpen(&quot;a.rso&quot;, &fileInfo);
119length = (s32) OSRoundUp32B(DVDGetLength(&fileInfo));
120module = OSAllocFromArenaLo((u32) length, 32);
121DVDRead(&fileInfo, module, length, 0);
122DVDClose(&fileInfo);</CODE></PRE>
123      </TD>
124    </TR>
125  </TBODY>
126</TABLE>
127<H3>2. Initializing the Linked List</H3>
128<p>Use <code><a href="./RSOListInit.html">RSOListInit</a></code> to initialize the linked list.<br>Static module information is set at this time.<br>The static module information is used to obtain the address of a function or variable inside the static module when it is referenced by a dynamic module.
129</p>
130<TABLE border="1" width="95%">
131  <TBODY>
132    <TR>
133      <TD width="100%">
134      <PRE><CODE>
135RSOListInit(staticModule);</CODE></PRE>
136      </TD>
137    </TR>
138  </TBODY>
139</TABLE>
140<H3>3. Registering the Dynamic Module to the Linked List</H3>
141<p>
142Use <code><a href="./RSOLinkList.html">RSOLinkList</a></code> to link the dynamic module.<br>The <code><I>bss</I></code> argument is a pointer to the section used as a BSS section (a section initialized with 0s). It is allocated and specified by the programmer.<br>The required BSS section size is given by <CODE>RSOObjectHeader.bssSize</CODE>.<br>After linking a module, the game is given the choice to call the <code>prolog</code> function (a member variable of the <code>RSOObjectHeader</code> structure).
143</p>
144<TABLE border="1" width="95%">
145  <TBODY>
146    <TR>
147      <TD width="100%">
148      <PRE><CODE>
149void *bss;
150// Allocate BSS region
151bss = OSAllocFromArenaLo(module-&gt;bssSize, 32);
152RSOLinkList(module, bss);
153((u32 (*)(void)) module-&gt;prolog)();</CODE></PRE>
154      </TD>
155    </TR>
156  </TBODY>
157</TABLE>
158<H3>4. Removing the Dynamic Module from the Linked List</H3>
159<p>
160If the loaded module becomes unnecessary, call <code><a href="./RSOUnLinkList.html">RSOUnLinkList</a></code> to free the memory space for another purpose.<br>Immediately before unlinking a module, the game is given the choice to call the <code>epilog</code> function (a member variable of the <code>RSOObjectHeader</code> structure).
161</p>
162<TABLE border="1" width="95%">
163  <TBODY>
164    <TR>
165      <TD width="100%">
166      <PRE><CODE>
167((void (*)(void)) module-&gt;epilog)();
168RSOUnLinkList(module);</CODE></PRE>
169      </TD>
170    </TR>
171  </TBODY>
172</TABLE>
173
174<h2>Partial Memory Deallocation of Relocatable Modules</h2>
175<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 the <code><a href="./RSOLinkList.html">RSOLinkListFixed</a></code> function, the memory space that comes after (specified by <code><a href="./RSOGetFixedSize.html">RSOGetFixedSize</a></code>) can be used for any purpose (for example, for the BSS 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. <br>
176</p>
177<p>
178The following is an example of partial deallocation of module memory and its reuse as a BSS region.
179</p>
180<TABLE border="1" width="95%">
181  <TBODY>
182    <TR>
183      <TD width="100%">
184      <PRE><CODE>
185int             fixed_level     // deallocation stage
186RSOObjectHeader* module;        // Target dynamic module
187u32             fixed_size;
188u32             new_arenaLo;
189u32             old_arenaLo;
190
191//
192fixed_size = RSOGetFixedSize(module,fixed_level);
193//
194bss = (u8 *)((u32)module + fixed_size);
195// 32 byte alignment
196bss = (u8*) OSRoundUp32B(bss);
197
198new_arenaLo = ((u32)bss + (u32)module-&gt;bssSize);
199new_arenaLo = OSRoundUp32B(new_arenaLo);
200old_arenaLo = (u32)OSGetMEM1ArenaLo();
201//
202if (module-&gt;bssSize &gt; 0) {
203    if(old_arenaLo &lt; new_arenaLo) {
204        // If the region is to increase, increase before RSOLocateObjectFixed
205        OSSetMEM1ArenaLo((void*)new_arenaLo);
206    }
207} else {
208    bss = NULL;
209}
210// Link process
211RSOLinkListFixed(module,bss,i_fixed_level);
212// If the region is to decrease, decrease after RSOLocateObjectFixed
213if(bss == NULL || old_arenaLo &gt; new_arenaLo) {
214    OSSetMEM1ArenaLo((void*)new_arenaLo);
215}</CODE></PRE>
216      </TD>
217    </TR>
218  </TBODY>
219</TABLE>
220
221<h2>Required Alignment Conditions for Relocatable Modules</h2>
222<p>
223Dynamic 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.
224</p>
225<h2>Accessing a Dynamic Module's Functions and Variables from the Static Module</h2>
226<p>
227To 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>
228</p>
229<p>
230The 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>
231</p>
232<TABLE border="1" width="95%">
233  <TBODY>
234    <TR>
235      <TD width="100%">
236      <PRE><CODE>
237int (*foo)(int);
238int *g_int;
239
240foo = (int (*)(int)) RSOFindExportSymbolAddr(module,&quot;foo&quot;);
241g_int = (int *)RSOFindExportSymbolAddr(module,&quot;g_int&quot;);
242
243*g_int += foo(3);
244</CODE></PRE>
245      </TD>
246    </TR>
247  </TBODY>
248</TABLE>
249<h2>Notes</h2>
250<p>
251
252</p>
253<h2>Note: Using C++ Global Constructors in Dynamic Modules</h2>
254<p>
255If using C++ global constructors in relocatable modules, you must manually call global constructors and destructors from the module <code>_prolog</code> and <code>_epilog</code>, Code examples for each case follow below.
256</p>
257<TABLE border="1" width="95%">
258  <TBODY>
259    <TR>
260      <TD width="100%">
261      <PRE><CODE>#ifdef __cplusplus
262extern &quot;C&quot; {
263#endif
264
265typedef void (*voidfunctionptr) (void); /* ptr to function returning void */
266__declspec(section &quot;.init&quot;) extern voidfunctionptr _ctors[];
267__declspec(section &quot;.init&quot;) extern voidfunctionptr _dtors[];
268
269void _prolog(void);
270void _epilog(void);
271void _unresolved(void);
272
273#ifdef __cplusplus
274}
275#endif
276
277void _prolog(void)
278{
279    voidfunctionptr *constructor;
280
281    /*
282     *  call static initializers
283     */
284    for (constructor = _ctors; *constructor; constructor++) {
285        (*constructor)();
286    }
287}
288
289void _epilog(void)
290{
291    voidfunctionptr *destructor;
292
293    /*
294     *  call destructors
295     */
296    for (destructor = _dtors; *destructor; destructor++) {
297        (*destructor)();
298    }
299}</CODE></PRE>
300      </TD>
301    </TR>
302  </TBODY>
303</TABLE>
304<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 <STRONG>static</STRONG> module, and if no static module exists, destructors are never called. <B>Note:</B> Since <CODE>Runtime.PPCEABI.H.a</CODE> uses small data sections and contains unnecessary functions, dynamic modules cannot be linked to it.</P>
305
306<h2>Note: Use caution when placing a dynamic module in external main memory (the MEM2 region)</h2>
307<p>
308Typically, branch instructions (<CODE>bx</CODE>) have only a 28-bit offset (±32 MB). Therefore, when a relocatable module is placed in external main memory (<CODE>MEM2</CODE>), it cannot access functions or variables in internal main memory (<CODE>MEM1</CODE>).<br>Avoid this issue 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>
309</p>
310<H3>1. Using Pragma</H3>
311<p>
312Indicate to the compiler that the module needs to be branched in a 32-bit absolute address, using <CODE>pragma</CODE>.<BR>An example is given of branching the <CODE>foo</CODE> function (located in <CODE>MEM1</CODE>) to an absolute address. This applies whether the target function is in a static module or a dynamic (relocatable) module.<BR>Also take similar precautions when calling functions in <CODE>MEM2</CODE> from a dynamic module in <CODE>MEM1</CODE>.
313</p>
314<TABLE border="1" width="95%">
315  <TBODY>
316    <TR>
317      <TD width="100%">
318      <PRE><CODE>
319#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=far_abs
320#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=far_abs
321
322void foo(void);
323
324#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=pc_rel
325#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=pc_rel
326</CODE></PRE>
327      </TD>
328    </TR>
329  </TBODY>
330</TABLE>
331<p>
332<B>Note</B> as of 2006/06/15:<br>Certain run-time codes may not be properly called in 32-bit codes in the release version.<br>As a temporary workaround, use the <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>The compile option &quot;<code>-use_lmw_stmw on</code>&quot; may also be used for the same effect.<br>
333</p>
334<TABLE border="1" width="95%">
335  <TBODY>
336    <TR>
337      <TD width="100%">
338      <PRE><CODE>
339// Tentatively set &quot;<CODE>use_lmw_stmw</CODE>&quot; to <CODE>ON</CODE>.
340#pragma use_lmw_stmw on
341</CODE></PRE>
342      </TD>
343    </TR>
344  </TBODY>
345</TABLE>
346<H3>2. Using RSOLinkFar</H3>
347<p>
348Because 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><I>buff</I></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 that region is allocated and linked using <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code>.
349</p>
350<TABLE border="1" width="95%">
351  <TBODY>
352    <TR>
353      <TD width="100%">
354      <PRE><CODE>
355static u32 *LinkFar(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp)
356{
357    int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp);
358    u32 *a_buff;
359
360    //
361    if(a_size == 0) {
362        // not needed
363        return NULL;
364    }
365    //
366    a_buff = OSAllocFromArenaLo((u32)a_size,4);
367    //
368    RSOLinkFar(i_rsoImp,i_rsoExp,a_buff);
369    return a_buff;
370}
371</CODE></PRE>
372      </TD>
373    </TR>
374  </TBODY>
375</TABLE>
376<p>
377<B>Note:</B> Allocate the buffer from the same main memory (<CODE>MEM2</CODE> or <CODE>MEM1</CODE>) as the module being linked (<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.
378</p>
379
380<H3>3. Using RSOLinkJump</H3>
381<p>
382<code><a href="./RSOLinkJump.html">RSOLinkJump</a></code> creates a relay code to the module being referenced. The referencing side then uses it to link.<br>To create a relay code, use <code><a href="./RSOGetJumpCodeSize.html">RSOGetJumpCodeSize</a></code> to obtain the necessary buffer size, and then use <code><a href="./RSOMakeJumpCode.html">RSOMakeJumpCode</a></code> to create the relay code.<br>
383
384</p>
385<TABLE border="1" width="95%">
386  <TBODY>
387    <TR>
388      <TD width="100%">
389      <PRE><CODE>
390static u32 *MakeJumpCode(RSOObjectHeader *i_rsoExp)
391{
392    int a_size = RSOGetJumpCodeSize(i_rsoExp);
393    u32 *a_buff;
394
395    //
396    if(a_size == 0) {
397        // not needed
398        return NULL;
399    }
400    //
401    a_buff = OSAllocFromArenaLo((u32)a_size,4);
402    //
403    RSOMakeJumpCode(i_rsoExp,a_buff);
404    return a_buff;
405}
406</CODE></PRE>
407      </TD>
408    </TR>
409  </TBODY>
410</TABLE>
411<p>
412Link with the created buffer and <code><a href="./RSOLinkJump.html">RSOLinkJump</a></code>.
413</p>
414<TABLE border="1" width="95%">
415  <TBODY>
416    <TR>
417      <TD width="100%">
418      <PRE><CODE>
419{
420    u32 *buff = MakeJumpCode(rsoExp);
421    RSOLinkJump(rsoImp,rsoExp,buff);
422}
423</CODE></PRE>
424      </TD>
425    </TR>
426  </TBODY>
427</TABLE>
428
429<H2>Revision History</H2>
430<p>
4312009/10/13 Revised the name of the LCF file used for partial linking.<br> 2009/07/21 Explained the relationship between RSO and PLF file sizes. <br> 2006/12/19 Explained <code>RSOLinkJump</code>.<br>2006/10/25 Added a description for <code>RSOLinkFar</code>.<br>2006/06/14 Initial version.<br>
432</p>
433
434<hr><p>CONFIDENTIAL</p></body>
435</html>
436