diff options
author | Chris Johns <chrisj@rtems.org> | 2012-11-30 20:54:07 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-11-30 20:54:07 +1100 |
commit | 9856d096995e701ce68c6e0107146c7be3518502 (patch) | |
tree | ac1bbf4272a23e54b16eb09f28128cea5398e091 | |
parent | abb3dd4f73727756efd4856156acdbbbb271c26d (diff) |
Add a section handler to load sections.
-rw-r--r-- | rtl-elf.c | 35 | ||||
-rw-r--r-- | rtl-obj.c | 68 | ||||
-rw-r--r-- | rtl-obj.h | 11 | ||||
-rw-r--r-- | rtl-rap.c | 11 |
4 files changed, 81 insertions, 44 deletions
@@ -493,6 +493,39 @@ rtems_rtl_elf_symbols (rtems_rtl_obj_t* obj, } static bool +rtems_rtl_elf_loader (rtems_rtl_obj_t* obj, + int fd, + rtems_rtl_obj_sect_t* sect, + void* data) +{ + uint8_t* base_offset; + size_t len; + + if (lseek (fd, obj->ooffset + sect->offset, SEEK_SET) < 0) + { + rtems_rtl_set_error (errno, "section load seek failed"); + return false; + } + + base_offset = sect->base; + len = sect->size; + + while (len) + { + ssize_t r = read (fd, base_offset, len); + if (r <= 0) + { + rtems_rtl_set_error (errno, "section load read failed"); + return false; + } + base_offset += r; + len -= r; + } + + return true; +} + +static bool rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr) { rtems_rtl_obj_cache_t* sects; @@ -716,7 +749,7 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd) obj->entry = (void*)(uintptr_t) ehdr.e_entry; - if (!rtems_rtl_obj_load_sections (obj, fd)) + if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_elf_loader, &ehdr)) return false; if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols, &ehdr)) @@ -619,65 +619,52 @@ rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj, } static size_t -rtems_rtl_obj_sections_loader (rtems_chain_control* sections, - uint32_t mask, - int fd, - off_t offset, - uint8_t* base) +rtems_rtl_obj_sections_loader (uint32_t mask, + rtems_rtl_obj_t* obj, + int fd, + uint8_t* base, + rtems_rtl_obj_sect_handler_t handler, + void* data) { - rtems_chain_node* node = rtems_chain_first (sections); - size_t base_offset = 0; - bool first = true; + rtems_chain_control* sections = &obj->sections; + rtems_chain_node* node = rtems_chain_first (sections); + size_t base_offset = 0; + bool first = true; while (!rtems_chain_is_tail (sections, node)) { rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; if ((sect->size != 0) && ((sect->flags & mask) != 0)) { - uint8_t* sect_base = base + base_offset; - if (!first) base_offset = rtems_rtl_sect_align (base_offset, sect->alignment); + sect->base = base + base_offset; + if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT)) printf ("rtl: loading: %s -> %8p (%zi)\n", - sect->name, base + base_offset, sect->size); + sect->name, sect->base, sect->size); if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD) { - size_t len; - - if (lseek (fd, offset + sect->offset, SEEK_SET) < 0) + if (!handler (obj, fd, sect, data)) { - rtems_rtl_set_error (errno, "section load seek failed"); + sect->base = 0; return false; } - - len = sect->size; - while (len) - { - ssize_t r = read (fd, base + base_offset, len); - if (r <= 0) - { - rtems_rtl_set_error (errno, "section load read failed"); - return false; - } - base_offset += r; - len -= r; - } } else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO) { memset (base + base_offset, 0, sect->size); - base_offset += sect->size; } else { + sect->base = 0; rtems_rtl_set_error (errno, "section has no load op"); return false; } - sect->base = sect_base; + base_offset += sect->size; first = false; } @@ -688,7 +675,10 @@ rtems_rtl_obj_sections_loader (rtems_chain_control* sections, } bool -rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd) +rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, + int fd, + rtems_rtl_obj_sect_handler_t handler, + void* data) { size_t text_size; size_t const_size; @@ -732,14 +722,14 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd) * Load all text then data then bss sections in seperate operations so each * type of section is grouped together. */ - if (!rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_TEXT, - fd, obj->ooffset, obj->text_base) || - !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_CONST, - fd, obj->ooffset, obj->const_base) || - !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_DATA, - fd, obj->ooffset, obj->data_base) || - !rtems_rtl_obj_sections_loader (&obj->sections, RTEMS_RTL_OBJ_SECT_BSS, - fd, obj->ooffset, obj->bss_base)) + if (!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_TEXT, + obj, fd, obj->text_base, handler, data) || + !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST, + obj, fd, obj->const_base, handler, data) || + !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA, + obj, fd, obj->data_base, handler, data) || + !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS, + obj, fd, obj->bss_base, handler, data)) { rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->data_base, &obj->bss_base); @@ -55,7 +55,7 @@ typedef struct rtems_rtl_loader_table_s #define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */ #define RTEMS_RTL_OBJ_SECT_REL (1 << 4) /**< Section holds relocation records. */ #define RTEMS_RTL_OBJ_SECT_RELA (1 << 5) /**< Section holds relocation addend - * records. */ + * records. */ #define RTEMS_RTL_OBJ_SECT_SYM (1 << 6) /**< Section holds symbols. */ #define RTEMS_RTL_OBJ_SECT_STR (1 << 7) /**< Section holds strings. */ #define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 8) /**< Section allocates runtime memory. */ @@ -84,7 +84,7 @@ struct rtems_rtl_obj_sect_s int info; /**< Secfion info field. */ uint32_t flags; /**< The section's flags. */ void* base; /**< The base address of the section in - * memory. */ + * memory. */ }; /** @@ -470,10 +470,15 @@ bool rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj, * * @param obj The object file's descriptor. * @param fd The object file's file descriptor. + * @param handler The object file's format specific load handler. + * @param data User specific data handle. * @retval true The object has been sucessfully loaded. * @retval false The load failed. The RTL error has been set. */ -bool rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, int fd); +bool rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj, + int fd, + rtems_rtl_obj_sect_handler_t handler, + void* data); /** * Invoke the constructors the object has. Constructors are a table of pointers @@ -183,6 +183,15 @@ rtems_rtl_rap_read_uint32 (rtems_rtl_obj_comp_t* comp, uint32_t* value) } static bool +rtems_rtl_rap_loader (rtems_rtl_obj_t* obj, + int fd, + rtems_rtl_obj_sect_t* sect, + void* data) +{ + return true; +} + +static bool rtems_rtl_rap_symbols (rtems_rtl_obj_t* obj, int fd, rtems_rtl_obj_sect_t* sect, @@ -440,7 +449,7 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd) /** obj->entry = (void*)(uintptr_t) ehdr.e_entry; */ - if (!rtems_rtl_obj_load_sections (obj, fd)) + if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_rap_loader, &rap)) return false; if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_rap_symbols, &rap)) |