LoongArch: Fix LD check fails.
[binutils-gdb.git] / bfd / peicode.h
index 2a564fec984e13797c560c144d1d3432a98fb19d..0346bc2174ec37d31b1872a7a1e7ee864700d71f 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright (C) 1995-2019 Free Software Foundation, Inc.
+   Copyright (C) 1995-2022 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.
@@ -56,7 +56,7 @@
 
 #include "libpei.h"
 
 
 #include "libpei.h"
 
-static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
+static bool (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
 #ifndef coff_bfd_print_private_bfd_data
      NULL;
 #else
 #ifndef coff_bfd_print_private_bfd_data
      NULL;
 #else
@@ -64,10 +64,10 @@ 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 bool pe_print_private_bfd_data (bfd *, void *);
 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
 
 #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 *) =
+static bool (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
 #ifndef coff_bfd_copy_private_bfd_data
      NULL;
 #else
 #ifndef coff_bfd_copy_private_bfd_data
      NULL;
 #else
@@ -75,7 +75,7 @@ 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 bool pe_bfd_copy_private_bfd_data (bfd *, bfd *);
 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
 
 #define coff_mkobject     pe_mkobject
 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
 
 #define coff_mkobject     pe_mkobject
@@ -122,7 +122,7 @@ typedef struct
 pe_ILF_vars;
 #endif /* COFF_IMAGE_WITH_PE */
 
 pe_ILF_vars;
 #endif /* COFF_IMAGE_WITH_PE */
 
-const bfd_target *coff_real_object_p
+bfd_cleanup coff_real_object_p
   (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
 \f
 #ifndef NO_COFF_RELOCS
   (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
 \f
 #ifndef NO_COFF_RELOCS
@@ -231,7 +231,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }
@@ -253,16 +253,16 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
 #endif
 }
 
 #endif
 }
 
-static bfd_boolean
+static bool
 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);
 
   if (abfd->tdata.pe_obj_data == 0)
 
   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
 
   if (abfd->tdata.pe_obj_data == 0)
-    return FALSE;
+    return false;
 
   pe = pe_data (abfd);
 
 
   pe = pe_data (abfd);
 
@@ -271,8 +271,26 @@ 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);
   memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
-  return TRUE;
+  return true;
 }
 
 /* Create the COFF backend specific information.  */
 }
 
 /* Create the COFF backend specific information.  */
@@ -325,19 +343,22 @@ 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;
 }
 
-static bfd_boolean
+static bool
 pe_print_private_bfd_data (bfd *abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
 
   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
 pe_print_private_bfd_data (bfd *abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
 
   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
-    return FALSE;
+    return false;
 
   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
 
   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
-    return TRUE;
+    return true;
 
   fputc ('\n', file);
 
 
   fputc ('\n', file);
 
@@ -347,7 +368,7 @@ pe_print_private_bfd_data (bfd *abfd, void * vfile)
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
-static bfd_boolean
+static bool
 pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   /* PR binutils/716: Copy the large address aware flag.
 pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   /* PR binutils/716: Copy the large address aware flag.
@@ -359,12 +380,12 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
 
   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
 
   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
-    return FALSE;
+    return false;
 
   if (pe_saved_coff_bfd_copy_private_bfd_data)
     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
 
 
   if (pe_saved_coff_bfd_copy_private_bfd_data)
     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
 
-  return TRUE;
+  return true;
 }
 
 #define coff_bfd_copy_private_section_data \
 }
 
 #define coff_bfd_copy_private_section_data \
@@ -468,7 +489,7 @@ pe_ILF_make_a_symbol_reloc (pe_ILF_vars *           vars,
 
   internal->r_vaddr  = address;
   internal->r_symndx = sym_index;
 
   internal->r_vaddr  = address;
   internal->r_symndx = sym_index;
-  internal->r_type   = entry->howto->type;
+  internal->r_type   = entry->howto ? entry->howto->type : 0;
 
   vars->relcount ++;
 
 
   vars->relcount ++;
 
@@ -499,7 +520,7 @@ pe_ILF_save_relocs (pe_ILF_vars * vars,
     abort ();
 
   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
     abort ();
 
   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
-  coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
+  coff_section_data (vars->abfd, sec)->keep_relocs = true;
 
   sec->relocation  = vars->reltab;
   sec->reloc_count = vars->relcount;
 
   sec->relocation  = vars->reltab;
   sec->reloc_count = vars->relcount;
@@ -568,7 +589,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   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_sclass         = sclass;
   ent->u.syment.n_scnum                  = section->target_index;
   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
-  ent->is_sym = TRUE;
+  ent->is_sym = true;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
@@ -601,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)
@@ -608,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);
 
 
-  (void) 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 ++;
 
@@ -631,20 +653,18 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
   if (size & 1)
     vars->data --;
 
   if (size & 1)
     vars->data --;
 
-# if (GCC_VERSION >= 3000)
   /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
   /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
-     preserve host alignment requirements.  We test 'size' rather than
-     vars.data as we cannot perform binary arithmetic on pointers.  We assume
-     that vars.data was sufficiently aligned upon entry to this function.
-     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.  */
-  {
-    unsigned int alignment = __alignof__ (struct coff_section_tdata);
-
-    if (size & (alignment - 1))
-      vars->data += alignment - (size & (alignment - 1));
-  }
+     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
 #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);
@@ -679,7 +699,7 @@ typedef struct
 }
 jump_table;
 
 }
 jump_table;
 
