diff options
author | Chris Johns <chrisj@rtems.org> | 2012-05-13 18:29:13 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-05-13 18:29:13 +1000 |
commit | fb0c9b27451d420175a76a0eef733792317d225f (patch) | |
tree | fa2799063f54b4cd6324bf3f028eee40d45b87dc | |
parent | b78c02ab55ae3c0a932901896051617e1a212952 (diff) |
Support indirect pointers for strings in the object file.
Add indirect pointers and use it for the file names parts which
are part of the object module.
-rw-r--r-- | rtl-allocator.c | 73 | ||||
-rw-r--r-- | rtl-allocator.h | 52 | ||||
-rw-r--r-- | rtl-indirect-ptr.h | 209 | ||||
-rw-r--r-- | rtl-mdreloc-i386.c | 8 | ||||
-rw-r--r-- | rtl-mdreloc-m68k.c | 8 | ||||
-rw-r--r-- | rtl-mdreloc-sparc.c | 6 | ||||
-rw-r--r-- | rtl-obj.c | 102 | ||||
-rw-r--r-- | rtl-obj.h | 73 | ||||
-rw-r--r-- | rtl-shell.c | 9 | ||||
-rw-r--r-- | rtl-string.c | 13 | ||||
-rw-r--r-- | rtl-string.h | 12 | ||||
-rw-r--r-- | rtl.c | 11 | ||||
-rw-r--r-- | rtl.h | 22 |
13 files changed, 516 insertions, 82 deletions
diff --git a/rtl-allocator.c b/rtl-allocator.c index 93235db..21cd5ab 100644 --- a/rtl-allocator.c +++ b/rtl-allocator.c @@ -16,6 +16,7 @@ #include <stdio.h> #include <rtl.h> +#include <rtl-alloc-heap.h> #include <rtl-trace.h> /** @@ -34,14 +35,23 @@ static const char* tag_labels[4] = #define rtems_rtl_trace_tag_label(_l) "" #endif +void +rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data) +{ + int c; + data->allocator = rtems_rtl_alloc_heap; + for (c = 0; c < RTEMS_RTL_ALLOC_TAGS; ++c) + rtems_chain_initialize_empty (&data->indirects[c]); +} + void* -rtems_rtl_alloc_new(rtems_rtl_alloc_tag_t tag, size_t size) +rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size) { rtems_rtl_data_t* rtl = rtems_rtl_lock (); void* address = NULL; if (rtl) - rtl->allocator (true, tag, &address, size); + rtl->allocator.allocator (true, tag, &address, size); if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR)) printf ("alloc: new: %s addr=%p size=%zu\n", @@ -53,7 +63,7 @@ rtems_rtl_alloc_new(rtems_rtl_alloc_tag_t tag, size_t size) } void -rtems_rtl_alloc_del(rtems_rtl_alloc_tag_t tag, void* address) +rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address) { rtems_rtl_data_t* rtl = rtems_rtl_lock (); @@ -62,18 +72,67 @@ rtems_rtl_alloc_del(rtems_rtl_alloc_tag_t tag, void* address) rtems_rtl_trace_tag_label (tag), address); if (rtl) - rtl->allocator (false, tag, &address, 0); + rtl->allocator.allocator (false, tag, &address, 0); rtems_rtl_unlock (); } rtems_rtl_allocator_t -rtems_rtl_alloc_hook(rtems_rtl_allocator_t handler) +rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler) { rtems_rtl_data_t* rtl = rtems_rtl_lock (); - rtems_rtl_allocator_t previous = rtl->allocator; - rtl->allocator = handler; + rtems_rtl_allocator_t previous = rtl->allocator.allocator; + rtl->allocator.allocator = handler; rtems_rtl_unlock (); return previous; } +void +rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag, + rtems_rtl_ptr_t* handle, + size_t size) +{ + rtems_rtl_data_t* rtl = rtems_rtl_lock (); + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR)) + { + if (!rtems_rtl_ptr_null (handle)) + printf ("alloc: inew: %s handle=%p: not null\n", + rtems_rtl_trace_tag_label (tag), handle); + printf ("alloc: inew: %s handle=%p size=%zd\n", + rtems_rtl_trace_tag_label (tag), handle, size); + } + + if (rtl) + { + rtems_rtl_alloc_data_t* allocator = &rtl->allocator; + handle->pointer = rtems_rtl_alloc_new (tag, size); + if (!rtems_rtl_ptr_null (handle)) + rtems_chain_append_unprotected (&allocator->indirects[tag], + &handle->node); + } + + rtems_rtl_unlock (); +} + +void +rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag, + rtems_rtl_ptr_t* handle) +{ + rtems_rtl_data_t* rtl = rtems_rtl_lock (); + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR)) + { + if (rtems_rtl_ptr_null (handle)) + printf ("alloc: idel: %s handle=%p: is null\n", + rtems_rtl_trace_tag_label (tag), handle); + printf ("alloc: idel: %s handle=%p\n", + rtems_rtl_trace_tag_label (tag), handle); + } + + if (rtl && !rtems_rtl_ptr_null (handle)) + { + rtems_chain_extract_unprotected (&handle->node); + rtems_rtl_alloc_del (tag, &handle->pointer); + } +} diff --git a/rtl-allocator.h b/rtl-allocator.h index 6f1e9bb..41135cb 100644 --- a/rtl-allocator.h +++ b/rtl-allocator.h @@ -18,12 +18,17 @@ #include <stdbool.h> +#include "rtl-indirect-ptr.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * Define the types of allocation the loader requires. + * + * @note The module allocation type may need to be split into text, data and + * bss if memory protection schemes require we do this. */ enum rtems_rtl_alloc_tags_e { RTEMS_RTL_ALLOC_SYMBOL, /**< A symbol in the symbol table. */ @@ -32,9 +37,17 @@ enum rtems_rtl_alloc_tags_e { RTEMS_RTL_ALLOC_MODULE /**< The module's code, data and bss memory. */ }; +/** + * 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_MODULE + 1)) + +/** * Allocator handler handles all RTL allocations. It can be hooked and * overridded for customised allocation schemes or memory maps. * @@ -54,6 +67,25 @@ typedef void (*rtems_rtl_allocator_t)(bool allocate, 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. * * @param tag The type of allocation request. @@ -81,6 +113,26 @@ void rtems_rtl_alloc_del(rtems_rtl_alloc_tag_t tag, void* address); */ 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); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/rtl-indirect-ptr.h b/rtl-indirect-ptr.h new file mode 100644 index 0000000..2c4843f --- /dev/null +++ b/rtl-indirect-ptr.h @@ -0,0 +1,209 @@ +/* + * 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.com/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; + +/** + * 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/rtl-mdreloc-i386.c b/rtl-mdreloc-i386.c index 6b83621..db46cb3 100644 --- a/rtl-mdreloc-i386.c +++ b/rtl-mdreloc-i386.c @@ -55,7 +55,7 @@ rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj, if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n", sect->name, (void*) symvalue, - (void *)*where, obj->oname); + (void *)*where, rtems_rtl_obj_oname (obj)); break; case R_TYPE(GOT32): @@ -68,13 +68,15 @@ rtems_rtl_elf_relocate_rel (rtems_rtl_obj_t* obj, *where = tmp; if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n", - sect->name, (void *)*where, obj->oname); + sect->name, (void *)*where, + rtems_rtl_obj_oname (obj)); break; case R_TYPE(RELATIVE): *where += (Elf_Addr)sect->base; if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) - printf ("rtl: reloc RELATIVE in %s --> %p\n", obj->oname, (void *)*where); + printf ("rtl: reloc RELATIVE in %s --> %p\n", + rtems_rtl_obj_oname (obj), (void *)*where); break; case R_TYPE(COPY): diff --git a/rtl-mdreloc-m68k.c b/rtl-mdreloc-m68k.c index fe1b7b5..917d052 100644 --- a/rtl-mdreloc-m68k.c +++ b/rtl-mdreloc-m68k.c @@ -44,7 +44,7 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj, if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n", sect->name, (void*) (symvalue + rela->r_addend), - (void *)*where, obj->oname); + (void *)*where, rtems_rtl_obj_oname (obj)); break; case R_TYPE(GOT32): @@ -57,13 +57,15 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj, if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n", - sect->name, (void *)*where, obj->oname); + sect->name, (void *)*where, + rtems_rtl_obj_oname (obj)); break; case R_TYPE(RELATIVE): *where += (Elf_Addr) sect->base + rela->r_addend; if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) - printf ("rtl: reloc RELATIVE in %s --> %p\n", obj->oname, (void *)*where); + printf ("rtl: reloc RELATIVE in %s --> %p\n", + rtems_rtl_obj_oname (obj), (void *)*where); break; case R_TYPE(COPY): diff --git a/rtl-mdreloc-sparc.c b/rtl-mdreloc-sparc.c index aee9b7b..697f039 100644 --- a/rtl-mdreloc-sparc.c +++ b/rtl-mdreloc-sparc.c @@ -176,7 +176,8 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj, if (type == R_TYPE (RELATIVE)) { *where += (Elf_Addr)(sect->base + value); if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) - printf ("rtl: reloc relative in %s --> %p", obj->oname, (void *)*where); + printf ("rtl: reloc relative in %s --> %p", + rtems_rtl_obj_oname (obj), (void *)*where); return true; } @@ -208,7 +209,8 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj_t* obj, if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf("rtl: reloc base_rel(%s): where=%p, *where 0x%lx, " "addend=0x%lx, base %p\n", - obj->oname, where, *where, rela->r_addend, sect->base); + rtems_rtl_obj_oname (obj), + where, *where, rela->r_addend, sect->base); } #endif value += (Elf_Word)(sect->base + *where); @@ -56,10 +56,12 @@ rtems_rtl_obj_alloc (void) static void rtems_rtl_obj_free_names (rtems_rtl_obj_t* obj) { - rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, (void*) obj->oname); - rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, (void*) obj->aname); - if ((obj->fname != obj->aname) && (obj->fname != obj->oname)) - rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, (void*) obj->fname); + if (rtems_rtl_obj_oname_valid (obj)) + rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->oname); + if (rtems_rtl_obj_aname_valid (obj)) + rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->aname); + if (rtems_rtl_obj_fname_valid (obj)) + rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->fname); } bool @@ -88,33 +90,34 @@ rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj) static bool rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name) { - const char* p; - const char* e; - char* aname; - char* oname; + rtems_rtl_ptr_t aname; + rtems_rtl_ptr_t oname; + const char* p; + const char* e; + char* s; + + rtems_rtl_ptr_init (&aname); + rtems_rtl_ptr_init (&oname); /* * Parse the name to determine if the object file is part of an archive or it * is an object file. */ e = name + strlen (name); - p = strchr (name, ':'); - if (p == NULL) p = e; - aname = NULL; - - oname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_STRING, p - name + 1); - if (oname == NULL) + rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, &oname, p - name + 1); + if (rtems_rtl_ptr_null (&oname)) { rtems_rtl_set_error (ENOMEM, "no memory for object file name"); return false; } - memcpy (oname, name, p - name); - oname[p - name] = '\0'; + s = rtems_rtl_ptr_get (&oname); + memcpy (s, name, p - name); + s[p - name] = '\0'; if (p != e) { @@ -122,9 +125,9 @@ rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name) /* * The file name is an archive and the object file name is next after the - * delimiter. + * delimiter. Move the pointer to the archive name. */ - aname = oname; + rtems_rtl_ptr_move (&aname, &oname); ++p; /* @@ -136,16 +139,18 @@ rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name) if (o == NULL) o = e; - oname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_STRING, o - p + 1); - if (oname == NULL) + + rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, &oname, o - p + 1); + if (rtems_rtl_ptr_null (&oname)) { - rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, aname); + rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &aname); rtems_rtl_set_error (ENOMEM, "no memory for object file name"); return false; } - memcpy (oname, p, o - p); - oname[o - p] = '\0'; + s = rtems_rtl_ptr_get (&oname); + memcpy (s, p, o - p); + s[o - p] = '\0'; if (o != e) { @@ -158,8 +163,8 @@ rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name) } } - obj->oname = oname; - obj->aname = aname; + rtems_rtl_ptr_move (&obj->oname, &oname); + rtems_rtl_ptr_move (&obj->aname, &aname); return true; } @@ -300,7 +305,7 @@ rtems_rtl_obj_section_handler (uint32_t mask, bool rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name) { - const char* n1 = obj->oname; + const char* n1 = rtems_rtl_ptr_get (&obj->oname); while ((*n1 != '\0') && (*n1 != '\n') && (*n1 != '/') && (*name != '\0') && (*name != '/') && (*n1 == *name)) { @@ -334,15 +339,15 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name) * field to the fname field to that name. If the field is relative we search * the paths set in the RTL for the file. */ - if (obj->aname != NULL) - n = obj->aname; + if (rtems_rtl_obj_aname_valid (obj)) + n = rtems_rtl_obj_aname (obj); else - n = obj->oname; + n = rtems_rtl_obj_oname (obj); if (rtems_filesystem_is_delimiter (n[0])) { if (stat (n, &sb) == 0) - obj->fname = n; + rtems_rtl_str_copy (&obj->fname, n); } else { @@ -357,11 +362,14 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name) e = s + strlen (rtl->paths); l = strlen (n); - while ((obj->fname == NULL) && (s != e)) + while (rtems_rtl_ptr_null (&obj->fname) && (s != e)) { - const char* d; - char* p; + rtems_rtl_ptr_t fname; + const char* d; + char* p; + rtems_rtl_ptr_init (&fname); + d = strchr (s, ':'); if (d == NULL) d = e; @@ -369,27 +377,30 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name) /* * Allocate the path fragment, separator, name, terminating nul. */ - p = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_STRING, (d - s) + 1 + l + 1); - if (p == NULL) + + rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, + &fname, (d - s) + 1 + l + 1); + if (rtems_rtl_ptr_null (&fname)) { rtems_rtl_set_error (ENOMEM, "no memory searching for object file"); rtems_rtl_unlock (); return false; } + p = rtems_rtl_ptr_get (&fname); memcpy (p, s, d - s); p[d - s] = '/'; memcpy (p + (d - s) + 1, n, l); p[(d - s) + 1 + l] = '\0'; if (stat (p, &sb) < 0) - rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, p); + rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &fname); else { /* * We have found the file. Do not release the path memory. */ - obj->fname = p; + rtems_rtl_ptr_move (&obj->fname, &fname); } s = d; @@ -398,12 +409,15 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name) rtems_rtl_unlock (); } - if (obj->fname) - obj->fsize = sb.st_size; - else + if (rtems_rtl_ptr_null (&obj->fname)) + { rtems_rtl_set_error (ENOMEM, "object file not found"); + return false; + } + + obj->fsize = sb.st_size; - return obj->fname ? true : false; + return true; } bool @@ -986,13 +1000,13 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj) { int fd; - if (!obj->fname) + if (!rtems_rtl_obj_fname_valid (obj)) { rtems_rtl_set_error (ENOMEM, "invalid object file name path"); return false; } - fd = open (obj->fname, O_RDONLY); + fd = open (rtems_rtl_obj_fname (obj), O_RDONLY); if (fd < 0) { rtems_rtl_set_error (ENOMEM, "opening for object file"); @@ -1003,7 +1017,7 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj) * Find the object file in the archive if it is an archive that * has been opened. */ - if (obj->aname != NULL) + if (rtems_rtl_obj_aname_valid (obj)) { if (!rtems_rtl_obj_archive_find (obj, fd)) { @@ -18,6 +18,7 @@ #include <rtems.h> #include <rtems/chain.h> +#include <rtl-indirect-ptr.h> #include <rtl-sym.h> #ifdef __cplusplus @@ -82,10 +83,10 @@ 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. */ - const char* fname; /**< The file name for the object. */ - const char* oname; /**< The object file name. Can be + rtems_rtl_ptr_t fname; /**< The file name for the object. */ + rtems_rtl_ptr_t oname; /**< The object file name. Can be * relative. */ - const char* aname; /**< The archive name containing the + rtems_rtl_ptr_t 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. */ @@ -128,6 +129,72 @@ typedef bool (*rtems_rtl_obj_sect_handler_t)(rtems_rtl_obj_t* obj, void* data); /** + * Get the file name. + * + * @param obj The object file. + * @return const char* The string. + */ +static inline const char* rtems_rtl_obj_fname (rtems_rtl_obj_t* obj) +{ + return rtems_rtl_ptr_type_get (&obj->fname, const char); +} + +/** + * 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 (rtems_rtl_obj_t* obj) +{ + return !rtems_rtl_ptr_null (&obj->fname); +} + +/** + * Get the object name. + * + * @param obj The object file. + * @return const char* The string. + */ +static inline const char* rtems_rtl_obj_oname (rtems_rtl_obj_t* obj) +{ + return rtems_rtl_ptr_type_get (&obj->oname, const char); +} + +/** + * 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 (rtems_rtl_obj_t* obj) +{ + return !rtems_rtl_ptr_null (&obj->oname); +} + +/** + * Get the archive name. + * + * @param obj The object file. + * @return const char* The string. + */ +static inline const char* rtems_rtl_obj_aname (rtems_rtl_obj_t* obj) +{ + return rtems_rtl_ptr_type_get (&obj->aname, const char); +} + +/** + * 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 (rtems_rtl_obj_t* obj) +{ + return !rtems_rtl_ptr_null (&obj->aname); +} + +/** * Allocate an object structure on the heap. * * @retval NULL No memory for the object. diff --git a/rtl-shell.c b/rtl-shell.c index 52d34c9..69ce24f 100644 --- a/rtl-shell.c +++ b/rtl-shell.c @@ -159,11 +159,14 @@ rtems_rtl_obj_print_iterator (rtems_chain_node* node, void* data) if (!print->base && (obj == print->rtl->base)) return true; - printf ("%-*cobject name : %s\n", print->indent, ' ', obj->oname); + printf ("%-*cobject name : %s\n", + print->indent, ' ', rtems_rtl_obj_oname (obj)); if (print->names) { - printf ("%-*cfile name : %s\n", print->indent, ' ', obj->fname); - printf ("%-*carchive name : %s\n", print->indent, ' ', obj->aname); + printf ("%-*cfile name : %s\n", + print->indent, ' ', rtems_rtl_obj_fname (obj)); + printf ("%-*carchive name : %s\n", + print->indent, ' ', rtems_rtl_obj_aname (obj)); strcpy (flags_str, "--"); if (obj->flags & RTEMS_RTL_OBJ_LOCKED) flags_str[0] = 'L'; diff --git a/rtl-string.c b/rtl-string.c index cba7616..921eca0 100644 --- a/rtl-string.c +++ b/rtl-string.c @@ -30,3 +30,16 @@ rtems_rtl_strdup (const char *s1) } return s2; } + +void +rtems_rtl_str_copy (rtems_rtl_ptr_t* dst, const char* str) +{ + size_t len = strlen (str); + rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, dst, len + 1); + if (!rtems_rtl_ptr_null (dst)) + { + char* p = rtems_rtl_ptr_get (dst); + memcpy (p, str, len); + p[len] = '\0'; + } +} diff --git a/rtl-string.h b/rtl-string.h index 00d2c9c..5c599e9 100644 --- a/rtl-string.h +++ b/rtl-string.h @@ -16,6 +16,8 @@ #if !defined (_RTEMS_RTL_STRING_H_) #define _RTEMS_RTL_STRING_H_ +#include <rtl-indirect-ptr.h> + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -26,7 +28,15 @@ extern "C" { * @param s1 The string to duplicate. * @return char* The copy of the string. NULL if there is no memory. */ -char* rtems_rtl_strdup(const char *s1); +char* rtems_rtl_strdup (const char *s1); + +/** + * Copy a string to an indirect pointer. + * + * @param dst The indirect pointer handle to copy the string too. + * @param str The string to copy. + */ +void rtems_rtl_str_copy (rtems_rtl_ptr_t* dst, const char* str); #ifdef __cplusplus } @@ -26,8 +26,9 @@ #include <rtems/libio_.h> #include <rtl.h> -#include "rtl-alloc-heap.h" +#include "rtl-allocator.h" #include "rtl-error.h" +#include "rtl-string.h" #include "rtl-trace.h" /** @@ -101,9 +102,9 @@ rtems_rtl_data_init (void) *rtl = (rtems_rtl_data_t) { 0 }; /* - * The default allocator uses the libc heap. + * The initialise the allocator data. */ - rtl->allocator = rtems_rtl_alloc_heap; + rtems_rtl_alloc_initialise (&rtl->allocator); /* * Create the RTL lock. @@ -185,7 +186,7 @@ rtems_rtl_data_init (void) /* * Need to malloc the memory so the free does not complain. */ - rtl->base->oname = strdup ("rtems-kernel"); + rtems_rtl_str_copy (&rtl->base->oname, "rtems-kernel"); rtems_chain_append (&rtl->objects, &rtl->base->link); } @@ -396,7 +397,7 @@ rtems_rtl_unload_object (rtems_rtl_obj_t* obj) bool ok = true; if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNLOAD)) - printf ("rtl: unloading '%s'\n", obj->fname); + printf ("rtl: unloading '%s'\n", rtems_rtl_obj_fname (obj)); /* * If the object is locked it cannot be unloaded and the unload fails. @@ -80,17 +80,17 @@ typedef void (*rtems_rtl_cdtor_t)(void); */ struct rtems_rtl_data_s { - rtems_id lock; /**< The RTL lock id */ - rtems_rtl_allocator_t allocator; /**< The memory allocator handler. */ - 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_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. */ - int last_errno; /**< Last error number. */ - char last_error[64]; /**< Last error string. */ + 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_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. */ + int last_errno; /**< Last error number. */ + char last_error[64]; /**< Last error string. */ }; /** |