diff options
author | Chris Johns <chrisj@rtems.org> | 2012-05-28 08:23:58 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-05-28 08:23:58 +1000 |
commit | 9f020ad54f678f6f2e271b3cb9153191f407f746 (patch) | |
tree | f05ed68071f077bf45c781cef145426137ee36b4 | |
parent | fb0c9b27451d420175a76a0eef733792317d225f (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.c | 102 | ||||
-rw-r--r-- | rtl-allocator.h | 54 | ||||
-rw-r--r-- | rtl-elf.c | 13 | ||||
-rw-r--r-- | rtl-obj-cache.c | 2 | ||||
-rw-r--r-- | rtl-obj.c | 192 | ||||
-rw-r--r-- | rtl-obj.h | 18 | ||||
-rw-r--r-- | rtl-string.c | 15 | ||||
-rw-r--r-- | rtl-string.h | 8 | ||||
-rw-r--r-- | rtl-sym.c | 3 | ||||
-rw-r--r-- | rtl.c | 4 |
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 */ @@ -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"); @@ -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, §->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; } @@ -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 */ @@ -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; @@ -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) { |