diff options
author | nickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-07 10:54:13 +0000 |
---|---|---|
committer | nickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-07 10:54:13 +0000 |
commit | 7c6733e83d719397e14db3fe220bc544132a6550 (patch) | |
tree | 46d6178c94554a22a20fe838a94fbf98cec94d4d /gcc/varasm.c | |
parent | 90bf0a0066d0e93b78eb3012c17b323cd084ff8b (diff) | |
download | gcc-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.c | 101 |
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" |