gdb/gdbserver/win32-i386-low.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Copyright (C) 2007-2015 Free Software Foundation, Inc.

  2.    This file is part of GDB.

  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 3 of the License, or
  6.    (at your option) any later version.

  7.    This program is distributed in the hope that it will be useful,
  8.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.    GNU General Public License for more details.

  11.    You should have received a copy of the GNU General Public License
  12.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  13. #include "server.h"
  14. #include "win32-low.h"
  15. #include "x86-low.h"

  16. #ifndef CONTEXT_EXTENDED_REGISTERS
  17. #define CONTEXT_EXTENDED_REGISTERS 0
  18. #endif

  19. #define FCS_REGNUM 27
  20. #define FOP_REGNUM 31

  21. #define FLAG_TRACE_BIT 0x100

  22. #ifdef __x86_64__
  23. /* Defined in auto-generated file reg-amd64.c.  */
  24. void init_registers_amd64 (void);
  25. extern const struct target_desc *tdesc_amd64;
  26. #else
  27. /* Defined in auto-generated file reg-i386.c.  */
  28. void init_registers_i386 (void);
  29. extern const struct target_desc *tdesc_i386;
  30. #endif

  31. static struct x86_debug_reg_state debug_reg_state;

  32. static int
  33. update_debug_registers_callback (struct inferior_list_entry *entry,
  34.                                  void *pid_p)
  35. {
  36.   struct thread_info *thr = (struct thread_info *) entry;
  37.   win32_thread_info *th = inferior_target_data (thr);
  38.   int pid = *(int *) pid_p;

  39.   /* Only update the threads of this process.  */
  40.   if (pid_of (thr) == pid)
  41.     {
  42.       /* The actual update is done later just before resuming the lwp,
  43.          we just mark that the registers need updating.  */
  44.       th->debug_registers_changed = 1;
  45.     }

  46.   return 0;
  47. }

  48. /* Update the inferior's debug register REGNUM from STATE.  */

  49. static void
  50. x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
  51. {
  52.   /* Only update the threads of this process.  */
  53.   int pid = pid_of (current_thread);

  54.   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

  55.   find_inferior (&all_threads, update_debug_registers_callback, &pid);
  56. }

  57. /* Update the inferior's DR7 debug control register from STATE.  */

  58. static void
  59. x86_dr_low_set_control (unsigned long control)
  60. {
  61.   /* Only update the threads of this process.  */
  62.   int pid = pid_of (current_thread);

  63.   find_inferior (&all_threads, update_debug_registers_callback, &pid);
  64. }

  65. /* Return the current value of a DR register of the current thread's
  66.    context.  */

  67. static DWORD64
  68. win32_get_current_dr (int dr)
  69. {
  70.   win32_thread_info *th = inferior_target_data (current_thread);

  71.   win32_require_context (th);

  72. #define RET_DR(DR)                                \
  73.   case DR:                                        \
  74.     return th->context.Dr ## DR

  75.   switch (dr)
  76.     {
  77.       RET_DR (0);
  78.       RET_DR (1);
  79.       RET_DR (2);
  80.       RET_DR (3);
  81.       RET_DR (6);
  82.       RET_DR (7);
  83.     }

  84. #undef RET_DR

  85.   gdb_assert_not_reached ("unhandled dr");
  86. }

  87. static CORE_ADDR
  88. x86_dr_low_get_addr (int regnum)
  89. {
  90.   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

  91.   return win32_get_current_dr (regnum - DR_FIRSTADDR);
  92. }

  93. static unsigned long
  94. x86_dr_low_get_control (void)
  95. {
  96.   return win32_get_current_dr (7);
  97. }

  98. /* Get the value of the DR6 debug status register from the inferior
  99.    and record it in STATE.  */

  100. static unsigned long
  101. x86_dr_low_get_status (void)
  102. {
  103.   return win32_get_current_dr (6);
  104. }

  105. /* Low-level function vector.  */
  106. struct x86_dr_low_type x86_dr_low =
  107.   {
  108.     x86_dr_low_set_control,
  109.     x86_dr_low_set_addr,
  110.     x86_dr_low_get_addr,
  111.     x86_dr_low_get_status,
  112.     x86_dr_low_get_control,
  113.     sizeof (void *),
  114.   };

  115. /* Breakpoint/watchpoint support.  */

  116. static int
  117. i386_supports_z_point_type (char z_type)
  118. {
  119.   switch (z_type)
  120.     {
  121.     case Z_PACKET_WRITE_WP:
  122.     case Z_PACKET_ACCESS_WP:
  123.       return 1;
  124.     default:
  125.       return 0;
  126.     }
  127. }

  128. static int
  129. i386_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
  130.                    int size, struct raw_breakpoint *bp)
  131. {
  132.   switch (type)
  133.     {
  134.     case raw_bkpt_type_write_wp:
  135.     case raw_bkpt_type_access_wp:
  136.       {
  137.         enum target_hw_bp_type hw_type
  138.           = raw_bkpt_type_to_target_hw_bp_type (type);

  139.         return x86_dr_insert_watchpoint (&debug_reg_state,
  140.                                          hw_type, addr, size);
  141.       }
  142.     default:
  143.       /* Unsupported.  */
  144.       return 1;
  145.     }
  146. }

  147. static int
  148. i386_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
  149.                    int size, struct raw_breakpoint *bp)
  150. {
  151.   switch (type)
  152.     {
  153.     case raw_bkpt_type_write_wp:
  154.     case raw_bkpt_type_access_wp:
  155.       {
  156.         enum target_hw_bp_type hw_type
  157.           = raw_bkpt_type_to_target_hw_bp_type (type);

  158.         return x86_dr_remove_watchpoint (&debug_reg_state,
  159.                                          hw_type, addr, size);
  160.       }
  161.     default:
  162.       /* Unsupported.  */
  163.       return 1;
  164.     }
  165. }

  166. static int
  167. x86_stopped_by_watchpoint (void)
  168. {
  169.   return x86_dr_stopped_by_watchpoint (&debug_reg_state);
  170. }

  171. static CORE_ADDR
  172. x86_stopped_data_address (void)
  173. {
  174.   CORE_ADDR addr;
  175.   if (x86_dr_stopped_data_address (&debug_reg_state, &addr))
  176.     return addr;
  177.   return 0;
  178. }

  179. static void
  180. i386_initial_stuff (void)
  181. {
  182.   x86_low_init_dregs (&debug_reg_state);
  183. }

  184. static void
  185. i386_get_thread_context (win32_thread_info *th)
  186. {
  187.   /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
  188.      the system doesn't support extended registers.  */
  189.   static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;

  190. again:
  191.   th->context.ContextFlags = (CONTEXT_FULL
  192.                               | CONTEXT_FLOATING_POINT
  193.                               | CONTEXT_DEBUG_REGISTERS
  194.                               | extended_registers);

  195.   if (!GetThreadContext (th->h, &th->context))
  196.     {
  197.       DWORD e = GetLastError ();

  198.       if (extended_registers && e == ERROR_INVALID_PARAMETER)
  199.         {
  200.           extended_registers = 0;
  201.           goto again;
  202.         }

  203.       error ("GetThreadContext failure %ld\n", (long) e);
  204.     }
  205. }

  206. static void
  207. i386_prepare_to_resume (win32_thread_info *th)
  208. {
  209.   if (th->debug_registers_changed)
  210.     {
  211.       struct x86_debug_reg_state *dr = &debug_reg_state;

  212.       win32_require_context (th);

  213.       th->context.Dr0 = dr->dr_mirror[0];
  214.       th->context.Dr1 = dr->dr_mirror[1];
  215.       th->context.Dr2 = dr->dr_mirror[2];
  216.       th->context.Dr3 = dr->dr_mirror[3];
  217.       /* th->context.Dr6 = dr->dr_status_mirror;
  218.          FIXME: should we set dr6 also ?? */
  219.       th->context.Dr7 = dr->dr_control_mirror;

  220.       th->debug_registers_changed = 0;
  221.     }
  222. }

  223. static void
  224. i386_thread_added (win32_thread_info *th)
  225. {
  226.   th->debug_registers_changed = 1;
  227. }

  228. static void
  229. i386_single_step (win32_thread_info *th)
  230. {
  231.   th->context.EFlags |= FLAG_TRACE_BIT;
  232. }

  233. #ifndef __x86_64__

  234. /* An array of offset mappings into a Win32 Context structure.
  235.    This is a one-to-one mapping which is indexed by gdb's register
  236.    numbers.  It retrieves an offset into the context structure where
  237.    the 4 byte register is located.
  238.    An offset value of -1 indicates that Win32 does not provide this
  239.    register in it's CONTEXT structure.  In this case regptr will return
  240.    a pointer into a dummy register.  */
  241. #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
  242. static const int mappings[] = {
  243.   context_offset (Eax),
  244.   context_offset (Ecx),
  245.   context_offset (Edx),
  246.   context_offset (Ebx),
  247.   context_offset (Esp),
  248.   context_offset (Ebp),
  249.   context_offset (Esi),
  250.   context_offset (Edi),
  251.   context_offset (Eip),
  252.   context_offset (EFlags),
  253.   context_offset (SegCs),
  254.   context_offset (SegSs),
  255.   context_offset (SegDs),
  256.   context_offset (SegEs),
  257.   context_offset (SegFs),
  258.   context_offset (SegGs),
  259.   context_offset (FloatSave.RegisterArea[0 * 10]),
  260.   context_offset (FloatSave.RegisterArea[1 * 10]),
  261.   context_offset (FloatSave.RegisterArea[2 * 10]),
  262.   context_offset (FloatSave.RegisterArea[3 * 10]),
  263.   context_offset (FloatSave.RegisterArea[4 * 10]),
  264.   context_offset (FloatSave.RegisterArea[5 * 10]),
  265.   context_offset (FloatSave.RegisterArea[6 * 10]),
  266.   context_offset (FloatSave.RegisterArea[7 * 10]),
  267.   context_offset (FloatSave.ControlWord),
  268.   context_offset (FloatSave.StatusWord),
  269.   context_offset (FloatSave.TagWord),
  270.   context_offset (FloatSave.ErrorSelector),
  271.   context_offset (FloatSave.ErrorOffset),
  272.   context_offset (FloatSave.DataSelector),
  273.   context_offset (FloatSave.DataOffset),
  274.   context_offset (FloatSave.ErrorSelector),
  275.   /* XMM0-7 */
  276.   context_offset (ExtendedRegisters[10 * 16]),
  277.   context_offset (ExtendedRegisters[11 * 16]),
  278.   context_offset (ExtendedRegisters[12 * 16]),
  279.   context_offset (ExtendedRegisters[13 * 16]),
  280.   context_offset (ExtendedRegisters[14 * 16]),
  281.   context_offset (ExtendedRegisters[15 * 16]),
  282.   context_offset (ExtendedRegisters[16 * 16]),
  283.   context_offset (ExtendedRegisters[17 * 16]),
  284.   /* MXCSR */
  285.   context_offset (ExtendedRegisters[24])
  286. };
  287. #undef context_offset

  288. #else /* __x86_64__ */

  289. #define context_offset(x) (offsetof (CONTEXT, x))
  290. static const int mappings[] =
  291. {
  292.   context_offset (Rax),
  293.   context_offset (Rbx),
  294.   context_offset (Rcx),
  295.   context_offset (Rdx),
  296.   context_offset (Rsi),
  297.   context_offset (Rdi),
  298.   context_offset (Rbp),
  299.   context_offset (Rsp),
  300.   context_offset (R8),
  301.   context_offset (R9),
  302.   context_offset (R10),
  303.   context_offset (R11),
  304.   context_offset (R12),
  305.   context_offset (R13),
  306.   context_offset (R14),
  307.   context_offset (R15),
  308.   context_offset (Rip),
  309.   context_offset (EFlags),
  310.   context_offset (SegCs),
  311.   context_offset (SegSs),
  312.   context_offset (SegDs),
  313.   context_offset (SegEs),
  314.   context_offset (SegFs),
  315.   context_offset (SegGs),
  316.   context_offset (FloatSave.FloatRegisters[0]),
  317.   context_offset (FloatSave.FloatRegisters[1]),
  318.   context_offset (FloatSave.FloatRegisters[2]),
  319.   context_offset (FloatSave.FloatRegisters[3]),
  320.   context_offset (FloatSave.FloatRegisters[4]),
  321.   context_offset (FloatSave.FloatRegisters[5]),
  322.   context_offset (FloatSave.FloatRegisters[6]),
  323.   context_offset (FloatSave.FloatRegisters[7]),
  324.   context_offset (FloatSave.ControlWord),
  325.   context_offset (FloatSave.StatusWord),
  326.   context_offset (FloatSave.TagWord),
  327.   context_offset (FloatSave.ErrorSelector),
  328.   context_offset (FloatSave.ErrorOffset),
  329.   context_offset (FloatSave.DataSelector),
  330.   context_offset (FloatSave.DataOffset),
  331.   context_offset (FloatSave.ErrorSelector)
  332.   /* XMM0-7 */ ,
  333.   context_offset (Xmm0),
  334.   context_offset (Xmm1),
  335.   context_offset (Xmm2),
  336.   context_offset (Xmm3),
  337.   context_offset (Xmm4),
  338.   context_offset (Xmm5),
  339.   context_offset (Xmm6),
  340.   context_offset (Xmm7),
  341.   context_offset (Xmm8),
  342.   context_offset (Xmm9),
  343.   context_offset (Xmm10),
  344.   context_offset (Xmm11),
  345.   context_offset (Xmm12),
  346.   context_offset (Xmm13),
  347.   context_offset (Xmm14),
  348.   context_offset (Xmm15),
  349.   /* MXCSR */
  350.   context_offset (FloatSave.MxCsr)
  351. };
  352. #undef context_offset

  353. #endif /* __x86_64__ */

  354. /* Fetch register from gdbserver regcache data.  */
  355. static void
  356. i386_fetch_inferior_register (struct regcache *regcache,
  357.                               win32_thread_info *th, int r)
  358. {
  359.   char *context_offset = (char *) &th->context + mappings[r];

  360.   long l;
  361.   if (r == FCS_REGNUM)
  362.     {
  363.       l = *((long *) context_offset) & 0xffff;
  364.       supply_register (regcache, r, (char *) &l);
  365.     }
  366.   else if (r == FOP_REGNUM)
  367.     {
  368.       l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
  369.       supply_register (regcache, r, (char *) &l);
  370.     }
  371.   else
  372.     supply_register (regcache, r, context_offset);
  373. }

  374. /* Store a new register value into the thread context of TH.  */
  375. static void
  376. i386_store_inferior_register (struct regcache *regcache,
  377.                               win32_thread_info *th, int r)
  378. {
  379.   char *context_offset = (char *) &th->context + mappings[r];
  380.   collect_register (regcache, r, context_offset);
  381. }

  382. static const unsigned char i386_win32_breakpoint = 0xcc;
  383. #define i386_win32_breakpoint_len 1

  384. static void
  385. i386_arch_setup (void)
  386. {
  387. #ifdef __x86_64__
  388.   init_registers_amd64 ();
  389.   win32_tdesc = tdesc_amd64;
  390. #else
  391.   init_registers_i386 ();
  392.   win32_tdesc = tdesc_i386;
  393. #endif
  394. }

  395. struct win32_target_ops the_low_target = {
  396.   i386_arch_setup,
  397.   sizeof (mappings) / sizeof (mappings[0]),
  398.   i386_initial_stuff,
  399.   i386_get_thread_context,
  400.   i386_prepare_to_resume,
  401.   i386_thread_added,
  402.   i386_fetch_inferior_register,
  403.   i386_store_inferior_register,
  404.   i386_single_step,
  405.   &i386_win32_breakpoint,
  406.   i386_win32_breakpoint_len,
  407.   i386_supports_z_point_type,
  408.   i386_insert_point,
  409.   i386_remove_point,
  410.   x86_stopped_by_watchpoint,
  411.   x86_stopped_data_address
  412. };