From d5ac0401eb128bf3dadec943741dfde7c499e49a Mon Sep 17 00:00:00 2001 From: Haochen Gui Date: Tue, 17 Nov 2020 13:52:15 -0600 Subject: 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. --- gcc/varasm.c | 71 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 19 deletions(-) (limited to 'gcc/varasm.c') diff --git a/gcc/varasm.c b/gcc/varasm.c index 435c7b3..ada9994 100644 --- a/gcc/varasm.c +++ b/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,38 +764,56 @@ 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.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 @@ -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 -- cgit v1.1