GDB (API)
|
00001 /* Darwin support for GDB, the GNU debugger. 00002 Copyright (C) 1997-2013 Free Software Foundation, Inc. 00003 00004 Contributed by Apple Computer, Inc. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "defs.h" 00022 #include "frame.h" 00023 #include "inferior.h" 00024 #include "target.h" 00025 #include "symfile.h" 00026 #include "symtab.h" 00027 #include "objfiles.h" 00028 #include "gdbcmd.h" 00029 #include "regcache.h" 00030 #include "gdb_assert.h" 00031 #include "i386-tdep.h" 00032 #include "i387-tdep.h" 00033 #include "gdbarch.h" 00034 #include "arch-utils.h" 00035 #include "gdbcore.h" 00036 00037 #include "i386-nat.h" 00038 #include "darwin-nat.h" 00039 #include "i386-darwin-tdep.h" 00040 00041 #ifdef BFD64 00042 #include "amd64-nat.h" 00043 #include "amd64-tdep.h" 00044 #include "amd64-darwin-tdep.h" 00045 #endif 00046 00047 /* Read register values from the inferior process. 00048 If REGNO is -1, do this for all registers. 00049 Otherwise, REGNO specifies which register (so we can save time). */ 00050 static void 00051 i386_darwin_fetch_inferior_registers (struct target_ops *ops, 00052 struct regcache *regcache, int regno) 00053 { 00054 thread_t current_thread = ptid_get_tid (inferior_ptid); 00055 int fetched = 0; 00056 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00057 00058 #ifdef BFD64 00059 if (gdbarch_ptr_bit (gdbarch) == 64) 00060 { 00061 if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno)) 00062 { 00063 x86_thread_state_t gp_regs; 00064 unsigned int gp_count = x86_THREAD_STATE_COUNT; 00065 kern_return_t ret; 00066 00067 ret = thread_get_state 00068 (current_thread, x86_THREAD_STATE, (thread_state_t) & gp_regs, 00069 &gp_count); 00070 if (ret != KERN_SUCCESS) 00071 { 00072 printf_unfiltered (_("Error calling thread_get_state for " 00073 "GP registers for thread 0x%lx\n"), 00074 (unsigned long) current_thread); 00075 MACH_CHECK_ERROR (ret); 00076 } 00077 amd64_supply_native_gregset (regcache, &gp_regs.uts, -1); 00078 fetched++; 00079 } 00080 00081 if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno)) 00082 { 00083 x86_float_state_t fp_regs; 00084 unsigned int fp_count = x86_FLOAT_STATE_COUNT; 00085 kern_return_t ret; 00086 00087 ret = thread_get_state 00088 (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs, 00089 &fp_count); 00090 if (ret != KERN_SUCCESS) 00091 { 00092 printf_unfiltered (_("Error calling thread_get_state for " 00093 "float registers for thread 0x%lx\n"), 00094 (unsigned long) current_thread); 00095 MACH_CHECK_ERROR (ret); 00096 } 00097 amd64_supply_fxsave (regcache, -1, &fp_regs.ufs.fs64.__fpu_fcw); 00098 fetched++; 00099 } 00100 } 00101 else 00102 #endif 00103 { 00104 if (regno == -1 || regno < I386_NUM_GREGS) 00105 { 00106 x86_thread_state32_t gp_regs; 00107 unsigned int gp_count = x86_THREAD_STATE32_COUNT; 00108 kern_return_t ret; 00109 int i; 00110 00111 ret = thread_get_state 00112 (current_thread, x86_THREAD_STATE32, (thread_state_t) &gp_regs, 00113 &gp_count); 00114 if (ret != KERN_SUCCESS) 00115 { 00116 printf_unfiltered (_("Error calling thread_get_state for " 00117 "GP registers for thread 0x%lx\n"), 00118 (unsigned long) current_thread); 00119 MACH_CHECK_ERROR (ret); 00120 } 00121 for (i = 0; i < I386_NUM_GREGS; i++) 00122 regcache_raw_supply 00123 (regcache, i, 00124 (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]); 00125 00126 fetched++; 00127 } 00128 00129 if (regno == -1 00130 || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS)) 00131 { 00132 x86_float_state32_t fp_regs; 00133 unsigned int fp_count = x86_FLOAT_STATE32_COUNT; 00134 kern_return_t ret; 00135 00136 ret = thread_get_state 00137 (current_thread, x86_FLOAT_STATE32, (thread_state_t) &fp_regs, 00138 &fp_count); 00139 if (ret != KERN_SUCCESS) 00140 { 00141 printf_unfiltered (_("Error calling thread_get_state for " 00142 "float registers for thread 0x%lx\n"), 00143 (unsigned long) current_thread); 00144 MACH_CHECK_ERROR (ret); 00145 } 00146 i387_supply_fxsave (regcache, -1, &fp_regs.__fpu_fcw); 00147 fetched++; 00148 } 00149 } 00150 00151 if (! fetched) 00152 { 00153 warning (_("unknown register %d"), regno); 00154 regcache_raw_supply (regcache, regno, NULL); 00155 } 00156 } 00157 00158 /* Store our register values back into the inferior. 00159 If REGNO is -1, do this for all registers. 00160 Otherwise, REGNO specifies which register (so we can save time). */ 00161 00162 static void 00163 i386_darwin_store_inferior_registers (struct target_ops *ops, 00164 struct regcache *regcache, int regno) 00165 { 00166 thread_t current_thread = ptid_get_tid (inferior_ptid); 00167 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00168 00169 #ifdef BFD64 00170 if (gdbarch_ptr_bit (gdbarch) == 64) 00171 { 00172 if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno)) 00173 { 00174 x86_thread_state_t gp_regs; 00175 kern_return_t ret; 00176 unsigned int gp_count = x86_THREAD_STATE_COUNT; 00177 00178 ret = thread_get_state 00179 (current_thread, x86_THREAD_STATE, (thread_state_t) &gp_regs, 00180 &gp_count); 00181 MACH_CHECK_ERROR (ret); 00182 gdb_assert (gp_regs.tsh.flavor == x86_THREAD_STATE64); 00183 gdb_assert (gp_regs.tsh.count == x86_THREAD_STATE64_COUNT); 00184 00185 amd64_collect_native_gregset (regcache, &gp_regs.uts, regno); 00186 00187 ret = thread_set_state (current_thread, x86_THREAD_STATE, 00188 (thread_state_t) &gp_regs, 00189 x86_THREAD_STATE_COUNT); 00190 MACH_CHECK_ERROR (ret); 00191 } 00192 00193 if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno)) 00194 { 00195 x86_float_state_t fp_regs; 00196 kern_return_t ret; 00197 unsigned int fp_count = x86_FLOAT_STATE_COUNT; 00198 00199 ret = thread_get_state 00200 (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs, 00201 &fp_count); 00202 MACH_CHECK_ERROR (ret); 00203 gdb_assert (fp_regs.fsh.flavor == x86_FLOAT_STATE64); 00204 gdb_assert (fp_regs.fsh.count == x86_FLOAT_STATE64_COUNT); 00205 00206 amd64_collect_fxsave (regcache, regno, &fp_regs.ufs.fs64.__fpu_fcw); 00207 00208 ret = thread_set_state (current_thread, x86_FLOAT_STATE, 00209 (thread_state_t) & fp_regs, 00210 x86_FLOAT_STATE_COUNT); 00211 MACH_CHECK_ERROR (ret); 00212 } 00213 } 00214 else 00215 #endif 00216 { 00217 if (regno == -1 || regno < I386_NUM_GREGS) 00218 { 00219 x86_thread_state32_t gp_regs; 00220 kern_return_t ret; 00221 unsigned int gp_count = x86_THREAD_STATE32_COUNT; 00222 int i; 00223 00224 ret = thread_get_state 00225 (current_thread, x86_THREAD_STATE32, (thread_state_t) &gp_regs, 00226 &gp_count); 00227 MACH_CHECK_ERROR (ret); 00228 00229 for (i = 0; i < I386_NUM_GREGS; i++) 00230 if (regno == -1 || regno == i) 00231 regcache_raw_collect 00232 (regcache, i, 00233 (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]); 00234 00235 ret = thread_set_state (current_thread, x86_THREAD_STATE32, 00236 (thread_state_t) &gp_regs, 00237 x86_THREAD_STATE32_COUNT); 00238 MACH_CHECK_ERROR (ret); 00239 } 00240 00241 if (regno == -1 00242 || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS)) 00243 { 00244 x86_float_state32_t fp_regs; 00245 unsigned int fp_count = x86_FLOAT_STATE32_COUNT; 00246 kern_return_t ret; 00247 00248 ret = thread_get_state 00249 (current_thread, x86_FLOAT_STATE32, (thread_state_t) & fp_regs, 00250 &fp_count); 00251 MACH_CHECK_ERROR (ret); 00252 00253 i387_collect_fxsave (regcache, regno, &fp_regs.__fpu_fcw); 00254 00255 ret = thread_set_state (current_thread, x86_FLOAT_STATE32, 00256 (thread_state_t) &fp_regs, 00257 x86_FLOAT_STATE32_COUNT); 00258 MACH_CHECK_ERROR (ret); 00259 } 00260 } 00261 } 00262 00263 /* Support for debug registers, boosted mostly from i386-linux-nat.c. */ 00264 00265 static void 00266 i386_darwin_dr_set (int regnum, CORE_ADDR value) 00267 { 00268 int current_pid; 00269 thread_t current_thread; 00270 x86_debug_state_t dr_regs; 00271 kern_return_t ret; 00272 unsigned int dr_count; 00273 00274 gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); 00275 00276 current_thread = ptid_get_tid (inferior_ptid); 00277 00278 dr_regs.dsh.flavor = x86_DEBUG_STATE; 00279 dr_regs.dsh.count = x86_DEBUG_STATE_COUNT; 00280 dr_count = x86_DEBUG_STATE_COUNT; 00281 ret = thread_get_state (current_thread, x86_DEBUG_STATE, 00282 (thread_state_t) &dr_regs, &dr_count); 00283 MACH_CHECK_ERROR (ret); 00284 00285 switch (dr_regs.dsh.flavor) 00286 { 00287 case x86_DEBUG_STATE32: 00288 switch (regnum) 00289 { 00290 case 0: 00291 dr_regs.uds.ds32.__dr0 = value; 00292 break; 00293 case 1: 00294 dr_regs.uds.ds32.__dr1 = value; 00295 break; 00296 case 2: 00297 dr_regs.uds.ds32.__dr2 = value; 00298 break; 00299 case 3: 00300 dr_regs.uds.ds32.__dr3 = value; 00301 break; 00302 case 4: 00303 dr_regs.uds.ds32.__dr4 = value; 00304 break; 00305 case 5: 00306 dr_regs.uds.ds32.__dr5 = value; 00307 break; 00308 case 6: 00309 dr_regs.uds.ds32.__dr6 = value; 00310 break; 00311 case 7: 00312 dr_regs.uds.ds32.__dr7 = value; 00313 break; 00314 } 00315 break; 00316 #ifdef BFD64 00317 case x86_DEBUG_STATE64: 00318 switch (regnum) 00319 { 00320 case 0: 00321 dr_regs.uds.ds64.__dr0 = value; 00322 break; 00323 case 1: 00324 dr_regs.uds.ds64.__dr1 = value; 00325 break; 00326 case 2: 00327 dr_regs.uds.ds64.__dr2 = value; 00328 break; 00329 case 3: 00330 dr_regs.uds.ds64.__dr3 = value; 00331 break; 00332 case 4: 00333 dr_regs.uds.ds64.__dr4 = value; 00334 break; 00335 case 5: 00336 dr_regs.uds.ds64.__dr5 = value; 00337 break; 00338 case 6: 00339 dr_regs.uds.ds64.__dr6 = value; 00340 break; 00341 case 7: 00342 dr_regs.uds.ds64.__dr7 = value; 00343 break; 00344 } 00345 break; 00346 #endif 00347 } 00348 00349 ret = thread_set_state (current_thread, dr_regs.dsh.flavor, 00350 (thread_state_t) &dr_regs.uds, dr_count); 00351 00352 MACH_CHECK_ERROR (ret); 00353 } 00354 00355 static CORE_ADDR 00356 i386_darwin_dr_get (int regnum) 00357 { 00358 thread_t current_thread; 00359 x86_debug_state_t dr_regs; 00360 kern_return_t ret; 00361 unsigned int dr_count; 00362 00363 gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); 00364 00365 current_thread = ptid_get_tid (inferior_ptid); 00366 00367 dr_regs.dsh.flavor = x86_DEBUG_STATE; 00368 dr_regs.dsh.count = x86_DEBUG_STATE_COUNT; 00369 dr_count = x86_DEBUG_STATE_COUNT; 00370 ret = thread_get_state (current_thread, x86_DEBUG_STATE, 00371 (thread_state_t) &dr_regs, &dr_count); 00372 MACH_CHECK_ERROR (ret); 00373 00374 switch (dr_regs.dsh.flavor) 00375 { 00376 case x86_DEBUG_STATE32: 00377 switch (regnum) 00378 { 00379 case 0: 00380 return dr_regs.uds.ds32.__dr0; 00381 case 1: 00382 return dr_regs.uds.ds32.__dr1; 00383 case 2: 00384 return dr_regs.uds.ds32.__dr2; 00385 case 3: 00386 return dr_regs.uds.ds32.__dr3; 00387 case 4: 00388 return dr_regs.uds.ds32.__dr4; 00389 case 5: 00390 return dr_regs.uds.ds32.__dr5; 00391 case 6: 00392 return dr_regs.uds.ds32.__dr6; 00393 case 7: 00394 return dr_regs.uds.ds32.__dr7; 00395 default: 00396 return -1; 00397 } 00398 break; 00399 #ifdef BFD64 00400 case x86_DEBUG_STATE64: 00401 switch (regnum) 00402 { 00403 case 0: 00404 return dr_regs.uds.ds64.__dr0; 00405 case 1: 00406 return dr_regs.uds.ds64.__dr1; 00407 case 2: 00408 return dr_regs.uds.ds64.__dr2; 00409 case 3: 00410 return dr_regs.uds.ds64.__dr3; 00411 case 4: 00412 return dr_regs.uds.ds64.__dr4; 00413 case 5: 00414 return dr_regs.uds.ds64.__dr5; 00415 case 6: 00416 return dr_regs.uds.ds64.__dr6; 00417 case 7: 00418 return dr_regs.uds.ds64.__dr7; 00419 default: 00420 return -1; 00421 } 00422 break; 00423 #endif 00424 default: 00425 return -1; 00426 } 00427 } 00428 00429 static void 00430 i386_darwin_dr_set_control (unsigned long control) 00431 { 00432 i386_darwin_dr_set (DR_CONTROL, control); 00433 } 00434 00435 static void 00436 i386_darwin_dr_set_addr (int regnum, CORE_ADDR addr) 00437 { 00438 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR); 00439 00440 i386_darwin_dr_set (DR_FIRSTADDR + regnum, addr); 00441 } 00442 00443 static CORE_ADDR 00444 i386_darwin_dr_get_addr (int regnum) 00445 { 00446 return i386_darwin_dr_get (regnum); 00447 } 00448 00449 static unsigned long 00450 i386_darwin_dr_get_status (void) 00451 { 00452 return i386_darwin_dr_get (DR_STATUS); 00453 } 00454 00455 static unsigned long 00456 i386_darwin_dr_get_control (void) 00457 { 00458 return i386_darwin_dr_get (DR_CONTROL); 00459 } 00460 00461 void 00462 darwin_check_osabi (darwin_inferior *inf, thread_t thread) 00463 { 00464 if (gdbarch_osabi (target_gdbarch ()) == GDB_OSABI_UNKNOWN) 00465 { 00466 /* Attaching to a process. Let's figure out what kind it is. */ 00467 x86_thread_state_t gp_regs; 00468 struct gdbarch_info info; 00469 unsigned int gp_count = x86_THREAD_STATE_COUNT; 00470 kern_return_t ret; 00471 00472 ret = thread_get_state (thread, x86_THREAD_STATE, 00473 (thread_state_t) &gp_regs, &gp_count); 00474 if (ret != KERN_SUCCESS) 00475 { 00476 MACH_CHECK_ERROR (ret); 00477 return; 00478 } 00479 00480 gdbarch_info_init (&info); 00481 gdbarch_info_fill (&info); 00482 info.byte_order = gdbarch_byte_order (target_gdbarch ()); 00483 info.osabi = GDB_OSABI_DARWIN; 00484 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 00485 info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, 00486 bfd_mach_x86_64); 00487 else 00488 info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, 00489 bfd_mach_i386_i386); 00490 gdbarch_update_p (info); 00491 } 00492 } 00493 00494 #define X86_EFLAGS_T 0x100UL 00495 00496 /* Returning from a signal trampoline is done by calling a 00497 special system call (sigreturn). This system call 00498 restores the registers that were saved when the signal was 00499 raised, including %eflags/%rflags. That means that single-stepping 00500 won't work. Instead, we'll have to modify the signal context 00501 that's about to be restored, and set the trace flag there. */ 00502 00503 static int 00504 i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) 00505 { 00506 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00507 static const gdb_byte darwin_syscall[] = { 0xcd, 0x80 }; /* int 0x80 */ 00508 gdb_byte buf[sizeof (darwin_syscall)]; 00509 00510 /* Check if PC is at a sigreturn system call. */ 00511 if (target_read_memory (regs->uts.ts32.__eip, buf, sizeof (buf)) == 0 00512 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 00513 && regs->uts.ts32.__eax == 0xb8 /* SYS_sigreturn */) 00514 { 00515 ULONGEST uctx_addr; 00516 ULONGEST mctx_addr; 00517 ULONGEST flags_addr; 00518 unsigned int eflags; 00519 00520 uctx_addr = read_memory_unsigned_integer 00521 (regs->uts.ts32.__esp + 4, 4, byte_order); 00522 mctx_addr = read_memory_unsigned_integer 00523 (uctx_addr + 28, 4, byte_order); 00524 00525 flags_addr = mctx_addr + 12 + 9 * 4; 00526 read_memory (flags_addr, (gdb_byte *) &eflags, 4); 00527 eflags |= X86_EFLAGS_T; 00528 write_memory (flags_addr, (gdb_byte *) &eflags, 4); 00529 00530 return 1; 00531 } 00532 return 0; 00533 } 00534 00535 #ifdef BFD64 00536 static int 00537 amd64_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) 00538 { 00539 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00540 static const gdb_byte darwin_syscall[] = { 0x0f, 0x05 }; /* syscall */ 00541 gdb_byte buf[sizeof (darwin_syscall)]; 00542 00543 /* Check if PC is at a sigreturn system call. */ 00544 if (target_read_memory (regs->uts.ts64.__rip, buf, sizeof (buf)) == 0 00545 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 00546 && (regs->uts.ts64.__rax & 0xffffffff) == 0x20000b8 /* SYS_sigreturn */) 00547 { 00548 ULONGEST mctx_addr; 00549 ULONGEST flags_addr; 00550 unsigned int rflags; 00551 00552 mctx_addr = read_memory_unsigned_integer 00553 (regs->uts.ts64.__rdi + 48, 8, byte_order); 00554 flags_addr = mctx_addr + 16 + 17 * 8; 00555 00556 /* AMD64 is little endian. */ 00557 read_memory (flags_addr, (gdb_byte *) &rflags, 4); 00558 rflags |= X86_EFLAGS_T; 00559 write_memory (flags_addr, (gdb_byte *) &rflags, 4); 00560 00561 return 1; 00562 } 00563 return 0; 00564 } 00565 #endif 00566 00567 void 00568 darwin_set_sstep (thread_t thread, int enable) 00569 { 00570 x86_thread_state_t regs; 00571 unsigned int count = x86_THREAD_STATE_COUNT; 00572 kern_return_t kret; 00573 00574 kret = thread_get_state (thread, x86_THREAD_STATE, 00575 (thread_state_t) ®s, &count); 00576 if (kret != KERN_SUCCESS) 00577 { 00578 printf_unfiltered (_("darwin_set_sstep: error %x, thread=%x\n"), 00579 kret, thread); 00580 return; 00581 } 00582 00583 switch (regs.tsh.flavor) 00584 { 00585 case x86_THREAD_STATE32: 00586 { 00587 __uint32_t bit = enable ? X86_EFLAGS_T : 0; 00588 00589 if (enable && i386_darwin_sstep_at_sigreturn (®s)) 00590 return; 00591 if ((regs.uts.ts32.__eflags & X86_EFLAGS_T) == bit) 00592 return; 00593 regs.uts.ts32.__eflags 00594 = (regs.uts.ts32.__eflags & ~X86_EFLAGS_T) | bit; 00595 kret = thread_set_state (thread, x86_THREAD_STATE, 00596 (thread_state_t) ®s, count); 00597 MACH_CHECK_ERROR (kret); 00598 } 00599 break; 00600 #ifdef BFD64 00601 case x86_THREAD_STATE64: 00602 { 00603 __uint64_t bit = enable ? X86_EFLAGS_T : 0; 00604 00605 if (enable && amd64_darwin_sstep_at_sigreturn (®s)) 00606 return; 00607 if ((regs.uts.ts64.__rflags & X86_EFLAGS_T) == bit) 00608 return; 00609 regs.uts.ts64.__rflags 00610 = (regs.uts.ts64.__rflags & ~X86_EFLAGS_T) | bit; 00611 kret = thread_set_state (thread, x86_THREAD_STATE, 00612 (thread_state_t) ®s, count); 00613 MACH_CHECK_ERROR (kret); 00614 } 00615 break; 00616 #endif 00617 default: 00618 error (_("darwin_set_sstep: unknown flavour: %d"), regs.tsh.flavor); 00619 } 00620 } 00621 00622 void 00623 darwin_complete_target (struct target_ops *target) 00624 { 00625 #ifdef BFD64 00626 amd64_native_gregset64_reg_offset = amd64_darwin_thread_state_reg_offset; 00627 amd64_native_gregset64_num_regs = amd64_darwin_thread_state_num_regs; 00628 amd64_native_gregset32_reg_offset = i386_darwin_thread_state_reg_offset; 00629 amd64_native_gregset32_num_regs = i386_darwin_thread_state_num_regs; 00630 #endif 00631 00632 i386_use_watchpoints (target); 00633 00634 i386_dr_low.set_control = i386_darwin_dr_set_control; 00635 i386_dr_low.set_addr = i386_darwin_dr_set_addr; 00636 i386_dr_low.get_addr = i386_darwin_dr_get_addr; 00637 i386_dr_low.get_status = i386_darwin_dr_get_status; 00638 i386_dr_low.get_control = i386_darwin_dr_get_control; 00639 00640 /* Let's assume that the kernel is 64 bits iff the executable is. */ 00641 #ifdef __x86_64__ 00642 i386_set_debug_register_length (8); 00643 #else 00644 i386_set_debug_register_length (4); 00645 #endif 00646 00647 target->to_fetch_registers = i386_darwin_fetch_inferior_registers; 00648 target->to_store_registers = i386_darwin_store_inferior_registers; 00649 }