gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / peicode.h
index 05e3363c00d4e313768423b00713fcbed02e1ddc..f7d2b5f5f526762b7e61435193d13395f988175a 100644 (file)
@@ -1,6 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+   Copyright (C) 1995-2020 Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -25,7 +24,7 @@
                        sac@cygnus.com
 
    PE/PEI rearrangement (and code added): Donn Terry
                        sac@cygnus.com
 
    PE/PEI rearrangement (and code added): Donn Terry
-                                       Softway Systems, Inc.  */
+                                      Softway Systems, Inc.  */
 
 /* Hey look, some documentation [and in a place you expect to find it]!
 
 
 /* Hey look, some documentation [and in a place you expect to find it]!
 
@@ -65,7 +64,7 @@ static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
 #undef coff_bfd_print_private_bfd_data
 #endif
 
 #undef coff_bfd_print_private_bfd_data
 #endif
 
-static bfd_boolean                      pe_print_private_bfd_data (bfd *, void *);
+static bfd_boolean                     pe_print_private_bfd_data (bfd *, void *);
 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
 
 static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
 
 static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
@@ -76,10 +75,10 @@ static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
 #undef coff_bfd_copy_private_bfd_data
 #endif
 
 #undef coff_bfd_copy_private_bfd_data
 #endif
 
-static bfd_boolean                     pe_bfd_copy_private_bfd_data (bfd *, bfd *);
+static bfd_boolean                    pe_bfd_copy_private_bfd_data (bfd *, bfd *);
 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
 
 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
 
-#define coff_mkobject      pe_mkobject
+#define coff_mkobject     pe_mkobject
 #define coff_mkobject_hook pe_mkobject_hook
 
 #ifdef COFF_IMAGE_WITH_PE
 #define coff_mkobject_hook pe_mkobject_hook
 
 #ifdef COFF_IMAGE_WITH_PE
@@ -91,17 +90,17 @@ typedef struct
   bfd *                        abfd;
   bfd_byte *           data;
   struct bfd_in_memory * bim;
   bfd *                        abfd;
   bfd_byte *           data;
   struct bfd_in_memory * bim;
-  unsigned short        magic;
+  unsigned short       magic;
 
   arelent *            reltab;
 
   arelent *            reltab;
-  unsigned int                 relcount;
+  unsigned int         relcount;
 
 
-  coff_symbol_type *   sym_cache;
-  coff_symbol_type *   sym_ptr;
-  unsigned int         sym_index;
+  coff_symbol_type *   sym_cache;
+  coff_symbol_type *   sym_ptr;
+  unsigned int         sym_index;
 
 
-  unsigned int *       sym_table;
-  unsigned int *       table_ptr;
+  unsigned int *       sym_table;
+  unsigned int *       table_ptr;
 
   combined_entry_type * native_syms;
   combined_entry_type * native_ptr;
 
   combined_entry_type * native_syms;
   combined_entry_type * native_ptr;
@@ -111,17 +110,20 @@ typedef struct
 
   unsigned int         sec_index;
 
 
   unsigned int         sec_index;
 
-  char *                string_table;
-  char *                string_ptr;
+  char *               string_table;
+  char *               string_ptr;
   char *               end_string_ptr;
 
   char *               end_string_ptr;
 
-  SYMENT *              esym_table;
-  SYMENT *              esym_ptr;
+  SYMENT *             esym_table;
+  SYMENT *             esym_ptr;
 
   struct internal_reloc * int_reltab;
 }
 pe_ILF_vars;
 #endif /* COFF_IMAGE_WITH_PE */
 
   struct internal_reloc * int_reltab;
 }
 pe_ILF_vars;
 #endif /* COFF_IMAGE_WITH_PE */
+
+bfd_cleanup coff_real_object_p
+  (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
 \f
 #ifndef NO_COFF_RELOCS
 static void
 \f
 #ifndef NO_COFF_RELOCS
 static void
@@ -148,7 +150,7 @@ coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
 
   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
 
-#ifdef SWAP_OUT_RELOC_OFFSET 
+#ifdef SWAP_OUT_RELOC_OFFSET
   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
 #endif
 #ifdef SWAP_OUT_RELOC_EXTRA
   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
 #endif
 #ifdef SWAP_OUT_RELOC_EXTRA
@@ -158,6 +160,11 @@ coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
 }
 #endif /* not NO_COFF_RELOCS */
 
 }
 #endif /* not NO_COFF_RELOCS */
 
