/* Definitions for frame unwinder, for GDB, the GNU debugger.
- Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "inline-frame.h"
#include "value.h"
#include "regcache.h"
-#include "exceptions.h"
-#include "gdb_assert.h"
#include "gdb_obstack.h"
#include "target.h"
+#include "gdbarch.h"
static struct gdbarch_data *frame_unwind_data;
frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder)
{
- struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
+ struct frame_unwind_table *table
+ = (struct frame_unwind_table *) gdbarch_data (gdbarch, frame_unwind_data);
struct frame_unwind_table_entry *entry;
/* Insert the new entry at the start of the list. */
frame_unwind_append_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder)
{
- struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
+ struct frame_unwind_table *table
+ = (struct frame_unwind_table *) gdbarch_data (gdbarch, frame_unwind_data);
struct frame_unwind_table_entry **ip;
/* Find the end of the list and insert the new entry there. */
frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
const struct frame_unwind *unwinder)
{
- struct cleanup *old_cleanup;
- volatile struct gdb_exception ex;
int res = 0;
- old_cleanup = frame_prepare_for_sniffer (this_frame, unwinder);
+ frame_prepare_for_sniffer (this_frame, unwinder);
- TRY_CATCH (ex, RETURN_MASK_ERROR)
+ try
{
res = unwinder->sniffer (unwinder, this_frame, this_cache);
}
- if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
- {
- /* This usually means that not even the PC is available,
- thus most unwinders aren't able to determine if they're
- the best fit. Keep trying. Fallback prologue unwinders
- should always accept the frame. */
- do_cleanups (old_cleanup);
- return 0;
- }
- else if (ex.reason < 0)
- throw_exception (ex);
- else if (res)
+ catch (const gdb_exception &ex)
{
- discard_cleanups (old_cleanup);
- return 1;
+ /* Catch all exceptions, caused by either interrupt or error.
+ Reset *THIS_CACHE. */
+ *this_cache = NULL;
+ frame_cleanup_after_sniffer (this_frame);
+
+ if (ex.error == NOT_AVAILABLE_ERROR)
+ {
+ /* This usually means that not even the PC is available,
+ thus most unwinders aren't able to determine if they're
+ the best fit. Keep trying. Fallback prologue unwinders
+ should always accept the frame. */
+ return 0;
+ }
+ throw;
}
+
+ if (res)
+ return 1;
else
{
- do_cleanups (old_cleanup);
+ /* Don't set *THIS_CACHE to NULL here, because sniffer has to do
+ so. */
+ frame_cleanup_after_sniffer (this_frame);
return 0;
}
gdb_assert_not_reached ("frame_unwind_try_unwinder");
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 = gdbarch_data (gdbarch, frame_unwind_data);
+ 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;
return UNWIND_NO_REASON;
}
+/* See frame-unwind.h. */
+
+CORE_ADDR
+default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ int pc_regnum = gdbarch_pc_regnum (gdbarch);
+ CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum);
+ pc = gdbarch_addr_bits_remove (gdbarch, pc);
+ return pc;
+}
+
+/* See frame-unwind.h. */
+
+CORE_ADDR
+default_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ int sp_regnum = gdbarch_sp_regnum (gdbarch);
+ return frame_unwind_register_unsigned (next_frame, sp_regnum);
+}
+
/* Helper functions for value-based register unwinding. These return
a (possibly lazy) value of the appropriate type. */
"<not saved>". */
val = allocate_value_lazy (type);
set_value_lazy (val, 0);
- set_value_optimized_out (val, 1);
+ mark_value_bytes_optimized_out (val, 0, TYPE_LENGTH (type));
VALUE_LVAL (val) = lval_register;
VALUE_REGNUM (val) = regnum;
- VALUE_FRAME_ID (val) = get_frame_id (frame);
+ VALUE_NEXT_FRAME_ID (val)
+ = get_frame_id (get_next_frame_sentinel_okay (frame));
return val;
}
return reg_val;
}
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_frame_unwind;
-
void
_initialize_frame_unwind (void)
{