From 939fa31ee6b81113879b05cea222c56dd7e3ca19 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 27 Dec 2009 18:19:59 -0800 Subject: [PATCH] kgdb - Fix kernel trapframe backtraces for i386 * A recent gdb update removed our stack frame sniffer hooks, add them back in for i386. * I got trapframe to work properly for i386. I dunno about interrupt frames. --- gnu/usr.bin/gdb/kgdb/kgdb.c | 1 + gnu/usr.bin/gdb/kgdb/kgdb.h | 2 ++ gnu/usr.bin/gdb/kgdb/trgt.c | 2 ++ gnu/usr.bin/gdb/kgdb/trgt_i386.c | 17 +++++++++-------- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.c b/gnu/usr.bin/gdb/kgdb/kgdb.c index d38525f698..77ad5c50c9 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.c +++ b/gnu/usr.bin/gdb/kgdb/kgdb.c @@ -64,6 +64,7 @@ #include #include #include +#include #include "kgdb.h" diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h index 4b72303a23..40aa95a67f 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.h +++ b/gnu/usr.bin/gdb/kgdb/kgdb.h @@ -54,6 +54,8 @@ void kgdb_trgt_fetch_registers(struct target_ops *, struct regcache *, int); void kld_init(void); void kld_new_objfile(struct objfile *); +extern const struct frame_unwind kgdb_trgt_trapframe_unwind; + struct kthr *kgdb_thr_first(void); struct kthr *kgdb_thr_init(void); struct kthr *kgdb_thr_lookup_tid(int); diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c index a884005f85..4ccff7359e 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt.c +++ b/gnu/usr.bin/gdb/kgdb/trgt.c @@ -136,6 +136,8 @@ kgdb_trgt_open(char *filename, int from_tty) if (curkthr != 0) inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid); + frame_unwind_prepend_unwinder(get_frame_arch(get_current_frame()), &kgdb_trgt_trapframe_unwind); + if (ontop) { /* XXX: fetch registers? */ kld_init(); diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c index f9dd0af1e9..8932266f93 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c @@ -239,6 +239,7 @@ struct kgdb_frame_cache { #define FT_INTRFRAME 2 /*#define FT_INTRTRAPFRAME 3*/ #define FT_TIMERFRAME 4 +#define FT_CALLTRAP 5 static int kgdb_trgt_frame_offset[15] = { offsetof(struct trapframe, tf_eax), @@ -261,8 +262,6 @@ static int kgdb_trgt_frame_offset[15] = { static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { - enum bfd_endian byte_order = gdbarch_byte_order(get_frame_arch(next_frame)); - char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; char *pname; @@ -271,9 +270,12 @@ kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = get_frame_address_in_block(next_frame); + cache->sp = get_frame_sp(next_frame); find_pc_partial_function(cache->pc, &pname, NULL, NULL); - if (pname[0] != 'X') + if (strcmp(pname, "calltrap") == 0) + cache->frame_type = FT_CALLTRAP; + else if (pname[0] != 'X') cache->frame_type = FT_NORMAL; else if (strcmp(pname, "Xtimerint") == 0) cache->frame_type = FT_TIMERFRAME; @@ -285,11 +287,6 @@ kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) */ else cache->frame_type = FT_INTRFRAME; - - frame_unwind_register(next_frame, I386_ESP_REGNUM, buf); - cache->sp = extract_unsigned_integer(buf, - register_size(get_frame_arch(next_frame), I386_ESP_REGNUM), - byte_order); } return (cache); } @@ -318,6 +315,7 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, ofs = kgdb_trgt_frame_offset[regnum] + 4; cache = kgdb_trgt_frame_cache(next_frame, this_cache); + switch (cache->frame_type) { case FT_NORMAL: break; @@ -331,6 +329,9 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, ofs -= ofs_fix; break; */ + case FT_CALLTRAP: + ofs += 0; + break; default: fprintf_unfiltered(gdb_stderr, "Correct FT_XXX frame offsets " "for %d\n", cache->frame_type); -- 2.41.0