+#ifdef COFF_IMAGE_WITH_PE
+#undef FILHDR
+#define FILHDR struct external_PEI_IMAGE_hdr
+#endif
+
 static void
 coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
 {
 static void
 coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
 {
@@ -237,7 +244,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
   if (scnhdr_int->s_paddr > 0
       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
           && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
   if (scnhdr_int->s_paddr > 0
       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
           && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
-          || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
+         || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
   /* This code used to set scnhdr_int->s_paddr to 0.  However,
      coff_set_alignment_hook stores s_paddr in virt_size, which
      only works if it correctly holds the virtual size of the
   /* This code used to set scnhdr_int->s_paddr to 0.  However,
      coff_set_alignment_hook stores s_paddr in virt_size, which
      only works if it correctly holds the virtual size of the
@@ -250,7 +257,7 @@ static bfd_boolean
 pe_mkobject (bfd * abfd)
 {
   pe_data_type *pe;
 pe_mkobject (bfd * abfd)
 {
   pe_data_type *pe;
-  bfd_size_type amt = sizeof (pe_data_type);
+  size_t amt = sizeof (pe_data_type);
 
   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
 
 
   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
 
@@ -264,6 +271,25 @@ pe_mkobject (bfd * abfd)
   /* in_reloc_p is architecture dependent.  */
   pe->in_reloc_p = in_reloc_p;
 
   /* in_reloc_p is architecture dependent.  */
   pe->in_reloc_p = in_reloc_p;
 
+  /* Default DOS message string.  */
+  pe->dos_message[0]  = 0x0eba1f0e;
+  pe->dos_message[1]  = 0xcd09b400;
+  pe->dos_message[2]  = 0x4c01b821;
+  pe->dos_message[3]  = 0x685421cd;
+  pe->dos_message[4]  = 0x70207369;
+  pe->dos_message[5]  = 0x72676f72;
+  pe->dos_message[6]  = 0x63206d61;
+  pe->dos_message[7]  = 0x6f6e6e61;
+  pe->dos_message[8]  = 0x65622074;
+  pe->dos_message[9]  = 0x6e757220;
+  pe->dos_message[10] = 0x206e6920;
+  pe->dos_message[11] = 0x20534f44;
+  pe->dos_message[12] = 0x65646f6d;
+  pe->dos_message[13] = 0x0a0d0d2e;
+  pe->dos_message[14] = 0x24;
+  pe->dos_message[15] = 0x0;
+
+  memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -317,6 +343,9 @@ pe_mkobject_hook (bfd * abfd,
     coff_data (abfd) ->flags = 0;
 #endif
 
     coff_data (abfd) ->flags = 0;
 #endif
 
+  memcpy (pe->dos_message, internal_f->pe.dos_message,
+         sizeof (pe->dos_message));
+
   return (void *) pe;
 }
 
   return (void *) pe;
 }
 
@@ -349,7 +378,7 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
       && pe_data (ibfd) != NULL
       && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
       && pe_data (ibfd) != NULL
       && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
-      
+
   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
     return FALSE;
 
   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
     return FALSE;
 
@@ -392,8 +421,8 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
       the table in order to for the string lookup code in coffgen/coffcode to
       work.  */
 #define NUM_ILF_RELOCS         8
       the table in order to for the string lookup code in coffgen/coffcode to
       work.  */
 #define NUM_ILF_RELOCS         8
-#define NUM_ILF_SECTIONS        6
-#define NUM_ILF_SYMS           (2 + NUM_ILF_SECTIONS)
+#define NUM_ILF_SECTIONS       6
+#define NUM_ILF_SYMS           (2 + NUM_ILF_SECTIONS)
 
 #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_SYMS                 (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
 #define SIZEOF_ILF_SYM_TABLE    (NUM_ILF_SYMS * sizeof (* vars.sym_table))
@@ -419,10 +448,9 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
 #define SIZEOF_IDATA6          (2 + strlen (symbol_name) + 1 + 1)
 #define SIZEOF_IDATA7          (strlen (source_dll) + 1 + 1)
 
 #define SIZEOF_IDATA6          (2 + strlen (symbol_name) + 1 + 1)
 #define SIZEOF_IDATA7          (strlen (source_dll) + 1 + 1)
-#define SIZEOF_ILF_SECTIONS     (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
+#define SIZEOF_ILF_SECTIONS    (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
 
 #define ILF_DATA_SIZE                          \
 
 #define ILF_DATA_SIZE                          \
-      sizeof (* vars.bim)                      \
     + SIZEOF_ILF_SYMS                          \
     + SIZEOF_ILF_SYM_TABLE                     \
     + SIZEOF_ILF_NATIVE_SYMS                   \
     + SIZEOF_ILF_SYMS                          \
     + SIZEOF_ILF_SYM_TABLE                     \
     + SIZEOF_ILF_NATIVE_SYMS                   \
@@ -442,11 +470,11 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 /* Create an empty relocation against the given symbol.  */
 
 static void
 /* 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 bfd_symbol **        sym,
-                           unsigned int                sym_index)
+pe_ILF_make_a_symbol_reloc (pe_ILF_vars *              vars,
+                           bfd_vma                     address,
+                           bfd_reloc_code_real_type    reloc,
+                           struct bfd_symbol **        sym,
+                           unsigned int                sym_index)
 {
   arelent * entry;
   struct internal_reloc * internal;
 {
   arelent * entry;
   struct internal_reloc * internal;
@@ -471,10 +499,10 @@ pe_ILF_make_a_symbol_reloc (pe_ILF_vars *               vars,
 /* Create an empty relocation against the given section.  */
 
 static void
 /* Create an empty relocation against the given section.  */
 
 static void
-pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
-                    bfd_vma                   address,
+pe_ILF_make_a_reloc (pe_ILF_vars *            vars,
+                    bfd_vma                   address,
                     bfd_reloc_code_real_type  reloc,
                     bfd_reloc_code_real_type  reloc,
-                    asection_ptr              sec)
+                    asection_ptr              sec)
 {
   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
                              coff_section_data (vars->abfd, sec)->i);
 {
   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
                              coff_section_data (vars->abfd, sec)->i);
@@ -546,7 +574,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
 
   if (section == NULL)
   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
 
   if (section == NULL)
-    section = (asection_ptr) & bfd_und_section;
+    section = bfd_und_section_ptr;
 
   /* Initialise the external symbol.  */
   H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
 
   /* Initialise the external symbol.  */
   H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
@@ -558,15 +586,16 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
      zero initialised.  They are just kept here as reminders.  */
 
   /* Initialise the internal symbol structure.  */
      zero initialised.  They are just kept here as reminders.  */
 
   /* Initialise the internal symbol structure.  */
-  ent->u.syment.n_sclass          = sclass;
-  ent->u.syment.n_scnum           = section->target_index;
+  ent->u.syment.n_sclass         = sclass;
+  ent->u.syment.n_scnum                  = section->target_index;
   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
+  ent->is_sym = TRUE;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
   sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
   sym->symbol.section = section;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
   sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
   sym->symbol.section = section;
-  sym->native         = ent;
+  sym->native        = ent;
 
   * vars->table_ptr = vars->sym_index;
   * vars->sym_ptr_ptr = sym;
 
   * vars->table_ptr = vars->sym_index;
   * vars->sym_ptr_ptr = sym;
@@ -593,6 +622,7 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
 {
   asection_ptr sec;
   flagword     flags;
 {
   asection_ptr sec;
   flagword     flags;
+  intptr_t alignment;
 
   sec = bfd_make_section_old_way (vars->abfd, name);
   if (sec == NULL)
 
   sec = bfd_make_section_old_way (vars->abfd, name);
   if (sec == NULL)
@@ -600,16 +630,16 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
 
   flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
 
 
   flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
 
-  bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
+  bfd_set_section_flags (sec, flags | extra_flags);
 
 
-  bfd_set_section_alignment (vars->abfd, sec, 2);
+  bfd_set_section_alignment (sec, 2);
 
   /* Check that we will not run out of space.  */
   BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
 
   /* Set the section size and contents.  The actual
      contents are filled in by our parent.  */
 
   /* Check that we will not run out of space.  */
   BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
 
   /* Set the section size and contents.  The actual
      contents are filled in by our parent.  */
-  bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
+  bfd_set_section_size (sec, (bfd_size_type) size);
   sec->contents = vars->data;
   sec->target_index = vars->sec_index ++;
 
   sec->contents = vars->data;
   sec->target_index = vars->sec_index ++;
 
@@ -623,6 +653,18 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
   if (size & 1)
     vars->data --;
 
   if (size & 1)
     vars->data --;
 
+  /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
+     preserve host alignment requirements.  The BFD_ASSERTs in this
+     functions will warn us if we run out of room, but we should
+     already have enough padding built in to ILF_DATA_SIZE.  */
+#if GCC_VERSION >= 3000
+  alignment = __alignof__ (struct coff_section_tdata);
+#else
+  alignment = 8;
+#endif
+  vars->data
+    = (bfd_byte *) (((intptr_t) vars->data + alignment - 1) & -alignment);
+
   /* Create a coff_section_tdata structure for our use.  */
   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
   vars->data += sizeof (struct coff_section_tdata);
   /* Create a coff_section_tdata structure for our use.  */
   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
   vars->data += sizeof (struct coff_section_tdata);
@@ -721,21 +763,22 @@ static jump_table jtab[] =
 /* Build a full BFD from the information supplied in a ILF object.  */
 
 static bfd_boolean
 /* Build a full BFD from the information supplied in a ILF object.  */
 
 static bfd_boolean
-pe_ILF_build_a_bfd (bfd *           abfd,
+pe_ILF_build_a_bfd (bfd *          abfd,
                    unsigned int    magic,
                    unsigned int    magic,
-                   char *          symbol_name,
-                   char *          source_dll,
+                   char *          symbol_name,
+                   char *          source_dll,
                    unsigned int    ordinal,
                    unsigned int    types)
 {
                    unsigned int    ordinal,
                    unsigned int    types)
 {
-  bfd_byte *               ptr;
-  pe_ILF_vars              vars;
+  bfd_byte *              ptr;
+  pe_ILF_vars             vars;
   struct internal_filehdr  internal_f;
   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;
+  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;
+  intptr_t alignment;
 
   /* Decode and verify the types field of the ILF structure.  */
   import_type = types & 0x3;
 
   /* Decode and verify the types field of the ILF structure.  */
   import_type = types & 0x3;
@@ -749,12 +792,14 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
     case IMPORT_CONST:
       /* XXX code yet to be written.  */
 
     case IMPORT_CONST:
       /* XXX code yet to be written.  */
-      _bfd_error_handler (_("%B: Unhandled import type; %x"),
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unhandled import type; %x"),
                          abfd, import_type);
       return FALSE;
 
     default:
                          abfd, import_type);
       return FALSE;
 
     default:
-      _bfd_error_handler (_("%B: Unrecognised import type; %x"),
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unrecognized import type; %x"),
                          abfd, import_type);
       return FALSE;
     }
                          abfd, import_type);
       return FALSE;
     }
@@ -768,7 +813,8 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       break;
 
     default:
       break;
 
     default:
-      _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
                          abfd, import_name_type);
       return FALSE;
     }
                          abfd, import_name_type);
       return FALSE;
     }
