From 8a73acb71305c58c6ea58aa0da84d4adb4c125cc Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Fri, 15 Feb 2019 16:03:59 +1100 Subject: [PATCH] user: Add a Dynamic Loader section. --- images/user/libdl-load.png | Bin 0 -> 38044 bytes images/user/libdl-load.puml | 39 ++ images/user/libdl.ditaa | 42 ++ images/user/libdl.png | Bin 0 -> 26974 bytes user/exe/executables.rst | 2 + user/exe/execution.rst | 2 + user/exe/index.rst | 5 +- user/exe/loader.rst | 866 ++++++++++++++++++++++++++++++++ user/installation/developer.rst | 3 +- user/tools/exeinfo.rst | 2 + user/tools/linker.rst | 2 + user/tools/symbols.rst | 2 + 12 files changed, 962 insertions(+), 3 deletions(-) create mode 100644 images/user/libdl-load.png create mode 100644 images/user/libdl-load.puml create mode 100644 images/user/libdl.ditaa create mode 100644 images/user/libdl.png create mode 100644 user/exe/loader.rst diff --git a/images/user/libdl-load.png b/images/user/libdl-load.png new file mode 100644 index 0000000000000000000000000000000000000000..10aafcfe65f44599760f1c01ec0d37df9c42e947 GIT binary patch literal 38044 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

Y@G_2^T3s&$GsA2&=mwdf#sz6PZexknm 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 F{{i_LmBIi3 literal 0 HcmV?d00001 diff --git a/images/user/libdl-load.puml b/images/user/libdl-load.puml new file mode 100644 index 0000000..b9ae20d --- /dev/null +++ b/images/user/libdl-load.puml @@ -0,0 +1,39 @@ +' +' Libdl Load Executable Object file +' +' Copyright (c) 2019 Chris Johns +' 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 diff --git a/images/user/libdl.ditaa b/images/user/libdl.ditaa new file mode 100644 index 0000000..c317dd1 --- /dev/null +++ b/images/user/libdl.ditaa @@ -0,0 +1,42 @@ +' +' Executable debugging : QEMU +' +' Copyright (c) 2018 Chris Johns +' 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 diff --git a/images/user/libdl.png b/images/user/libdl.png new file mode 100644 index 0000000000000000000000000000000000000000..f1446dde068a422fd93cece4ddc93de81228726e GIT binary patch literal 26974 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

NaBwWKTB=j--zcKM@Q3# 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 +.. _TargetExecution: + Target Execution ================ .. index:: Target Execution diff --git a/user/exe/index.rst b/user/exe/index.rst index 136a410..02dab19 100644 --- a/user/exe/index.rst +++ b/user/exe/index.rst @@ -11,10 +11,11 @@ Executables 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 -created, what happens when an executable is loaded and run as well as -debugging an execiutable. +created, what happens when an executable is loaded and run, debugging an +execiutable, and creating and dynamically loading code. .. include:: executables.rst .. include:: execution.rst .. include:: initialization.rst .. include:: debugging.rst +.. include:: loader.rst diff --git a/user/exe/loader.rst b/user/exe/loader.rst new file mode 100644 index 0000000..77d7cda --- /dev/null +++ b/user/exe/loader.rst @@ -0,0 +1,866 @@ +.. SPDX-License-Identifier: CC-BY-SA-4.0 + +.. Copyright (C) 2019 Chris Johns + +.. 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 ````. 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 ````) 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 + #include + #include + + 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() ` 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() ` 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 + #include + #include + + 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 + #include + #include + + 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() ` 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() `. 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() ` 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() ` 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. diff --git a/user/installation/developer.rst b/user/installation/developer.rst index 70d676e..90912cc 100644 --- a/user/installation/developer.rst +++ b/user/installation/developer.rst @@ -90,6 +90,8 @@ requires: If you are unsure how to specify the build set for the architecture you wish to build, just ask the tool: +.. code-block:: shell + $ ../source-builder/sb-set-builder --list-bsets <1> RTEMS Source Builder - Set Builder, v4.11.0 Examining: config @@ -750,4 +752,3 @@ Install the kernel to our prefix: make[1]: Leaving directory '/c/opt/rtems/kernel/pc686' /c/opt/rtems/kernel/pc686 $ - diff --git a/user/tools/exeinfo.rst b/user/tools/exeinfo.rst index 5e5948c..1913986 100644 --- a/user/tools/exeinfo.rst +++ b/user/tools/exeinfo.rst @@ -2,6 +2,8 @@ .. Copyright (C) 2017 Chris Johns +.. _RTEMSExecutableInfomation: + RTEMS Executable Infomation =========================== diff --git a/user/tools/linker.rst b/user/tools/linker.rst index 73c892b..474f3c9 100644 --- a/user/tools/linker.rst +++ b/user/tools/linker.rst @@ -2,6 +2,8 @@ .. Copyright (C) 2017 Chris Johns +.. _RTEMSLinker: + RTEMS Linker ============ diff --git a/user/tools/symbols.rst b/user/tools/symbols.rst index 869baf2..16e04ee 100644 --- a/user/tools/symbols.rst +++ b/user/tools/symbols.rst @@ -2,6 +2,8 @@ .. Copyright (C) 2017 Chris Johns +.. _RTEMSSymbols: + RTEMS Symbols =============