diff options
author | kib <kib@FreeBSD.org> | 2008-09-27 15:58:37 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-09-27 15:58:37 +0000 |
commit | 802c3a101549b6fba5032c0e2cfe71891dfd8f21 (patch) | |
tree | 445fc0de89b305db93db01a86e0155f6f51bccf9 | |
parent | e6297afce29b524a8ee4e58ae9032d87c18c9705 (diff) | |
download | FreeBSD-src-802c3a101549b6fba5032c0e2cfe71891dfd8f21.zip FreeBSD-src-802c3a101549b6fba5032c0e2cfe71891dfd8f21.tar.gz |
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
-rw-r--r-- | gnu/usr.bin/gdb/kgdb/trgt_i386.c | 36 |
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 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); } |