@@ -780,15 +826,16 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
      We are going to construct the contents of the BFD in memory,
      so allocate all the space that we will need right now.  */
 
      We are going to construct the contents of the BFD in memory,
      so allocate all the space that we will need right now.  */
-  ptr = bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE);
-  if (ptr == NULL)
+  vars.bim
+    = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
+  if (vars.bim == NULL)
     return FALSE;
 
     return FALSE;
 
-  /* Create a bfd_in_memory structure.  */
-  vars.bim = (struct bfd_in_memory *) ptr;
+  ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
   vars.bim->buffer = ptr;
   vars.bim->size   = ILF_DATA_SIZE;
   vars.bim->buffer = ptr;
   vars.bim->size   = ILF_DATA_SIZE;
-  ptr += sizeof (* vars.bim);
+  if (ptr == NULL)
+    goto error_return;
 
   /* Initialise the pointers to regions of the memory and the
      other contents of the pe_ILF_vars structure as well.  */
 
   /* Initialise the pointers to regions of the memory and the
      other contents of the pe_ILF_vars structure as well.  */
@@ -827,6 +874,18 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
   /* The remaining space in bim->buffer is used
      by the pe_ILF_make_a_section() function.  */
 
   /* The remaining space in bim->buffer is used
      by the pe_ILF_make_a_section() function.  */
