mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-14 23:00:31 +08:00
user: Add a Dynamic Loader section.
This commit is contained in:
parent
789b0caad7
commit
8a73acb713
BIN
images/user/libdl-load.png
Normal file
BIN
images/user/libdl-load.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
39
images/user/libdl-load.puml
Normal file
39
images/user/libdl-load.puml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
'
|
||||||
|
' Libdl Load Executable Object file
|
||||||
|
'
|
||||||
|
' Copyright (c) 2019 Chris Johns <chrisj@rtems.org>
|
||||||
|
' All rights reserved.
|
||||||
|
'
|
||||||
|
@startuml
|
||||||
|
start
|
||||||
|
:dlopen;
|
||||||
|
|
||||||
|
if (check libraries ?) then (changed)
|
||||||
|
:load libraries;
|
||||||
|
else (no change)
|
||||||
|
endif
|
||||||
|
:load object;
|
||||||
|
floating note left
|
||||||
|
Searching of unreolved symbols
|
||||||
|
continues until the remain symbols
|
||||||
|
cannot be found in the global symbol
|
||||||
|
table or libraries.
|
||||||
|
end note
|
||||||
|
while (unresolved symbols?) is (unresolved)
|
||||||
|
if (search globals) then (found)
|
||||||
|
:fix relocations;
|
||||||
|
else (not found)
|
||||||
|
endif
|
||||||
|
if (search libraries ?) then (found)
|
||||||
|
:load library object;
|
||||||
|
floating note left
|
||||||
|
If a symbol is found the library object file
|
||||||
|
is load adding the symbol to the global
|
||||||
|
symbol table and potentially adding more
|
||||||
|
unresolved symbols.
|
||||||
|
end note
|
||||||
|
else (not found)
|
||||||
|
endif
|
||||||
|
endwhile (all searched)
|
||||||
|
stop
|
||||||
|
@enduml
|
42
images/user/libdl.ditaa
Normal file
42
images/user/libdl.ditaa
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
'
|
||||||
|
' Executable debugging : QEMU
|
||||||
|
'
|
||||||
|
' Copyright (c) 2018 Chris Johns <chrisj@rtems.org>
|
||||||
|
' All rights reserved.
|
||||||
|
'
|
||||||
|
@startditaa
|
||||||
|
|
||||||
|
+----------------------------------------+
|
||||||
|
/--------------------------\ | RTL (libdl) |
|
||||||
|
| RTEMS File System | | |
|
||||||
|
| | | +----------+ /---------------\ |
|
||||||
|
| | /------->| archives |<--->| lib symbols | |
|
||||||
|
| +---------------------+ | | | +----------+ \---------------/ |
|
||||||
|
| | /etc/libdl.conf |-----+ | ^ |
|
||||||
|
| +---------------------+ | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| +---------------------+ | | | V |
|
||||||
|
| | /lib/librtemscpu.a | | | | +-------------+ /-------------\ |
|
||||||
|
| | /lib/librtemsbsp.a |-----/ /----->| link editor |<--->| symbols | |
|
||||||
|
| | /lib/libc.a | | | | +-------------+ \-------------/ |
|
||||||
|
| | /lib/libm.a | | | | ^ ^ |
|
||||||
|
| | /lib/libgcc.a | | | | | | |
|
||||||
|
| +---------------------+ | | | | V |
|
||||||
|
| | | | | /---------------\ |
|
||||||
|
| +---------------------+ | | | +----->| objects | |
|
||||||
|
| | /app/foo.o |-------/ | | \---------------/ |
|
||||||
|
| +---------------------+ | | | ^ |
|
||||||
|
\--------------------------/ | | | |
|
||||||
|
| | | |
|
||||||
|
| | /------+--------\ |
|
||||||
|
| +----->| unresolved | |
|
||||||
|
| | | symbols | |
|
||||||
|
| | \---------------/ |
|
||||||
|
| | |
|
||||||
|
+---------|------------------------------+
|
||||||
|
|
|
||||||
|
V
|
||||||
|
/----------------------------------\
|
||||||
|
| target memory |
|
||||||
|
\----------------------------------/
|
||||||
|
@endditaa
|
BIN
images/user/libdl.png
Normal file
BIN
images/user/libdl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -77,6 +77,8 @@ built with ``make``, ``autotools``, ``cmake``, ``waf`` and more. User should
|
|||||||
select a build system that meets their project, system, corporate or personal
|
select a build system that meets their project, system, corporate or personal
|
||||||
needs.
|
needs.
|
||||||
|
|
||||||
|
.. _MachineFlagsandABI:
|
||||||
|
|
||||||
Machine Flags and ABI
|
Machine Flags and ABI
|
||||||
---------------------
|
---------------------
|
||||||
.. index:: Machine flags
|
.. index:: Machine flags
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
.. Copyright (C) 2018 Chris Johns <chrisj@rtems.org>
|
.. Copyright (C) 2018 Chris Johns <chrisj@rtems.org>
|
||||||
|
|
||||||
|
.. _TargetExecution:
|
||||||
|
|
||||||
Target Execution
|
Target Execution
|
||||||
================
|
================
|
||||||
.. index:: Target Execution
|
.. index:: Target Execution
|
||||||
|
@ -11,10 +11,11 @@ Executables
|
|||||||
|
|
||||||
This section discusses what an RTEMS executable is and what happens when you
|
This section discusses what an RTEMS executable is and what happens when you
|
||||||
execute it in a target. The section discusses how an application executable is
|
execute it in a target. The section discusses how an application executable is
|
||||||
created, what happens when an executable is loaded and run as well as
|
created, what happens when an executable is loaded and run, debugging an
|
||||||
debugging an execiutable.
|
execiutable, and creating and dynamically loading code.
|
||||||
|
|
||||||
.. include:: executables.rst
|
.. include:: executables.rst
|
||||||
.. include:: execution.rst
|
.. include:: execution.rst
|
||||||
.. include:: initialization.rst
|
.. include:: initialization.rst
|
||||||
.. include:: debugging.rst
|
.. include:: debugging.rst
|
||||||
|
.. include:: loader.rst
|
||||||
|
866
user/exe/loader.rst
Normal file
866
user/exe/loader.rst
Normal file
@ -0,0 +1,866 @@
|
|||||||
|
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
|
||||||
|
.. Copyright (C) 2019 Chris Johns <chrisj@rtems.org>
|
||||||
|
|
||||||
|
.. index:: Dynamic Loader
|
||||||
|
|
||||||
|
Dynamic Loader
|
||||||
|
==============
|
||||||
|
.. index:: Dynamic Loader
|
||||||
|
.. index:: Run-time Loader
|
||||||
|
.. index:: RTL
|
||||||
|
.. index:: Libdl
|
||||||
|
|
||||||
|
RTEMS supports dynamically loading of executable code and data in the form of
|
||||||
|
object files into a running system where the run-time loaded code can be
|
||||||
|
executed and data accessed
|
||||||
|
|
||||||
|
This section describes RTEMS loader, preparing and loading executable code into
|
||||||
|
a running system, the supported architectures and any limitation that may exist
|
||||||
|
with an architecture.
|
||||||
|
|
||||||
|
The RTEMS operating system contains a link editor that runs on the target. The
|
||||||
|
link editor supports loading Extendable Linker Format (ELF) relocatable
|
||||||
|
executable object files locating the code and data in the target's address space
|
||||||
|
as it is loaded. An executable object file's external references to function
|
||||||
|
identifiers and data object identifiers are resolved and any external symbols
|
||||||
|
can be made available in the global symbol table. The executing performance of
|
||||||
|
dynamically loaded code is similar to the same code statically linked into an
|
||||||
|
executable. This is a core requirement of the RTEMS link editor.
|
||||||
|
|
||||||
|
.. _fig-dl-libdl:
|
||||||
|
|
||||||
|
.. figure:: ../../images/user/libdl.png
|
||||||
|
:width: 95%
|
||||||
|
:alt: Run Time Loader (libdl)
|
||||||
|
:figclass: align-center
|
||||||
|
|
||||||
|
Run Time Loader (libdl)
|
||||||
|
|
||||||
|
The RTEMS operating system's dynamic loader is not the same as the dynamic
|
||||||
|
shared library support Unix or Windows have. Those operating systems use dynamic
|
||||||
|
loading to share code between processes and this is an important feature in
|
||||||
|
their design. RTEMS is a single address space operating system and that means
|
||||||
|
there is no ability to share code at run-time. As a result code is loaded in a
|
||||||
|
similar manner to static linking removing the need for any overheads sharing
|
||||||
|
code may have.
|
||||||
|
|
||||||
|
To load an executable object file it must be resident on a target and accessible
|
||||||
|
by RTEMS's file system. The executable object file can be a single file or a
|
||||||
|
collection in a library stored using the Unix standard archive format. The RTEMS
|
||||||
|
loader supports the extended GNU format for long file names in archives.
|
||||||
|
|
||||||
|
The RTEMS developers do not see dynamically loading of code as a real-time
|
||||||
|
activity. A system should not respond to real-time external events by loading
|
||||||
|
code. The loading of code should happen before a system is considered available
|
||||||
|
and the activity the system is experiencing is low and stable.
|
||||||
|
|
||||||
|
.. index: base image
|
||||||
|
|
||||||
|
The statically linked executable that is loaded and run after reset is called
|
||||||
|
the *base image*. The *base image* contains your base application that is used
|
||||||
|
to dynamically load code, a global symbol table, the parts of the RTEMS
|
||||||
|
operating system code used in the base image as well as functions and data from
|
||||||
|
the tool suite libraries and packages you are using. Only the software
|
||||||
|
referenced is used to create the base image. The parts of the libraries not
|
||||||
|
referenced are not part of the executable or present in the global symbol table.
|
||||||
|
|
||||||
|
Application software can locate a symbol by name and call the address or
|
||||||
|
reference the data at that address. A function identifier located by a symbol
|
||||||
|
does not have it's signatures checked, it is the responsibility of the caller to
|
||||||
|
make sure the function is called with the correct arguments. It is the same for
|
||||||
|
data objects, there is no type checking. Symbol versioning is not supported and
|
||||||
|
supporting it does not make sense within the RTEMS operating system. An RTEMS
|
||||||
|
target system is closed to normal users and software needs to be built from the
|
||||||
|
same tool set and header files used to the build the base image.
|
||||||
|
|
||||||
|
An executable object file's text or code has to be built for the target's
|
||||||
|
architecture it is loaded on and it must be built with the same ABI flags the
|
||||||
|
base image is built with. See :ref:`MachineFlagsandABI`.
|
||||||
|
|
||||||
|
System Design
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The use of dynamic loading in a project is a system design decision. Some
|
||||||
|
systems will have strict requirements where loading code into a live system is
|
||||||
|
not allowed while other projects will benefit from the system level flexibility
|
||||||
|
dynamically loading code provides.
|
||||||
|
|
||||||
|
Code loaded at run time needs to be resident or accessible to the target via
|
||||||
|
RTEMS's file system. Targets that have suitable media or a network interface to
|
||||||
|
NFS servers to hold the executable object and library files are best suited.
|
||||||
|
|
||||||
|
Dynamically loading code uses more memory than statically linking the same code
|
||||||
|
into the base image. The link editor maintains symbol tables where each symbol
|
||||||
|
is a string, an address, and some additional data. The executable object files
|
||||||
|
resident in memory each have data to manage them, the memory they use, and any
|
||||||
|
dependencies they might have. The link editor is designed to minimize the memory
|
||||||
|
overheads however only statically linked executables have no memory overhead.
|
||||||
|
|
||||||
|
The link editor relocates the code and data into RAM fixing it to the load
|
||||||
|
address as it is loaded. A target needs to have suitably configured memory
|
||||||
|
available for the executable object file to reside in. The memory must be able
|
||||||
|
to support read, write and executable type access. Fine control of the memory
|
||||||
|
and it's modes can be supported using a customer allocator. Examples are systems
|
||||||
|
that have a custom memory map, specialized memory for the execution of code or a
|
||||||
|
requirement for read-only executable sections.
|
||||||
|
|
||||||
|
The load address of an executable object file is determined by the load order
|
||||||
|
and the allocator used. The default allocator for the link editor is the system
|
||||||
|
heap which means the location a specific executable object file is loaded at
|
||||||
|
depends on the memory allocated before it is loaded and when in the load order
|
||||||
|
it is loaded. A statically linked executable's address map is fixed and this is
|
||||||
|
considered important in some systems. A dynamically loaded system can be loaded
|
||||||
|
in a repeatable manner if the load order is the same and the initialization
|
||||||
|
sequence of the system is controlled. A custom allocator may also help.
|
||||||
|
|
||||||
|
Management of dynamically loadable object files and libraries adds to the
|
||||||
|
configuration management of the hosts in a project. The loadable files need to
|
||||||
|
be released and tracked in a suitable configuration management process just like
|
||||||
|
the base image is. Executable object files and libraries are specific to a
|
||||||
|
version of RTEMS and cannot be mixed or moved and this needs to be carefully
|
||||||
|
managed. Currently there are no checks an executable object file matches the
|
||||||
|
version of the base image it is being loaded on. These extra configuration
|
||||||
|
controlled items add to the overheads of a project and need to be considered.
|
||||||
|
|
||||||
|
Dynamically loadable systems have a number of features that benefit some systems
|
||||||
|
and products. Systems can be built on a base of trusted or *golden* modules. A
|
||||||
|
number of projects using a common base of hardware can make use of proven
|
||||||
|
modules reducing the testing and qualification overhead for each new release. A
|
||||||
|
tested base image with libraries for common and available boards provides a
|
||||||
|
simple and fast way for new users to trial and use RTEMS.
|
||||||
|
|
||||||
|
A project can use dynamic loading during development, shipping statically linked
|
||||||
|
executables in production. Hardware used by a development team can have more
|
||||||
|
memory, extra media for disk drives, or a network interface.
|
||||||
|
|
||||||
|
Loader Interface
|
||||||
|
----------------
|
||||||
|
.. index:: Loader Interface
|
||||||
|
.. index:: Loading object files
|
||||||
|
.. index:: dlfcn.h
|
||||||
|
|
||||||
|
Run-time executable object file loading and management is via the standard's
|
||||||
|
based calls provided by the header file ``<dlfcn.h>``. The details of the calls
|
||||||
|
follow.
|
||||||
|
|
||||||
|
.. _dlopen:
|
||||||
|
.. index:: dlopen
|
||||||
|
``void* dlopen(const char* path, int mode);``
|
||||||
|
The ``dlopen()`` function makes the symbols (function identifiers and data
|
||||||
|
object identifiers) in the executable object file specified by `file`
|
||||||
|
available to the calling program.
|
||||||
|
|
||||||
|
The executable object files eligible for this operation are in the ELF
|
||||||
|
format.
|
||||||
|
|
||||||
|
The link loader may load embedded dependencies in executable object files. In
|
||||||
|
such cases, a ``dlopen()`` operation may load those dependencies in addition
|
||||||
|
to the executable object file specified by `file`.
|
||||||
|
|
||||||
|
A successful ``dlopen()`` returns a `handle` which the caller may use on
|
||||||
|
subsequent calls to ``dlsym()``, ``dlinfo()`` and ``dlclose()``.
|
||||||
|
|
||||||
|
The value of the `handle` should not be interpreted in any way by the caller.
|
||||||
|
|
||||||
|
Subsequent calls to ``dlopen()`` for the same executable object file increases
|
||||||
|
the references to it.
|
||||||
|
|
||||||
|
The `file` argument is used to construct a pathname to the executable object
|
||||||
|
file or archive library of executable object files. If the `file` argument
|
||||||
|
contains a colon (``:``) the name of the executable object file in the library
|
||||||
|
follows and this file name may optionally end with ``@`` followed by a number
|
||||||
|
which is the absolute offset in the library file where the executable object
|
||||||
|
file starts. If an executable object file is not detected at the offset the
|
||||||
|
archive library's file table is searched.
|
||||||
|
|
||||||
|
If `file` is a null pointer, ``dlopen()`` returns a global symbol table
|
||||||
|
handle. This `handle` provides access to the global symbols from an ordered
|
||||||
|
set of executable object files consisting of the original base image file, the
|
||||||
|
set of executable object files loaded using ``dlopen()`` operations with the
|
||||||
|
``RTLD_GLOBAL`` flag, and any dependencies loaded. As the latter sets of
|
||||||
|
executable object files can change during execution, the set of symbols made
|
||||||
|
available by this `handle` can also change dynamically.
|
||||||
|
|
||||||
|
Only a single copy of an executable object file is brought into the address
|
||||||
|
space, even if ``dlopen()`` is invoked multiple times in reference to the
|
||||||
|
executable object file, and even if different pathnames are used to reference
|
||||||
|
the executable object file.
|
||||||
|
|
||||||
|
Unresolved external symbols do not cause an error to be returned allowing the
|
||||||
|
loading of jointly dependent executable object files.
|
||||||
|
|
||||||
|
If ``dlopen()`` fails, it returns a null pointer, and sets an error condition
|
||||||
|
which may be interrogated with ``dlerror()``.
|
||||||
|
|
||||||
|
The `mode` parameter describes how ``dlopen()`` operates upon `file` with
|
||||||
|
respect to the processing of relocations and the scope of visibility of the
|
||||||
|
symbols provided within `file`. When an executable object file is brought into
|
||||||
|
the address space, it may contain references to symbols whose addresses are
|
||||||
|
not known until the executable object file is loaded.
|
||||||
|
|
||||||
|
If a loaded executable object file and any dependent executable object files
|
||||||
|
loaded with it contain any initialiser functions, they are called in the order
|
||||||
|
loaded before ``dlopen()`` returns.
|
||||||
|
|
||||||
|
The modes ``RTLD_LAZY`` and ``RTLD_NOW`` do not effect the type of relocation
|
||||||
|
performed, it is same for both modes. All relocations of an executable object
|
||||||
|
file and any dependent executable object files loaded with it are completed
|
||||||
|
before the ``dlopen()`` call returns. The execution performance of the code
|
||||||
|
loaded can be considered deterministic once ``dlopen()`` has returned.
|
||||||
|
|
||||||
|
Any executable object file loaded by ``dlopen()`` can reference global symbols
|
||||||
|
in the base image, any executable object files loaded included in the same
|
||||||
|
``dlopen()`` invocation, and any executable object files that were loaded in
|
||||||
|
any ``dlopen()`` invocation and which specified the ``RTLD_GLOBAL`` flag. To
|
||||||
|
determine the scope of visibility for the symbols loaded with a ``dlopen()``
|
||||||
|
invocation, the `mode` parameter should be a bitwise-inclusive ``OR`` with one
|
||||||
|
of the following values:
|
||||||
|
|
||||||
|
``RTLD_GLOBAL``
|
||||||
|
The executable object file's symbols are made available for relocation
|
||||||
|
processing of any other executable object file. In addition, symbol lookup
|
||||||
|
using ``dlopen(NULL,mode)`` and an associated ``dlsym()`` allows
|
||||||
|
executable object files loaded with this mode to be searched.
|
||||||
|
|
||||||
|
``RTLD_LOCAL``
|
||||||
|
The executable object file's symbols shall not be made available for
|
||||||
|
relocation processing of any other executable object files.
|
||||||
|
|
||||||
|
If neither ``RTLD_GLOBAL`` nor ``RTLD_LOCAL`` is specified, the default
|
||||||
|
behavior is unspecified.
|
||||||
|
|
||||||
|
If ``RTLD_GLOBAL`` has been specified, the executable object file maintains
|
||||||
|
it's ``RTLD_GLOBAL`` status regardless of any previous or future specification
|
||||||
|
of ``RTLD_LOCAL``, as long as the executable object file remains in the
|
||||||
|
address space.
|
||||||
|
|
||||||
|
Symbols introduced through calls to ``dlopen()`` may be used in relocation
|
||||||
|
activities. Symbols that duplicate symbols already defined by the base image
|
||||||
|
or previous ``dlopen()`` calls are treated as an error and the object file is
|
||||||
|
not loaded. Symbols introduced through loading dependent executable object
|
||||||
|
files are ignored or not loaded depending on the method used to build the
|
||||||
|
executable object files.
|
||||||
|
|
||||||
|
The symbols introduced by ``dlopen()`` operations and available through
|
||||||
|
``dlsym()`` are at a minimum those which are exported as identifiers of global
|
||||||
|
scope by the executable object file. Typically, such identifiers shall be
|
||||||
|
those that were specified in (for example) C source code as having ``extern``
|
||||||
|
linkage.
|
||||||
|
|
||||||
|
.. _dlclose:
|
||||||
|
.. index:: dlclose
|
||||||
|
``int dlclose(void* handle);``
|
||||||
|
Releases a reference to the executable object file referenced by `handle`. If
|
||||||
|
the reference count drops to ``0``, the executable object file's global symbol
|
||||||
|
table is made unavailable. When all references to the global symbols the
|
||||||
|
executable object file provided have been removed the object file is removed
|
||||||
|
from the address space.
|
||||||
|
|
||||||
|
If the executable object being removed has any termination routines in it they
|
||||||
|
are called.
|
||||||
|
|
||||||
|
.. _dlsym:
|
||||||
|
.. index:: dlsym
|
||||||
|
``void* dlsym(void* handle, const char* symbol);``
|
||||||
|
The ``dlsym()`` function obtains the address of a symbol (a function identifier
|
||||||
|
or a data object identifier) defined in the symbol table identified by the
|
||||||
|
handle argument. The handle argument is a symbol table handle returned from a
|
||||||
|
call to ``dlopen()`` (and which has not since been released by a call to
|
||||||
|
``dlclose()``), and name is the symbol's name as a character string. The return
|
||||||
|
value from ``dlsym()``, cast to a pointer to the type of the named symbol, can
|
||||||
|
be used to call (in the case of a function) or access the contents of (in the
|
||||||
|
case of a data object) the named symbol.
|
||||||
|
|
||||||
|
The ``dlsym()`` function searches for the named symbol in the symbol table
|
||||||
|
referenced by handle and returns the address of the code or data location
|
||||||
|
specified by the null-terminated character string symbol. Which libraries and
|
||||||
|
objects are searched depends on the `handle` parameter.
|
||||||
|
|
||||||
|
Upon successful completion, if name names a function identifier, ``dlsym()``
|
||||||
|
returns the address of the function converted from type pointer to function to
|
||||||
|
type pointer to ``void``; otherwise, ``dlsym()`` shall return the address of
|
||||||
|
the data object associated with the data object identifier named by name
|
||||||
|
converted from a pointer to the type of the data object to a pointer to
|
||||||
|
``void``. If `handle` does not refer to a valid symbol table handle or if the
|
||||||
|
symbol named by name cannot be found in the symbol table associated with
|
||||||
|
`handle`, ``dlsym()`` shall return a null pointer.
|
||||||
|
|
||||||
|
.. _dlinfo:
|
||||||
|
.. index:: dlinfo
|
||||||
|
``int dlinfo(void* handle, int request, void* args);``
|
||||||
|
|
||||||
|
The ``dlinfo()`` function provides information about dynamically loaded object.
|
||||||
|
The action taken by ``dlinfo()`` and exact meaning and type of the argument
|
||||||
|
`args` depend on value of the `request` argument provided by the caller.
|
||||||
|
|
||||||
|
``RTLD_DI_UNRESOLVED``
|
||||||
|
Return ``1`` in an indexer value pointed to by `args` if the symbol table
|
||||||
|
handle has unresolved relocation records to symbols. If the `handle` is the
|
||||||
|
global symbol table handle or ``RTLD_SELF`` return ``1`` if any unresolved
|
||||||
|
relocation records to symbols are present in any loaded executable object
|
||||||
|
files..
|
||||||
|
|
||||||
|
.. _dlerror:
|
||||||
|
.. index:: dlerror
|
||||||
|
``const char *dlerror(void);``
|
||||||
|
The ``dlerror()`` function returns a null-terminated character string (with no
|
||||||
|
trailing ``<newline>``) that describes the last error that occurred during
|
||||||
|
dynamic linking processing. If no dynamic linking errors have occurred since
|
||||||
|
the last invocation of ``dlerror()``, ``dlerror()`` returns ``NULL``. Thus,
|
||||||
|
invoking ``dlerror()`` a second time, immediately following a prior
|
||||||
|
invocation, results in ``NULL`` being returned.
|
||||||
|
|
||||||
|
This example opens an object file, checks for any unresolved symbols the object
|
||||||
|
file may have, locates a global symbol in the object file, calls it then closes
|
||||||
|
the object file:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
typedef int (*call_sig)(void);
|
||||||
|
|
||||||
|
bool load_object (void)
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
call_sig call;
|
||||||
|
int unresolved;
|
||||||
|
|
||||||
|
handle = dlopen ("/code.o", RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
printf ("dlopen failed: %s\n", dlerror ());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
|
||||||
|
{
|
||||||
|
printf ("dlinfo failed: %s\n", dlerror ());
|
||||||
|
dlclose (handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unresolved != 0)
|
||||||
|
{
|
||||||
|
printf ("object.o has unresolved external symbols\n");
|
||||||
|
dlclose (handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
call = dlsym (handle, "foo");
|
||||||
|
if (call == NULL)
|
||||||
|
{
|
||||||
|
printf("dlsym failed: symbol 'foo' not found\n");
|
||||||
|
dlclose (handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("'foo()' returns: %i\n", call ());
|
||||||
|
|
||||||
|
if (dlclose (handle) < 0)
|
||||||
|
{
|
||||||
|
printf("dlclose failed: %s\n", dlerror());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbols
|
||||||
|
-------
|
||||||
|
.. index:: symbol
|
||||||
|
.. index:: global symbol
|
||||||
|
.. index:: function identifier
|
||||||
|
.. index:: data object identifier
|
||||||
|
|
||||||
|
The RTEMS link editor manages the symbols for the base image and all resident
|
||||||
|
executable object files. A symbol is an identifier string and a pointer value to
|
||||||
|
a function identifier or a data object identifier. The symbols held in the
|
||||||
|
symbol tables are used in the relocation of executable object files or they can
|
||||||
|
be accessed by application code using the :ref:`dlsym() <dlsym>` call.
|
||||||
|
|
||||||
|
.. index:: orphaned object file
|
||||||
|
|
||||||
|
An executable object file's symbols are removed from the global symbol table
|
||||||
|
when it is closed or orphaned. An executale object file cannot be unloaded if a
|
||||||
|
symbol it provides is referenced by another object and that object is still
|
||||||
|
resident. An executable object file that has no references to any of its symbols
|
||||||
|
and was not explicitly loaded using the :ref:`dlopen() <dlopen>` call is
|
||||||
|
orphaned and automatically removed from the address space.
|
||||||
|
|
||||||
|
Base Image Symbols
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
.. index:: base image symbols
|
||||||
|
|
||||||
|
The base image symbol table provides access to the function and data objects
|
||||||
|
statically linked into the base image. Loaded executable object files can be
|
||||||
|
directly linked to the code and data resident in the base image.
|
||||||
|
|
||||||
|
A statically linked RTEMS executable does not contain a symbol table, it has to
|
||||||
|
be generated and either embedded into the executable or loaded as a specially
|
||||||
|
created executable object file.
|
||||||
|
|
||||||
|
The base image symbol table is dependent on the contents of the base image and
|
||||||
|
this is not known until it has been linked. This means the base image symbol
|
||||||
|
table needs to be constructed after the base image executable has been linked
|
||||||
|
and the list of global symbols is known.
|
||||||
|
|
||||||
|
The RTEMS Tools command :program:`rtems-syms` (see :ref:`RTEMSSymbols`) extracts
|
||||||
|
the global and weak symbols from an RTEMS static executable file, creates a C
|
||||||
|
file and compiles it creating a relocatable executable object file. This file
|
||||||
|
can be linked with the static executable's object files and libraries to create
|
||||||
|
a static executables with an embedded symbol table or the executable file can be
|
||||||
|
loaded dynamically at run-time. The following needs to be observed:
|
||||||
|
|
||||||
|
#. The option ``-e`` or ``--embedded`` to :program:`rtems-syms` creates an
|
||||||
|
executable object file to be embedded in the base image and not providing
|
||||||
|
either of these options creates a symbols executable object file that is
|
||||||
|
loaded at run-time. The same executable object file cannot be used to
|
||||||
|
embedded or load.
|
||||||
|
|
||||||
|
#. The target C compiler and machine options need to be provided to make sure
|
||||||
|
the correct ABI for the target is used. See :ref:`MachineFlagsandABI`.
|
||||||
|
|
||||||
|
.. index:: embedded symbol table
|
||||||
|
.. _EmbbeddedSymbolTable:
|
||||||
|
|
||||||
|
Embedded Symbols
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
An embedded symbol table is *embedded* within the base image executable file and
|
||||||
|
loaded when the static executable is loaded into memory by the bootloader. The
|
||||||
|
symbol table is automatically added to the link editor's global symbol table
|
||||||
|
when the first executable object file is loaded.
|
||||||
|
|
||||||
|
The process to embed the symbol table requires linking the base image twice.
|
||||||
|
The first link is to create a static executable that collects together the
|
||||||
|
symbols to make the symbol table. The RTEMS Tools command `rtems-syms` extracts
|
||||||
|
the global and weak symbols from the static executable ELF file, creates a C
|
||||||
|
file and compiles it to create an executable object file. The base image is
|
||||||
|
linked a second time and this time the symbol table executable object file is
|
||||||
|
added to the list of object files.
|
||||||
|
|
||||||
|
Embedding the symbol table means the chances of the symbol table and base image
|
||||||
|
not matching is low, however it also means the symbol table is always present in
|
||||||
|
the kernel image when dynamic loading may be optional. A project's build system
|
||||||
|
is made more complex as it needs to have extra steps to link a second time.
|
||||||
|
|
||||||
|
This example shows creating an embedded symbol table object file and linking it
|
||||||
|
into the base image.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ sparc-rtems5-gcc -mcpu=cypress foo.o -lrtemsbsp -lrtemscpu -o foo.pre
|
||||||
|
$ rtems-syms -e -C sparc-rtems5-gcc -c "-mcpu=cypress" -o foo-sym.o foo.pre
|
||||||
|
$ sparc-rtems5-gcc -mcpu=cypress foo.o foo-sym.o -lrtemsbsp -lrtemscpu -o foo.exe
|
||||||
|
|
||||||
|
The link command line steps in this example are not complete.
|
||||||
|
|
||||||
|
.. _LoadableSymbolTable:
|
||||||
|
|
||||||
|
Loadable Symbols
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A run-time loaded symbol table is the default for the command
|
||||||
|
:program:`rtems-syms`. The symbol table executable object file is packaged with
|
||||||
|
the other files to be dynamically loaded at run-time and placed on the target's
|
||||||
|
file system. It needs to be loaded before any other executable object file are
|
||||||
|
loaded or unresolved symbols can occur that will not be resolved.
|
||||||
|
|
||||||
|
A run-time loaded symbol table does not consume any target resources until it is
|
||||||
|
loaded. This is useful in a system that optionally needs to dynamically load
|
||||||
|
code, for example as a development environment. The symbol table executable
|
||||||
|
needs to exactly match the base image loading it or the behavior is
|
||||||
|
unpredictable. No checks are made.
|
||||||
|
|
||||||
|
The example shows creating and loading a symbol table executable object
|
||||||
|
file. First create the symbol table's executable object file:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ sparc-rtems5-gcc -mcpu=cypress foo.o -lrtemsbsp -lrtemscpu -o foo.exe
|
||||||
|
$ rtems-syms -C sparc-rtems5-gcc -c "-mcpu=cypress" -o foo-sym.o foo.exe
|
||||||
|
|
||||||
|
The link command line steps in this example are not complete.
|
||||||
|
|
||||||
|
Load the symbol table:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
bool load (void)
|
||||||
|
{
|
||||||
|
void* handle = dlopen ("/foo-sym.o", RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
printf ("failed to load the symbol table: %s\n", dlerror ());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unresolved Symbols
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The RTEMS link editor does not return an error when an executable object file is
|
||||||
|
loaded with unresolved symbols. This allows dependent object files to be
|
||||||
|
loaded. For example an executable object file :file:`foo.o` contains the
|
||||||
|
function ``foo()`` and that function calls ``bar()`` and an executable object
|
||||||
|
file :file:`bar.o` contains a function ``bar()`` that calls the function
|
||||||
|
``foo()``. Either of these executable object files can be loaded first as long
|
||||||
|
both are loaded before any symbols are accessed.
|
||||||
|
|
||||||
|
The link editor defers the resolution of unresolved symbols until the symbol is
|
||||||
|
available in the global symbol table. Executing code or accessing data in a
|
||||||
|
loaded executable object file with unresolved external symbols results in
|
||||||
|
unpredictable behavior.
|
||||||
|
|
||||||
|
All unresolved symbols are checked after an executable object file has been
|
||||||
|
loaded. If a symbol is found and resolved any relocations that reference the
|
||||||
|
symbol are fixed. If valid library files have been configured the symbol table's
|
||||||
|
of each library are searched and if the symbol is found the dependent executable
|
||||||
|
object file is loaded. This process repeats until no more symbols can be
|
||||||
|
resolved.
|
||||||
|
|
||||||
|
The ``dlinfo()`` call can be used to see if a loaded executable object file has
|
||||||
|
any unresolved symbols:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
bool has_unresolved(void* handle)
|
||||||
|
{
|
||||||
|
int unresolved;
|
||||||
|
if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
|
||||||
|
{
|
||||||
|
printf ("dlinfo failed: %s\n", dlerror ());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return unresolved != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
The handle ``RTLD_SELF`` checks for any unresolved symbols in all resident
|
||||||
|
object files:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
if (has_unresolved(RTLD_SELF))
|
||||||
|
printf("system has unsolved symbols\n");
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
|
||||||
|
The RTEMS link editor supports loading executable object files from
|
||||||
|
libraries. Executable object files can be explicitly loaded from a library using
|
||||||
|
a specific path to :ref:`dlopen() <dlopen>` and treated the same as loading a
|
||||||
|
stand alone executable object file. Libraries can be searched and an executable
|
||||||
|
object file containing the search symbol can be loaded automatically as a
|
||||||
|
dependent executable object file. A dependent executable object file loaded from
|
||||||
|
a library with no symbol references to it's symbols is orphaned and
|
||||||
|
automatically unloaded and removed from the address space.
|
||||||
|
|
||||||
|
.. _fig-dl-libs:
|
||||||
|
|
||||||
|
.. figure:: ../../images/user/libdl-load.png
|
||||||
|
:width: 65%
|
||||||
|
:alt: Loading Executable Object Files
|
||||||
|
:figclass: align-center
|
||||||
|
|
||||||
|
Loading Executable Object Files
|
||||||
|
|
||||||
|
A library is an archive format file created using the RTEMS architecture
|
||||||
|
prefixed :program:`ar` command. The RTEMS tool suite provides the :program:`ar`
|
||||||
|
program and system libraries such as :file:`libc.a` and :file:`libm.a` for each
|
||||||
|
architecture and ABI. Libraries used by the RTEMS link editor for searching must
|
||||||
|
contain a symbol table created by the :program:`ranlib` program from the RTEMS
|
||||||
|
tool suite.
|
||||||
|
|
||||||
|
Searching a library's symbol table and loading an executable object file
|
||||||
|
containing the symbol is called *dependent loading*. Dependent loading provides
|
||||||
|
a simple way to manage the dependencies when loading an executable object
|
||||||
|
file. If code in an executable object file references functions or data objects
|
||||||
|
that are part of a library and the symbols are not part of the base image those
|
||||||
|
symbols will not resolve unless the library is on the target and available for
|
||||||
|
searching and loading. Dependent loading from libraries on the target provides a
|
||||||
|
simple and understandable way to manage the dependency issue between the base
|
||||||
|
image, loaded code and the system libraries.
|
||||||
|
|
||||||
|
The RTEMS link editor checks for the configuration file :file:`/etc/libdl.conf`
|
||||||
|
on each call to :ref:`dlopen() <dlopen>`. If the file has changed since the last
|
||||||
|
check it is loaded again and the contents processed. The file format is:
|
||||||
|
|
||||||
|
#. Comments start with the ``#`` character.
|
||||||
|
#. A line is a wildcard path of libraries to search for. The wildcard search
|
||||||
|
uses the ``fnmatch()`` call. The ``fnmatch()`` function matches patterns
|
||||||
|
according to the rules used by a shell.
|
||||||
|
|
||||||
|
Files that match the search pattern are verified as a library and if a symbol
|
||||||
|
table is found it is loaded and the symbols it contains made search-able.
|
||||||
|
|
||||||
|
A call to :ref:`dlopen() <dlopen>` checks the global symbols table and any
|
||||||
|
references to relocation symbols not found are *unresolved* and added to the
|
||||||
|
unresolved symbol table. Once the executable object file is loaded the link
|
||||||
|
editor attempts to resolve any unresolved symbols. The unresolved symbol
|
||||||
|
resolver checks each unresolved symbol against the global symbol table and if
|
||||||
|
not found the available library symbol tables are searched. If a symbol is found
|
||||||
|
in a library the dependent executable object file is loaded. The process repeats
|
||||||
|
until all unresolved symbols have been resolved and the remaining unresolved
|
||||||
|
symbols are not in the global symbol table or any libraries. The loading of a
|
||||||
|
library executable object file will resolve at least one symbol and it may add
|
||||||
|
more unresolved symbols requiring further searching of the libraries.
|
||||||
|
|
||||||
|
.. index:: strip library
|
||||||
|
|
||||||
|
A library of executable object files built by the RTEMS Tool suite can contain
|
||||||
|
debug information and this should be stripped before loading on to the
|
||||||
|
target. The tool suite's command :program:`strip` can strip all the object files
|
||||||
|
in a library with a single command.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ sparc-rtems5-strip libc.a
|
||||||
|
|
||||||
|
Large Memory
|
||||||
|
------------
|
||||||
|
|
||||||
|
The RTEMS link editor supports large memory relocations. Some architectures have
|
||||||
|
instructions where the relative branch or jump offset from the instruction to
|
||||||
|
the target address is limited. These instructions provide improved performance
|
||||||
|
because less code generated compared to larger instructions which contain full
|
||||||
|
address space references. The compact code helps lower cache pressure as well
|
||||||
|
and providing improved performance for localalized functions and loops. The
|
||||||
|
compiler defaults to generating the smaller instruction and as the final address
|
||||||
|
map not known when generating the code, linkers need to provide glue code to
|
||||||
|
extend the small address range to the enitre address space. This is called a
|
||||||
|
trampoline. A trampoline is transparent to the execution of the code.
|
||||||
|
|
||||||
|
The link editor parses an executable object file's relocation records to
|
||||||
|
determine the number of trampolines needed. Added to this value are all
|
||||||
|
unresolved symbols present in an executable object file after it is
|
||||||
|
loaded. There is a slot allocated even if the symbol ends up being within range
|
||||||
|
as there is no way to determine a symbol's address until it is loaded and the
|
||||||
|
range calculated.
|
||||||
|
|
||||||
|
The trampoline table is allocated a separate block of memory to the executable
|
||||||
|
object file's text, data and constants memory. The trampoline parsing requires
|
||||||
|
the executable object file's instructions (text) be in memory as the
|
||||||
|
instructions are inspected by the architecture specific relocation support to
|
||||||
|
determine an instruction's range. As a result the allocation for the trampoline
|
||||||
|
table has to occur after the text memory has been allocated. Most instructions
|
||||||
|
have relative offsets and the trampoline table is allocated at one end limiting
|
||||||
|
the size of an object to half the maximum range.
|
||||||
|
|
||||||
|
Trampolines support is available for the ARM and PowerPC architectures. The
|
||||||
|
SPARC and Intel x86 architectures do not need trampolines and MIPS needs support
|
||||||
|
added.
|
||||||
|
|
||||||
|
Allocator
|
||||||
|
---------
|
||||||
|
|
||||||
|
The RTEMS link editor supports custom allocators. A custom allocator lets you
|
||||||
|
manage the memory used by the RTEMS link editor as it runs. Allocators could
|
||||||
|
provide:
|
||||||
|
|
||||||
|
#. Support for the various types of memory that can be allocated allowing
|
||||||
|
specialised target support for specific use cases.
|
||||||
|
#. Locking of read-only memory. The link editor unlocks read-only memory when it
|
||||||
|
needs to write to it.
|
||||||
|
#. Separation of memory holding code and data from the heap.
|
||||||
|
|
||||||
|
The allocator can be hooked using the ``rtems_rtl_alloc_hook`` call before any
|
||||||
|
calls to :ref:`dlopen() <dlopen>` are made. The hook call returns the current
|
||||||
|
allocate allowing the allocators to be chained.
|
||||||
|
|
||||||
|
The default allocator uses the heap.
|
||||||
|
|
||||||
|
.. _rtems_rtl_alloc_tags:
|
||||||
|
.. index:: rtems_rtl_alloc_tags
|
||||||
|
|
||||||
|
The allocator tags specify the type of memory the allocator is handling. The tag
|
||||||
|
used to allocate memory at an address must be used when making allocator
|
||||||
|
calls. The ``rtems_rtl_alloc_tags`` are:
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_OBJECT
|
||||||
|
``RTEMS_RTL_ALLOC_OBJECT``
|
||||||
|
Allocate a generic object. The link editor uses this memory for data
|
||||||
|
structures it uses to manage the linking process and resident executable
|
||||||
|
object files.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_SYMBOL
|
||||||
|
``RTEMS_RTL_ALLOC_SYMBOL``
|
||||||
|
Allocate memory to hold symbol data.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_EXTERNAL
|
||||||
|
``RTEMS_RTL_ALLOC_EXTERNAL``
|
||||||
|
Allocate memory for unresolved external symbols.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_READ
|
||||||
|
``RTEMS_RTL_ALLOC_READ``
|
||||||
|
Allocate memory for read-only data such as constants and exception tables.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_READ_WRITE
|
||||||
|
``RTEMS_RTL_ALLOC_READ_WRITE``
|
||||||
|
Allocate memory for read-write data such as a initialised, uninitialized and
|
||||||
|
common variables.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_READ_EXEC
|
||||||
|
``RTEMS_RTL_ALLOC_READ_EXEC``
|
||||||
|
Allocate memory for code to be executed in. The address space is configure for
|
||||||
|
read and execute.
|
||||||
|
|
||||||
|
.. _rtems_rtl_alloc_cmd:
|
||||||
|
.. index:: rtems_rtl_alloc_cmd
|
||||||
|
|
||||||
|
The commands are used to control the action the allocator performs. The
|
||||||
|
``rtems_rtl_alloc_cmd`` are:
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_NEW
|
||||||
|
``RTEMS_RTL_ALLOC_NEW``
|
||||||
|
Allocate memory of the ``tag`` type. Returns ``NULL`` if the allocation fails.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_DEL
|
||||||
|
``RTEMS_RTL_ALLOC_DEL``
|
||||||
|
Delete a previous allocation freeing the memory. The ``tag`` has to match
|
||||||
|
address of the memory being deleted.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_WR_ENABLE
|
||||||
|
``RTEMS_RTL_ALLOC_WR_ENABLE``
|
||||||
|
Enable writes to a region of memory previously allocated. The ``tag`` has to
|
||||||
|
match the address of the memory being write enabled. The link editor may call
|
||||||
|
issue this command for memory that is already write enabled.
|
||||||
|
|
||||||
|
.. index:: RTEMS_RTL_ALLOC_WR_DISABLE
|
||||||
|
``RTEMS_RTL_ALLOC_WR_DISABLE``
|
||||||
|
Disable writes to a region of memory previously allocated. The ``tag`` has to
|
||||||
|
match address of the memory being write disabled. The link editor may call
|
||||||
|
issue this command for memory that is writable and not to be write
|
||||||
|
disabled. The allocator need to manage this case.
|
||||||
|
|
||||||
|
.. _rtems_rtl_allocator:
|
||||||
|
.. index:: rtems_rtl_allocator
|
||||||
|
|
||||||
|
The allocator handler is a single call to handle all allocator requests. The
|
||||||
|
handler called on evey allocation action made by the link editor. The type of
|
||||||
|
the function you need is:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
typedef void (*rtems_rtl_allocator)(rtems_rtl_alloc_cmd cmd,
|
||||||
|
rtems_rtl_alloc_tag tag,
|
||||||
|
void** address,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
The arguments are:
|
||||||
|
|
||||||
|
``cmd``
|
||||||
|
The command to action. See :ref:`_rtems_rtl_alloc_cmd`.
|
||||||
|
|
||||||
|
``tag``
|
||||||
|
The type of memory the command is for. The ``tag`` must match the address for
|
||||||
|
commands other than ``RTEMS_RTL_ALLOC_OBJECT``.
|
||||||
|
|
||||||
|
``address``
|
||||||
|
Pointer to the address. This is set of the ``RTEMS_RTL_ALLOC_OBJECT`` command
|
||||||
|
and read for the other commands. The ``tag`` must match the address for
|
||||||
|
commands that read the address from the pointer.
|
||||||
|
|
||||||
|
``size``
|
||||||
|
The size of the memory to allocate. This is only valid for the
|
||||||
|
``RTEMS_RTL_ALLOC_OBJECT`` command.
|
||||||
|
|
||||||
|
The call to hook the allocator is:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
rtems_rtl_allocator rtems_rtl_alloc_hook (rtems_rtl_allocator handler);
|
||||||
|
|
||||||
|
The current allocator is returned. You can provide a full allocator or you can
|
||||||
|
filter commands.
|
||||||
|
|
||||||
|
Languages
|
||||||
|
---------
|
||||||
|
|
||||||
|
C is supported.
|
||||||
|
|
||||||
|
C++ is supported. Initializer functions are called when an object is loaded and
|
||||||
|
finalizer functions are called before it is unloaded and removed. Static
|
||||||
|
constructions are initializer functions and static destructors are finalizer
|
||||||
|
functions.
|
||||||
|
|
||||||
|
C++ exceptions are handled across modules. The compiler generated exception
|
||||||
|
tables present in an executable object file are registered with the architecture
|
||||||
|
specific mechanism when loaded and deregistered when unloaded. An exception
|
||||||
|
thrown in loaded code can be caught in the base image or another loaded
|
||||||
|
module. If you are using C++ and exceptions it is recommended some exception
|
||||||
|
code is added to the base image to place the architecture specific support in
|
||||||
|
the base image.
|
||||||
|
|
||||||
|
Thread Local Storage
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Thread local storage (TLS) is currenly not supported by the RTEMS link
|
||||||
|
editor. The RTEMS executive needs to have a special allocator added to manage
|
||||||
|
dynamically allocating TLS variables in a thread.
|
||||||
|
|
||||||
|
If you need TLS support in dynamically loaded code please consider the RTEMS
|
||||||
|
support options.
|
||||||
|
|
||||||
|
Architectures
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The following architectures are supported:
|
||||||
|
|
||||||
|
- ARM
|
||||||
|
- Blackfin
|
||||||
|
- H8300
|
||||||
|
- Intel x86 (i386)
|
||||||
|
- LM32
|
||||||
|
- M68K
|
||||||
|
- MIPS
|
||||||
|
- Moxie
|
||||||
|
- PowerPC
|
||||||
|
- SPARC
|
||||||
|
- V850
|
||||||
|
|
||||||
|
ARM
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The ARM relocation backend supports veneers which is trampolines.
|
||||||
|
|
||||||
|
The veneer implementation is a single instruction and a 32bit target address
|
||||||
|
making the overhead 8 bytes for each veneer. The performance overhead is a
|
||||||
|
single instruction.
|
||||||
|
|
||||||
|
PowerPC
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
The PowerPC relocation backend support trampolines and small data.
|
||||||
|
|
||||||
|
The trampoline is four instructions and uses register 12 which the PowerPC ABI
|
||||||
|
reserves for scratch use. The implementation loads the counter register and
|
||||||
|
branches to the address it contains. The trampoline size is 16 bytes. The
|
||||||
|
performance overhead is four instructions.
|
||||||
|
|
||||||
|
The PowerPC relocation backend also supports small data. The sections of an
|
||||||
|
executable object file are parsed and small data are tagged as needing
|
||||||
|
architecture specific allocations. These sections are not allocated as part of
|
||||||
|
the standard section allocation. Small data sections are allocated in the global
|
||||||
|
small data region of memory. The size of this region is defined in the BSP's
|
||||||
|
linker command file by setting ``bsp_section_small_data_area_size`` variable:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
bsp_section_small_data_area_size = 65536;
|
||||||
|
|
||||||
|
The maximum size of the small data region is 65536 bytes. It is recommended code
|
||||||
|
built for loading uses the same settings for small base as the base image.
|
@ -90,6 +90,8 @@ requires:
|
|||||||
If you are unsure how to specify the build set for the architecture you wish to
|
If you are unsure how to specify the build set for the architecture you wish to
|
||||||
build, just ask the tool:
|
build, just ask the tool:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
$ ../source-builder/sb-set-builder --list-bsets <1>
|
$ ../source-builder/sb-set-builder --list-bsets <1>
|
||||||
RTEMS Source Builder - Set Builder, v4.11.0
|
RTEMS Source Builder - Set Builder, v4.11.0
|
||||||
Examining: config
|
Examining: config
|
||||||
@ -750,4 +752,3 @@ Install the kernel to our prefix:
|
|||||||
make[1]: Leaving directory '/c/opt/rtems/kernel/pc686'
|
make[1]: Leaving directory '/c/opt/rtems/kernel/pc686'
|
||||||
/c/opt/rtems/kernel/pc686
|
/c/opt/rtems/kernel/pc686
|
||||||
$
|
$
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
||||||
|
|
||||||
|
.. _RTEMSExecutableInfomation:
|
||||||
|
|
||||||
RTEMS Executable Infomation
|
RTEMS Executable Infomation
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
||||||
|
|
||||||
|
.. _RTEMSLinker:
|
||||||
|
|
||||||
RTEMS Linker
|
RTEMS Linker
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
.. Copyright (C) 2017 Chris Johns <chrisj@rtems.org>
|
||||||
|
|
||||||
|
.. _RTEMSSymbols:
|
||||||
|
|
||||||
RTEMS Symbols
|
RTEMS Symbols
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user