gdb/user-regs.c - gdb

Global variables defined

Data types defined

Functions defined

Source code

  1. /* User visible, per-frame registers, for GDB, the GNU debugger.

  2.    Copyright (C) 2002-2015 Free Software Foundation, Inc.

  3.    Contributed by Red Hat.

  4.    This file is part of GDB.

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

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

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

  15. #include "defs.h"
  16. #include "user-regs.h"
  17. #include "gdbtypes.h"
  18. #include "frame.h"
  19. #include "arch-utils.h"
  20. #include "command.h"
  21. #include "cli/cli-cmds.h"

  22. /* A table of user registers.

  23.    User registers have regnum's that live above of the range [0
  24.    .. gdbarch_num_regs + gdbarch_num_pseudo_regs)
  25.    (which is controlled by the target).
  26.    The target should never see a user register's regnum value.

  27.    Always append, never delete.  By doing this, the relative regnum
  28.    (offset from gdbarch_num_regs + gdbarch_num_pseudo_regs)
  29.     assigned to each user  register never changes.  */

  30. struct user_reg
  31. {
  32.   const char *name;
  33.   struct value *(*read) (struct frame_info * frame, const void *baton);
  34.   const void *baton;
  35.   struct user_reg *next;
  36. };

  37. /* This structure is named gdb_user_regs instead of user_regs to avoid
  38.    conflicts with any "struct user_regs" in system headers.  For instance,
  39.    on ARM GNU/Linux native builds, nm-linux.h includes <signal.h> includes
  40.    <sys/ucontext.h> includes <sys/procfs.h> includes <sys/user.h>, which
  41.    declares "struct user_regs".  */

  42. struct gdb_user_regs
  43. {
  44.   struct user_reg *first;
  45.   struct user_reg **last;
  46. };

  47. static void
  48. append_user_reg (struct gdb_user_regs *regs, const char *name,
  49.                  user_reg_read_ftype *read, const void *baton,
  50.                  struct user_reg *reg)
  51. {
  52.   /* The caller is responsible for allocating memory needed to store
  53.      the register.  By doing this, the function can operate on a
  54.      register list stored in the common heap or a specific obstack.  */
  55.   gdb_assert (reg != NULL);
  56.   reg->name = name;
  57.   reg->read = read;
  58.   reg->baton = baton;
  59.   reg->next = NULL;
  60.   (*regs->last) = reg;
  61.   regs->last = &(*regs->last)->next;
  62. }

  63. /* An array of the builtin user registers.  */

  64. static struct gdb_user_regs builtin_user_regs = {
  65.   NULL, &builtin_user_regs.first
  66. };

  67. void
  68. user_reg_add_builtin (const char *name, user_reg_read_ftype *read,
  69.                       const void *baton)
  70. {
  71.   append_user_reg (&builtin_user_regs, name, read, baton,
  72.                    XNEW (struct user_reg));
  73. }

  74. /* Per-architecture user registers.  Start with the builtin user
  75.    registers and then, again, append.  */

  76. static struct gdbarch_data *user_regs_data;

  77. static void *
  78. user_regs_init (struct gdbarch *gdbarch)
  79. {
  80.   struct user_reg *reg;
  81.   struct gdb_user_regs *regs
  82.     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdb_user_regs);

  83.   regs->last = &regs->first;
  84.   for (reg = builtin_user_regs.first; reg != NULL; reg = reg->next)
  85.     append_user_reg (regs, reg->name, reg->read, reg->baton,
  86.                      GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
  87.   return regs;
  88. }

  89. void
  90. user_reg_add (struct gdbarch *gdbarch, const char *name,
  91.               user_reg_read_ftype *read, const void *baton)
  92. {
  93.   struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);

  94.   if (regs == NULL)
  95.     {
  96.       /* ULGH, called during architecture initialization.  Patch
  97.          things up.  */
  98.       regs = user_regs_init (gdbarch);
  99.       deprecated_set_gdbarch_data (gdbarch, user_regs_data, regs);
  100.     }
  101.   append_user_reg (regs, name, read, baton,
  102.                    GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
  103. }

  104. int
  105. user_reg_map_name_to_regnum (struct gdbarch *gdbarch, const char *name,
  106.                              int len)
  107. {
  108.   /* Make life easy, set the len to something reasonable.  */
  109.   if (len < 0)
  110.     len = strlen (name);

  111.   /* Search register name space first - always let an architecture
  112.      specific register override the user registers.  */
  113.   {
  114.     int i;
  115.     int maxregs = (gdbarch_num_regs (gdbarch)
  116.                    + gdbarch_num_pseudo_regs (gdbarch));

  117.     for (i = 0; i < maxregs; i++)
  118.       {
  119.         const char *regname = gdbarch_register_name (gdbarch, i);

  120.         if (regname != NULL && len == strlen (regname)
  121.             && strncmp (regname, name, len) == 0)
  122.           {
  123.             return i;
  124.           }
  125.       }
  126.   }

  127.   /* Search the user name space.  */
  128.   {
  129.     struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
  130.     struct user_reg *reg;
  131.     int nr;

  132.     for (nr = 0, reg = regs->first; reg != NULL; reg = reg->next, nr++)
  133.       {
  134.         if ((len < 0 && strcmp (reg->name, name))
  135.             || (len == strlen (reg->name)
  136.                 && strncmp (reg->name, name, len) == 0))
  137.           return gdbarch_num_regs (gdbarch)
  138.                  + gdbarch_num_pseudo_regs (gdbarch) + nr;
  139.       }
  140.   }

  141.   return -1;
  142. }

  143. static struct user_reg *
  144. usernum_to_user_reg (struct gdbarch *gdbarch, int usernum)
  145. {
  146.   struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
  147.   struct user_reg *reg;

  148.   for (reg = regs->first; reg != NULL; reg = reg->next)
  149.     {
  150.       if (usernum == 0)
  151.         return reg;
  152.       usernum--;
  153.     }
  154.   return NULL;
  155. }

  156. const char *
  157. user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum)
  158. {
  159.   int maxregs = (gdbarch_num_regs (gdbarch)
  160.                  + gdbarch_num_pseudo_regs (gdbarch));

  161.   if (regnum < 0)
  162.     return NULL;
  163.   else if (regnum < maxregs)
  164.     return gdbarch_register_name (gdbarch, regnum);
  165.   else
  166.     {
  167.       struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
  168.       if (reg == NULL)
  169.         return NULL;
  170.       else
  171.         return reg->name;
  172.     }
  173. }

  174. struct value *
  175. value_of_user_reg (int regnum, struct frame_info *frame)
  176. {
  177.   struct gdbarch *gdbarch = get_frame_arch (frame);
  178.   int maxregs = (gdbarch_num_regs (gdbarch)
  179.                  + gdbarch_num_pseudo_regs (gdbarch));
  180.   struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);

  181.   gdb_assert (reg != NULL);
  182.   return reg->read (frame, reg->baton);
  183. }

  184. static void
  185. maintenance_print_user_registers (char *args, int from_tty)
  186. {
  187.   struct gdbarch *gdbarch = get_current_arch ();
  188.   struct gdb_user_regs *regs;
  189.   struct user_reg *reg;
  190.   int regnum;

  191.   regs = gdbarch_data (gdbarch, user_regs_data);
  192.   regnum = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);

  193.   fprintf_unfiltered (gdb_stdout, " %-11s %3s\n", "Name", "Nr");
  194.   for (reg = regs->first; reg != NULL; reg = reg->next, ++regnum)
  195.     fprintf_unfiltered (gdb_stdout, " %-11s %3d\n", reg->name, regnum);
  196. }

  197. extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */

  198. void
  199. _initialize_user_regs (void)
  200. {
  201.   user_regs_data = gdbarch_data_register_post_init (user_regs_init);

  202.   add_cmd ("user-registers", class_maintenance,
  203.            maintenance_print_user_registers,
  204.            _("List the names of the current user registers.\n"),
  205.            &maintenanceprintlist);
  206. }