+2016-05-23 Yao Qi <yao.qi@arm.com>
+
+ * arch-utils.c (default_code_of_frame_writable): New function.
+ * arch-utils.h (default_code_of_frame_writable): Declare.
+ * arm-tdep.c (arm_code_of_frame_writable): New function.
+ (arm_gdbarch_init): Install gdbarch method
+ code_of_frame_writable if the target is M-profile.
+ * frame.c (skip_unwritable_frames): New function.
+ * frame.h (skip_unwritable_frames): Declare.
+ * gdbarch.sh (code_of_frame_writable): New.
+ * gdbarch.c, gdbarch.h: Re-generated.
+ * infcmd.c (finish_command): Call skip_unwritable_frames.
+
2016-05-23 Tom Tromey <tom@tromey.com>
PR python/19438, PR python/18393:
return 0;
}
+int
+default_code_of_frame_writable (struct gdbarch *gdbarch,
+ struct frame_info *frame)
+{
+ return 1;
+}
+
/* Helper functions for gdbarch_inner_than */
int
extern int generic_stack_frame_destroyed_p (struct gdbarch *gdbarch,
CORE_ADDR pc);
+extern int default_code_of_frame_writable (struct gdbarch *gdbarch,
+ struct frame_info *frame);
+
/* By default, registers are not convertible. */
extern int generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
struct type *type);
/* Otherwise we don't have a useful guess. */
}
+/* Implement the code_of_frame_writable gdbarch method. */
+
+static int
+arm_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ if (gdbarch_tdep (gdbarch)->is_m
+ && get_frame_type (frame) == SIGTRAMP_FRAME)
+ {
+ /* M-profile exception frames return to some magic PCs, where
+ isn't writable at all. */
+ return 0;
+ }
+ else
+ return 1;
+}
+
\f
/* Initialize the current architecture based on INFO. If possible,
re-use an architecture from ARCHES, which is a list of
set_gdbarch_push_dummy_call (gdbarch, arm_push_dummy_call);
set_gdbarch_frame_align (gdbarch, arm_frame_align);
+ if (is_m)
+ set_gdbarch_code_of_frame_writable (gdbarch, arm_code_of_frame_writable);
+
set_gdbarch_write_pc (gdbarch, arm_write_pc);
/* Frame handling. */
return frame;
}
+struct frame_info *
+skip_unwritable_frames (struct frame_info *frame)
+{
+ while (gdbarch_code_of_frame_writable (get_frame_arch (frame), frame) == 0)
+ {
+ frame = get_prev_frame (frame);
+ if (frame == NULL)
+ break;
+ }
+
+ return frame;
+}
+
/* See frame.h. */
struct frame_info *
extern struct frame_info *skip_tailcall_frames (struct frame_info *frame);
+/* Return the first frame above FRAME or FRAME of which the code is
+ writable. */
+
+extern struct frame_info *skip_unwritable_frames (struct frame_info *frame);
+
#endif /* !defined (FRAME_H) */
gdbarch_push_dummy_call_ftype *push_dummy_call;
int call_dummy_location;
gdbarch_push_dummy_code_ftype *push_dummy_code;
+ gdbarch_code_of_frame_writable_ftype *code_of_frame_writable;
gdbarch_print_registers_info_ftype *print_registers_info;
gdbarch_print_float_info_ftype *print_float_info;
gdbarch_print_vector_info_ftype *print_vector_info;
gdbarch->dwarf2_reg_to_regnum = no_op_reg_to_regnum;
gdbarch->deprecated_fp_regnum = -1;
gdbarch->call_dummy_location = AT_ENTRY_POINT;
+ gdbarch->code_of_frame_writable = default_code_of_frame_writable;
gdbarch->print_registers_info = default_print_registers_info;
gdbarch->print_float_info = default_print_float_info;
gdbarch->register_sim_regno = legacy_register_sim_regno;
/* Skip verify of push_dummy_call, has predicate. */
/* Skip verify of call_dummy_location, invalid_p == 0 */
/* Skip verify of push_dummy_code, has predicate. */
+ /* Skip verify of code_of_frame_writable, invalid_p == 0 */
/* Skip verify of print_registers_info, invalid_p == 0 */
/* Skip verify of print_float_info, invalid_p == 0 */
/* Skip verify of print_vector_info, has predicate. */
fprintf_unfiltered (file,
"gdbarch_dump: char_signed = %s\n",
plongest (gdbarch->char_signed));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: code_of_frame_writable = <%s>\n",
+ host_address_to_string (gdbarch->code_of_frame_writable));
fprintf_unfiltered (file,
"gdbarch_dump: coff_make_msymbol_special = <%s>\n",
host_address_to_string (gdbarch->coff_make_msymbol_special));
gdbarch->push_dummy_code = push_dummy_code;
}
+int
+gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->code_of_frame_writable != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_code_of_frame_writable called\n");
+ return gdbarch->code_of_frame_writable (gdbarch, frame);
+}
+
+void
+set_gdbarch_code_of_frame_writable (struct gdbarch *gdbarch,
+ gdbarch_code_of_frame_writable_ftype code_of_frame_writable)
+{
+ gdbarch->code_of_frame_writable = code_of_frame_writable;
+}
+
void
gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all)
{
extern CORE_ADDR gdbarch_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr, struct regcache *regcache);
extern void set_gdbarch_push_dummy_code (struct gdbarch *gdbarch, gdbarch_push_dummy_code_ftype *push_dummy_code);
+/* Return true if the code of FRAME is writable. */
+
+typedef int (gdbarch_code_of_frame_writable_ftype) (struct gdbarch *gdbarch, struct frame_info *frame);
+extern int gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame);
+extern void set_gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, gdbarch_code_of_frame_writable_ftype *code_of_frame_writable);
+
typedef void (gdbarch_print_registers_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all);
extern void gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all);
extern void set_gdbarch_print_registers_info (struct gdbarch *gdbarch, gdbarch_print_registers_info_ftype *print_registers_info);
v:int:call_dummy_location::::AT_ENTRY_POINT::0
M:CORE_ADDR:push_dummy_code:CORE_ADDR sp, CORE_ADDR funaddr, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr, struct regcache *regcache:sp, funaddr, args, nargs, value_type, real_pc, bp_addr, regcache
+# Return true if the code of FRAME is writable.
+m:int:code_of_frame_writable:struct frame_info *frame:frame::default_code_of_frame_writable::0
+
m:void:print_registers_info:struct ui_file *file, struct frame_info *frame, int regnum, int all:file, frame, regnum, all::default_print_registers_info::0
m:void:print_float_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args::default_print_float_info::0
M:void:print_vector_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args
entering THISFRAME. */
frame = skip_tailcall_frames (frame);
+ frame = skip_unwritable_frames (frame);
+
if (frame == NULL)
error (_("Cannot find the caller frame."));