[PATCH] Add support for putting jump table into relocation read-only section

HAO CHEN GUI guihaoc@linux.ibm.com
Mon Aug 17 02:20:57 GMT 2020


Segher,

Seems I sent the wrong diff file. Now the attachments should be correct 
ones. Sorry for that.

For the reloc,  my understanding is the jump table needs to be relocated 
if it's a non-relative jump table and PIC flag is set at the same time.

//stmt.c

  if (CASE_VECTOR_PC_RELATIVE
           || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
     emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
                                                  gen_rtx_LABEL_REF (Pmode,
table_label),
                                                  gen_rtvec_v (ncases, 
labelvec),
                                                  const0_rtx, const0_rtx));
   else
     emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
                                             gen_rtvec_v (ncases, 
labelvec)));

According to the slice of code in stmt.c,  the non-relative jump table 
is created with PIC flag set when CASE_VECTOR_PC_RELATIVE is false, 
flag_pic is true and targetm.asm_out.generate_pic_addr_diff_vec is 
false. So I set the reloc to

reloc = (! CASE_VECTOR_PC_RELATIVE && flag_pic &&
            ! targetm.asm_out.generate_pic_addr_diff_vec ()) ? 1 : 0;

The funcation_rodata_section is not only for jump tables. It's no relro 
in other cases. I am not sure if it's suitable to put selecting relro 
section in it. Of course, I can create a separate function for section 
selection of jump table and send its output to funcation_rodata_section.

Please advice. Thanks a lot.


On 15/8/2020 上午 7:39, Segher Boessenkool wrote:

