GDB (API)
/home/stan/gdb/src/gdb/amd64obsd-nat.c
Go to the documentation of this file.
00001 /* Native-dependent code for OpenBSD/amd64.
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbcore.h"
00022 #include "regcache.h"
00023 #include "target.h"
00024 
00025 #include "gdb_assert.h"
00026 
00027 #include "amd64-tdep.h"
00028 #include "amd64-nat.h"
00029 
00030 /* Mapping between the general-purpose registers in OpenBSD/amd64
00031    `struct reg' format and GDB's register cache layout for
00032    OpenBSD/i386.
00033 
00034    Note that most (if not all) OpenBSD/amd64 registers are 64-bit,
00035    while the OpenBSD/i386 registers are all 32-bit, but since we're
00036    little-endian we get away with that.  */
00037 
00038 /* From <machine/reg.h>.  */
00039 static int amd64obsd32_r_reg_offset[] =
00040 {
00041   14 * 8,                       /* %eax */
00042   3 * 8,                        /* %ecx */
00043   2 * 8,                        /* %edx */
00044   13 * 8,                       /* %ebx */
00045   15 * 8,                       /* %esp */
00046   12 * 8,                       /* %ebp */
00047   1 * 8,                        /* %esi */
00048   0 * 8,                        /* %edi */
00049   16 * 8,                       /* %eip */
00050   17 * 8,                       /* %eflags */
00051   18 * 8,                       /* %cs */
00052   19 * 8,                       /* %ss */
00053   20 * 8,                       /* %ds */
00054   21 * 8,                       /* %es */
00055   22 * 8,                       /* %fs */
00056   23 * 8                        /* %gs */
00057 };
00058 
00059 
00060 /* Support for debugging kernel virtual memory images.  */
00061 
00062 #include <sys/types.h>
00063 #include <machine/frame.h>
00064 #include <machine/pcb.h>
00065 
00066 #include "bsd-kvm.h"
00067 
00068 static int
00069 amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
00070 {
00071   struct switchframe sf;
00072   int regnum;
00073 
00074   /* The following is true for OpenBSD 3.5:
00075 
00076      The pcb contains the stack pointer at the point of the context
00077      switch in cpu_switch().  At that point we have a stack frame as
00078      described by `struct switchframe', which for OpenBSD 3.5 has the
00079      following layout:
00080 
00081      interrupt level
00082      %r15
00083      %r14
00084      %r13
00085      %r12
00086      %rbp
00087      %rbx
00088      return address
00089 
00090      Together with %rsp in the pcb, this accounts for all callee-saved
00091      registers specified by the psABI.  From this information we
00092      reconstruct the register state as it would look when we just
00093      returned from cpu_switch().
00094 
00095      For core dumps the pcb is saved by savectx().  In that case the
00096      stack frame only contains the return address, and there is no way
00097      to recover the other registers.  */
00098 
00099   /* The stack pointer shouldn't be zero.  */
00100   if (pcb->pcb_rsp == 0)
00101     return 0;
00102 
00103   /* Read the stack frame, and check its validity.  */
00104   read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf);
00105   if (sf.sf_rbp == pcb->pcb_rbp)
00106     {
00107       /* Yes, we have a frame that matches cpu_switch().  */
00108       pcb->pcb_rsp += sizeof (struct switchframe);
00109       regcache_raw_supply (regcache, 12, &sf.sf_r12);
00110       regcache_raw_supply (regcache, 13, &sf.sf_r13);
00111       regcache_raw_supply (regcache, 14, &sf.sf_r14);
00112       regcache_raw_supply (regcache, 15, &sf.sf_r15);
00113       regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx);
00114       regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip);
00115     }
00116   else
00117     {
00118       /* No, the pcb must have been last updated by savectx().  */
00119       pcb->pcb_rsp += 8;
00120       regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf);
00121     }
00122 
00123   regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
00124   regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
00125 
00126   return 1;
00127 }
00128 
00129 
00130 /* Provide a prototype to silence -Wmissing-prototypes.  */
00131 void _initialize_amd64obsd_nat (void);
00132 
00133 void
00134 _initialize_amd64obsd_nat (void)
00135 {
00136   amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
00137   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
00138   amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
00139 
00140   /* We've got nothing to add to the common *BSD/amd64 target.  */
00141   add_target (amd64bsd_target ());
00142 
00143   /* Support debugging kernel virtual memory images.  */
00144   bsd_kvm_add_target (amd64obsd_supply_pcb);
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines