summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-05-28 08:23:58 +1000
committerChris Johns <chrisj@rtems.org>2012-05-28 08:23:58 +1000
commit9f020ad54f678f6f2e271b3cb9153191f407f746 (patch)
treef05ed68071f077bf45c781cef145426137ee36b4
parentfb0c9b27451d420175a76a0eef733792317d225f (diff)
Rework the allocator.
The allocator now supports symbols, externals, objects and various memory attributes when allocating. Provide a clear on allocation, is calloc. Make the strings in the object files object allocations and not indirect pointers. This is due to symbols and symbol strings being allocated in a single blocks per object file. Only externals will be indirect allocations. Some trace output changes adding 'rtl'.
-rw-r--r--rtl-allocator.c102
-rw-r--r--rtl-allocator.h54
-rw-r--r--rtl-elf.c13
-rw-r--r--rtl-obj-cache.c2
-rw-r--r--rtl-obj.c192
-rw-r--r--rtl-obj.h18
-rw-r--r--rtl-string.c15
-rw-r--r--rtl-string.h8
-rw-r--r--rtl-sym.c3
-rw-r--r--rtl.c4
10 files changed, 242 insertions, 169 deletions
diff --git a/rtl-allocator.c b/rtl-allocator.c
index 21cd5ab..a3e97e5 100644
--- a/rtl-allocator.c
+++ b/rtl-allocator.c
@@ -23,12 +23,14 @@
* Tags as symbols for tracing.
*/
#if RTEMS_RTL_TRACE
-static const char* tag_labels[4] =
+static const char* tag_labels[6] =
{
- "SYMBOL",
- "STRING",
"OBJECT",
- "MODULE"
+ "SYMBOL",
+ "EXTERNAL",
+ "READ",
+ "READ_WRITE",
+ "READ_EXEC",
};
#define rtems_rtl_trace_tag_label(_l) tag_labels[_l]
#else
@@ -45,7 +47,7 @@ rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data)
}
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, bool zero)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
void* address = NULL;
@@ -53,12 +55,15 @@ rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size)
if (rtl)
rtl->allocator.allocator (true, tag, &address, size);
+ rtems_rtl_unlock ();
+
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
- printf ("alloc: new: %s addr=%p size=%zu\n",
+ printf ("rtl: alloc: new: %s addr=%p size=%zu\n",
rtems_rtl_trace_tag_label (tag), address, size);
- rtems_rtl_unlock ();
-
+ if (zero)
+ memset (address, 0, size);
+
return address;
}
@@ -68,10 +73,10 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address)
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
- printf ("alloc: del: %s addr=%p\n",
+ printf ("rtl: alloc: del: %s addr=%p\n",
rtems_rtl_trace_tag_label (tag), address);
- if (rtl)
+ if (rtl && address)
rtl->allocator.allocator (false, tag, &address, 0);
rtems_rtl_unlock ();
@@ -97,16 +102,16 @@ rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
{
if (!rtems_rtl_ptr_null (handle))
- printf ("alloc: inew: %s handle=%p: not null\n",
+ printf ("rtl: alloc: inew: %s handle=%p: not null\n",
rtems_rtl_trace_tag_label (tag), handle);
- printf ("alloc: inew: %s handle=%p size=%zd\n",
+ printf ("rtl: 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);
+ handle->pointer = rtems_rtl_alloc_new (tag, size, false);
if (!rtems_rtl_ptr_null (handle))
rtems_chain_append_unprotected (&allocator->indirects[tag],
&handle->node);
@@ -124,9 +129,9 @@ rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
{
if (rtems_rtl_ptr_null (handle))
- printf ("alloc: idel: %s handle=%p: is null\n",
+ printf ("rtl: alloc: idel: %s handle=%p: is null\n",
rtems_rtl_trace_tag_label (tag), handle);
- printf ("alloc: idel: %s handle=%p\n",
+ printf ("rtl: alloc: idel: %s handle=%p\n",
rtems_rtl_trace_tag_label (tag), handle);
}
@@ -136,3 +141,70 @@ rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
rtems_rtl_alloc_del (tag, &handle->pointer);
}
}
+
+bool
+rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
+ void** const_base, size_t const_size,
+ void** data_base, size_t data_size,
+ void** bss_base, size_t bss_size)
+{
+ *text_base = *const_base = *data_base = *bss_base = NULL;
+
+ if (text_size)
+ {
+ *text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_EXEC,
+ text_size, false);
+ if (!*text_base)
+ {
+ return false;
+ }
+ }
+
+ if (const_size)
+ {
+ *const_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
+ const_size, false);
+ if (!*const_base)
+ {
+ rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+ return false;
+ }
+ }
+
+ if (data_size)
+ {
+ *data_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+ data_size, false);
+ if (!*data_base)
+ {
+ rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+ return false;
+ }
+ }
+
+ if (bss_size)
+ {
+ *bss_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+ bss_size, false);
+ if (!*bss_base)
+ {
+ rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+rtems_rtl_alloc_module_del (void** text_base,
+ void** const_base,
+ void** data_base,
+ void** bss_base)
+{
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
+ *text_base = *const_base = *data_base = *bss_base = NULL;
+}
diff --git a/rtl-allocator.h b/rtl-allocator.h
index 41135cb..47e896f 100644
--- a/rtl-allocator.h
+++ b/rtl-allocator.h
@@ -27,14 +27,16 @@ extern "C" {
/**
* 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.
+ * @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_SYMBOL, /**< A symbol in the symbol table. */
- RTEMS_RTL_ALLOC_STRING, /**< A runtime loader string. */
- RTEMS_RTL_ALLOC_OBJECT, /**< An RTL object. */
- RTEMS_RTL_ALLOC_MODULE /**< The module's code, data and bss memory. */
+ 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. */
};
/**
@@ -45,7 +47,7 @@ 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))
+#define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
/**
* Allocator handler handles all RTL allocations. It can be hooked and
@@ -86,13 +88,15 @@ typedef struct rtems_rtl_alloc_data_s rtems_rtl_alloc_data_t;
void rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data);
/**
- * The Runtime Loader allocator new allocates new memory.
+ * 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);
+void* rtems_rtl_alloc_new(rtems_rtl_alloc_tag_t tag, size_t size, bool zero);
/**
* The Runtime Loader allocator delete deletes allocated memory.
@@ -133,6 +137,38 @@ void rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
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 data_base Pointer to the data base pointer.
+ * @prarm 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** 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 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** data_base, void** bss_base);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/rtl-elf.c b/rtl-elf.c
index f9a5684..acf7893 100644
--- a/rtl-elf.c
+++ b/rtl-elf.c
@@ -123,7 +123,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
}
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("relocation: %s, syms:%s\n", sect->name, symsect->name);
+ printf ("rtl: relocation: %s, syms:%s\n", sect->name, symsect->name);
/*
* Handle the different relocation record types.
@@ -203,7 +203,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
if (is_rela)
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rela: sym:%-2d type:%-2d off:%08lx addend:%d\n",
+ printf ("rtl: rela: sym:%-2d type:%-2d off:%08lx addend:%d\n",
(int) ELF_R_SYM (rela->r_info), (int) ELF_R_TYPE (rela->r_info),
rela->r_offset, (int) rela->r_addend);
if (!rtems_rtl_elf_relocate_rela (obj, rela, targetsect, symvalue))
@@ -212,7 +212,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
else
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rel: sym:%-2d type:%-2d off:%08lx\n",
+ printf ("rtl: rel: sym:%-2d type:%-2d off:%08lx\n",
(int) ELF_R_SYM (rel->r_info), (int) ELF_R_TYPE (rel->r_info),
rel->r_offset);
if (!rtems_rtl_elf_relocate_rel (obj, rel, targetsect, symvalue))
@@ -319,7 +319,8 @@ rtems_rtl_elf_symbols (rtems_rtl_obj_t* obj,
rtems_rtl_obj_sym_t* gsym;
obj->global_size = globals * sizeof (rtems_rtl_obj_sym_t) + string_space;
- obj->global_table = calloc (1, obj->global_size);
+ obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+ obj->global_size, true);
if (!obj->global_table)
{
obj->global_size = 0;
@@ -381,7 +382,7 @@ rtems_rtl_elf_symbols (rtems_rtl_obj_t* obj,
gsym->value = symbol.st_value + (uint8_t*) symsect->base;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
- printf ("sym:%-2d name:%-2d:%-20s bind:%-2d type:%-2d val:%8p sect:%d size:%d\n",
+ printf ("rtl: sym:%-2d name:%-2d:%-20s bind:%-2d type:%-2d val:%8p sect:%d size:%d\n",
sym, (int) symbol.st_name, gsym->name,
(int) ELF_ST_BIND (symbol.st_info),
(int) ELF_ST_TYPE (symbol.st_info),
@@ -493,7 +494,7 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
break;
default:
- printf ("unsupported section: %2d: type=%02d flags=%02x\n",
+ printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
section, (int) shdr.sh_type, (int) shdr.sh_flags);
break;
}
diff --git a/rtl-obj-cache.c b/rtl-obj-cache.c
index 6e071c5..5a8df5d 100644
--- a/rtl-obj-cache.c
+++ b/rtl-obj-cache.c
@@ -33,7 +33,7 @@ rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size)
cache->offset = 0;
cache->size = size;
cache->level = 0;
- cache->buffer = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, size);
+ cache->buffer = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, size, false);
if (!cache->buffer)
{
rtems_rtl_set_error (ENOMEM, "no memory for cache buffer");
diff --git a/rtl-obj.c b/rtl-obj.c
index a23f804..1e71b74 100644
--- a/rtl-obj.c
+++ b/rtl-obj.c
@@ -37,15 +37,11 @@ rtems_rtl_obj_t*
rtems_rtl_obj_alloc (void)
{
rtems_rtl_obj_t* obj = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
- sizeof (rtems_rtl_obj_t));
+ sizeof (rtems_rtl_obj_t),
+ true);
if (obj)
{
/*
- * Initalise to 0.
- */
- *obj = (rtems_rtl_obj_t) { { 0 } };
-
- /*
* Initialise the chains.
*/
rtems_chain_initialize_empty (&obj->sections);
@@ -57,11 +53,11 @@ static void
rtems_rtl_obj_free_names (rtems_rtl_obj_t* obj)
{
if (rtems_rtl_obj_oname_valid (obj))
- rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->oname);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->oname);
if (rtems_rtl_obj_aname_valid (obj))
- rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->aname);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->aname);
if (rtems_rtl_obj_fname_valid (obj))
- rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &obj->fname);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->fname);
}
bool
@@ -74,8 +70,9 @@ rtems_rtl_obj_free (rtems_rtl_obj_t* obj)
}
if (!rtems_chain_is_node_off_chain (&obj->link))
rtems_chain_extract (&obj->link);
+ rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
+ &obj->data_base, &obj->bss_base);
rtems_rtl_obj_symbol_erase (obj);
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_MODULE, obj->text_base);
rtems_rtl_obj_free_names (obj);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
return true;
@@ -90,81 +87,77 @@ rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj)
static bool
rtems_rtl_obj_parse_name (rtems_rtl_obj_t* obj, const char* name)
{
- 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);
+ const char* aname = NULL;
+ const char* oname = NULL;
+ const char* colon;
+ const char* end;
/*
* Parse the name to determine if the object file is part of an archive or it
- * is an object file.
+ * is an object file. If an archive check the name for a '@' to see if the
+ * archive contains an offset.
*/
- e = name + strlen (name);
- p = strchr (name, ':');
- if (p == NULL)
- p = e;
+ end = name + strlen (name);
+ colon = strchr (name, ':');
+ if (colon == NULL)
+ colon = end;
- rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, &oname, p - name + 1);
- if (rtems_rtl_ptr_null (&oname))
+ oname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, colon - name + 1, true);
+ if (!oname)
{
rtems_rtl_set_error (ENOMEM, "no memory for object file name");
return false;
}
- s = rtems_rtl_ptr_get (&oname);
- memcpy (s, name, p - name);
- s[p - name] = '\0';
+ memcpy ((void*) oname, name, colon - name);
- if (p != e)
+ /*
+ * If the pointers match there is no ':' delimiter.
+ */
+ if (colon != end)
{
- const char* o;
+ const char* at;
/*
* The file name is an archive and the object file name is next after the
* delimiter. Move the pointer to the archive name.
*/
- rtems_rtl_ptr_move (&aname, &oname);
- ++p;
+ aname = oname;
+ ++colon;
/*
* See if there is a '@' to delimit an archive offset for the object in the
* archive.
*/
- o = strchr (p, '@');
+ at = strchr (colon, '@');
- if (o == NULL)
- o = e;
+ if (at == NULL)
+ at = end;
- rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING, &oname, o - p + 1);
- if (rtems_rtl_ptr_null (&oname))
+ oname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, at - colon + 1, true);
+ if (!oname)
{
- rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &aname);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) aname);
rtems_rtl_set_error (ENOMEM, "no memory for object file name");
return false;
}
- s = rtems_rtl_ptr_get (&oname);
- memcpy (s, p, o - p);
- s[o - p] = '\0';
+ memcpy ((void*) oname, colon, at - colon);
- if (o != e)
+ if (at != end)
{
/*
* The object name has an archive offset. If the number
* does not parse 0 will be returned and the archive will be
* searched.
*/
- obj->ooffset = strtoul (o + 1, 0, 0);
+ obj->ooffset = strtoul (at + 1, 0, 0);
}
}
- rtems_rtl_ptr_move (&obj->oname, &oname);
- rtems_rtl_ptr_move (&obj->aname, &aname);
+ obj->oname = oname;
+ obj->aname = aname;
return true;
}
@@ -305,7 +298,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 = rtems_rtl_ptr_get (&obj->oname);
+ const char* n1 = obj->oname;
while ((*n1 != '\0') && (*n1 != '\n') && (*n1 != '/') &&
(*name != '\0') && (*name != '/') && (*n1 == *name))
{
@@ -322,7 +315,7 @@ bool
rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
{
struct stat sb;
- const char* n;
+ const char* pname;
/*
* Parse the name. The object descriptor will have the archive name and/or
@@ -340,76 +333,71 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
* the paths set in the RTL for the file.
*/
if (rtems_rtl_obj_aname_valid (obj))
- n = rtems_rtl_obj_aname (obj);
+ pname = rtems_rtl_obj_aname (obj);
else
- n = rtems_rtl_obj_oname (obj);
+ pname = rtems_rtl_obj_oname (obj);
- if (rtems_filesystem_is_delimiter (n[0]))
+ if (rtems_filesystem_is_delimiter (pname[0]))
{
- if (stat (n, &sb) == 0)
- rtems_rtl_str_copy (&obj->fname, n);
+ if (stat (pname, &sb) == 0)
+ obj->fname = rtems_rtl_strdup (pname);
}
else
{
rtems_rtl_data_t* rtl;
- const char* s;
- const char* e;
- int l;
+ const char* start;
+ const char* end;
+ int len;
+ char* fname;
rtl = rtems_rtl_lock ();
- s = rtl->paths;
- e = s + strlen (rtl->paths);
- l = strlen (n);
+ start = rtl->paths;
+ end = start + strlen (rtl->paths);
+ len = strlen (pname);
- while (rtems_rtl_ptr_null (&obj->fname) && (s != e))
+ while (!obj->fname && (start != end))
{
- rtems_rtl_ptr_t fname;
- const char* d;
- char* p;
-
- rtems_rtl_ptr_init (&fname);
+ const char* delimiter = strchr (start, ':');
- d = strchr (s, ':');
- if (d == NULL)
- d = e;
+ if (delimiter == NULL)
+ delimiter = end;
/*
- * Allocate the path fragment, separator, name, terminating nul.
+ * Allocate the path fragment, separator, name, terminating nul. Form the
+ * path then see if the stat call works.
*/
- rtems_rtl_alloc_indirect_new (RTEMS_RTL_ALLOC_STRING,
- &fname, (d - s) + 1 + l + 1);
- if (rtems_rtl_ptr_null (&fname))
+ fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+ (delimiter - start) + 1 + len + 1, true);
+ if (!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';
+ memcpy (fname, start, delimiter - start);
+ fname[delimiter - start] = '/';
+ memcpy (fname + (delimiter - start) + 1, pname, len);
- if (stat (p, &sb) < 0)
- rtems_rtl_alloc_indirect_del (RTEMS_RTL_ALLOC_STRING, &fname);
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+ printf ("rtl: loading: find-path: %s\n", fname);
+
+ if (stat (fname, &sb) < 0)
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
else
- {
- /*
- * We have found the file. Do not release the path memory.
- */
- rtems_rtl_ptr_move (&obj->fname, &fname);
- }
-
- s = d;
+ obj->fname = fname;
+
+ start = delimiter;
+ if (start != end)
+ ++start;
}
rtems_rtl_unlock ();
}
- if (rtems_rtl_ptr_null (&obj->fname))
+ if (!obj->fname)
{
rtems_rtl_set_error (ENOMEM, "object file not found");
return false;
@@ -432,7 +420,7 @@ rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
uint32_t flags)
{
rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
- sizeof (rtems_rtl_obj_sect_t));
+ sizeof (rtems_rtl_obj_sect_t), true);
if (!sect)
{
rtems_rtl_set_error (ENOMEM, "adding allocated section");
@@ -450,7 +438,7 @@ rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
rtems_chain_append (&obj->sections, &sect->node);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
- printf ("sect: %-2d: %s\n", section, name);
+ printf ("rtl: sect: %-2d: %s\n", section, name);
return true;
}
@@ -464,8 +452,8 @@ rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj)
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
rtems_chain_node* next_node = rtems_chain_next (node);
rtems_chain_extract (node);
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_STRING, (void*) sect->name);
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, node);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) sect->name);
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, sect);
node = next_node;
}
}
@@ -681,22 +669,20 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd)
bss_size = rtems_rtl_obj_bss_size (obj);
/*
- * The object file's memory allocated on the heap. This should be the
- * first allocation and any temporary allocations come after this
- * so the heap does not become fragmented.
+ * Let the allocator manage the actual allocation. The user can use the
+ * standard heap or provide a specific allocator with memory protection.
*/
- obj->exec_size = text_size + const_size + data_size + bss_size;
- obj->text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, obj->exec_size);
- if (!obj->text_base)
+ if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
+ &obj->const_base, const_size,
+ &obj->data_base, data_size,
+ &obj->bss_base, bss_size))
{
obj->exec_size = 0;
rtems_rtl_set_error (ENOMEM, "no memory to load obj");
return false;
}
- obj->const_base = obj->text_base + text_size;
- obj->data_base = obj->const_base + const_size;
- obj->bss_base = obj->data_base + data_size;
+ obj->exec_size = text_size + const_size + data_size + bss_size;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
{
@@ -723,11 +709,9 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd)
!rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_BSS,
fd, obj->ooffset, obj->bss_base))
{
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_MODULE, obj->text_base);
+ rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
+ &obj->data_base, &obj->bss_base);
obj->exec_size = 0;
- obj->text_base = 0;
- obj->data_base = 0;
- obj->bss_base = 0;
return false;
}
diff --git a/rtl-obj.h b/rtl-obj.h
index ca1a4c1..8440078 100644
--- a/rtl-obj.h
+++ b/rtl-obj.h
@@ -83,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. */
- rtems_rtl_ptr_t fname; /**< The file name for the object. */
- rtems_rtl_ptr_t oname; /**< The object file name. Can be
+ const char* fname; /**< The file name for the object. */
+ const char* oname; /**< The object file name. Can be
* relative. */
- rtems_rtl_ptr_t aname; /**< The archive name containing the
+ 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. */
@@ -136,7 +136,7 @@ typedef bool (*rtems_rtl_obj_sect_handler_t)(rtems_rtl_obj_t* obj,
*/
static inline const char* rtems_rtl_obj_fname (rtems_rtl_obj_t* obj)
{
- return rtems_rtl_ptr_type_get (&obj->fname, const char);
+ return obj->fname;
}
/**
@@ -147,7 +147,7 @@ static inline const char* rtems_rtl_obj_fname (rtems_rtl_obj_t* obj)
*/
static inline bool rtems_rtl_obj_fname_valid (rtems_rtl_obj_t* obj)
{
- return !rtems_rtl_ptr_null (&obj->fname);
+ return obj->fname;
}
/**
@@ -158,7 +158,7 @@ static inline bool rtems_rtl_obj_fname_valid (rtems_rtl_obj_t* obj)
*/
static inline const char* rtems_rtl_obj_oname (rtems_rtl_obj_t* obj)
{
- return rtems_rtl_ptr_type_get (&obj->oname, const char);
+ return obj->oname;
}
/**
@@ -169,7 +169,7 @@ static inline const char* rtems_rtl_obj_oname (rtems_rtl_obj_t* obj)
*/
static inline bool rtems_rtl_obj_oname_valid (rtems_rtl_obj_t* obj)
{
- return !rtems_rtl_ptr_null (&obj->oname);
+ return obj->oname;
}
/**
@@ -180,7 +180,7 @@ static inline bool rtems_rtl_obj_oname_valid (rtems_rtl_obj_t* obj)
*/
static inline const char* rtems_rtl_obj_aname (rtems_rtl_obj_t* obj)
{
- return rtems_rtl_ptr_type_get (&obj->aname, const char);
+ return obj->aname;
}
/**
@@ -191,7 +191,7 @@ static inline const char* rtems_rtl_obj_aname (rtems_rtl_obj_t* obj)
*/
static inline bool rtems_rtl_obj_aname_valid (rtems_rtl_obj_t* obj)
{
- return !rtems_rtl_ptr_null (&obj->aname);
+ return obj->aname;
}
/**
diff --git a/rtl-string.c b/rtl-string.c
index 921eca0..4a49b77 100644
--- a/rtl-string.c
+++ b/rtl-string.c
@@ -22,7 +22,7 @@ char*
rtems_rtl_strdup (const char *s1)
{
size_t len = strlen (s1);
- char* s2 = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_STRING, len + 1);
+ char* s2 = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, len + 1, false);
if (s2)
{
memcpy (s2, s1, len);
@@ -30,16 +30,3 @@ 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 5c599e9..d64d20b 100644
--- a/rtl-string.h
+++ b/rtl-string.h
@@ -30,14 +30,6 @@ extern "C" {
*/
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
}
#endif /* __cplusplus */
diff --git a/rtl-sym.c b/rtl-sym.c
index 163b683..7e5eb03 100644
--- a/rtl-sym.c
+++ b/rtl-sym.c
@@ -125,7 +125,8 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj,
printf ("rtl: global symbol add: %zi\n", count);
obj->global_size = count * sizeof (rtems_rtl_obj_sym_t);
- obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL, obj->global_size);
+ obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
+ obj->global_size, true);
if (!obj->global_table)
{
obj->global_size = 0;
diff --git a/rtl.c b/rtl.c
index 35fb06a..bad0a7c 100644
--- a/rtl.c
+++ b/rtl.c
@@ -186,7 +186,7 @@ rtems_rtl_data_init (void)
/*
* Need to malloc the memory so the free does not complain.
*/
- rtems_rtl_str_copy (&rtl->base->oname, "rtems-kernel");
+ rtl->base->oname = rtems_rtl_strdup ("rtems-kernel");
rtems_chain_append (&rtl->objects, &rtl->base->link);
}
@@ -453,7 +453,7 @@ rtems_rtl_path_update (bool prepend, const char* path)
else
prepend = true;
- paths = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_STRING, len + 1);
+ paths = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, len + 1, false);
if (!paths)
{