| 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;
|
| }
|
|
|