From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7810) id D67333858C50; Tue, 12 Jul 2022 10:36:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D67333858C50 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alex Coplan To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] except.c: Fix up switching to .data.rel.ro for purecap X-Act-Checkin: gcc X-Git-Author: Alex Coplan X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 6c7481a4f94978351fc26e33f66b1fbe36dc82e5 X-Git-Newrev: 66f714a213a282bbb95b4bb2a573115e021f31ac Message-Id: <20220712103628.D67333858C50@sourceware.org> Date: Tue, 12 Jul 2022 10:36:28 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jul 2022 10:36:28 -0000 https://gcc.gnu.org/g:66f714a213a282bbb95b4bb2a573115e021f31ac commit 66f714a213a282bbb95b4bb2a573115e021f31ac Author: Alex Coplan Date: Wed Jun 15 16:41:06 2022 +0100 except.c: Fix up switching to .data.rel.ro for purecap C++ templates use COMDAT groups to keep all codegen artifacts related to a single template instantiation together, so they can all be discarded or kept together. On purecap Morello, we introduced a switch to the .data.rel.ro section which happens halfway through outputting the .gcc_except_table section. However, this switch to .data.rel.ro didn't preserve any COMDAT group for the current_function_decl, so the .chericap we would insert in the .data.rel.ro section wasn't cleaned up by the linker's COMDAT group handling. This could lead to "dangerous relocation: out of range" errors as we would have stale R_MORELLO_CAPINIT relocations being applied to incompatible different instantiations of the same template. Notably the switch_to_exception_section function already has logic to apply the COMDAT group for the current function to the .gcc_except_table section we switch to, so this patch reuses this logic to do the same when we switch to the .data.rel.ro section. gcc/ChangeLog: * except.c (switch_to_relro_section): New. Use it ... (dw2_output_call_site_table): ... here. (get_eh_named_section): New. Use it ... (switch_to_exception_section): ... here. Diff: --- gcc/except.c | 69 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/gcc/except.c b/gcc/except.c index 09525244dc5..32f16ef6e78 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -223,6 +223,7 @@ static int sjlj_size_of_call_site_table (void); static void dw2_output_call_site_table (int, int); static void sjlj_output_call_site_table (void); static void switch_to_exception_section (const char * ); +static void switch_to_relro_section (const char *); void @@ -2933,8 +2934,7 @@ dw2_output_call_site_table (int cs_format, int section) ASM_OUTPUT_LABEL (asm_out_file, reg_cap_offs_lab); /* Then switch to the relocatable RO data section, build the capability as a POINTER_PLUS and output the capability. */ - switch_to_section (get_named_section (NULL, ".data.rel.ro", - 0)); + switch_to_relro_section (name); ASM_GENERATE_INTERNAL_LABEL (cap_lab, "Llpcap", call_site_base + i); ASM_OUTPUT_LABEL (asm_out_file, cap_lab); @@ -2994,10 +2994,50 @@ sjlj_output_call_site_table (void) call_site_base += n; } +static section * +get_eh_named_section (const char *base_sec_name, + unsigned flags, + const char * ARG_UNUSED (fnname), + section **cache = NULL) +{ + section *s; +#ifdef HAVE_LD_EH_GC_SECTIONS + if (flag_function_sections + || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)) + { + char *section_name = XNEWVEC (char, + strlen (base_sec_name) + 1 /* Dot. */ + + strlen (fnname) + 1 /* NUL. */); + /* The EH section must match the code section, so only mark + it linkonce if we have COMDAT groups to tie them together. */ + if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP) + flags |= SECTION_LINKONCE; + sprintf (section_name, "%s.%s", base_sec_name, fnname); + s = get_section (section_name, flags, current_function_decl); + free (section_name); + } + else +#endif + { + s = get_section (base_sec_name, flags, NULL); + if (cache) + *cache = s; + } + return s; +} + +static void +switch_to_relro_section (const char *fnname) +{ + gcc_assert (targetm_common.have_named_sections); + unsigned flags = SECTION_WRITE | SECTION_RELRO; + switch_to_section (get_eh_named_section (".data.rel.ro", flags, fnname)); +} + /* Switch to the section that should be used for exception tables. */ static void -switch_to_exception_section (const char * ARG_UNUSED (fnname)) +switch_to_exception_section (const char * fnname) { section *s; @@ -3005,7 +3045,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname)) s = exception_section; else { - int flags; + unsigned flags; if (EH_TABLES_CAN_BE_READ_ONLY) { @@ -3022,25 +3062,8 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname)) /* Compute the section and cache it into exception_section, unless it depends on the function name. */ if (targetm_common.have_named_sections) - { -#ifdef HAVE_LD_EH_GC_SECTIONS - if (flag_function_sections - || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)) - { - char *section_name = XNEWVEC (char, strlen (fnname) + 32); - /* The EH table must match the code section, so only mark - it linkonce if we have COMDAT groups to tie them together. */ - if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP) - flags |= SECTION_LINKONCE; - sprintf (section_name, ".gcc_except_table.%s", fnname); - s = get_section (section_name, flags, current_function_decl); - free (section_name); - } - else -#endif - exception_section - = s = get_section (".gcc_except_table", flags, NULL); - } + s = get_eh_named_section (".gcc_except_table", flags, fnname, + &exception_section); else exception_section = s = flags == SECTION_WRITE ? data_section : readonly_data_section;