From patchwork Sat Sep 13 17:42:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 120197 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 63B063857B84 for ; Sat, 13 Sep 2025 17:43:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 63B063857B84 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=YzBxj+Qw X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id BD6923858D21 for ; Sat, 13 Sep 2025 17:42:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BD6923858D21 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BD6923858D21 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::634 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757785345; cv=none; b=keq2WjBtEh2T2T93tIAB7Onk2SLudGtuKEl+zEst/voTKfltDn0x9CKLTkjxsCiKVhIfgbbmKMGXDFIbv29cKbS03TTpCCw0NRtMlkqYCVDwgK7s8Fk7dPUdIUfTiRn6dEqZr/sdN/YDUv+/N9plMAAMTp0+B9RfJFPW1Wd6VbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757785345; c=relaxed/simple; bh=hN5BtgjIsWBGwvkCGKIt+zCFn41xFRJMrF5LCBxJg1o=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=nU/GLm86lOznb5vr+cEBIsoClR1TfkgMxTAPxZF5n+qXBb9fBSQf7lE2kyn4KwzD+MKGB1+DYC3URUviT2bNINzLt7CoF2/EDEFV30HeJeZvnaEprmnEdb0NmKoTTa9kVM3oFw5R0leiOHWlaYxWVcTvWmQPmlT6fgwB/6kBiQg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BD6923858D21 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-25d9c3fed22so16485945ad.2 for ; Sat, 13 Sep 2025 10:42:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757785344; x=1758390144; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=nGcqBFnj3ugHAwaXeCMwNzZj9ABDBh1anhMu71xCmtU=; b=YzBxj+Qw/4AJ0j8bVx2Pc2LlgXivwypy5UyGBwrVU25YELDClUeqLN323ff1tzHhjJ NJYe1Bi6B5+e3L+3eFWwiIQ54DCcvrixcrCQX0bPOksKSME487WZ/JwPnrb5XxViDrEG 7kAAiJnBXdDNZ1F7kAWp/l5lH59EHQan3J+XFi+dvIsWykxy8Z0F0QdY4kC/fSnILlAX 9jNPN6nMfq3Uz3lQ+La/+e7eu+N3+lmlXknawy0kY2+qO8tM0PQqWPinue9LZRuhQAsp ht8fESLIv42HEVR21tK0ZJOaaq693za0QtS2+4iyV4jxSzAy2yt/xKyV6/Fqcy8Ma8yc 7biA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757785344; x=1758390144; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=nGcqBFnj3ugHAwaXeCMwNzZj9ABDBh1anhMu71xCmtU=; b=g850tMWWpv04mjo4MdXBsocOkijSzu7gmAkzSeEdsjmPBVRm18bH0szbEuOyFy6D7i 6SgMwU/VLDy1YmjOBXr4TOU2M0uEUue4ks3byZfZYnT9cgL5oq8PUVZOo6vihrNAUZIf wJ/ormbOOFFZS/UQp5NcbWzNeCfGTNHJ5QcphMMMuqwPvECWakw0FrGj07FK4q6pTW8u AxpH7J0D1kkNw2ukr+ARyWFnml1aDNwTS1VLkXg8WMMh+Rdd5GpfXIEQE66rH1asNOOq MQ7grjuPytGdqkbY1mpIYzV1EFgITlieqbKoZcQ7oecBncRmp5qHqxWMnZkDFntA42Wn sQSA== X-Gm-Message-State: AOJu0Yx7kVPZdVPFgPL5mi8DPUFzEA96vdMrYrzzHTAVhokkA89qp4Sj bD58JeojiCcR6gdbKXSWoommfS+tCATb7/WKVE/bfa8U5nbbx0KOx15fzawc2g== X-Gm-Gg: ASbGncvxuHul9/I3hJ+7R0EHyhs0gWWb3qXs0Dt9Q3n1xqxTOggNoi2SMD+6d2g8Rzb 2za/C6tXmMW3HgZaKZStxqLG9ZacrgpRsKCPfeFsbyFcRe0loMZxbqy8YOI6WVPjPAwrsEW3nKH Ca9plGfssnwqmJtp20wt0m0biCpusrJFvhKK3RCl+HfA8YVOahfk5wPQG56FJsi1qr0MczHcCWk xuP25yf2ynvKKS/YNYrXNlOEPKNJX/ptfmboGLw7Hzl4kVJO6jj63L97Ow017hMQ95ibW8e/3Xp nezcBjYXM4/uC0m30uIIruK7s+xGI8HmINWxCVLpi4kgSfTjnl1r6weK+A5AQ4LOUdBEwaOvRBi lpAPWXVeSzC2p3IlGQWmP8H2JiiLDiJhXBcsIxgVQ+cHKc2B6Og== X-Google-Smtp-Source: AGHT+IHY/SXLznr9f+RUeRuaZOK8AaPPKoEHTh73iH9MpUVMy8X9IUUwxvgkUdJzkJmuoYX9xI6AdA== X-Received: by 2002:a17:902:f791:b0:246:ceda:ebeb with SMTP id d9443c01a7336-25d268652b7mr77141405ad.33.1757785344302; Sat, 13 Sep 2025 10:42:24 -0700 (PDT) Received: from gnu-cfl-3.localdomain ([172.59.160.12]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-25e9fdfba64sm43165135ad.104.2025.09.13.10.42.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Sep 2025 10:42:23 -0700 (PDT) Received: from gnu-cfl-3.localdomain (localhost [127.0.0.1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id E76C3740247; Sat, 13 Sep 2025 10:42:22 -0700 (PDT) From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: fweimer@redhat.com, jason@redhat.com, josmyers@redhat.com Subject: [PATCH] c/c++: Treat __stack_chk_guard as an internal symbol Date: Sat, 13 Sep 2025 10:42:17 -0700 Message-ID: <20250913174217.141258-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3014.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org Treat the user defined stack protect guard, __stack_chk_guard, as an internal C/C++ symbol and declare __stack_chk_guard as a size_t variable if size_t has the same size as pointer. If a user defined variable name is the same as the stack protect guard, use the predefined stack protect guard declaration and apply its visibility attribute to the internal __stack_chk_guard symbol. gcc/ PR c/121911 * targhooks.cc (default_stack_protect_guard): Use size_type_node if it has the same size as ptr_type_node. * varasm.cc (mark_stack_protect_guard_decl_local): New. * varasm.h (mark_stack_protect_guard_decl_local): Likewise. gcc/c-family/ PR c/121911 * c-attribs.cc (handle_visibility_attribute): Call mark_stack_protect_guard_decl_local as local for non-default visibility. gcc/c/ PR c/121911 * c-decl.cc (grokdeclarator): If the variable name is the same as the stack protect guard, use the stack protect guard decl. gcc/cp/ PR c/121911 * decl.cc (grokdeclarator): If the variable name is the same as the stack protect guard, use the stack protect guard decl. gcc/testsuite/ PR c/121911 * g++.target/i386/ssp-global-hidden-1.C: New test. * g++.target/i386/ssp-global-hidden-2.C: Likewise. * gcc.target/i386/ssp-global-hidden-1.c: Likewise. * gcc.target/i386/ssp-global-hidden-2.c: Likewise. Signed-off-by: H.J. Lu --- gcc/c-family/c-attribs.cc | 5 +++ gcc/c/c-decl.cc | 16 +++++++ gcc/cp/decl.cc | 15 +++++++ gcc/targhooks.cc | 7 ++- .../g++.target/i386/ssp-global-hidden-1.C | 45 +++++++++++++++++++ .../g++.target/i386/ssp-global-hidden-2.C | 19 ++++++++ .../gcc.target/i386/ssp-global-hidden-1.c | 45 +++++++++++++++++++ .../gcc.target/i386/ssp-global-hidden-2.c | 19 ++++++++ gcc/varasm.cc | 12 +++++ gcc/varasm.h | 1 + 10 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index 1e3a94ed949..8d76e81bf98 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -3652,6 +3652,11 @@ handle_visibility_attribute (tree *node, tree name, tree args, DECL_VISIBILITY (decl) = vis; DECL_VISIBILITY_SPECIFIED (decl) = 1; + /* Mark the symbol of DECL for non-default visibility as local if it + is the stack protect guard decl. */ + if (flag_stack_protect && vis != VISIBILITY_DEFAULT) + mark_stack_protect_guard_decl_local (decl); + /* Go ahead and attach the attribute to the node as well. This is needed so we can determine whether we have VISIBILITY_DEFAULT because the visibility was not specified, or because it was explicitly overridden diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index b122e82bfc4..89885593acc 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -8106,6 +8106,22 @@ grokdeclarator (const struct c_declarator *declarator, else { /* It's a variable. */ + + if (flag_stack_protect) + { + /* If the variable name is the same as the stack protect + guard, use the stack protect guard decl. */ + tree guard_decl = targetm.stack_protect_guard (); + if (guard_decl && VAR_P (guard_decl)) + { + const char *stack_protect_guard_name + = IDENTIFIER_POINTER (DECL_NAME (guard_decl)); + if (strcmp (stack_protect_guard_name, + IDENTIFIER_POINTER (declarator->u.id.id)) == 0) + return guard_decl; + } + } + /* An uninitialized decl with `extern' is a reference. */ int extern_ref = !initialized && storage_class == csc_extern; diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a6a98426ed9..2e6e935bcc9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -16233,6 +16233,21 @@ grokdeclarator (const cp_declarator *declarator, { /* It's a variable. */ + if (flag_stack_protect && dname && identifier_p (dname)) + { + /* If the variable name is the same as the stack protect + guard, use the stack protect guard decl. */ + tree guard_decl = targetm.stack_protect_guard (); + if (guard_decl && VAR_P (guard_decl)) + { + const char *stack_protect_guard_name + = IDENTIFIER_POINTER (DECL_NAME (guard_decl)); + if (strcmp (stack_protect_guard_name, + IDENTIFIER_POINTER (unqualified_id)) == 0) + return guard_decl; + } + } + /* An uninitialized decl with `extern' is a reference. */ decl = grokvardecl (type, dname, unqualified_id, declspecs, diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 947e39aedc1..fc24a6fd488 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -924,9 +924,14 @@ default_stack_protect_guard (void) { rtx x; + /* __stack_chk_guard is treated as an internal C/C++ symbol. Use + size_type_node if it has the same size as ptr_type_node since + __stack_chk_guard can be initialized as an integer. */ t = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ("__stack_chk_guard"), - ptr_type_node); + (TYPE_PRECISION (size_type_node) + == TYPE_PRECISION (ptr_type_node) + ? size_type_node : ptr_type_node)); TREE_STATIC (t) = 1; TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; diff --git a/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C new file mode 100644 index 00000000000..2f7a554ccbd --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C @@ -0,0 +1,45 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */ + +#include +#include + +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +extern "C" void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C new file mode 100644 index 00000000000..845cf550eb9 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C @@ -0,0 +1,19 @@ +/* { dg-do compile { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global" } */ + +#include + +__attribute__ ((visibility ("hidden"))) +extern const size_t __stack_chk_guard; + +void +smash (char *p, int i) +{ + p[i] = 42; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c new file mode 100644 index 00000000000..cf6af3971d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c @@ -0,0 +1,45 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */ + +#include +#include + +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c new file mode 100644 index 00000000000..845cf550eb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global" } */ + +#include + +__attribute__ ((visibility ("hidden"))) +extern const size_t __stack_chk_guard; + +void +smash (char *p, int i) +{ + p[i] = 42; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 0d78f5b384f..5b54293dc1e 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -2920,6 +2920,18 @@ mark_decl_referenced (tree decl) which do not need to be marked. */ } +/* Mark the symbol of DECL as local if it is the stack protect guard + decl. */ + +void +mark_stack_protect_guard_decl_local (tree decl) +{ + if (decl != targetm.stack_protect_guard ()) + return; + rtx symbol = DECL_RTL (decl); + symbol = XEXP (symbol, 0); + SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL; +} /* Output to FILE (an assembly file) a reference to NAME. If NAME starts with a *, the rest of NAME is output verbatim. Otherwise diff --git a/gcc/varasm.h b/gcc/varasm.h index fc31c1bbf65..33171999496 100644 --- a/gcc/varasm.h +++ b/gcc/varasm.h @@ -41,6 +41,7 @@ extern void process_pending_assemble_externals (void); extern bool decl_replaceable_p (tree, bool); extern bool decl_binds_to_current_def_p (const_tree); extern enum tls_model decl_default_tls_model (const_tree); +extern void mark_stack_protect_guard_decl_local (tree); /* Declare DECL to be a weak symbol. */ extern void declare_weak (tree);