]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - ld/pe-dll.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / ld / pe-dll.c
index e45ae1042654bb57f3282731b22dfb46e7766a56..95eef84f607681fb1f534bccb4939accbbc0cd37 100644 (file)
@@ -1,5 +1,5 @@
 /* Routines to help build PEI-format DLLs (Win32 etc)
-   Copyright (C) 1998-2023 Free Software Foundation, Inc.
+   Copyright (C) 1998-2024 Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
    This file is part of the GNU Binutils.
@@ -1231,7 +1231,10 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
   memset (edata_d, 0, edata_sz);
 
   if (pe_data (abfd)->timestamp == -1)
-    H_PUT_32 (abfd, time (0), edata_d + 4);
+    {
+      time_t now = bfd_get_current_time (0);
+      H_PUT_32 (abfd, now, edata_d + 4);
+    }
   else
     H_PUT_32 (abfd, pe_data (abfd)->timestamp, edata_d + 4);
 
@@ -2107,6 +2110,7 @@ make_head (bfd *parent)
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2200,6 +2204,7 @@ make_tail (bfd *parent)
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2392,6 +2397,7 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2586,6 +2592,7 @@ make_singleton_name_thunk (const char *import, bfd *parent)
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2666,6 +2673,7 @@ make_import_fixup_entry (const char *name,
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2724,6 +2732,7 @@ make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2816,6 +2825,7 @@ pe_create_runtime_relocator_reference (bfd *parent)
   tmp_seq++;
 
   abfd = bfd_create (oname, parent);
+  free (oname);
   bfd_find_target (pe_details->object_target, abfd);
   bfd_make_writable (abfd);
 
@@ -2904,7 +2914,7 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name,
     }
 
   else if (addend != 0)
-    einfo (_("%X%P: %C: variable '%pT' can't be auto-imported; please read the documentation for ld's --enable-auto-import for details\n"),
+    einfo (_("%X%P: %H: variable '%pT' can't be auto-imported; please read the documentation for ld's --enable-auto-import for details\n"),
           s->owner, s, rel->address, (*rel->sym_ptr_ptr)->name);
 }
 
@@ -3322,6 +3332,14 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
                                               false, false, false);
                  if (blhe)
                    is_undef = (blhe->type == bfd_link_hash_undefined);
+
+                 if (is_cdecl && (!blhe || !is_undef))
+                   {
+                     blhe = pe_find_cdecl_alias_match (linfo, name + 6);
+                     include_jmp_stub = true;
+                     if (blhe)
+                       is_undef = (blhe->type == bfd_link_hash_undefined);
+                   }
                }
              else
                {
@@ -3329,16 +3347,6 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
                  is_undef = (blhe->type == bfd_link_hash_undefined);
                }
 
-             if (is_cdecl
-                 && (!blhe || (blhe && blhe->type != bfd_link_hash_undefined)))
-               {
-                 sprintf (name, "%s%s",U (""), imp[i].internal_name);
-                 blhe = pe_find_cdecl_alias_match (linfo, name);
-                 include_jmp_stub = true;
-                 if (blhe)
-                   is_undef = (blhe->type == bfd_link_hash_undefined);
-               }
-
              free (name);
 
              if (is_undef)
@@ -3403,22 +3411,30 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
    handled, FALSE if not.  */
 
 static unsigned int
-pe_get16 (bfd *abfd, int where)
+pe_get16 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[2];
 
-  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
-  bfd_bread (b, (bfd_size_type) 2, abfd);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 2, abfd) != 2)
+    {
+      *fail = true;
+      return 0;
+    }
   return b[0] + (b[1] << 8);
 }
 
 static unsigned int
-pe_get32 (bfd *abfd, int where)
+pe_get32 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[4];
 
-  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
-  bfd_bread (b, (bfd_size_type) 4, abfd);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 4, abfd) != 4)
+    {
+      *fail = true;
+      return 0;
+    }
   return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24);
 }
 
@@ -3465,38 +3481,49 @@ pe_implied_import_dll (const char *filename)
   /* PEI dlls seem to be bfd_objects.  */
   if (!bfd_check_format (dll, bfd_object))
     {
+    notdll:
       einfo (_("%X%P: %s: this doesn't appear to be a DLL\n"), filename);
       return false;
     }
 
   /* Get pe_header, optional header and numbers of directory entries.  */
