public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Jeff Law <law@redhat.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
	Jozef Lawrynowicz <jozef.l@mittosystems.com>
Subject: Re: V4 [PATCH 1/3] Switch to a new section if the SECTION_RETAIN bit doesn't match
Date: Wed, 16 Dec 2020 05:01:24 -0800	[thread overview]
Message-ID: <CAMe9rOo+YyC2wVx3_G1n7VbCuSOGG3ZD+yECFOtJ_nJfqd+U9Q@mail.gmail.com> (raw)
In-Reply-To: <2b92f4e4-a0d1-0269-02d8-328ce76d17d3@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2345 bytes --]

On Tue, Dec 15, 2020 at 4:44 PM Jeff Law <law@redhat.com> wrote:
>
>
>
> On 12/15/20 10:30 AM, H.J. Lu wrote:
> > When definitions marked with used attribute and unmarked definitions are
> > placed in the section with the same name, switch to a new section if the
> > SECTION_RETAIN bit doesn't match.
> >
> > gcc/
> >
> >       PR target/98146
> >       * output.h (switch_to_section): Add a tree argument, default to
> >       nullptr.
> >       * varasm.c (get_section): If the SECTION_RETAIN bit doesn't match,
> >       return and switch to a new section later.
> >       (assemble_start_function): Pass decl to switch_to_section.
> >       (assemble_variable): Likewise.
> >       (switch_to_section): If the SECTION_RETAIN bit doesn't match,
> >       switch to a new section.
> >
> > gcc/testsuite/
> >
> >       PR target/98146
> >       * c-c++-common/attr-used-5.c: New test.
> >       * c-c++-common/attr-used-6.c: Likewise.
> >       * c-c++-common/attr-used-7.c: Likewise.
> >       * c-c++-common/attr-used-8.c: Likewise.
> >       * c-c++-common/attr-used-9.c: Likewise.
> So as an additional follow-up could you add to the get_section comment
> the special handling were add SECTION_WRITE and SECTION_RELRO to the
> flags.  That's not something I would expect that function to do either.
> Consider that comment addition pre-approved.
>

I am checking the patch with this change:

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 46f79ea28e6..267a052331d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -282,7 +282,11 @@ get_noswitch_section (unsigned int flags,
noswitch_section_callback callback)
 /* Return the named section structure associated with NAME.  Create
    a new section with the given fields if no such structure exists.
    When NOT_EXISTING, then fail if the section already exists.  Return
-   the existing section if the SECTION_RETAIN bit doesn't match.  */
+   the existing section if the SECTION_RETAIN bit doesn't match.  Set
+   the SECTION_WRITE | SECTION_RELRO bits on the the existing section
+   if one of the section flags is SECTION_WRITE | SECTION_RELRO and the
+   other has none of these flags in named sections and either the section
+   hasn't been declared yet or has been declared as writable.  */

 section *
 get_section (const char *name, unsigned int flags, tree decl,

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-Switch-to-a-new-section-if-the-SECTION_RETAIN-bit-do.patch --]
[-- Type: text/x-patch, Size: 9429 bytes --]

From 22c1d0be1399becffac58d7509ab30a8ecd97a9a Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 3 Dec 2020 11:01:06 -0800
Subject: [PATCH] Switch to a new section if the SECTION_RETAIN bit doesn't
 match

When definitions marked with used attribute and unmarked definitions are
placed in the section with the same name, switch to a new section if the
SECTION_RETAIN bit doesn't match.

gcc/

	PR target/98146
	* output.h (switch_to_section): Add a tree argument, default to
	nullptr.
	* varasm.c (get_section): If the SECTION_RETAIN bit doesn't match,
	return and switch to a new section later.
	(assemble_start_function): Pass decl to switch_to_section.
	(assemble_variable): Likewise.
	(switch_to_section): If the SECTION_RETAIN bit doesn't match,
	switch to a new section.

gcc/testsuite/

	PR target/98146
	* c-c++-common/attr-used-5.c: New test.
	* c-c++-common/attr-used-6.c: Likewise.
	* c-c++-common/attr-used-7.c: Likewise.
	* c-c++-common/attr-used-8.c: Likewise.
	* c-c++-common/attr-used-9.c: Likewise.
