From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by sourceware.org (Postfix) with ESMTPS id CC2EE3858C33 for ; Wed, 24 Aug 2022 10:47:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CC2EE3858C33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=martin.st Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=martin.st Received: by mail-lf1-x12c.google.com with SMTP id m5so12758530lfj.4 for ; Wed, 24 Aug 2022 03:47:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=martin-st.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc; bh=VxnmERjsVAXIuW+AYQtADJhWnc2bUIYE1+TyXFybtkQ=; b=iPRc1gBZb86LjIV4Lis+aBOUSw2Qay3W0Hzpe/Z2+ev8/Dk1JtZQlfbF+aCr7Tra3O YuszITJBzkuAB1OGLjza08Y5YjFc88qqXfFwHBbVjG5tiE8yxh5ov4xLF7tPPvbFQ6+z S24Df8W/Ej11r6yRMbPI9wJtToHpQJj9TWhENJYVCSBwcgpJ8FXNUppFeGNk+6sCtu3Z De+X9JZn38+fwp9U91iimGIIKkpCk1XwVKyWanAbl7oN2E1tnGsLTE22METuuqkIx2e+ xJtLcew2c/Tl0TIgxgEgGRbLB295LqslvF1aS31VoVXW4dEWO5+M/UEKOo1OLmKpF4Xz D7FA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc; bh=VxnmERjsVAXIuW+AYQtADJhWnc2bUIYE1+TyXFybtkQ=; b=IfI5QScvgpTHiOXcUrP3Ut2Z275zV13nFPaT9nyh8wGb8JdiEqk202IAp/69J7JjcQ wzsxD1gmbqSRDausOdYnaGr82JREJkp9PjW4EOFkiOhRdrQ3ReQbwqlMFqsu9Nd+lR5V NhztyP0oPiGjNBbH/s8c4uXPl5hrXvT49XP8Hm4pUHNHiBkrv0gPV2xmS10ulevgON3H pvjUKffognJ7hDAGy8SaqWEkst/thaQs1hndBuzzGlxEnELgGC+JYbH8oz7GiMS4Kbt5 NljpxC+NEWDZeyNgX2cpz3wANSe20YJqaHTN5hZGxSyYaT72zCzJE96YbfZDtoPHZrfk PISA== X-Gm-Message-State: ACgBeo0YY2EiYzwdVOrSIWmkY5IvTq0qsMgrVGt5EwCcDP3DQo0MSQZv qlWa2oseuF1tBd0UCa7ODGepWzyDW1eSMWwx X-Google-Smtp-Source: AA6agR4hiHuOXS/mGs07tJysCuH/HtMgAaJTQJyvcHL1I9fycFeonPerIrRZoTTsTt3ggzhc11QoPQ== X-Received: by 2002:a05:6512:3984:b0:492:da1b:9683 with SMTP id j4-20020a056512398400b00492da1b9683mr6446100lfu.58.1661338068392; Wed, 24 Aug 2022 03:47:48 -0700 (PDT) Received: from localhost.localdomain (dsl-tkubng21-58c01c-243.dhcp.inet.fi. [88.192.28.243]) by smtp.gmail.com with ESMTPSA id j9-20020a056512344900b00492cbbbd18fsm2547210lfr.273.2022.08.24.03.47.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Aug 2022 03:47:47 -0700 (PDT) From: =?UTF-8?q?Martin=20Storsj=C3=B6?= To: binutils@sourceware.org Subject: [PATCH v6] ld: Make archive member file extension comparisons case insensitive when cross compiling too Date: Wed, 24 Aug 2022 13:47:47 +0300 Message-Id: <20220824104747.11804-1-martin@martin.st> X-Mailer: git-send-email 2.25.1 In-Reply-To: <9b767c3b-2690-863c-e7dd-17fa477ee482@martin.st> References: <9b767c3b-2690-863c-e7dd-17fa477ee482@martin.st> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,GIT_PATCH_0,JMQ_SPF_NEUTRAL,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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. --- v6: Switch the check for .def extension to use strrchr, add a missed null pointer check at the third call site. --- ld/emultempl/pe.em | 32 +++++++++++++++++++++++++++----- ld/emultempl/pep.em | 32 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index ad969ccec13..03c261e89c6 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -534,6 +534,28 @@ 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. 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 set_pe_name (char *name, long val) @@ -1666,7 +1688,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 +1705,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 +1723,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, "dll") == 0)) { int idata2 = 0, reloc_count=0; asection *sec; @@ -1855,9 +1877,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, "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..239f830edbb 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 && pnt != NULL && (fileext_cmp (pnt, "dll") == 0)) { int idata2 = 0, reloc_count=0; asection *sec; @@ -1725,9 +1747,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, "def") == 0) { pep_def_file = def_file_parse (entry->filename, pep_def_file); -- 2.25.1