Home | History | Annotate | Line # | Download | only in gdb
      1      1.1  christos /* Low level interface to i386 running the GNU Hurd.
      2      1.1  christos 
      3  1.1.1.5  christos    Copyright (C) 1992-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20  1.1.1.2  christos /* Include this first, to pick up the <mach.h> 'thread_info' diversion.  */
     21  1.1.1.2  christos #include "gnu-nat.h"
     22  1.1.1.2  christos 
     23      1.1  christos /* Mach/Hurd headers are not yet ready for C++ compilation.  */
     24      1.1  christos extern "C"
     25      1.1  christos {
     26      1.1  christos #include <mach.h>
     27      1.1  christos #include <mach_error.h>
     28      1.1  christos #include <mach/message.h>
     29      1.1  christos #include <mach/exception.h>
     30      1.1  christos }
     31      1.1  christos 
     32      1.1  christos #include "x86-nat.h"
     33      1.1  christos #include "inferior.h"
     34      1.1  christos #include "floatformat.h"
     35      1.1  christos #include "regcache.h"
     36      1.1  christos 
     37      1.1  christos #include "i386-tdep.h"
     38      1.1  christos 
     39      1.1  christos #include "inf-child.h"
     40      1.1  christos #include "i387-tdep.h"
     41      1.1  christos 
     42      1.1  christos /* Offset to the thread_state_t location where REG is stored.  */
     43      1.1  christos #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
     44      1.1  christos 
     45      1.1  christos /* At REG_OFFSET[N] is the offset to the thread_state_t location where
     46      1.1  christos    the GDB register N is stored.  */
     47      1.1  christos static int reg_offset[] =
     48      1.1  christos {
     49      1.1  christos   REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
     50      1.1  christos   REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
     51      1.1  christos   REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
     52      1.1  christos   REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
     53      1.1  christos };
     54      1.1  christos 
     55      1.1  christos #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
     56      1.1  christos 
     57      1.1  christos 
     58  1.1.1.2  christos 
     60  1.1.1.2  christos /* The i386 GNU Hurd target.  */
     61  1.1.1.2  christos 
     62  1.1.1.2  christos #ifdef i386_DEBUG_STATE
     63  1.1.1.2  christos using gnu_base_target = x86_nat_target<gnu_nat_target>;
     64  1.1.1.2  christos #else
     65  1.1.1.2  christos using gnu_base_target = gnu_nat_target;
     66  1.1.1.2  christos #endif
     67  1.1.1.2  christos 
     68  1.1.1.2  christos struct i386_gnu_nat_target final : public gnu_base_target
     69  1.1.1.2  christos {
     70  1.1.1.2  christos   void fetch_registers (struct regcache *, int) override;
     71  1.1.1.2  christos   void store_registers (struct regcache *, int) override;
     72  1.1.1.2  christos };
     73  1.1.1.2  christos 
     74  1.1.1.2  christos static i386_gnu_nat_target the_i386_gnu_nat_target;
     75      1.1  christos 
     76      1.1  christos /* Get the whole floating-point state of THREAD and record the values
     77      1.1  christos    of the corresponding (pseudo) registers.  */
     78      1.1  christos 
     79      1.1  christos static void
     80      1.1  christos fetch_fpregs (struct regcache *regcache, struct proc *thread)
     81      1.1  christos {
     82      1.1  christos   mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
     83      1.1  christos   struct i386_float_state state;
     84      1.1  christos   kern_return_t err;
     85      1.1  christos 
     86      1.1  christos   err = thread_get_state (thread->port, i386_FLOAT_STATE,
     87      1.1  christos 			  (thread_state_t) &state, &count);
     88      1.1  christos   if (err)
     89      1.1  christos     {
     90      1.1  christos       warning (_("Couldn't fetch floating-point state from %s"),
     91      1.1  christos 	       proc_string (thread));
     92      1.1  christos       return;
     93      1.1  christos     }
     94      1.1  christos 
     95      1.1  christos   if (!state.initialized)
     96      1.1  christos     {
     97      1.1  christos       /* The floating-point state isn't initialized.  */
     98      1.1  christos       i387_supply_fsave (regcache, -1, NULL);
     99      1.1  christos     }
    100      1.1  christos   else
    101      1.1  christos     {
    102      1.1  christos       /* Supply the floating-point registers.  */
    103      1.1  christos       i387_supply_fsave (regcache, -1, state.hw_state);
    104      1.1  christos     }
    105      1.1  christos }
    106      1.1  christos 
    107  1.1.1.2  christos /* Fetch register REGNO, or all regs if REGNO is -1.  */
    108  1.1.1.2  christos void
    109      1.1  christos i386_gnu_nat_target::fetch_registers (struct regcache *regcache, int regno)
    110      1.1  christos {
    111  1.1.1.2  christos   struct proc *thread;
    112      1.1  christos   ptid_t ptid = regcache->ptid ();
    113      1.1  christos 
    114      1.1  christos   /* Make sure we know about new threads.  */
    115      1.1  christos   inf_update_procs (gnu_current_inf);
    116  1.1.1.2  christos 
    117      1.1  christos   thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ());
    118      1.1  christos   if (!thread)
    119  1.1.1.3  christos     error (_("Can't fetch registers from thread %s: No such thread"),
    120      1.1  christos 	   target_pid_to_str (ptid).c_str ());
    121      1.1  christos 
    122      1.1  christos   if (regno < I386_NUM_GREGS || regno == -1)
    123      1.1  christos     {
    124      1.1  christos       thread_state_t state;
    125      1.1  christos 
    126      1.1  christos       /* This does the dirty work for us.  */
    127      1.1  christos       state = proc_get_state (thread, 0);
    128      1.1  christos       if (!state)
    129      1.1  christos 	{
    130      1.1  christos 	  warning (_("Couldn't fetch registers from %s"),
    131      1.1  christos 		   proc_string (thread));
    132      1.1  christos 	  return;
    133      1.1  christos 	}
    134      1.1  christos 
    135      1.1  christos       if (regno == -1)
    136      1.1  christos 	{
    137      1.1  christos 	  int i;
    138      1.1  christos 
    139      1.1  christos 	  proc_debug (thread, "fetching all register");
    140      1.1  christos 
    141  1.1.1.2  christos 	  for (i = 0; i < I386_NUM_GREGS; i++)
    142      1.1  christos 	    regcache->raw_supply (i, REG_ADDR (state, i));
    143      1.1  christos 	  thread->fetched_regs = ~0;
    144      1.1  christos 	}
    145      1.1  christos       else
    146      1.1  christos 	{
    147  1.1.1.2  christos 	  proc_debug (thread, "fetching register %s",
    148      1.1  christos 		      gdbarch_register_name (regcache->arch (),
    149      1.1  christos 					     regno));
    150  1.1.1.2  christos 
    151      1.1  christos 	  regcache->raw_supply (regno, REG_ADDR (state, regno));
    152      1.1  christos 	  thread->fetched_regs |= (1 << regno);
    153      1.1  christos 	}
    154      1.1  christos     }
    155      1.1  christos 
    156      1.1  christos   if (regno >= I386_NUM_GREGS || regno == -1)
    157      1.1  christos     {
    158      1.1  christos       proc_debug (thread, "fetching floating-point registers");
    159      1.1  christos 
    160      1.1  christos       fetch_fpregs (regcache, thread);
    161      1.1  christos     }
    162      1.1  christos }
    163      1.1  christos 
    164      1.1  christos 
    166      1.1  christos /* Store the whole floating-point state into THREAD using information
    167      1.1  christos    from the corresponding (pseudo) registers.  */
    168      1.1  christos static void
    169      1.1  christos store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
    170      1.1  christos {
    171      1.1  christos   mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
    172      1.1  christos   struct i386_float_state state;
    173      1.1  christos   kern_return_t err;
    174      1.1  christos 
    175      1.1  christos   err = thread_get_state (thread->port, i386_FLOAT_STATE,
    176      1.1  christos 			  (thread_state_t) &state, &count);
    177      1.1  christos   if (err)
    178      1.1  christos     {
    179      1.1  christos       warning (_("Couldn't fetch floating-point state from %s"),
    180      1.1  christos 	       proc_string (thread));
    181      1.1  christos       return;
    182      1.1  christos     }
    183      1.1  christos 
    184      1.1  christos   /* FIXME: kettenis/2001-07-15: Is this right?  Should we somehow
    185      1.1  christos      take into account DEPRECATED_REGISTER_VALID like the old code did?  */
    186      1.1  christos   i387_collect_fsave (regcache, regno, state.hw_state);
    187      1.1  christos 
    188      1.1  christos   err = thread_set_state (thread->port, i386_FLOAT_STATE,
    189      1.1  christos 			  (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
    190      1.1  christos   if (err)
    191      1.1  christos     {
    192      1.1  christos       warning (_("Couldn't store floating-point state into %s"),
    193      1.1  christos 	       proc_string (thread));
    194      1.1  christos       return;
    195      1.1  christos     }
    196      1.1  christos }
    197  1.1.1.2  christos 
    198  1.1.1.2  christos /* Store at least register REGNO, or all regs if REGNO == -1.  */
    199      1.1  christos void
    200      1.1  christos i386_gnu_nat_target::store_registers (struct regcache *regcache, int regno)
    201  1.1.1.2  christos {
    202  1.1.1.2  christos   struct proc *thread;
    203      1.1  christos   struct gdbarch *gdbarch = regcache->arch ();
    204      1.1  christos   ptid_t ptid = regcache->ptid ();
    205      1.1  christos 
    206      1.1  christos   /* Make sure we know about new threads.  */
    207  1.1.1.2  christos   inf_update_procs (gnu_current_inf);
    208      1.1  christos 
    209      1.1  christos   thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ());
    210  1.1.1.3  christos   if (!thread)
    211      1.1  christos     error (_("Couldn't store registers into thread %s: No such thread"),
    212      1.1  christos 	   target_pid_to_str (ptid).c_str ());
    213      1.1  christos 
    214      1.1  christos   if (regno < I386_NUM_GREGS || regno == -1)
    215      1.1  christos     {
    216      1.1  christos       thread_state_t state;
    217      1.1  christos       thread_state_data_t old_state;
    218      1.1  christos       int was_aborted = thread->aborted;
    219      1.1  christos       int was_valid = thread->state_valid;
    220      1.1  christos       int trace;
    221      1.1  christos 
    222      1.1  christos       if (!was_aborted && was_valid)
    223      1.1  christos 	memcpy (&old_state, &thread->state, sizeof (old_state));
    224      1.1  christos 
    225      1.1  christos       state = proc_get_state (thread, 1);
    226      1.1  christos       if (!state)
    227      1.1  christos 	{
    228      1.1  christos 	  warning (_("Couldn't store registers into %s"),
    229      1.1  christos 		   proc_string (thread));
    230      1.1  christos 	  return;
    231      1.1  christos 	}
    232  1.1.1.4  christos 
    233      1.1  christos       /* Save the T bit.  We might try to restore the %eflags register
    234      1.1  christos 	 below, but changing the T bit would seriously confuse GDB.  */
    235      1.1  christos       trace = ((struct i386_thread_state *)state)->efl & 0x100;
    236      1.1  christos 
    237      1.1  christos       if (!was_aborted && was_valid)
    238      1.1  christos 	/* See which registers have changed after aborting the thread.  */
    239      1.1  christos 	{
    240      1.1  christos 	  int check_regno;
    241      1.1  christos 
    242      1.1  christos 	  for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
    243      1.1  christos 	    if ((thread->fetched_regs & (1 << check_regno))
    244      1.1  christos 		&& memcpy (REG_ADDR (&old_state, check_regno),
    245      1.1  christos 			   REG_ADDR (state, check_regno),
    246      1.1  christos 			   register_size (gdbarch, check_regno)))
    247      1.1  christos 	      /* Register CHECK_REGNO has changed!  Ack!  */
    248      1.1  christos 	      {
    249      1.1  christos 		warning (_("Register %s changed after the thread was aborted"),
    250      1.1  christos 			 gdbarch_register_name (gdbarch, check_regno));
    251  1.1.1.2  christos 		if (regno >= 0 && regno != check_regno)
    252  1.1.1.2  christos 		  /* Update GDB's copy of the register.  */
    253      1.1  christos 		  regcache->raw_supply (check_regno,
    254      1.1  christos 					REG_ADDR (state, check_regno));
    255      1.1  christos 		else
    256      1.1  christos 		  warning (_("... also writing this register!  "
    257      1.1  christos 			     "Suspicious..."));
    258      1.1  christos 	      }
    259      1.1  christos 	}
    260      1.1  christos 
    261      1.1  christos       if (regno == -1)
    262      1.1  christos 	{
    263      1.1  christos 	  int i;
    264      1.1  christos 
    265      1.1  christos 	  proc_debug (thread, "storing all registers");
    266  1.1.1.2  christos 
    267  1.1.1.2  christos 	  for (i = 0; i < I386_NUM_GREGS; i++)
    268      1.1  christos 	    if (REG_VALID == regcache->get_register_status (i))
    269      1.1  christos 	      regcache->raw_collect (i, REG_ADDR (state, i));
    270      1.1  christos 	}
    271      1.1  christos       else
    272      1.1  christos 	{
    273      1.1  christos 	  proc_debug (thread, "storing register %s",
    274  1.1.1.2  christos 		      gdbarch_register_name (gdbarch, regno));
    275  1.1.1.2  christos 
    276      1.1  christos 	  gdb_assert (REG_VALID == regcache->get_register_status (regno));
    277      1.1  christos 	  regcache->raw_collect (regno, REG_ADDR (state, regno));
    278      1.1  christos 	}
    279      1.1  christos 
    280      1.1  christos       /* Restore the T bit.  */
    281      1.1  christos       ((struct i386_thread_state *)state)->efl &= ~0x100;
    282      1.1  christos       ((struct i386_thread_state *)state)->efl |= trace;
    283      1.1  christos     }
    284      1.1  christos 
    285      1.1  christos   if (regno >= I386_NUM_GREGS || regno == -1)
    286      1.1  christos     {
    287      1.1  christos       proc_debug (thread, "storing floating-point registers");
    288      1.1  christos 
    289      1.1  christos       store_fpregs (regcache, thread, regno);
    290      1.1  christos     }
    291      1.1  christos }
    292      1.1  christos 
    293      1.1  christos 
    294      1.1  christos /* Support for debug registers.  */
    296      1.1  christos 
    297      1.1  christos #ifdef i386_DEBUG_STATE
    298      1.1  christos /* Get debug registers for thread THREAD.  */
    299      1.1  christos 
    300      1.1  christos static void
    301      1.1  christos i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
    302      1.1  christos {
    303      1.1  christos   mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
    304      1.1  christos   kern_return_t err;
    305      1.1  christos 
    306      1.1  christos   err = thread_get_state (thread->port, i386_DEBUG_STATE,
    307      1.1  christos 			  (thread_state_t) regs, &count);
    308      1.1  christos   if (err != 0 || count != i386_DEBUG_STATE_COUNT)
    309      1.1  christos     warning (_("Couldn't fetch debug state from %s"),
    310      1.1  christos 	     proc_string (thread));
    311      1.1  christos }
    312      1.1  christos 
    313      1.1  christos /* Set debug registers for thread THREAD.  */
    314      1.1  christos 
    315      1.1  christos static void
    316      1.1  christos i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
    317      1.1  christos {
    318      1.1  christos   kern_return_t err;
    319      1.1  christos 
    320      1.1  christos   err = thread_set_state (thread->port, i386_DEBUG_STATE,
    321      1.1  christos 			  (thread_state_t) regs, i386_DEBUG_STATE_COUNT);
    322      1.1  christos   if (err != 0)
    323      1.1  christos     warning (_("Couldn't store debug state into %s"),
    324      1.1  christos 	     proc_string (thread));
    325      1.1  christos }
    326      1.1  christos 
    327      1.1  christos /* Set DR_CONTROL in THREAD.  */
    328      1.1  christos 
    329      1.1  christos static void
    330      1.1  christos i386_gnu_dr_set_control_one (struct proc *thread, void *arg)
    331      1.1  christos {
    332      1.1  christos   unsigned long *control = (unsigned long *) arg;
    333      1.1  christos   struct i386_debug_state regs;
    334      1.1  christos 
    335      1.1  christos   i386_gnu_dr_get (&regs, thread);
    336      1.1  christos   regs.dr[DR_CONTROL] = *control;
    337      1.1  christos   i386_gnu_dr_set (&regs, thread);
    338      1.1  christos }
    339      1.1  christos 
    340      1.1  christos /* Set DR_CONTROL to CONTROL in all threads.  */
    341      1.1  christos 
    342      1.1  christos static void
    343      1.1  christos i386_gnu_dr_set_control (unsigned long control)
    344      1.1  christos {
    345      1.1  christos   inf_update_procs (gnu_current_inf);
    346      1.1  christos   inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control);
    347      1.1  christos }
    348      1.1  christos 
    349      1.1  christos /* Parameters to set a debugging address.  */
    350      1.1  christos 
    351      1.1  christos struct reg_addr
    352      1.1  christos {
    353      1.1  christos   int regnum;		/* Register number (zero based).  */
    354      1.1  christos   CORE_ADDR addr;	/* Address.  */
    355      1.1  christos };
    356      1.1  christos 
    357      1.1  christos /* Set address REGNUM (zero based) to ADDR in THREAD.  */
    358      1.1  christos 
    359      1.1  christos static void
    360      1.1  christos i386_gnu_dr_set_addr_one (struct proc *thread, void *arg)
    361      1.1  christos {
    362      1.1  christos   struct reg_addr *reg_addr = (struct reg_addr *) arg;
    363      1.1  christos   struct i386_debug_state regs;
    364      1.1  christos 
    365      1.1  christos   i386_gnu_dr_get (&regs, thread);
    366      1.1  christos   regs.dr[reg_addr->regnum] = reg_addr->addr;
    367      1.1  christos   i386_gnu_dr_set (&regs, thread);
    368      1.1  christos }
    369      1.1  christos 
    370      1.1  christos /* Set address REGNUM (zero based) to ADDR in all threads.  */
    371      1.1  christos 
    372      1.1  christos static void
    373      1.1  christos i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr)
    374      1.1  christos {
    375      1.1  christos   struct reg_addr reg_addr;
    376      1.1  christos 
    377      1.1  christos   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
    378      1.1  christos 
    379      1.1  christos   reg_addr.regnum = regnum;
    380      1.1  christos   reg_addr.addr = addr;
    381      1.1  christos 
    382      1.1  christos   inf_update_procs (gnu_current_inf);
    383      1.1  christos   inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, &reg_addr);
    384      1.1  christos }
    385      1.1  christos 
    386      1.1  christos /* Get debug register REGNUM value from only the one LWP of PTID.  */
    387      1.1  christos 
    388      1.1  christos static unsigned long
    389      1.1  christos i386_gnu_dr_get_reg (ptid_t ptid, int regnum)
    390      1.1  christos {
    391      1.1  christos   struct i386_debug_state regs;
    392      1.1  christos   struct proc *thread;
    393      1.1  christos 
    394  1.1.1.2  christos   /* Make sure we know about new threads.  */
    395      1.1  christos   inf_update_procs (gnu_current_inf);
    396      1.1  christos 
    397      1.1  christos   thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ());
    398      1.1  christos   i386_gnu_dr_get (&regs, thread);
    399      1.1  christos 
    400      1.1  christos   return regs.dr[regnum];
    401      1.1  christos }
    402      1.1  christos 
    403      1.1  christos /* Return the inferior's debug register REGNUM.  */
    404      1.1  christos 
    405      1.1  christos static CORE_ADDR
    406      1.1  christos i386_gnu_dr_get_addr (int regnum)
    407      1.1  christos {
    408      1.1  christos   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
    409      1.1  christos 
    410      1.1  christos   return i386_gnu_dr_get_reg (inferior_ptid, regnum);
    411      1.1  christos }
    412      1.1  christos 
    413      1.1  christos /* Get DR_STATUS from only the one thread of INFERIOR_PTID.  */
    414      1.1  christos 
    415      1.1  christos static unsigned long
    416      1.1  christos i386_gnu_dr_get_status (void)
    417      1.1  christos {
    418      1.1  christos   return i386_gnu_dr_get_reg (inferior_ptid, DR_STATUS);
    419      1.1  christos }
    420      1.1  christos 
    421      1.1  christos /* Return the inferior's DR7 debug control register.  */
    422      1.1  christos 
    423      1.1  christos static unsigned long
    424      1.1  christos i386_gnu_dr_get_control (void)
    425      1.1  christos {
    426      1.1  christos   return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL);
    427  1.1.1.3  christos }
    428      1.1  christos #endif /* i386_DEBUG_STATE */
    429  1.1.1.3  christos 
    430      1.1  christos void _initialize_i386gnu_nat ();
    431      1.1  christos void
    432      1.1  christos _initialize_i386gnu_nat ()
    433      1.1  christos {
    434      1.1  christos #ifdef i386_DEBUG_STATE
    435      1.1  christos   x86_dr_low.set_control = i386_gnu_dr_set_control;
    436      1.1  christos   gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT);
    437      1.1  christos   x86_dr_low.set_addr = i386_gnu_dr_set_addr;
    438      1.1  christos   x86_dr_low.get_addr = i386_gnu_dr_get_addr;
    439      1.1  christos   x86_dr_low.get_status = i386_gnu_dr_get_status;
    440      1.1  christos   x86_dr_low.get_control = i386_gnu_dr_get_control;
    441  1.1.1.3  christos   x86_set_debug_register_length (4);
    442  1.1.1.3  christos #endif /* i386_DEBUG_STATE */
    443      1.1  christos 
    444  1.1.1.2  christos   gnu_target = &the_i386_gnu_nat_target;
    445      1.1  christos 
    446                      /* Register the target.  */
    447                      add_inf_child_target (&the_i386_gnu_nat_target);
    448                    }
    449