1 /* Native-dependent code for DragonFly/i386.
3 Copyright (C) 2001-2013 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include <sys/types.h>
27 #include <sys/procfs.h>
28 #include <sys/ptrace.h>
29 #include <sys/sysctl.h>
32 #include "i386-tdep.h"
34 #include "i386bsd-nat.h"
36 #ifdef DFLY_PCB_SUPPLY
37 /* Resume execution of the inferior process. If STEP is nonzero,
38 single-step it. If SIGNAL is nonzero, give it that signal. */
41 i386dfly_resume(struct target_ops *ops,
42 ptid_t ptid, int step, enum gdb_signal signal)
44 pid_t pid = ptid_get_pid(ptid);
45 int request = PT_STEP;
48 /* Resume all threads. This only gets used in the
49 * non-threaded case, where "resume all threads" and "resume
50 * inferior_ptid" are the same. */
51 pid = ptid_get_pid(inferior_ptid);
54 struct regcache *regcache = get_current_regcache();
57 /* Workaround for a bug in FreeBSD. Make sure that the trace
58 * flag is off when doing a continue. There is a code path
59 * through the kernel which leaves the flag set when it should
60 * have been cleared. If a process has a signal pending (such
61 * as SIGALRM) and we do a PT_STEP, the process never really
62 * has a chance to run because the kernel needs to notify the
63 * debugger that a signal is being sent. Therefore, the
64 * process never goes through the kernel's trap() function
65 * which would normally clear it. */
67 regcache_cooked_read_unsigned(regcache, I386_EFLAGS_REGNUM,
70 regcache_cooked_write_unsigned(regcache, I386_EFLAGS_REGNUM,
73 request = PT_CONTINUE;
75 /* An addres of (caddr_t) 1 tells ptrace to continue from where it
76 * was. (If GDB wanted it to start some other way, we have already
77 * written a new PC value to the child.) */
78 if (ptrace(request, pid, (caddr_t) 1,
79 gdb_signal_to_host(signal)) == -1)
80 perror_with_name(("ptrace"));
85 /* Transfering the registers between GDB, inferiors and core files. */
87 /* Fill GDB's register array with the general-purpose register values
91 supply_gregset(struct regcache *regcache, const gregset_t * gregsetp)
93 i386bsd_supply_gregset(regcache, gregsetp);
96 /* Fill register REGNUM (if it is a general-purpose register) in
97 *GREGSETPS with the value in GDB's register array. If REGNUM is -1,
98 do this for all registers. */
101 fill_gregset(const struct regcache *regcache, gdb_gregset_t * gregsetp, int regnum)
103 i386bsd_collect_gregset(regcache, gregsetp, regnum);
106 #include "i387-tdep.h"
108 /* Fill GDB's register array with the floating-point register values
112 supply_fpregset(struct regcache *regcache, const fpregset_t * fpregsetp)
114 i387_supply_fsave(regcache, -1, fpregsetp);
117 /* Fill register REGNUM (if it is a floating-point register) in
118 *FPREGSETP with the value in GDB's register array. If REGNUM is -1,
119 do this for all registers. */
122 fill_fpregset(const struct regcache *regcache, gdb_fpregset_t * fpregsetp, int regnum)
124 i387_collect_fsave(regcache, regnum, fpregsetp);
129 /* Support for debugging kernel virtual memory images. */
131 #include <sys/types.h>
132 #include <machine/pcb.h>
137 i386dfly_supply_pcb(struct regcache *regcache, struct pcb *pcb)
139 /* The following is true for FreeBSD 4.7:
141 * The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs. This
142 * accounts for all callee-saved registers specified by the psABI and
143 * then some. Here %esp contains the stack pointer at the point just
144 * after the call to cpu_switch(). From this information we
145 * reconstruct the register state as it would look when we just
146 * returned from cpu_switch(). */
148 /* The stack pointer shouldn't be zero. */
149 if (pcb->pcb_esp == 0)
153 regcache_raw_supply(regcache, I386_EDI_REGNUM, &pcb->pcb_edi);
154 regcache_raw_supply(regcache, I386_ESI_REGNUM, &pcb->pcb_esi);
155 regcache_raw_supply(regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
156 regcache_raw_supply(regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
157 regcache_raw_supply(regcache, I386_EBX_REGNUM, &pcb->pcb_ebx);
158 regcache_raw_supply(regcache, I386_EIP_REGNUM, &pcb->pcb_eip);
159 regcache_raw_supply(regcache, I386_GS_REGNUM, &pcb->pcb_gs);
163 #endif /* DFLY_PCB_SUPPLY */
167 /* Prevent warning from -Wmissing-prototypes. */
168 void _initialize_i386dfly_nat(void);
171 _initialize_i386dfly_nat(void)
173 struct target_ops *t;
175 /* Add some extra features to the common *BSD/i386 target. */
176 t = i386bsd_target();
178 #ifdef HAVE_PT_GETDBREGS
180 i386_use_watchpoints(t);
182 i386_dr_low.set_control = i386bsd_dr_set_control;
183 i386_dr_low.set_addr = i386bsd_dr_set_addr;
184 i386_dr_low.get_addr = i386bsd_dr_get_addr;
185 i386_dr_low.get_status = i386bsd_dr_get_status;
186 i386_dr_low.get_control = i386bsd_dr_get_control;
187 i386_set_debug_register_length(4);
189 #endif /* HAVE_PT_GETDBREGS */
192 t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
193 t->to_find_memory_regions = fbsd_find_memory_regions;
194 t->to_make_corefile_notes = fbsd_make_corefile_notes;
197 #ifdef DFLY_PCB_SUPPLY
198 /* Support debugging kernel virtual memory images. */
199 bsd_kvm_add_target(i386dfly_supply_pcb);
202 /* DragonFly provides a kern.ps_strings sysctl that we can use to
203 * locate the sigtramp. That way we can still recognize a sigtramp if
204 * its location is changed in a new kernel. Of course this is still
205 * based on the assumption that the sigtramp is placed directly under
206 * the location where the program arguments and environment can be
208 #ifdef KERN_PS_STRINGS
215 mib[1] = KERN_PS_STRINGS;
216 len = sizeof(ps_strings);
217 if (sysctl(mib, 2, &ps_strings, &len, NULL, 0) == 0) {
218 i386dfly_sigtramp_start_addr = ps_strings - 128;
219 i386dfly_sigtramp_end_addr = ps_strings;