public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Use the section flag 'o' for __patchable_function_entries
@ 2020-02-07  2:57 H.J. Lu
  2020-10-02 13:00 ` PING: " H.J. Lu
  0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2020-02-07  2:57 UTC (permalink / raw)
  To: gcc-patches

This commit in GNU binutils 2.35:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=b7d072167715829eed0622616f6ae0182900de3e

added the section flag 'o' to .section directive:

.section __patchable_function_entries,"awo",@progbits,foo

which specifies the symbol name which the section references.  Assembler
creates a unique __patchable_function_entries section with the section,
where foo is defined, as its linked-to section.  Linker keeps a section
if its linked-to section is kept during garbage collection.

This patch checks assembler support for the section flag 'o' and uses
it to implement __patchable_function_entries section.  Since Solaris may
use GNU assembler with Solairs ld.  Even if GNU assembler supports the
section flag 'o', it doesn't mean that Solairs ld supports it.  This
feature is disabled for Solairs targets.

gcc/

	PR middle-end/93195
	PR middle-end/93197
	* configure.ac (HAVE_GAS_SECTION_LINK_ORDER): New.  Define if
	the assembler supports the section flag 'o' for specifying
	section with link-order.
	* dwarf2out.c (output_comdat_type_unit): Pass 0 as flags2
	to targetm.asm_out.named_section.
	* config/sol2.c (solaris_elf_asm_comdat_section): Likewise.
	* output.h (SECTION2_LINK_ORDER): New.
	(switch_to_section): Add an unsigned int argument.
	(default_no_named_section): Likewise.
	(default_elf_asm_named_section): Likewise.
	* target.def (asm_out.named_section): Likewise.
	* targhooks.c (default_print_patchable_function_entry): Pass
	current_function_decl to get_section and SECTION2_LINK_ORDER
	to switch_to_section.
	* varasm.c (default_no_named_section): Add an unsigned int
	argument.
	(default_elf_asm_named_section): Add an unsigned int argument,
	flags2.  Use 'o' flag for SECTION2_LINK_ORDER if assembler
	supports it.
	(switch_to_section): Add an unsigned int argument and pass it
	to targetm.asm_out.named_section.
	(handle_vtv_comdat_section): Pass 0 to
	targetm.asm_out.named_section.
	* config.in: Regenerated.
	* configure: Likewise.
	* doc/tm.texi: Likewise.

gcc/testsuite/

	PR middle-end/93195
	* g++.dg/pr93195a.C: New test.
	* g++.dg/pr93195b.C: Likewise.
	* lib/target-supports.exp
	(check_effective_target_o_flag_in_section): New proc.
---
 gcc/config.in                         |  6 ++++
 gcc/config/sol2.c                     |  3 +-
 gcc/configure                         | 52 +++++++++++++++++++++++++++
 gcc/configure.ac                      | 22 ++++++++++++
 gcc/doc/tm.texi                       |  5 +--
 gcc/dwarf2out.c                       |  4 +--
 gcc/output.h                          | 11 ++++--
 gcc/target.def                        |  5 +--
 gcc/targhooks.c                       |  4 ++-
 gcc/testsuite/g++.dg/pr93195a.C       | 27 ++++++++++++++
 gcc/testsuite/g++.dg/pr93195b.C       | 14 ++++++++
 gcc/testsuite/lib/target-supports.exp | 40 +++++++++++++++++++++
 gcc/varasm.c                          | 25 ++++++++++---
 13 files changed, 202 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr93195a.C
 create mode 100644 gcc/testsuite/g++.dg/pr93195b.C

diff --git a/gcc/config.in b/gcc/config.in
index 48292861842..d1ecc5b15a6 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1313,6 +1313,12 @@
 #endif
 
 
+/* Define if your assembler supports 'o' flag in .section directive. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_SECTION_LINK_ORDER
+#endif
+
+
 /* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
    */
 #ifndef USED_FOR_TARGET
diff --git a/gcc/config/sol2.c b/gcc/config/sol2.c
index cf9d9f1f684..62bbdec2f97 100644
--- a/gcc/config/sol2.c
+++ b/gcc/config/sol2.c
@@ -224,7 +224,8 @@ solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
      emits this as a regular section.  Emit section before .group
      directive since Sun as treats undeclared sections as @progbits,
      which conflicts with .bss* sections which are @nobits.  */
-  targetm.asm_out.named_section (section, flags & ~SECTION_LINKONCE, decl);
+  targetm.asm_out.named_section (section, flags & ~SECTION_LINKONCE,
+				 0, decl);
   
   /* Sun as separates declaration of a group section and of the group
      itself, using the .group directive and the #comdat flag.  */
diff --git a/gcc/configure b/gcc/configure
index 5fa565a40a4..a7315e33a62 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -24185,6 +24185,58 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# Test if the assembler supports the section flag 'o' for specifying
+# section with link-order.
+case "${target}" in
+  # Solaris may use GNU assembler with Solairs ld.  Even if GNU
+  # assembler supports the section flag 'o', it doesn't mean that
+  # Solairs ld supports it.
+  *-*-solaris2*)
+    gcc_cv_as_section_link_order=no
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'o' flag" >&5
+$as_echo_n "checking assembler for section 'o' flag... " >&6; }
+if ${gcc_cv_as_section_link_order+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_section_link_order=no
+    if test $in_tree_gas = yes; then
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 35 \) \* 1000 + 0`
+  then gcc_cv_as_section_link_order=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    $as_echo '.section .foo,"a"
+.byte 0
+.section __patchable_function_entries,"awo",%progbits,.foo
+.byte 0' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_section_link_order=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_link_order" >&5
+$as_echo "$gcc_cv_as_section_link_order" >&6; }
+
+
+    ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_SECTION_LINK_ORDER `if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5
 $as_echo_n "checking assembler for section merging support... " >&6; }
 if ${gcc_cv_as_shf_merge+:} false; then :
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 671b9a67d81..5619736ee0c 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3199,6 +3199,28 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_EXCLUDE,
   [`if test $gcc_cv_as_section_exclude_e = yes || test $gcc_cv_as_section_exclude_hash = yes; then echo 1; else echo 0; fi`],
 [Define if your assembler supports specifying the exclude section flag.])
 
+# Test if the assembler supports the section flag 'o' for specifying
+# section with link-order.
+case "${target}" in
+  # Solaris may use GNU assembler with Solairs ld.  Even if GNU
+  # assembler supports the section flag 'o', it doesn't mean that
+  # Solairs ld supports it.
+  *-*-solaris2*)
+    gcc_cv_as_section_link_order=no
+    ;;
+  *)
+    gcc_GAS_CHECK_FEATURE([section 'o' flag], gcc_cv_as_section_link_order,
+      [2,35,0], [--fatal-warnings],
+      [.section .foo,"a"
+.byte 0
+.section __patchable_function_entries,"awo",%progbits,.foo
+.byte 0])
+    ;;
+esac
+AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_LINK_ORDER,
+  [`if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`],
+  [Define if your assembler supports 'o' flag in .section directive.])
+
 gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
  [elf,2,12,0], [--fatal-warnings],
  [.section .rodata.str, "aMS", @progbits, 1])
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 19985adac3e..f50ce812a1d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -8003,9 +8003,10 @@ the assembler source.  So you can use it to canonicalize the format
 of the filename using this macro.
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_ASM_NAMED_SECTION (const char *@var{name}, unsigned int @var{flags}, tree @var{decl})
+@deftypefn {Target Hook} void TARGET_ASM_NAMED_SECTION (const char *@var{name}, unsigned int @var{flags}, unsigned int @var{flags2}, tree @var{decl})
 Output assembly directives to switch to section @var{name}.  The section
-should have attributes as specified by @var{flags}, which is a bit mask
+should have attributes as specified by @var{flags} and @var{flags2},
+which are bit masks
 of the @code{SECTION_*} flags defined in @file{output.h}.  If @var{decl}
 is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index fe46c7e1eee..1b0dd2364bb 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -11303,7 +11303,7 @@ output_comdat_type_unit (comdat_type_node *node,
   comdat_key = get_identifier (tmp);
   targetm.asm_out.named_section (secname,
                                  SECTION_DEBUG | SECTION_LINKONCE,
-                                 comdat_key);
+				 0, comdat_key);
 #else
   tmp = XALLOCAVEC (char, 18 + DWARF_TYPE_SIGNATURE_SIZE * 2);
   sprintf (tmp, (dwarf_version >= 5
@@ -28511,7 +28511,7 @@ output_macinfo (const char *debug_line_label, bool early_lto_debug)
 					 | SECTION_LINKONCE
 					 | (early_lto_debug
 					    ? SECTION_EXCLUDE : 0),
-					 comdat_key);
+					 0, comdat_key);
 	  ASM_GENERATE_INTERNAL_LABEL (label,
 				       DEBUG_MACRO_SECTION_LABEL,
 				       ref->lineno + macinfo_label_base);
diff --git a/gcc/output.h b/gcc/output.h
index eb253c50329..becbeadc8ea 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -396,6 +396,9 @@ extern void no_asm_to_stream (FILE *);
    to declare the object.  */
 #define SECTION_NOSWITCH 0x400000
 
+/* Flags2 controlling properties of a section.  */
+#define SECTION2_LINK_ORDER	0x00000001 /* section needs link-order.  */
+
 /* A helper function for default_elf_select_section and
    default_elf_unique_section.  Categorizes the DECL.  */
 
@@ -542,7 +545,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 *, unsigned int = 0);
 extern void output_section_asm_op (const void *);
 
 extern void record_tm_clone_pair (tree, tree);
@@ -557,8 +560,10 @@ extern unsigned int default_section_type_flags (tree, const char *, int);
 extern bool have_global_bss_p (void);
 extern bool bss_initializer_p (const_tree, bool = false);
 
-extern void default_no_named_section (const char *, unsigned int, tree);
-extern void default_elf_asm_named_section (const char *, unsigned int, tree);
+extern void default_no_named_section (const char *, unsigned int,
+				      unsigned int, tree);
+extern void default_elf_asm_named_section (const char *, unsigned int,
+					   unsigned int, tree);
 extern enum section_category categorize_decl_for_section (const_tree, int);
 extern void default_coff_asm_named_section (const char *, unsigned int, tree);
 extern void default_pe_asm_named_section (const char *, unsigned int, tree);
diff --git a/gcc/target.def b/gcc/target.def
index b5e82ff826e..97d53c909cf 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -414,11 +414,12 @@ described below.",
 DEFHOOK
 (named_section,
  "Output assembly directives to switch to section @var{name}.  The section\n\
-should have attributes as specified by @var{flags}, which is a bit mask\n\
+should have attributes as specified by @var{flags} and @var{flags2},\n\
+which are bit masks\n\
 of the @code{SECTION_*} flags defined in @file{output.h}.  If @var{decl}\n\
 is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which\n\
 this section is associated.",
- void, (const char *name, unsigned int flags, tree decl),
+ void, (const char *name, unsigned int flags, unsigned int flags2, tree decl),
  default_no_named_section)
 
 /* Tell assembler what section attributes to assign this elf section
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 7cb04f30bdb..0bae7bad1d4 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1811,7 +1811,9 @@ default_print_patchable_function_entry (FILE *file,
       ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
 
       switch_to_section (get_section ("__patchable_function_entries",
-				      SECTION_WRITE | SECTION_RELRO, NULL));
+				      SECTION_WRITE | SECTION_RELRO,
+				      current_function_decl),
+			 SECTION2_LINK_ORDER);
       assemble_align (POINTER_SIZE);
       fputs (asm_op, file);
       assemble_name_raw (file, buf);
diff --git a/gcc/testsuite/g++.dg/pr93195a.C b/gcc/testsuite/g++.dg/pr93195a.C
new file mode 100644
index 00000000000..26d265da74e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr93195a.C
@@ -0,0 +1,27 @@
+/* { dg-do link { target { ! { nvptx*-*-* visium-*-* } } } } */
+// { dg-require-effective-target o_flag_in_section }
+/* { dg-options "-O0 -fpatchable-function-entry=1" } */
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
+/* { dg-additional-sources pr93195b.C } */
+
+extern void bar1 (void);
+
+inline void
+foo (void)
+{
+}
+
+void
+bar (void)
+{
+  foo ();
+  bar1 ();
+}
+
+int
+main ()
+{
+  bar ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/pr93195b.C b/gcc/testsuite/g++.dg/pr93195b.C
new file mode 100644
index 00000000000..303d8588c0f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr93195b.C
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
+/* { dg-options "-O0 -fpatchable-function-entry=1" } */
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
+
+inline void
+foo (void)
+{
+}
+
+void
+bar1 (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index d3b2798df3e..ca3835204eb 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -9872,3 +9872,43 @@ proc check_effective_target_indirect_calls { } {
   }
   return 1
 }
+
+# Return 1 if this target supports 'o' flag in .section directive, 0
+# otherwise.  Cache the result.
+
+proc check_effective_target_o_flag_in_section { } {
+    global tool
+    global GCC_UNDER_TEST
+
+    # Need auto-host.h to check linker support.
+    if { ![file exists ../../auto-host.h ] } {
+	return 0
+    }
+
+    return [check_cached_effective_target o_flag_in_section {
+
+	set src pie[pid].c
+	set obj pie[pid].o
+
+	set f [open $src "w"]
+	puts $f "#include \"../../auto-host.h\""
+	puts $f "#if HAVE_GAS_SECTION_LINK_ORDER == 0"
+	puts $f "# error Assembler does not support 'o' flag in .section directive."
+	puts $f "#endif"
+	close $f
+
+	verbose "check_effective_target_o_flag_in_section compiling testfile $src" 2
+	set lines [${tool}_target_compile $src $obj object ""]
+
+	file delete $src
+	file delete $obj
+
+	if [string match "" $lines] then {
+	    verbose "check_effective_target_o_flag_in_section testfile compilation passed" 2
+	    return 1
+	} else {
+	    verbose "check_effective_target_o_flag_in_section testfile compilation failed" 2
+	    return 0
+	}
+    }]
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index dc6da6c0b5b..8c9dc9dd476 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6507,6 +6507,7 @@ have_global_bss_p (void)
 void
 default_no_named_section (const char *name ATTRIBUTE_UNUSED,
 			  unsigned int flags ATTRIBUTE_UNUSED,
+			  unsigned int flags2 ATTRIBUTE_UNUSED,
 			  tree decl ATTRIBUTE_UNUSED)
 {
   /* Some object formats don't support named sections at all.  The
@@ -6520,7 +6521,7 @@ default_no_named_section (const char *name ATTRIBUTE_UNUSED,
 
 void
 default_elf_asm_named_section (const char *name, unsigned int flags,
-			       tree decl)
+			       unsigned int flags2, tree decl)
 {
   char flagchars[11], *f = flagchars;
   unsigned int numeric_value = 0;
@@ -6562,6 +6563,10 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 	*f++ = TLS_SECTION_ASM_FLAG;
       if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
 	*f++ = 'G';
+#if HAVE_GAS_SECTION_LINK_ORDER
+      if (flags2 & SECTION2_LINK_ORDER)
+	*f++ = 'o';
+#endif
 #ifdef MACH_DEP_SECTION_ASM_FLAG
       if (flags & SECTION_MACH_DEP)
 	*f++ = MACH_DEP_SECTION_ASM_FLAG;
@@ -6594,6 +6599,16 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 
       if (flags & SECTION_ENTSIZE)
 	fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
+#if HAVE_GAS_SECTION_LINK_ORDER
+      if (flags2 & SECTION2_LINK_ORDER)
+	{
+	  tree id = DECL_ASSEMBLER_NAME (decl);
+	  ultimate_transparent_alias_target (&id);
+	  const char *name = IDENTIFIER_POINTER (id);
+	  name = targetm.strip_name_encoding (name);
+	  fprintf (asm_out_file, ",%s", name);
+	}
+#endif
       if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
 	{
 	  if (TREE_CODE (decl) == IDENTIFIER_NODE)
@@ -7462,7 +7477,7 @@ 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, unsigned int flags2)
 {
   if (in_section == new_section)
     return;
@@ -7477,7 +7492,7 @@ switch_to_section (section *new_section)
     case SECTION_NAMED:
       targetm.asm_out.named_section (new_section->named.name,
 				     new_section->named.common.flags,
-				     new_section->named.decl);
+				     flags2, new_section->named.decl);
       break;
 
     case SECTION_UNNAMED:
@@ -8145,7 +8160,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
   targetm.asm_out.named_section (sect->named.name,
 				 sect->named.common.flags
 				 | SECTION_LINKONCE,
-				 DECL_NAME (decl));
+				 0, DECL_NAME (decl));
   in_section = sect;
 #else
   /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
@@ -8171,7 +8186,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
       targetm.asm_out.named_section (name,
 				     sect->named.common.flags
 				     | SECTION_LINKONCE,
-				     DECL_NAME (decl));
+				     0, DECL_NAME (decl));
       in_section = sect;
     }
   else
-- 
2.24.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-12-16 14:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-07  2:57 [PATCH] Use the section flag 'o' for __patchable_function_entries H.J. Lu
2020-10-02 13:00 ` PING: " H.J. Lu
2020-10-23 12:41   ` PING^2 " H.J. Lu
2020-10-31 12:01     ` PING^3 " H.J. Lu
2020-11-07 15:47       ` PING^4 " H.J. Lu
2020-11-18 14:00         ` PING^5 " H.J. Lu
2020-12-02  5:23           ` Jeff Law
2020-12-02 13:15             ` V2 " H.J. Lu
2020-12-15 20:48               ` [PATCH] varasm: Fix up __patchable_function_entries handling Jakub Jelinek
2020-12-16 13:36                 ` H.J. Lu
2020-12-16 13:47                   ` Jakub Jelinek
2020-12-16 14:18                     ` Jeff Law

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).