public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] ld: pe: Make archive member file extension comparisons case insensitive when cross compiling too
@ 2022-08-24 20:19 Martin Storsjo
  0 siblings, 0 replies; only message in thread
From: Martin Storsjo @ 2022-08-24 20:19 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b53b12c8e86bb30003f7dd644638db770127e689

commit b53b12c8e86bb30003f7dd644638db770127e689
Author: Martin Storsjö <martin@martin.st>
Date:   Mon Sep 27 11:20:24 2021 +0300

    ld: pe: Make archive member file extension comparisons case insensitive when cross compiling too
    
    On Windows, filename_cmp is case insensitive, but when cross compiling
    with libraries that may contain members with uppercase file names, we
    should keep those comparisons case insensitive when running the build
    tools on other OSes too.
    
    Also make the check for .def consistent with the other ones, fixing
    out of bounds reads if file names are shorter than 4 characters.

Diff:
---
 ld/emultempl/pe.em  | 27 ++++++++++++++++++++++-----
 ld/emultempl/pep.em | 27 ++++++++++++++++++++++-----
 2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index ad969ccec13..2706d73d144 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -534,6 +534,23 @@ gld${EMULATION_NAME}_list_options (FILE *file)
   fprintf (file, _("  --build-id[=STYLE]                 Generate build ID\n"));
 }
 
+/* A case insensitive comparison, regardless of the host platform, used for
+   comparing file extensions.  */
+static int
+fileext_cmp (const char *s1, const char *s2)
+{
+  for (;;)
+    {
+      int c1 = TOLOWER (*s1++);
+      int c2 = *s2++; /* Assumed to be lower case from the caller.  */
+
+      if (c1 != c2)
+        return (c1 - c2);
+
+      if (c1 == '\0')
+        return 0;
+    }
+}
 
 static void
 set_pe_name (char *name, long val)
@@ -1666,7 +1683,7 @@ gld${EMULATION_NAME}_after_open (void)
 		       extension, and use that for the remainder of the
 		       comparisons.  */
 		    pnt = strrchr (bfd_get_filename (is3->the_bfd), '.');
-		    if (pnt != NULL && filename_cmp (pnt, ".dll") == 0)
+		    if (pnt != NULL && fileext_cmp (pnt + 1, "dll") == 0)
 		      break;
 		  }
 
@@ -1683,7 +1700,7 @@ gld${EMULATION_NAME}_after_open (void)
 			/* Skip static members, ie anything with a .obj
 			   extension.  */
 			pnt = strrchr (bfd_get_filename (is2->the_bfd), '.');
-			if (pnt != NULL && filename_cmp (pnt, ".obj") == 0)
+			if (pnt != NULL && fileext_cmp (pnt + 1, "obj") == 0)
 			  continue;
 
 			if (filename_cmp (bfd_get_filename (is3->the_bfd),
@@ -1701,7 +1718,7 @@ gld${EMULATION_NAME}_after_open (void)
 	       then leave the filename alone.  */
 	    pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
 
-	    if (is_ms_arch && (filename_cmp (pnt, ".dll") == 0))
+	    if (is_ms_arch && pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0))
 	      {
 		int idata2 = 0, reloc_count=0;
 		asection *sec;
@@ -1855,9 +1872,9 @@ static bool
 gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
 {
 #ifdef DLL_SUPPORT
-  const char *ext = entry->filename + strlen (entry->filename) - 4;
+  const char *ext = strrchr (entry->filename, '.');
 
-  if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0)
+  if (ext != NULL && fileext_cmp (ext + 1, "def") == 0)
     {
       pe_def_file = def_file_parse (entry->filename, pe_def_file);
 
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index ee36a9a7e56..accefc0ed60 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -181,6 +181,23 @@ static int is_underscoring (void)
   return pep_leading_underscore;
 }
 
+/* A case insensitive comparison, regardless of the host platform, used for
+   comparing file extensions.  */
+static int
+fileext_cmp (const char *s1, const char *s2)
+{
+  for (;;)
+    {
+      int c1 = TOLOWER (*s1++);
+      int c2 = *s2++; /* Assumed to be lower case from the caller.  */
+
+      if (c1 != c2)
+        return (c1 - c2);
+
+      if (c1 == '\0')
+        return 0;
+    }
+}
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -1630,7 +1647,7 @@ gld${EMULATION_NAME}_after_open (void)
 		       extension, and use that for the remainder of the
 		       comparisons.  */
 		    pnt = strrchr (bfd_get_filename (is3->the_bfd), '.');
-		    if (pnt != NULL && filename_cmp (pnt, ".dll") == 0)
+		    if (pnt != NULL && fileext_cmp (pnt + 1, "dll") == 0)
 		      break;
 		  }
 
@@ -1647,7 +1664,7 @@ gld${EMULATION_NAME}_after_open (void)
 			/* Skip static members, ie anything with a .obj
 			   extension.  */
 			pnt = strrchr (bfd_get_filename (is2->the_bfd), '.');
-			if (pnt != NULL && filename_cmp (pnt, ".obj") == 0)
+			if (pnt != NULL && fileext_cmp (pnt + 1, "obj") == 0)
 			  continue;
 
 			if (filename_cmp (bfd_get_filename (is3->the_bfd),
@@ -1665,7 +1682,7 @@ gld${EMULATION_NAME}_after_open (void)
 	       then leave the filename alone.  */
 	    pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
 
-	    if (is_ms_arch && (filename_cmp (pnt, ".dll") == 0))
+	    if (is_ms_arch && pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0))
 	      {
 		int idata2 = 0, reloc_count=0;
 		asection *sec;
@@ -1725,9 +1742,9 @@ static bool
 gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
 {
 #ifdef DLL_SUPPORT
-  const char *ext = entry->filename + strlen (entry->filename) - 4;
+  const char *ext = strrchr (entry->filename, '.');
 
-  if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0)
+  if (ext != NULL && fileext_cmp (ext + 1, "def") == 0)
     {
       pep_def_file = def_file_parse (entry->filename, pep_def_file);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-08-24 20:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-24 20:19 [binutils-gdb] ld: pe: Make archive member file extension comparisons case insensitive when cross compiling too Martin Storsjo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).