summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-05-13 18:29:13 +1000
committerChris Johns <chrisj@rtems.org>2012-05-13 18:29:13 +1000
commitfb0c9b27451d420175a76a0eef733792317d225f (patch)
treefa2799063f54b4cd6324bf3f028eee40d45b87dc
parentb78c02ab55ae3c0a932901896051617e1a212952 (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.c73
-rw-r--r--rtl-allocator.h52
-rw-r--r--rtl-indirect-ptr.h209
-rw-r--r--rtl-mdreloc-i386.c8
-rw-r--r--rtl-mdreloc-m68k.c8
-rw-r--r--rtl-mdreloc-sparc.c6
-rw-r--r--rtl-obj.c102
-rw-r--r--rtl-obj.h73
-rw-r--r--rtl-shell.c9
-rw-r--r--rtl-string.c13
-rw-r--r--rtl-string.h12
-rw-r--r--rtl.c11
-rw-r--r--rtl.h22
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);
diff --git a/rtl-obj.c b/rtl-obj.c
index 0274977..a23f804 100644
--- a/rtl-obj.c
+++ b/rtl-obj.c
@@ -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))
{
diff --git a/rtl-obj.h b/rtl-obj.h
index c00397a..ca1a4c1 100644
--- a/rtl-obj.h
+++ b/rtl-obj.h
@@ -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
}
diff --git a/rtl.c b/rtl.c
index 78d395c..35fb06a 100644
--- a/rtl.c
+++ b/rtl.c
@@ -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.
diff --git a/rtl.h b/rtl.h
index 0ebfce1..03d15e2 100644
--- a/rtl.h
+++ b/rtl.h
@@ -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. */
};
/**