Open main menu

Difference between revisions of "HOWTO-Dynamic Modules"

2,708 bytes added ,  07:23, 16 August 2010
Filled out the "making the plugin linker script for your backend"
(Added rough, initial HOWTO for implementing dynamic modules on a smaller target)
 
(Filled out the "making the plugin linker script for your backend")
Line 3: Line 3:
=== Introduction ===
=== Introduction ===


This page is meant as a mini-HOWTO which roughly outlines the steps needed to implement dynamic engine plugins for a previously unsupported backend (port) of ScummVM. This HOWTO only applies to targets that can use the ELF file-format and will generally only be useful for smaller targets that cannot support POSIX plugins.  
This page is meant as a HOWTO which roughly outlines the steps needed to implement dynamic engine plugins for a previously unsupported backend (port) of ScummVM. This HOWTO only applies to targets that can use the ELF file-format and will generally only be useful for smaller targets that cannot support POSIX plugins.  


I will assume that you are at least roughly familiar with ScummVM, and have a fresh checkout of our Subversion repository. Note that it's strongly advised to base your work on the current development version of ScummVM, and not on a release version. This will ease integration of your work.
I will assume that you are at least roughly familiar with ScummVM, and have a fresh checkout of our Subversion repository. Note that it's strongly advised to base your work on the current development version of ScummVM, and not on a release version. This will ease integration of your work.
Line 47: Line 47:


==== Making the plugin linker script for your backend ====
==== Making the plugin linker script for your backend ====
To generate this script, first find the linker script used to link a static build of the target platform (usually this is the default script for the linker, which you can dump via the command <tt>foobar-compiler-ld --verbose</tt>).
To generate this script, first find the linker script used to link a static build of the target platform (usually this is the default script for the linker, which you can dump via the command <tt>foobar-compiler-ld --verbose</tt>). You'll want to modify this linker in a few key ways.


TODO: Fill out this section.
*First, you can remove the <tt>ENTRY(symbol)</tt> command. This command normally tells the linker which instruction should be the first to execute in the program, but since you're generating a plugin that will be linked in and jumped to from the main executable, it is not needed.
*Next, define an ELF program header for a "plugin" segment to be loaded from the file. Do this by adding the following before the SECTIONS command:
<syntax type="C++">PHDRS
{
  plugin PT_LOAD ;
}</syntax>
*Set the start address of the file to be 0 (since this will be linked in at a different address later), usually you can do this by replacing the first line in SECTIONS with <code>. = 0;</code>, though different ld scripts may require different modifications.
*Place the first section (as listed under the SECTIONS command) into the "plugin" segment you defined in PHDRS by appending <tt>:plugin</tt> to the first sections-command, i.e <code>.text . : { *(.text) } :plugin</code>. As long as there aren't any other PHDRS, this should ensure the entire linked file is put in the "plugin" segment, since future sections assume they are to be put in the same segment as the previous section unless specified otherwise (via <tt>:phdr</tt> or <tt>:NONE</tt>).
*Find the <tt>.ctors</tt> and <tt>.dtors</tt> sections (constructors and destructors) and delete any output-section-commands within them that reference crtbegin or crtend, i.e <code>KEEP (*crtbegin*.o(.dtors))</code> or <code>KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))</code>. Put <code>___plugin_ctors = .;</code> as the first output-section-command in the <tt>.ctors</tt> section and <code>___plugin_ctors_end = .;</code> as the last output-section-command. Do the same for the <tt>.dtors</tt> section but with <tt>___plugin_dtors</tt>, etc. This gives these symbols values that our run-time loader can use. In the end, <tt>.ctors</tt> and <tt>.dtors</tt> should look something like this:
<syntax type="C++">.ctors          :
  {
    ___plugin_ctors = .;
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    ___plugin_ctors_end = .;
  }
  .dtors          :
  {
    ___plugin_dtors = .;
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    ___plugin_dtors_end = .;
  }</syntax>
*That's it! If you have trouble with any of these instructions or need to further modify the linker script for something specific to your platform, see [http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts.html] for linker script documentation and peruse the various <tt>plugin.ld</tt> files in the subdirectories of <tt>backends/plugins/</tt>. TODO: Add stuff about MIPS-specific linker script modifications, namely the "shorts" segment.


==== Necessary Build Modifications ====
==== Necessary Build Modifications ====
27

edits