diff options
Diffstat (limited to 'cpukit/include/rtems/rtl')
-rw-r--r-- | cpukit/include/rtems/rtl/dlfcn-shell.h | 17 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rap-shell.h | 14 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rap.h | 115 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-allocator.h | 181 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-fwd.h | 33 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-indirect-ptr.h | 235 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-obj-cache.h | 132 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-obj-comp.h | 122 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-obj-fwd.h | 39 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-obj.h | 635 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-sym.h | 135 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-trace.h | 102 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl-unresolved.h | 212 | ||||
-rw-r--r-- | cpukit/include/rtems/rtl/rtl.h | 321 |
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 |