summaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-07 10:54:13 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-07 10:54:13 +0000
commit7c6733e83d719397e14db3fe220bc544132a6550 (patch)
tree46d6178c94554a22a20fe838a94fbf98cec94d4d /gcc/varasm.c
parent90bf0a0066d0e93b78eb3012c17b323cd084ff8b (diff)
downloadgcc-7c6733e83d719397e14db3fe220bc544132a6550.tar.gz
* common.opt (record-gcc-switches): New command line switch.
* target.h (print_switch_type): New enum. (print_switch_fn_type): New typedef for a function pointer. (struct gcc_target): Add record_gcc_switches and record_gcc_switches_section fields. * target-def.h (TARGET_ASM_RECORD_GCC_SWITCHES): Provide a default definition. (TARGET_ASM_RECORD_GCC_SWITCHES_SECTION): Provide a default definition. * toplev.c (print_single_switch): Simplify by providing a pointer to function that will format and output the switch appropriately. (print_switch_values): Likewise. (print_to_asm_out_file): New function. (print_to_stderr): New function. (init_asm_output): If flag_record_gcc_switches is set then if the target supports recording the switches then emit them into the assembler output file, otherwise tell the user that the switch is not supported. * varasm.c (eld_record_gcc_switches): New function. Example handler for the record_gcc_switches target hook. * doc/tm.texi (TARGET_ASM_RECORD_GCC_SWITCHES): Document the new target hook. (TARGET_ASM_RECORD_GCC_SWITCHES_SECTION): Likewise. * doc/invoke.texi (-frecord-gcc-switches): Document. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119615 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 819add8afba..1e7af0e5b5d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6226,4 +6226,105 @@ output_object_blocks (void)
htab_traverse (object_block_htab, output_object_block_htab, NULL);
}
+/* This function provides a possible implementation of the
+ TARGET_ASM_RECORD_GCC_SWITCHES target hook for ELF targets. When triggered
+ by -frecord-gcc-switches it creates a new mergeable, string section in the
+ assembler output file called TARGET_ASM_RECORD_GCC_SWITCHES_SECTION which
+ contains the switches in ASCII format.
+
+ FIXME: This code does not correctly handle double quote characters
+ that appear inside strings, (it strips them rather than preserving them).
+ FIXME: ASM_OUTPUT_ASCII, as defined in config/elfos.h will not emit NUL
+ characters - instead it treats them as sub-string separators. Since
+ we want to emit NUL strings terminators into the object file we have to use
+ ASM_OUTPUT_SKIP. */
+
+int
+elf_record_gcc_switches (print_switch_type type, const char * name)
+{
+ static char buffer[1024];
+
+ /* This variable is used as part of a simplistic heuristic to detect
+ command line switches which take an argument:
+
+ "If a command line option does not start with a dash then
+ it is an argument for the previous command line option."
+
+ This fails in the case of the command line option which is the name
+ of the file to compile, but otherwise it is pretty reasonable. */
+ static bool previous_name_held_back = FALSE;
+
+ switch (type)
+ {
+ case SWITCH_TYPE_PASSED:
+ if (* name != '-')
+ {
+ if (previous_name_held_back)
+ {
+ unsigned int len = strlen (buffer);
+
+ snprintf (buffer + len, sizeof buffer - len, " %s", name);
+ ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
+ ASM_OUTPUT_SKIP (asm_out_file, 1L);
+ previous_name_held_back = FALSE;
+ }
+ else
+ {
+ strncpy (buffer, name, sizeof buffer);
+ ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
+ ASM_OUTPUT_SKIP (asm_out_file, 1L);
+ }
+ }
+ else
+ {
+ if (previous_name_held_back)
+ {
+ ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
+ ASM_OUTPUT_SKIP (asm_out_file, 1L);
+ }
+
+ strncpy (buffer, name, sizeof buffer);
+ previous_name_held_back = TRUE;
+ }
+ break;
+
+ case SWITCH_TYPE_DESCRIPTIVE:
+ if (name == NULL)
+ {
+ /* Distinguish between invocations where name is NULL. */
+ static bool started = false;
+
+ if (started)
+ {
+ if (previous_name_held_back)
+ {
+ ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
+ ASM_OUTPUT_SKIP (asm_out_file, 1L);
+ }
+ }
+ else
+ {
+ section * sec;
+
+ sec = get_section (targetm.asm_out.record_gcc_switches_section,
+ SECTION_DEBUG
+ | SECTION_MERGE
+ | SECTION_STRINGS
+ | (SECTION_ENTSIZE & 1),
+ NULL);
+ switch_to_section (sec);
+ started = true;
+ }
+ }
+
+ default:
+ break;
+ }
+
+ /* The return value is currently ignored by the caller, but must be 0.
+ For -fverbose-asm the return value would be the number of characters
+ emitted into the assembler file. */
+ return 0;
+}
+
#include "gt-varasm.h"