summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2005-09-10 20:12:52 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2005-09-10 20:12:52 +0000
commit6ab0894870650d8f56224aa83722ecd212eb1ee5 (patch)
tree337f0b239ed3083f211908342ebc74698bfef52e /gnu
parentc67d07416a0ae8ee92b268aec7825b1ed8367bce (diff)
downloadsrc-test2-6ab0894870650d8f56224aa83722ecd212eb1ee5.tar.gz
src-test2-6ab0894870650d8f56224aa83722ecd212eb1ee5.zip
Notes
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c92
1 files changed, 86 insertions, 6 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index eb58df3e4baa..0522e2445384 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.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 <i386-tdep.h>
#include "kgdb.h"
@@ -55,12 +57,12 @@ kgdb_trgt_fetch_registers(int regno __unused)
warnx("kvm_read: %s", kvm_geterr(kvm));
memset(&pcb, 0, sizeof(pcb));
}
- supply_register(3, (char *)&pcb.pcb_ebx);
- supply_register(4, (char *)&pcb.pcb_esp);
- supply_register(5, (char *)&pcb.pcb_ebp);
- supply_register(6, (char *)&pcb.pcb_esi);
- supply_register(7, (char *)&pcb.pcb_edi);
- supply_register(8, (char *)&pcb.pcb_eip);
+ supply_register(I386_EBX_REGNUM, (char *)&pcb.pcb_ebx);
+ supply_register(I386_ESP_REGNUM, (char *)&pcb.pcb_esp);
+ supply_register(I386_EBP_REGNUM, (char *)&pcb.pcb_ebp);
+ supply_register(I386_ESI_REGNUM, (char *)&pcb.pcb_esi);
+ supply_register(I386_EDI_REGNUM, (char *)&pcb.pcb_edi);
+ supply_register(I386_EIP_REGNUM, (char *)&pcb.pcb_eip);
}
void
@@ -69,10 +71,55 @@ 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[15] = {
+ offsetof(struct trapframe, tf_eax),
+ offsetof(struct trapframe, tf_ecx),
+ offsetof(struct trapframe, tf_edx),
+ offsetof(struct trapframe, tf_ebx),
+ offsetof(struct trapframe, tf_esp),
+ offsetof(struct trapframe, tf_ebp),
+ offsetof(struct trapframe, tf_esi),
+ offsetof(struct trapframe, tf_edi),
+ offsetof(struct trapframe, tf_eip),
+ offsetof(struct trapframe, tf_eflags),
+ offsetof(struct trapframe, tf_cs),
+ offsetof(struct trapframe, tf_ss),
+ offsetof(struct trapframe, tf_ds),
+ offsetof(struct trapframe, tf_es),
+ offsetof(struct trapframe, tf_fs)
+};
+
+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
@@ -80,6 +127,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 >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM)
+ ? kgdb_trgt_frame_offset[regnum] : -1;
+ if (ofs == -1)
+ return;
+
+ cache = kgdb_trgt_frame_cache(next_frame, this_cache);
+ *addrp = cache->sp + ofs;
+ *lvalp = lval_memory;
+ target_read_memory(*addrp, valuep, regsz);
}
static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
@@ -91,6 +161,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;
+ pc = frame_pc_unwind(next_frame);
+ pname = NULL;
+ find_pc_partial_function(pc, &pname, NULL, NULL);
+ if (pname == NULL)
+ return (NULL);
+ if (strcmp(pname, "calltrap") == 0)
+ return (&kgdb_trgt_trapframe_unwind);
+ /* printf("%s: %llx =%s\n", __func__, pc, pname); */
return (NULL);
}