summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/include/rtems/rtl')
-rw-r--r--cpukit/include/rtems/rtl/dlfcn-shell.h17
-rw-r--r--cpukit/include/rtems/rtl/rap-shell.h14
-rw-r--r--cpukit/include/rtems/rtl/rap.h115
-rw-r--r--cpukit/include/rtems/rtl/rtl-allocator.h181
-rw-r--r--cpukit/include/rtems/rtl/rtl-fwd.h33
-rw-r--r--cpukit/include/rtems/rtl/rtl-indirect-ptr.h235
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-cache.h132
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-comp.h122
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-fwd.h39
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj.h635
-rw-r--r--cpukit/include/rtems/rtl/rtl-sym.h135
-rw-r--r--cpukit/include/rtems/rtl/rtl-trace.h102
-rw-r--r--cpukit/include/rtems/rtl/rtl-unresolved.h212
-rw-r--r--cpukit/include/rtems/rtl/rtl.h321
14 files changed, 2293 insertions, 0 deletions
diff --git a/cpukit/include/rtems/rtl/dlfcn-shell.h b/cpukit/include/rtems/rtl/dlfcn-shell.h
new file mode 100644
index 0000000000..9383577d25
--- /dev/null
+++ b/cpukit/include/rtems/rtl/dlfcn-shell.h
@@ -0,0 +1,17 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(_DLFCN_SHELL_H_)
+#define _DLFCN_SHELL_H_
+
+int shell_dlopen (int argc, char* argv[]);
+int shell_dlclose (int argc, char* argv[]);
+int shell_dlsym (int argc, char* argv[]);
+int shell_dlcall (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rap-shell.h b/cpukit/include/rtems/rtl/rap-shell.h
new file mode 100644
index 0000000000..c2d9112c0f
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rap-shell.h
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(_RAP_SHELL_H_)
+#define _RAP_SHELL_H_
+
+int shell_rap (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rap.h b/cpukit/include/rtems/rtl/rap.h
new file mode 100644
index 0000000000..0b86553e2b
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rap.h
@@ -0,0 +1,115 @@
+/*
+ * COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rap
+ *
+ * @brief RTEMS Application Loader
+ *
+ * This is the RTEMS Application loader for files in the RAP format.
+ */
+
+#if !defined (_RAP_H_)
+#define _RAP_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rap RTEMS Application Loader
+ *
+ * The module implements an application loader for files in the RAP format. The
+ * RAP format is:
+ *
+ * <header>
+ * <compressed container>
+ *
+ * The compressed container is a stream of ELF relocatable object files.
+ *
+ * TBD.
+ */
+
+/**
+ * The module iterator handle.
+ */
+typedef bool (*rtems_rap_iterator_t) (void* handle);
+
+/**
+ * Load an application.
+ *
+ * @param name The name of the application file.
+ * @return bool True if the module loads else an error.
+ */
+bool rtems_rap_load (const char* name, int mode, int argc, const char* argv[]);
+
+/**
+ * Unload an application.
+ *
+ * @param obj The application descriptor.
+ * @retval true The application file has been unloaded.
+ * @retval false The application could not be unloaded.
+ */
+bool rtems_rap_unload (const char* name);
+
+/**
+ * Find the application handle given a file name.
+ *
+ * @param name The name of the application file. It can be absolute or
+ * relative. Relative names can the basename with an extension.
+ * @retval NULL No application file with that name found.
+ * @return void* The application descriptor.
+ */
+void* rtems_rap_find (const char* name);
+
+/**
+ * Run an iterator over the modules calling the iterator function.
+ *
+ * @param iterator The iterator function.
+ * @retval true The iterator function returned did not return false.
+ * @retval false The iterator function returned false..
+ */
+bool rtems_rap_iterate (rtems_rap_iterator_t iterator);
+
+/**
+ * Return the name of the module given a handle.
+ *
+ * @param handle The module handle.
+ * @return const char* The name of the module if the handle is valid else it
+ * is NULL.
+ */
+const char* rtems_rap_name (void* handle);
+
+/**
+ * Return the DL handle used to load the module given the RAP handle.
+ *
+ * @param handle The module handle.
+ * @return void* The DL handle returned by the dlopen call.
+ */
+void* rtems_rap_dl_handle (void* handle);
+
+/**
+ * Get the last error message clearing it. This call is not thread safe is
+ * multiple threads are loading object files at the same time. This call
+ * follows the model provided by the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rap_get_error (char* message, size_t max_message);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
new file mode 100644
index 0000000000..e8044ee1e8
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -0,0 +1,181 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator
+ */
+
+#if !defined (_RTEMS_RTL_ALLOCATOR_H_)
+#define _RTEMS_RTL_ALLOCATOR_H_
+
+#include <stdbool.h>
+
+#include "rtl-indirect-ptr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Define the types of allocation the loader requires.
+ *
+ * @note It is best to use the object tag for general memory allocation and to
+ * leave the tags with specific access properties to the module data
+ */
+enum rtems_rtl_alloc_tags_e {
+ RTEMS_RTL_ALLOC_OBJECT, /**< A generic memory object. */
+ RTEMS_RTL_ALLOC_SYMBOL, /**< Memory used for symbols. */
+ RTEMS_RTL_ALLOC_EXTERNAL, /**< Memory used for external symbols. */
+ RTEMS_RTL_ALLOC_READ, /**< The memory is read only. */
+ RTEMS_RTL_ALLOC_READ_WRITE, /**< The memory is read and write. */
+ RTEMS_RTL_ALLOC_READ_EXEC /**< The memory is read and executable. */
+};
+
+/**
+ * The allocator tag type.
+ */
+typedef enum rtems_rtl_alloc_tags_e rtems_rtl_alloc_tag_t;
+
+/**
+ * The number of tags.
+ */
+#define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
+
+/**
+ * Allocator handler handles all RTL allocations. It can be hooked and
+ * overridded for customised allocation schemes or memory maps.
+ *
+ * @param allocation If true the request is to allocate memory else free.
+ * @param tag The type of allocation request.
+ * @param address Pointer to the memory address. If an allocation the value is
+ * unspecific on entry and the allocated address or NULL on
+ * exit. The NULL value means the allocation failed. If a delete
+ * or free request the memory address is the block to free. A
+ * free request of NULL is silently ignored.
+ * @param size The size of the allocation if an allocation request and
+ * not used if deleting or freeing a previous allocation.
+ */
+typedef void (*rtems_rtl_allocator_t)(bool allocate,
+ rtems_rtl_alloc_tag_t tag,
+ void** address,
+ size_t size);
+
+/**
+ * The allocator data.
+ */
+struct rtems_rtl_alloc_data_s {
+ /**< The memory allocator handler. */
+ rtems_rtl_allocator_t allocator;
+ /**< The indirect pointer chains. */
+ rtems_chain_control indirects[RTEMS_RTL_ALLOC_TAGS];
+};
+
+typedef struct rtems_rtl_alloc_data_s rtems_rtl_alloc_data_t;
+
+/**
+ * Initialise the allocate data.
+ *
+ * @param data The data to initialise.
+ */
+void rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data);
+
+/**
+ * The Runtime Loader allocator new allocates new memory and optionally clear
+ * the memory if requested.
+ *
+ * @param tag The type of allocation request.
+ * @param size The size of the allocation.
+ * @param zero If true the memory is cleared.
+ * @return void* The memory address or NULL is not memory available.
+ */
+void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero);
+
+/**
+ * The Runtime Loader allocator delete deletes allocated memory.
+ *
+ * @param tag The type of allocation request.
+ * @param address The memory address to delete. A NULL is ignored.
+ */
+void rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address);
+
+/**
+ * Hook the Runtime Loader allocatior. A handler can call the previous handler
+ * in the chain to use it for specific tags. The default handler uses the
+ * system heap. Do not unhook your handler if memory it allocates has not been
+ * returned.
+ *
+ * @param handler The handler to use as the allocator.
+ * @return rtems_rtl_alloc_handler_t The previous handler.
+ */
+rtems_rtl_allocator_t rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler);
+
+/**
+ * Allocate memory to an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to allocate the memory to.
+ * @param size The size of the allocation.
+ */
+void rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
+ rtems_rtl_ptr_t* handle,
+ size_t size);
+
+/**
+ * Free memory from an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to free the memory from.
+ */
+void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
+ rtems_rtl_ptr_t* handle);
+
+/**
+ * Allocate the memory for a module given the size of the text, const, data and
+ * bss sections. If any part of the allocation fails the no memory is
+ * allocated.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param text_size The size of the read/exec section.
+ * @param const_base Pointer to the const base pointer.
+ * @param const_size The size of the read only section.
+ * @param eh_base Pointer to the eh base pointer.
+ * @param eh_size The size of the eh section.
+ * @param data_base Pointer to the data base pointer.
+ * @param data_size The size of the read/write secton.
+ * @param bss_base Pointer to the bss base pointer.
+ * @param bss_size The size of the read/write.
+ * @retval true The memory has been allocated.
+ * @retval false The allocation of memory has failed.
+ */
+bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
+ void** const_base, size_t const_size,
+ void** eh_base, size_t eh_size,
+ void** data_base, size_t data_size,
+ void** bss_base, size_t bss_size);
+
+/**
+ * Free the memory allocated to a module.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param const_base Pointer to the const base pointer.
+ * @param eh_base Pointer to the eh base pointer.
+ * @param data_base Pointer to the data base pointer.
+ * @param bss_base Pointer to the bss base pointer.
+ */
+void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
+ void** eh_base, void** data_base,
+ void** bss_base);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-fwd.h b/cpukit/include/rtems/rtl/rtl-fwd.h
new file mode 100644
index 0000000000..4641ad5d5e
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-fwd.h
@@ -0,0 +1,33 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_FWD_H_)
+#define _RTEMS_RTL_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_data_s;
+typedef struct rtems_rtl_data_s rtems_rtl_data_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-indirect-ptr.h b/cpukit/include/rtems/rtl/rtl-indirect-ptr.h
new file mode 100644
index 0000000000..81503a3b45
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-indirect-ptr.h
@@ -0,0 +1,235 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
+ * compaction in the allocator.
+ */
+
+#if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
+#define _RTEMS_RTL_INDIRECT_PTR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <rtems/chain.h>
+
+/**
+ * The RTL Indirect pointer.
+ */
+struct rtems_rtl_ptr_s {
+ rtems_chain_node node; /**< Indirect pointers are held on lists. */
+ void* pointer; /**< The actual pointer. */
+};
+
+typedef struct rtems_rtl_ptr_s rtems_rtl_ptr_t;
+
+/**
+ * The RTL Indirect size and pointer.
+ */
+struct rtems_rtl_sptr_s {
+ rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
+ size_t size; /**< The size of the memory block. */
+};
+
+typedef struct rtems_rtl_sptr_s rtems_rtl_sptr_t;
+
+/**
+ * A chain of indirect pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ * used by applications.
+ */
+struct rtems_rtl_ptr_chain_s {
+ rtems_chain_node node; /**< Chain of indirect pointers. */
+ rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_ptr_chain_s rtems_rtl_ptr_chain_t;
+
+/**
+ * A chain of indirect sized pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ * used by applications.
+ */
+struct rtems_rtl_sptr_chain_s {
+ rtems_chain_node node; /**< Chain of indirect pointers. */
+ rtems_rtl_sptr_t ptr; /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_sptr_chain_s rtems_rtl_sptr_chain_t;
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr_t* handle)
+{
+ return handle->pointer;
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_ptr_set (rtems_rtl_ptr_t* handle, void* pointer)
+{
+ handle->pointer = pointer;
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_ptr_init (rtems_rtl_ptr_t* handle)
+{
+ rtems_chain_set_off_chain (&handle->node);
+ handle->pointer = NULL;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr_t* handle)
+{
+ return handle->pointer == NULL;
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_ptr_move (rtems_rtl_ptr_t* dst, rtems_rtl_ptr_t* src)
+{
+ /*
+ * We do not know which chain the src handle resides on so insert the dst
+ * handle after the src handle then extract the src handle.
+ */
+ rtems_chain_insert_unprotected (&src->node, &dst->node);
+ rtems_chain_extract_unprotected (&src->node);
+ dst->pointer = src->pointer;
+ rtems_rtl_ptr_init (src);
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr_t* handle)
+{
+ return rtems_rtl_ptr_get (&handle->ptr);
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_sptr_set (rtems_rtl_sptr_t* handle, void* pointer)
+{
+ rtems_rtl_ptr_set (&handle->ptr, pointer);
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_sptr_init (rtems_rtl_sptr_t* handle)
+{
+ rtems_rtl_ptr_init (&handle->ptr);
+ handle->size = 0;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr_t* handle)
+{
+ return rtems_rtl_ptr_null (&handle->ptr);
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_sptr_move (rtems_rtl_sptr_t* dst, rtems_rtl_sptr_t* src)
+{
+ rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
+ dst->size = src->size;
+ src->size = 0;
+}
+
+/**
+ * Get the size.
+ *
+ * @param handle The handle to get the size from.
+ * @return size_t The size_t.
+ */
+static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr_t* handle)
+{
+ return handle->size;
+}
+
+/**
+ * Set the size.
+ *
+ * @param handle The handle to set the size.
+ * @param size The size to set..
+ */
+static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr_t* handle, size_t size)
+{
+ handle->size = size;
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-cache.h b/cpukit/include/rtems/rtl/rtl-obj-cache.h
new file mode 100644
index 0000000000..8eacdd316b
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-cache.h
@@ -0,0 +1,132 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File cache buffers a section of the
+ * object file in a buffer to localise read performance.
+ *
+ * This is a simple object file cache that holds a buffer of data from the
+ * offset in the file the read is requested from. Writes are not supported.
+ *
+ * The cache holds the file descriptor, the offset into the file and the amount
+ * of valid data in the cache. If the file is ever modified the user of the
+ * cache to responsible for flushing the cache. For example the cache should be
+ * flused if the file is closed.
+ *
+ * The cache can return by reference or by value. By reference allow access to
+ * the cache buffer. Do not modify the cache's data. By value will copy the
+ * requested data into the user supplied buffer.
+ *
+ * The read by reference call allows you to probe the file's data. For example
+ * a string in an object file can be an unknown length. You can request a read
+ * up to the cache's size by reference. The code will attempt to have this data
+ * in the buffer. If there is not enough data in the file the length will be
+ * modifed to reflect this.
+ *
+ * You can have more than one cache for a single file all looking at different
+ * parts of the file.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_CACHE_H_)
+#define _RTEMS_RTL_OBJ_CACHE_H_
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The buffer cache.
+ */
+typedef struct rtems_rtl_obj_cache_s
+{
+ int fd; /**< The file descriptor of the data in the cache. */
+ size_t file_size; /**< The size of the file. */
+ off_t offset; /**< The base offset of the buffer. */
+ size_t size; /**< The size of the cache. */
+ size_t level; /**< The amount of data in the cache. A file can be
+ * smaller than the cache file. */
+ uint8_t* buffer; /**< The buffer */
+} rtems_rtl_obj_cache_t;
+
+/**
+ * Open a cache allocating a single buffer of the size passed. The default
+ * state of the cache is flushed. No already open checks are made.
+ *
+ * @param cache The cache to initialise.
+ * @param size The size of the cache.
+ * @retval true The cache is open.
+ * @retval false The cache is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size);
+
+/**
+ * Close a cache.
+ *
+ * @param cache The cache to close.
+ */
+void rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Flush the cache. Any further read will read the data from the file.
+ *
+ * @param cache The cache to flush.
+ */
+void rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Read data by reference. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param cache The cache to reference data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to reference the data to.
+ * @param buffer The location to reference the data from.
+ * @param length The length of data to reference. Can be modified to a
+ * lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache,
+ int fd,
+ off_t offset,
+ void** buffer,
+ size_t* length);
+
+/**
+ * Read data by value. The data is copied to the user supplied buffer.
+ *
+ * @param cache The cache to read the data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to read the data from.
+ * @param buffer The location the data is written into.
+ * @param length The length of data to read.
+ * @retval true The data has been read from the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read_byval (rtems_rtl_obj_cache_t* cache,
+ int fd,
+ off_t offset,
+ void* buffer,
+ size_t length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-comp.h b/cpukit/include/rtems/rtl/rtl-obj-comp.h
new file mode 100644
index 0000000000..34bfa6ffa1
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-comp.h
@@ -0,0 +1,122 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Compression manages a
+ * compressed stream of data.
+ *
+ * This is a simple interface to the object file cache to stream data from
+ * from a compressed object file. There is no ability to seek with the
+ * data from a compressed file. The module exists to allocate the output
+ * buffer when the loader starts and use the cache buffers will have been
+ * allocated.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_COMP_H_)
+#define _RTEMS_RTL_OBJ_COMP_H_
+
+#include <rtems/rtl/rtl-obj-cache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The amount of input data read at a time from the file.
+ */
+#define RTEMS_RTL_DECOMP_INPUT_SIZE (256)
+
+/**
+ * The types of supported compression.
+ */
+#define RTEMS_RTL_COMP_NONE (0)
+#define RTEMS_RTL_COMP_LZ77 (1)
+
+/**
+ * The compressed file.
+ */
+typedef struct rtems_rtl_obj_cpmp_s
+{
+ rtems_rtl_obj_cache_t* cache; /**< The cache provides the input
+ * buffer. */
+ int fd; /**< The file descriptor. */
+ int compression; /**< The type of compression. */
+ off_t offset; /**< The base offset of the buffer. */
+ size_t size; /**< The size of the output buffer. */
+ size_t level; /**< The amount of data in the buffer. */
+ uint8_t* buffer; /**< The buffer */
+ uint32_t read; /**< The amount of data read. */
+} rtems_rtl_obj_comp_t;
+
+/**
+ * Return the input level.
+ */
+static inline uint32_t rtems_rtl_obj_comp_input (rtems_rtl_obj_comp_t* comp)
+{
+ return comp->read;
+}
+
+/**
+ * Open a compressor allocating the output buffer.
+ *
+ * @param comp The compressor to initialise.
+ * @param size The size of the compressor's output buffer.
+ * @retval true The compressor is open.
+ * @retval false The compressor is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_comp_open (rtems_rtl_obj_comp_t* comp,
+ size_t size);
+
+/**
+ * Close a compressor.
+ *
+ * @param comp The compressor to close.
+ */
+void rtems_rtl_obj_comp_close (rtems_rtl_obj_comp_t* comp);
+
+/**
+ * Set the cache and offset in the file the compressed stream starts.
+ *
+ * @param comp The compressor to set the offset in.
+ * @param cache The cache to read the file in by.
+ * @param fd The file descriptor. Must be an open file.
+ * @param compression The type of compression being streamed.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp_set (rtems_rtl_obj_comp_t* comp,
+ rtems_rtl_obj_cache_t* cache,
+ int fd,
+ int compression,
+ off_t offset);
+
+/**
+ * Read decompressed data. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param comp The compressor to read data from.
+ * @param buffer The buffer the output is written too.
+ * @param length The length of data to read. Can be modified to a
+ * lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_comp_read (rtems_rtl_obj_comp_t* comp,
+ void* buffer,
+ size_t length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-fwd.h b/cpukit/include/rtems/rtl/rtl-obj-fwd.h
new file mode 100644
index 0000000000..2c53244316
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-fwd.h
@@ -0,0 +1,39 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_FWD_H_)
+#define _RTEMS_RTL_OBJ_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj section structure.
+ */
+struct rtems_rtl_obj_sect_s;
+typedef struct rtems_rtl_obj_sect_s rtems_rtl_obj_sect_t;
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_obj_s;
+typedef struct rtems_rtl_obj_s rtems_rtl_obj_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h
new file mode 100644
index 0000000000..6a35a72822
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -0,0 +1,635 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_H_)
+#define _RTEMS_RTL_OBJ_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/rtl/rtl-sym.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Loader format flags.
+ */
+#define RTEMS_RTL_FMT_ELF (1 << 0)
+#define RTEMS_RTL_FMT_COMP (1 << 1)
+#define RTEMS_RTL_FMT_PRIVATE (1 << 16)
+
+/**
+ * Loader format definition.
+ */
+typedef struct rtems_rtl_loader_format_s
+{
+ /**
+ * The format label. This can be used to determine and manage
+ * specific formats.
+ */
+ const char* label;
+
+ /**
+ * The format flags.
+ */
+ uint32_t flags;
+} rtems_rtl_loader_format_t;
+
+/**
+ * The type of the format loader check handler. This handler checks the format
+ * and if it is detected as suitable it returns true.
+ */
+typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader load handler. This handler loads the specific
+ * format.
+ */
+typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader unload handler. This handler unloads the
+ * specific format.
+ */
+typedef bool (*rtems_rtl_loader_unload) (rtems_rtl_obj_t* obj);
+
+/**
+ * The type of the format loader signature handler. This handler checks the
+ * format signature.
+ */
+typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
+
+/**
+ * Table for supported loadable formats.
+ */
+typedef struct rtems_rtl_loader_table_s
+{
+ rtems_rtl_loader_check check; /**< The check handler. */
+ rtems_rtl_loader_load load; /**< The loader. */
+ rtems_rtl_loader_unload unload; /**< The unloader. */
+ rtems_rtl_loader_sig signature; /**< The loader's signature. */
+} rtems_rtl_loader_table_t;
+
+/**
+ * Flags for the various section types.
+ */
+#define RTEMS_RTL_OBJ_SECT_TEXT (1 << 0) /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1) /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_DATA (1 << 2) /**< Section holds program data. */
+#define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */
+#define RTEMS_RTL_OBJ_SECT_EH (1 << 4) /**< Section holds exception data. */
+#define RTEMS_RTL_OBJ_SECT_REL (1 << 5) /**< Section holds relocation records. */
+#define RTEMS_RTL_OBJ_SECT_RELA (1 << 6) /**< Section holds relocation addend
+ * records. */
+#define RTEMS_RTL_OBJ_SECT_SYM (1 << 7) /**< Section holds symbols. */
+#define RTEMS_RTL_OBJ_SECT_STR (1 << 8) /**< Section holds strings. */
+#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 9) /**< Section allocates runtime memory. */
+#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 10) /**< Section is loaded from object file. */
+#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 11) /**< Section is writable, ie data. */
+#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 12) /**< Section is executable. */
+#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 13) /**< Section is preset to zero. */
+#define RTEMS_RTL_OBJ_SECT_LINK (1 << 14) /**< Section is link-ordered. */
+#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 15) /**< Section contains constructors. */
+#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 16) /**< Section contains destructors. */
+#define RTEMS_RTL_OBJ_SECT_LOCD (1 << 17) /**< Section has been located. */
+
+/**
+ * Section types mask.
+ */
+#define RTEMS_RTL_OBJ_SECT_TYPES (RTEMS_RTL_OBJ_SECT_TEXT | \
+ RTEMS_RTL_OBJ_SECT_CONST | \
+ RTEMS_RTL_OBJ_SECT_DATA | \
+ RTEMS_RTL_OBJ_SECT_BSS | \
+ RTEMS_RTL_OBJ_SECT_EH)
+
+/**
+ * An object file is made up of sections and the can be more than
+ * one of a specific type of sections. All sections and grouped
+ * together in memory.
+ */
+struct rtems_rtl_obj_sect_s
+{
+ rtems_chain_node node; /**< The node's link in the chain. */
+ int section; /**< The section number. */
+ const char* name; /**< The section's name. */
+ size_t size; /**< The size of the section in memory. */
+ off_t offset; /**< Offset into the object file. Relative to
+ * the start of the object file. */
+ uint32_t alignment; /**< Alignment of this section. */
+ int link; /**< Section link field. */
+ int info; /**< Secfion info field. */
+ uint32_t flags; /**< The section's flags. */
+ void* base; /**< The base address of the section in
+ * memory. */
+ int load_order; /**< Order we load sections. */
+};
+
+/**
+ * Object file descriptor flags.
+ */
+#define RTEMS_RTL_OBJ_LOCKED (1 << 0) /**< Lock the object file so it cannot
+ * be unloaded. */
+#define RTEMS_RTL_OBJ_UNRESOLVED (1 << 1) /**< The object file has unresolved
+ * external symbols. */
+
+/**
+ * RTL Object. There is one for each object module loaded plus one for the base
+ * kernel image.
+ */
+struct rtems_rtl_obj_s
+{
+ rtems_chain_node link; /**< The node's link in the chain. */
+ uint32_t flags; /**< The status of the object file. */
+ uint32_t users; /**< References to the object file. */
+ int format; /**< The format of the object file. */
+ const char* fname; /**< The file name for the object. */
+ const char* oname; /**< The object file name. Can be
+ * relative. */
+ const char* aname; /**< The archive name containing the
+ * object. NULL means the object is not
+ * in a lib */
+ off_t ooffset; /**< The object offset in the archive. */
+ size_t fsize; /**< Size of the object file. */
+ rtems_chain_control sections; /**< The sections of interest in the
+ * object file. */
+ rtems_rtl_obj_sym_t* local_table; /**< Local symbol table. */
+ size_t local_syms; /**< Local symbol count. */
+ size_t local_size; /**< Local symbol memory usage. */
+ rtems_rtl_obj_sym_t* global_table; /**< Global symbol table. */
+ size_t global_syms; /**< Global symbol count. */
+ size_t global_size; /**< Global symbol memory usage. */
+ uint32_t unresolved; /**< The number of unresolved relocations. */
+ void* text_base; /**< The base address of the text section
+ * in memory. */
+ size_t text_size; /**< The size of the text section. */
+ void* const_base; /**< The base address of the const section
+ * in memory. */
+ void* eh_base; /**< The base address of the eh section
+ * in memory. */
+ size_t eh_size; /**< The size of the eh section. */
+ void* data_base; /**< The base address of the data section
+ * in memory. */
+ void* bss_base; /**< The base address of the bss section
+ * in memory. */
+ size_t bss_size; /**< The size of the bss section. */
+ size_t exec_size; /**< The amount of executable memory
+ * allocated */
+ void* entry; /**< The entry point of the module. */
+ uint32_t checksum; /**< The checksum of the text sections. A
+ * zero means do not checksum. */
+ uint32_t* sec_num; /**< The sec nums of each obj. */
+ uint32_t obj_num; /**< The count of elf files in an rtl obj. */
+ struct link_map* linkmap; /**< For GDB. */
+ void* loader; /**< The file details specific to a loader. */
+};
+
+/**
+ * A section handler is called once for each section that needs to be
+ * processed by this handler.
+ *
+ * @param obj The object file's descriptor the section belongs too.
+ * @param fd The file descriptor of the object file beling loaded.
+ * @param sect The section the handler is being invoked to handle.
+ * @param data A user supplied data variable.
+ * @retval true The operation was successful.
+ * @retval false The operation failed and the RTL has been set.
+ */
+typedef bool (*rtems_rtl_obj_sect_handler_t)(rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_t* sect,
+ void* data);
+
+/**
+ * Get the file name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_fname (const rtems_rtl_obj_t* obj)
+{
+ return obj->fname;
+}
+
+/**
+ * Is the file name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is a file name
+ */
+static inline bool rtems_rtl_obj_fname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->fname;
+}
+
+/**
+ * Get the object name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_oname (const rtems_rtl_obj_t* obj)
+{
+ return obj->oname;
+}
+
+/**
+ * Is the object name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an object name
+ */
+static inline bool rtems_rtl_obj_oname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->oname;
+}
+
+/**
+ * Get the archive name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_aname (const rtems_rtl_obj_t* obj)
+{
+ return obj->aname;
+}
+
+/**
+ * Is the archive name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an archive name
+ */
+static inline bool rtems_rtl_obj_aname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->aname;
+}
+
+/**
+ * Is the address inside the text section?
+ *
+ * @param obj The object file.
+ * @return bool There is an archive name
+ */
+static inline bool rtems_rtl_obj_text_inside (const rtems_rtl_obj_t* obj,
+ const void* address)
+{
+ return
+ (address >= obj->text_base) &&
+ (address < (obj->text_base + obj->text_size));
+}
+
+/**
+ * Allocate an object structure on the heap.
+ *
+ * @retval NULL No memory for the object.
+ */
+rtems_rtl_obj_t* rtems_rtl_obj_alloc (void);
+
+/**
+ * Free the object structure and related resources.
+ *
+ * @param obj The object file's descriptor to free.
+ * @retval false The object has dependences.
+ * @retval true The object has been freed.
+ */
+bool rtems_rtl_obj_free (rtems_rtl_obj_t* obj);
+
+/**
+ * Does the object file have unresolved external references ? If it does the
+ * results of executing code is unpredictable.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has unresolved externals.
+ * @retval false The object file has all external references resolved.
+ */
+bool rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj);
+
+/**
+ * Parses a filename and returns newly allocated strings with the archive name,
+ * object name, and the object's offset
+ *
+ * @param name The filename of the object
+ * @param aname Address of a string pointer that holds the archive name
+ * @param oname Address of a string pointer that holds the object name
+ * @param ooffset Address of an int that holds the object offset
+ * @retval true The parsing was successful
+ * @retval false The parsing was unsuccessful
+ */
+bool rtems_rtl_parse_name (const char* name,
+ const char** aname,
+ const char** oname,
+ off_t* ooffset);
+
+/**
+ * Check of the name matches the object file's object name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to match.
+ */
+bool rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Find an object file on disk that matches the name. The object descriptor is
+ * fill in with the various parts of a name. A name can have archive, object
+ * file and offset components. The search path in the RTL is searched.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to locate on disk.
+ * @retval true The file has been found.
+ * @retval false The file could not be located. The RTL error has been set.
+ */
+bool rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Add a section to the object descriptor.
+ *
+ * @param obj The object file's descriptor.
+ * @param section The section's index number.
+ * @param name The name of the section.
+ * @param size The size of the section in memory.
+ * @param offset The offset of the section in the object file.
+ * @param alignment The alignment of the section in memory.
+ * @param link The section's link field (from the ELF format).
+ * @param info The section's info field (from the ELF format).
+ * @param flags The section's flags.
+ * @retval true The section has been added.
+ * @retval false The section has not been added. See the RTL error.
+ */
+bool rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
+ int section,
+ const char* name,
+ size_t size,
+ off_t offset,
+ uint32_t alignment,
+ int link,
+ int info,
+ uint32_t flags);
+
+/**
+ * Erase the object file descriptor's sections.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj);
+
+/**
+ * Find the section given a name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name of the section to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The named section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
+ const char* name);
+
+/**
+ * Find a section given a section's index number.
+ *
+ * @param obj The object file's descriptor.
+ * @param index The section's index to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The found section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
+ int index);
+
+/**
+ * The text section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's text
+ * area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the text area of the object file.
+ */
+size_t rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The text section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * text type section loaded the text section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_text_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The const section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's const
+ * area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the const area of the object file.
+ */
+size_t rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The const section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * const type section loaded the const section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_const_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The eh section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's bss area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the bss area of the object file.
+ */
+size_t rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The eh section alignment for the object file. Only use once all the sections
+ * has been added. The section alignment is the alignment of the first bss type
+ * section loaded the bss section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_eh_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The data section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's data
+ * area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the data area of the object file.
+ */
+size_t rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The data section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * data type section loaded the data section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_data_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The bss section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's bss area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the bss area of the object file.
+ */
+size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The bss section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * bss type section loaded the bss section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * Relocate the object file. The object file's section are parsed for any
+ * relocation type sections.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific relocation handler.
+ * @param data User specific data handle.
+ * @retval true The object file was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Synchronize caches to make code visible to CPU(s)
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj);
+
+/**
+ * Relocate an object file's unresolved reference.
+ *
+ * @param rec The unresolved relocation record.
+ * @param sym The unresolved relocation's referenced symbol.
+ * @retval true The object file record was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
+ rtems_rtl_obj_sym_t* sym);
+
+/**
+ * Load the symbols from the object file. Only the exported or public symbols
+ * are read into memory and held in the global symbol table.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific symbol handler.
+ * @param data User specific data handle.
+ * @retval true The object file's symbol where loaded.
+ * @retval false The symbol loading failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Load the sections that have been allocated memory in the target. The bss
+ * type section does not load any data, it is set to 0. The text and data
+ * sections read the detault data from the object file into the target memory.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific load handler.
+ * @param data User specific data handle.
+ * @retval true The object has been sucessfully loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Invoke the constructors the object has. Constructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain constructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Invoke the destructors the object has. Destructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain destructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_dtors (rtems_rtl_obj_t* obj);
+
+/**
+ * Load the object file, reading all sections into memory, symbols and
+ * performing any relocation fixups.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load (rtems_rtl_obj_t* obj);
+
+/**
+ * Unload the object file, erasing all symbols and releasing all memory.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The unload failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_unload (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-sym.h b/cpukit/include/rtems/rtl/rtl-sym.h
new file mode 100644
index 0000000000..fe00da89d7
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-sym.h
@@ -0,0 +1,135 @@
+/*
+ * COPYRIGHT (c) 2012-2014 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Symbol Table.
+ */
+
+#if !defined (_RTEMS_RTL_SYM_H_)
+#define _RTEMS_RTL_SYM_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * An object file symbol.
+ */
+typedef struct rtems_rtl_obj_sym_s
+{
+ rtems_chain_node node; /**< The node's link in the chain. */
+ const char* name; /**< The symbol's name. */
+ void* value; /**< The value of the symbol. */
+ uint32_t data; /**< Format specific data. */
+} rtems_rtl_obj_sym_t;
+
+/**
+ * Table of symbols stored in a hash table.
+ */
+typedef struct rtems_rtl_symbols_s
+{
+ rtems_chain_control* buckets;
+ size_t nbuckets;
+} rtems_rtl_symbols_t;
+
+/**
+ * Open a symbol table with the specified number of buckets.
+ *
+ * @param symbols The symbol table to open.
+ * @param buckets The number of buckets in the hash table.
+ * @retval true The symbol is open.
+ * @retval false The symbol table could not created. The RTL
+ * error has the error.
+ */
+bool rtems_rtl_symbol_table_open (rtems_rtl_symbols_t* symbols,
+ size_t buckets);
+
+/**
+ * Close the table and erase the hash table.
+ *
+ * @param symbols Close the symbol table.
+ */
+void rtems_rtl_symbol_table_close (rtems_rtl_symbols_t* symbols);
+
+/**
+ * Add a table of exported symbols to the symbol table.
+ *
+ * The export table is a series of symbol records and each record has two
+ * fields:
+ *
+ * 1. label
+ * 2. address
+ *
+ * The 'label' is an ASCIIZ string of variable length. The address is of size
+ * of an unsigned long for the target running the link editor. The byte order
+ * is defined by the machine type because the table should be built by the
+ * target compiler.
+ *
+ * The table is terminated with a nul string followed by the bytes 0xDE, 0xAD,
+ * 0xBE, and 0xEF. This avoids alignments issues.
+ *
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj,
+ const unsigned char* esyms,
+ unsigned int size);
+
+/**
+ * Find a symbol given the symbol label in the global symbol table.
+ *
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_global_find (const char* name);
+
+/**
+ * Find a symbol given the symbol label in the local object file.
+ *
+ * @param obj The object file to search.
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj,
+ const char* name);
+
+/**
+ * Add the object file's symbols to the global table.
+ *
+ * @param obj The object file the symbols are to be added.
+ */
+void rtems_rtl_symbol_obj_add (rtems_rtl_obj_t* obj);
+
+/**
+ * Erase the object file's local symbols.
+ *
+ * @param obj The object file the local symbols are to be erased from.
+ */
+void rtems_rtl_symbol_obj_erase_local (rtems_rtl_obj_t* obj);
+
+/**
+ * Erase the object file's symbols.
+ *
+ * @param obj The object file the symbols are to be erased from.
+ */
+void rtems_rtl_symbol_obj_erase (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-trace.h b/cpukit/include/rtems/rtl/rtl-trace.h
new file mode 100644
index 0000000000..4b93c8c91c
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-trace.h
@@ -0,0 +1,102 @@
+/*
+ * COPYRIGHT (c) 2012-2014 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Trace Support.
+ */
+
+#if !defined (_RTEMS_RTL_TRACE_H_)
+#define _RTEMS_RTL_TRACE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * Set to 1 to build trace support in to the RTL code.
+ */
+#define RTEMS_RTL_TRACE 1
+
+/**
+ * The type of the mask.
+ */
+typedef uint32_t rtems_rtl_trace_mask;
+
+/**
+ * List of tracing bits for the various parts of the link editor.
+ */
+#define RTEMS_RTL_TRACE_DETAIL (1UL << 0)
+#define RTEMS_RTL_TRACE_WARNING (1UL << 1)
+#define RTEMS_RTL_TRACE_LOAD (1UL << 2)
+#define RTEMS_RTL_TRACE_UNLOAD (1UL << 3)
+#define RTEMS_RTL_TRACE_SECTION (1UL << 4)
+#define RTEMS_RTL_TRACE_SYMBOL (1UL << 5)
+#define RTEMS_RTL_TRACE_RELOC (1UL << 6)
+#define RTEMS_RTL_TRACE_GLOBAL_SYM (1UL << 7)
+#define RTEMS_RTL_TRACE_LOAD_SECT (1UL << 8)
+#define RTEMS_RTL_TRACE_ALLOCATOR (1UL << 9)
+#define RTEMS_RTL_TRACE_UNRESOLVED (1UL << 10)
+#define RTEMS_RTL_TRACE_CACHE (1UL << 11)
+#define RTEMS_RTL_TRACE_ALL (0xffffffffUL & ~(RTEMS_RTL_TRACE_CACHE))
+
+/**
+ * Call to check if this part is bring traced. If RTEMS_RTL_TRACE is defined to
+ * 0 the code is dead code elminiated when built with -Os, -O2, or higher.
+ *
+ * @param mask The part of the API to trace.
+ * @retval true Tracing is active for the mask.
+ * @retval false Do not trace.
+ */
+#if RTEMS_RTL_TRACE
+bool rtems_rtl_trace (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace(_m) (0)
+#endif
+
+/**
+ * Set the mask.
+ *
+ * @param mask The mask bits to set.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_set_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_set_mask(_m)
+#endif
+
+/**
+ * Clear the mask.
+ *
+ * @param mask The mask bits to clear.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_clear_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_clear_mask(_m)
+#endif
+
+/**
+ * Add shell trace shell command.
+ */
+#if RTEMS_RTL_TRACE
+int rtems_rtl_trace_shell_command (int argc, char *argv[]);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-unresolved.h b/cpukit/include/rtems/rtl/rtl-unresolved.h
new file mode 100644
index 0000000000..bd4ce2a215
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-unresolved.h
@@ -0,0 +1,212 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Unresolved Relocations Table.
+ *
+ * The unresolved relocation table holds relocations in a loaded object file
+ * which reference unresolved external symbols. The support is needed to allow
+ * dependent object files to load. In the case of dependent object files one
+ * will have unresolved externals until the dependent object file is also
+ * loaded. There is no load order that resolves this.
+ *
+ * The unresolved relocation table is a single table used by all object files
+ * with unresolved symbols. It made of blocks linked together where blocks are
+ * allocated as requiered. The table is always maintained compacted. That is as
+ * relocations are resolved and removed the table is compacted. The only
+ * pointer in the table is the object file poniter. This is used to identify
+ * which object the relocation belongs to. There are no linking or back
+ * pointers in the unresolved relocations table. The table is scanned for each
+ * object file's relocations. This is not fast but the table should be small
+ * and if it happens to grow large you have other more pressing issues to
+ * resolve in your application.
+ *
+ * The table holds two (2) types of records:
+ *
+ * # Symbol name strings.
+ * # Relocations.
+ *
+ * The symbol name a relocation references is held in a specific symbol name
+ * string record in the table the relocation record references. The record
+ * counts the number of references and the string is removed from the table
+ * when the reference count reaches 0. There can be many relocations
+ * referencing the symbol. The strings are referenced by a single 16bit
+ * unsigned integer which is the count of the string in the table.
+ *
+ * The section the relocation is for in the object is the section number. The
+ * relocation data is series of machine word sized fields:
+ *
+ * # Offset in the section.
+ * # Relocation info (format specific)
+ * # Additional format specific data.
+ */
+
+#if !defined (_RTEMS_RTL_UNRESOLVED_H_)
+#define _RTEMS_RTL_UNRESOLVED_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Hack to work around machine size. This needs to be cleaned up
+ * to better support 64bit targets.
+ */
+typedef uint32_t rtems_rtl_word_t;
+
+/**
+ * The types of records in the blocks.
+ */
+typedef enum rtems_rtl_unresolved_rtype_e
+{
+ rtems_rtl_unresolved_empty = 0, /**< The records is empty. Must always be 0 */
+ rtems_rtl_unresolved_name = 1, /**< The record is a name. */
+ rtems_rtl_unresolved_reloc = 2 /**< The record is a relocation record. */
+} rtems_rtl_unresolved_rtype_t;
+
+/**
+ * Unresolved externals symbol names. The names are reference counted and
+ * separate from the relocation records because a number of records could
+ * reference the same symbol name.
+ */
+typedef struct rtems_rtl_unresolv_name_s
+{
+ uint16_t refs; /**< The number of references to this name. */
+ uint16_t length; /**< The length of this name. */
+ const char name[12]; /**< The symbol name. */
+} rtems_rtl_unresolv_name_t;
+
+/**
+ * Unresolved externals symbols require the relocation records to be held
+ * and references.
+ */
+typedef struct rtems_rtl_unresolv_reloc_s
+{
+ rtems_rtl_obj_t* obj; /**< The relocation's object file. */
+ uint16_t flags; /**< Format specific flags. */
+ uint16_t name; /**< The symbol's name. */
+ uint16_t sect; /**< The target section. */
+ rtems_rtl_word_t rel[3]; /**< Relocation record. */
+} rtems_rtl_unresolv_reloc_t;
+
+/**
+ * Unresolved externals records.
+ */
+typedef struct rtems_rtl_unresolv_rec_s
+{
+ rtems_rtl_unresolved_rtype_t type;
+ union
+ {
+ rtems_rtl_unresolv_name_t name; /**< The name, or */
+ rtems_rtl_unresolv_reloc_t reloc; /**< the relocation record. */
+ } rec;
+} rtems_rtl_unresolv_rec_t;
+
+/**
+ * Unresolved blocks.
+ */
+typedef struct rtems_rtl_unresolv_block_s
+{
+ rtems_chain_node link; /**< Blocks are chained. */
+ uint32_t recs; /**< The number of records in the block. */
+ rtems_rtl_unresolv_rec_t rec; /**< The records. More follow. */
+} rtems_rtl_unresolv_block_t;
+
+/**
+ * Unresolved table holds the names and relocations.
+ */
+typedef struct rtems_rtl_unresolved_s
+{
+ uint32_t marker;
+ size_t block_recs; /**< The records per blocks allocated. */
+ rtems_chain_control blocks; /**< List of blocks. */
+} rtems_rtl_unresolved_t;
+
+/**
+ * The iterator function used to iterate over the unresolved table.
+ *
+ * @param rec The current iterator.
+ * @param data The user data.
+ * @retval true The iterator has finished.
+ * @retval false The iterator has not finished. Keep iterating.
+ */
+typedef bool rtems_rtl_unresolved_iterator_t (rtems_rtl_unresolv_rec_t* rec,
+ void* data);
+
+/**
+ * Open an unresolved relocation table.
+ *
+ * @param unresolv The unresolved table to open.
+ * @param block_records The number of records per block allocated.
+ * @retval true The table is open.
+ * @retval false The unresolved relocation table could not created. The RTL
+ * error has the error.
+ */
+bool rtems_rtl_unresolved_table_open (rtems_rtl_unresolved_t* unresolved,
+ size_t block_records);
+
+/**
+ * Close the table and erase the blocks.
+ *
+ * @param unreolved Close the unresolved table.
+ */
+void rtems_rtl_unresolved_table_close (rtems_rtl_unresolved_t* unresolved);
+
+/**
+ * Iterate over the table of unresolved entries.
+ */
+bool rtems_rtl_unresolved_interate (rtems_rtl_unresolved_iterator_t iterator,
+ void* data);
+
+/**
+ * Add a relocation to the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param flags Format specific flags.
+ * @param name The symbol name the relocation references.
+ * @param sect The target section number the relocation references.
+ * @param rel The format specific relocation data.
+ * @retval true The relocation has been added.
+ * @retval false The relocation could not be added.
+ */
+bool rtems_rtl_unresolved_add (rtems_rtl_obj_t* obj,
+ const uint16_t flags,
+ const char* name,
+ const uint16_t sect,
+ const rtems_rtl_word_t* rel);
+
+/**
+ * Resolve the unresolved symbols.
+ */
+void rtems_rtl_unresolved_resolve (void);
+
+/**
+ * Remove a relocation from the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_unresolved_remove (rtems_rtl_obj_t* obj,
+ const char* name,
+ const uint16_t sect,
+ const rtems_rtl_word_t* rel);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl.h b/cpukit/include/rtems/rtl/rtl.h
new file mode 100644
index 0000000000..fe9a7df081
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl.h
@@ -0,0 +1,321 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker
+ *
+ * This is the POSIX interface to run-time loading of code into RTEMS.
+ */
+
+#if !defined (_RTEMS_RTL_H_)
+#define _RTEMS_RTL_H_
+
+#include <link.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#include <rtems/rtl/rtl-allocator.h>
+#include <rtems/rtl/rtl-fwd.h>
+#include <rtems/rtl/rtl-obj.h>
+#include <rtems/rtl/rtl-obj-cache.h>
+#include <rtems/rtl/rtl-obj-comp.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rtl RTEMS Runtime Link Editor
+ *
+ * The module implements a runtime link editor with the standard dlopen, and
+ * dlclose family of functions.
+ *
+ * The runtime link editor is different to that found on Unix type systems. The
+ * object modules are compiled for PIC or position indepentent code and
+ * therefore require relocating when loaded.
+ *
+ * The object file format is currently ELF and object files can be separate
+ * files or in an archive. Object files in an archive are referenced by
+ * specifing 'archive:object' format. For example 'libfoo.a:bar.o'.
+ */
+
+/**
+ * Macros to glue two tokens.
+ */
+#ifdef __STDC__
+#define RTL_XGLUE(a,b) a##b
+#else
+#define RTL_XGLUE(a,b) a/**/b
+#endif
+
+#define RTL_GLUE(a,b) RTL_XGLUE(a,b)
+
+/**
+ * The number of buckets in the global symbol table.
+ */
+#define RTEMS_RTL_SYMS_GLOBAL_BUCKETS (32)
+
+/**
+ * The number of relocation record per block in the unresolved table.
+ */
+#define RTEMS_RTL_UNRESOLVED_BLOCK_SIZE (64)
+
+/**
+ * The global debugger interface variable.
+ */
+extern struct r_debug _rtld_debug;
+
+/**
+ * Debugger break function. Call when debugging to have it read the _rtld_debug
+ * variable.
+ */
+extern void _rtld_debug_state (void);
+
+/**
+ * The type of constructor/destructor function.
+ */
+typedef void (*rtems_rtl_cdtor_t)(void);
+
+/**
+ * The global RTL data. This structure is allocated on the heap when the first
+ * call to the RTL is made and never released.
+ *
+ * The global symbol table is a hash table held in this structure and the
+ * actual symbols are part of the object's structure. If this is a problem we
+ * could look at a hash table per object file.
+ */
+struct rtems_rtl_data_s
+{
+ rtems_id lock; /**< The RTL lock id */
+ rtems_rtl_alloc_data_t allocator; /**< The allocator data. */
+ rtems_chain_control objects; /**< List if loaded object files. */
+ const char* paths; /**< Search paths for archives. */
+ rtems_rtl_symbols_t globals; /**< Global symbol table. */
+ rtems_rtl_unresolved_t unresolved; /**< Unresolved symbols. */
+ rtems_rtl_obj_t* base; /**< Base object file. */
+ rtems_rtl_obj_cache_t symbols; /**< Symbols object file cache. */
+ rtems_rtl_obj_cache_t strings; /**< Strings object file cache. */
+ rtems_rtl_obj_cache_t relocs; /**< Relocations object file cache. */
+ rtems_rtl_obj_comp_t decomp; /**< The decompression compressor. */
+ int last_errno; /**< Last error number. */
+ char last_error[64]; /**< Last error string. */
+};
+
+/**
+ * Get the RTL data with out locking. This call assumes the RTL is locked.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_data_t* rtems_rtl_data (void);
+
+/**
+ * Get the RTL global symbol table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_symbols_t* The RTL global symbols after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_symbols_t* rtems_rtl_global_symbols (void);
+
+/**
+ * Get the RTL resolved table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_unresolv_t* The RTL unresolved symbols and reloc records.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_unresolved_t* rtems_rtl_unresolved (void);
+
+/**
+ * Get the RTL symbols, strings, or relocations object file caches. This call
+ * assmes the RTL is locked.
+ *
+ * @param symbols Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ * @param strings Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ * @param relocs Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ */
+void rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
+ rtems_rtl_obj_cache_t** strings,
+ rtems_rtl_obj_cache_t** relocs);
+
+/**
+ * Flush all the object file caches.
+ */
+void rtems_rtl_obj_caches_flush (void);
+
+/**
+ * Get the RTL decompressor setting the cache and the offset in the file the
+ * compressed stream starts. This call assmes the RTL is locked.
+ *
+ * @param decomp Pointer to the location to set the compressor into. Returns
+ * NULL is rtl is not initialised.
+ * @param cache The cache to read the file with. Saves needing an extrs buffer.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp (rtems_rtl_obj_comp_t** decomp,
+ rtems_rtl_obj_cache_t* cache,
+ int fd,
+ int compression,
+ off_t offset);
+
+/**
+ * Lock the Run-time Linker.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data could not be initialised or locked. Typically this
+ * means the lock could not be created.
+ */
+rtems_rtl_data_t* rtems_rtl_lock (void);
+
+/**
+ * Unlock the Run-time Linker.
+ *
+ * @return True The RTL is unlocked.
+ * @return False The RTL could not be unlocked. Not much you can do.
+ */
+bool rtems_rtl_unlock (void);
+
+/**
+ * Check a pointer is a valid object file descriptor returning the pointer as
+ * that type.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param handle Pointer to the object file to be validated.
+ * @return rtl_obj* The object file descriptor. NULL is returned if invalid.
+ */
+rtems_rtl_obj_t* rtems_rtl_check_handle (void* handle);
+
+/**
+ * Find the object given a file name.
+ *
+ * @param name The name of the object file.
+ * @retval NULL No object file with that name found.
+ * @return rtems_rtl_obj_t* The object file descriptor.
+ */
+rtems_rtl_obj_t* rtems_rtl_find_obj (const char* name);
+
+/**
+ * Load an object file into memory relocating it. It will not be resolved
+ * against other symbols in other object files or the base image.
+ *
+ * The name can be a file name for an object file or it can be encoded to
+ * reference an archive of object modules (static library). This encoding is
+ * specific to RTEMS and allows dependences to specify an archive without the
+ * searching overhead normally incurred by linkers locating object files in an
+ * archive. The file name format rules are:
+ *
+ * 1. Absolute file references a specific object file in the architecture
+ * specific location on the file system.
+ *
+ * 2. Relative file references an object format file in the search path.
+ *
+ * 3. Absolute archive and file reference to a specific location in the file
+ * system. The archive and file are encoded as 'archive:file [@@offset]'
+ * where 'archive' is a valid file at the absolute path in the file system,
+ * and 'file' is a contained in the archive, and optionally an offset to
+ * the 'file' in the 'archive'. If no offset is provided the archive is
+ * searched.
+ *
+ * 4. Relative archive and file in the search path. The encoding is the same
+ * as described in item 3 of this list.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param name The name of the object file.
+ * @param mode The mode of the load as defined by the dlopen call.
+ * @return rtl_obj* The object file descriptor. NULL is returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_load_object (const char* name, int mode);
+
+/**
+ * Unload an object file. This only happens when the user count is 0.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param obj The object file descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The object file could not be unloaded.
+ */
+bool rtems_rtl_unload_object (rtems_rtl_obj_t* obj);
+
+/**
+ * Run any constructor functions the object file may contain. This call
+ * assumes the linker is unlocked.
+ *
+ * @param obj The object file.
+ */
+void rtems_rtl_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Get the last error message clearing it. This operation locks the run time
+ * linker and therefore keeps the RTL thread safe but this call is not thread
+ * safe is multiple threads are loading object files at the same time. This
+ * call is provided to map to the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rtl_get_error (char* message, size_t max_message);
+
+/**
+ * Append the path to the search path.
+ *
+ * @param path The path to append.
+ * @retval false The path could not be appended.
+ * @retval true The path was appended.
+ */
+bool rtems_rtl_path_append (const char* path);
+
+/**
+ * Prepend the path to the search path.
+ *
+ * @param path The path to prepend.
+ * @retval false The path could not be prepended.
+ * @retval true The path was prepended.
+ */
+
+bool rtems_rtl_path_prepend (const char* path);
+
+/**
+ * Add an exported symbol table to the global symbol table. This call is
+ * normally used by an object file when loaded that contains a global symbol
+ * table.
+ *
+ * @param esyms The exported symbol table.
+ * @param count The size of the exported symbol table.
+ */
+void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+ unsigned int count);
+
+/**
+ * Return the object file descriptor for the base image. The object file
+ * descriptor returned is created when the run time linker is initialised.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @return rtl_obj* The object file descriptor for the base image. NULL is
+ * returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_baseimage (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif