summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2005-09-10 23:11:54 +0000
committermarcel <marcel@FreeBSD.org>2005-09-10 23:11:54 +0000
commit63c6575f860383f41a6fb197fe5bb43d76c06e75 (patch)
tree89b307a0cfa099f089e48944a466c8b712b245df /gnu
parent9d88c7f7b7004dffafb8e7e5d1d098ed506b015a (diff)
downloadFreeBSD-src-63c6575f860383f41a6fb197fe5bb43d76c06e75.zip
FreeBSD-src-63c6575f860383f41a6fb197fe5bb43d76c06e75.tar.gz
Unwind across trapframes. All kernel entries are handled.
MFC after: 1 week
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_alpha.c105
1 files changed, 94 insertions, 11 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
index c63c005..99e8df6 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/pcb.h>
+#include <machine/frame.h>
#include <err.h>
#include <kvm.h>
#include <string.h>
@@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <inferior.h>
#include <regcache.h>
#include <frame-unwind.h>
+#include <alpha-tdep.h>
#include "kgdb.h"
@@ -55,16 +57,17 @@ kgdb_trgt_fetch_registers(int regno __unused)
warnx("kvm_read: %s", kvm_geterr(kvm));
memset(&pcb, 0, sizeof(pcb));
}
-
- supply_register(9, (char *)&pcb.pcb_context[0]);
- supply_register(10, (char *)&pcb.pcb_context[1]);
- supply_register(11, (char *)&pcb.pcb_context[2]);
- supply_register(12, (char *)&pcb.pcb_context[3]);
- supply_register(13, (char *)&pcb.pcb_context[4]);
- supply_register(14, (char *)&pcb.pcb_context[5]);
- supply_register(15, (char *)&pcb.pcb_context[6]);
- supply_register(30, (char *)&pcb.pcb_hw.apcb_ksp);
- supply_register(64, (char *)&pcb.pcb_context[7]);
+#define ALPHA_S0_REGNUM ALPHA_T7_REGNUM + 1
+ supply_register(ALPHA_S0_REGNUM + 0, (char *)&pcb.pcb_context[0]);
+ supply_register(ALPHA_S0_REGNUM + 1, (char *)&pcb.pcb_context[1]);
+ supply_register(ALPHA_S0_REGNUM + 2, (char *)&pcb.pcb_context[2]);
+ supply_register(ALPHA_S0_REGNUM + 3, (char *)&pcb.pcb_context[3]);
+ supply_register(ALPHA_S0_REGNUM + 4, (char *)&pcb.pcb_context[4]);
+ supply_register(ALPHA_S0_REGNUM + 5, (char *)&pcb.pcb_context[5]);
+ supply_register(ALPHA_S0_REGNUM + 6, (char *)&pcb.pcb_context[6]);
+ supply_register(ALPHA_SP_REGNUM, (char *)&pcb.pcb_hw.apcb_ksp);
+ supply_register(ALPHA_PC_REGNUM, (char *)&pcb.pcb_context[7]);
+#undef ALPHA_S0_REGNUM
}
void
@@ -73,10 +76,57 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+struct kgdb_frame_cache {
+ CORE_ADDR pc;
+ CORE_ADDR sp;
+};
+
+static int kgdb_trgt_frame_offset[65] = {
+ FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2,
+ FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6,
+ FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2,
+ FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6,
+ FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3,
+ FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9,
+ FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12,
+ -1, FRAME_GP, FRAME_SP, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ FRAME_PC
+};
+
+static struct kgdb_frame_cache *
+kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
+{
+ char buf[MAX_REGISTER_SIZE];
+ struct kgdb_frame_cache *cache;
+
+ cache = *this_cache;
+ if (cache == NULL) {
+ cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
+ *this_cache = cache;
+ cache->pc = frame_func_unwind(next_frame);
+ frame_unwind_register(next_frame, SP_REGNUM, buf);
+ cache->sp = extract_unsigned_integer(buf,
+ register_size(current_gdbarch, SP_REGNUM));
+ }
+ return (cache);
+}
+
static void
kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
struct frame_id *this_id)
{
+ struct kgdb_frame_cache *cache;
+
+ cache = kgdb_trgt_frame_cache(next_frame, this_cache);
+ *this_id = frame_id_build(cache->sp, cache->pc);
}
static void
@@ -84,6 +134,29 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp,
CORE_ADDR *addrp, int *realnump, void *valuep)
{
+ char dummy_valuep[MAX_REGISTER_SIZE];
+ struct kgdb_frame_cache *cache;
+ int ofs, regsz;
+
+ regsz = register_size(current_gdbarch, regnum);
+
+ if (valuep == NULL)
+ valuep = dummy_valuep;
+ memset(valuep, 0, regsz);
+ *optimizedp = 0;
+ *addrp = 0;
+ *lvalp = not_lval;
+ *realnump = -1;
+
+ ofs = (regnum >= 0 && regnum <= ALPHA_PC_REGNUM)
+ ? kgdb_trgt_frame_offset[regnum] : -1;
+ if (ofs == -1)
+ return;
+
+ cache = kgdb_trgt_frame_cache(next_frame, this_cache);
+ *addrp = cache->sp + ofs * 8;
+ *lvalp = lval_memory;
+ target_read_memory(*addrp, valuep, regsz);
}
static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
@@ -95,6 +168,16 @@ static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
const struct frame_unwind *
kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
{
+ char *pname;
+ CORE_ADDR pc;
- return (NULL);
+ pc = frame_func_unwind(next_frame);
+ pname = NULL;
+ find_pc_partial_function(pc, &pname, NULL, NULL);
+ if (pname == NULL)
+ return (NULL);
+ if (strncmp(pname, "Xent", 4) == 0)
+ return (&kgdb_trgt_trapframe_unwind);
+ /* printf("%s: %lx =%s\n", __func__, pc, pname); */
+ return (NULL);
}
OpenPOWER on IntegriCloud