Home | History | Annotate | Line # | Download | only in gdb
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) &regs, &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 (&regs))
    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) &regs, 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 (&regs))
    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) &regs, 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