-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.
#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;
? 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:
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));
}
else
{
+ rtx init = const0_rtx;
+
machopic_nl_symbol_ptr_section ();
assemble_name (asm_out_file, ptr_name);
fprintf (asm_out_file, ":\n");
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);
}
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);
}
|| (!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
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"
/* 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 {
/* 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) \
#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. */
}
#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)
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
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
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.