@@ -2854,8 +2854,32 @@ switch_to_exception_section (const char
#ifdef HAVE_LD_EH_GC_SECTIONS
if (flag_function_sections)
{
- char *section_name = XNEWVEC (char, strlen (fnname) + 32);
- sprintf (section_name, ".gcc_except_table.%s", fnname);
+ char *section_name;
+ const char *suffix = fnname;
+ section *sect;
+ /* If varasm decided to put the current function
+ into special section like .text.startup.main or
+ .text.exit.fnname, use .gcc_except_table.startup.main
+ or .gcc_except_table.exit.fnname instead of
+ .gcc_except_table.main or .gcc_except_table.fnname,
+ otherwise --gc-sections might misbehave in older linkers. */
+ if (current_function_decl
+ && DECL_HAS_IMPLICIT_SECTION_NAME_P (current_function_decl)
+ && (sect = function_section (current_function_decl)) != NULL
+ && SECTION_STYLE (sect) == SECTION_NAMED
+ && sect->named.decl == current_function_decl
+ && sect->named.name)
+ {
+ size_t len = strlen (sect->named.name);
+ size_t fnname_len = strlen (fnname);
+ if (len > fnname_len + 6
+ && strncmp (sect->named.name, ".text.", 6) == 0
+ && memcmp (sect->named.name + len - fnname_len,
+ fnname, fnname_len) == 0)
+ suffix = sect->named.name + 6;
+ }
+ section_name = XNEWVEC (char, strlen (suffix) + 32);
+ sprintf (section_name, ".gcc_except_table.%s", suffix);
s = get_section (section_name, flags, NULL);
free (section_name);
}