---
 gcc/output.h                             |  2 +-
 gcc/testsuite/c-c++-common/attr-used-5.c | 26 ++++++++++++++++
 gcc/testsuite/c-c++-common/attr-used-6.c | 26 ++++++++++++++++
 gcc/testsuite/c-c++-common/attr-used-7.c |  8 +++++
 gcc/testsuite/c-c++-common/attr-used-8.c |  8 +++++
 gcc/testsuite/c-c++-common/attr-used-9.c | 28 +++++++++++++++++
 gcc/varasm.c                             | 38 ++++++++++++++++++++----
 7 files changed, 130 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/attr-used-5.c
 create mode 100644 gcc/testsuite/c-c++-common/attr-used-6.c
 create mode 100644 gcc/testsuite/c-c++-common/attr-used-7.c
 create mode 100644 gcc/testsuite/c-c++-common/attr-used-8.c
 create mode 100644 gcc/testsuite/c-c++-common/attr-used-9.c

diff --git a/gcc/output.h b/gcc/output.h
index fa8ace1f394..1f9af46da1d 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -548,7 +548,7 @@ extern void switch_to_other_text_partition (void);
 extern section *get_cdtor_priority_section (int, bool);
 
 extern bool unlikely_text_section_p (section *);
-extern void switch_to_section (section *);
+extern void switch_to_section (section *, tree = nullptr);
 extern void output_section_asm_op (const void *);
 
 extern void record_tm_clone_pair (tree, tree);
diff --git a/gcc/testsuite/c-c++-common/attr-used-5.c b/gcc/testsuite/c-c++-common/attr-used-5.c
new file mode 100644
index 00000000000..9fc0d3834e9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-5.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+struct dtv_slotinfo_list
+{
+  struct dtv_slotinfo_list *next;
+};
+
+extern struct dtv_slotinfo_list *list;
+
+static int __attribute__ ((section ("__libc_freeres_fn")))
+free_slotinfo (struct dtv_slotinfo_list **elemp)
+{
+  if (!free_slotinfo (&(*elemp)->next))
+    return 0;
+  return 1;
+}
+
+__attribute__ ((used, section ("__libc_freeres_fn")))
+static void free_mem (void)
+{
+  free_slotinfo (&list);
+}
+
+/* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */
+/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-6.c b/gcc/testsuite/c-c++-common/attr-used-6.c
new file mode 100644
index 00000000000..0cb82ade5a9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-6.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+struct dtv_slotinfo_list
+{
+  struct dtv_slotinfo_list *next;
+};
+
+extern struct dtv_slotinfo_list *list;
+
+static int __attribute__ ((used, section ("__libc_freeres_fn")))
+free_slotinfo (struct dtv_slotinfo_list **elemp)
+{
+  if (!free_slotinfo (&(*elemp)->next))
+    return 0;
+  return 1;
+}
+
+__attribute__ ((section ("__libc_freeres_fn")))
+void free_mem (void)
+{
+  free_slotinfo (&list);
+}
+
+/* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */
+/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-7.c b/gcc/testsuite/c-c++-common/attr-used-7.c
new file mode 100644
index 00000000000..fba2706ffc1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-7.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+int __attribute__((used,section(".data.foo"))) foo2 = 2;
+int __attribute__((section(".data.foo"))) foo1 = 1;
+
+/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
+/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-8.c b/gcc/testsuite/c-c++-common/attr-used-8.c
new file mode 100644
index 00000000000..4da4aabe573
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-8.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+int __attribute__((section(".data.foo"))) foo1 = 1;
+int __attribute__((used,section(".data.foo"))) foo2 = 2;
+
+/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
+/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-9.c b/gcc/testsuite/c-c++-common/attr-used-9.c
new file mode 100644
index 00000000000..cf3bde67622
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-9.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+struct dtv_slotinfo_list
+{
+  struct dtv_slotinfo_list *next;
+};
+
+extern struct dtv_slotinfo_list *list;
+
+static int __attribute__ ((used, section ("__libc_freeres_fn")))
+free_slotinfo (struct dtv_slotinfo_list **elemp)
+{
+  if (!free_slotinfo (&(*elemp)->next))
+    return 0;
+  return 1;
+}
+
+__attribute__ ((section ("__libc_freeres_fn")))
+static void free_mem (void)
+/* { dg-warning "defined but not used" "" { target *-*-* } .-1 } */
+{
+  free_slotinfo (&list);
+}
+
+/* { dg-final { scan-assembler-not "__libc_freeres_fn\n" } } */
+/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */
+/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index c5487a78b13..cfec870e067 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -281,7 +281,12 @@ get_noswitch_section (unsigned int flags, noswitch_section_callback callback)
 
 /* Return the named section structure associated with NAME.  Create
    a new section with the given fields if no such structure exists.
-   When NOT_EXISTING, then fail if the section already exists.  */
+   When NOT_EXISTING, then fail if the section already exists.  Return
+   the existing section if the SECTION_RETAIN bit doesn't match.  Set
+   the SECTION_WRITE | SECTION_RELRO bits on the the existing section
+   if one of the section flags is SECTION_WRITE | SECTION_RELRO and the
+   other has none of these flags in named sections and either the section
+   hasn't been declared yet or has been declared as writable.  */
 
 section *
 get_section (const char *name, unsigned int flags, tree decl,
@@ -343,6 +348,11 @@ get_section (const char *name, unsigned int flags, tree decl,
 	      sect->common.flags |= (SECTION_WRITE | SECTION_RELRO);
 	      return sect;
 	    }
+	  /* If the SECTION_RETAIN bit doesn't match, return and switch
+	     to a new section later.  */
+	  if ((sect->common.flags & SECTION_RETAIN)
+	      != (flags & SECTION_RETAIN))
+	    return sect;
 	  /* Sanity check user variables for flag changes.  */
 	  if (sect->named.decl != NULL
 	      && DECL_P (sect->named.decl)
@@ -1879,7 +1889,7 @@ assemble_start_function (tree decl, const char *fnname)
 
   /* Switch to the correct text section for the start of the function.  */
 
-  switch_to_section (function_section (decl));
+  switch_to_section (function_section (decl), decl);
   if (crtl->has_bb_partition && !hot_label_written)
     ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_label);
 
@@ -2375,7 +2385,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
 	  && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
 	handle_vtv_comdat_section (sect, decl);
       else
-	switch_to_section (sect);
+	switch_to_section (sect, decl);
       if (align > BITS_PER_UNIT)
 	ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
       assemble_variable_contents (decl, name, dont_output_data,
@@ -7742,10 +7752,28 @@ output_section_asm_op (const void *directive)
    the current section is NEW_SECTION.  */
 
 void
-switch_to_section (section *new_section)
+switch_to_section (section *new_section, tree decl)
 {
   if (in_section == new_section)
-    return;
+    {
+      if (HAVE_GAS_SHF_GNU_RETAIN
+	  && (new_section->common.flags & SECTION_NAMED)
+	  && decl != nullptr
+	  && DECL_P (decl)
+	  && (!!DECL_PRESERVE_P (decl)
+	      != !!(new_section->common.flags & SECTION_RETAIN)))
+	{
+	  /* If the SECTION_RETAIN bit doesn't match, switch to a new
+	     section.  */
+	  if (DECL_PRESERVE_P (decl))
+	    new_section->common.flags |= SECTION_RETAIN;
+	  else
+	    new_section->common.flags &= ~(SECTION_RETAIN
+					   | SECTION_DECLARED);
+	}
+      else
+	return;
+    }
 
   if (new_section->common.flags & SECTION_FORGET)
     in_section = NULL;
-- 
2.29.2


  reply	other threads:[~2020-12-16 13:02 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-15 17:30 V4 [PATCH 0/3] " H.J. Lu
2020-12-15 17:30 ` V4 [PATCH 1/3] " H.J. Lu
2020-12-16  0:44   ` Jeff Law
2020-12-16 13:01     ` H.J. Lu [this message]
2020-12-15 17:30 ` V4 [PATCH 2/3] Warn used and not used symbols in section with the same name H.J. Lu
2020-12-16  0:44   ` Jeff Law
2020-12-15 17:30 ` V4 [PATCH 3/3] Require .init_array/.fini_array support for SHF_GNU_RETAIN H.J. Lu
2020-12-16  0:45   ` Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAMe9rOo+YyC2wVx3_G1n7VbCuSOGG3ZD+yECFOtJ_nJfqd+U9Q@mail.gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jozef.l@mittosystems.com \
    --cc=law@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).