aboutsummaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2008-09-27 15:58:37 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2008-09-27 15:58:37 +0000
commit42003afced7bd8be111838173be371d75be0f341 (patch)
tree445fc0de89b305db93db01a86e0155f6f51bccf9 /gnu
parentd558cef9e6577a0d7d9118afbb620f60ca0433a9 (diff)
downloadsrc-42003afced7bd8be111838173be371d75be0f341.tar.gz
src-42003afced7bd8be111838173be371d75be0f341.zip
Differentiate between interrupt frames, trap interrupt frames and timer
frame in the kgdb, to allow it to properly backtrace over the interrupt stacks. Noted and reviewed by: tegge Tested by: pho MFC after: 1 week
Notes
Notes: svn path=/head/; revision=183414
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index 879caea60536..4a66906de62c 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
@@ -242,10 +242,14 @@ static const struct frame_unwind kgdb_trgt_dblfault_unwind = {
};
struct kgdb_frame_cache {
- int intrframe;
+ int frame_type;
CORE_ADDR pc;
CORE_ADDR sp;
};
+#define FT_NORMAL 1
+#define FT_INTRFRAME 2
+#define FT_INTRTRAPFRAME 3
+#define FT_TIMERFRAME 4
static int kgdb_trgt_frame_offset[15] = {
offsetof(struct trapframe, tf_eax),
@@ -278,7 +282,17 @@ kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
*this_cache = cache;
cache->pc = frame_func_unwind(next_frame);
find_pc_partial_function(cache->pc, &pname, NULL, NULL);
- cache->intrframe = (pname[0] == 'X') ? 1 : 0;
+ if (pname[0] != 'X')
+ cache->frame_type = FT_NORMAL;
+ else if (strcmp(pname, "Xtimerint") == 0)
+ cache->frame_type = FT_TIMERFRAME;
+ else if (strcmp(pname, "Xcpustop") == 0 ||
+ strcmp(pname, "Xrendezvous") == 0 ||
+ strcmp(pname, "Xipi_intr_bitmap_handler") == 0 ||
+ strcmp(pname, "Xlazypmap") == 0)
+ cache->frame_type = FT_INTRTRAPFRAME;
+ else
+ cache->frame_type = FT_INTRFRAME;
frame_unwind_register(next_frame, SP_REGNUM, buf);
cache->sp = extract_unsigned_integer(buf,
register_size(current_gdbarch, SP_REGNUM));
@@ -321,7 +335,23 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
return;
cache = kgdb_trgt_frame_cache(next_frame, this_cache);
- *addrp = cache->sp + ofs + (cache->intrframe ? 4 : 0);
+ switch (cache->frame_type) {
+ case FT_NORMAL:
+ break;
+ case FT_INTRFRAME:
+ ofs += 4;
+ break;
+ case FT_TIMERFRAME:
+ break;
+ case FT_INTRTRAPFRAME:
+ ofs -= ofs_fix;
+ break;
+ default:
+ fprintf_unfiltered(gdb_stderr, "Correct FT_XXX frame offsets "
+ "for %d\n", cache->frame_type);
+ break;
+ }
+ *addrp = cache->sp + ofs;
*lvalp = lval_memory;
target_read_memory(*addrp, valuep, regsz);
}