i386-darwin-nat.c revision 1.11 1 1.1 christos /* Darwin support for GDB, the GNU debugger.
2 1.11 christos Copyright (C) 1997-2024 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos Contributed by Apple Computer, Inc.
5 1.1 christos
6 1.1 christos This file is part of GDB.
7 1.1 christos
8 1.1 christos This program is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3 of the License, or
11 1.1 christos (at your option) any later version.
12 1.1 christos
13 1.1 christos This program is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #include "frame.h"
22 1.1 christos #include "inferior.h"
23 1.1 christos #include "target.h"
24 1.1 christos #include "symfile.h"
25 1.1 christos #include "symtab.h"
26 1.1 christos #include "objfiles.h"
27 1.11 christos #include "cli/cli-cmds.h"
28 1.1 christos #include "regcache.h"
29 1.1 christos #include "i386-tdep.h"
30 1.1 christos #include "i387-tdep.h"
31 1.1 christos #include "gdbarch.h"
32 1.1 christos #include "arch-utils.h"
33 1.1 christos #include "gdbcore.h"
34 1.1 christos
35 1.3 christos #include "x86-nat.h"
36 1.1 christos #include "darwin-nat.h"
37 1.1 christos #include "i386-darwin-tdep.h"
38 1.1 christos
39 1.1 christos #ifdef BFD64
40 1.1 christos #include "amd64-nat.h"
41 1.1 christos #include "amd64-tdep.h"
42 1.1 christos #include "amd64-darwin-tdep.h"
43 1.1 christos #endif
44 1.1 christos
45 1.8 christos struct i386_darwin_nat_target final : public x86_nat_target<darwin_nat_target>
46 1.8 christos {
47 1.8 christos /* Add our register access methods. */
48 1.8 christos void fetch_registers (struct regcache *, int) override;
49 1.8 christos void store_registers (struct regcache *, int) override;
50 1.8 christos };
51 1.8 christos
52 1.8 christos static struct i386_darwin_nat_target darwin_target;
53 1.8 christos
54 1.1 christos /* Read register values from the inferior process.
55 1.1 christos If REGNO is -1, do this for all registers.
56 1.1 christos Otherwise, REGNO specifies which register (so we can save time). */
57 1.8 christos
58 1.8 christos void
59 1.8 christos i386_darwin_nat_target::fetch_registers (struct regcache *regcache, int regno)
60 1.1 christos {
61 1.8 christos thread_t current_thread = regcache->ptid ().tid ();
62 1.1 christos int fetched = 0;
63 1.8 christos struct gdbarch *gdbarch = regcache->arch ();
64 1.1 christos
65 1.1 christos #ifdef BFD64
66 1.1 christos if (gdbarch_ptr_bit (gdbarch) == 64)
67 1.1 christos {
68 1.1 christos if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno))
69 1.10 christos {
70 1.10 christos x86_thread_state_t gp_regs;
71 1.10 christos unsigned int gp_count = x86_THREAD_STATE_COUNT;
72 1.10 christos kern_return_t ret;
73 1.1 christos
74 1.1 christos ret = thread_get_state
75 1.10 christos (current_thread, x86_THREAD_STATE, (thread_state_t) & gp_regs,
76 1.10 christos &gp_count);
77 1.1 christos if (ret != KERN_SUCCESS)
78 1.1 christos {
79 1.10 christos warning (_("Error calling thread_get_state for "
80 1.10 christos "GP registers for thread 0x%lx\n"),
81 1.10 christos (unsigned long) current_thread);
82 1.1 christos MACH_CHECK_ERROR (ret);
83 1.1 christos }
84 1.3 christos
85 1.3 christos /* Some kernels don't sanitize the values. */
86 1.3 christos gp_regs.uts.ts64.__fs &= 0xffff;
87 1.3 christos gp_regs.uts.ts64.__gs &= 0xffff;
88 1.3 christos
89 1.1 christos amd64_supply_native_gregset (regcache, &gp_regs.uts, -1);
90 1.10 christos fetched++;
91 1.10 christos }
92 1.1 christos
93 1.1 christos if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno))
94 1.10 christos {
95 1.10 christos x86_float_state_t fp_regs;
96 1.10 christos unsigned int fp_count = x86_FLOAT_STATE_COUNT;
97 1.10 christos kern_return_t ret;
98 1.1 christos
99 1.1 christos ret = thread_get_state
100 1.10 christos (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs,
101 1.10 christos &fp_count);
102 1.1 christos if (ret != KERN_SUCCESS)
103 1.1 christos {
104 1.10 christos warning (_("Error calling thread_get_state for "
105 1.10 christos "float registers for thread 0x%lx\n"),
106 1.10 christos (unsigned long) current_thread);
107 1.1 christos MACH_CHECK_ERROR (ret);
108 1.1 christos }
109 1.10 christos amd64_supply_fxsave (regcache, -1, &fp_regs.ufs.fs64.__fpu_fcw);
110 1.10 christos fetched++;
111 1.10 christos }
112 1.1 christos }
113 1.1 christos else
114 1.1 christos #endif
115 1.1 christos {
116 1.1 christos if (regno == -1 || regno < I386_NUM_GREGS)
117 1.10 christos {
118 1.10 christos x86_thread_state32_t gp_regs;
119 1.10 christos unsigned int gp_count = x86_THREAD_STATE32_COUNT;
120 1.10 christos kern_return_t ret;
121 1.1 christos int i;
122 1.1 christos
123 1.1 christos ret = thread_get_state
124 1.10 christos (current_thread, x86_THREAD_STATE32, (thread_state_t) &gp_regs,
125 1.10 christos &gp_count);
126 1.1 christos if (ret != KERN_SUCCESS)
127 1.1 christos {
128 1.10 christos warning (_("Error calling thread_get_state for "
129 1.10 christos "GP registers for thread 0x%lx\n"),
130 1.10 christos (unsigned long) current_thread);
131 1.1 christos MACH_CHECK_ERROR (ret);
132 1.1 christos }
133 1.1 christos for (i = 0; i < I386_NUM_GREGS; i++)
134 1.8 christos regcache->raw_supply
135 1.8 christos (i, (char *) &gp_regs + i386_darwin_thread_state_reg_offset[i]);
136 1.1 christos
137 1.10 christos fetched++;
138 1.10 christos }
139 1.1 christos
140 1.1 christos if (regno == -1
141 1.1 christos || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS))
142 1.10 christos {
143 1.10 christos x86_float_state32_t fp_regs;
144 1.10 christos unsigned int fp_count = x86_FLOAT_STATE32_COUNT;
145 1.10 christos kern_return_t ret;
146 1.1 christos
147 1.1 christos ret = thread_get_state
148 1.10 christos (current_thread, x86_FLOAT_STATE32, (thread_state_t) &fp_regs,
149 1.10 christos &fp_count);
150 1.1 christos if (ret != KERN_SUCCESS)
151 1.1 christos {
152 1.10 christos warning (_("Error calling thread_get_state for "
153 1.10 christos "float registers for thread 0x%lx\n"),
154 1.10 christos (unsigned long) current_thread);
155 1.1 christos MACH_CHECK_ERROR (ret);
156 1.1 christos }
157 1.10 christos i387_supply_fxsave (regcache, -1, &fp_regs.__fpu_fcw);
158 1.10 christos fetched++;
159 1.10 christos }
160 1.1 christos }
161 1.1 christos
162 1.1 christos if (! fetched)
163 1.1 christos {
164 1.1 christos warning (_("unknown register %d"), regno);
165 1.8 christos regcache->raw_supply (regno, NULL);
166 1.1 christos }
167 1.1 christos }
168 1.1 christos
169 1.1 christos /* Store our register values back into the inferior.
170 1.1 christos If REGNO is -1, do this for all registers.
171 1.1 christos Otherwise, REGNO specifies which register (so we can save time). */
172 1.1 christos
173 1.8 christos void
174 1.8 christos i386_darwin_nat_target::store_registers (struct regcache *regcache,
175 1.8 christos int regno)
176 1.1 christos {
177 1.8 christos thread_t current_thread = regcache->ptid ().tid ();
178 1.8 christos struct gdbarch *gdbarch = regcache->arch ();
179 1.1 christos
180 1.1 christos #ifdef BFD64
181 1.1 christos if (gdbarch_ptr_bit (gdbarch) == 64)
182 1.1 christos {
183 1.1 christos if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno))
184 1.10 christos {
185 1.10 christos x86_thread_state_t gp_regs;
186 1.10 christos kern_return_t ret;
187 1.1 christos unsigned int gp_count = x86_THREAD_STATE_COUNT;
188 1.1 christos
189 1.1 christos ret = thread_get_state
190 1.1 christos (current_thread, x86_THREAD_STATE, (thread_state_t) &gp_regs,
191 1.1 christos &gp_count);
192 1.10 christos MACH_CHECK_ERROR (ret);
193 1.1 christos gdb_assert (gp_regs.tsh.flavor == x86_THREAD_STATE64);
194 1.10 christos gdb_assert (gp_regs.tsh.count == x86_THREAD_STATE64_COUNT);
195 1.1 christos
196 1.1 christos amd64_collect_native_gregset (regcache, &gp_regs.uts, regno);
197 1.1 christos
198 1.3 christos /* Some kernels don't sanitize the values. */
199 1.3 christos gp_regs.uts.ts64.__fs &= 0xffff;
200 1.3 christos gp_regs.uts.ts64.__gs &= 0xffff;
201 1.3 christos
202 1.10 christos ret = thread_set_state (current_thread, x86_THREAD_STATE,
203 1.10 christos (thread_state_t) &gp_regs,
204 1.10 christos x86_THREAD_STATE_COUNT);
205 1.10 christos MACH_CHECK_ERROR (ret);
206 1.10 christos }
207 1.1 christos
208 1.1 christos if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno))
209 1.10 christos {
210 1.10 christos x86_float_state_t fp_regs;
211 1.10 christos kern_return_t ret;
212 1.1 christos unsigned int fp_count = x86_FLOAT_STATE_COUNT;
213 1.1 christos
214 1.1 christos ret = thread_get_state
215 1.1 christos (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs,
216 1.1 christos &fp_count);
217 1.10 christos MACH_CHECK_ERROR (ret);
218 1.10 christos gdb_assert (fp_regs.fsh.flavor == x86_FLOAT_STATE64);
219 1.10 christos gdb_assert (fp_regs.fsh.count == x86_FLOAT_STATE64_COUNT);
220 1.1 christos
221 1.1 christos amd64_collect_fxsave (regcache, regno, &fp_regs.ufs.fs64.__fpu_fcw);
222 1.1 christos
223 1.1 christos ret = thread_set_state (current_thread, x86_FLOAT_STATE,
224 1.1 christos (thread_state_t) & fp_regs,
225 1.1 christos x86_FLOAT_STATE_COUNT);
226 1.1 christos MACH_CHECK_ERROR (ret);
227 1.10 christos }
228 1.1 christos }
229 1.1 christos else
230 1.1 christos #endif
231 1.1 christos {
232 1.1 christos if (regno == -1 || regno < I386_NUM_GREGS)
233 1.10 christos {
234 1.10 christos x86_thread_state32_t gp_regs;
235 1.10 christos kern_return_t ret;
236 1.10 christos unsigned int gp_count = x86_THREAD_STATE32_COUNT;
237 1.1 christos int i;
238 1.1 christos
239 1.10 christos ret = thread_get_state
240 1.10 christos (current_thread, x86_THREAD_STATE32, (thread_state_t) &gp_regs,
241 1.10 christos &gp_count);
242 1.1 christos MACH_CHECK_ERROR (ret);
243 1.1 christos
244 1.1 christos for (i = 0; i < I386_NUM_GREGS; i++)
245 1.1 christos if (regno == -1 || regno == i)
246 1.8 christos regcache->raw_collect
247 1.8 christos (i, (char *) &gp_regs + i386_darwin_thread_state_reg_offset[i]);
248 1.1 christos
249 1.10 christos ret = thread_set_state (current_thread, x86_THREAD_STATE32,
250 1.10 christos (thread_state_t) &gp_regs,
251 1.10 christos x86_THREAD_STATE32_COUNT);
252 1.10 christos MACH_CHECK_ERROR (ret);
253 1.10 christos }
254 1.1 christos
255 1.1 christos if (regno == -1
256 1.1 christos || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS))
257 1.10 christos {
258 1.10 christos x86_float_state32_t fp_regs;
259 1.10 christos unsigned int fp_count = x86_FLOAT_STATE32_COUNT;
260 1.10 christos kern_return_t ret;
261 1.1 christos
262 1.1 christos ret = thread_get_state
263 1.10 christos (current_thread, x86_FLOAT_STATE32, (thread_state_t) & fp_regs,
264 1.10 christos &fp_count);
265 1.1 christos MACH_CHECK_ERROR (ret);
266 1.1 christos
267 1.1 christos i387_collect_fxsave (regcache, regno, &fp_regs.__fpu_fcw);
268 1.1 christos
269 1.1 christos ret = thread_set_state (current_thread, x86_FLOAT_STATE32,
270 1.1 christos (thread_state_t) &fp_regs,
271 1.1 christos x86_FLOAT_STATE32_COUNT);
272 1.1 christos MACH_CHECK_ERROR (ret);
273 1.10 christos }
274 1.1 christos }
275 1.1 christos }
276 1.1 christos
277 1.1 christos /* Support for debug registers, boosted mostly from i386-linux-nat.c. */
278 1.1 christos
279 1.1 christos static void
280 1.1 christos i386_darwin_dr_set (int regnum, CORE_ADDR value)
281 1.1 christos {
282 1.1 christos thread_t current_thread;
283 1.1 christos x86_debug_state_t dr_regs;
284 1.1 christos kern_return_t ret;
285 1.1 christos unsigned int dr_count;
286 1.1 christos
287 1.1 christos gdb_assert (regnum >= 0 && regnum <= DR_CONTROL);
288 1.1 christos
289 1.8 christos current_thread = inferior_ptid.tid ();
290 1.1 christos
291 1.1 christos dr_regs.dsh.flavor = x86_DEBUG_STATE;
292 1.1 christos dr_regs.dsh.count = x86_DEBUG_STATE_COUNT;
293 1.1 christos dr_count = x86_DEBUG_STATE_COUNT;
294 1.1 christos ret = thread_get_state (current_thread, x86_DEBUG_STATE,
295 1.10 christos (thread_state_t) &dr_regs, &dr_count);
296 1.1 christos MACH_CHECK_ERROR (ret);
297 1.1 christos
298 1.1 christos switch (dr_regs.dsh.flavor)
299 1.1 christos {
300 1.1 christos case x86_DEBUG_STATE32:
301 1.1 christos switch (regnum)
302 1.1 christos {
303 1.1 christos case 0:
304 1.1 christos dr_regs.uds.ds32.__dr0 = value;
305 1.1 christos break;
306 1.1 christos case 1:
307 1.1 christos dr_regs.uds.ds32.__dr1 = value;
308 1.1 christos break;
309 1.1 christos case 2:
310 1.1 christos dr_regs.uds.ds32.__dr2 = value;
311 1.1 christos break;
312 1.1 christos case 3:
313 1.1 christos dr_regs.uds.ds32.__dr3 = value;
314 1.1 christos break;
315 1.1 christos case 4:
316 1.1 christos dr_regs.uds.ds32.__dr4 = value;
317 1.1 christos break;
318 1.1 christos case 5:
319 1.1 christos dr_regs.uds.ds32.__dr5 = value;
320 1.1 christos break;
321 1.1 christos case 6:
322 1.1 christos dr_regs.uds.ds32.__dr6 = value;
323 1.1 christos break;
324 1.1 christos case 7:
325 1.1 christos dr_regs.uds.ds32.__dr7 = value;
326 1.1 christos break;
327 1.1 christos }
328 1.1 christos break;
329 1.1 christos #ifdef BFD64
330 1.1 christos case x86_DEBUG_STATE64:
331 1.1 christos switch (regnum)
332 1.1 christos {
333 1.1 christos case 0:
334 1.1 christos dr_regs.uds.ds64.__dr0 = value;
335 1.1 christos break;
336 1.1 christos case 1:
337 1.1 christos dr_regs.uds.ds64.__dr1 = value;
338 1.1 christos break;
339 1.1 christos case 2:
340 1.1 christos dr_regs.uds.ds64.__dr2 = value;
341 1.1 christos break;
342 1.1 christos case 3:
343 1.1 christos dr_regs.uds.ds64.__dr3 = value;
344 1.1 christos break;
345 1.1 christos case 4:
346 1.1 christos dr_regs.uds.ds64.__dr4 = value;
347 1.1 christos break;
348 1.1 christos case 5:
349 1.1 christos dr_regs.uds.ds64.__dr5 = value;
350 1.1 christos break;
351 1.1 christos case 6:
352 1.1 christos dr_regs.uds.ds64.__dr6 = value;
353 1.1 christos break;
354 1.1 christos case 7:
355 1.1 christos dr_regs.uds.ds64.__dr7 = value;
356 1.1 christos break;
357 1.1 christos }
358 1.1 christos break;
359 1.1 christos #endif
360 1.1 christos }
361 1.1 christos
362 1.1 christos ret = thread_set_state (current_thread, dr_regs.dsh.flavor,
363 1.10 christos (thread_state_t) &dr_regs.uds, dr_count);
364 1.1 christos
365 1.1 christos MACH_CHECK_ERROR (ret);
366 1.1 christos }
367 1.1 christos
368 1.1 christos static CORE_ADDR
369 1.1 christos i386_darwin_dr_get (int regnum)
370 1.1 christos {
371 1.1 christos thread_t current_thread;
372 1.1 christos x86_debug_state_t dr_regs;
373 1.1 christos kern_return_t ret;
374 1.1 christos unsigned int dr_count;
375 1.1 christos
376 1.1 christos gdb_assert (regnum >= 0 && regnum <= DR_CONTROL);
377 1.1 christos
378 1.8 christos current_thread = inferior_ptid.tid ();
379 1.1 christos
380 1.1 christos dr_regs.dsh.flavor = x86_DEBUG_STATE;
381 1.1 christos dr_regs.dsh.count = x86_DEBUG_STATE_COUNT;
382 1.1 christos dr_count = x86_DEBUG_STATE_COUNT;
383 1.1 christos ret = thread_get_state (current_thread, x86_DEBUG_STATE,
384 1.10 christos (thread_state_t) &dr_regs, &dr_count);
385 1.1 christos MACH_CHECK_ERROR (ret);
386 1.1 christos
387 1.1 christos switch (dr_regs.dsh.flavor)
388 1.1 christos {
389 1.1 christos case x86_DEBUG_STATE32:
390 1.1 christos switch (regnum)
391 1.1 christos {
392 1.1 christos case 0:
393 1.1 christos return dr_regs.uds.ds32.__dr0;
394 1.1 christos case 1:
395 1.1 christos return dr_regs.uds.ds32.__dr1;
396 1.1 christos case 2:
397 1.1 christos return dr_regs.uds.ds32.__dr2;
398 1.1 christos case 3:
399 1.1 christos return dr_regs.uds.ds32.__dr3;
400 1.1 christos case 4:
401 1.1 christos return dr_regs.uds.ds32.__dr4;
402 1.1 christos case 5:
403 1.1 christos return dr_regs.uds.ds32.__dr5;
404 1.1 christos case 6:
405 1.1 christos return dr_regs.uds.ds32.__dr6;
406 1.1 christos case 7:
407 1.1 christos return dr_regs.uds.ds32.__dr7;
408 1.1 christos default:
409 1.1 christos return -1;
410 1.1 christos }
411 1.1 christos break;
412 1.1 christos #ifdef BFD64
413 1.1 christos case x86_DEBUG_STATE64:
414 1.1 christos switch (regnum)
415 1.1 christos {
416 1.1 christos case 0:
417 1.1 christos return dr_regs.uds.ds64.__dr0;
418 1.1 christos case 1:
419 1.1 christos return dr_regs.uds.ds64.__dr1;
420 1.1 christos case 2:
421 1.1 christos return dr_regs.uds.ds64.__dr2;
422 1.1 christos case 3:
423 1.1 christos return dr_regs.uds.ds64.__dr3;
424 1.1 christos case 4:
425 1.1 christos return dr_regs.uds.ds64.__dr4;
426 1.1 christos case 5:
427 1.1 christos return dr_regs.uds.ds64.__dr5;
428 1.1 christos case 6:
429 1.1 christos return dr_regs.uds.ds64.__dr6;
430 1.1 christos case 7:
431 1.1 christos return dr_regs.uds.ds64.__dr7;
432 1.1 christos default:
433 1.1 christos return -1;
434 1.1 christos }
435 1.1 christos break;
436 1.1 christos #endif
437 1.1 christos default:
438 1.1 christos return -1;
439 1.1 christos }
440 1.1 christos }
441 1.1 christos
442 1.1 christos static void
443 1.1 christos i386_darwin_dr_set_control (unsigned long control)
444 1.1 christos {
445 1.1 christos i386_darwin_dr_set (DR_CONTROL, control);
446 1.1 christos }
447 1.1 christos
448 1.1 christos static void
449 1.1 christos i386_darwin_dr_set_addr (int regnum, CORE_ADDR addr)
450 1.1 christos {
451 1.1 christos gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
452 1.1 christos
453 1.1 christos i386_darwin_dr_set (DR_FIRSTADDR + regnum, addr);
454 1.1 christos }
455 1.1 christos
456 1.1 christos static CORE_ADDR
457 1.1 christos i386_darwin_dr_get_addr (int regnum)
458 1.1 christos {
459 1.1 christos return i386_darwin_dr_get (regnum);
460 1.1 christos }
461 1.1 christos
462 1.1 christos static unsigned long
463 1.1 christos i386_darwin_dr_get_status (void)
464 1.1 christos {
465 1.1 christos return i386_darwin_dr_get (DR_STATUS);
466 1.1 christos }
467 1.1 christos
468 1.1 christos static unsigned long
469 1.1 christos i386_darwin_dr_get_control (void)
470 1.1 christos {
471 1.1 christos return i386_darwin_dr_get (DR_CONTROL);
472 1.1 christos }
473 1.1 christos
474 1.1 christos void
475 1.1 christos darwin_check_osabi (darwin_inferior *inf, thread_t thread)
476 1.1 christos {
477 1.11 christos if (gdbarch_osabi (current_inferior ()->arch ()) == GDB_OSABI_UNKNOWN)
478 1.1 christos {
479 1.1 christos /* Attaching to a process. Let's figure out what kind it is. */
480 1.1 christos x86_thread_state_t gp_regs;
481 1.1 christos unsigned int gp_count = x86_THREAD_STATE_COUNT;
482 1.1 christos kern_return_t ret;
483 1.1 christos
484 1.1 christos ret = thread_get_state (thread, x86_THREAD_STATE,
485 1.1 christos (thread_state_t) &gp_regs, &gp_count);
486 1.1 christos if (ret != KERN_SUCCESS)
487 1.1 christos {
488 1.1 christos MACH_CHECK_ERROR (ret);
489 1.1 christos return;
490 1.1 christos }
491 1.1 christos
492 1.10 christos gdbarch_info info;
493 1.1 christos gdbarch_info_fill (&info);
494 1.11 christos info.byte_order = gdbarch_byte_order (current_inferior ()->arch ());
495 1.1 christos info.osabi = GDB_OSABI_DARWIN;
496 1.1 christos if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
497 1.1 christos info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386,
498 1.1 christos bfd_mach_x86_64);
499 1.1 christos else
500 1.1 christos info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386,
501 1.1 christos bfd_mach_i386_i386);
502 1.1 christos gdbarch_update_p (info);
503 1.1 christos }
504 1.1 christos }
505 1.1 christos
506 1.1 christos #define X86_EFLAGS_T 0x100UL
507 1.1 christos
508 1.1 christos /* Returning from a signal trampoline is done by calling a
509 1.1 christos special system call (sigreturn). This system call
510 1.1 christos restores the registers that were saved when the signal was
511 1.1 christos raised, including %eflags/%rflags. That means that single-stepping
512 1.1 christos won't work. Instead, we'll have to modify the signal context
513 1.1 christos that's about to be restored, and set the trace flag there. */
514 1.1 christos
515 1.1 christos static int
516 1.1 christos i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs)
517 1.1 christos {
518 1.11 christos bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
519 1.1 christos static const gdb_byte darwin_syscall[] = { 0xcd, 0x80 }; /* int 0x80 */
520 1.1 christos gdb_byte buf[sizeof (darwin_syscall)];
521 1.1 christos
522 1.1 christos /* Check if PC is at a sigreturn system call. */
523 1.1 christos if (target_read_memory (regs->uts.ts32.__eip, buf, sizeof (buf)) == 0
524 1.1 christos && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0
525 1.1 christos && regs->uts.ts32.__eax == 0xb8 /* SYS_sigreturn */)
526 1.1 christos {
527 1.1 christos ULONGEST uctx_addr;
528 1.1 christos ULONGEST mctx_addr;
529 1.1 christos ULONGEST flags_addr;
530 1.1 christos unsigned int eflags;
531 1.1 christos
532 1.1 christos uctx_addr = read_memory_unsigned_integer
533 1.1 christos (regs->uts.ts32.__esp + 4, 4, byte_order);
534 1.1 christos mctx_addr = read_memory_unsigned_integer
535 1.1 christos (uctx_addr + 28, 4, byte_order);
536 1.1 christos
537 1.1 christos flags_addr = mctx_addr + 12 + 9 * 4;
538 1.1 christos read_memory (flags_addr, (gdb_byte *) &eflags, 4);
539 1.1 christos eflags |= X86_EFLAGS_T;
540 1.1 christos write_memory (flags_addr, (gdb_byte *) &eflags, 4);
541 1.1 christos
542 1.1 christos return 1;
543 1.1 christos }
544 1.1 christos return 0;
545 1.1 christos }
546 1.1 christos
547 1.1 christos #ifdef BFD64
548 1.1 christos static int
549 1.1 christos amd64_darwin_sstep_at_sigreturn (x86_thread_state_t *regs)
550 1.1 christos {
551 1.11 christos bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
552 1.1 christos static const gdb_byte darwin_syscall[] = { 0x0f, 0x05 }; /* syscall */
553 1.1 christos gdb_byte buf[sizeof (darwin_syscall)];
554 1.1 christos
555 1.1 christos /* Check if PC is at a sigreturn system call. */
556 1.1 christos if (target_read_memory (regs->uts.ts64.__rip, buf, sizeof (buf)) == 0
557 1.1 christos && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0
558 1.1 christos && (regs->uts.ts64.__rax & 0xffffffff) == 0x20000b8 /* SYS_sigreturn */)
559 1.1 christos {
560 1.1 christos ULONGEST mctx_addr;
561 1.1 christos ULONGEST flags_addr;
562 1.1 christos unsigned int rflags;
563 1.1 christos
564 1.1 christos mctx_addr = read_memory_unsigned_integer
565 1.1 christos (regs->uts.ts64.__rdi + 48, 8, byte_order);
566 1.1 christos flags_addr = mctx_addr + 16 + 17 * 8;
567 1.1 christos
568 1.1 christos /* AMD64 is little endian. */
569 1.1 christos read_memory (flags_addr, (gdb_byte *) &rflags, 4);
570 1.1 christos rflags |= X86_EFLAGS_T;
571 1.1 christos write_memory (flags_addr, (gdb_byte *) &rflags, 4);
572 1.1 christos
573 1.1 christos return 1;
574 1.1 christos }
575 1.1 christos return 0;
576 1.1 christos }
577 1.1 christos #endif
578 1.1 christos
579 1.1 christos void
580 1.1 christos darwin_set_sstep (thread_t thread, int enable)
581 1.1 christos {
582 1.1 christos x86_thread_state_t regs;
583 1.1 christos unsigned int count = x86_THREAD_STATE_COUNT;
584 1.1 christos kern_return_t kret;
585 1.1 christos
586 1.1 christos kret = thread_get_state (thread, x86_THREAD_STATE,
587 1.1 christos (thread_state_t) ®s, &count);
588 1.1 christos if (kret != KERN_SUCCESS)
589 1.1 christos {
590 1.10 christos warning (_("darwin_set_sstep: error %x, thread=%x\n"),
591 1.10 christos kret, thread);
592 1.1 christos return;
593 1.1 christos }
594 1.1 christos
595 1.1 christos switch (regs.tsh.flavor)
596 1.1 christos {
597 1.1 christos case x86_THREAD_STATE32:
598 1.1 christos {
599 1.1 christos __uint32_t bit = enable ? X86_EFLAGS_T : 0;
600 1.1 christos
601 1.1 christos if (enable && i386_darwin_sstep_at_sigreturn (®s))
602 1.1 christos return;
603 1.1 christos if ((regs.uts.ts32.__eflags & X86_EFLAGS_T) == bit)
604 1.1 christos return;
605 1.1 christos regs.uts.ts32.__eflags
606 1.1 christos = (regs.uts.ts32.__eflags & ~X86_EFLAGS_T) | bit;
607 1.1 christos kret = thread_set_state (thread, x86_THREAD_STATE,
608 1.1 christos (thread_state_t) ®s, count);
609 1.1 christos MACH_CHECK_ERROR (kret);
610 1.1 christos }
611 1.1 christos break;
612 1.1 christos #ifdef BFD64
613 1.1 christos case x86_THREAD_STATE64:
614 1.1 christos {
615 1.1 christos __uint64_t bit = enable ? X86_EFLAGS_T : 0;
616 1.1 christos
617 1.1 christos if (enable && amd64_darwin_sstep_at_sigreturn (®s))
618 1.1 christos return;
619 1.1 christos if ((regs.uts.ts64.__rflags & X86_EFLAGS_T) == bit)
620 1.1 christos return;
621 1.1 christos regs.uts.ts64.__rflags
622 1.1 christos = (regs.uts.ts64.__rflags & ~X86_EFLAGS_T) | bit;
623 1.1 christos kret = thread_set_state (thread, x86_THREAD_STATE,
624 1.1 christos (thread_state_t) ®s, count);
625 1.1 christos MACH_CHECK_ERROR (kret);
626 1.1 christos }
627 1.1 christos break;
628 1.1 christos #endif
629 1.1 christos default:
630 1.1 christos error (_("darwin_set_sstep: unknown flavour: %d"), regs.tsh.flavor);
631 1.1 christos }
632 1.1 christos }
633 1.1 christos
634 1.9 christos void _initialize_i386_darwin_nat ();
635 1.1 christos void
636 1.9 christos _initialize_i386_darwin_nat ()
637 1.1 christos {
638 1.1 christos #ifdef BFD64
639 1.1 christos amd64_native_gregset64_reg_offset = amd64_darwin_thread_state_reg_offset;
640 1.1 christos amd64_native_gregset64_num_regs = amd64_darwin_thread_state_num_regs;
641 1.1 christos amd64_native_gregset32_reg_offset = i386_darwin_thread_state_reg_offset;
642 1.1 christos amd64_native_gregset32_num_regs = i386_darwin_thread_state_num_regs;
643 1.1 christos #endif
644 1.1 christos
645 1.3 christos x86_dr_low.set_control = i386_darwin_dr_set_control;
646 1.3 christos x86_dr_low.set_addr = i386_darwin_dr_set_addr;
647 1.3 christos x86_dr_low.get_addr = i386_darwin_dr_get_addr;
648 1.3 christos x86_dr_low.get_status = i386_darwin_dr_get_status;
649 1.3 christos x86_dr_low.get_control = i386_darwin_dr_get_control;
650 1.1 christos
651 1.1 christos /* Let's assume that the kernel is 64 bits iff the executable is. */
652 1.1 christos #ifdef __x86_64__
653 1.3 christos x86_set_debug_register_length (8);
654 1.1 christos #else
655 1.3 christos x86_set_debug_register_length (4);
656 1.1 christos #endif
657 1.1 christos
658 1.8 christos add_inf_child_target (&darwin_target);
659 1.1 christos }
660