+
+  /* PR 18758: Make sure that the data area is sufficiently aligned for
+     struct coff_section_tdata.  __alignof__ is a gcc extension, hence
+     the test of GCC_VERSION.  For other compilers we assume 8 byte
+     alignment.  */
+#if GCC_VERSION >= 3000
+  alignment = __alignof__ (struct coff_section_tdata);
+#else
+  alignment = 8;
+#endif
+  ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
+
   vars.data = ptr;
   vars.abfd = abfd;
   vars.sec_index = 0;
   vars.data = ptr;
   vars.abfd = abfd;
   vars.sec_index = 0;
@@ -842,14 +901,14 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   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)
   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;
+    goto error_return;
 
   /* Fill in the contents of these sections.  */
   if (import_name_type == IMPORT_ORDINAL)
     {
       if (ordinal == 0)
 
   /* Fill in the contents of these sections.  */
   if (import_name_type == IMPORT_ORDINAL)
     {
       if (ordinal == 0)
-       /* XXX - treat as IMPORT_NAME ??? */
-       abort ();
+       /* See PR 20907 for a reproducer.  */
+       goto error_return;
 
 #ifdef COFF_WITH_pex64
       ((unsigned int *) id4->contents)[0] = ordinal;
 
 #ifdef COFF_WITH_pex64
       ((unsigned int *) id4->contents)[0] = ordinal;
@@ -869,7 +928,7 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       /* Create .idata$6 - the Hint Name Table.  */
       id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
       if (id6 == NULL)
       /* Create .idata$6 - the Hint Name Table.  */
       id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
       if (id6 == NULL)
-       return FALSE;
+       goto error_return;
 
       /* If necessary, trim the import symbol name.  */
       symbol = symbol_name;
 
       /* If necessary, trim the import symbol name.  */
       symbol = symbol_name;
@@ -884,10 +943,14 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       if (import_name_type != IMPORT_NAME)
        {
          char c = symbol[0];
       if (import_name_type != IMPORT_NAME)
        {
          char c = symbol[0];
-         if (c == '_' || c == '@' || c == '?')
+
+         /* Check that we don't remove for targets with empty
+            USER_LABEL_PREFIX the leading underscore.  */
+         if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
+             || c == '@' || c == '?')
            symbol++;
        }
            symbol++;
        }
-      
+
       len = strlen (symbol);
       if (import_name_type == IMPORT_NAME_UNDECORATE)
        {
       len = strlen (symbol);
       if (import_name_type == IMPORT_NAME_UNDECORATE)
        {
@@ -914,13 +977,19 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       pe_ILF_save_relocs (&vars, id5);
     }
 
       pe_ILF_save_relocs (&vars, id5);
     }
 
+  /* 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 extra sections depending upon the type of import we are dealing with.  */
   switch (import_type)
     {
       int i;
 
     case IMPORT_CODE:
   /* Create extra sections depending upon the type of import we are dealing with.  */
   switch (import_type)
     {
       int i;
 
     case IMPORT_CODE:
-      /* Create a .text section.
+      /* CODE functions are special, in that they get a trampoline that
+        jumps to the main import symbol.  Create a .text section to hold it.
         First we need to look up its contents in the jump table.  */
       for (i = NUM_ENTRIES (jtab); i--;)
        {
         First we need to look up its contents in the jump table.  */
       for (i = NUM_ENTRIES (jtab); i--;)
        {
@@ -936,16 +1005,11 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       /* Create the .text section.  */
       text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
       if (text == NULL)
       /* Create the .text section.  */
       text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
       if (text == NULL)
-       return FALSE;
+       goto error_return;
 
       /* Copy in the jump code.  */
       memcpy (text->contents, jtab[i].data, jtab[i].size);
 
 
       /* 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)
       /* Create a reloc for the data in the text section.  */
 #ifdef MIPS_ARCH_MAGIC_WINCE
       if (magic == MIPS_ARCH_MAGIC_WINCE)
@@ -959,6 +1023,15 @@ pe_ILF_build_a_bfd (bfd *           abfd,
                                      imp_index);
        }
       else
                                      imp_index);
        }
       else
+#endif
+#ifdef AMD64MAGIC
+      if (magic == AMD64MAGIC)
+       {
+         pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
+                                     BFD_RELOC_32_PCREL, (asymbol **) imp_sym,
+                                     imp_index);
+       }
+      else
 #endif
        pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
                                    BFD_RELOC_32, (asymbol **) imp_sym,
 #endif
        pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
                                    BFD_RELOC_32, (asymbol **) imp_sym,
@@ -985,10 +1058,10 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
   if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
       || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
 
   if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
       || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
-    return FALSE;
+    goto error_return;
 
   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
 
   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
-    return FALSE;
+    goto error_return;
 
   coff_data (abfd)->pe = 1;
 #ifdef THUMBPEMAGIC
 
   coff_data (abfd)->pe = 1;
 #ifdef THUMBPEMAGIC
@@ -1002,7 +1075,9 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
   abfd->iostream = (void *) vars.bim;
   abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
 
   abfd->iostream = (void *) vars.bim;
   abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
+  abfd->iovec = &_bfd_memory_iovec;
   abfd->where = 0;
   abfd->where = 0;
+  abfd->origin = 0;
   obj_sym_filepos (abfd) = 0;
 
   /* Now create a symbol describing the imported value.  */
   obj_sym_filepos (abfd) = 0;
 
   /* Now create a symbol describing the imported value.  */
@@ -1012,14 +1087,6 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
                            BSF_NOT_AT_END | BSF_FUNCTION);
 
       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 = (bfd_byte *) 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:
       break;
 
     case IMPORT_DATA:
