aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@gnu.org>2012-02-27 16:40:48 +0000
committerThomas Schwinge <tschwinge@gnu.org>2012-02-27 16:40:48 +0000
commitcb2cf4ce192f78f24ca010ecc21eae8b2b18c337 (patch)
treec393465e9cbdd8fe99123d06e316e8110b7b42b5
parent644cebc98ce121ef7e6a8c0d1867ae01e936b41b (diff)
downloadgdb-cb2cf4ce192f78f24ca010ecc21eae8b2b18c337.zip
gdb-cb2cf4ce192f78f24ca010ecc21eae8b2b18c337.tar.gz
gdb-cb2cf4ce192f78f24ca010ecc21eae8b2b18c337.tar.bz2
* sh-tdep.c (sh_make_stub_cache, sh_stub_this_id)
(sh_stub_unwind_sniffer): New functions. (sh_stub_unwind): New variable. (sh_gdbarch_init): Wire everything.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/sh-tdep.c53
2 files changed, 60 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e2379f4..02c9c42 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2012-02-27 Thomas Schwinge <thomas@codesourcery.com>
+
+ * sh-tdep.c (sh_make_stub_cache, sh_stub_this_id)
+ (sh_stub_unwind_sniffer): New functions.
+ (sh_stub_unwind): New variable.
+ (sh_gdbarch_init): Wire everything.
+
2012-02-27 Pedro Alves <palves@redhat.com>
* linux-nat.c (pid_is_stopped): Delete, moved to common/.
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 489bb40..e5b66b4 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -41,6 +41,7 @@
#include "osabi.h"
#include "reggroups.h"
#include "regset.h"
+#include "objfiles.h"
#include "sh-tdep.h"
@@ -2666,6 +2667,57 @@ static const struct frame_base sh_frame_base = {
sh_frame_base_address
};
+static struct sh_frame_cache *
+sh_make_stub_cache (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct sh_frame_cache *cache;
+
+ cache = sh_alloc_frame_cache ();
+
+ cache->saved_sp
+ = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
+
+ return cache;
+}
+
+static void
+sh_stub_this_id (struct frame_info *this_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sh_frame_cache *cache;
+
+ if (*this_cache == NULL)
+ *this_cache = sh_make_stub_cache (this_frame);
+ cache = *this_cache;
+
+ *this_id = frame_id_build (cache->saved_sp, get_frame_pc (this_frame));
+}
+
+static int
+sh_stub_unwind_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ CORE_ADDR addr_in_block;
+
+ addr_in_block = get_frame_address_in_block (this_frame);
+ if (in_plt_section (addr_in_block, NULL))
+ return 1;
+
+ return 0;
+}
+
+static const struct frame_unwind sh_stub_unwind =
+{
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ sh_stub_this_id,
+ sh_frame_prev_register,
+ NULL,
+ sh_stub_unwind_sniffer
+};
+
/* The epilogue is defined here as the area at the end of a function,
either on the `ret' instruction itself or after an instruction which
destroys the function's stack frame. */
@@ -3055,6 +3107,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
gdbarch_init_osabi (info, gdbarch);
dwarf2_append_unwinders (gdbarch);
+ frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
return gdbarch;