diff options
author | Mark Kettenis <kettenis@gnu.org> | 2004-05-22 22:42:53 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2004-05-22 22:42:53 +0000 |
commit | 492cf391e36017aca823e106e1613e93cb4f0870 (patch) | |
tree | a5479d757f7726c4e2d690186a514316a7a189ba /gdb/amd64obsd-nat.c | |
parent | a770d4eca642f4ae0d2e2e8d04a76933afed7b78 (diff) | |
download | gdb-492cf391e36017aca823e106e1613e93cb4f0870.zip gdb-492cf391e36017aca823e106e1613e93cb4f0870.tar.gz gdb-492cf391e36017aca823e106e1613e93cb4f0870.tar.bz2 |
* amd64obsd-nat.c: Include "gdbcore.h", "regcache.h",
<sys/types.h>, <machine/frame.h>, <machine/pcb.h> and "bsd-kvm.h".
(amd64obsd_supply_pcb): New function.
(_initialize_amd64obsd_nat): Enable libkvm interface.
* Makefile.in (amd64obsd-nat.o): Update dependencies.
* config/i386/obsd64.mh (NATDEPFILES): Add bsd-kvm.o
(LOADLIBES): New variable.
Diffstat (limited to 'gdb/amd64obsd-nat.c')
-rw-r--r-- | gdb/amd64obsd-nat.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/gdb/amd64obsd-nat.c b/gdb/amd64obsd-nat.c index e8d92fe..0f9b5ef 100644 --- a/gdb/amd64obsd-nat.c +++ b/gdb/amd64obsd-nat.c @@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "gdbcore.h" +#include "regcache.h" #include "gdb_assert.h" @@ -56,6 +58,76 @@ static int amd64obsd32_r_reg_offset[] = }; +/* Support for debugging kernel virtual memory images. */ + +#include <sys/types.h> +#include <machine/frame.h> +#include <machine/pcb.h> + +#include "bsd-kvm.h" + +static int +amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) +{ + struct switchframe sf; + int regnum; + + /* The following is true for OpenBSD 3.5: + + The pcb contains the stack pointer at the point of the context + switch in cpu_switch(). At that point we have a stack frame as + described by `struct switchframe', which for OpenBSD 3.5 has the + following layout: + + interrupt level + %r15 + %r14 + %r13 + %r12 + %rbp + %rbx + return address + + Together with %rsp in the pcb, this accounts for all callee-saved + registers specified by the psABI. From this information we + reconstruct the register state as it would look when we just + returned from cpu_switch(). + + For core dumps the pcb is saved by savectx(). In that case the + stack frame only contains the return address, and there is no way + to recover the other registers. */ + + /* The stack pointer shouldn't be zero. */ + if (pcb->pcb_rsp == 0) + return 0; + + /* Read the stack frame, and check its validity. */ + read_memory (pcb->pcb_rsp, (char *) &sf, sizeof sf); + if (sf.sf_rbp == pcb->pcb_rbp) + { + /* Yes, we have a frame that matches cpu_switch(). */ + pcb->pcb_rsp += sizeof (struct switchframe); + regcache_raw_supply (regcache, 12, &sf.sf_r12); + regcache_raw_supply (regcache, 13, &sf.sf_r13); + regcache_raw_supply (regcache, 14, &sf.sf_r14); + regcache_raw_supply (regcache, 15, &sf.sf_r15); + regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx); + regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip); + } + else + { + /* No, the pcb must have been last updated by savectx(). */ + pcb->pcb_rsp += 8; + regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf); + } + + regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp); + regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp); + + return 1; +} + + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64obsd_nat (void); @@ -65,4 +137,7 @@ _initialize_amd64obsd_nat (void) amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset; amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset); amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset; + + /* Support debugging kernel virtual memory images. */ + bsd_kvm_add_target (amd64obsd_supply_pcb); } |