Relocatable read-only section support for absolute jump table
This patch puts absolute jump tables into a relocatable read-only section if they are on ELF target and relocation is supported. gcc/ChangeLog: * 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.
This commit is contained in:
parent
287cc750b0
commit
d5ac0401eb
8 changed files with 92 additions and 38 deletions
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -11746,7 +11746,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);
|
||||
|
|
|
@ -11290,7 +11290,7 @@
|
|||
""
|
||||
{
|
||||
switch_to_section (targetm.asm_out.function_rodata_section
|
||||
(current_function_decl));
|
||||
(current_function_decl, false));
|
||||
return "";
|
||||
}
|
||||
[(set_attr "length" "0")])
|
||||
|
|
|
@ -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
|
||||
|
|
22
gcc/final.c
22
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 ());
|
||||
|
||||
|
|
|
@ -572,8 +572,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);
|
||||
|
|
|
@ -559,16 +559,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
|
||||
|
|
65
gcc/varasm.c
65
gcc/varasm.c
|
@ -732,12 +732,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);
|
||||
|
||||
|
@ -750,37 +764,55 @@ 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;
|
||||
|
||||
if (relocatable)
|
||||
{
|
||||
len = strlen (name) + strlen (".rel.ro.local") + 1;
|
||||
rname = (char *) alloca (len);
|
||||
|
||||
strcpy (rname, ".gnu.linkonce.d.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, decl);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (relocatable)
|
||||
return get_section (sname, flags, decl);
|
||||
else
|
||||
return readonly_data_section;
|
||||
}
|
||||
|
||||
|
@ -789,7 +821,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;
|
||||
}
|
||||
|
@ -799,7 +831,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
|
||||
|
|
Loading…
Add table
Reference in a new issue