GDB (API)
|
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 }