diff mbox series

V4 [PATCH 3/3] Require .init_array/.fini_array support for SHF_GNU_RETAIN

Message ID 20201215173031.3242097-4-hjl.tools@gmail.com
State New
Headers show
Series V4 [PATCH 3/3] Require .init_array/.fini_array support for SHF_GNU_RETAIN | expand

Commit Message

H.J. Lu Dec. 15, 2020, 5:30 p.m. UTC
Since SHF_GNU_RETAIN support doesn't work for crtstuff.c which switches
the output section directly with asm statement:

---
static void __attribute__((used))
__do_global_dtors_aux (void)
{
  static _Bool completed;

  if (__builtin_expect (completed, 0))
    return;
  completed = 1;
}

static void __attribute__((__used__))
call___do_global_dtors_aux (void)
{
  asm ("\t.section\t.fini");
  __do_global_dtors_aux ();
  asm ("\t.section\t.text");
}
---

use SHF_GNU_RETAIN only if .init_array/.fini_array section is supported.

gcc/

	PR target/98146
	* defaults.h (SUPPORTS_SHF_GNU_RETAIN): New.
	* varasm.c (get_section): Replace HAVE_GAS_SHF_GNU_RETAIN with
	SUPPORTS_SHF_GNU_RETAIN.
	(resolve_unique_section): Likewise.
	(get_variable_section): Likewise.
	(switch_to_section): Likewise.

gcc/testsuite/

	PR target/98146
	* lib/target-supports.exp
	(check_effective_target_R_flag_in_section): Also check
	HAVE_INITFINI_ARRAY_SUPPORT != 0.
---
 gcc/defaults.h                        | 11 +++++++++++
 gcc/testsuite/lib/target-supports.exp |  2 +-
 gcc/varasm.c                          |  8 ++++----
 3 files changed, 16 insertions(+), 5 deletions(-)

Comments

Jeff Law Dec. 16, 2020, 12:45 a.m. UTC | #1
On 12/15/20 10:30 AM, H.J. Lu wrote:
> Since SHF_GNU_RETAIN support doesn't work for crtstuff.c which switches
> the output section directly with asm statement:
>
> ---
> static void __attribute__((used))
> __do_global_dtors_aux (void)
> {
>   static _Bool completed;
>
>   if (__builtin_expect (completed, 0))
>     return;
>   completed = 1;
> }
>
> static void __attribute__((__used__))
> call___do_global_dtors_aux (void)
> {
>   asm ("\t.section\t.fini");
>   __do_global_dtors_aux ();
>   asm ("\t.section\t.text");
> }
> ---
>
> use SHF_GNU_RETAIN only if .init_array/.fini_array section is supported.
>
> gcc/
>
> 	PR target/98146
> 	* defaults.h (SUPPORTS_SHF_GNU_RETAIN): New.
> 	* varasm.c (get_section): Replace HAVE_GAS_SHF_GNU_RETAIN with
> 	SUPPORTS_SHF_GNU_RETAIN.
> 	(resolve_unique_section): Likewise.
> 	(get_variable_section): Likewise.
> 	(switch_to_section): Likewise.
>
> gcc/testsuite/
>
> 	PR target/98146
> 	* lib/target-supports.exp
> 	(check_effective_target_R_flag_in_section): Also check
> 	HAVE_INITFINI_ARRAY_SUPPORT != 0.
Ah.  I didn't realize that you added this to the V4 patch.  OK.

jeff
diff mbox series

Patch

diff --git a/gcc/defaults.h b/gcc/defaults.h
index f1a38626624..80a84dde2d6 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -286,6 +286,17 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #endif
 #endif
 
+/* This determines whether or not we support marking sections with
+   SHF_GNU_RETAIN flag.  Also require .init_array/.fini_array section
+   for constructors and destructors.  */
+#ifndef SUPPORTS_SHF_GNU_RETAIN
+#if HAVE_GAS_SHF_GNU_RETAIN && HAVE_INITFINI_ARRAY_SUPPORT
+#define SUPPORTS_SHF_GNU_RETAIN 1
+#else
+#define SUPPORTS_SHF_GNU_RETAIN 0
+#endif
+#endif
+
 /* This determines whether or not we support link-once semantics.  */
 #ifndef SUPPORTS_ONE_ONLY
 #ifdef MAKE_DECL_ONE_ONLY
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 3c02f763e7e..11343d0192f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10840,7 +10840,7 @@  proc check_effective_target_R_flag_in_section { } {
 
 	set f [open $src "w"]
 	puts $f "#include \"../../auto-host.h\""
-	puts $f "#if HAVE_GAS_SHF_GNU_RETAIN == 0"
+	puts $f "#if HAVE_GAS_SHF_GNU_RETAIN == 0 || HAVE_INITFINI_ARRAY_SUPPORT == 0"
 	puts $f "# error Assembler does not support 'R' flag in .section directive."
 	puts $f "#endif"
 	close $f
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 72d5379303a..46f79ea28e6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -293,7 +293,7 @@  get_section (const char *name, unsigned int flags, tree decl,
   slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
 					    INSERT);
   flags |= SECTION_NAMED;
-  if (HAVE_GAS_SHF_GNU_RETAIN
+  if (SUPPORTS_SHF_GNU_RETAIN
       && decl != nullptr
       && DECL_P (decl)
       && DECL_PRESERVE_P (decl))
@@ -483,7 +483,7 @@  resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
   if (DECL_SECTION_NAME (decl) == NULL
       && targetm_common.have_named_sections
       && (flag_function_or_data_sections
-	  || (HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))
+	  || (SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))
 	  || DECL_COMDAT_GROUP (decl)))
     {
       targetm.asm_out.unique_section (decl, reloc);
@@ -1223,7 +1223,7 @@  get_variable_section (tree decl, bool prefer_noswitch_p)
     vnode->get_constructor ();
 
   if (DECL_COMMON (decl)
-      && !(HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)))
+      && !(SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)))
     {
       /* If the decl has been given an explicit section name, or it resides
 	 in a non-generic address space, then it isn't common, and shouldn't
@@ -7752,7 +7752,7 @@  switch_to_section (section *new_section, tree decl)
 {
   if (in_section == new_section)
     {
-      if (HAVE_GAS_SHF_GNU_RETAIN
+      if (SUPPORTS_SHF_GNU_RETAIN
 	  && (new_section->common.flags & SECTION_NAMED)
 	  && decl != nullptr
 	  && DECL_P (decl)