static void rtems_rtl_obj_free_names (rtems_rtl_obj_t* obj) { if (rtems_rtl_obj_oname_valid (obj)) rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->oname); if (rtems_rtl_obj_aname_valid (obj)) rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->aname); if (rtems_rtl_obj_fname_valid (obj)) rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->fname); }
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; }
void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj) { rtems_chain_node* node = rtems_chain_first (&obj->sections); while (!rtems_chain_is_tail (&obj->sections, node)) { 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_OBJECT, (void*) sect->name); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, sect); node = next_node; } }
void rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, cache->buffer); cache->fd = -1; cache->file_size = 0; cache->level = 0; }
void rtems_rtl_symbol_obj_erase_local (rtems_rtl_obj_t* obj) { if (obj->local_table) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->local_table); obj->local_table = NULL; obj->local_size = 0; obj->local_syms = 0; } }
void rtems_rtl_obj_comp_close (rtems_rtl_obj_comp_t* comp) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, comp->buffer); comp->cache = NULL; comp->fd = -1; comp->compression = RTEMS_RTL_COMP_LZ77; comp->level = 0; comp->size = 0; comp->offset = 0; comp->read = 0; }
bool rtems_rtl_obj_free (rtems_rtl_obj_t* obj) { if (obj->users || ((obj->flags & RTEMS_RTL_OBJ_LOCKED) != 0)) { rtems_rtl_set_error (EINVAL, "cannot free obj still in use"); return false; } 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_symbol_obj_erase (obj); rtems_rtl_obj_free_names (obj); if (obj->sec_num) free (obj->sec_num); if (obj->detail) rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*)obj->detail); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj); return true; }
void rtems_rtl_symbol_obj_erase (rtems_rtl_obj_t* obj) { rtems_rtl_symbol_obj_erase_local (obj); if (obj->global_table) { rtems_rtl_obj_sym_t* sym; size_t s; for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym) if (!rtems_chain_is_node_off_chain (&sym->node)) rtems_chain_extract (&sym->node); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table); obj->global_table = NULL; obj->global_size = 0; obj->global_syms = 0; } }
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 ("rtl: alloc: idel: %s handle=%p: is null\n", rtems_rtl_trace_tag_label (tag), handle); printf ("rtl: 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); } }
void rtems_rtl_symbol_table_close (rtems_rtl_symbols_t* symbols) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, symbols->buckets); }
bool rtems_rtl_parse_name (const char* name, const char** aname, const char** oname, off_t* ooffset) { const char* laname = NULL; const char* loname = 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. If an archive check the name for a '@' to see if the * archive contains an offset. */ end = name + strlen (name); colon = strrchr (name, ':'); if (colon == NULL || colon < strrchr(name, '/')) colon = end; loname = 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; } memcpy ((void*) loname, name, colon - name); /* * If the pointers match there is no ':' delimiter. */ if (colon != end) { 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. */ laname = loname; ++colon; /* * See if there is a '@' to delimit an archive offset for the object in the * archive. */ at = strchr (colon, '@'); if (at == NULL) at = end; loname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, at - colon + 1, true); if (!loname) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) laname); rtems_rtl_set_error (ENOMEM, "no memory for object file name"); return false; } memcpy ((void*) loname, colon, at - colon); 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. */ *ooffset = strtoul (at + 1, 0, 0); } } *oname = loname; *aname = laname; return true; }
bool rtems_rtl_find_file (const char* name, const char* paths, const char** file_name, size_t* size) { struct stat sb; *file_name = NULL; *size = 0; if (rtems_filesystem_is_delimiter (name[0]) || (name[0] == '.')) { if (stat (name, &sb) == 0) *file_name = rtems_rtl_strdup (name); } else if (paths) { const char* start; const char* end; int len; char* fname; start = paths; end = start + strlen (paths); len = strlen (name); while (!*file_name && (start != end)) { const char* delimiter = strchr (start, ':'); if (delimiter == NULL) delimiter = end; /* * Allocate the path fragment, separator, name, terminating nul. Form the * path then see if the stat call works. */ 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 file"); return false; } memcpy (fname, start, delimiter - start); fname[delimiter - start] = '/'; memcpy (fname + (delimiter - start) + 1, name, len); if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD)) printf ("rtl: find-file: path: %s\n", fname); if (stat (fname, &sb) < 0) rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname); else *file_name = fname; start = delimiter; if (start != end) ++start; } } if (!*file_name) return false; *size = sb.st_size; return true; }