PR26069, strip/objcopy misaligned address accesses
[deliverable/binutils-gdb.git] / bfd / peicode.h
index b5046b3192cab030e3ccaef3c8db9a75663be77d..f7d2b5f5f526762b7e61435193d13395f988175a 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright (C) 1995-2018 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.
@@ -122,7 +122,7 @@ typedef struct
 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
@@ -257,7 +257,7 @@ static bfd_boolean
 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);
 
@@ -271,6 +271,24 @@ pe_mkobject (bfd * abfd)
   /* 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;
 }
@@ -325,6 +343,9 @@ pe_mkobject_hook (bfd * abfd,
     coff_data (abfd) ->flags = 0;
 #endif
 
+  memcpy (pe->dos_message, internal_f->pe.dos_message,
+         sizeof (pe->dos_message));
+
   return (void *) pe;
 }
 
@@ -601,6 +622,7 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
 {
   asection_ptr sec;
   flagword     flags;
+  intptr_t alignment;
 
   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;
 
-  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.  */
-  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 ++;
 
@@ -631,20 +653,18 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
   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
-     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
+  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);
@@ -758,6 +778,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;
+  intptr_t alignment;
 
   /* Decode and verify the types field of the ILF structure.  */
   import_type = types & 0x3;
@@ -772,13 +793,13 @@ pe_ILF_build_a_bfd (bfd *     abfd,
     case IMPORT_CONST:
       /* XXX code yet to be written.  */
       /* xgettext:c-format */
-      _bfd_error_handler (_("%pB: Unhandled import type; %x"),
+      _bfd_error_handler (_("%pB: unhandled import type; %x"),
                          abfd, import_type);
       return FALSE;
 
     default:
       /* xgettext:c-format */
-      _bfd_error_handler (_("%pB: Unrecognised import type; %x"),
+      _bfd_error_handler (_("%pB: unrecognized import type; %x"),
                          abfd, import_type);
       return FALSE;
     }
@@ -793,7 +814,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
 
     default:
       /* xgettext:c-format */
-      _bfd_error_handler (_("%pB: Unrecognised import name type; %x"),
+      _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
                          abfd, import_name_type);
       return FALSE;
     }
@@ -853,23 +874,17 @@ pe_ILF_build_a_bfd (bfd *     abfd,
 
   /* 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
-     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
+  ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
 
   vars.data = ptr;
   vars.abfd = abfd;
@@ -1093,7 +1108,7 @@ pe_ILF_build_a_bfd (bfd *     abfd,
 
   /* 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;
@@ -1112,8 +1127,7 @@ pe_ILF_build_a_bfd (bfd *     abfd,
   return TRUE;
 
  error_return:
-  if (vars.bim->buffer != NULL)
-    free (vars.bim->buffer);
+  free (vars.bim->buffer);
   free (vars.bim);
   return FALSE;
 }
@@ -1121,7 +1135,7 @@ pe_ILF_build_a_bfd (bfd *     abfd,
 /* 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];
@@ -1167,12 +1181,6 @@ pe_ILF_object_p (bfd * abfd)
 #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:
@@ -1214,7 +1222,7 @@ pe_ILF_object_p (bfd * abfd)
     default:
       _bfd_error_handler
        /* xgettext:c-format */
-       (_("%pB: Unrecognised machine type (0x%x)"
+       (_("%pB: unrecognised machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_malformed_archive);
@@ -1227,7 +1235,7 @@ pe_ILF_object_p (bfd * abfd)
     {
       _bfd_error_handler
        /* xgettext:c-format */
-       (_("%pB: Recognised but unhandled machine type (0x%x)"
+       (_("%pB: recognised but unhandled machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
       bfd_set_error (bfd_error_wrong_format);
@@ -1258,16 +1266,10 @@ pe_ILF_object_p (bfd * abfd)
   /* 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 (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;
@@ -1277,7 +1279,7 @@ pe_ILF_object_p (bfd * abfd)
       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
     {
       _bfd_error_handler
-       (_("%pB: 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;
@@ -1291,7 +1293,7 @@ pe_ILF_object_p (bfd * abfd)
       return NULL;
     }
 
-  return abfd->xvec;
+  return _bfd_no_cleanup;
 }
 
 static void
@@ -1332,16 +1334,16 @@ pe_bfd_read_buildid (bfd *abfd)
   if (dataoff >= section->size
       || size > section->size - dataoff)
     {
-      _bfd_error_handler (_("%pB: Error: Debug Data ends beyond end of debug directory."),
-                         abfd);
+      _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))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return;
     }
 
@@ -1380,9 +1382,11 @@ pe_bfd_read_buildid (bfd *abfd)
          break;
        }
     }
+
+  free (data);
 }
 
-static const bfd_target *
+static bfd_cleanup
 pe_bfd_object_p (bfd * abfd)
 {
   bfd_byte buffer[6];
@@ -1390,9 +1394,9 @@ pe_bfd_object_p (bfd * abfd)
   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;
-  const bfd_target *result;
+  bfd_cleanup result;
 
   /* Detect if this a Microsoft Import Library Format element.  */
   /* First read the beginning of the header.  */
@@ -1461,6 +1465,9 @@ pe_bfd_object_p (bfd * abfd)
       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;
 
@@ -1473,12 +1480,11 @@ pe_bfd_object_p (bfd * abfd)
       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 (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);
This page took 0.027929 seconds and 4 git commands to generate.