Change regcache list to be an hash map
[deliverable/binutils-gdb.git] / bfd / peXXigen.c
index 6caca1729b8e80fc6e341e551e7a381af56befc4..71d47ae660fbb922b1aa125b82997adc089f310b 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
-   Copyright (C) 1995-2018 Free Software Foundation, Inc.
+   Copyright (C) 1995-2019 Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
    "Peering Inside the PE: A Tour of the Win32 Portable Executable
    File Format", MSJ 1994, Volume 9.
 
+   The PE/PEI format is also used by .NET. ECMA-335 describes this:
+
+   "Standard ECMA-335 Common Language Infrastructure (CLI)", 6th Edition, June 2012.
+
+   This is also available at
+   https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf.
+
    The *sole* difference between the pe format and the pei format is that the
    latter has an MSDOS 2.0 .exe header on the front that prints the message
    "This app must be run under Windows." (or some such).
@@ -154,7 +161,7 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
          name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
          if (name == NULL)
            {
-             _bfd_error_handler (_("%B: unable to find name for empty section"),
+             _bfd_error_handler (_("%pB: unable to find name for empty section"),
                                  abfd);
              bfd_set_error (bfd_error_invalid_target);
              return;
@@ -180,7 +187,7 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
              name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
              if (name == NULL)
                {
-                 _bfd_error_handler (_("%B: out of memory creating name for empty section"),
+                 _bfd_error_handler (_("%pB: out of memory creating name for empty section"),
                                      abfd);
                  return;
                }
@@ -191,7 +198,7 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
          sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
          if (sec == NULL)
            {
-             _bfd_error_handler (_("%B: unable to create fake empty section"),
+             _bfd_error_handler (_("%pB: unable to create fake empty section"),
                                  abfd);
              return;
            }
@@ -522,15 +529,15 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
 
   {
-    int idx;
+    unsigned idx;
 
     /* PR 17512: Corrupt PE binaries can cause seg-faults.  */
     if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
       {
        /* xgettext:c-format */
        _bfd_error_handler
-         (_("%B: aout header specifies an invalid number of data-directory entries: %ld"),
-          abfd, a->NumberOfRvaAndSizes);
+         (_("%pB: aout header specifies an invalid number of"
+            " data-directory entries: %u"), abfd, a->NumberOfRvaAndSizes);
        bfd_set_error (bfd_error_bad_value);
 
        /* Paranoia: If the number is corrupt, then assume that the
@@ -716,6 +723,9 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
       {
        int rounded = FA (sec->size);
 
+       if (rounded == 0)
+         continue;
+
        /* The first non-zero section filepos is the header size.
           Sections without contents will have a filepos of 0.  */
        if (hsize == 0)
@@ -856,28 +866,16 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
 
   /* This next collection of data are mostly just characters.  It
      appears to be constant within the headers put on NT exes.  */
-  filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
-  filehdr_in->pe.dos_message[1]  = 0xcd09b400;
-  filehdr_in->pe.dos_message[2]  = 0x4c01b821;
-  filehdr_in->pe.dos_message[3]  = 0x685421cd;
-  filehdr_in->pe.dos_message[4]  = 0x70207369;
-  filehdr_in->pe.dos_message[5]  = 0x72676f72;
-  filehdr_in->pe.dos_message[6]  = 0x63206d61;
-  filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
-  filehdr_in->pe.dos_message[8]  = 0x65622074;
-  filehdr_in->pe.dos_message[9]  = 0x6e757220;
-  filehdr_in->pe.dos_message[10] = 0x206e6920;
-  filehdr_in->pe.dos_message[11] = 0x20534f44;
-  filehdr_in->pe.dos_message[12] = 0x65646f6d;
-  filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
-  filehdr_in->pe.dos_message[14] = 0x24;
-  filehdr_in->pe.dos_message[15] = 0x0;
+  memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message,
+         sizeof (filehdr_in->pe.dos_message));
+
   filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE;
 
   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
 
-  /* Only use a real timestamp if the option was chosen.  */
+  /* Use a real timestamp by default, unless the no-insert-timestamp
+     option was chosen.  */
   if ((pe_data (abfd)->insert_timestamp))
     H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
   else
@@ -1018,7 +1016,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
 
     typedef struct
     {
-      const char *     section_name;
+      char section_name[SCNNMLEN];
       unsigned long    must_have;
     }
     pe_required_section_flags;
@@ -1037,7 +1035,6 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
        { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
        { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
        { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
-       { NULL, 0}
       };
 
     pe_required_section_flags * p;
@@ -1050,10 +1047,12 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
        by ld --enable-auto-import (if auto-import is actually needed),
        by ld --omagic, or by obcopy --writable-text.  */
 
-    for (p = known_sections; p->section_name; p++)
-      if (strcmp (scnhdr_int->s_name, p->section_name) == 0)
+    for (p = known_sections;
+        p < known_sections + ARRAY_SIZE (known_sections);
+        p++)
+      if (memcmp (scnhdr_int->s_name, p->section_name, SCNNMLEN) == 0)
        {
-         if (strcmp (scnhdr_int->s_name, ".text")
+         if (memcmp (scnhdr_int->s_name, ".text", sizeof ".text")
              || (bfd_get_file_flags (abfd) & WP_TEXT))
            scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
          scnhdr_int->s_flags |= p->must_have;
@@ -1066,7 +1065,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
   if (coff_data (abfd)->link_info
       && ! bfd_link_relocatable (coff_data (abfd)->link_info)
       && ! bfd_link_pic (coff_data (abfd)->link_info)
-      && strcmp (scnhdr_int->s_name, ".text") == 0)
+      && memcmp (scnhdr_int->s_name, ".text", sizeof ".text") == 0)
     {
       /* By inference from looking at MS output, the 32 bit field
         which is the combination of the number_of_relocs and
@@ -1086,7 +1085,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
       else
        {
          /* xgettext:c-format */
-         _bfd_error_handler (_("%B: line number overflow: 0x%lx > 0xffff"),
+         _bfd_error_handler (_("%pB: line number overflow: 0x%lx > 0xffff"),
                              abfd, scnhdr_int->s_nlnno);
          bfd_set_error (bfd_error_file_truncated);
          H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nlnno);
@@ -1207,7 +1206,10 @@ _bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinf
   if (bfd_seek (abfd, where, SEEK_SET) != 0)
     return 0;
 
-  buffer = xmalloc (size);
+  buffer = bfd_malloc (size);
+  if (buffer == NULL)
+    return 0;
+
   cvinfo70 = (CV_INFO_PDB70 *) buffer;
   H_PUT_32 (abfd, CVINFO_PDB70_CVSIGNATURE, cvinfo70->CvSignature);
 
@@ -1437,7 +1439,7 @@ pe_print_idata (bfd * abfd, void * vfile)
       if (hint_addr == 0)
        hint_addr = first_thunk;
 
-      if (hint_addr != 0)
+      if (hint_addr != 0 && hint_addr - adj < datasize)
        {
          bfd_byte *ft_data;
          asection *ft_section;
@@ -1660,7 +1662,8 @@ pe_print_edata (bfd * abfd, void * vfile)
 
       dataoff = addr - section->vma;
       datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
-      if (datasize > section->size - dataoff)
+      if (dataoff > section->size
+         || datasize > section->size - dataoff)
        {
          fprintf (file,
                   _("\nThere is an export table in %s, but it does not fit into that section\n"),
@@ -1670,7 +1673,7 @@ pe_print_edata (bfd * abfd, void * vfile)
     }
 
   /* PR 17512: Handle corrupt PE binaries.  */
-  if (datasize < 36)
+  if (datasize < 40)
     {
       fprintf (file,
               /* xgettext:c-format */
@@ -1777,11 +1780,11 @@ pe_print_edata (bfd * abfd, void * vfile)
          edt.base);
 
   /* PR 17512: Handle corrupt PE binaries.  */
-  if (edt.eat_addr + (edt.num_functions * 4) - adj >= datasize
+  /* PR 17512 file: 140-165018-0.004.  */
+  if (edt.eat_addr - adj >= datasize
       /* PR 17512: file: 092b1829 */
-      || (edt.num_functions * 4) < edt.num_functions
-      /* PR 17512 file: 140-165018-0.004.  */
-      || data + edt.eat_addr - adj < data)
+      || (edt.num_functions + 1) * 4 < edt.num_functions
+      || edt.eat_addr - adj + (edt.num_functions + 1) * 4 > datasize)
     fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
             (long) edt.eat_addr,
             (long) edt.num_functions);
@@ -1903,7 +1906,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
   if ((stop % onaline) != 0)
     fprintf (file,
             /* xgettext:c-format */
-            _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
+            _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
             (long) stop, onaline);
 
   fprintf (file,
@@ -2100,7 +2103,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
   if ((stop % onaline) != 0)
     fprintf (file,
             /* xgettext:c-format */
-            _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
+            _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
             (long) stop, onaline);
 
   fprintf (file,
@@ -2803,12 +2806,13 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     fprintf (file, "\t(%s)",name);
   fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
   fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
-  fprintf (file, "SizeOfCode\t\t%08lx\n", (unsigned long) i->SizeOfCode);
-  fprintf (file, "SizeOfInitializedData\t%08lx\n",
-          (unsigned long) i->SizeOfInitializedData);
-  fprintf (file, "SizeOfUninitializedData\t%08lx\n",
-          (unsigned long) i->SizeOfUninitializedData);
-  fprintf (file, "AddressOfEntryPoint\t");
+  fprintf (file, "SizeOfCode\t\t");
+  bfd_fprintf_vma (abfd, file, i->SizeOfCode);
+  fprintf (file, "\nSizeOfInitializedData\t");
+  bfd_fprintf_vma (abfd, file, i->SizeOfInitializedData);
+  fprintf (file, "\nSizeOfUninitializedData\t");
+  bfd_fprintf_vma (abfd, file, i->SizeOfUninitializedData);
+  fprintf (file, "\nAddressOfEntryPoint\t");
   bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   fprintf (file, "\nBaseOfCode\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfCode);
@@ -2820,20 +2824,18 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
 
   fprintf (file, "\nImageBase\t\t");
   bfd_fprintf_vma (abfd, file, i->ImageBase);
-  fprintf (file, "\nSectionAlignment\t");
-  bfd_fprintf_vma (abfd, file, i->SectionAlignment);
-  fprintf (file, "\nFileAlignment\t\t");
-  bfd_fprintf_vma (abfd, file, i->FileAlignment);
-  fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
+  fprintf (file, "\nSectionAlignment\t%08x\n", i->SectionAlignment);
+  fprintf (file, "FileAlignment\t\t%08x\n", i->FileAlignment);
+  fprintf (file, "MajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
   fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
   fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
   fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
   fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
   fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
-  fprintf (file, "Win32Version\t\t%08lx\n", (unsigned long) i->Reserved1);
-  fprintf (file, "SizeOfImage\t\t%08lx\n", (unsigned long) i->SizeOfImage);
-  fprintf (file, "SizeOfHeaders\t\t%08lx\n", (unsigned long) i->SizeOfHeaders);
-  fprintf (file, "CheckSum\t\t%08lx\n", (unsigned long) i->CheckSum);
+  fprintf (file, "Win32Version\t\t%08x\n", i->Reserved1);
+  fprintf (file, "SizeOfImage\t\t%08x\n", i->SizeOfImage);
+  fprintf (file, "SizeOfHeaders\t\t%08x\n", i->SizeOfHeaders);
+  fprintf (file, "CheckSum\t\t%08x\n", i->CheckSum);
 
   switch (i->Subsystem)
     {
@@ -2967,6 +2969,8 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
       && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
     pe_data (obfd)->dont_strip_reloc = 1;
 
+  memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
+
   /* The file offsets contained in the debug directory need rewriting.  */
   if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
     {
@@ -2982,13 +2986,16 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
            (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
 
          /* PR 17512: file: 0f15796a.  */
-         if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size + (addr - section->vma)
-             > bfd_get_section_size (section))
+         if ((unsigned long) ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+             > section->size - (addr - section->vma))
            {
              /* xgettext:c-format */
-             _bfd_error_handler (_("%B: Data Directory size (%lx) exceeds space left in section (%Lx)"),
-                                 obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
-                                 bfd_get_section_size (section) - (addr - section->vma));
+             _bfd_error_handler
+               (_("%pB: Data Directory size (%lx) "
+                  "exceeds space left in section (%" PRIx64 ")"),
+                obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
+                (uint64_t) (section->size - (addr - section->vma)));
+             free (data);
              return FALSE;
            }
 
@@ -3016,13 +3023,15 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 
          if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
            {
-             _bfd_error_handler (_("Failed to update file offsets in debug directory"));
+             _bfd_error_handler (_("failed to update file offsets in debug directory"));
+             free (data);
              return FALSE;
            }
+         free (data);
        }
       else if (section)
        {
-         _bfd_error_handler (_("%B: Failed to read debug data section"), obfd);
+         _bfd_error_handler (_("%pB: failed to read debug data section"), obfd);
          return FALSE;
        }
     }
@@ -4101,14 +4110,14 @@ rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
 
   if (adir->characteristics != bdir->characteristics)
     {
-      _bfd_error_handler (_(".rsrc merge failure: dirs with differing characteristics\n"));
+      _bfd_error_handler (_(".rsrc merge failure: dirs with differing characteristics"));
       bfd_set_error (bfd_error_file_truncated);
       return;
     }
 
   if (adir->major != bdir->major || adir->minor != bdir->minor)
     {
-      _bfd_error_handler (_(".rsrc merge failure: differing directory versions\n"));
+      _bfd_error_handler (_(".rsrc merge failure: differing directory versions"));
       bfd_set_error (bfd_error_file_truncated);
       return;
     }
@@ -4225,7 +4234,7 @@ rsrc_process_section (bfd * abfd,
       if (data > dataend)
        {
          /* Corrupted .rsrc section - cannot merge.  */
-         _bfd_error_handler (_("%B: .rsrc merge failure: corrupt .rsrc section"),
+         _bfd_error_handler (_("%pB: .rsrc merge failure: corrupt .rsrc section"),
                              abfd);
          bfd_set_error (bfd_error_file_truncated);
          goto end;
@@ -4233,7 +4242,7 @@ rsrc_process_section (bfd * abfd,
 
       if ((data - p) > rsrc_sizes [num_resource_sets])
        {
-         _bfd_error_handler (_("%B: .rsrc merge failure: unexpected .rsrc size"),
+         _bfd_error_handler (_("%pB: .rsrc merge failure: unexpected .rsrc size"),
                              abfd);
          bfd_set_error (bfd_error_file_truncated);
          goto end;
@@ -4372,7 +4381,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"),
+           (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
             abfd);
          result = FALSE;
        }
@@ -4392,7 +4401,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"),
+           (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
             abfd);
          result = FALSE;
        }
@@ -4413,7 +4422,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"),
+           (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
             abfd);
          result = FALSE;
        }
@@ -4433,7 +4442,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
+           (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
             abfd);
          result = FALSE;
        }
@@ -4475,7 +4484,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          else
            {
              _bfd_error_handler
-               (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
+               (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
                   " because .idata$6 is missing"), abfd);
              result = FALSE;
            }
@@ -4500,7 +4509,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"),
+           (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
             abfd);
          result = FALSE;
        }
This page took 0.031171 seconds and 4 git commands to generate.