From 802c3a101549b6fba5032c0e2cfe71891dfd8f21 Mon Sep 17 00:00:00 2001 From: kib Date: Sat, 27 Sep 2008 15:58:37 +0000 Subject: 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 --- gnu/usr.bin/gdb/kgdb/trgt_i386.c | 36 +++++++++++++++++++++++++++++++++--- 1 file 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 879caea..4a66906 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); } -- cgit v1.1