Hi,
Jump tables are put into text or rodata section originally. On some
platforms, it gains the performance benefit from absolute address jump
tables. So I want to let absolute address jump table be relocatable.
This patch puts absolute jump table in read only relocation section if
the target supports relocations.
/* 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,
relocatable));
The attachments are the patch diff file and change log file.
Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk? Any recommendations? Thanks a lot.
* final.c (final_scan_insn_1): Judge if a jump table is relative or
absoluted, and if it needs to be relocated.
* 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 (default_function_rodata_section): Add the second argument
to default_function_rodata_section. It indicates the section should be
read-only or relocated read-only.
(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..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)
{
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 34776c8421e..29d2d7ce40b 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -324,7 +324,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 758315c0c72..eb619d39ad7 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -11639,7 +11639,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 cd1c0634b71..6ca03ed9002 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -11218,7 +11218,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 6e7d9dc54a9..3907b7b8cc7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7703,13 +7703,13 @@ 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
+@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RODATA_SECTION (tree
@var{decl}, bool @var{relocatable})
+Return the readonly or reloc readonly data section associated with
@samp{DECL_SECTION_NAME (@var{decl})}.
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 a3601964a8d..c86e639dc23 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -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;
+
+ /* 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);
@@ -2571,8 +2581,21 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int
optimize_p ATTRIBUTE_UNUSED,
#endif
if (! JUMP_TABLES_IN_TEXT_SECTION)
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ {
+ bool relocatable;
+
+ relocatable = 0;
+
+ /* 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, relocatable));
+ }
else
switch_to_section (current_function_section ());
diff --git a/gcc/output.h b/gcc/output.h
index eb253c50329..94eb0d6ebef 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 relocatable);
+extern section *default_no_function_rodata_section (tree, bool relocatable);
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 07059a87caf..8cda974c3c5 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -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\
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);
}
}
- 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
@@ -783,7 +800,8 @@ 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 decl ATTRIBUTE_UNUSED,
+ bool relocatable ATTRIBUTE_UNUSED)
{
return readonly_data_section;
}
@@ -793,7 +811,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