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 API</h1>
12
13<h2>Introduction</h2>
14<p>
15The RSO Library is a relocatable module system.<BR><BR> It can use main memory efficiently by dynamically reading and deallocating program modules in the game application.<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>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.&nbsp;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> Import information is used to reference external elements, and export information allows referencing by external elements.<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 a dynamic module will be the result of adding <CODE>FORCEFILES</CODE> and <CODE>FORCEACTIVE</CODE> to the <CODE>&lt;revolution/eppc.$(PLATFORM).lcf&gt;</CODE> file. <CODE>FORCEFILES</CODE> includes the target files, and <CODE>FORCEACTIVE</CODE> includes the <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
47<H3>2. Create a dynamic module file from the partially linked ELF files.</H3>
48<p>
49Run 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.
50</p>
51<TABLE border="1" width="95%">
52  <TBODY>
53    <TR>
54      <TD width="100%">
55      <PRE><CODE>
56% makerso.exe a.plf -a</CODE></PRE>
57      </TD>
58    </TR>
59  </TBODY>
60</TABLE>
61
62<H3>3. Create a static module linker command file and symbol list from all dynamic module files.</H3>
63<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;revolution/eppc.$(PLATFORM).lcf&gt;</CODE> file.<br>
64</p>
65<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>.
66</p>
67<TABLE border="1" width="95%">
68  <TBODY>
69    <TR>
70      <TD width="100%">
71      <PRE><CODE>
72% makelcf.exe -o static.lcf -s symbol.lst -t eppc.RVL.lcf a.rso b.rso
73</CODE></PRE>
74      </TD>
75    </TR>
76  </TBODY>
77</TABLE>
78<H3>4. Build the program static modules.</H3>
79<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.
80</p>
81</p>
82<H3>5. Generate static module information from the static ELF file.</H3>
83<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.
84</p>
85<p>
86The following shows how to generate a static module information as a <CODE>static.sel</CODE> file.
87</p>
88<TABLE border="1" width="95%">
89  <TBODY>
90    <TR>
91      <TD width="100%">
92      <PRE><CODE>
93% makerso.exe static.elf -e symbol.lst
94</CODE></PRE>
95      </TD>
96    </TR>
97  </TBODY>
98</TABLE>
99
100</p>
101
102<h2>Using Dynamic Modules</h2>
103<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.
104</p>
105<H3>1. Loading Individual Modules</H3>
106<p>The following is an example of loading modules.
107</p>
108<TABLE border="1" width="95%">
109  <TBODY>
110    <TR>
111      <TD width="100%">
112      <PRE><CODE>
113DVDFileInfo     fileInfo;
114s32             length;
115RSOObjectHeader* module;
116
117DVDOpen(&quot;a.rso&quot;, &amp;fileInfo);
118length = (s32) OSRoundUp32B(DVDGetLength(&amp;fileInfo));
119module = OSAllocFromArenaLo((u32) length, 32);
120DVDRead(&amp;fileInfo, module, length, 0);
121DVDClose(&amp;fileInfo);</CODE></PRE>
122      </TD>
123    </TR>
124  </TBODY>
125</TABLE>
126<H3>2. Initializing the Linked List</H3>
127<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.
128</p>
129<TABLE border="1" width="95%">
130  <TBODY>
131    <TR>
132      <TD width="100%">
133      <PRE><CODE>
134RSOListInit(staticModule);</CODE></PRE>
135      </TD>
136    </TR>
137  </TBODY>
138</TABLE>
139<H3>3. Registering the Dynamic Module to the Linked List</H3>
140<p>
141Use <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).
142</p>
143<TABLE border="1" width="95%">
144  <TBODY>
145    <TR>
146      <TD width="100%">
147      <PRE><CODE>
148void *bss;
149// Allocate BSS region
150bss = OSAllocFromArenaLo(module-&gt;bssSize, 32);
151RSOLinkList(module, bss);
152((u32 (*)(void)) module-&gt;prolog)();</CODE></PRE>
153      </TD>
154    </TR>
155  </TBODY>
156</TABLE>
157<H3>4. Removing the Dynamic Module from the Linked List</H3>
158<p>
159If 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).
160</p>
161<TABLE border="1" width="95%">
162  <TBODY>
163    <TR>
164      <TD width="100%">
165      <PRE><CODE>
166((void (*)(void)) module-&gt;epilog)();
167RSOUnLinkList(module);</CODE></PRE>
168      </TD>
169    </TR>
170  </TBODY>
171</TABLE>
172
173<h2>Partial Memory Deallocation of Relocatable Modules</h2>
174<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.&nbsp;<br>
175</p>
176<p>
177The following is an example of partial deallocation of module memory and its reuse as a BSS region.
178</p>
179<TABLE border="1" width="95%">
180  <TBODY>
181    <TR>
182      <TD width="100%">
183      <PRE><CODE>
184int             fixed_level     // deallocation stage
185RSOObjectHeader* module;        // Target dynamic module
186u32             fixed_size;
187u32             new_arenaLo;
188u32             old_arenaLo;
189
190//
191fixed_size = RSOGetFixedSize(module,fixed_level);
192//
193bss = (u8 *)((u32)module + fixed_size);
194// 32 byte alignment
195bss = (u8*) OSRoundUp32B(bss);
196
197new_arenaLo = ((u32)bss + (u32)module-&gt;bssSize);
198new_arenaLo = OSRoundUp32B(new_arenaLo);
199old_arenaLo = (u32)OSGetMEM1ArenaLo();
200//
201if (module-&gt;bssSize &gt; 0) {
202    if(old_arenaLo &lt; new_arenaLo) {
203        // If the region is to increase, increase before RSOLocateObjectFixed
204        OSSetMEM1ArenaLo((void*)new_arenaLo);
205    }
206} else {
207    bss = NULL;
208}
209// Link process
210RSOLinkListFixed(module,bss,i_fixed_level);
211// If the region is to decrease, decrease after RSOLocateObjectFixed
212if(bss == NULL || old_arenaLo &gt; new_arenaLo) {
213    OSSetMEM1ArenaLo((void*)new_arenaLo);
214}</CODE></PRE>
215      </TD>
216    </TR>
217  </TBODY>
218</TABLE>
219
220<h2>Required Alignment Conditions for Relocatable Modules</h2>
221<p>
222Dynamic 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.
223</p>
224<h2>Accessing a Dynamic Module's Functions and Variables from the Static Module</h2>
225<p>
226To 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>
227</p>
228<p>
229The 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>
230</p>
231<TABLE border="1" width="95%">
232  <TBODY>
233    <TR>
234      <TD width="100%">
235      <PRE><CODE>
236int (*foo)(int);
237int *g_int;
238
239foo = (int (*)(int)) RSOFindExportSymbolAddr(module,&quot;foo&quot;);
240g_int = (int *)RSOFindExportSymbolAddr(module,&quot;g_int&quot;);
241
242*g_int += foo(3);
243</CODE></PRE>
244      </TD>
245    </TR>
246  </TBODY>
247</TABLE>
248<h2>Notes</h2>
249<p>
250
251</p>
252<h2>Note: Using C++ Global Constructors in Dynamic Modules</h2>
253<p>
254If 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.
255</p>
256<TABLE border="1" width="95%">
257  <TBODY>
258    <TR>
259      <TD width="100%">
260      <PRE><CODE>#ifdef __cplusplus
261extern &quot;C&quot; {
262#endif
263
264typedef void (*voidfunctionptr) (void); /* ptr to function returning void */
265__declspec(section &quot;.init&quot;) extern voidfunctionptr _ctors[];
266__declspec(section &quot;.init&quot;) extern voidfunctionptr _dtors[];
267
268void _prolog(void);
269void _epilog(void);
270void _unresolved(void);
271
272#ifdef __cplusplus
273}
274#endif
275
276void _prolog(void)
277{
278    voidfunctionptr *constructor;
279
280    /*
281     *  call static initializers
282     */
283    for (constructor = _ctors; *constructor; constructor++) {
284        (*constructor)();
285    }
286}
287
288void _epilog(void)
289{
290    voidfunctionptr *destructor;
291
292    /*
293     *  call destructors
294     */
295    for (destructor = _dtors; *destructor; destructor++) {
296        (*destructor)();
297    }
298}</CODE></PRE>
299      </TD>
300    </TR>
301  </TBODY>
302</TABLE>
303<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>
304
305<h2>Note: Use caution when placing a dynamic module in external main memory (the MEM2 region)</h2>
306<p>
307Typically, branch instructions (<CODE>bx</CODE>) have only a 28-bit offset (&plusmn;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>
308</p>
309<H3>1. Using Pragma</H3>
310<p>
311Indicate 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>.
312</p>
313<TABLE border="1" width="95%">
314  <TBODY>
315    <TR>
316      <TD width="100%">
317      <PRE><CODE>
318#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=far_abs
319#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=far_abs
320
321void foo(void);
322
323#pragma section code_type &quot;.text&quot; data_mode=far_abs code_mode=pc_rel
324#pragma section RX &quot;.init&quot; &quot;.init&quot; data_mode=far_abs code_mode=pc_rel
325</CODE></PRE>
326      </TD>
327    </TR>
328  </TBODY>
329</TABLE>
330<p>
331<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>
332</p>
333<TABLE border="1" width="95%">
334  <TBODY>
335    <TR>
336      <TD width="100%">
337      <PRE><CODE>
338// Tentatively set &quot;<CODE>use_lmw_stmw</CODE>&quot; to <CODE>ON</CODE>.
339#pragma use_lmw_stmw on
340</CODE></PRE>
341      </TD>
342    </TR>
343  </TBODY>
344</TABLE>
345<H3>2. Using RSOLinkFar</H3>
346<p>
347Because 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. The required buffer size is obtained using <code><a href="./RSOGetFarCodeSize.html">RSOGetFarCodeSize</a></code> and then allocated. It is then linked using <code><a href="./RSOLinkFar.html">RSOLinkFar</a></code>.
348</p>
349<TABLE border="1" width="95%">
350  <TBODY>
351    <TR>
352      <TD width="100%">
353      <PRE><CODE>
354static u32* LinkFar(RSOObjectHeader *i_rsoImp,RSOObjectHeader *i_rsoExp)
355{
356    int a_size = RSOGetFarCodeSize(i_rsoImp,i_rsoExp);
357    u32 *a_buff;
358
359    //
360    if(a_size == 0) {
361        // not needed
362        return NULL;
363    }
364    //
365    a_buff = OSAllocFromArenaLo((u32)a_size,4);
366    //
367    RSOLinkFar(i_rsoImp,i_rsoExp,a_buff);
368    return a_buff;
369}
370</CODE></PRE>
371      </TD>
372    </TR>
373  </TBODY>
374</TABLE>
375<p>
376<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.
377</p>
378
379<H3>3. Using RSOLinkJump</H3>
380<p>
381<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>
382
383</p>
384<TABLE border="1" width="95%">
385  <TBODY>
386    <TR>
387      <TD width="100%">
388      <PRE><CODE>
389static u32 *MakeJumpCode(RSOObjectHeader *i_rsoExp)
390{
391    int a_size = RSOGetJumpCodeSize(i_rsoExp);
392    u32 *a_buff;
393
394    //
395    if(a_size == 0) {
396        // not needed
397        return NULL;
398    }
399    //
400    a_buff = OSAllocFromArenaLo((u32)a_size,4);
401    //
402    RSOMakeJumpCode(i_rsoExp,a_buff);
403    return a_buff;
404}
405</CODE></PRE>
406      </TD>
407    </TR>
408  </TBODY>
409</TABLE>
410<p>
411Link with the created buffer and <code><a href="./RSOLinkJump.html">RSOLinkJump</a></code>.
412</p>
413<TABLE border="1" width="95%">
414  <TBODY>
415    <TR>
416      <TD width="100%">
417      <PRE><CODE>
418{
419    u32 *buff = MakeJumpCode(rsoExp);
420    RSOLinkJump(rsoImp,rsoExp,buff);
421}
422</CODE></PRE>
423      </TD>
424    </TR>
425  </TBODY>
426</TABLE>
427
428<H2>Revision History</H2>
429<p>
4302006/12/19 Added a description for <code>RSOLinkJump</code>.<br>2006/10/25 Added a description for <code>RSOLinkFar</code>.<br> 2006/06/14 Initial version.<br>
431</p>
432
433<hr><p>CONFIDENTIAL</p></body>
434</html>
435