-static jump_table jtab[] =
+static const jump_table jtab[] =
 {
 #ifdef I386MAGIC
   { I386MAGIC,
 {
 #ifdef I386MAGIC
   { I386MAGIC,
@@ -718,6 +738,16 @@ static jump_table jtab[] =
   },
 #endif
 
   },
 #endif
 
+#ifdef AARCH64MAGIC
+/* We don't currently support jumping to DLLs, so if
+   someone does try emit a runtime trap.  Through UDF #0.  */
+  { AARCH64MAGIC,
+    { 0x00, 0x00, 0x00, 0x00 },
+    4, 0
+  },
+
+#endif
+
 #ifdef  ARMPEMAGIC
   { ARMPEMAGIC,
     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
 #ifdef  ARMPEMAGIC
   { ARMPEMAGIC,
     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
@@ -742,7 +772,7 @@ static jump_table jtab[] =
 
 /* Build a full BFD from the information supplied in a ILF object.  */
 
 
 /* Build a full BFD from the information supplied in a ILF object.  */
 
-static bfd_boolean
+static bool
 pe_ILF_build_a_bfd (bfd *          abfd,
                    unsigned int    magic,
                    char *          symbol_name,
 pe_ILF_build_a_bfd (bfd *          abfd,
                    unsigned int    magic,
                    char *          symbol_name,
@@ -758,6 +788,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
   asection_ptr            id4, id5, id6 = NULL, text = NULL;
   coff_symbol_type **     imp_sym;
   unsigned int            imp_index;
   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;
@@ -774,13 +805,13 @@ pe_ILF_build_a_bfd (bfd *     abfd,
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unhandled import type; %x"),
                          abfd, import_type);
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unhandled import type; %x"),
                          abfd, import_type);
-      return FALSE;
+      return false;
 
     default:
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import type; %x"),
                          abfd, import_type);
 
     default:
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import type; %x"),
                          abfd, import_type);
-      return FALSE;
+      return false;
     }
 
   switch (import_name_type)
     }
 
   switch (import_name_type)
@@ -795,7 +826,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
                          abfd, import_name_type);
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
                          abfd, import_name_type);
-      return FALSE;
+      return false;
     }
 
   /* Initialise local variables.
     }
 
   /* Initialise local variables.
@@ -808,7 +839,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
   vars.bim
     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
   if (vars.bim == NULL)
   vars.bim
     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
   if (vars.bim == NULL)
-    return FALSE;
+    return false;
 
   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
   vars.bim->buffer = ptr;
 
   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
   vars.bim->buffer = ptr;
@@ -853,23 +884,17 @@ 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.  */
-# if (GCC_VERSION >= 3000)
+
   /* PR 18758: Make sure that the data area is sufficiently aligned for
   /* PR 18758: Make sure that the data area is sufficiently aligned for
-     pointers on the host.  __alignof__ is a gcc extension, hence the test
-     above.  For other compilers we will have to assume that the alignment is
-     unimportant, or else extra code can be added here and in
-     pe_ILF_make_a_section.
-
-     Note - we cannot test 'ptr' directly as it is illegal to perform binary
-     arithmetic on pointers, but we know that the strings section is the only
-     one that might end on an unaligned boundary.  */
-  {
-    unsigned int alignment = __alignof__ (char *);
-
-    if (SIZEOF_ILF_STRINGS & (alignment - 1))
-      ptr += alignment - (SIZEOF_ILF_STRINGS & (alignment - 1));
-  }
+     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
 #endif
+  ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
 
   vars.data = ptr;
   vars.abfd = abfd;
 
   vars.data = ptr;
   vars.abfd = abfd;
