+ gdb_assert_not_reached ("frame_unwind_try_unwinder");
+}
+
+/* Iterate through sniffers for THIS_FRAME frame until one returns with an
+ unwinder implementation. THIS_FRAME->UNWIND must be NULL, it will get set
+ by this function. Possibly initialize THIS_CACHE. */
+
+void
+frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct frame_unwind_table *table
+ = (struct frame_unwind_table *) gdbarch_data (gdbarch, frame_unwind_data);
+ struct frame_unwind_table_entry *entry;
+ const struct frame_unwind *unwinder_from_target;
+
+ unwinder_from_target = target_get_unwinder ();
+ if (unwinder_from_target != NULL
+ && frame_unwind_try_unwinder (this_frame, this_cache,
+ unwinder_from_target))
+ return;
+
+ unwinder_from_target = target_get_tailcall_unwinder ();
+ if (unwinder_from_target != NULL
+ && frame_unwind_try_unwinder (this_frame, this_cache,
+ unwinder_from_target))
+ return;
+
+ for (entry = table->list; entry != NULL; entry = entry->next)
+ if (frame_unwind_try_unwinder (this_frame, this_cache, entry->unwinder))
+ return;
+
+ internal_error (__FILE__, __LINE__, _("frame_unwind_find_by_frame failed"));
+}
+
+/* A default frame sniffer which always accepts the frame. Used by
+ fallback prologue unwinders. */
+
+int
+default_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ return 1;
+}
+
+/* The default frame unwinder stop_reason callback. */
+
+enum unwind_stop_reason
+default_frame_unwind_stop_reason (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct frame_id this_id = get_frame_id (this_frame);
+
+ if (frame_id_eq (this_id, outer_frame_id))
+ return UNWIND_OUTERMOST;
+ else
+ return UNWIND_NO_REASON;
+}
+
+/* Helper functions for value-based register unwinding. These return
+ a (possibly lazy) value of the appropriate type. */
+
+/* Return a value which indicates that FRAME did not save REGNUM. */
+
+struct value *
+frame_unwind_got_optimized (struct frame_info *frame, int regnum)
+{
+ struct gdbarch *gdbarch = frame_unwind_arch (frame);
+ struct type *type = register_type (gdbarch, regnum);
+ struct value *val;
+
+ /* Return an lval_register value, so that we print it as
+ "<not saved>". */
+ val = allocate_value_lazy (type);
+ set_value_lazy (val, 0);
+ mark_value_bytes_optimized_out (val, 0, TYPE_LENGTH (type));
+ VALUE_LVAL (val) = lval_register;
+ VALUE_REGNUM (val) = regnum;
+ VALUE_NEXT_FRAME_ID (val)
+ = get_frame_id (get_next_frame_sentinel_okay (frame));
+ return val;
+}
+
+/* Return a value which indicates that FRAME copied REGNUM into
+ register NEW_REGNUM. */
+
+struct value *
+frame_unwind_got_register (struct frame_info *frame,
+ int regnum, int new_regnum)
+{
+ return value_of_register_lazy (frame, new_regnum);
+}
+
+/* Return a value which indicates that FRAME saved REGNUM in memory at
+ ADDR. */
+
+struct value *
+frame_unwind_got_memory (struct frame_info *frame, int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = frame_unwind_arch (frame);
+ struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);
+
+ set_value_stack (v, 1);
+ return v;