Fix C-x 1 from gdb prompt
[deliverable/binutils-gdb.git] / bfd / peXXigen.c
index 1f55f927dc881d0c62155a2d54470f558f9ebe13..c33c495a0f6a4e4ac741d0b77d7a50a7e1c721a1 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
 /* Support for the generic parts of PE/PEI; the common executable parts.
-   Copyright (C) 1995-2019 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.
@@ -177,25 +177,25 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
          int unused_section_number = 0;
          asection *sec;
          flagword flags;
          int unused_section_number = 0;
          asection *sec;
          flagword flags;
+         size_t name_len;
+         char *sec_name;
 
          for (sec = abfd->sections; sec; sec = sec->next)
            if (unused_section_number <= sec->target_index)
              unused_section_number = sec->target_index + 1;
 
 
          for (sec = abfd->sections; sec; sec = sec->next)
            if (unused_section_number <= sec->target_index)
              unused_section_number = sec->target_index + 1;
 
-         if (name == namebuf)
+         name_len = strlen (name) + 1;
+         sec_name = bfd_alloc (abfd, name_len);
+         if (sec_name == NULL)
            {
            {
-             name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
-             if (name == NULL)
-               {
-                 _bfd_error_handler (_("%pB: out of memory creating name for empty section"),
-                                     abfd);
-                 return;
-               }
-             strcpy ((char *) name, namebuf);
+             _bfd_error_handler (_("%pB: out of memory creating name "
+                                   "for empty section"), abfd);
+             return;
            }
            }
+         memcpy (sec_name, name, name_len);
 
          flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
 
          flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
-         sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
+         sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags);
          if (sec == NULL)
            {
              _bfd_error_handler (_("%pB: unable to create fake empty section"),
          if (sec == NULL)
            {
              _bfd_error_handler (_("%pB: unable to create fake empty section"),
@@ -723,6 +723,9 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
       {
        int rounded = FA (sec->size);
 
       {
        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)
        /* The first non-zero section filepos is the header size.
           Sections without contents will have a filepos of 0.  */
        if (hsize == 0)
@@ -873,10 +876,10 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
 
   /* Use a real timestamp by default, unless the no-insert-timestamp
      option was chosen.  */
 
   /* Use a real timestamp by default, unless the no-insert-timestamp
      option was chosen.  */
-  if ((pe_data (abfd)->insert_timestamp))
+  if ((pe_data (abfd)->timestamp) == -1)
     H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
   else
     H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
   else
-    H_PUT_32 (abfd, 0, filehdr_out->f_timdat);
+    H_PUT_32 (abfd, pe_data (abfd)->timestamp, filehdr_out->f_timdat);
 
   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
                      filehdr_out->f_symptr);
 
   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
                      filehdr_out->f_symptr);
@@ -1340,8 +1343,7 @@ pe_print_idata (bfd * abfd, void * vfile)
 
       if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
        {
 
       if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
        {
-         if (data != NULL)
-           free (data);
+         free (data);
          return FALSE;
        }
 
          return FALSE;
        }
 
@@ -1349,8 +1351,7 @@ pe_print_idata (bfd * abfd, void * vfile)
 
       if (offset >= rel_section->size || offset + 8 > rel_section->size)
        {
 
       if (offset >= rel_section->size || offset + 8 > rel_section->size)
        {
-         if (data != NULL)
-           free (data);
+         free (data);
          return FALSE;
        }
 
          return FALSE;
        }
 
@@ -1365,8 +1366,7 @@ pe_print_idata (bfd * abfd, void * vfile)
               /* xgettext:c-format */
               _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
               start_address, loadable_toc_address, toc_address);
               /* xgettext:c-format */
               _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
               start_address, loadable_toc_address, toc_address);
