This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

LINK6 format bug fixes


Hi Guys,

  I am checking in the patch below to fix several bugs that have been
  discovered in the LINK6 support code that I added to BFD recently.

Cheers
	Nick

2000-03-06  Nick Clifton  <nickc@cygnus.com>

	* peicode.h (struct pe_ILF_vars): Add sym_ptr_table and
	sym_ptr_ptr fields.
	(SIZEOF_ILF_SYM_PTR_TABLE): Define.
	(SIZEOF_ILF_STRINGS): Redefine.
	(pe_ILF_make_a_symbol-reloc): New function.  Creates a symbol
	relative reloc, as opposed to a section relative reloc.
	(pe_ILF_make_a_symbol): Set the class of local symbols to C_STAT
	not C_LABEL.
	Add length of symbol's prefix to string pointer.
	Store a pointer to the symbol in the symbol pointer table.
	(pe_ILF_build_a_bfd): Do not build .idata$2 or .idata$7.
	Initialise the symbol pointer table.
	Store the hint in the Hint/Name table.
	Make the jump reloc be symbol realtive, not section relative.
	Create an import symbol for imported code.

Index: bfd/peicode.h
===================================================================
RCS file: /cvs/src//src/bfd/peicode.h,v
retrieving revision 1.18
diff -p -w -r1.18 peicode.h
*** peicode.h	2000/03/01 20:39:07	1.18
--- peicode.h	2000/03/06 19:46:47
*************** typedef struct
*** 118,123 ****
--- 118,126 ----
    combined_entry_type * native_syms;
    combined_entry_type * native_ptr;
  
+   coff_symbol_type **	sym_ptr_table;
+   coff_symbol_type **	sym_ptr_ptr;
+   
    unsigned int		sec_index;
  
    char *                string_table;
*************** static asection_ptr       pe_ILF_make_a_
*** 135,140 ****
--- 138,144 ----
  static void               pe_ILF_make_a_reloc     PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, asection_ptr));
  static void               pe_ILF_make_a_symbol    PARAMS ((pe_ILF_vars *, const char *, const char *, asection_ptr, flagword));
  static void               pe_ILF_save_relocs      PARAMS ((pe_ILF_vars *, asection_ptr));
+ static void		  pe_ILF_make_a_symbol_reloc  PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type,	   struct symbol_cache_entry **, unsigned int));
  static boolean            pe_ILF_build_a_bfd      PARAMS ((bfd *, unsigned short, bfd_byte *, bfd_byte *, unsigned int, unsigned int));
  static const bfd_target * pe_ILF_object_p         PARAMS ((bfd *));
  static const bfd_target * pe_bfd_object_p 	  PARAMS ((bfd *));
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 431,441 ****
     The value for SIZEOF_ILF_STRINGS is computed as follows:
  
        There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
!       per symbol for their names (longest section name is .idata$2).
  
        There will be two symbols for the imported value, one the symbol name
        and one with _imp__ prefixed.  Allowing for the terminating nul's this
!       is strlen (symbol_name) * 2 + 8.
  
        The strings in the string table must start STRING__SIZE_SIZE bytes into
        the table in order to for the string lookup code in coffgen/coffcode to
--- 435,445 ----
     The value for SIZEOF_ILF_STRINGS is computed as follows:
  
        There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
!       per symbol for their names (longest section name is .idata$x).
  
        There will be two symbols for the imported value, one the symbol name
        and one with _imp__ prefixed.  Allowing for the terminating nul's this
!       is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
  
        The strings in the string table must start STRING__SIZE_SIZE bytes into
        the table in order to for the string lookup code in coffgen/coffcode to
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 447,456 ****
  #define SIZEOF_ILF_SYMS		(NUM_ILF_SYMS * sizeof (* vars.sym_cache))
  #define SIZEOF_ILF_SYM_TABLE	(NUM_ILF_SYMS * sizeof (* vars.sym_table))
  #define SIZEOF_ILF_NATIVE_SYMS	(NUM_ILF_SYMS * sizeof (* vars.native_syms))
  #define SIZEOF_ILF_EXT_SYMS	(NUM_ILF_SYMS * sizeof (* vars.esym_table))
  #define SIZEOF_ILF_RELOCS	(NUM_ILF_RELOCS * sizeof (* vars.reltab))
  #define SIZEOF_ILF_INT_RELOCS	(NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
