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