Ejemplo n.º 1
0
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);
   }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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
   }
}