[PATCH v3] ld: Make archive member file extension comparisons case insensitive when cross compiling too

Martin Storsjö martin@martin.st
Tue Aug 23 21:11:54 GMT 2022


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.
---
v3: Renamed the function to fileext_cmp as suggested. (This also fixes
building on Windows, where there already existed a non-static
function named stricmp.)
---
 ld/emultempl/pe.em  | 25 +++++++++++++++++++++----
 ld/emultempl/pep.em | 24 ++++++++++++++++++++----
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index ad969ccec13..c34ddebd489 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -171,6 +171,23 @@ static int is_underscoring (void)
   return pe_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 = TOLOWER (*s2++);
+
+      if (c1 != c2)
+        return (c1 - c2);
+
+      if (c1 == '\0')
+        return 0;
+    }
+}
+
 static void
 gld${EMULATION_NAME}_before_parse (void)
 {
@@ -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, ".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, ".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 && (fileext_cmp (pnt, ".dll") == 0))
 	      {
 		int idata2 = 0, reloc_count=0;
 		asection *sec;
@@ -1857,7 +1874,7 @@ gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBU
 #ifdef DLL_SUPPORT
   const char *ext = entry->filename + strlen (entry->filename) - 4;
 
-  if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0)
+  if (fileext_cmp (ext, ".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..ba4fc01ed70 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -181,6 +181,22 @@ 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 = TOLOWER (*s2++);
+
+      if (c1 != c2)
+        return (c1 - c2);
+
+      if (c1 == '\0')
+        return 0;
+    }
+}
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -1630,7 +1646,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, ".dll") == 0)
 		      break;
 		  }
 
@@ -1647,7 +1663,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, ".obj") == 0)
 			  continue;
 
 			if (filename_cmp (bfd_get_filename (is3->the_bfd),
@@ -1665,7 +1681,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 && (fileext_cmp (pnt, ".dll") == 0))
 	      {
 		int idata2 = 0, reloc_count=0;
 		asection *sec;
@@ -1727,7 +1743,7 @@ gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBU
 #ifdef DLL_SUPPORT
   const char *ext = entry->filename + strlen (entry->filename) - 4;
 
-  if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0)
+  if (fileext_cmp (ext, ".def") == 0)
     {
       pep_def_file = def_file_parse (entry->filename, pep_def_file);
 
-- 
2.25.1



More information about the Binutils mailing list