-  pe_header_offset = pe_get32 (dll, 0x3c);
+  bool fail = false;
+  pe_header_offset = pe_get32 (dll, 0x3c, &fail);
+  if (fail)
+    goto notdll;
   opthdr_ofs = pe_header_offset + 4 + 20;
 #ifdef pe_use_plus
-  num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /*  & NumberOfRvaAndSizes.  */
+  /* NumberOfRvaAndSizes.  */
+  num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4, &fail);
 #else
-  num_entries = pe_get32 (dll, opthdr_ofs + 92);
+  num_entries = pe_get32 (dll, opthdr_ofs + 92, &fail);
 #endif
+  if (fail)
+    goto notdll;
 
   /* No import or export directory entry.  */
   if (num_entries < 1)
     return false;
 
 #ifdef pe_use_plus
-  export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
-  export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
+  export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4, &fail);
+  export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4, &fail);
 #else
-  export_rva = pe_get32 (dll, opthdr_ofs + 96);
-  export_size = pe_get32 (dll, opthdr_ofs + 100);
+  export_rva = pe_get32 (dll, opthdr_ofs + 96, &fail);
+  export_size = pe_get32 (dll, opthdr_ofs + 100, &fail);
 #endif
+  if (fail)
+    goto notdll;
 
   /* No export table - nothing to export.  */
   if (export_size == 0)
     return false;
 
-  nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
+  nsections = pe_get16 (dll, pe_header_offset + 4 + 2, &fail);
   secptr = (pe_header_offset + 4 + 20 +
-           pe_get16 (dll, pe_header_offset + 4 + 16));
+           pe_get16 (dll, pe_header_offset + 4 + 16, &fail));
+  if (fail)
+    goto notdll;
   expptr = 0;
 
   /* Get the rva and size of the export section.  */
@@ -3504,12 +3531,14 @@ pe_implied_import_dll (const char *filename)
     {
       char sname[8];
       bfd_vma secptr1 = secptr + 40 * i;
-      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
-      bfd_vma vsize = pe_get32 (dll, secptr1 + 16);
-      bfd_vma fptr = pe_get32 (dll, secptr1 + 20);
+      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      bfd_vma vsize = pe_get32 (dll, secptr1 + 16, &fail);
+      bfd_vma fptr = pe_get32 (dll, secptr1 + 20, &fail);
 
-      bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
-      bfd_bread (sname, (bfd_size_type) 8, dll);
+      if (fail
+         || bfd_seek (dll, secptr1, SEEK_SET) != 0
+         || bfd_read (sname, 8, dll) != 8)
+       goto notdll;
 
       if (vaddr <= export_rva && vaddr + vsize > export_rva)
        {
@@ -3525,14 +3554,16 @@ pe_implied_import_dll (const char *filename)
   for (i = 0; i < nsections; i++)
     {
       bfd_vma secptr1 = secptr + 40 * i;
-      bfd_vma vsize = pe_get32 (dll, secptr1 + 8);
-      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
-      bfd_vma flags = pe_get32 (dll, secptr1 + 36);
+      bfd_vma vsize = pe_get32 (dll, secptr1 + 8, &fail);
+      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      bfd_vma flags = pe_get32 (dll, secptr1 + 36, &fail);
       char sec_name[9];
 
       sec_name[8] = '\0';
-      bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
-      bfd_bread (sec_name, (bfd_size_type) 8, dll);
+      if (fail
+         || bfd_seek (dll, secptr1 + 0, SEEK_SET) != 0
+         || bfd_read (sec_name, 8, dll) != 8)
+       goto notdll;
 
       if (strcmp(sec_name,".data") == 0)
        {
@@ -3567,8 +3598,9 @@ pe_implied_import_dll (const char *filename)
     }
 
   expdata = xmalloc (export_size);
-  bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
-  bfd_bread (expdata, (bfd_size_type) export_size, dll);
+  if (bfd_seek (dll, expptr, SEEK_SET) != 0
+      || bfd_read (expdata, export_size, dll) != export_size)
+    goto notdll;
   erva = (char *) expdata - export_rva;
 
   if (pe_def_file == 0)