GDB (API)
/home/stan/gdb/src/gdb/i386obsd-nat.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines