static void file_list_initialize (struct VdlList *files) { // The only thing we need to make sure here is that the executable // gets assigned tls module id 1 if needed. void **cur; for (cur = vdl_list_begin (files); cur != vdl_list_end (files); cur = vdl_list_next (files, cur)) { struct VdlFile *item = *cur; if (item->is_executable) { file_initialize (item); break; } } for (cur = vdl_list_begin (files); cur != vdl_list_end (files); cur = vdl_list_next (files, cur)) { struct VdlFile *item = *cur; if (!item->is_executable) { file_initialize (item); } } }
void vdl_list_sort (struct VdlList *list, bool (*is_strictly_lower) (void *a, void *b, void *context), void *context) { // insertion sort. struct VdlList sorted; vdl_list_construct (&sorted); void **i; for (i = vdl_list_begin (list); i != vdl_list_end (list); i = vdl_list_next (i)) { void **j; void **insertion = vdl_list_end (&sorted); for (j = vdl_list_begin (&sorted); j != vdl_list_end (&sorted); j = vdl_list_next (j)) { if (!is_strictly_lower (*j, *i, context)) { insertion = j; break; } } vdl_list_insert (&sorted, insertion, *i); } vdl_list_clear (list); vdl_list_insert_range (list, vdl_list_begin (list), vdl_list_begin (&sorted), vdl_list_end (&sorted)); vdl_list_destruct (&sorted); }
void vdl_list_unicize (struct VdlList *list) { void **i; for (i = vdl_list_begin (list); i != vdl_list_end (list); i = vdl_list_next (i)) { void *next = vdl_list_find_from (list, vdl_list_next (i), *i); while (next != vdl_list_end (list)) { next = vdl_list_erase (list, next); next = vdl_list_find_from (list, next, *i); } } }
static void file_delete (struct VdlFile *file, bool mapping) { vdl_context_remove_file (file->context, file); vdl_linkmap_remove (file); if (mapping) { void **i; for (i = vdl_list_begin (file->maps); i != vdl_list_end (file->maps); i = vdl_list_next (file->maps, i)) { struct VdlFileMap *map = *i; struct VdlFileAddress *ret, *address = vdl_alloc_new (struct VdlFileAddress); address->key = map->mem_start_align; ret = vdl_rbfind (g_vdl.address_ranges, address); vdl_rberase (g_vdl.address_ranges, ret); vdl_alloc_delete (address); int status = system_munmap ((void *) map->mem_start_align, map->mem_size_align); if (status == -1) { VDL_LOG_ERROR ("unable to unmap map 0x%lx[0x%lx] for \"%s\"\n", map->mem_start_align, map->mem_size_align, file->filename); } } } if (vdl_context_empty (file->context)) { vdl_context_delete (file->context); } vdl_list_delete (file->deps); vdl_list_delete (file->local_scope); vdl_list_delete (file->gc_symbols_resolved_in); vdl_alloc_free (file->name); vdl_alloc_free (file->filename); vdl_alloc_free (file->phdr); vdl_list_iterate (file->maps, vdl_alloc_free); vdl_list_delete (file->maps); rwlock_delete (file->lock); file->deps = 0; file->local_scope = 0; file->gc_symbols_resolved_in = 0; file->name = 0; file->filename = 0; file->context = 0; file->phdr = 0; file->phnum = 0; file->maps = 0; file->lock = 0; vdl_alloc_delete (file); }
void vdl_list_unique (struct VdlList *list) { void **i = vdl_list_begin (list); while (i != vdl_list_end (list)) { void **prev = vdl_list_prev (i); if (prev == vdl_list_end (list) || *prev != *i) { i = vdl_list_next (i); } else { i = vdl_list_erase (list, i); } } }
void vdl_unmap (struct VdlList *files, bool mapping) { void **i; for (i = vdl_list_begin (files); i != vdl_list_end (files); i = vdl_list_next (i)) { file_delete (*i, mapping); } }
struct VdlList *vdl_list_copy (struct VdlList *list) { struct VdlList *copy = vdl_list_new (); vdl_list_insert_range (copy, vdl_list_begin (copy), vdl_list_begin (list), vdl_list_end (list)); return copy; }
void vdl_list_remove (struct VdlList *list, void *data) { void **i; for (i = vdl_list_find (list, data); i != vdl_list_end (list); i = vdl_list_find_from (list, i, data)) { i = vdl_list_erase (list, i); } }
void vdl_utils_str_list_delete (struct VdlList *list) { void **i; for (i = vdl_list_begin (list); i != vdl_list_end (list); i = vdl_list_next (list, i)) { vdl_alloc_free (*i); } vdl_list_delete (list); }
void vdl_list_iterate (struct VdlList *list, void (*iterator) (void *data)) { void **i; for (i = vdl_list_begin (list); i != vdl_list_end (list); i = vdl_list_next (i)) { (*iterator) (*i); } }
void vdl_tls_file_deinitialize (struct VdlList *files) { write_lock (g_vdl.tls_lock); // the deinitialization order here does not matter at all. void **cur; for (cur = vdl_list_begin (files); cur != vdl_list_end (files); cur = vdl_list_next (files, cur)) { file_deinitialize (*cur); } write_unlock (g_vdl.tls_lock); }
static void file_delete (struct VdlFile *file, bool mapping) { vdl_context_remove_file (file->context, file); if (mapping) { void **i; for (i = vdl_list_begin (file->maps); i != vdl_list_end (file->maps); i = vdl_list_next (i)) { struct VdlFileMap *map = *i; int status = system_munmap ((void*)map->mem_start_align, map->mem_size_align); if (status == -1) { VDL_LOG_ERROR ("unable to unmap map 0x%lx[0x%lx] for \"%s\"\n", map->mem_start_align, map->mem_size_align, file->filename); } } } if (vdl_context_empty (file->context)) { vdl_context_delete (file->context); } vdl_list_delete (file->deps); vdl_list_delete (file->local_scope); vdl_list_delete (file->gc_symbols_resolved_in); vdl_alloc_free (file->name); vdl_alloc_free (file->filename); vdl_alloc_free (file->phdr); vdl_list_iterate (file->maps, vdl_alloc_free); vdl_list_delete (file->maps); file->deps = 0; file->local_scope = 0; file->gc_symbols_resolved_in = 0; file->name = 0; file->filename = 0; file->context = 0; file->phdr = 0; file->phnum = 0; file->maps = 0; vdl_alloc_delete (file); }
struct VdlList * vdl_utils_splitpath (const char *value) { struct VdlList *list = vdl_utils_strsplit (value, ':'); void **i; for (i = vdl_list_begin (list); i != vdl_list_end (list); i = vdl_list_next (list, i)) { if (vdl_utils_strisequal (*i, "")) { // the empty string is interpreted as '.' vdl_alloc_free (*i); i = vdl_list_erase (list, i); i = vdl_list_insert (list, i, vdl_utils_strdup (".")); } } return list; }
struct static_tls initialize_static_tls (struct VdlList *list) { // We calculate the size of the memory needed for the // static and local tls model. We also initialize correctly // the tls_offset field to be able to perform relocations // next (the TLS relocations need the tls_offset field). unsigned long tcb_size = g_vdl.tls_static_current_size; unsigned long n_dtv = 0; unsigned long max_align = g_vdl.tls_static_align; void **cur; for (cur = vdl_list_begin (list); cur != vdl_list_end (list); cur = vdl_list_next (list, cur)) { struct VdlFile *file = *cur; if (file->has_tls) { if (file->tls_is_static) { tcb_size += file->tls_tmpl_size + file->tls_init_zero_size; tcb_size = vdl_utils_align_up (tcb_size, file->tls_align); file->tls_offset = -tcb_size; if (file->tls_align > max_align) { max_align = file->tls_align; } } n_dtv++; } } struct static_tls static_tls; static_tls.size = tcb_size; static_tls.align = max_align; return static_tls; }
void vdl_list_clear (struct VdlList *list) { vdl_list_erase_range (list, vdl_list_begin (list), vdl_list_end (list)); }
void vdl_list_push_back (struct VdlList *list, void *data) { vdl_list_insert (list, vdl_list_end (list), data); }