Jump to navigation Jump to search
Fix syntax highlighting
==== Example of foobar-provider.h====
<syntax typesource lang="C++cpp">#if defined(DYNAMIC_MODULES) && defined(FOOBAR)
#include "backends/plugins/elf-provider.h"
#endif // defined(DYNAMIC_MODULES) && defined(FOOBAR)
==== Making the plugin linker script for your backend ====
*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 typesource lang="C++cpp">PHDRS
plugin PT_LOAD ;
*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 typesource lang="C++cpp">.ctors :
___plugin_ctors = .;
KEEP (*(.dtors))
___plugin_dtors_end = .;
*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 [] 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.
There will undoubtedly be a number of things specific to your platform to deal with when it comes to modifying the building, but you should definitely add the following, bordered by #ifdef guards to make sure DYNAMIC_MODULES is set to 1 (along with telling the desired engines that you want them to be separate plugin files, i.e. "ENABLE_SCUMM = DYNAMIC_PLUGIN"):
<syntax typesource lang="C++Makefile">DEFINES += ELF_LOADER_TARGET //also add any other necessary defines
PLUGIN_SUFFIX := .plg //or whatever your suffix is
PRE_OBJS_FLAGS := -Wl,--whole-archive
POST_OBJS_FLAGS := -Wl,--no-whole-archive
As you can see, these modifications mainly deal with making sure the plugins are dependent on the main executable and use the custom linker script.


Navigation menu