Ejemplo n.º 1
0
void DSBT_release_entry(int32_t file_handle)
{
   int32_t i; 
   DSBT_Entry *client_dsbt = (DSBT_Entry *)(DSBT_master.buf);
   for (i = 0; i < AL_size(&DSBT_master); i++)
   {
      DSBT_Index_Request *curr_req = client_dsbt[i].index_request;

      if (curr_req && (curr_req->file_handle == file_handle))
      {
         client_dsbt[i].index_request = NULL;
         if (i < DSBT_first_avail_index) DSBT_first_avail_index = i;
         DLIF_free(curr_req);
      }
   }
}
Ejemplo n.º 2
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
   }
}
Ejemplo n.º 3
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.º 4
0
void DLREL_c60_relocate(DLOAD_HANDLE handle,
                        LOADER_FILE_DESC *fd, DLIMP_Dynamic_Module *dyn_module)
{
   struct Elf32_Dyn  *dyn_nugget     = dyn_module->dyntab;
   struct Elf32_Rela *rela_table     = NULL;
   struct Elf32_Rel  *rel_table      = NULL;
   struct Elf32_Rela *rela_plt_table = NULL;
   struct Elf32_Rel  *rel_plt_table  = NULL;

   /*------------------------------------------------------------------------*/
   /* Read the size of the relocation table (DT_RELASZ) and the size per     */
   /* relocation (DT_RELAENT) from the dynamic segment.                      */
   /*------------------------------------------------------------------------*/
   uint32_t relasz  = DLIMP_get_first_dyntag(DT_RELASZ, dyn_nugget);
   uint32_t relaent = DLIMP_get_first_dyntag(DT_RELAENT, dyn_nugget);
   uint32_t relanum = 0;

   /*------------------------------------------------------------------------*/
   /* Read the size of the relocation table (DT_RELSZ) and the size per      */
   /* relocation (DT_RELENT) from the dynamic segment.                       */
   /*------------------------------------------------------------------------*/
   uint32_t relsz  = DLIMP_get_first_dyntag(DT_RELSZ, dyn_nugget);
   uint32_t relent = DLIMP_get_first_dyntag(DT_RELENT, dyn_nugget);
   uint32_t relnum = 0;

   /*------------------------------------------------------------------------*/
   /* Read the size of the relocation table (DT_PLTRELSZ) and the type of    */
   /* of the PLTGOT relocation table (DT_PLTREL): one of DT_REL or DT_RELA   */
   /*------------------------------------------------------------------------*/
   uint32_t pltrelsz  = DLIMP_get_first_dyntag(DT_PLTRELSZ, dyn_nugget);
   int      pltreltyp = DLIMP_get_first_dyntag(DT_PLTREL, dyn_nugget);
   uint32_t pltnum    = 0;

   /*------------------------------------------------------------------------*/
   /* Find/record DSBT index associated with this module.                    */
   /*------------------------------------------------------------------------*/
   if (is_dsbt_module(dyn_module) && 
       (dyn_module->dsbt_index == DSBT_INDEX_INVALID))
      dyn_module->dsbt_index = 
                   DLIF_get_dsbt_index(dyn_module->loaded_module->file_handle);

   /*------------------------------------------------------------------------*/
   /* Read the PLTGOT relocation table from the file                         */
   /* The PLTGOT table is a subsection at the end of either the DT_REL or    */
   /* DT_RELA table.  The size of the table it belongs to DT_REL(A)SZ        */
   /* includes the size of the PLTGOT table.  So it must be adjusted so that */
   /* the GOT relocation tables only contain actual GOT relocations.         */
   /*------------------------------------------------------------------------*/
   if (pltrelsz != INT_MAX && pltrelsz != 0)
   {
      if (pltreltyp == DT_REL)
      {
         pltnum = pltrelsz/relent;
	 relsz -= pltrelsz;
	 read_rel_table((&rel_plt_table),
	                DLIMP_get_first_dyntag(DT_JMPREL, dyn_nugget),
			pltnum, relent, fd, dyn_module->wrong_endian);
      } 
      
      else if (pltreltyp == DT_RELA) 
      {
         pltnum = pltrelsz/relaent;
	 relasz -= pltrelsz;
	 read_rela_table((&rela_plt_table),
	                 DLIMP_get_first_dyntag(DT_JMPREL, dyn_nugget),
			 pltnum, relaent, fd, dyn_module->wrong_endian);
      } 
      
      else 
      {
         DLIF_error(DLET_RELOC,
	            "DT_PLTREL is invalid: must be either %d or %d\n",
		    DT_REL, DT_RELA);
      }
   }

   /*------------------------------------------------------------------------*/
   /* Read the DT_RELA GOT relocation table from the file                    */
   /*------------------------------------------------------------------------*/
   if (relasz != INT_MAX && relasz != 0)
   {
      relanum = relasz/relaent;
      read_rela_table(&rela_table, DLIMP_get_first_dyntag(DT_RELA, dyn_nugget),
                      relanum, relaent, fd, dyn_module->wrong_endian);
   }

   /*------------------------------------------------------------------------*/
   /* Read the DT_REL GOT relocation table from the file                     */
   /*------------------------------------------------------------------------*/ 
   if (relsz != INT_MAX && relsz != 0)
   {
      relnum = relsz/relent;
      read_rel_table(&rel_table, DLIMP_get_first_dyntag(DT_REL, dyn_nugget),
                     relnum, relent, fd, dyn_module->wrong_endian);
   }

   /*------------------------------------------------------------------------*/
   /* Process the PLTGOT relocations                                         */
   /*------------------------------------------------------------------------*/
   if (rela_plt_table) 
      process_pltgot_relocs(handle, rela_plt_table, pltreltyp, pltnum, 
                            dyn_module); 

   if (rel_plt_table) 
      process_pltgot_relocs(handle, rel_plt_table, pltreltyp, pltnum, 
                            dyn_module); 
   
   /*------------------------------------------------------------------------*/
   /* Process the GOT relocations                                            */
   /*------------------------------------------------------------------------*/
   if (rel_table || rela_table)
      process_got_relocs(handle, rel_table, relnum, rela_table, relanum, 
                         dyn_module); 
   
   /*-------------------------------------------------------------------------*/
   /* Free memory used for ELF relocation table copies.                       */
   /*-------------------------------------------------------------------------*/
   if (rela_table)     DLIF_free(rela_table);
   if (rel_table)      DLIF_free(rel_table);
   if (rela_plt_table) DLIF_free(rela_plt_table);
   if (rel_plt_table)  DLIF_free(rel_plt_table);
}