! #define SIZEOF_ILF_STRINGS	(strlen (symbol_name) * 2 + 8 + NUM_ILF_SECTIONS * 9 + STRING_SIZE_SIZE)
  #define SIZEOF_IDATA2		(5 * 4)
  #define SIZEOF_IDATA4		(1 * 4)
  #define SIZEOF_IDATA5		(1 * 4)
--- 451,464 ----
  #define SIZEOF_ILF_SYMS		(NUM_ILF_SYMS * sizeof (* vars.sym_cache))
  #define SIZEOF_ILF_SYM_TABLE	(NUM_ILF_SYMS * sizeof (* vars.sym_table))
  #define SIZEOF_ILF_NATIVE_SYMS	(NUM_ILF_SYMS * sizeof (* vars.native_syms))
+ #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
  #define SIZEOF_ILF_EXT_SYMS	(NUM_ILF_SYMS * sizeof (* vars.esym_table))
  #define SIZEOF_ILF_RELOCS	(NUM_ILF_RELOCS * sizeof (* vars.reltab))
  #define SIZEOF_ILF_INT_RELOCS	(NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
! #define SIZEOF_ILF_STRINGS	(strlen (symbol_name) * 2 + 8 \
! 					+ 21 + strlen (source_dll) \
! 					+ NUM_ILF_SECTIONS * 9 \
! 					+ STRING_SIZE_SIZE)
  #define SIZEOF_IDATA2		(5 * 4)
  #define SIZEOF_IDATA4		(1 * 4)
  #define SIZEOF_IDATA5		(1 * 4)
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 463,468 ****
--- 471,477 ----
      + SIZEOF_ILF_SYMS				\
      + SIZEOF_ILF_SYM_TABLE			\
      + SIZEOF_ILF_NATIVE_SYMS			\
+     + SIZEOF_ILF_SYM_PTR_TABLE			\
      + SIZEOF_ILF_EXT_SYMS			\
      + SIZEOF_ILF_RELOCS				\
      + SIZEOF_ILF_INT_RELOCS			\
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 478,487 ****
  
  /* Create an empty relocation against the given symbol.  */
  static void
! pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
  		     bfd_vma                   address,
  		     bfd_reloc_code_real_type  reloc,
