diff options
-rw-r--r-- | gcc/config/sparc/sysv4.h | 3 | ||||
-rw-r--r-- | gcc/dbxout.c | 25 | ||||
-rw-r--r-- | gcc/flags.h | 5 | ||||
-rw-r--r-- | gcc/toplev.c | 24 | ||||
-rw-r--r-- | gcc/varasm.c | 26 |
5 files changed, 81 insertions, 2 deletions
diff --git a/gcc/config/sparc/sysv4.h b/gcc/config/sparc/sysv4.h index bc27b0c009a..1c69dd5ee17 100644 --- a/gcc/config/sparc/sysv4.h +++ b/gcc/config/sparc/sysv4.h @@ -185,7 +185,8 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \ #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \ do { \ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \ - fprintf (FILE, ".section\t\"%s\",#alloc,#execinstr\n", (NAME)); \ + fprintf (FILE, ".section\t\"%s%s\",#alloc,#execinstr\n", \ + flag_function_sections ? ".text%" : "", (NAME)); \ else if ((DECL) && TREE_READONLY (DECL)) \ fprintf (FILE, ".section\t\"%s\",#alloc\n", (NAME)); \ else \ diff --git a/gcc/dbxout.c b/gcc/dbxout.c index cc6b9ca69c5..9831cdddc36 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -438,6 +438,27 @@ abspath (rel_filename) } #endif /* 0 */ +static int scope_labelno = 0; +static void +dbxout_function_end () +{ + char lscope_label_name[100]; + /* Convert Ltext into the appropriate format for local labels in case + the system doesn't insert underscores in front of user generated + labels. */ + ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno); + ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno); + scope_labelno++; + + /* By convention, GCC will mark the end of a function with an N_FUN + symbol and an empty string. */ + fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN); + assemble_name (asmfile, lscope_label_name); + fputc ('-', asmfile); + assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); + fprintf (asmfile, "-1\n"); +} + /* At the beginning of compilation, start writing the symbol table. Initialize `typevec' and output the standard data types of C. */ @@ -2670,5 +2691,9 @@ dbxout_function (decl) #ifdef DBX_OUTPUT_FUNCTION_END DBX_OUTPUT_FUNCTION_END (asmfile, decl); #endif +#ifdef ASM_OUTPUT_SECTION_NAME + if (flag_function_sections && use_gnu_debug_info_extensions) + dbxout_function_end (); +#endif } #endif /* DBX_DEBUGGING_INFO */ diff --git a/gcc/flags.h b/gcc/flags.h index ed1cf57a310..60528ab3de1 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -325,6 +325,11 @@ extern int flag_no_common; needed for crtstuff.c on other systems. */ extern int flag_inhibit_size_directive; +/* Nonzero means place each function into its own section on those platforms + which support arbitrary section names and unlimited numbers of sections. */ + +extern int flag_function_sections; + /* -fverbose-asm causes extra commentary information to be produced in the generated assembly code (to make it more readable). This option is generally only of use to those who actually need to read the diff --git a/gcc/toplev.c b/gcc/toplev.c index 4d866cd1b17..2c8f9a24223 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -403,6 +403,11 @@ int flag_no_function_cse = 0; int flag_omit_frame_pointer = 0; +/* Nonzero means place each function into its own section on those platforms + which support arbitrary section names and unlimited numbers of sections. */ + +int flag_function_sections = 0; + /* Nonzero to inhibit use of define_optimization peephole opts. */ int flag_no_peephole = 0; @@ -564,6 +569,7 @@ struct { char *string; int *variable; int on_value;} f_options[] = {"fast-math", &flag_fast_math, 1}, {"common", &flag_no_common, 0}, {"inhibit-size-directive", &flag_inhibit_size_directive, 1}, + {"function-sections", &flag_function_sections, 1}, {"verbose-asm", &flag_verbose_asm, 1}, {"gnu-linker", &flag_gnu_linker, 1}, {"pack-struct", &flag_pack_struct, 1}, @@ -2187,6 +2193,24 @@ compile_file (name) ASM_IDENTIFY_LANGUAGE (asm_out_file); #endif +#ifndef ASM_OUTPUT_SECTION_NAME + if (flag_function_sections) + { + warning ("-ffunction-sections not supported for this target."); + flag_function_sections = 0; + } +#endif + + if (flag_function_sections + && (profile_flag || profile_block_flag)) + { + warning ("-ffunction-sections disabled; it makes profiling impossible."); + flag_function_sections = 0; + } + + if (flag_function_sections && write_symbols != NO_DEBUG) + warning ("-ffunction-sections may affect debugging on some targets."); + if (output_bytecode) { if (profile_flag || profile_block_flag) diff --git a/gcc/varasm.c b/gcc/varasm.c index 9b831100124..cc60f03fec1 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -255,7 +255,8 @@ named_section (decl, name) if (in_section != in_named || strcmp (name, in_named_name)) { - in_named_name = name; + in_named_name = obstack_alloc (&permanent_obstack, strlen (name) + 1); + strcpy (in_named_name, name); in_section = in_named; #ifdef ASM_OUTPUT_SECTION_NAME @@ -349,6 +350,29 @@ void function_section (decl) tree decl; { + +#ifdef ASM_OUTPUT_SECTION_NAME + /* If we are placing functions into their own sections, and this + function doesn't already have a section specified, set it now. */ + if (flag_function_sections + && decl != NULL_TREE + && DECL_SECTION_NAME (decl) == NULL_TREE) + { + int len; + char *string; + + len = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 1; + string = alloca (len); + strcpy (string, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); + + /* Strip off any encoding in fnname. */ + STRIP_NAME_ENCODING (string, string); + + /* Set DECL_SECTION_NAME. */ + DECL_SECTION_NAME (decl) = build_string (len, string); + } +#endif + if (decl != NULL_TREE && DECL_SECTION_NAME (decl) != NULL_TREE) named_section (decl, (char *) 0); |