blob: c8bca5356c3e490cef36b69edc4766a8f5e171de [file] [log] [blame]
Different depthcharge modules may need to run from overlapping memory regions.
Loading one from the other directly would be problematic, because parts of the
first module might be overwritten by the second before they're done being used.
The trampoline module works around that problem by being loaded somewhere else
in memory and loading the second module on behalf of the first. It contains
just enough logic that it can load a pre-vetted ELF file. It has its own stack
since that might also be overwritten along with the rest of the module, but
that stack is set up as part of loading the trampoline rather than by the
trampoline itself since the originating module has facilities for catching
and reporting exceptions.
To ensure that the trampoline is independent of its parent module it's linked
independently into its own ELF file. Previously, the trampoline would then be
linked into the parent module. The problem with that, though, is that the
linker tricks are necessary to load the trampoline in one place but to make
it run in another. Also, the BSS of the trampoline would be zeroed when loading
the parent module. When transplanting the trampoline into place when it's time
for it to run, either the BSS (a bank of zeroes) will have to be copied, or
support for recognizing the BSS and treating it specially would have to be
added.
Instead, the trampoline can be stored as a compressed ELF file in the module
as a raw binary blob. The code which the trampoline uses to load the next
module can be used to load the trampoline itself. The few symbols that are
necessary to load and call into the trampoline are linked into the parent
module using the --just-symbols linker option. When the trampoline is loaded,
those symbols will map to locations in it.
To allow putting the trampoline at different locations depending on the needs
of the parent module, the trampoline is linked twice. The first time it's
linked as a relocatable module. The subsequent times it's linked into its
final location based on the base address which is part of the file name.
Two different versions of the trampoline are created. The first is an ELF
which is used with the --just-symbols option as described above. The second
is the compressed ELF binary which is wrapped in an object file so it can be
linked into another ELF. The path of the binary is handled very carefully so
that the symbols gcc automatically creates which describe it have the names
we expect.