! 		     asection_ptr              sec)
  {
    arelent * entry;
    struct internal_reloc * internal;
--- 487,497 ----
  
  /* Create an empty relocation against the given symbol.  */
  static void
! pe_ILF_make_a_symbol_reloc (pe_ILF_vars *                 vars,
  			    bfd_vma                       address,
  			    bfd_reloc_code_real_type      reloc,
! 			    struct symbol_cache_entry **  sym,
! 			    unsigned int                  sym_index)
  {
    arelent * entry;
    struct internal_reloc * internal;
*************** pe_ILF_make_a_reloc (pe_ILF_vars *      
*** 492,501 ****
    entry->address     = address;
    entry->addend      = 0;
    entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
!   entry->sym_ptr_ptr = sec->symbol_ptr_ptr;
  
    internal->r_vaddr  = address;
!   internal->r_symndx = coff_section_data (vars->abfd, sec)->i;
    internal->r_type   = entry->howto->type;
  #if 0  /* These fields do not need to be initialised.  */
    internal->r_size   = 0;
--- 502,511 ----
    entry->address     = address;
    entry->addend      = 0;
    entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
!   entry->sym_ptr_ptr = sym;
  
    internal->r_vaddr  = address;
!   internal->r_symndx = sym_index;
    internal->r_type   = entry->howto->type;
  #if 0  /* These fields do not need to be initialised.  */
    internal->r_size   = 0;
*************** pe_ILF_make_a_reloc (pe_ILF_vars *      
*** 508,513 ****
--- 518,534 ----
    BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
  }
  
+ /* Create an empty relocation against the given section.  */
+ static void
+ pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
+ 		     bfd_vma                   address,
+ 		     bfd_reloc_code_real_type  reloc,
+ 		     asection_ptr              sec)
+ {
+   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
+ 			      coff_section_data (vars->abfd, sec)->i);
+ }
+ 
  /* Move the queued relocs into the given section.  */
  static void
  pe_ILF_save_relocs (pe_ILF_vars * vars,
*************** pe_ILF_make_a_symbol (pe_ILF_vars *  var
*** 546,552 ****
    unsigned short sclass;
  
    if (extra_flags & BSF_LOCAL)
!     sclass = C_LABEL;
    else
      sclass = C_EXT;
    
--- 567,573 ----
    unsigned short sclass;
  
    if (extra_flags & BSF_LOCAL)
!     sclass = C_STAT;
    else
      sclass = C_EXT;
    
*************** pe_ILF_make_a_symbol (pe_ILF_vars *  var
*** 556,562 ****
        if (extra_flags & BSF_FUNCTION)
  	sclass = C_THUMBEXTFUNC;
        else if (extra_flags & BSF_LOCAL)
! 	sclass = C_THUMBLABEL;
        else
  	sclass = C_THUMBEXT;
      }
--- 577,583 ----
        if (extra_flags & BSF_FUNCTION)
  	sclass = C_THUMBEXTFUNC;
        else if (extra_flags & BSF_LOCAL)
! 	sclass = C_THUMBSTAT;
        else
  	sclass = C_THUMBEXT;
      }
*************** pe_ILF_make_a_symbol (pe_ILF_vars *  var
*** 573,579 ****
--- 594,604 ----
  
    /* Initialise the external symbol.  */
    bfd_h_put_32 (vars->abfd, vars->string_ptr - vars->string_table, (bfd_byte *) esym->e.e.e_offset);
+   if (section)
      bfd_h_put_16 (vars->abfd, section->target_index, (bfd_byte *) esym->e_scnum);
+   else
+     bfd_h_put_16 (vars->abfd, 0, (bfd_byte *) esym->e_scnum);
+     
    esym->e_sclass[0] = sclass;
  
    /* The following initialisations are unnecessary - the memory is
*************** pe_ILF_make_a_symbol (pe_ILF_vars *  var
*** 587,592 ****
--- 612,618 ----
    
    /* Initialise the internal symbol structure.  */
    ent->u.syment.n_sclass          = sclass;
+   if (section)
      ent->u.syment.n_scnum         = section->target_index;
    ent->u.syment._n._n_n._n_offset = (long) sym;
    
*************** pe_ILF_make_a_symbol (pe_ILF_vars *  var
*** 612,625 ****
  #endif
    
    * vars->table_ptr = vars->sym_index;
  
    /* Adjust pointers for the next symbol.  */
    vars->sym_index ++;
    vars->sym_ptr ++;
    vars->table_ptr ++;
    vars->native_ptr ++;
    vars->esym_ptr ++;
!   vars->string_ptr += strlen (symbol_name) + 1;
  
    BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
  }
--- 638,653 ----
  #endif
    
    * vars->table_ptr = vars->sym_index;
+   * vars->sym_ptr_ptr = sym;
    
    /* Adjust pointers for the next symbol.  */
    vars->sym_index ++;
    vars->sym_ptr ++;
+   vars->sym_ptr_ptr ++;
    vars->table_ptr ++;
    vars->native_ptr ++;
    vars->esym_ptr ++;
!   vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
  
    BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
  }
*************** pe_ILF_make_a_section (pe_ILF_vars * var
*** 672,678 ****
    /* Create a symbol to refer to this section.  */
    pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
  
!   /* Cache the index to the symbol in the coff_section_data structire.  */
    coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
    
    return sec;
--- 700,706 ----
    /* Create a symbol to refer to this section.  */
    pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
  
!   /* Cache the index to the symbol in the coff_section_data structure.  */
    coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
    
    return sec;
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 761,770 ****
    struct internal_filehdr  internal_f;
    unsigned int             import_type;
    unsigned int             import_name_type;
!   asection_ptr             id2, id4, id5, id6 = NULL, id7, text;
  
-   text = NULL;
-   
    /* Decode and verify the types field of the ILF structure.  */
    import_type = types & 0x3;
    import_name_type = (types & 0x1c) >> 2;
--- 789,798 ----
    struct internal_filehdr  internal_f;
    unsigned int             import_type;
    unsigned int             import_name_type;
!   asection_ptr             id4, id5, id6 = NULL, text = NULL;
!   coff_symbol_type **      imp_sym;
!   unsigned int             imp_index;
  
    /* Decode and verify the types field of the ILF structure.  */
    import_type = types & 0x3;
    import_name_type = (types & 0x1c) >> 2;
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 833,838 ****
--- 861,870 ----
    vars.native_ptr  = (combined_entry_type *) ptr;
    ptr += SIZEOF_ILF_NATIVE_SYMS;
  
+   vars.sym_ptr_table = (coff_symbol_type **) ptr;
+   vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
+   ptr += SIZEOF_ILF_SYM_PTR_TABLE;
+   
    vars.esym_table = (SYMENT *) ptr;
    vars.esym_ptr   = (SYMENT *) ptr;
    ptr += SIZEOF_ILF_EXT_SYMS;
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 857,872 ****
    vars.magic = magic;
    
    /* Create the initial .idata$<n> sections:
!      .idata$2:  Import Directory Table
       .idata$4:  Import Lookup Table
       .idata$5:  Import Address Table
  
       Note we do not create a .idata$3 section as this is
       created for us by the linker script.  */
-   id2 = pe_ILF_make_a_section (& vars, ".idata$2", SIZEOF_IDATA2, 0);
    id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
    id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
!   if (id2 == NULL || id4 == NULL || id5 == NULL)
      return false;
    
    /* Fill in the contents of these sections.  */
--- 889,903 ----
    vars.magic = magic;
    
    /* Create the initial .idata$<n> sections:
!      [.idata$2:  Import Directory Table -- not needed]
       .idata$4:  Import Lookup Table
       .idata$5:  Import Address Table
  
       Note we do not create a .idata$3 section as this is
       created for us by the linker script.  */
    id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
    id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
!   if (id4 == NULL || id5 == NULL)
      return false;
    
    /* Fill in the contents of these sections.  */
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 876,883 ****
  	/* XXX - treat as IMPORT_NAME ??? */
  	abort ();
        
!       * (unsigned int *) id4->contents = ordinal | 0x80000000;
!       * (unsigned int *) id5->contents = ordinal | 0x80000000;
      }
    else
      {
--- 907,914 ----
  	/* XXX - treat as IMPORT_NAME ??? */
  	abort ();
        
!       * (unsigned int *) id4->contents = ordinal | 0x80000000UL;
!       * (unsigned int *) id5->contents = ordinal | 0x80000000UL;
      }
    else
      {
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 904,925 ****
  
  	  * symbol = 0;
  	}
-       
-       strcpy (id6->contents, symbol);
-     }
- 
-   /* Create .idata$7 - the Dll Name Table.  */
-   id7 = pe_ILF_make_a_section (& vars, ".idata$7", SIZEOF_IDATA7, 0);
-   if (id7 == NULL)
-     return false;
    
!   strcpy (id7->contents + 2, source_dll);
  
!   /* Now generate the relocs for the sections.  */
!   pe_ILF_make_a_reloc (& vars,  0, BFD_RELOC_RVA, id4);
!   pe_ILF_make_a_reloc (& vars, 12, BFD_RELOC_RVA, id7);
!   pe_ILF_make_a_reloc (& vars, 16, BFD_RELOC_RVA, id5);
!   pe_ILF_save_relocs (& vars, id2);
  
    if (import_name_type != IMPORT_ORDINAL)
      {
--- 935,946 ----
  
  	  * symbol = 0;
  	}
        
!       id6->contents[0] = ordinal & 0xff;
!       id6->contents[1] = ordinal >> 8;
        
!       strcpy (id6->contents + 2, symbol);
!     }
  
    if (import_name_type != IMPORT_ORDINAL)
      {
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 957,973 ****
        /* Copy in the jump code.  */
        memcpy (text->contents, jtab[i].data, jtab[i].size);
  
        /* Create a reloc for the data in the text section.  */
  #ifdef MIPS_ARCH_MAGIC_WINCE      
        if (magic == MIPS_ARCH_MAGIC_WINCE)
  	{
! 	  pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_HI16_S, id5);
  	  pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_LO16, text);
