/* Definitions for frame unwinder, for GDB, the GNU debugger.
- Copyright (C) 2003-2019 Free Software Foundation, Inc.
+ Copyright (C) 2003-2020 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-
-/* Local non-gdb includes. */
-#include "dummy-frame.h"
-#include "frame-unwind.h"
#include "frame.h"
-#include "gdb_obstack.h"
+#include "frame-unwind.h"
+#include "dummy-frame.h"
#include "inline-frame.h"
+#include "value.h"
#include "regcache.h"
+#include "gdb_obstack.h"
#include "target.h"
-#include "value.h"
+#include "gdbarch.h"
+#include "dwarf2/frame-tailcall.h"
static struct gdbarch_data *frame_unwind_data;
struct frame_unwind_table_entry **osabi_head;
};
+/* A helper function to add an unwinder to a list. LINK says where to
+ install the new unwinder. The new link is returned. */
+
+static struct frame_unwind_table_entry **
+add_unwinder (struct obstack *obstack, const struct frame_unwind *unwinder,
+ struct frame_unwind_table_entry **link)
+{
+ *link = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
+ (*link)->unwinder = unwinder;
+ return &(*link)->next;
+}
+
static void *
frame_unwind_init (struct obstack *obstack)
{
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
- table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
- table->list->unwinder = &dummy_frame_unwind;
- table->list->next = OBSTACK_ZALLOC (obstack,
- struct frame_unwind_table_entry);
- table->list->next->unwinder = &inline_frame_unwind;
+ struct frame_unwind_table_entry **link = &table->list;
+
+ link = add_unwinder (obstack, &dummy_frame_unwind, link);
+ /* The DWARF tailcall sniffer must come before the inline sniffer.
+ Otherwise, we can end up in a situation where a DWARF frame finds
+ tailcall information, but then the inline sniffer claims a frame
+ before the tailcall sniffer, resulting in confusion. This is
+ safe to do always because the tailcall sniffer can only ever be
+ activated if the newer frame was created using the DWARF
+ unwinder, and it also found tailcall information. */
+ link = add_unwinder (obstack, &dwarf2_tailcall_frame_unwind, link);
+ link = add_unwinder (obstack, &inline_frame_unwind, link);
+
/* The insertion point for OSABI sniffers. */
- table->osabi_head = &table->list->next->next;
+ table->osabi_head = link;
return table;
}
frame_prepare_for_sniffer (this_frame, unwinder);
- TRY
+ try
{
res = unwinder->sniffer (unwinder, this_frame, this_cache);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
/* Catch all exceptions, caused by either interrupt or error.
Reset *THIS_CACHE. */
should always accept the frame. */
return 0;
}
- throw_exception (ex);
+ throw;
}
- END_CATCH
if (res)
return 1;
return reg_val;
}
+void _initialize_frame_unwind ();
void
-_initialize_frame_unwind (void)
+_initialize_frame_unwind ()
{
frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init);
}