GDB (API)
|
00001 /* Native-dependent code for FreeBSD/i386. 00002 00003 Copyright (C) 2001-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 "inferior.h" 00022 #include "regcache.h" 00023 #include "target.h" 00024 00025 #include <sys/types.h> 00026 #include <sys/ptrace.h> 00027 #include <sys/sysctl.h> 00028 00029 #include "fbsd-nat.h" 00030 #include "i386-tdep.h" 00031 #include "i386-nat.h" 00032 #include "i386bsd-nat.h" 00033 00034 /* Resume execution of the inferior process. If STEP is nonzero, 00035 single-step it. If SIGNAL is nonzero, give it that signal. */ 00036 00037 static void 00038 i386fbsd_resume (struct target_ops *ops, 00039 ptid_t ptid, int step, enum gdb_signal signal) 00040 { 00041 pid_t pid = ptid_get_pid (ptid); 00042 int request = PT_STEP; 00043 00044 if (pid == -1) 00045 /* Resume all threads. This only gets used in the non-threaded 00046 case, where "resume all threads" and "resume inferior_ptid" are 00047 the same. */ 00048 pid = ptid_get_pid (inferior_ptid); 00049 00050 if (!step) 00051 { 00052 struct regcache *regcache = get_current_regcache (); 00053 ULONGEST eflags; 00054 00055 /* Workaround for a bug in FreeBSD. Make sure that the trace 00056 flag is off when doing a continue. There is a code path 00057 through the kernel which leaves the flag set when it should 00058 have been cleared. If a process has a signal pending (such 00059 as SIGALRM) and we do a PT_STEP, the process never really has 00060 a chance to run because the kernel needs to notify the 00061 debugger that a signal is being sent. Therefore, the process 00062 never goes through the kernel's trap() function which would 00063 normally clear it. */ 00064 00065 regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM, 00066 &eflags); 00067 if (eflags & 0x0100) 00068 regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM, 00069 eflags & ~0x0100); 00070 00071 request = PT_CONTINUE; 00072 } 00073 00074 /* An addres of (caddr_t) 1 tells ptrace to continue from where it 00075 was. (If GDB wanted it to start some other way, we have already 00076 written a new PC value to the child.) */ 00077 if (ptrace (request, pid, (caddr_t) 1, 00078 gdb_signal_to_host (signal)) == -1) 00079 perror_with_name (("ptrace")); 00080 } 00081 00082 00083 /* Support for debugging kernel virtual memory images. */ 00084 00085 #include <sys/types.h> 00086 #include <machine/pcb.h> 00087 00088 #include "bsd-kvm.h" 00089 00090 static int 00091 i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 00092 { 00093 /* The following is true for FreeBSD 4.7: 00094 00095 The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs. 00096 This accounts for all callee-saved registers specified by the 00097 psABI and then some. Here %esp contains the stack pointer at the 00098 point just after the call to cpu_switch(). From this information 00099 we reconstruct the register state as it would look when we just 00100 returned from cpu_switch(). */ 00101 00102 /* The stack pointer shouldn't be zero. */ 00103 if (pcb->pcb_esp == 0) 00104 return 0; 00105 00106 pcb->pcb_esp += 4; 00107 regcache_raw_supply (regcache, I386_EDI_REGNUM, &pcb->pcb_edi); 00108 regcache_raw_supply (regcache, I386_ESI_REGNUM, &pcb->pcb_esi); 00109 regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp); 00110 regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp); 00111 regcache_raw_supply (regcache, I386_EBX_REGNUM, &pcb->pcb_ebx); 00112 regcache_raw_supply (regcache, I386_EIP_REGNUM, &pcb->pcb_eip); 00113 regcache_raw_supply (regcache, I386_GS_REGNUM, &pcb->pcb_gs); 00114 00115 return 1; 00116 } 00117 00118 00119 /* Prevent warning from -Wmissing-prototypes. */ 00120 void _initialize_i386fbsd_nat (void); 00121 00122 void 00123 _initialize_i386fbsd_nat (void) 00124 { 00125 struct target_ops *t; 00126 00127 /* Add some extra features to the common *BSD/i386 target. */ 00128 t = i386bsd_target (); 00129 00130 #ifdef HAVE_PT_GETDBREGS 00131 00132 i386_use_watchpoints (t); 00133 00134 i386_dr_low.set_control = i386bsd_dr_set_control; 00135 i386_dr_low.set_addr = i386bsd_dr_set_addr; 00136 i386_dr_low.get_addr = i386bsd_dr_get_addr; 00137 i386_dr_low.get_status = i386bsd_dr_get_status; 00138 i386_dr_low.get_control = i386bsd_dr_get_control; 00139 i386_set_debug_register_length (4); 00140 00141 #endif /* HAVE_PT_GETDBREGS */ 00142 00143 00144 t->to_resume = i386fbsd_resume; 00145 t->to_pid_to_exec_file = fbsd_pid_to_exec_file; 00146 t->to_find_memory_regions = fbsd_find_memory_regions; 00147 t->to_make_corefile_notes = fbsd_make_corefile_notes; 00148 add_target (t); 00149 00150 /* Support debugging kernel virtual memory images. */ 00151 bsd_kvm_add_target (i386fbsd_supply_pcb); 00152 00153 /* FreeBSD provides a kern.ps_strings sysctl that we can use to 00154 locate the sigtramp. That way we can still recognize a sigtramp 00155 if its location is changed in a new kernel. Of course this is 00156 still based on the assumption that the sigtramp is placed 00157 directly under the location where the program arguments and 00158 environment can be found. */ 00159 #ifdef KERN_PS_STRINGS 00160 { 00161 int mib[2]; 00162 u_long ps_strings; 00163 size_t len; 00164 00165 mib[0] = CTL_KERN; 00166 mib[1] = KERN_PS_STRINGS; 00167 len = sizeof (ps_strings); 00168 if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) 00169 { 00170 i386fbsd_sigtramp_start_addr = ps_strings - 128; 00171 i386fbsd_sigtramp_end_addr = ps_strings; 00172 } 00173 } 00174 #endif 00175 }