diff -urN gdb-6.8-orig/gdb/gdbarch.c gdb-6.8-new/gdb/gdbarch.c --- gdb-6.8-orig/gdb/gdbarch.c 2009-03-19 17:29:47.000000000 -0700 +++ gdb-6.8-new/gdb/gdbarch.c 2009-03-20 11:29:29.000000000 -0700 @@ -190,6 +190,8 @@ gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint; gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint; CORE_ADDR decr_pc_after_break; + gdbarch_skip_program_breakpoint_ftype *skip_program_breakpoint; + gdbarch_describe_program_breakpoint_ftype *describe_program_breakpoint; CORE_ADDR deprecated_function_start_offset; gdbarch_remote_register_number_ftype *remote_register_number; gdbarch_fetch_tls_load_module_address_ftype *fetch_tls_load_module_address; @@ -312,6 +314,8 @@ default_memory_insert_breakpoint, /* memory_insert_breakpoint */ default_memory_remove_breakpoint, /* memory_remove_breakpoint */ 0, /* decr_pc_after_break */ + 0, /* skip_program_breakpoint */ + 0, /* describe_program_breakpoint */ 0, /* deprecated_function_start_offset */ default_remote_register_number, /* remote_register_number */ 0, /* fetch_tls_load_module_address */ @@ -550,6 +554,10 @@ /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */ /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */ /* Skip verify of decr_pc_after_break, invalid_p == 0 */ + if (gdbarch->skip_program_breakpoint == 0) + gdbarch->skip_program_breakpoint = default_skip_program_breakpoint; + if (gdbarch->describe_program_breakpoint == 0) + gdbarch->describe_program_breakpoint = default_describe_program_breakpoint; /* Skip verify of deprecated_function_start_offset, invalid_p == 0 */ /* Skip verify of remote_register_number, invalid_p == 0 */ /* Skip verify of fetch_tls_load_module_address, has predicate */ @@ -709,6 +717,9 @@ "gdbarch_dump: deprecated_function_start_offset = 0x%s\n", paddr_nz (gdbarch->deprecated_function_start_offset)); fprintf_unfiltered (file, + "gdbarch_dump: describe_program_breakpoint = <0x%lx>\n", + (long) gdbarch->describe_program_breakpoint); + fprintf_unfiltered (file, "gdbarch_dump: double_bit = %s\n", paddr_d (gdbarch->double_bit)); fprintf_unfiltered (file, @@ -940,6 +951,9 @@ "gdbarch_dump: skip_permanent_breakpoint = <0x%lx>\n", (long) gdbarch->skip_permanent_breakpoint); fprintf_unfiltered (file, + "gdbarch_dump: skip_program_breakpoint = <0x%lx>\n", + (long) gdbarch->skip_program_breakpoint); + fprintf_unfiltered (file, "gdbarch_dump: skip_prologue = <0x%lx>\n", (long) gdbarch->skip_prologue); fprintf_unfiltered (file, @@ -2183,6 +2197,40 @@ gdbarch->decr_pc_after_break = decr_pc_after_break; } +void +gdbarch_skip_program_breakpoint (struct gdbarch *gdbarch, int kind) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->skip_program_breakpoint != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_program_breakpoint called\n"); + gdbarch->skip_program_breakpoint (kind); +} + +void +set_gdbarch_skip_program_breakpoint (struct gdbarch *gdbarch, + gdbarch_skip_program_breakpoint_ftype skip_program_breakpoint) +{ + gdbarch->skip_program_breakpoint = skip_program_breakpoint; +} + +const char * +gdbarch_describe_program_breakpoint (struct gdbarch *gdbarch, int kind) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->describe_program_breakpoint != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_describe_program_breakpoint called\n"); + return gdbarch->describe_program_breakpoint (kind); +} + +void +set_gdbarch_describe_program_breakpoint (struct gdbarch *gdbarch, + gdbarch_describe_program_breakpoint_ftype describe_program_breakpoint) +{ + gdbarch->describe_program_breakpoint = describe_program_breakpoint; +} + CORE_ADDR gdbarch_deprecated_function_start_offset (struct gdbarch *gdbarch) { diff -urN gdb-6.8-orig/gdb/gdbarch.h gdb-6.8-new/gdb/gdbarch.h --- gdb-6.8-orig/gdb/gdbarch.h 2009-03-19 17:29:47.000000000 -0700 +++ gdb-6.8-new/gdb/gdbarch.h 2009-03-20 11:29:24.000000000 -0700 @@ -399,6 +399,21 @@ extern CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch); extern void set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch, CORE_ADDR decr_pc_after_break); +/* TENSILICA_LOCAL + Program breakpoints. These are break instructions in the target code, + not planted by GDB. Define this to skip program breakpoints: */ + +typedef void (gdbarch_skip_program_breakpoint_ftype) (int kind); +extern void gdbarch_skip_program_breakpoint (struct gdbarch *gdbarch, int kind); +extern void set_gdbarch_skip_program_breakpoint (struct gdbarch *gdbarch, gdbarch_skip_program_breakpoint_ftype *skip_program_breakpoint); + +/* TENSILICA_LOCAL + Define this to describe program breakpoints: */ + +typedef const char * (gdbarch_describe_program_breakpoint_ftype) (int kind); +extern const char * gdbarch_describe_program_breakpoint (struct gdbarch *gdbarch, int kind); +extern void set_gdbarch_describe_program_breakpoint (struct gdbarch *gdbarch, gdbarch_describe_program_breakpoint_ftype *describe_program_breakpoint); + /* A function can be addressed by either it's "pointer" (possibly a descriptor address) or "entry point" (first executable instruction). The method "convert_from_func_ptr_addr" converting the former to the diff -urN gdb-6.8-orig/gdb/gdbarch.sh gdb-6.8-new/gdb/gdbarch.sh --- gdb-6.8-orig/gdb/gdbarch.sh 2009-03-19 17:29:47.000000000 -0700 +++ gdb-6.8-new/gdb/gdbarch.sh 2009-03-20 11:29:09.000000000 -0700 @@ -484,6 +484,14 @@ m:int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0 v:CORE_ADDR:decr_pc_after_break:::0:::0 +# TENSILICA_LOCAL +# Program breakpoints. These are break instructions in the target code, +# not planted by GDB. Define this to skip program breakpoints: +f:void:skip_program_breakpoint:int kind:kind:::default_skip_program_breakpoint::0 +# TENSILICA_LOCAL +# Define this to describe program breakpoints: +f:const char *:describe_program_breakpoint:int kind:kind:::default_describe_program_breakpoint::0 + # A function can be addressed by either it's "pointer" (possibly a # descriptor address) or "entry point" (first executable instruction). # The method "convert_from_func_ptr_addr" converting the former to the diff -urN gdb-6.8-orig/gdb/infcmd.c gdb-6.8-new/gdb/infcmd.c --- gdb-6.8-orig/gdb/infcmd.c 2009-03-19 17:29:48.000000000 -0700 +++ gdb-6.8-new/gdb/infcmd.c 2009-03-20 11:33:21.000000000 -0700 @@ -696,6 +696,9 @@ struct frame_info *frame; struct cleanup *cleanups = 0; int async_exec = 0; +/* TENSILICA_LOCAL */ + int program_break_kind; +/* END TENSILICA_LOCAL */ ERROR_NO_INFERIOR; @@ -725,6 +728,33 @@ else make_exec_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/); } +/* TENSILICA_LOCAL */ + else if (STOPPED_BY_PROGRAM_BREAKPOINT (&program_break_kind) && + read_pc() == stop_pc && count > 0) + { + /* "stepi" off program breakpoint: the first step is to just increment + the PC past the break, then there are count-1 steps to go. + Note proceed() won't be called the first time, and on subsequent + steps the PC will already be off the break, so the entire handling + of "stepi" off a program breakpoint is done here. If stopping after + the break, display location information as for normal_stop. */ + count--; + gdbarch_skip_program_breakpoint (current_gdbarch, program_break_kind); + if (count == 0) + { + deprecated_update_frame_pc_hack (get_current_frame (), read_pc ()); + if (ui_out_is_mi_like_p (uiout)) + { + ui_out_field_string (uiout, "reason", "end-stepping-range"); + ui_out_field_int (uiout, "thread-id", + pid_to_thread_id (inferior_ptid)); + print_stack_frame (get_selected_frame (NULL), -1, LOC_AND_ADDRESS); + } + else + print_stack_frame (get_selected_frame (NULL), -1, SRC_LINE); + } + } +/* END TENSILICA_LOCAL */ /* In synchronous case, all is well, just use the regular for loop. */ if (!target_can_async_p ()) diff -urN gdb-6.8-orig/gdb/infrun.c gdb-6.8-new/gdb/infrun.c --- gdb-6.8-orig/gdb/infrun.c 2009-03-19 17:29:48.000000000 -0700 +++ gdb-6.8-new/gdb/infrun.c 2009-03-20 11:36:37.000000000 -0700 @@ -511,6 +511,9 @@ resume (int step, enum target_signal sig) { int should_resume = 1; +/* TENSILICA_LOCAL */ + int program_break_kind; +/* END TENSILICA_LOCAL */ struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0); QUIT; @@ -549,6 +552,18 @@ a command like `return' or `jump' to continue execution.")); } +/* TENSILICA_LOCAL */ + /* Skip a program breakpoint, unless PC changed without running inferior. + This is the same as skipping a permanent breakpoint, except that + the preceding macro does not provide an argument to differentiate + varieties of break instructions to skip, requiring the implementation + to probe and decode the target code. Also the SKIP_PERMANENT_BREAKPOINT + macro is used only by HPPA and is not in gdbarch.h. */ + if (STOPPED_BY_PROGRAM_BREAKPOINT (&program_break_kind) && + read_pc() == stop_pc) + gdbarch_skip_program_breakpoint (current_gdbarch, program_break_kind); +/* END TENSILICA_LOCAL */ + if (step && gdbarch_software_single_step_p (current_gdbarch)) { /* Do it the hard way, w/temp breakpoints */ @@ -928,7 +943,11 @@ /* Inferior exited. */ EXITED, /* Inferior received signal, and user asked to be notified. */ - SIGNAL_RECEIVED + SIGNAL_RECEIVED, +/* TENSILICA_LOCAL */ + /* Inferior stopped because of program breakpoint. */ + PROGRAM_BREAK +/* END TENSILICA_LOCAL */ }; /* This structure contains what used to be local variables in @@ -2007,6 +2026,9 @@ ecs->random_signal = !(bpstat_explains_signal (stop_bpstat) || stepping_over_breakpoint +/* TENSILICA_LOCAL */ + || STOPPED_BY_PROGRAM_BREAKPOINT (NULL) +/* END TENSILICA_LOCAL */ || (step_range_end && step_resume_breakpoint == NULL)); else { @@ -2329,6 +2351,23 @@ } } +/* TENSILICA_LOCAL */ + /* Handle case of hitting a program breakpoint (break instruction + in target program, not planted by or known to GDB). */ + + if (STOPPED_BY_PROGRAM_BREAKPOINT (NULL)) + { + stop_print_frame = 1; + + /* We are about to nuke the step_resume_breakpoint and + through_sigtramp_breakpoint via the cleanup chain, so + no need to worry about it here. */ + + stop_stepping (ecs); + return; + } +/* END TENSILICA_LOCAL */ + /* We come here if we hit a breakpoint but should not stop for it. Possibly we also were stepping and should stop for that. So fall through and @@ -3023,6 +3062,20 @@ (uiout, "reason", async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE)); break; +/* TENSILICA_LOCAL */ + case PROGRAM_BREAK: + /* This stop reason is used only for program breaks, never planted. */ + { + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_string (uiout, "reason", "program-breakpoint"); + ui_out_text (uiout, "\nProgram breakpoint \""); + ui_out_field_fmt (uiout, "break-insn", "%s", + gdbarch_describe_program_breakpoint (current_gdbarch, stop_info)); + ui_out_text (uiout, "\", "); + /* to be followed by source location, as for planted breakpoint */ + } + break; +/* END TENSILICA_LOCAL */ case SIGNAL_EXITED: /* The inferior was terminated by a signal. */ annotate_signalled (); @@ -3208,10 +3261,21 @@ int source_flag; int do_frame_printing = 1; - bpstat_ret = bpstat_print (stop_bpstat); - switch (bpstat_ret) +/* TENSILICA_LOCAL */ + /* Print program break stop reason and description. */ + + if (STOPPED_BY_PROGRAM_BREAKPOINT (&bpstat_ret)) + { + print_stop_reason (PROGRAM_BREAK, bpstat_ret); + source_flag = SRC_AND_LOC; /* print location and source line */ + } + else { - case PRINT_UNKNOWN: +/* END TENSILICA_LOCAL */ + bpstat_ret = bpstat_print (stop_bpstat); + switch (bpstat_ret) + { + case PRINT_UNKNOWN: /* If we had hit a shared library event breakpoint, bpstat_print would print out this message. If we hit an OS-level shared library event, do the same @@ -3224,30 +3288,34 @@ break; } - /* FIXME: cagney/2002-12-01: Given that a frame ID does - (or should) carry around the function and does (or - should) use that when doing a frame comparison. */ - if (stop_step - && frame_id_eq (step_frame_id, - get_frame_id (get_current_frame ())) - && step_start_function == find_pc_function (stop_pc)) - source_flag = SRC_LINE; /* finished step, just print source line */ - else - source_flag = SRC_AND_LOC; /* print location and source line */ - break; - case PRINT_SRC_AND_LOC: - source_flag = SRC_AND_LOC; /* print location and source line */ - break; - case PRINT_SRC_ONLY: - source_flag = SRC_LINE; - break; - case PRINT_NOTHING: - source_flag = SRC_LINE; /* something bogus */ - do_frame_printing = 0; - break; - default: - internal_error (__FILE__, __LINE__, _("Unknown value.")); + /* FIXME: cagney/2002-12-01: Given that a frame ID does + (or should) carry around the function and does (or + should) use that when doing a frame comparison. */ + if (stop_step + && frame_id_eq (step_frame_id, + get_frame_id (get_current_frame ())) + && step_start_function == find_pc_function (stop_pc)) + source_flag = SRC_LINE; /* finished step, just print source line */ + else + source_flag = SRC_AND_LOC; /* print location and source line */ + break; + case PRINT_SRC_AND_LOC: + source_flag = SRC_AND_LOC; /* print location and source line */ + break; + case PRINT_SRC_ONLY: + source_flag = SRC_LINE; + break; + case PRINT_NOTHING: + source_flag = SRC_LINE; /* something bogus */ + do_frame_printing = 0; + break; + default: + internal_error (__FILE__, __LINE__, _("Unknown value.")); + } +/* TENSILICA_LOCAL */ } +/* END TENSILICA_LOCAL */ + if (ui_out_is_mi_like_p (uiout)) ui_out_field_int (uiout, "thread-id", diff -urN gdb-6.8-orig/gdb/remote.c gdb-6.8-new/gdb/remote.c --- gdb-6.8-orig/gdb/remote.c 2009-03-19 17:29:48.000000000 -0700 +++ gdb-6.8-new/gdb/remote.c 2009-03-20 11:41:52.000000000 -0700 @@ -473,6 +473,15 @@ /* This is non-zero if target stopped for a watchpoint. */ static int remote_stopped_by_watchpoint_p; +/* TENSILICA_LOCAL */ +/* This is non-zero if target stopped for a program breakpoint. */ +static int remote_stopped_by_program_breakpoint_p = 0; + +/* This is set to a architecture-specific representation of the kind of + program breakpoint if remote_stopped_by_program_breakpoint_p != 0. */ +static int remote_program_breakpoint_kind = 0; +/* END TENSILICA_LOCAL */ + static struct target_ops remote_ops; static struct target_ops extended_remote_ops; @@ -3399,6 +3408,9 @@ (*deprecated_target_wait_loop_hook) (); remote_stopped_by_watchpoint_p = 0; +/* TENSILICA_LOCAL */ + remote_stopped_by_program_breakpoint_p = 0; +/* END TENSILICA_LOCAL */ switch (buf[0]) { @@ -3474,6 +3486,19 @@ solibs_changed = 1; p = p_temp; } +/* TENSILICA_LOCAL */ + else if ((strncmp (p, "pbreak", p1 - p) == 0)) + { + /* Protocol extension for program break 'TAApbreak:kind' + where kind is an arch-specific integer encoding info + about the break instruction (eg. size, type, args). */ + ULONGEST kind; + + remote_stopped_by_program_breakpoint_p = 1; + p = unpack_varlen_hex (++p1, &kind); + remote_program_breakpoint_kind = (int)kind; + } +/* END TENSILICA_LOCAL */ else { /* Silently skip unknown optional info. */ @@ -3592,6 +3617,11 @@ remote_stopped_by_watchpoint_p = 0; +/* TENSILICA_LOCAL */ + remote_stopped_by_program_breakpoint_p = 0; + sigint_interrupt_flag = 0; +/* END TENSILICA_LOCAL PR */ + while (1) { char *buf, *p; @@ -3702,6 +3732,18 @@ solibs_changed = 1; p = p_temp; } +/* TENSILICA_LOCAL */ + else if ((strncmp (p, "pbreak", p1 - p) == 0)) + { + /* Protocol extension for program break 'TAApbreak:kind' + where kind is an arch-specific integer. */ + ULONGEST kind; + + remote_stopped_by_program_breakpoint_p = 1; + p = unpack_varlen_hex (++p1, &kind); + remote_program_breakpoint_kind = (int)kind; + } +/* END TENSILICA_LOCAL */ else { /* Silently skip unknown optional info. */ @@ -5720,6 +5762,19 @@ return rc; } +/* TENSILICA_LOCAL */ +/* Return non-zero if target was stopped by a program breakpoint. + If so and kind != NULL, set *kind to an architecture-specific value. */ + +static int +remote_stopped_by_program_breakpoint (int *kind) +{ + if (remote_stopped_by_program_breakpoint_p && kind != NULL) + *kind = remote_program_breakpoint_kind; + return remote_stopped_by_program_breakpoint_p; +} +/* END TENSILICA_LOCAL */ + static int remote_insert_hw_breakpoint (struct bp_target_info *bp_tgt) @@ -7229,6 +7284,10 @@ remote_ops.to_remove_breakpoint = remote_remove_breakpoint; remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; remote_ops.to_stopped_data_address = remote_stopped_data_address; +/* TENSILICA_LOCAL */ + remote_ops.to_stopped_by_program_breakpoint = + remote_stopped_by_program_breakpoint; +/* END TENSILICA_LOCAL */ remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; @@ -7365,6 +7424,10 @@ remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint; remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; remote_async_ops.to_stopped_data_address = remote_stopped_data_address; +/* TENSILICA_LOCAL */ + remote_async_ops.to_stopped_by_program_breakpoint = + remote_stopped_by_program_breakpoint; +/* END TENSILICA_LOCAL */ remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior; remote_async_ops.to_terminal_ours = remote_async_terminal_ours; remote_async_ops.to_kill = remote_async_kill; diff -urN gdb-6.8-orig/gdb/target.c gdb-6.8-new/gdb/target.c --- gdb-6.8-orig/gdb/target.c 2009-03-19 17:29:49.000000000 -0700 +++ gdb-6.8-new/gdb/target.c 2009-03-20 11:44:22.000000000 -0700 @@ -410,6 +410,9 @@ INHERIT (to_insert_watchpoint, t); INHERIT (to_remove_watchpoint, t); INHERIT (to_stopped_data_address, t); +/* TENSILICA_LOCAL */ + INHERIT (to_stopped_by_program_breakpoint, t); +/* END TENSILICA_LOCAL */ INHERIT (to_stopped_by_watchpoint, t); INHERIT (to_have_steppable_watchpoint, t); INHERIT (to_have_continuable_watchpoint, t); @@ -539,6 +542,11 @@ de_fault (to_stopped_data_address, (int (*) (struct target_ops *, CORE_ADDR *)) return_zero); +/* TENSILICA_LOCAL -- Program breakpoint. */ + de_fault (to_stopped_by_program_breakpoint, + (int (*) (int*)) + return_zero); +/* END TENSILICA_LOCAL */ de_fault (to_region_ok_for_hw_watchpoint, default_region_ok_for_hw_watchpoint); de_fault (to_terminal_init, @@ -2400,6 +2408,22 @@ return retval; } +/* TENSILICA_LOCAL */ +static int +debug_to_stopped_by_program_breakpoint (int *kind) +{ + int retval; + + retval = debug_target.to_stopped_by_program_breakpoint (kind); + + fprintf_unfiltered (gdb_stdlog, + "target_stopped_by_program_breakpoint (%ld) = %ld\n", + (unsigned long) *kind, + (unsigned long) retval); + return retval; +} +/* END TENSILICA_LOCAL */ + static void debug_to_terminal_init (void) { @@ -2703,6 +2727,9 @@ current_target.to_remove_watchpoint = debug_to_remove_watchpoint; current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint; current_target.to_stopped_data_address = debug_to_stopped_data_address; +/* TENSILICA_LOCAL */ + current_target.to_stopped_by_program_breakpoint = debug_to_stopped_by_program_breakpoint; +/* END TENSILICA_LOCAL */ current_target.to_region_ok_for_hw_watchpoint = debug_to_region_ok_for_hw_watchpoint; current_target.to_terminal_init = debug_to_terminal_init; current_target.to_terminal_inferior = debug_to_terminal_inferior; diff -urN gdb-6.8-orig/gdb/target.h gdb-6.8-new/gdb/target.h --- gdb-6.8-orig/gdb/target.h 2009-03-19 17:29:49.000000000 -0700 +++ gdb-6.8-new/gdb/target.h 2009-03-20 11:45:20.000000000 -0700 @@ -369,6 +369,9 @@ int to_have_continuable_watchpoint; int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *); int (*to_region_ok_for_hw_watchpoint) (CORE_ADDR, int); +/* TENSILICA_LOCAL -- Program breakpoints */ + int (*to_stopped_by_program_breakpoint) (int *); +/* END TENSILICA_LOCAL */ void (*to_terminal_init) (void); void (*to_terminal_inferior) (void); void (*to_terminal_ours_for_output) (void); @@ -1107,6 +1110,18 @@ extern const struct target_desc *target_read_description (struct target_ops *); +/* TENSILICA_LOCAL */ +/* Returns non-zero if we were stopped by a program breakpoint (break instr + embedded in the target code, not planted by GDB). If k != 0, sets *k to + an arch-specific integer indicating the kind of break instruction. */ + +#ifndef STOPPED_BY_PROGRAM_BREAKPOINT +#define STOPPED_BY_PROGRAM_BREAKPOINT(k) \ + (*current_target.to_stopped_by_program_breakpoint) (k) +#endif +/* END TENSILICA_LOCAL */ + + /* Command logging facility. */ #define target_log_command(p) \ diff -urN gdb-6.8-orig/gdb/xtensa-tdep.c gdb-6.8-new/gdb/xtensa-tdep.c --- gdb-6.8-orig/gdb/xtensa-tdep.c 2009-03-19 17:29:49.000000000 -0700 +++ gdb-6.8-new/gdb/xtensa-tdep.c 2009-03-20 11:52:50.000000000 -0700 @@ -2454,6 +2454,34 @@ return body_pc != 0 ? body_pc : start_pc; } +/* TENSILICA_LOCAL */ +static void +xtensa_skip_program_breakpoint (int kind) +{ + DEBUGTRACE ("xtensa_skip_program_breakpoint (pc = 0x%08x, kind = 0x%03x)\n", + (unsigned)read_pc (), kind); + + write_pc (read_pc () + 2 + ((kind >> 8) & 1)); + return; +} + +/* Provide a string description of a program breakpoint of a given kind. */ + +static const char * +xtensa_describe_program_breakpoint (int kind) +{ +/* Keep an eye: potential conflict with concurrent instances of this arch. */ + static char descr[16]; + int len; + + len = sprintf (descr, "break%s %u,%u", + (kind & 0xf00) ? "" : ".n", + (kind & 0x0f0) >> 4, + (kind & 0x00f)); + gdb_assert (len < 16); + return descr; +} + /* Verify the current configuration. */ static void xtensa_verify_config (struct gdbarch *gdbarch) @@ -2632,6 +2660,14 @@ /* Advance PC across any prologue instructions to reach "real" code. */ set_gdbarch_skip_prologue (gdbarch, xtensa_skip_prologue); +/* TENSILICA_LOCAL */ + /* Handle program breakpoints not planted by GDB. + It's Xtensa-specific, although we want to submit it. */ + set_gdbarch_skip_program_breakpoint (gdbarch, xtensa_skip_program_breakpoint); + set_gdbarch_describe_program_breakpoint (gdbarch, + xtensa_describe_program_breakpoint); +/* END TENSILICA_LOCAL */ + /* Stack grows downward. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);