[PATCH v5] ld: Make archive member file extension comparisons case insensitive when cross compiling too
Martin Storsjö
martin@martin.st
Wed Aug 24 10:04:33 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.
---
v5: Moved the function name to a separate line, added double spaces
before the closing of comments.
---
ld/emultempl/pe.em | 31 +++++++++++++++++++++++++++----
ld/emultempl/pep.em | 30 ++++++++++++++++++++++++++----
2 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index ad969ccec13..d51bf4d3abb 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -171,6 +171,29 @@ static int is_underscoring (void)
return pe_leading_underscore;
}
+/* A case insensitive comparison, regardless of the host platform, used for
+ comparing file extensions. Parameter s1 points at the extension in a file
+ name (pointing at the starting '.'). Parameter s2 is a lower case string
+ without the leading '.'. */
+static int
+fileext_cmp (const char *s1, const char *s2)
+{
+ if (*s1 != '.')
+ return 1;
+ s1++;
+ 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)
{
@@ -1666,7 +1689,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 +1706,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 +1724,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 +1880,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..f060bf092ed 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -181,6 +181,28 @@ static int is_underscoring (void)
return pep_leading_underscore;
}
+/* A case insensitive comparison, regardless of the host platform, used for
+ comparing file extensions. Parameter s1 points at the extension in a file
+ name (pointing at the starting '.'). Parameter s2 is a lower case string
+ without the leading '.'. */
+static int
+fileext_cmp (const char *s1, const char *s2)
+{
+ if (*s1 != '.')
+ return 1;
+ s1++;
+ 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 +1652,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 +1669,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 +1687,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 +1749,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