Restore GET_SAVED_REGISTERS
[deliverable/binutils-gdb.git] / bfd / peicode.h
index b94d0f8449767a589da0e8e8b7a3bbc7eb8bdd4a..9071c72b29e9668ad5e443f43c55a733851bc0b2 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -69,7 +69,6 @@ static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
 static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));
 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
 
-
 static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
     PARAMS ((bfd *, bfd *)) =
 #ifndef coff_bfd_copy_private_bfd_data
@@ -114,10 +113,13 @@ typedef struct
   
   unsigned int *       sym_table;
   unsigned int *       table_ptr;
-
+  
   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;
@@ -135,9 +137,10 @@ static asection_ptr       pe_ILF_make_a_section   PARAMS ((pe_ILF_vars *, const
 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 *));
+static const bfd_target * pe_bfd_object_p        PARAMS ((bfd *));
 #endif /* COFF_IMAGE_WITH_PE */
 
 /**********************************************************************/
@@ -217,8 +220,13 @@ coff_swap_filehdr_in (abfd, src, dst)
      correctly for a PEI file, check the e_magic number here, and, if
      it doesn't match, clobber the f_magic number so that we don't get
      a false match.  */
+#if 0
+  /* We can't assume that the PE header is at offset 0x80.  When it
+     isn't, the DOS header isn't read correctly, so we can't assume
+     e_magic is set even for valid PE files. */
   if (bfd_h_get_16 (abfd, (bfd_byte *) filehdr_src->e_magic) != DOSMAGIC)
     filehdr_dst->f_magic = -1;
+#endif
 #endif
 
   /* Other people's tools sometimes generate headers with an nsyms but
@@ -239,7 +247,6 @@ coff_swap_filehdr_in (abfd, src, dst)
 #define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
 #endif
 
-
 static void
 coff_swap_scnhdr_in (abfd, ext, in)
      bfd            *abfd;
@@ -431,11 +438,11 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd)
    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).
+      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.
+      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
@@ -447,10 +454,14 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd)
 #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 + NUM_ILF_SECTIONS * 9 + STRING_SIZE_SIZE)
+#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)
@@ -463,6 +474,7 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd)
     + 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                    \
@@ -478,10 +490,11 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd)
 
 /* 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)
+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;
@@ -492,10 +505,10 @@ pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
   entry->address     = address;
   entry->addend      = 0;
   entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
-  entry->sym_ptr_ptr = sec->symbol_ptr_ptr;
+  entry->sym_ptr_ptr = sym;
 
   internal->r_vaddr  = address;
-  internal->r_symndx = coff_section_data (vars->abfd, sec)->i;
+  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;
@@ -508,6 +521,17 @@ pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
   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,
@@ -546,7 +570,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   unsigned short sclass;
 
   if (extra_flags & BSF_LOCAL)
-    sclass = C_LABEL;
+    sclass = C_STAT;
   else
     sclass = C_EXT;
   
@@ -556,7 +580,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
       if (extra_flags & BSF_FUNCTION)
        sclass = C_THUMBEXTFUNC;
       else if (extra_flags & BSF_LOCAL)
-       sclass = C_THUMBLABEL;
+       sclass = C_THUMBSTAT;
       else
        sclass = C_THUMBEXT;
     }
@@ -571,6 +595,9 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   /* Copy the symbol's name into the string table.  */
   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
 
+  if (section == NULL)
+    section = (asection_ptr) & bfd_und_section;
+  
   /* Initialise the external symbol.  */
   bfd_h_put_32 (vars->abfd, vars->string_ptr - vars->string_table, (bfd_byte *) esym->e.e.e_offset);
   bfd_h_put_16 (vars->abfd, section->target_index, (bfd_byte *) esym->e_scnum);
@@ -612,14 +639,16 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
 #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) + 1;
+  vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
 
   BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
 }
@@ -672,7 +701,7 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
   /* 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.  */
+  /* 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;
@@ -697,7 +726,7 @@ typedef struct
 }
 jump_table;
 
-jump_table jtab[] =
+static jump_table jtab[] =
 {
 #ifdef I386MAGIC
   { I386MAGIC,
@@ -761,10 +790,10 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   struct internal_filehdr  internal_f;
   unsigned int             import_type;
   unsigned int             import_name_type;
-  asection_ptr             id2, id4, id5, id6, id7, text;
+  asection_ptr             id4, id5, id6 = NULL, text = NULL;
+  coff_symbol_type **      imp_sym;
+  unsigned int             imp_index;
 
-  text = NULL;
-  
   /* Decode and verify the types field of the ILF structure.  */
   import_type = types & 0x3;
   import_name_type = (types & 0x1c) >> 2;
@@ -832,6 +861,10 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   vars.native_syms = (combined_entry_type *) ptr;
   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;
@@ -857,16 +890,15 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   vars.magic = magic;
   
   /* Create the initial .idata$<n> sections:
-     .idata$2:  Import Directory Table
+     [.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.  */
-  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)
+  if (id4 == NULL || id5 == NULL)
     return false;
   
   /* Fill in the contents of these sections.  */
@@ -905,22 +937,12 @@ pe_ILF_build_a_bfd (bfd *           abfd,
          * symbol = 0;
        }
       
-      strcpy (id6->contents, symbol);
+      id6->contents[0] = ordinal & 0xff;
+      id6->contents[1] = ordinal >> 8;
+      
+      strcpy (id6->contents + 2, 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)
     {
       pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_RVA, id6);
@@ -957,17 +979,25 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       /* 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_reloc (& vars, 0, BFD_RELOC_HI16_S, id5);
+         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_reloc (& vars, 4, BFD_RELOC_LO16, id5);
+         pe_ILF_make_a_symbol_reloc (& vars, 4, BFD_RELOC_LO16,
+                                     (asection **) imp_sym, imp_index);
        }
       else
 #endif
-       pe_ILF_make_a_reloc (& vars, jtab[i].offset, BFD_RELOC_32, id5);
+       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;
@@ -1013,13 +1043,24 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   /* 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:
-      /* XXX not sure if I need to do anythign here.  */
+      /* Nothing to do here.  */
       break;
       
     default:
@@ -1027,8 +1068,6 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       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;
@@ -1130,9 +1169,9 @@ pe_ILF_object_p (bfd * abfd)
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
-       extern bfd_target armpei_little_vec;
+       extern bfd_target TARGET_LITTLE_SYM;
        
-       if (abfd->xvec == & armpei_little_vec)
+       if (abfd->xvec == & TARGET_LITTLE_SYM)
          magic = THUMBPEMAGIC;
       }
 #endif      
@@ -1197,7 +1236,7 @@ _("%s: Recognised but unhandled machine type (0x%x) in Import Library Format arc
   source_dll  = ptr + strlen (ptr) + 1;
   
   /* Verify that the strings are null terminated.  */
-  if (ptr[size - 1] != 0 || ((source_dll - ptr) >= size))
+  if (ptr[size - 1] != 0 || ((unsigned long) (source_dll - ptr) >= size))
     {
       _bfd_error_handler
        (_("%s: string not null terminated in ILF object file."),
This page took 0.046161 seconds and 4 git commands to generate.