! 	  pe_ILF_make_a_reloc (& vars, 4, BFD_RELOC_LO16, id5);
  	}
        else
  #endif
! 	pe_ILF_make_a_reloc (& vars, jtab[i].offset, BFD_RELOC_32, id5);
        
        pe_ILF_save_relocs (& vars, text);
        break;
--- 978,1002 ----
        /* Copy in the jump code.  */
        memcpy (text->contents, jtab[i].data, jtab[i].size);
  
+       /* Create an import symbol.  */
+       pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
+       imp_sym   = vars.sym_ptr_ptr - 1;
+       imp_index = vars.sym_index - 1;
+     
        /* Create a reloc for the data in the text section.  */
  #ifdef MIPS_ARCH_MAGIC_WINCE      
        if (magic == MIPS_ARCH_MAGIC_WINCE)
  	{
! 	  pe_ILF_make_a_symbol_reloc (& vars, 0, BFD_RELOC_HI16_S,
! 				      (asection **) imp_sym, imp_index);
  	  pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_LO16, text);
! 	  pe_ILF_make_a_symbol_reloc (& vars, 4, BFD_RELOC_LO16,
! 				      (asection **) imp_sym, imp_index);
  	}
        else
  #endif
! 	pe_ILF_make_a_symbol_reloc (& vars, jtab[i].offset, BFD_RELOC_32,
! 				    (asymbol **) imp_sym, imp_index);
        
        pe_ILF_save_relocs (& vars, text);
        break;
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 1013,1025 ****
    /* Now create a symbol describing the imported value.  */
    switch (import_type)
      {
      case IMPORT_CODE:
        pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
  			    BSF_NOT_AT_END | BSF_FUNCTION);
        break;
  
      case IMPORT_DATA:
!       /* XXX not sure if I need to do anythign here.  */
        break;
        
      default:
--- 1042,1065 ----
    /* Now create a symbol describing the imported value.  */
    switch (import_type)
      {
+       bfd_byte * ptr;
+       
      case IMPORT_CODE:
        pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
  			    BSF_NOT_AT_END | BSF_FUNCTION);
+       
+       /* Create an import symbol for the DLL, without the
+        .dll suffix.  */
+       ptr = strrchr (source_dll, '.');
+       if (ptr)
+ 	* ptr = 0;
+       pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
+       if (ptr)
+ 	* ptr = '.';
        break;
  
      case IMPORT_DATA:
!       /* Nothing to do here.  */
        break;
        
      default:
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 1027,1034 ****
        abort ();
      }
  
-   pe_ILF_make_a_symbol (& vars, "_imp__", symbol_name, id5, 0);
-   
    /* Point the bfd at the symbol table.  */
    obj_symbols (abfd) = vars.sym_cache;
    bfd_get_symcount (abfd) = vars.sym_index;
--- 1067,1072 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]