invoke.texi (-mfix-and-continue): Add support for fast turn around debugging.
authorMike Stump <mrs@gcc.gnu.org>
Thu, 19 Aug 2004 00:43:03 +0000 (00:43 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Thu, 19 Aug 2004 00:43:03 +0000 (00:43 +0000)
* 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
gcc/config/darwin.c
gcc/config/darwin.h
gcc/config/rs6000/darwin.h
gcc/config/rs6000/rs6000.c
gcc/doc/invoke.texi

index 706fb616160c1715ca1934b167630e9e1a982f36..3336545a1cf9bce66ffcb77424e4b305ce843a43 100644 (file)
@@ -1,4 +1,27 @@
-2004-09-19  Steven Bosscher  <stevenb@suse.de>
+2004-08-18  Mike Stump  <mrs@apple.com>
+
+       * 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  <stevenb@suse.de>
 
        * basic-block.h (struct edge_def): Remove crossing_edge.
        (EDGE_CROSSING): New define.
index 579daf876fac51b719fce1adf989bbe659236c46..d34dcfe411d05388f3a5dbbbc9765be5dc103f4c 100644 (file)
@@ -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"
index 249458918912ffd30393c49244102d5b61237fc8..cd37567215e2bd79d7ff8b9cec5629cb42db6cd9 100644 (file)
@@ -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 {
index 96e878bbcdef993031c201e707c2a16cc0930298..f1d5e7658639dc447fa62b2d12a7fcaca86d2757 100644 (file)
@@ -94,6 +94,17 @@ do {                                                                 \
         /* Darwin doesn't support -fpic.  */                           \
         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)
index 13143d7aed179d9d07a1a16de892ae25901e0db8..f9792ecdadcb120a3f1070f85e958438b9bf96ed 100644 (file)
@@ -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
index 0cf590c231932debd92e11686f8fd00f88f62180..72f0af871f2a9536310c08a9b3d168152f9e5307 100644 (file)
@@ -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.