summaryrefslogtreecommitdiff
path: root/rtl-obj.c
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 /rtl-obj.c
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'.
Diffstat (limited to 'rtl-obj.c')
-rw-r--r--rtl-obj.c192
1 files changed, 88 insertions, 104 deletions
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;
}