gdb/nat/mips-linux-watch.c - gdb

Functions defined

Source code

  1. /* Copyright (C) 2009-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 "common-defs.h"
  14. #include <sys/ptrace.h>
  15. #include "mips-linux-watch.h"

  16. /* Assuming usable watch registers REGS, return the irw_mask of
  17.    register N.  */

  18. uint32_t
  19. mips_linux_watch_get_irw_mask (struct pt_watch_regs *regs, int n)
  20. {
  21.   switch (regs->style)
  22.     {
  23.     case pt_watch_style_mips32:
  24.       return regs->mips32.watch_masks[n] & IRW_MASK;
  25.     case pt_watch_style_mips64:
  26.       return regs->mips64.watch_masks[n] & IRW_MASK;
  27.     default:
  28.       internal_error (__FILE__, __LINE__,
  29.                       _("Unrecognized watch register style"));
  30.     }
  31. }

  32. /* Assuming usable watch registers REGS, return the reg_mask of
  33.    register N.  */

  34. static uint32_t
  35. get_reg_mask (struct pt_watch_regs *regs, int n)
  36. {
  37.   switch (regs->style)
  38.     {
  39.     case pt_watch_style_mips32:
  40.       return regs->mips32.watch_masks[n] & ~IRW_MASK;
  41.     case pt_watch_style_mips64:
  42.       return regs->mips64.watch_masks[n] & ~IRW_MASK;
  43.     default:
  44.       internal_error (__FILE__, __LINE__,
  45.                       _("Unrecognized watch register style"));
  46.     }
  47. }

  48. /* Assuming usable watch registers REGS, return the num_valid.  */

  49. uint32_t
  50. mips_linux_watch_get_num_valid (struct pt_watch_regs *regs)
  51. {
  52.   switch (regs->style)
  53.     {
  54.     case pt_watch_style_mips32:
  55.       return regs->mips32.num_valid;
  56.     case pt_watch_style_mips64:
  57.       return regs->mips64.num_valid;
  58.     default:
  59.       internal_error (__FILE__, __LINE__,
  60.                       _("Unrecognized watch register style"));
  61.     }
  62. }

  63. /* Assuming usable watch registers REGS, return the watchlo of
  64.    register N.  */

  65. CORE_ADDR
  66. mips_linux_watch_get_watchlo (struct pt_watch_regs *regs, int n)
  67. {
  68.   switch (regs->style)
  69.     {
  70.     case pt_watch_style_mips32:
  71.       return regs->mips32.watchlo[n];
  72.     case pt_watch_style_mips64:
  73.       return regs->mips64.watchlo[n];
  74.     default:
  75.       internal_error (__FILE__, __LINE__,
  76.                       _("Unrecognized watch register style"));
  77.     }
  78. }

  79. /* Assuming usable watch registers REGS, set watchlo of register N to
  80.    VALUE.  */

  81. void
  82. mips_linux_watch_set_watchlo (struct pt_watch_regs *regs, int n,
  83.                               CORE_ADDR value)
  84. {
  85.   switch (regs->style)
  86.     {
  87.     case pt_watch_style_mips32:
  88.       /*  The cast will never throw away bits as 64 bit addresses can
  89.           never be used on a 32 bit kernel.  */
  90.       regs->mips32.watchlo[n] = (uint32_t) value;
  91.       break;
  92.     case pt_watch_style_mips64:
  93.       regs->mips64.watchlo[n] = value;
  94.       break;
  95.     default:
  96.       internal_error (__FILE__, __LINE__,
  97.                       _("Unrecognized watch register style"));
  98.     }
  99. }

  100. /* Assuming usable watch registers REGS, return the watchhi of
  101.    register N.  */

  102. uint32_t
  103. mips_linux_watch_get_watchhi (struct pt_watch_regs *regs, int n)
  104. {
  105.   switch (regs->style)
  106.     {
  107.     case pt_watch_style_mips32:
  108.       return regs->mips32.watchhi[n];
  109.     case pt_watch_style_mips64:
  110.       return regs->mips64.watchhi[n];
  111.     default:
  112.       internal_error (__FILE__, __LINE__,
  113.                       _("Unrecognized watch register style"));
  114.     }
  115. }

  116. /* Assuming usable watch registers REGS, set watchhi of register N to
  117.    VALUE.  */

  118. void
  119. mips_linux_watch_set_watchhi (struct pt_watch_regs *regs, int n,
  120.                               uint16_t value)
  121. {
  122.   switch (regs->style)
  123.     {
  124.     case pt_watch_style_mips32:
  125.       regs->mips32.watchhi[n] = value;
  126.       break;
  127.     case pt_watch_style_mips64:
  128.       regs->mips64.watchhi[n] = value;
  129.       break;
  130.     default:
  131.       internal_error (__FILE__, __LINE__,
  132.                       _("Unrecognized watch register style"));
  133.     }
  134. }

  135. /* Read the watch registers of process LWPID and store it in
  136.    WATCH_READBACK.  Save true to *WATCH_READBACK_VALID if watch
  137.    registers are valid.  Return 1 if watch registers are usable.
  138.    Cached information is used unless FORCE is true.  */

  139. int
  140. mips_linux_read_watch_registers (long lwpid,
  141.                                  struct pt_watch_regs *watch_readback,
  142.                                  int *watch_readback_valid, int force)
  143. {
  144.   if (force || *watch_readback_valid == 0)
  145.     {
  146.       if (ptrace (PTRACE_GET_WATCH_REGS, lwpid, watch_readback) == -1)
  147.         {
  148.           *watch_readback_valid = -1;
  149.           return 0;
  150.         }
  151.       switch (watch_readback->style)
  152.         {
  153.         case pt_watch_style_mips32:
  154.           if (watch_readback->mips32.num_valid == 0)
  155.             {
  156.               *watch_readback_valid = -1;
  157.               return 0;
  158.             }
  159.           break;
  160.         case pt_watch_style_mips64:
  161.           if (watch_readback->mips64.num_valid == 0)
  162.             {
  163.               *watch_readback_valid = -1;
  164.               return 0;
  165.             }
  166.           break;
  167.         default:
  168.           *watch_readback_valid = -1;
  169.           return 0;
  170.         }
  171.       /* Watch registers appear to be usable.  */
  172.       *watch_readback_valid = 1;
  173.     }
  174.   return (*watch_readback_valid == 1) ? 1 : 0;
  175. }

  176. /* Convert GDB's TYPE to an IRW mask.  */

  177. uint32_t
  178. mips_linux_watch_type_to_irw (int type)
  179. {
  180.   switch (type)
  181.     {
  182.     case hw_write:
  183.       return W_MASK;
  184.     case hw_read:
  185.       return R_MASK;
  186.     case hw_access:
  187.       return (W_MASK | R_MASK);
  188.     default:
  189.       return 0;
  190.     }
  191. }

  192. /* Set any low order bits in MASK that are not set.  */

  193. static CORE_ADDR
  194. fill_mask (CORE_ADDR mask)
  195. {
  196.   CORE_ADDR f = 1;

  197.   while (f && f < mask)
  198.     {
  199.       mask |= f;
  200.       f <<= 1;
  201.     }
  202.   return mask;
  203. }

  204. /* Try to add a single watch to the specified registers REGS.  The
  205.    address of added watch is ADDR, the length is LEN, and the mask
  206.    is IRW.  Return 1 on success, 0 on failure.  */

  207. int
  208. mips_linux_watch_try_one_watch (struct pt_watch_regs *regs,
  209.                                 CORE_ADDR addr, int len, uint32_t irw)
  210. {
  211.   CORE_ADDR base_addr, last_byte, break_addr, segment_len;
  212.   CORE_ADDR mask_bits, t_low;
  213.   uint16_t t_hi;
  214.   int i, free_watches;
  215.   struct pt_watch_regs regs_copy;

  216.   if (len <= 0)
  217.     return 0;

  218.   last_byte = addr + len - 1;
  219.   mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK;
  220.   base_addr = addr & ~mask_bits;

  221.   /* Check to see if it is covered by current registers.  */
  222.   for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
  223.     {
  224.       t_low = mips_linux_watch_get_watchlo (regs, i);
  225.       if (t_low != 0 && irw == ((uint32_t) t_low & irw))
  226.         {
  227.           t_hi = mips_linux_watch_get_watchhi (regs, i) | IRW_MASK;
  228.           t_low &= ~(CORE_ADDR) t_hi;
  229.           if (addr >= t_low && last_byte <= (t_low + t_hi))
  230.             return 1;
  231.         }
  232.     }
  233.   /* Try to find an empty register.  */
  234.   free_watches = 0;
  235.   for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
  236.     {
  237.       t_low = mips_linux_watch_get_watchlo (regs, i);
  238.       if (t_low == 0
  239.           && irw == (mips_linux_watch_get_irw_mask (regs, i) & irw))
  240.         {
  241.           if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK))
  242.             {
  243.               /* It fits, we'll take it.  */
  244.               mips_linux_watch_set_watchlo (regs, i, base_addr | irw);
  245.               mips_linux_watch_set_watchhi (regs, i, mask_bits & ~IRW_MASK);
  246.               return 1;
  247.             }
  248.           else
  249.             {
  250.               /* It doesn't fit, but has the proper IRW capabilities.  */
  251.               free_watches++;
  252.             }
  253.         }
  254.     }
  255.   if (free_watches > 1)
  256.     {
  257.       /* Try to split it across several registers.  */
  258.       regs_copy = *regs;
  259.       for (i = 0; i < mips_linux_watch_get_num_valid (&regs_copy); i++)
  260.         {
  261.           t_low = mips_linux_watch_get_watchlo (&regs_copy, i);
  262.           t_hi = get_reg_mask (&regs_copy, i) | IRW_MASK;
  263.           if (t_low == 0 && irw == (t_hi & irw))
  264.             {
  265.               t_low = addr & ~(CORE_ADDR) t_hi;
  266.               break_addr = t_low + t_hi + 1;
  267.               if (break_addr >= addr + len)
  268.                 segment_len = len;
  269.               else
  270.                 segment_len = break_addr - addr;
  271.               mask_bits = fill_mask (addr ^ (addr + segment_len - 1));
  272.               mips_linux_watch_set_watchlo (&regs_copy, i,
  273.                                             (addr & ~mask_bits) | irw);
  274.               mips_linux_watch_set_watchhi (&regs_copy, i,
  275.                                             mask_bits & ~IRW_MASK);
  276.               if (break_addr >= addr + len)
  277.                 {
  278.                   *regs = regs_copy;
  279.                   return 1;
  280.                 }
  281.               len = addr + len - break_addr;
  282.               addr = break_addr;
  283.             }
  284.         }
  285.     }
  286.   /* It didn't fit anywhere, we failed.  */
  287.   return 0;
  288. }

  289. /* Fill in the watch registers REGS with the currently cached
  290.    watches CURRENT_WATCHES.  */

  291. void
  292. mips_linux_watch_populate_regs (struct mips_watchpoint *current_watches,
  293.                                 struct pt_watch_regs *regs)
  294. {
  295.   struct mips_watchpoint *w;
  296.   int i;

  297.   /* Clear them out.  */
  298.   for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
  299.     {
  300.       mips_linux_watch_set_watchlo (regs, i, 0);
  301.       mips_linux_watch_set_watchhi (regs, i, 0);
  302.     }

  303.   w = current_watches;
  304.   while (w)
  305.     {
  306.       uint32_t irw = mips_linux_watch_type_to_irw (w->type);

  307.       i = mips_linux_watch_try_one_watch (regs, w->addr, w->len, irw);
  308.       /* They must all fit, because we previously calculated that they
  309.          would.  */
  310.       gdb_assert (i);
  311.       w = w->next;
  312.     }
  313. }