GDB (API)
|
00001 /* Native-dependent code for OpenBSD/i386. 00002 00003 Copyright (C) 2002-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 <sys/sysctl.h> 00026 #include <machine/frame.h> 00027 #include <machine/pcb.h> 00028 00029 #include "i386-tdep.h" 00030 #include "i386bsd-nat.h" 00031 #include "bsd-kvm.h" 00032 00033 static int 00034 i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 00035 { 00036 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00037 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00038 struct switchframe sf; 00039 00040 /* The following is true for OpenBSD 3.6: 00041 00042 The pcb contains %esp and %ebp at the point of the context switch 00043 in cpu_switch(). At that point we have a stack frame as 00044 described by `struct switchframe', which for OpenBSD 3.6 has the 00045 following layout: 00046 00047 interrupt level 00048 %edi 00049 %esi 00050 %ebx 00051 %eip 00052 00053 we reconstruct the register state as it would look when we just 00054 returned from cpu_switch(). */ 00055 00056 /* The stack pointer shouldn't be zero. */ 00057 if (pcb->pcb_esp == 0) 00058 return 0; 00059 00060 /* Read the stack frame, and check its validity. We do this by 00061 checking if the saved interrupt priority level in the stack frame 00062 looks reasonable.. */ 00063 #ifdef PCB_SAVECTX 00064 if ((pcb->pcb_flags & PCB_SAVECTX) == 0) 00065 { 00066 /* Yes, we have a frame that matches cpu_switch(). */ 00067 read_memory (pcb->pcb_esp, (char *) &sf, sizeof sf); 00068 pcb->pcb_esp += sizeof (struct switchframe); 00069 regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi); 00070 regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi); 00071 regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx); 00072 regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip); 00073 } 00074 else 00075 #endif 00076 { 00077 /* No, the pcb must have been last updated by savectx(). */ 00078 pcb->pcb_esp = pcb->pcb_ebp; 00079 pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order); 00080 sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order); 00081 regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip); 00082 } 00083 00084 regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp); 00085 regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp); 00086 00087 return 1; 00088 } 00089 00090 00091 /* Prevent warning from -Wmissing-prototypes. */ 00092 void _initialize_i386obsd_nat (void); 00093 00094 void 00095 _initialize_i386obsd_nat (void) 00096 { 00097 /* We've got nothing to add to the common *BSD/i386 target. */ 00098 add_target (i386bsd_target ()); 00099 00100 /* Support debugging kernel virtual memory images. */ 00101 bsd_kvm_add_target (i386obsd_supply_pcb); 00102 00103 /* OpenBSD provides a vm.psstrings sysctl that we can use to locate 00104 the sigtramp. That way we can still recognize a sigtramp if its 00105 location is changed in a new kernel. This is especially 00106 important for OpenBSD, since it uses a different memory layout 00107 than NetBSD, yet we cannot distinguish between the two. 00108 00109 Of course this is still based on the assumption that the sigtramp 00110 is placed directly under the location where the program arguments 00111 and environment can be found. */ 00112 #ifdef VM_PSSTRINGS 00113 { 00114 struct _ps_strings _ps; 00115 int mib[2]; 00116 size_t len; 00117 00118 mib[0] = CTL_VM; 00119 mib[1] = VM_PSSTRINGS; 00120 len = sizeof (_ps); 00121 if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0) 00122 { 00123 i386obsd_sigtramp_start_addr = (u_long) _ps.val - 128; 00124 i386obsd_sigtramp_end_addr = (u_long) _ps.val; 00125 } 00126 } 00127 #endif 00128 }