Index: gdb/i386-darwin-nat.c |
diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c |
index 6afbbd0beceb89ba358b4c36bf12be5cafbb135f..742ceda2e84498c0fc6bdd05b13e45408abede14 100644 |
--- a/gdb/i386-darwin-nat.c |
+++ b/gdb/i386-darwin-nat.c |
@@ -1,5 +1,5 @@ |
/* Darwin support for GDB, the GNU debugger. |
- Copyright 1997-2002, 2008-2012 Free Software Foundation, Inc. |
+ Copyright (C) 1997-2013 Free Software Foundation, Inc. |
Contributed by Apple Computer, Inc. |
@@ -260,132 +260,179 @@ i386_darwin_store_inferior_registers (struct target_ops *ops, |
} |
} |
-#ifdef HW_WATCHPOINT_NOT_YET_ENABLED |
/* Support for debug registers, boosted mostly from i386-linux-nat.c. */ |
static void |
-i386_darwin_dr_set (int regnum, uint32_t value) |
+i386_darwin_dr_set (int regnum, CORE_ADDR value) |
{ |
int current_pid; |
thread_t current_thread; |
x86_debug_state_t dr_regs; |
kern_return_t ret; |
- unsigned int dr_count = x86_DEBUG_STATE_COUNT; |
+ unsigned int dr_count; |
gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); |
current_thread = ptid_get_tid (inferior_ptid); |
- dr_regs.dsh.flavor = x86_DEBUG_STATE32; |
- dr_regs.dsh.count = x86_DEBUG_STATE32_COUNT; |
+ dr_regs.dsh.flavor = x86_DEBUG_STATE; |
+ dr_regs.dsh.count = x86_DEBUG_STATE_COUNT; |
dr_count = x86_DEBUG_STATE_COUNT; |
- ret = thread_get_state (current_thread, x86_DEBUG_STATE, |
+ ret = thread_get_state (current_thread, x86_DEBUG_STATE, |
(thread_state_t) &dr_regs, &dr_count); |
+ MACH_CHECK_ERROR (ret); |
- if (ret != KERN_SUCCESS) |
+ switch (dr_regs.dsh.flavor) |
{ |
- printf_unfiltered (_("Error reading debug registers " |
- "thread 0x%x via thread_get_state\n"), |
- (int) current_thread); |
- MACH_CHECK_ERROR (ret); |
- } |
- |
- switch (regnum) |
- { |
- case 0: |
- dr_regs.uds.ds32.__dr0 = value; |
- break; |
- case 1: |
- dr_regs.uds.ds32.__dr1 = value; |
- break; |
- case 2: |
- dr_regs.uds.ds32.__dr2 = value; |
- break; |
- case 3: |
- dr_regs.uds.ds32.__dr3 = value; |
- break; |
- case 4: |
- dr_regs.uds.ds32.__dr4 = value; |
- break; |
- case 5: |
- dr_regs.uds.ds32.__dr5 = value; |
- break; |
- case 6: |
- dr_regs.uds.ds32.__dr6 = value; |
- break; |
- case 7: |
- dr_regs.uds.ds32.__dr7 = value; |
- break; |
+ case x86_DEBUG_STATE32: |
+ switch (regnum) |
+ { |
+ case 0: |
+ dr_regs.uds.ds32.__dr0 = value; |
+ break; |
+ case 1: |
+ dr_regs.uds.ds32.__dr1 = value; |
+ break; |
+ case 2: |
+ dr_regs.uds.ds32.__dr2 = value; |
+ break; |
+ case 3: |
+ dr_regs.uds.ds32.__dr3 = value; |
+ break; |
+ case 4: |
+ dr_regs.uds.ds32.__dr4 = value; |
+ break; |
+ case 5: |
+ dr_regs.uds.ds32.__dr5 = value; |
+ break; |
+ case 6: |
+ dr_regs.uds.ds32.__dr6 = value; |
+ break; |
+ case 7: |
+ dr_regs.uds.ds32.__dr7 = value; |
+ break; |
+ } |
+ break; |
+#ifdef BFD64 |
+ case x86_DEBUG_STATE64: |
+ switch (regnum) |
+ { |
+ case 0: |
+ dr_regs.uds.ds64.__dr0 = value; |
+ break; |
+ case 1: |
+ dr_regs.uds.ds64.__dr1 = value; |
+ break; |
+ case 2: |
+ dr_regs.uds.ds64.__dr2 = value; |
+ break; |
+ case 3: |
+ dr_regs.uds.ds64.__dr3 = value; |
+ break; |
+ case 4: |
+ dr_regs.uds.ds64.__dr4 = value; |
+ break; |
+ case 5: |
+ dr_regs.uds.ds64.__dr5 = value; |
+ break; |
+ case 6: |
+ dr_regs.uds.ds64.__dr6 = value; |
+ break; |
+ case 7: |
+ dr_regs.uds.ds64.__dr7 = value; |
+ break; |
+ } |
+ break; |
+#endif |
} |
- ret = thread_set_state (current_thread, x86_DEBUG_STATE, |
- (thread_state_t) &dr_regs, dr_count); |
+ ret = thread_set_state (current_thread, dr_regs.dsh.flavor, |
+ (thread_state_t) &dr_regs.uds, dr_count); |
- if (ret != KERN_SUCCESS) |
- { |
- printf_unfiltered (_("Error writing debug registers " |
- "thread 0x%x via thread_get_state\n"), |
- (int) current_thread); |
- MACH_CHECK_ERROR (ret); |
- } |
+ MACH_CHECK_ERROR (ret); |
} |
-static uint32_t |
+static CORE_ADDR |
i386_darwin_dr_get (int regnum) |
{ |
thread_t current_thread; |
x86_debug_state_t dr_regs; |
kern_return_t ret; |
- unsigned int dr_count = x86_DEBUG_STATE_COUNT; |
+ unsigned int dr_count; |
gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); |
current_thread = ptid_get_tid (inferior_ptid); |
- dr_regs.dsh.flavor = x86_DEBUG_STATE32; |
- dr_regs.dsh.count = x86_DEBUG_STATE32_COUNT; |
+ dr_regs.dsh.flavor = x86_DEBUG_STATE; |
+ dr_regs.dsh.count = x86_DEBUG_STATE_COUNT; |
dr_count = x86_DEBUG_STATE_COUNT; |
- ret = thread_get_state (current_thread, x86_DEBUG_STATE, |
+ ret = thread_get_state (current_thread, x86_DEBUG_STATE, |
(thread_state_t) &dr_regs, &dr_count); |
+ MACH_CHECK_ERROR (ret); |
- if (ret != KERN_SUCCESS) |
+ switch (dr_regs.dsh.flavor) |
{ |
- printf_unfiltered (_("Error reading debug registers " |
- "thread 0x%x via thread_get_state\n"), |
- (int) current_thread); |
- MACH_CHECK_ERROR (ret); |
- } |
- |
- switch (regnum) |
- { |
- case 0: |
- return dr_regs.uds.ds32.__dr0; |
- case 1: |
- return dr_regs.uds.ds32.__dr1; |
- case 2: |
- return dr_regs.uds.ds32.__dr2; |
- case 3: |
- return dr_regs.uds.ds32.__dr3; |
- case 4: |
- return dr_regs.uds.ds32.__dr4; |
- case 5: |
- return dr_regs.uds.ds32.__dr5; |
- case 6: |
- return dr_regs.uds.ds32.__dr6; |
- case 7: |
- return dr_regs.uds.ds32.__dr7; |
- default: |
- return -1; |
+ case x86_DEBUG_STATE32: |
+ switch (regnum) |
+ { |
+ case 0: |
+ return dr_regs.uds.ds32.__dr0; |
+ case 1: |
+ return dr_regs.uds.ds32.__dr1; |
+ case 2: |
+ return dr_regs.uds.ds32.__dr2; |
+ case 3: |
+ return dr_regs.uds.ds32.__dr3; |
+ case 4: |
+ return dr_regs.uds.ds32.__dr4; |
+ case 5: |
+ return dr_regs.uds.ds32.__dr5; |
+ case 6: |
+ return dr_regs.uds.ds32.__dr6; |
+ case 7: |
+ return dr_regs.uds.ds32.__dr7; |
+ default: |
+ return -1; |
+ } |
+ break; |
+#ifdef BFD64 |
+ case x86_DEBUG_STATE64: |
+ switch (regnum) |
+ { |
+ case 0: |
+ return dr_regs.uds.ds64.__dr0; |
+ case 1: |
+ return dr_regs.uds.ds64.__dr1; |
+ case 2: |
+ return dr_regs.uds.ds64.__dr2; |
+ case 3: |
+ return dr_regs.uds.ds64.__dr3; |
+ case 4: |
+ return dr_regs.uds.ds64.__dr4; |
+ case 5: |
+ return dr_regs.uds.ds64.__dr5; |
+ case 6: |
+ return dr_regs.uds.ds64.__dr6; |
+ case 7: |
+ return dr_regs.uds.ds64.__dr7; |
+ default: |
+ return -1; |
+ } |
+ break; |
+#endif |
+ default: |
+ return -1; |
} |
} |
-void |
+static void |
i386_darwin_dr_set_control (unsigned long control) |
{ |
i386_darwin_dr_set (DR_CONTROL, control); |
} |
-void |
+static void |
i386_darwin_dr_set_addr (int regnum, CORE_ADDR addr) |
{ |
gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR); |
@@ -393,29 +440,28 @@ i386_darwin_dr_set_addr (int regnum, CORE_ADDR addr) |
i386_darwin_dr_set (DR_FIRSTADDR + regnum, addr); |
} |
-CORE_ADDR |
+static CORE_ADDR |
i386_darwin_dr_get_addr (int regnum) |
{ |
return i386_darwin_dr_get (regnum); |
} |
-unsigned long |
+static unsigned long |
i386_darwin_dr_get_status (void) |
{ |
return i386_darwin_dr_get (DR_STATUS); |
} |
-unsigned long |
+static unsigned long |
i386_darwin_dr_get_control (void) |
{ |
return i386_darwin_dr_get (DR_CONTROL); |
} |
-#endif |
void |
darwin_check_osabi (darwin_inferior *inf, thread_t thread) |
{ |
- if (gdbarch_osabi (target_gdbarch) == GDB_OSABI_UNKNOWN) |
+ if (gdbarch_osabi (target_gdbarch ()) == GDB_OSABI_UNKNOWN) |
{ |
/* Attaching to a process. Let's figure out what kind it is. */ |
x86_thread_state_t gp_regs; |
@@ -433,13 +479,13 @@ darwin_check_osabi (darwin_inferior *inf, thread_t thread) |
gdbarch_info_init (&info); |
gdbarch_info_fill (&info); |
- info.byte_order = gdbarch_byte_order (target_gdbarch); |
+ info.byte_order = gdbarch_byte_order (target_gdbarch ()); |
info.osabi = GDB_OSABI_DARWIN; |
if (gp_regs.tsh.flavor == x86_THREAD_STATE64) |
info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, |
bfd_mach_x86_64); |
else |
- info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, |
+ info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, |
bfd_mach_i386_i386); |
gdbarch_update_p (info); |
} |
@@ -457,7 +503,7 @@ darwin_check_osabi (darwin_inferior *inf, thread_t thread) |
static int |
i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) |
{ |
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); |
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); |
static const gdb_byte darwin_syscall[] = { 0xcd, 0x80 }; /* int 0x80 */ |
gdb_byte buf[sizeof (darwin_syscall)]; |
@@ -490,7 +536,7 @@ i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) |
static int |
amd64_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) |
{ |
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); |
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); |
static const gdb_byte darwin_syscall[] = { 0x0f, 0x05 }; /* syscall */ |
gdb_byte buf[sizeof (darwin_syscall)]; |
@@ -539,14 +585,14 @@ darwin_set_sstep (thread_t thread, int enable) |
case x86_THREAD_STATE32: |
{ |
__uint32_t bit = enable ? X86_EFLAGS_T : 0; |
- |
+ |
if (enable && i386_darwin_sstep_at_sigreturn (®s)) |
return; |
if ((regs.uts.ts32.__eflags & X86_EFLAGS_T) == bit) |
return; |
regs.uts.ts32.__eflags |
= (regs.uts.ts32.__eflags & ~X86_EFLAGS_T) | bit; |
- kret = thread_set_state (thread, x86_THREAD_STATE, |
+ kret = thread_set_state (thread, x86_THREAD_STATE, |
(thread_state_t) ®s, count); |
MACH_CHECK_ERROR (kret); |
} |
@@ -562,7 +608,7 @@ darwin_set_sstep (thread_t thread, int enable) |
return; |
regs.uts.ts64.__rflags |
= (regs.uts.ts64.__rflags & ~X86_EFLAGS_T) | bit; |
- kret = thread_set_state (thread, x86_THREAD_STATE, |
+ kret = thread_set_state (thread, x86_THREAD_STATE, |
(thread_state_t) ®s, count); |
MACH_CHECK_ERROR (kret); |
} |
@@ -583,6 +629,21 @@ darwin_complete_target (struct target_ops *target) |
amd64_native_gregset32_num_regs = i386_darwin_thread_state_num_regs; |
#endif |
+ i386_use_watchpoints (target); |
+ |
+ i386_dr_low.set_control = i386_darwin_dr_set_control; |
+ i386_dr_low.set_addr = i386_darwin_dr_set_addr; |
+ i386_dr_low.get_addr = i386_darwin_dr_get_addr; |
+ i386_dr_low.get_status = i386_darwin_dr_get_status; |
+ i386_dr_low.get_control = i386_darwin_dr_get_control; |
+ |
+ /* Let's assume that the kernel is 64 bits iff the executable is. */ |
+#ifdef __x86_64__ |
+ i386_set_debug_register_length (8); |
+#else |
+ i386_set_debug_register_length (4); |
+#endif |
+ |
target->to_fetch_registers = i386_darwin_fetch_inferior_registers; |
target->to_store_registers = i386_darwin_store_inferior_registers; |
} |