@@ -895,7 +920,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
        /* See PR 20907 for a reproducer.  */
        goto error_return;
 
        /* See PR 20907 for a reproducer.  */
        goto error_return;
 
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       ((unsigned int *) id4->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[1] = 0x80000000;
       ((unsigned int *) id5->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[1] = 0x80000000;
       ((unsigned int *) id5->contents)[0] = ordinal;
@@ -1093,35 +1118,34 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
   /* 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_coff_external_syms (abfd) = (void *) vars.esym_table;
 
   obj_raw_syments (abfd) = vars.native_syms;
   obj_raw_syment_count (abfd) = vars.sym_index;
 
   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
-  obj_coff_keep_syms (abfd) = TRUE;
+  obj_coff_keep_syms (abfd) = true;
 
   obj_convert (abfd) = vars.sym_table;
   obj_conv_table_size (abfd) = vars.sym_index;
 
   obj_coff_strings (abfd) = vars.string_table;
 
   obj_convert (abfd) = vars.sym_table;
   obj_conv_table_size (abfd) = vars.sym_index;
 
   obj_coff_strings (abfd) = vars.string_table;
-  obj_coff_keep_strings (abfd) = TRUE;
+  obj_coff_keep_strings (abfd) = true;
 
   abfd->flags |= HAS_SYMS;
 
 
   abfd->flags |= HAS_SYMS;
 
-  return TRUE;
+  return true;
 
  error_return:
 
  error_return:
-  if (vars.bim->buffer != NULL)
-    free (vars.bim->buffer);
+  free (vars.bim->buffer);
   free (vars.bim);
   free (vars.bim);
-  return FALSE;
+  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)
 {
   bfd_byte       buffer[14];
 pe_ILF_object_p (bfd * abfd)
 {
   bfd_byte       buffer[14];
@@ -1192,6 +1216,12 @@ pe_ILF_object_p (bfd * abfd)
 #endif
       break;
 
 #endif
       break;
 
+    case IMAGE_FILE_MACHINE_ARM64:
+#ifdef AARCH64MAGIC
+      magic = AARCH64MAGIC;
+#endif
+      break;
+
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
@@ -1252,16 +1282,10 @@ 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_byte *) 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;
   /* See PR 20905 for an example of where the strnlen is necessary.  */
   source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
   symbol_name = (char *) ptr;
   /* See PR 20905 for an example of where the strnlen is necessary.  */
   source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
@@ -1285,7 +1309,7 @@ pe_ILF_object_p (bfd * abfd)
       return NULL;
     }
 
       return NULL;
     }
 
-  return abfd->xvec;
+  return _bfd_no_cleanup;
 }
 
 static void
 }
 
 static void
@@ -1335,8 +1359,7 @@ pe_bfd_read_buildid (bfd *abfd)
   /* Read the whole section. */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
   /* Read the whole section. */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return;
     }
 
       return;
     }
 
@@ -1375,9 +1398,11 @@ pe_bfd_read_buildid (bfd *abfd)
          break;
        }
     }
          break;
        }
     }
+
+  free (data);
 }
 
 }
 
-static const bfd_target *
+static bfd_cleanup
 pe_bfd_object_p (bfd * abfd)
 {
   bfd_byte buffer[6];
 pe_bfd_object_p (bfd * abfd)
 {
   bfd_byte buffer[6];
@@ -1385,9 +1410,9 @@ pe_bfd_object_p (bfd * abfd)
   struct external_PEI_IMAGE_hdr image_hdr;
   struct internal_filehdr internal_f;
   struct internal_aouthdr internal_a;
   struct external_PEI_IMAGE_hdr image_hdr;
   struct internal_filehdr internal_f;
   struct internal_aouthdr internal_a;
-  file_ptr opt_hdr_size;
+  bfd_size_type opt_hdr_size;
   file_ptr offset;
   file_ptr offset;
-  const bfd_target *result;
+  bfd_cleanup result;
 
   /* Detect if this a Microsoft Import Library Format element.  */
   /* First read the beginning of the header.  */
 
   /* Detect if this a Microsoft Import Library Format element.  */
   /* First read the beginning of the header.  */
@@ -1456,24 +1481,26 @@ pe_bfd_object_p (bfd * abfd)
       return NULL;
     }
 
       return NULL;
     }
 
+  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;
   /* 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;
+      bfd_byte * opthdr;
 
       /* PR 17521 file: 230-131433-0.004.  */
       if (amt < sizeof (PEAOUTHDR))
        amt = sizeof (PEAOUTHDR);
 
 
       /* PR 17521 file: 230-131433-0.004.  */
       if (amt < sizeof (PEAOUTHDR))
        amt = sizeof (PEAOUTHDR);
 
-      opthdr = bfd_zalloc (abfd, amt);
+      opthdr = _bfd_alloc_and_read (abfd, amt, opt_hdr_size);
       if (opthdr == NULL)
        return NULL;
       if (opthdr == NULL)
        return NULL;
-      if (bfd_bread (opthdr, opt_hdr_size, abfd)
-         != (bfd_size_type) opt_hdr_size)
-       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);
 
       bfd_set_error (bfd_error_no_error);
       bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);