@@ -1031,9 +1098,17 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       abort ();
     }
 
       abort ();
     }
 
+  /* Create an import symbol for the DLL, without the .dll suffix.  */
+  ptr = (bfd_byte *) strrchr (source_dll, '.');
+  if (ptr)
+    * ptr = 0;
+  pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
+  if (ptr)
+    * ptr = '.';
+
   /* Point the bfd at the symbol table.  */
   obj_symbols (abfd) = vars.sym_cache;
   /* Point the bfd at the symbol table.  */
   obj_symbols (abfd) = vars.sym_cache;
-  bfd_get_symcount (abfd) = vars.sym_index;
+  abfd->symcount = vars.sym_index;
 
   obj_raw_syments (abfd) = vars.native_syms;
   obj_raw_syment_count (abfd) = vars.sym_index;
 
   obj_raw_syments (abfd) = vars.native_syms;
   obj_raw_syment_count (abfd) = vars.sym_index;
@@ -1050,35 +1125,36 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   abfd->flags |= HAS_SYMS;
 
   return TRUE;
   abfd->flags |= HAS_SYMS;
 
   return TRUE;
+
+ error_return:
+  free (vars.bim->buffer);
+  free (vars.bim);
+  return FALSE;
 }
 
 /* We have detected a Image Library Format archive element.
    Decode the element and return the appropriate target.  */
 
 }
 
 /* We have detected a Image Library Format archive element.
    Decode the element and return the appropriate target.  */
 
-static const bfd_target *
+static bfd_cleanup
 pe_ILF_object_p (bfd * abfd)
 {
 pe_ILF_object_p (bfd * abfd)
 {
-  bfd_byte        buffer[16];
-  bfd_byte *      ptr;
-  char *          symbol_name;
-  char *          source_dll;
-  unsigned int    machine;
-  bfd_size_type   size;
-  unsigned int    ordinal;
-  unsigned int    types;
-  unsigned int    magic;
-
-  /* Upon entry the first four buyes of the ILF header have
+  bfd_byte       buffer[14];
+  bfd_byte *     ptr;
+  char *         symbol_name;
+  char *         source_dll;
+  unsigned int   machine;
+  bfd_size_type          size;
+  unsigned int   ordinal;
+  unsigned int   types;
+  unsigned int   magic;
+
+  /* Upon entry the first six bytes of the ILF header have
       already been read.  Now read the rest of the header.  */
       already been read.  Now read the rest of the header.  */
-  if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16)
+  if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
     return NULL;
 
   ptr = buffer;
 
     return NULL;
 
   ptr = buffer;
 
-  /*  We do not bother to check the version number.
-      version = H_GET_16 (abfd, ptr);  */
-  ptr += 2;
-
   machine = H_GET_16 (abfd, ptr);
   ptr += 2;
 
   machine = H_GET_16 (abfd, ptr);
   ptr += 2;
 
@@ -1105,12 +1181,6 @@ pe_ILF_object_p (bfd * abfd)
 #endif
       break;
 
 #endif
       break;
 
-    case IMAGE_FILE_MACHINE_M68K:
-#ifdef MC68AGIC
-      magic = MC68MAGIC;
-#endif
-      break;
-
     case IMAGE_FILE_MACHINE_R3000:
     case IMAGE_FILE_MACHINE_R4000:
     case IMAGE_FILE_MACHINE_R10000:
     case IMAGE_FILE_MACHINE_R3000:
     case IMAGE_FILE_MACHINE_R4000:
     case IMAGE_FILE_MACHINE_R10000:
@@ -1151,7 +1221,8 @@ pe_ILF_object_p (bfd * abfd)
       /* We no longer support PowerPC.  */
     default:
       _bfd_error_handler
       /* We no longer support PowerPC.  */
     default:
       _bfd_error_handler
-       (_("%B: Unrecognised machine type (0x%x)"
+       /* xgettext:c-format */
+       (_("%pB: unrecognised machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_malformed_archive);
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_malformed_archive);
@@ -1163,7 +1234,8 @@ pe_ILF_object_p (bfd * abfd)
   if (magic == 0)
     {
       _bfd_error_handler
   if (magic == 0)
     {
       _bfd_error_handler
-       (_("%B: Recognised but unhandled machine type (0x%x)"
+       /* xgettext:c-format */
+       (_("%pB: recognised but unhandled machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_wrong_format);
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_wrong_format);
@@ -1181,7 +1253,7 @@ pe_ILF_object_p (bfd * abfd)
   if (size == 0)
     {
       _bfd_error_handler
   if (size == 0)
     {
       _bfd_error_handler
-       (_("%B: size field is zero in Import Library Format header"), abfd);
+       (_("%pB: size field is zero in Import Library Format header"), abfd);
       bfd_set_error (bfd_error_malformed_archive);
 
       return NULL;
       bfd_set_error (bfd_error_malformed_archive);
 
       return NULL;
@@ -1194,25 +1266,20 @@ pe_ILF_object_p (bfd * abfd)
   /* ptr += 2; */
 
   /* Now read in the two strings that follow.  */
   /* ptr += 2; */
 
   /* Now read in the two strings that follow.  */
-  ptr = bfd_alloc (abfd, size);
+  ptr = (bfd_byte *) _bfd_alloc_and_read (abfd, size, size);
   if (ptr == NULL)
     return NULL;
 
   if (ptr == NULL)
     return NULL;
 
-  if (bfd_bread (ptr, size, abfd) != size)
-    {
-      bfd_release (abfd, ptr);
-      return NULL;
-    }
-
   symbol_name = (char *) ptr;
   symbol_name = (char *) ptr;
-  source_dll  = symbol_name + strlen (symbol_name) + 1;
+  /* See PR 20905 for an example of where the strnlen is necessary.  */
+  source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
 
   /* Verify that the strings are null terminated.  */
   if (ptr[size - 1] != 0
       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
     {
       _bfd_error_handler
 
   /* Verify that the strings are null terminated.  */
   if (ptr[size - 1] != 0
       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
     {
       _bfd_error_handler
-       (_("%B: string not null terminated in ILF object file."), abfd);
+       (_("%pB: string not null terminated in ILF object file"), abfd);
       bfd_set_error (bfd_error_malformed_archive);
       bfd_release (abfd, ptr);
       return NULL;
       bfd_set_error (bfd_error_malformed_archive);
       bfd_release (abfd, ptr);
       return NULL;
@@ -1226,27 +1293,124 @@ pe_ILF_object_p (bfd * abfd)
       return NULL;
     }
 
       return NULL;
     }
 
-  return abfd->xvec;
+  return _bfd_no_cleanup;
 }
 
 }
 
-static const bfd_target *
+static void
+pe_bfd_read_buildid (bfd *abfd)
+{
+  pe_data_type *pe = pe_data (abfd);
+  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+  asection *section;
+  bfd_byte *data = 0;
+  bfd_size_type dataoff;
+  unsigned int i;
+  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
+  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
+
+  if (size == 0)
+    return;
+
+  addr += extra->ImageBase;
+
+  /* Search for the section containing the DebugDirectory.  */
+  for (section = abfd->sections; section != NULL; section = section->next)
+    {
+      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
+       break;
+    }
+
+  if (section == NULL)
+    return;
+
+  if (!(section->flags & SEC_HAS_CONTENTS))
+    return;
+
+  dataoff = addr - section->vma;
+
+  /* PR 20605 and 22373: Make sure that the data is really there.
+     Note - since we are dealing with unsigned quantities we have
+     to be careful to check for potential overflows.  */
+  if (dataoff >= section->size
+      || size > section->size - dataoff)
+    {
+      _bfd_error_handler
+       (_("%pB: error: debug data ends beyond end of debug directory"),
+        abfd);
+      return;
+    }
+
+  /* Read the whole section. */
+  if (!bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      free (data);
+      return;
+    }
+
+  /* Search for a CodeView entry in the DebugDirectory */
+  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+    {
+      struct external_IMAGE_DEBUG_DIRECTORY *ext
+       = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
+      struct internal_IMAGE_DEBUG_DIRECTORY idd;
+
+      _bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
+
+      if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
+       {
+         char buffer[256 + 1];
+         CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
+
+         /*
+           The debug entry doesn't have to have to be in a section, in which
+           case AddressOfRawData is 0, so always use PointerToRawData.
+         */
+         if (_bfd_XXi_slurp_codeview_record (abfd,
+                                             (file_ptr) idd.PointerToRawData,
+                                             idd.SizeOfData, cvinfo))
+           {
+             struct bfd_build_id* build_id = bfd_alloc (abfd,
+                        sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
+             if (build_id)
+               {
+                 build_id->size = cvinfo->SignatureLength;
+                 memcpy(build_id->data,  cvinfo->Signature,
+                        cvinfo->SignatureLength);
+                 abfd->build_id = build_id;
+               }
+           }
+         break;
+       }
+    }
+
+  free (data);
+}
+
+static bfd_cleanup
 pe_bfd_object_p (bfd * abfd)
 {
 pe_bfd_object_p (bfd * abfd)
 {
-  bfd_byte buffer[4];
-  struct external_PEI_DOS_hdr dos_hdr;
+  bfd_byte buffer[6];
+  struct external_DOS_hdr dos_hdr;
   struct external_PEI_IMAGE_hdr image_hdr;
   struct external_PEI_IMAGE_hdr image_hdr;
+  struct internal_filehdr internal_f;
+  struct internal_aouthdr internal_a;
+  bfd_size_type opt_hdr_size;
   file_ptr offset;
   file_ptr offset;
+  bfd_cleanup result;
 
   /* Detect if this a Microsoft Import Library Format element.  */
 
   /* Detect if this a Microsoft Import Library Format element.  */
+  /* First read the beginning of the header.  */
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
-      || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4)
+      || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6)
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
-  if (H_GET_32 (abfd, buffer) == 0xffff0000)
+  /* Then check the magic and the version (only 0 is supported).  */
+  if (H_GET_32 (abfd, buffer) == 0xffff0000
+      && H_GET_16 (abfd, buffer + 4) == 0)
     return pe_ILF_object_p (abfd);
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
     return pe_ILF_object_p (abfd);
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
@@ -1260,7 +1424,7 @@ pe_bfd_object_p (bfd * abfd)
 
   /* There are really two magic numbers involved; the magic number
      that says this is a NT executable (PEI) and the magic number that
 
   /* There are really two magic numbers involved; the magic number
      that says this is a NT executable (PEI) and the magic number that
-     determines the architecture.  The former is DOSMAGIC, stored in
+     determines the architecture.  The former is IMAGE_DOS_SIGNATURE, stored in
      the e_magic field.  The latter is stored in the f_magic field.
      If the NT magic number isn't valid, the architecture magic number
      could be mimicked by some other field (specifically, the number
      the e_magic field.  The latter is stored in the f_magic field.
      If the NT magic number isn't valid, the architecture magic number
      could be mimicked by some other field (specifically, the number
@@ -1268,7 +1432,7 @@ pe_bfd_object_p (bfd * abfd)
      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.  */
      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 (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
+  if (H_GET_16 (abfd, dos_hdr.e_magic) != IMAGE_DOS_SIGNATURE)
     {
       bfd_set_error (bfd_error_wrong_format);
       return NULL;
     {
       bfd_set_error (bfd_error_wrong_format);
       return NULL;
@@ -1290,17 +1454,58 @@ pe_bfd_object_p (bfd * abfd)
       return NULL;
     }
 
       return NULL;
     }
 
-  /* Here is the hack.  coff_object_p wants to read filhsz bytes to
-     pick up the COFF header for PE, see "struct external_PEI_filehdr"
-     in include/coff/pe.h.  We adjust so that that will work. */
-  if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0)
+  /* Swap file header, so that we get the location for calling
+     real_object_p.  */
+  bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f);
+
+  if (! bfd_coff_bad_format_hook (abfd, &internal_f)
+      || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
     {
     {
-      if (bfd_get_error () != bfd_error_system_call)
-       bfd_set_error (bfd_error_wrong_format);
+      bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
       return NULL;
     }
 
-  return coff_object_p (abfd);
+  memcpy (internal_f.pe.dos_message, dos_hdr.dos_message,
+         sizeof (internal_f.pe.dos_message));
+
+  /* Read the optional header, which has variable size.  */
+  opt_hdr_size = internal_f.f_opthdr;
+
+  if (opt_hdr_size != 0)
+    {
+      bfd_size_type amt = opt_hdr_size;
+      void * opthdr;
+
+      /* PR 17521 file: 230-131433-0.004.  */
+      if (amt < sizeof (PEAOUTHDR))
+       amt = sizeof (PEAOUTHDR);
+
+      opthdr = _bfd_alloc_and_read (abfd, amt, opt_hdr_size);
+      if (opthdr == NULL)
+       return NULL;
+      if (amt > opt_hdr_size)
+       memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
+
+      bfd_set_error (bfd_error_no_error);
+      bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
+      if (bfd_get_error () != bfd_error_no_error)
+       return NULL;
+    }
+
+
+  result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
+                              (opt_hdr_size != 0
+                               ? &internal_a
+                               : (struct internal_aouthdr *) NULL));
+
+
+  if (result)
+    {
+      /* Now the whole header has been processed, see if there is a build-id */
+      pe_bfd_read_buildid(abfd);
+    }
+
+  return result;
 }
 
 #define coff_object_p pe_bfd_object_p
 }
 
 #define coff_object_p pe_bfd_object_p
This page took 0.037864 seconds and 4 git commands to generate.