> Hi!
>
> On Fri, Aug 14, 2020 at 03:20:03PM +0800, HAO CHEN GUI wrote:
>> section *
>> select_jump_table_section (tree decl)
>> {
>>    int reloc;
>>    bool section_reloc;
>>
>>    reloc = (! CASE_VECTOR_PC_RELATIVE && flag_pic &&
>>             ! targetm.asm_out.generate_pic_addr_diff_vec ()) ? 1 :
>> 0;
> (Modern style is no space after "!", and your mailer wrapped the code).
>
>>    section_reloc = (reloc & targetm.asm_out.reloc_rw_mask ());
> (No space after & either).
>
>>    return targetm.asm_out.function_rodata_section (decl, section_reloc);
> So you are saying it should not go into relro if either there is no pic
> flag, the targets are pc relative, or pic uses some address diff?
>
> This seems too complicated, and/or not the right abstraction.
>
>
>> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
>> index 3be984bbd5c..0ac1488c837 100644
>> --- a/gcc/doc/tm.texi.in
>> +++ b/gcc/doc/tm.texi.in
>> @@ -5007,6 +5007,8 @@ it is unlikely to be called.
>>   
>>   @hook TARGET_ASM_FUNCTION_RODATA_SECTION
>>   
>> +@hook TARGET_ASM_FUNCTION_RELRO_SECTION
> I would expect people to just use TARGET_ASM_FUNCTION_RODATA_SECTION to
> get the .data.rel.ro?  With another argument then.
>
>> +section *
>> +select_jump_table_section (tree decl)
>> +{
>> +  int relco;
> "reloc"?
>
>> +  relco = JUMP_TABLES_IN_RELRO;
> Just put that on the same line as the declaration?
>
>> +  if (relco & targetm.asm_out.reloc_rw_mask ())
>> +    return targetm.asm_out.function_relro_section (decl);
>> +  else
>> +    return targetm.asm_out.function_rodata_section (decl);
>> +}
> (trailing spaces btw)
>
>> @@ -2492,7 +2513,7 @@ 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
>> +	      switch_to_section (select_jump_table_section
>>   				 (current_function_decl));
> 	      section *section
> 		= select_jump_table_section (current_function_decl));
> 	      switch_to_section (section);
>
> (but it would be better if we didn't indent so deeply here).
>
>
> I think this should be split into a function just selecting the relro
> section (either directly, or from the rodata selection function), and
> then separately the jumptable section thing.
>
> There is a lot of stuff here that seems confused, and a lot of that
> already was there :-(
>
>
> Segher
-------------- next part --------------
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6e7d9dc54a9..3ff7527f2cc 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7712,6 +7712,15 @@ if function is in @code{.text.name}, and the normal readonly-data section
 otherwise.
 @end deftypefn
 
+@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RELRO_SECTION (tree @var{decl})
+Return the relro 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{.data.rel.ro.name} if function is in @code{.text.name}, 
+and the normal data relro section otherwise.
+@end deftypefn
+
 @deftypevr {Target Hook} {const char *} TARGET_ASM_MERGEABLE_RODATA_PREFIX
 Usually, the compiler uses the prefix @code{".rodata"} to construct
 section names for mergeable constant data.  Define this macro to override
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3be984bbd5c..0ac1488c837 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5007,6 +5007,8 @@ it is unlikely to be called.
 
 @hook TARGET_ASM_FUNCTION_RODATA_SECTION
 
+@hook TARGET_ASM_FUNCTION_RELRO_SECTION
+
 @hook TARGET_ASM_MERGEABLE_RODATA_PREFIX
 
 @hook TARGET_ASM_TM_CLONE_TABLE_SECTION
diff --git a/gcc/final.c b/gcc/final.c
index a3601964a8d..ba198182663 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -107,6 +107,10 @@ along with GCC; see the file COPYING3.  If not see
 #define JUMP_TABLES_IN_TEXT_SECTION 0
 #endif
 
+#ifndef JUMP_TABLES_IN_RELRO
+#define JUMP_TABLES_IN_RELRO 0
+#endif
+
 /* Bitflags used by final_scan_insn.  */
 #define SEEN_NOTE	1
 #define SEEN_EMITTED	2
@@ -2154,6 +2158,23 @@ asm_show_source (const char *filename, int linenum)
   fputc ('\n', asm_out_file);
 }
 
+/* Select sections for jump table.
+   If the jump table need to be relocated, 
+   select relro sections. Otherwise in readonly section */
+
+section *
+select_jump_table_section (tree decl)
+{
+  int relco;
+
+  relco = JUMP_TABLES_IN_RELRO;
+
+  if (relco & targetm.asm_out.reloc_rw_mask ())
+    return targetm.asm_out.function_relro_section (decl);
+  else 
+    return targetm.asm_out.function_rodata_section (decl);
+}
+
 /* The final scan for one insn, INSN.
    Args are same as in `final', except that INSN
    is the insn being scanned.
@@ -2492,7 +2513,7 @@ 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
+	      switch_to_section (select_jump_table_section
 				 (current_function_decl));
 
 #ifdef ADDR_VEC_ALIGN
@@ -2571,7 +2592,7 @@ 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
+	      switch_to_section (select_jump_table_section
 				 (current_function_decl));
 	    else
 	      switch_to_section (current_function_section ());
diff --git a/gcc/output.h b/gcc/output.h
index eb253c50329..9a463c42955 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -573,6 +573,7 @@ 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_relro_section (tree);
 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..9bd61b4e018 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -561,6 +561,18 @@ otherwise.",
  section *, (tree decl),
  default_function_rodata_section)
 
+/* Return the relro section associated with function DECL.  */
+DEFHOOK
+(function_relro_section,
+ "Return the relro 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}, \n\
+@code{.data.rel.ro.name} if function is in @code{.text.name}, \n\
+and the normal data relro section otherwise.",
+ section *, (tree decl),
+ default_function_relro_section)
+
 /* Nonnull if the target wants to override the default ".rodata" prefix
    for mergeable data sections.  */
 DEFHOOKPOD
diff --git a/gcc/varasm.c b/gcc/varasm.c
-------------- next part --------------
        * final.c (select_jump_table_section): Implement a function to select 
		the section of jump tables by reloc_rw_mask and other flags.
		* 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, default_no_function_rodata_section, 
		function_mergeable_rodata_prefix): Add the second argument in default_function_rodata_section.
		It indicates the section should be read-only or relocation read-only.
		Add the second argument in default_function_rodata_section. Set the second argument to
		false when default_function_rodata_section calls function_rodata_section.
		* config/mips/mips.c (mips_function_rodata_section): Add the second arugment and set it
		to false when it calls function_rodata_section.
		* config/s390/s390.c (targetm.asm_out.function_rodata_section): 
		Set the second argument to false.
		* config/s390/s390.md Likewise.


More information about the Gcc-patches mailing list