198944Sobrien/* Native-dependent code for FreeBSD/i386. 298944Sobrien 3130803Smarcel Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 4130803Smarcel 598944Sobrien This file is part of GDB. 698944Sobrien 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1198944Sobrien 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1698944Sobrien 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2198944Sobrien 2298944Sobrien#include "defs.h" 2398944Sobrien#include "inferior.h" 2498944Sobrien#include "regcache.h" 2598944Sobrien 2698944Sobrien#include <sys/types.h> 2798944Sobrien#include <sys/ptrace.h> 2898944Sobrien#include <sys/sysctl.h> 2998944Sobrien 30130803Smarcel#include "i386-tdep.h" 31130803Smarcel 3298944Sobrien/* Prevent warning from -Wmissing-prototypes. */ 3398944Sobrienvoid _initialize_i386fbsd_nat (void); 3498944Sobrien 3598944Sobrien/* Resume execution of the inferior process. 3698944Sobrien If STEP is nonzero, single-step it. 3798944Sobrien If SIGNAL is nonzero, give it that signal. */ 3898944Sobrien 3998944Sobrienvoid 4098944Sobrienchild_resume (ptid_t ptid, int step, enum target_signal signal) 4198944Sobrien{ 4298944Sobrien pid_t pid = ptid_get_pid (ptid); 4398944Sobrien int request = PT_STEP; 4498944Sobrien 4598944Sobrien if (pid == -1) 4698944Sobrien /* Resume all threads. This only gets used in the non-threaded 4798944Sobrien case, where "resume all threads" and "resume inferior_ptid" are 4898944Sobrien the same. */ 4998944Sobrien pid = ptid_get_pid (inferior_ptid); 5098944Sobrien 5198944Sobrien if (!step) 5298944Sobrien { 53130803Smarcel ULONGEST eflags; 5498944Sobrien 5598944Sobrien /* Workaround for a bug in FreeBSD. Make sure that the trace 5698944Sobrien flag is off when doing a continue. There is a code path 5798944Sobrien through the kernel which leaves the flag set when it should 5898944Sobrien have been cleared. If a process has a signal pending (such 5998944Sobrien as SIGALRM) and we do a PT_STEP, the process never really has 6098944Sobrien a chance to run because the kernel needs to notify the 6198944Sobrien debugger that a signal is being sent. Therefore, the process 6298944Sobrien never goes through the kernel's trap() function which would 6398944Sobrien normally clear it. */ 6498944Sobrien 65130803Smarcel regcache_cooked_read_unsigned (current_regcache, I386_EFLAGS_REGNUM, 66130803Smarcel &eflags); 6798944Sobrien if (eflags & 0x0100) 68130803Smarcel regcache_cooked_write_unsigned (current_regcache, I386_EFLAGS_REGNUM, 69130803Smarcel eflags & ~0x0100); 7098944Sobrien 7198944Sobrien request = PT_CONTINUE; 7298944Sobrien } 7398944Sobrien 7498944Sobrien /* An addres of (caddr_t) 1 tells ptrace to continue from where it 7598944Sobrien was. (If GDB wanted it to start some other way, we have already 7698944Sobrien written a new PC value to the child.) */ 7798944Sobrien if (ptrace (request, pid, (caddr_t) 1, 7898944Sobrien target_signal_to_host (signal)) == -1) 7998944Sobrien perror_with_name ("ptrace"); 8098944Sobrien} 8198944Sobrien 8298944Sobrienvoid 8398944Sobrien_initialize_i386fbsd_nat (void) 8498944Sobrien{ 8598944Sobrien /* FreeBSD provides a kern.ps_strings sysctl that we can use to 8698944Sobrien locate the sigtramp. That way we can still recognize a sigtramp 87130803Smarcel if its location is changed in a new kernel. Of course this is 8898944Sobrien still based on the assumption that the sigtramp is placed 8998944Sobrien directly under the location where the program arguments and 9098944Sobrien environment can be found. */ 9198944Sobrien#ifdef KERN_PS_STRINGS 9298944Sobrien { 9398944Sobrien int mib[2]; 94173619Sobrien u_long ps_strings; 9598944Sobrien size_t len; 9698944Sobrien 9798944Sobrien mib[0] = CTL_KERN; 9898944Sobrien mib[1] = KERN_PS_STRINGS; 9998944Sobrien len = sizeof (ps_strings); 10098944Sobrien if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) 10198944Sobrien { 102130803Smarcel i386fbsd_sigtramp_start_addr = ps_strings - 128; 103130803Smarcel i386fbsd_sigtramp_end_addr = ps_strings; 10498944Sobrien } 10598944Sobrien } 10698944Sobrien#endif 10798944Sobrien} 108