-      if (data != NULL)
-       free (data);
+      free (data);
     }
   else
     {
     }
   else
     {
@@ -1386,8 +1386,7 @@ pe_print_idata (bfd * abfd, void * vfile)
   /* Read the whole section.  Some of the fields might be before dataoff.  */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
   /* Read the whole section.  Some of the fields might be before dataoff.  */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -1932,8 +1931,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -2116,8 +2114,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -2232,8 +2229,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -2540,8 +2536,7 @@ rsrc_print_section (bfd * abfd, void * vfile)
 
   if (! bfd_malloc_and_get_section (abfd, section, & data))
     {
 
   if (! bfd_malloc_and_get_section (abfd, section, & data))
     {
-      if (data != NULL)
-       free (data);
+      free (data);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -2600,7 +2595,7 @@ rsrc_print_section (bfd * abfd, void * vfile)
   return TRUE;
 }
 
   return TRUE;
 }
 
-#define IMAGE_NUMBEROF_DEBUG_TYPES 12
+#define IMAGE_NUMBEROF_DEBUG_TYPES 17
 
 static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
 {
 
 static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
 {
@@ -2616,6 +2611,11 @@ static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
   "Borland",
   "Reserved",
   "CLSID",
   "Borland",
   "Reserved",
   "CLSID",
+  "Feature",
+  "CoffGrp",
+  "ILTCG",
+  "MPX",
+  "Repro",
 };
 
 static bfd_boolean
 };
 
 static bfd_boolean
@@ -2627,7 +2627,7 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   asection *section;
   bfd_byte *data = 0;
   bfd_size_type dataoff;
   asection *section;
   bfd_byte *data = 0;
   bfd_size_type dataoff;
-  unsigned int i;
+  unsigned int i, j;
 
   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
 
   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
@@ -2680,8 +2680,7 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   /* 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 FALSE;
     }
 
       return FALSE;
     }
 
@@ -2719,8 +2718,8 @@ pe_print_debugdata (bfd * abfd, void * vfile)
                                               idd.SizeOfData, cvinfo))
            continue;
 
                                               idd.SizeOfData, cvinfo))
            continue;
 
-         for (i = 0; i < cvinfo->SignatureLength; i++)
-           sprintf (&signature[i*2], "%02x", cvinfo->Signature[i] & 0xff);
+         for (j = 0; j < cvinfo->SignatureLength; j++)
+           sprintf (&signature[j*2], "%02x", cvinfo->Signature[j] & 0xff);
 
          /* xgettext:c-format */
          fprintf (file, _("(format %c%c%c%c signature %s age %ld)\n"),
 
          /* xgettext:c-format */
          fprintf (file, _("(format %c%c%c%c signature %s age %ld)\n"),
@@ -2729,6 +2728,8 @@ pe_print_debugdata (bfd * abfd, void * vfile)
        }
     }
 
        }
     }
 
+  free(data);
+
   if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
     fprintf (file,
            _("The debug directory size is not a multiple of the debug directory entry size\n"));
   if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
     fprintf (file,
            _("The debug directory size is not a multiple of the debug directory entry size\n"));
@@ -2736,6 +2737,70 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   return TRUE;
 }
 
   return TRUE;
 }
 
+static bfd_boolean
+pe_is_repro (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_boolean res = FALSE;
+
+  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
+  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
+
+  if (size == 0)
+    return FALSE;
+
+  addr += extra->ImageBase;
+  for (section = abfd->sections; section != NULL; section = section->next)
+    {
+      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
+       break;
+    }
+
+  if ((section == NULL)
+      || (!(section->flags & SEC_HAS_CONTENTS))
+      || (section->size < size))
+    {
+      return FALSE;
+    }
+
+  dataoff = addr - section->vma;
+
+  if (size > (section->size - dataoff))
+    {
+      return FALSE;
+    }
+
+  if (!bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      free (data);
+      return FALSE;
+    }
+
+  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_REPRO)
+        {
+          res = TRUE;
+          break;
+        }
+    }
+
+  free(data);
+
+  return res;
+}
+
 /* Print out the program headers.  */
 
 bfd_boolean
 /* Print out the program headers.  */
 
 bfd_boolean
@@ -2767,11 +2832,21 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
 #undef PF
 
   PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
 #undef PF
 
-  /* ctime implies '\n'.  */
-  {
-    time_t t = pe->coff.timestamp;
-    fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
-  }
+  /*
+    If a PE_IMAGE_DEBUG_TYPE_REPRO entry is present in the debug directory, the
+    timestamp is to be interpreted as the hash of a reproducible build.
+  */
+  if (pe_is_repro (abfd))
+    {
+      fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp);
+      fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n");
+    }
+  else
+    {
+      /* ctime implies '\n'.  */
+      time_t t = pe->coff.timestamp;
+      fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
+    }
 
 #ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
 # define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
 
 #ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
 # define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
@@ -3053,7 +3128,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
     {
       if (coff_section_data (obfd, osec) == NULL)
        {
     {
       if (coff_section_data (obfd, osec) == NULL)
        {
-         bfd_size_type amt = sizeof (struct coff_section_tdata);
+         size_t amt = sizeof (struct coff_section_tdata);
          osec->used_by_bfd = bfd_zalloc (obfd, amt);
          if (osec->used_by_bfd == NULL)
            return FALSE;
          osec->used_by_bfd = bfd_zalloc (obfd, amt);
          if (osec->used_by_bfd == NULL)
            return FALSE;
@@ -3061,7 +3136,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
 
       if (pei_section_data (obfd, osec) == NULL)
        {
 
       if (pei_section_data (obfd, osec) == NULL)
        {
-         bfd_size_type amt = sizeof (struct pei_section_tdata);
+         size_t amt = sizeof (struct pei_section_tdata);
          coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
          if (coff_section_data (obfd, osec)->tdata == NULL)
            return FALSE;
          coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
          if (coff_section_data (obfd, osec)->tdata == NULL)
            return FALSE;
This page took 0.05148 seconds and 4 git commands to generate.