static void read_rela_table(struct Elf32_Rela **rela_table, int32_t table_offset, uint32_t relanum, uint32_t relaent, LOADER_FILE_DESC *fd, BOOL wrong_endian) { if (relanum == 0) { *rela_table = NULL; return; } *rela_table = (struct Elf32_Rela *)DLIF_malloc(relanum * relaent); DLIF_fseek(fd, table_offset, LOADER_SEEK_SET); DLIF_fread(*rela_table, relanum, relaent, fd); if (wrong_endian) { int i; for (i = 0; i < relanum; i++) DLIMP_change_rela_endian(*rela_table + i); } }
BOOL DLIF_register_dsbt_index_request(DLOAD_HANDLE handle, const char *requestor_name, int32_t requestor_file_handle, int32_t requested_dsbt_index) { DSBT_Index_Request *new_request = NULL; /*------------------------------------------------------------------------*/ /* If requesting a specific DSBT index, check existing list of DSBT index */ /* requests to see if we've already seen a request for the specified */ /* DSBT index or if a request has already been received on behalf of the */ /* specified file. Both cases constitute an error and will abort the */ /* load. */ /*------------------------------------------------------------------------*/ if (requested_dsbt_index != DSBT_INDEX_INVALID) { dsbt_index_request_ptr_Queue_Node *ptr; /*---------------------------------------------------------------------*/ /* If the client's master DSBT model already has content, then check */ /* to see if the requested DSBT index is available in the master DSBT. */ /*---------------------------------------------------------------------*/ if (AL_size(&DSBT_master) > requested_dsbt_index) { DSBT_Entry *client_dsbt = (DSBT_Entry *)(DSBT_master.buf); if (client_dsbt[requested_dsbt_index].index_request != NULL) { DLIF_error(DLET_MISC, "%s is requesting a DSBT index, %d, that is already " "being used by an active module, %s", requestor_name, requested_dsbt_index, client_dsbt[requested_dsbt_index].index_request->name); return FALSE; } } for (ptr = DSBT_index_request_queue.front_ptr; ptr != NULL; ptr = ptr->next_ptr) { DSBT_Index_Request *existing_request = ptr->value; /*------------------------------------------------------------------*/ /* Have we seen a request for this file already? That would be a */ /* problem (likely internal). */ /*------------------------------------------------------------------*/ if (requestor_file_handle == existing_request->file_handle) { DLIF_error(DLET_MISC, "A DSBT index has already been requested on behalf " "of %s; cannot make a second DSBT index request for " "the same module", existing_request->name); return FALSE; } /*------------------------------------------------------------------*/ /* Have we seen a specific request for this DSBT index already? */ /* Report a conflict among specific requests in the same load. */ /*------------------------------------------------------------------*/ if (requested_dsbt_index == existing_request->requested_index) { DLIF_error(DLET_MISC, "Requested DSBT index, %d, requested by %s has " "already been requested by %s; load aborted", requested_dsbt_index, requestor_name, existing_request->name); return FALSE; } } } /*------------------------------------------------------------------------*/ /* If specified module is requesting a specific DSBT index that hasn't */ /* been encountered yet, or if it is making a general DSBT index request */ /* (to be assigned by the client when the current top-level load is */ /* sucessfully completed), make a DSBT index request entry for the */ /* current module and add it to the DSBT_Index_Request_List. */ /*------------------------------------------------------------------------*/ new_request = (DSBT_Index_Request *)DLIF_malloc(sizeof(DSBT_Index_Request)); new_request->name = (char *)DLIF_malloc(strlen(requestor_name) + 1); strcpy(new_request->name, requestor_name); new_request->file_handle = requestor_file_handle; new_request->dsbt_size = DLOAD_get_dsbt_size(handle, requestor_file_handle); if (!DLOAD_get_dsbt_base(handle, requestor_file_handle, &new_request->dsbt_base)) { DLIF_error(DLET_MISC, "Could not resolve DSBT base value for %s", requestor_name); DLIF_free(new_request->name); new_request->name = NULL; DLIF_free(new_request); new_request = NULL; return FALSE; } if (!DLOAD_get_static_base(handle, requestor_file_handle, &new_request->static_base)) { DLIF_error(DLET_MISC, "Could not resolve static base value for %s", requestor_name); DLIF_free(new_request->name); new_request->name = NULL; DLIF_free(new_request); new_request = NULL; return FALSE; } new_request->requested_index = requested_dsbt_index; new_request->assigned_index = DSBT_INDEX_INVALID; dsbt_index_request_ptr_enqueue(&DSBT_index_request_queue, new_request); return TRUE; }
void DLSYM_copy_globals(DLIMP_Dynamic_Module *dyn_module) { Elf32_Word i, global_index, global_symnum; DLIMP_Loaded_Module *module = dyn_module->loaded_module; #if LOADER_DEBUG if (debugging_on) DLIF_trace("DLSYM_copy_globals:\n"); #endif /*------------------------------------------------------------------------*/ /* The dynamic symbol table is sorted so that the local symbols come */ /* before the global symbols. gsymtab_offset points to the address where */ /* the first global symbol starts. Only the global symbols need to be */ /* copied into the persistent info. */ /*------------------------------------------------------------------------*/ global_index = dyn_module->gsymtab_offset / sizeof(struct Elf32_Sym); global_symnum = dyn_module->symnum - global_index; /*------------------------------------------------------------------------*/ /* Create space for the new global symbol table. */ /*------------------------------------------------------------------------*/ if (module->gsymtab) DLIF_free(module->gsymtab); module->gsymtab = DLIF_malloc(sizeof(struct Elf32_Sym) * global_symnum); module->gsymnum = global_symnum; if (module->gsymtab) memcpy(module->gsymtab, &dyn_module->symtab[global_index], sizeof(struct Elf32_Sym) * global_symnum); /*------------------------------------------------------------------------*/ /* Copy the string table part that contains the global symbol names. */ /*------------------------------------------------------------------------*/ if (module->gstrtab) DLIF_free(module->gstrtab); module->gstrsz = dyn_module->strsz - dyn_module->gstrtab_offset; module->gstrtab = DLIF_malloc(module->gstrsz); if (module->gstrtab) memcpy(module->gstrtab, dyn_module->strtab + dyn_module->gstrtab_offset, module->gstrsz); /*------------------------------------------------------------------------*/ /* Update the symbol names of the global symbol entries to point to */ /* the symbol names in the string table. */ /* NOTE: Note that we don't set the offset into the string table. We */ /* instead set the full address so that the st_name field can be accessed */ /* as char *. */ /*------------------------------------------------------------------------*/ for (i = 0; i < global_symnum; i++) { Elf32_Word old_offset = dyn_module->symtab[i + global_index].st_name - (Elf32_Addr) dyn_module->strtab; Elf32_Word new_offset = old_offset - dyn_module->gstrtab_offset; if(module->gsymtab) { struct Elf32_Sym *sym = &((struct Elf32_Sym*)(module->gsymtab))[i]; sym->st_name = new_offset + (Elf32_Addr)module->gstrtab; } #if LOADER_DEBUG if (debugging_on) DLIF_trace("Copying symbol: %s\n", (char *) dyn_module->symtab[i + global_index].st_name); #endif } }