1699b0f92Schristos /* Native-dependent code for OpenBSD/i386. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2002-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "gdbcore.h" 22699b0f92Schristos #include "regcache.h" 23699b0f92Schristos #include "target.h" 24699b0f92Schristos 25699b0f92Schristos #include <sys/sysctl.h> 26699b0f92Schristos #include <machine/frame.h> 27699b0f92Schristos #include <machine/pcb.h> 28699b0f92Schristos 29699b0f92Schristos #include "i386-tdep.h" 30699b0f92Schristos #include "i386-bsd-nat.h" 31699b0f92Schristos #include "obsd-nat.h" 32699b0f92Schristos #include "bsd-kvm.h" 33699b0f92Schristos 34699b0f92Schristos static int 35699b0f92Schristos i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 36699b0f92Schristos { 377f2ac410Schristos struct gdbarch *gdbarch = regcache->arch (); 38699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 39699b0f92Schristos struct switchframe sf; 40699b0f92Schristos 41699b0f92Schristos /* The following is true for OpenBSD 3.6: 42699b0f92Schristos 43699b0f92Schristos The pcb contains %esp and %ebp at the point of the context switch 44699b0f92Schristos in cpu_switch(). At that point we have a stack frame as 45699b0f92Schristos described by `struct switchframe', which for OpenBSD 3.6 has the 46699b0f92Schristos following layout: 47699b0f92Schristos 48699b0f92Schristos interrupt level 49699b0f92Schristos %edi 50699b0f92Schristos %esi 51699b0f92Schristos %ebx 52699b0f92Schristos %eip 53699b0f92Schristos 54699b0f92Schristos we reconstruct the register state as it would look when we just 55699b0f92Schristos returned from cpu_switch(). */ 56699b0f92Schristos 57699b0f92Schristos /* The stack pointer shouldn't be zero. */ 58699b0f92Schristos if (pcb->pcb_esp == 0) 59699b0f92Schristos return 0; 60699b0f92Schristos 61699b0f92Schristos /* Read the stack frame, and check its validity. We do this by 62699b0f92Schristos checking if the saved interrupt priority level in the stack frame 63699b0f92Schristos looks reasonable.. */ 64699b0f92Schristos #ifdef PCB_SAVECTX 65699b0f92Schristos if ((pcb->pcb_flags & PCB_SAVECTX) == 0) 66699b0f92Schristos { 67699b0f92Schristos /* Yes, we have a frame that matches cpu_switch(). */ 68699b0f92Schristos read_memory (pcb->pcb_esp, (gdb_byte *) &sf, sizeof sf); 69699b0f92Schristos pcb->pcb_esp += sizeof (struct switchframe); 707f2ac410Schristos regcache->raw_supply (I386_EDI_REGNUM, &sf.sf_edi); 717f2ac410Schristos regcache->raw_supply (I386_ESI_REGNUM, &sf.sf_esi); 727f2ac410Schristos regcache->raw_supply (I386_EBX_REGNUM, &sf.sf_ebx); 737f2ac410Schristos regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); 74699b0f92Schristos } 75699b0f92Schristos else 76699b0f92Schristos #endif 77699b0f92Schristos { 78699b0f92Schristos /* No, the pcb must have been last updated by savectx(). */ 79699b0f92Schristos pcb->pcb_esp = pcb->pcb_ebp; 80699b0f92Schristos pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order); 81699b0f92Schristos sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order); 827f2ac410Schristos regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); 83699b0f92Schristos } 84699b0f92Schristos 857f2ac410Schristos regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp); 867f2ac410Schristos regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp); 87699b0f92Schristos 88699b0f92Schristos return 1; 89699b0f92Schristos } 90699b0f92Schristos 917f2ac410Schristos static i386_bsd_nat_target<obsd_nat_target> the_i386_obsd_nat_target; 92699b0f92Schristos 937d62b00eSchristos void _initialize_i386obsd_nat (); 94699b0f92Schristos void 957d62b00eSchristos _initialize_i386obsd_nat () 96699b0f92Schristos { 977f2ac410Schristos add_inf_child_target (&i386_obsd_nat_target); 98699b0f92Schristos 99699b0f92Schristos /* Support debugging kernel virtual memory images. */ 100699b0f92Schristos bsd_kvm_add_target (i386obsd_supply_pcb); 101699b0f92Schristos 102699b0f92Schristos /* OpenBSD provides a vm.psstrings sysctl that we can use to locate 103699b0f92Schristos the sigtramp. That way we can still recognize a sigtramp if its 104699b0f92Schristos location is changed in a new kernel. This is especially 105699b0f92Schristos important for OpenBSD, since it uses a different memory layout 106699b0f92Schristos than NetBSD, yet we cannot distinguish between the two. 107699b0f92Schristos 108699b0f92Schristos Of course this is still based on the assumption that the sigtramp 109699b0f92Schristos is placed directly under the location where the program arguments 110699b0f92Schristos and environment can be found. */ 111699b0f92Schristos #ifdef VM_PSSTRINGS 112699b0f92Schristos { 113699b0f92Schristos struct _ps_strings _ps; 114699b0f92Schristos int mib[2]; 115699b0f92Schristos size_t len; 116699b0f92Schristos 117699b0f92Schristos mib[0] = CTL_VM; 118699b0f92Schristos mib[1] = VM_PSSTRINGS; 119699b0f92Schristos len = sizeof (_ps); 120699b0f92Schristos if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0) 121699b0f92Schristos { 122699b0f92Schristos i386obsd_sigtramp_start_addr = (u_long) _ps.val - 128; 123699b0f92Schristos i386obsd_sigtramp_end_addr = (u_long) _ps.val; 124699b0f92Schristos } 125699b0f92Schristos } 126699b0f92Schristos #endif 127699b0f92Schristos } 128