I had a wrong email setting and got your reply later. I modified the patch according to your advice. Could you please review it again? Thanks.

On 2/10/2020 上午 1:47, Richard Sandiford wrote:
Sorry for the slow review.

HAO CHEN GUI via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 513fc5fe295..6f5bf8d7d73 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9315,10 +9315,10 @@ mips_select_rtx_section (machine_mode mode, rtx x,
     default_function_rodata_section.  */
static section *
-mips_function_rodata_section (tree decl)
+mips_function_rodata_section (tree decl, bool relocatable ATTRIBUTE_UNUSED)
Now that we're C++, it's more idiomatic to leave off the parameter name:

   mips_function_rodata_section (tree decl, bool)

Same for the rest of the patch.

@@ -2491,9 +2491,19 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int 
optimize_p ATTRIBUTE_UNUSED,
          if (! JUMP_TABLES_IN_TEXT_SECTION)
            {
              int log_align;
+             bool relocatable;
+
+             relocatable = 0;
Very minor, but simpler as:

    bool relocatable = false;

Same for the later hunk.

@@ -549,16 +549,17 @@ Whatever the actual target object format, this is often good 
enough.",
   void, (tree decl, int reloc),
   default_unique_section)
-/* Return the readonly data section associated with function DECL. */
+/* Return the readonly or relocated readonly data section
+   associated with function DECL.  */
  DEFHOOK
  (function_rodata_section,
- "Return the readonly data section associated with\n\
+ "Return the readonly or reloc readonly data section associated with\n\
  @samp{DECL_SECTION_NAME (@var{decl})}.\n\
Maybe add “; @var{relocatable} selects the latter over the former.”

  The default version of this function selects @code{.gnu.linkonce.r.name} if\n\
  the function's section is @code{.gnu.linkonce.t.name}, @code{.rodata.name}\n\
-if function is in @code{.text.name}, and the normal readonly-data section\n\
-otherwise.",
- section *, (tree decl),
+or @code{.data.rel.ro.name} if function is in @code{.text.name}, and\n\
+the normal readonly-data or reloc readonly data section otherwise.",
+ section *, (tree decl, bool relocatable),
   default_function_rodata_section)
/* Nonnull if the target wants to override the default ".rodata" prefix
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 4070f9c17e8..91ab75aed06 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -726,12 +726,26 @@ switch_to_other_text_partition (void)
    switch_to_section (current_function_section ());
  }
-/* Return the read-only data section associated with function DECL. */
+/* Return the read-only or relocated read-only data section
+   associated with function DECL.  */
section *
-default_function_rodata_section (tree decl)
+default_function_rodata_section (tree decl, bool relocatable)
  {
-  if (decl != NULL_TREE && DECL_SECTION_NAME (decl))
+  const char* sname;
+  unsigned int flags;
+
+  flags = 0;
+
+  if (relocatable)
+    {
+      sname = ".data.rel.ro.local";
+      flags = (SECTION_WRITE | SECTION_RELRO);
+    }
+  else
+    sname = ".rodata";
+
+  if (decl && DECL_SECTION_NAME (decl))
      {
        const char *name = DECL_SECTION_NAME (decl);
@@ -744,12 +758,12 @@ default_function_rodata_section (tree decl)
          dot = strchr (name + 1, '.');
          if (!dot)
            dot = name;
-         len = strlen (dot) + 8;
+         len = strlen (dot) + strlen (sname) + 1;
          rname = (char *) alloca (len);
- strcpy (rname, ".rodata");
+         strcpy (rname, sname);
          strcat (rname, dot);
-         return get_section (rname, SECTION_LINKONCE, decl);
+         return get_section (rname, (SECTION_LINKONCE | flags), decl);
        }
        /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo.  */
        else if (DECL_COMDAT_GROUP (decl)
@@ -767,15 +781,18 @@ default_function_rodata_section (tree decl)
               && strncmp (name, ".text.", 6) == 0)
        {
          size_t len = strlen (name) + 1;
-         char *rname = (char *) alloca (len + 2);
+         char *rname = (char *) alloca (len + strlen (sname) - 5);
- memcpy (rname, ".rodata", 7);
-         memcpy (rname + 7, name + 5, len - 5);
-         return get_section (rname, 0, decl);
+         memcpy (rname, sname, strlen (sname));
+         memcpy (rname + strlen (sname), name + 5, len - 5);
+         return get_section (rname, flags, decl);
        }
      }
Don't we need to handle the .gnu.linkonce.t. case too?  I believe
the suffix there is “.d.rel.ro.local” (replacing “.t”)

My main concern is how this interacts with non-ELF targets.
It looks like AIX/XCOFF, Darwin and Cygwin already pick
default_no_function_rodata_section, so they should be fine.
But at the moment, all the fancy stuff in default_function_rodata_section
is indirectly guarded by targetm_common.have_named_sections, with the
hook falling back to readonly_data_section if the function isn't in a
named section.

So I wonder if it would be safer to test targetm_common.have_named_sections
in this condition:

+
+             /* Judge if it's a absolute jump table. Set relocatable for
+                absolute jump table if the target supports relocations.  */
+
+             if (!CASE_VECTOR_PC_RELATIVE
+                 && !targetm.asm_out.generate_pic_addr_diff_vec ())
+               relocatable = targetm.asm_out.reloc_rw_mask ();
switch_to_section (targetm.asm_out.function_rodata_section
-                                (current_function_decl));
+                                (current_function_decl, relocatable));
#ifdef ADDR_VEC_ALIGN
              log_align = ADDR_VEC_ALIGN (table);
Similarly for the other case where the condition appears.  I think the
condition is subtle enough that it's worth splitting out into a helper.

Thanks,
Richard
        * final.c (final_scan_insn_1): Set jump table relocatable as the
        second argument of targetm.asm_out.function_rodata_section.
        * output.h (default_function_rodata_section,
        default_no_function_rodata_section): Add the second argument to the
        declarations.
        * target.def (function_rodata_section): Change the doc and add
        the second argument.
        * doc/tm.texi: Regenerate.
        * varasm.c (jumptable_relocatable): Implement.
        (default_function_rodata_section): Add the second argument
        and the support for relocatable read only sections.
        (default_no_function_rodata_section): Add the second argument.
        (function_mergeable_rodata_prefix): Set the second argument to false.
        * config/mips/mips.c (mips_function_rodata_section): Add the second
        arugment and set it to false.
        * config/s390/s390.c (targetm.asm_out.function_rodata_section): Set
        the second argument to false.
        * config/s390/s390.md Likewise.
        * gcc/config/rs6000/linux64.h (JUMP_TABLES_IN_TEXT_SECTION): Define.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 513fc5fe295..58e474e063d 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9315,10 +9315,10 @@ mips_select_rtx_section (machine_mode mode, rtx x,
    default_function_rodata_section.  */
 
 static section *
-mips_function_rodata_section (tree decl)
+mips_function_rodata_section (tree decl, bool)
 {
   if (!TARGET_ABICALLS || TARGET_ABSOLUTE_ABICALLS || TARGET_GPWORD)
-    return default_function_rodata_section (decl);
+    return default_function_rodata_section (decl, false);
 
   if (decl && DECL_SECTION_NAME (decl))
     {
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 73b6c01874c..35038570e04 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -241,7 +241,7 @@ extern int dot_symbols;
 
 /* Indicate that jump tables go in the text section.  */
 #undef  JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
+#define JUMP_TABLES_IN_TEXT_SECTION rs6000_relative_jumptables
 
 /* The linux ppc64 ABI isn't explicit on whether aggregates smaller
    than a doubleword should be padded upward or downward.  You could
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index dbb541bbea7..86978648299 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -11697,7 +11697,7 @@ s390_output_split_stack_data (rtx parm_block, rtx 
call_done,
   rtx ops[] = { parm_block, call_done };
 
   switch_to_section (targetm.asm_out.function_rodata_section
-                    (current_function_decl));
+                    (current_function_decl, false));
 
   if (TARGET_64BIT)
     output_asm_insn (".align\t8", NULL);
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 18edea1ce47..aaf41a559cc 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -11250,7 +11250,7 @@
   ""
 {
   switch_to_section (targetm.asm_out.function_rodata_section
-                (current_function_decl));
+                (current_function_decl, false));
   return "";
 }
   [(set_attr "length" "0")])
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 97437e8274f..d4fbd750fc7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7711,13 +7711,14 @@ example, the function @code{foo} would be placed in 
@code{.text.foo}.
 Whatever the actual target object format, this is often good enough.
 @end deftypefn
 
-@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RODATA_SECTION (tree 
@var{decl})
-Return the readonly data section associated with
-@samp{DECL_SECTION_NAME (@var{decl})}.
+@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RODATA_SECTION (tree 
@var{decl}, bool @var{relocatable})
+Return the readonly data or reloc readonly data section associated with
+@samp{DECL_SECTION_NAME (@var{decl})}. @var{relocatable} selects the latter
+over the former.
 The default version of this function selects @code{.gnu.linkonce.r.name} if
 the function's section is @code{.gnu.linkonce.t.name}, @code{.rodata.name}
-if function is in @code{.text.name}, and the normal readonly-data section
-otherwise.
+or @code{.data.rel.ro.name} if function is in @code{.text.name}, and
+the normal readonly-data or reloc readonly data section otherwise.
 @end deftypefn
 
 @deftypevr {Target Hook} {const char *} TARGET_ASM_MERGEABLE_RODATA_PREFIX
diff --git a/gcc/final.c b/gcc/final.c
index 80423d117d9..fc9a05e335f 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "print-rtl.h"
 #include "function-abi.h"
+#include "common/common-target.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"          /* Needed for external data declarations.  */
@@ -2154,6 +2155,21 @@ asm_show_source (const char *filename, int linenum)
   fputc ('\n', asm_out_file);
 }
 
+/* Judge if an absolute jump table is relocatable.  */
+
+bool
+jumptable_relocatable (void)
+{
+  bool relocatable = false;
+
+  if (!CASE_VECTOR_PC_RELATIVE
+      && !targetm.asm_out.generate_pic_addr_diff_vec ()
+      && targetm_common.have_named_sections)
+     relocatable = targetm.asm_out.reloc_rw_mask ();
+
+  return relocatable;
+}
+
 /* The final scan for one insn, INSN.
    Args are same as in `final', except that INSN
    is the insn being scanned.
@@ -2493,7 +2509,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int 
optimize_p ATTRIBUTE_UNUSED,
              int log_align;
 
              switch_to_section (targetm.asm_out.function_rodata_section
-                                (current_function_decl));
+                                (current_function_decl,
+                                 jumptable_relocatable ()));
 
 #ifdef ADDR_VEC_ALIGN
              log_align = ADDR_VEC_ALIGN (table);
@@ -2572,7 +2589,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int 
optimize_p ATTRIBUTE_UNUSED,
 
            if (! JUMP_TABLES_IN_TEXT_SECTION)
              switch_to_section (targetm.asm_out.function_rodata_section
-                                (current_function_decl));
+                                (current_function_decl,
+                                 jumptable_relocatable ()));
            else
              switch_to_section (current_function_section ());
 
diff --git a/gcc/output.h b/gcc/output.h
index eb253c50329..661ce9074ae 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -571,8 +571,8 @@ extern void default_ctor_section_asm_out_constructor (rtx, 
int);
 extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT);
 extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
 extern void default_unique_section (tree, int);
-extern section *default_function_rodata_section (tree);
-extern section *default_no_function_rodata_section (tree);
+extern section *default_function_rodata_section (tree, bool);
+extern section *default_no_function_rodata_section (tree, bool);
 extern section *default_clone_table_section (void);
 extern section *default_select_rtx_section (machine_mode, rtx,
                                            unsigned HOST_WIDE_INT);
diff --git a/gcc/target.def b/gcc/target.def
index ed2da154e30..d538cbbdf6b 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -549,16 +549,18 @@ Whatever the actual target object format, this is often 
good enough.",
  void, (tree decl, int reloc),
  default_unique_section)
 
-/* Return the readonly data section associated with function DECL.  */
+/* Return the readonly data or relocated readonly data section
+   associated with function DECL.  */
 DEFHOOK
 (function_rodata_section,
- "Return the readonly data section associated with\n\
-@samp{DECL_SECTION_NAME (@var{decl})}.\n\
+ "Return the readonly data or reloc readonly data section associated with\n\
+@samp{DECL_SECTION_NAME (@var{decl})}. @var{relocatable} selects the latter\n\
+over the former.\n\
 The default version of this function selects @code{.gnu.linkonce.r.name} if\n\
 the function's section is @code{.gnu.linkonce.t.name}, @code{.rodata.name}\n\
-if function is in @code{.text.name}, and the normal readonly-data section\n\
-otherwise.",
- section *, (tree decl),
+or @code{.data.rel.ro.name} if function is in @code{.text.name}, and\n\
+the normal readonly-data or reloc readonly data section otherwise.",
+ section *, (tree decl, bool relocatable),
  default_function_rodata_section)
 
 /* Nonnull if the target wants to override the default ".rodata" prefix
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ea0b59cf44a..40502049b61 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -727,12 +727,26 @@ switch_to_other_text_partition (void)
   switch_to_section (current_function_section ());
 }
 
-/* Return the read-only data section associated with function DECL.  */
+/* Return the read-only or relocated read-only data section
+   associated with function DECL.  */
 
 section *
-default_function_rodata_section (tree decl)
+default_function_rodata_section (tree decl, bool relocatable)
 {
-  if (decl != NULL_TREE && DECL_SECTION_NAME (decl))
+  const char* sname;
+  unsigned int flags;
+
+  flags = 0;
+
+  if (relocatable)
+    {
+      sname = ".data.rel.ro.local";
+      flags = (SECTION_WRITE | SECTION_RELRO);
+    }
+  else
+    sname = ".rodata";
+
+  if (decl && DECL_SECTION_NAME (decl))
     {
       const char *name = DECL_SECTION_NAME (decl);
 
@@ -745,38 +759,57 @@ default_function_rodata_section (tree decl)
          dot = strchr (name + 1, '.');
          if (!dot)
            dot = name;
-         len = strlen (dot) + 8;
+         len = strlen (dot) + strlen (sname) + 1;
          rname = (char *) alloca (len);
 
-         strcpy (rname, ".rodata");
+         strcpy (rname, sname);
          strcat (rname, dot);
-         return get_section (rname, SECTION_LINKONCE, decl);
+         return get_section (rname, (SECTION_LINKONCE | flags), decl);
        }
-      /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo.  */
+      /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo or
+        .gnu.linkonce.d.rel.ro.local.foo if the jump table is relocatable.  */
       else if (DECL_COMDAT_GROUP (decl)
               && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
        {
-         size_t len = strlen (name) + 1;
-         char *rname = (char *) alloca (len);
+         size_t len;
+         char *rname;
 
-         memcpy (rname, name, len);
-         rname[14] = 'r';
-         return get_section (rname, SECTION_LINKONCE, decl);
+         if (relocatable)
+           {
+             len = strlen (name) + strlen (".rel.ro.local") + 1;
+             rname = (char *) alloca (len);
+
+             strcpy (rname, ".gnu.linkonce.d");
+             strcat (rname, ".rel.ro.local");
+             strcat (rname, name + 15);
+           }
+         else
+           {
+             len = strlen (name) + 1;
+             rname = (char *) alloca (len);
+
+             memcpy (rname, name, len);
+             rname[14] = 'r';
+           }
+         return get_section (rname, (SECTION_LINKONCE | flags), decl);
        }
       /* For .text.foo we want to use .rodata.foo.  */
       else if (flag_function_sections && flag_data_sections
               && strncmp (name, ".text.", 6) == 0)
        {
          size_t len = strlen (name) + 1;
-         char *rname = (char *) alloca (len + 2);
+         char *rname = (char *) alloca (len + strlen (sname) - 5);
 
-         memcpy (rname, ".rodata", 7);
-         memcpy (rname + 7, name + 5, len - 5);
-         return get_section (rname, 0, decl);
+         memcpy (rname, sname, strlen (sname));
+         memcpy (rname + strlen (sname), name + 5, len - 5);
+         return get_section (rname, flags, decl);
        }
     }
 
-  return readonly_data_section;
+  if (relocatable)
+    return get_section (sname, flags, decl);
+  else
+    return readonly_data_section;
 }
 
 /* Return the read-only data section associated with function DECL
@@ -784,7 +817,7 @@ default_function_rodata_section (tree decl)
    readonly data section.  */
 
 section *
-default_no_function_rodata_section (tree decl ATTRIBUTE_UNUSED)
+default_no_function_rodata_section (tree, bool)
 {
   return readonly_data_section;
 }
@@ -794,7 +827,8 @@ default_no_function_rodata_section (tree decl 
ATTRIBUTE_UNUSED)
 static const char *
 function_mergeable_rodata_prefix (void)
 {
-  section *s = targetm.asm_out.function_rodata_section (current_function_decl);
+  section *s = targetm.asm_out.function_rodata_section (current_function_decl,
+                                                       false);
   if (SECTION_STYLE (s) == SECTION_NAMED)
     return s->named.name;
   else

Reply via email to