diff options
| author | Marcel Moolenaar <marcel@FreeBSD.org> | 2005-09-10 21:01:36 +0000 |
|---|---|---|
| committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2005-09-10 21:01:36 +0000 |
| commit | a8f01390e1f8beadbc5a4afa846ecb71743bb313 (patch) | |
| tree | 212132c6073b02591dc143c91dc327d1cc4cb419 /gnu | |
| parent | f0dc0215495bf8ce14825156bbd5c3620c2527be (diff) | |
Notes
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/usr.bin/gdb/kgdb/trgt_amd64.c | 105 |
1 files changed, 95 insertions, 10 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c index bd1558f0b3fa..9b83fd3dd3f3 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.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 <amd64-tdep.h> #include "kgdb.h" @@ -56,15 +58,15 @@ kgdb_trgt_fetch_registers(int regno __unused) memset(&pcb, 0, sizeof(pcb)); } - supply_register(1, (char *)&pcb.pcb_rbx); - supply_register(6, (char *)&pcb.pcb_rbp); - supply_register(7, (char *)&pcb.pcb_rsp); - supply_register(12, (char *)&pcb.pcb_r12); - supply_register(13, (char *)&pcb.pcb_r13); - supply_register(14, (char *)&pcb.pcb_r14); - supply_register(15, (char *)&pcb.pcb_r15); - supply_register(16, (char *)&pcb.pcb_rip); - supply_register(17, (char *)&pcb.pcb_rflags); + supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); + supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); + supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); + supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); + supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); + supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); + supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); + supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); + supply_register(AMD64_EFLAGS_REGNUM, (char *)&pcb.pcb_rflags); } void @@ -73,10 +75,60 @@ 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[20] = { + offsetof(struct trapframe, tf_rax), + offsetof(struct trapframe, tf_rbx), + offsetof(struct trapframe, tf_rcx), + offsetof(struct trapframe, tf_rdx), + offsetof(struct trapframe, tf_rsi), + offsetof(struct trapframe, tf_rdi), + offsetof(struct trapframe, tf_rbp), + offsetof(struct trapframe, tf_rsp), + offsetof(struct trapframe, tf_r8), + offsetof(struct trapframe, tf_r9), + offsetof(struct trapframe, tf_r10), + offsetof(struct trapframe, tf_r11), + offsetof(struct trapframe, tf_r12), + offsetof(struct trapframe, tf_r13), + offsetof(struct trapframe, tf_r14), + offsetof(struct trapframe, tf_r15), + offsetof(struct trapframe, tf_rip), + offsetof(struct trapframe, tf_rflags), + offsetof(struct trapframe, tf_cs), + offsetof(struct trapframe, tf_ss) +}; + +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 +136,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 >= AMD64_RAX_REGNUM && regnum <= AMD64_EFLAGS_REGNUM + 2) + ? 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 = { @@ -95,6 +170,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_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: %lx =%s\n", __func__, pc, pname); */ + return (NULL); } |
