From 699c914ac9882aa4435d4e5c6cb259cbb37d4645 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 19 Aug 2004 00:43:03 +0000 Subject: [PATCH] invoke.texi (-mfix-and-continue): Add support for fast turn around debugging. * doc/invoke.texi (-mfix-and-continue): Add support for fast turn around debugging. (-ffix-and-continue): Likewise. (-mindirect-data): Likewise. (-findirect-data): Likewise. * config/darwin.c (TARGET_FIX_AND_CONTINUE): Likewise. (indirect_data): Likewise. (machopic_data_defined_p): Likewise. (machopic_output_indirection): Likewise. (darwin_encode_section_info): Likewise. (darwin_fix_and_continue): Likewise. (darwin_fix_and_continue_switch): Likewise. * config/darwin.h (MACHO_SYMBOL_STATIC): Likewise. * config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise. (SUBTARGET_OPTION_TRANSLATE_TABLE): Likewise. (SUBTARGET_OPTIONS): Likewise. (darwin_fix_and_continue): Likewise. (darwin_fix_and_continue_switch): Likewise. (TARGET_FIX_AND_CONTINUE): Likewise. * config/rs6000.c (rs6000_emit_prologue): Likewise. From-SVN: r86229 --- gcc/ChangeLog | 25 ++++++++++- gcc/config/darwin.c | 107 +++++++++++++++++++++++++++++++++++++++++++-- gcc/config/darwin.h | 8 ++++ gcc/config/rs6000/darwin.h | 42 ++++++++++++++++-- gcc/config/rs6000/rs6000.c | 27 +++++++++--- gcc/doc/invoke.texi | 11 +++++ 6 files changed, 207 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 706fb61..3336545 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,27 @@ -2004-09-19 Steven Bosscher +2004-08-18 Mike Stump + + * doc/invoke.texi (-mfix-and-continue): Add support for + fast turn around debugging. + (-ffix-and-continue): Likewise. + (-mindirect-data): Likewise. + (-findirect-data): Likewise. + * config/darwin.c (TARGET_FIX_AND_CONTINUE): Likewise. + (indirect_data): Likewise. + (machopic_data_defined_p): Likewise. + (machopic_output_indirection): Likewise. + (darwin_encode_section_info): Likewise. + (darwin_fix_and_continue): Likewise. + (darwin_fix_and_continue_switch): Likewise. + * config/darwin.h (MACHO_SYMBOL_STATIC): Likewise. + * config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise. + (SUBTARGET_OPTION_TRANSLATE_TABLE): Likewise. + (SUBTARGET_OPTIONS): Likewise. + (darwin_fix_and_continue): Likewise. + (darwin_fix_and_continue_switch): Likewise. + (TARGET_FIX_AND_CONTINUE): Likewise. + * config/rs6000.c (rs6000_emit_prologue): Likewise. + +2004-08-19 Steven Bosscher * basic-block.h (struct edge_def): Remove crossing_edge. (EDGE_CROSSING): New define. diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 579daf8..d34dcfe 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -44,6 +44,37 @@ Boston, MA 02111-1307, USA. */ #include "errors.h" #include "hashtab.h" +/* Darwin supports a feature called fix-and-continue, which is used + for rapid turn around debugging. When code is compiled with the + -mfix-and-continue flag, two changes are made to the generated code + that allow the system to do things that it would normally not be + able to do easily. These changes allow gdb to load in + recompilation of a translation unit that has been changed into a + running program and replace existing functions and methods of that + translation unit with with versions of those functions and methods + from the newly compiled translation unit. The new functions access + the existing static data from the old translation unit, if the data + existed in the unit to be replaced, and from the new translation + unit, for new data. + + The changes are to insert 4 nops at the beginning of all functions + and to use indirection to get at static duration data. The 4 nops + are required by consumers of the generated code. Currently, gdb + uses this to patch in a jump to the overriding function, this + allows all uses of the old name to forward to the replacement, + including existing function poiinters and virtual methods. See + rs6000_emit_prologue for the code that handles the nop insertions. + + The added indirection allows gdb to redirect accesses to static + duration data from the newly loaded translation unit to the + existing data, if any. @code{static} data is special and is + handled by setting the second word in the .non_lazy_symbol_pointer + data structure to the address of the data. See indirect_data for + the code that handles the extra indirection, and + machopic_output_indirection and its use of MACHO_SYMBOL_STATIC for + the code that handles @code{static} data indirection. */ + + /* Nonzero if the user passes the -mone-byte-bool switch, which forces sizeof(bool) to be 1. */ const char *darwin_one_byte_bool = 0; @@ -90,9 +121,51 @@ machopic_classify_symbol (rtx sym_ref) ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA); } +#ifndef TARGET_FIX_AND_CONTINUE +#define TARGET_FIX_AND_CONTINUE 0 +#endif + +/* Indicate when fix-and-continue style code generation is being used + and when a reference to data should be indirected so that it can be + rebound in a new translation unit to refernce the original instance + of that data. Symbol names that are for code generation local to + the translation unit are bound to the new translation unit; + currently this means symbols that begin with L or _OBJC_; + otherwise, we indicate that an indirect reference should be made to + permit the runtime to rebind new instances of the translation unit + to the original instance of the data. */ + +static int +indirect_data (rtx sym_ref) +{ + int lprefix; + const char *name; + + /* If we aren't generating fix-and-continue code, don't do anything special. */ + if (TARGET_FIX_AND_CONTINUE == 0) + return 0; + + /* Otherwise, all symbol except symbols that begin with L or _OBJC_ + are indirected. Symbols that begin with L and _OBJC_ are always + bound to the current translation unit as they are used for + generated local data of the translation unit. */ + + name = XSTR (sym_ref, 0); + + lprefix = (((name[0] == '*' || name[0] == '&') + && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L'))) + || (strncmp (name, "_OBJC_", 6))); + + return ! lprefix; +} + + static int machopic_data_defined_p (rtx sym_ref) { + if (indirect_data (sym_ref)) + return 0; + switch (machopic_classify_symbol (sym_ref)) { case MACHOPIC_DEFINED_DATA: @@ -799,7 +872,8 @@ machopic_output_indirection (void **slot, void *data) machopic_output_stub (asm_out_file, sym, stub); } - else if (machopic_symbol_defined_p (symbol)) + else if (! indirect_data (symbol) + && machopic_symbol_defined_p (symbol)) { data_section (); assemble_align (GET_MODE_ALIGNMENT (Pmode)); @@ -810,6 +884,8 @@ machopic_output_indirection (void **slot, void *data) } else { + rtx init = const0_rtx; + machopic_nl_symbol_ptr_section (); assemble_name (asm_out_file, ptr_name); fprintf (asm_out_file, ":\n"); @@ -818,7 +894,18 @@ machopic_output_indirection (void **slot, void *data) assemble_name (asm_out_file, sym_name); fprintf (asm_out_file, "\n"); - assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode), + /* Variables that are marked with MACHO_SYMBOL_STATIC need to + have their symbol name instead of 0 in the second entry of + the non-lazy symbol pointer data structure when they are + defined. This allows the runtime to rebind newer instances + of the translation unit with the original instance of the + data. */ + + if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC) + && machopic_symbol_defined_p (symbol)) + init = gen_rtx_SYMBOL_REF (Pmode, sym_name); + + assemble_integer (init, GET_MODE_SIZE (Pmode), GET_MODE_ALIGNMENT (Pmode), 1); } @@ -829,7 +916,7 @@ void machopic_finish (FILE *asm_out_file) { if (machopic_indirections) - htab_traverse_noresize (machopic_indirections, + htab_traverse_noresize (machopic_indirections, machopic_output_indirection, asm_out_file); } @@ -887,6 +974,11 @@ darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) || (!DECL_COMMON (decl) && DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node))) SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED; + + if (TREE_CODE (decl) == VAR_DECL + && indirect_data (sym_ref) + && ! TREE_PUBLIC (decl)) + SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC; } void @@ -1258,4 +1350,13 @@ darwin_file_end (void) fprintf (asm_out_file, "\t.subsections_via_symbols\n"); } +/* True, iff we're generating fast turn around debugging code. When + true, we arrange for function prologues to start with 4 nops so + that gdb may insert code to redirect them, and for data to accessed + indirectly. The runtime uses this indirection to forward + references for data to the original instance of that data. */ + +int darwin_fix_and_continue; +const char *darwin_fix_and_continue_switch; + #include "gt-darwin.h" diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 2494589..cd37567 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -812,9 +812,17 @@ objc_section_init (void) \ /* Set on a symbol with SYMBOL_FLAG_FUNCTION or MACHO_SYMBOL_FLAG_VARIABLE to indicate that the function or variable has been defined in this translation unit. */ + #define MACHO_SYMBOL_FLAG_VARIABLE (SYMBOL_FLAG_MACH_DEP) #define MACHO_SYMBOL_FLAG_DEFINED ((SYMBOL_FLAG_MACH_DEP) << 1) +/* Set on a symbol to indicate when fix-and-continue style code + generation is being used and the symbol refers to a static symbol + that should be rebound from new instances of a translation unit to + the original instance of the data. */ + +#define MACHO_SYMBOL_STATIC ((SYMBOL_FLAG_MACH_DEP) << 2) + /* Symbolic names for various things we might know about a symbol. */ enum machopic_addr_class { diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h index 96e878b..f1d5e76 100644 --- a/gcc/config/rs6000/darwin.h +++ b/gcc/config/rs6000/darwin.h @@ -95,6 +95,17 @@ do { \ warning ("-fpic is not supported; -fPIC assumed"); \ flag_pic = 2; \ } \ + \ + /* Handle -mfix-and-continue. */ \ + if (darwin_fix_and_continue_switch) \ + { \ + const char *base = darwin_fix_and_continue_switch; \ + while (base[-1] != 'm') base--; \ + \ + if (*darwin_fix_and_continue_switch != '\0') \ + error ("invalid option `%s'", base); \ + darwin_fix_and_continue = (base[0] != 'n'); \ + } \ } \ if (TARGET_64BIT && ! TARGET_POWERPC64) \ { \ @@ -134,11 +145,16 @@ do { \ #define SUBTARGET_EXTRA_SPECS \ { "darwin_arch", "ppc" }, -/* The "-faltivec" option should have been called "-maltivec" all along. */ +/* The "-faltivec" option should have been called "-maltivec" all + along. -ffix-and-continue and -findirect-data is for compatibility + for old compilers. */ + #define SUBTARGET_OPTION_TRANSLATE_TABLE \ - { "-faltivec", "-maltivec -include altivec.h" }, \ - { "-fno-altivec", "-mno-altivec" }, \ - { "-Waltivec-long-deprecated", "-mwarn-altivec-long" }, \ + { "-ffix-and-continue", "-mfix-and-continue" }, \ + { "-findirect-data", "-mfix-and-continue" }, \ + { "-faltivec", "-maltivec -include altivec.h" }, \ + { "-fno-altivec", "-mno-altivec" }, \ + { "-Waltivec-long-deprecated", "-mwarn-altivec-long" }, \ { "-Wno-altivec-long-deprecated", "-mno-warn-altivec-long" } /* Make both r2 and r3 available for allocation. */ @@ -364,3 +380,21 @@ extern const char *darwin_one_byte_bool; } #define HAS_MD_FALLBACK_FRAME_STATE_FOR 1 + +#undef SUBTARGET_OPTIONS +#define SUBTARGET_OPTIONS \ + {"fix-and-continue", &darwin_fix_and_continue_switch, \ + N_("Generate code suitable for fast turn around debugging"), 0}, \ + {"no-fix-and-continue", &darwin_fix_and_continue_switch, \ + N_("Don't generate code suitable for fast turn around debugging"), 0} + +extern int darwin_fix_and_continue; +extern const char *darwin_fix_and_continue_switch; + +/* True, iff we're generating fast turn around debugging code. When + true, we arrange for function prologues to start with 4 nops so + that gdb may insert code to redirect them, and for data to accessed + indirectly. The runtime uses this indirection to forward + references for data to the original instance of that data. */ + +#define TARGET_FIX_AND_CONTINUE (darwin_fix_and_continue) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 13143d7..f9792ec 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -12863,6 +12863,10 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx)); } +#ifndef TARGET_FIX_AND_CONTINUE +#define TARGET_FIX_AND_CONTINUE 0 +#endif + /* Emit function prologue as insns. */ void @@ -12880,11 +12884,24 @@ rs6000_emit_prologue (void) int using_store_multiple; HOST_WIDE_INT sp_offset = 0; - if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) - { - reg_mode = V2SImode; - reg_size = 8; - } + if (TARGET_FIX_AND_CONTINUE) + { + /* gdb on darwin arranges to forward a function from the old + address by modifying the first 4 instructions of the function + to branch to the overriding function. This is necessary to + permit function pointers that point to the old function to + actually forward to the new function. */ + emit_insn (gen_nop ()); + emit_insn (gen_nop ()); + emit_insn (gen_nop ()); + emit_insn (gen_nop ()); + } + + if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) + { + reg_mode = V2SImode; + reg_size = 8; + } using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64 && (!TARGET_SPE_ABI diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0cf590c..72f0af8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -7010,6 +7010,17 @@ without that switch. Using this switch may require recompiling all other modules in a program, including system libraries. Use this switch to conform to a non-default data model. +@item -mfix-and-continue +@itemx -ffix-and-continue +@itemx -findirect-data +@opindex mfix-and-continue +@opindex ffix-and-continue +@opindex findirect-data +Generate code suitable for fast turn around development. Needed to +enable gdb to dynamically load @code{.o} files into already running +programs. @option{-findirect-data} and @option{-ffix-and-continue} +are provided for backwards compatibility. + @item -all_load @opindex all_load Loads all members of static archive libraries. -- 2.7.4