xref: /dflybsd-src/contrib/gdb-7/gdb/user-regs.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* User visible, per-frame registers, for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 2002-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Red Hat.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "user-regs.h"
245796c8dcSSimon Schubert #include "gdbtypes.h"
255796c8dcSSimon Schubert #include "gdb_string.h"
265796c8dcSSimon Schubert #include "gdb_assert.h"
275796c8dcSSimon Schubert #include "frame.h"
285796c8dcSSimon Schubert 
295796c8dcSSimon Schubert /* A table of user registers.
305796c8dcSSimon Schubert 
315796c8dcSSimon Schubert    User registers have regnum's that live above of the range [0
325796c8dcSSimon Schubert    .. gdbarch_num_regs + gdbarch_num_pseudo_regs)
335796c8dcSSimon Schubert    (which is controlled by the target).
345796c8dcSSimon Schubert    The target should never see a user register's regnum value.
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert    Always append, never delete.  By doing this, the relative regnum
375796c8dcSSimon Schubert    (offset from gdbarch_num_regs + gdbarch_num_pseudo_regs)
385796c8dcSSimon Schubert     assigned to each user  register never changes.  */
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert struct user_reg
415796c8dcSSimon Schubert {
425796c8dcSSimon Schubert   const char *name;
435796c8dcSSimon Schubert   struct value *(*read) (struct frame_info * frame, const void *baton);
445796c8dcSSimon Schubert   const void *baton;
455796c8dcSSimon Schubert   struct user_reg *next;
465796c8dcSSimon Schubert };
475796c8dcSSimon Schubert 
485796c8dcSSimon Schubert /* This structure is named gdb_user_regs instead of user_regs to avoid
495796c8dcSSimon Schubert    conflicts with any "struct user_regs" in system headers.  For instance,
505796c8dcSSimon Schubert    on ARM GNU/Linux native builds, nm-linux.h includes <signal.h> includes
515796c8dcSSimon Schubert    <sys/ucontext.h> includes <sys/procfs.h> includes <sys/user.h>, which
525796c8dcSSimon Schubert    declares "struct user_regs".  */
535796c8dcSSimon Schubert 
545796c8dcSSimon Schubert struct gdb_user_regs
555796c8dcSSimon Schubert {
565796c8dcSSimon Schubert   struct user_reg *first;
575796c8dcSSimon Schubert   struct user_reg **last;
585796c8dcSSimon Schubert };
595796c8dcSSimon Schubert 
605796c8dcSSimon Schubert static void
append_user_reg(struct gdb_user_regs * regs,const char * name,user_reg_read_ftype * read,const void * baton,struct user_reg * reg)615796c8dcSSimon Schubert append_user_reg (struct gdb_user_regs *regs, const char *name,
625796c8dcSSimon Schubert 		 user_reg_read_ftype *read, const void *baton,
635796c8dcSSimon Schubert 		 struct user_reg *reg)
645796c8dcSSimon Schubert {
655796c8dcSSimon Schubert   /* The caller is responsible for allocating memory needed to store
665796c8dcSSimon Schubert      the register.  By doing this, the function can operate on a
675796c8dcSSimon Schubert      register list stored in the common heap or a specific obstack.  */
685796c8dcSSimon Schubert   gdb_assert (reg != NULL);
695796c8dcSSimon Schubert   reg->name = name;
705796c8dcSSimon Schubert   reg->read = read;
715796c8dcSSimon Schubert   reg->baton = baton;
725796c8dcSSimon Schubert   reg->next = NULL;
735796c8dcSSimon Schubert   (*regs->last) = reg;
745796c8dcSSimon Schubert   regs->last = &(*regs->last)->next;
755796c8dcSSimon Schubert }
765796c8dcSSimon Schubert 
775796c8dcSSimon Schubert /* An array of the builtin user registers.  */
785796c8dcSSimon Schubert 
79c50c785cSJohn Marino static struct gdb_user_regs builtin_user_regs = {
80c50c785cSJohn Marino   NULL, &builtin_user_regs.first
81c50c785cSJohn Marino };
825796c8dcSSimon Schubert 
835796c8dcSSimon Schubert void
user_reg_add_builtin(const char * name,user_reg_read_ftype * read,const void * baton)845796c8dcSSimon Schubert user_reg_add_builtin (const char *name, user_reg_read_ftype *read,
855796c8dcSSimon Schubert 		      const void *baton)
865796c8dcSSimon Schubert {
875796c8dcSSimon Schubert   append_user_reg (&builtin_user_regs, name, read, baton,
885796c8dcSSimon Schubert 		   XMALLOC (struct user_reg));
895796c8dcSSimon Schubert }
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert /* Per-architecture user registers.  Start with the builtin user
925796c8dcSSimon Schubert    registers and then, again, append.  */
935796c8dcSSimon Schubert 
945796c8dcSSimon Schubert static struct gdbarch_data *user_regs_data;
955796c8dcSSimon Schubert 
965796c8dcSSimon Schubert static void *
user_regs_init(struct gdbarch * gdbarch)975796c8dcSSimon Schubert user_regs_init (struct gdbarch *gdbarch)
985796c8dcSSimon Schubert {
995796c8dcSSimon Schubert   struct user_reg *reg;
100cf7f2e2dSJohn Marino   struct gdb_user_regs *regs
101cf7f2e2dSJohn Marino     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdb_user_regs);
102cf7f2e2dSJohn Marino 
1035796c8dcSSimon Schubert   regs->last = &regs->first;
1045796c8dcSSimon Schubert   for (reg = builtin_user_regs.first; reg != NULL; reg = reg->next)
1055796c8dcSSimon Schubert     append_user_reg (regs, reg->name, reg->read, reg->baton,
1065796c8dcSSimon Schubert 		     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
1075796c8dcSSimon Schubert   return regs;
1085796c8dcSSimon Schubert }
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert void
user_reg_add(struct gdbarch * gdbarch,const char * name,user_reg_read_ftype * read,const void * baton)1115796c8dcSSimon Schubert user_reg_add (struct gdbarch *gdbarch, const char *name,
1125796c8dcSSimon Schubert 	      user_reg_read_ftype *read, const void *baton)
1135796c8dcSSimon Schubert {
1145796c8dcSSimon Schubert   struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
115cf7f2e2dSJohn Marino 
1165796c8dcSSimon Schubert   if (regs == NULL)
1175796c8dcSSimon Schubert     {
1185796c8dcSSimon Schubert       /* ULGH, called during architecture initialization.  Patch
1195796c8dcSSimon Schubert          things up.  */
1205796c8dcSSimon Schubert       regs = user_regs_init (gdbarch);
1215796c8dcSSimon Schubert       deprecated_set_gdbarch_data (gdbarch, user_regs_data, regs);
1225796c8dcSSimon Schubert     }
1235796c8dcSSimon Schubert   append_user_reg (regs, name, read, baton,
1245796c8dcSSimon Schubert 		   GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
1255796c8dcSSimon Schubert }
1265796c8dcSSimon Schubert 
1275796c8dcSSimon Schubert int
user_reg_map_name_to_regnum(struct gdbarch * gdbarch,const char * name,int len)1285796c8dcSSimon Schubert user_reg_map_name_to_regnum (struct gdbarch *gdbarch, const char *name,
1295796c8dcSSimon Schubert 			     int len)
1305796c8dcSSimon Schubert {
1315796c8dcSSimon Schubert   /* Make life easy, set the len to something reasonable.  */
1325796c8dcSSimon Schubert   if (len < 0)
1335796c8dcSSimon Schubert     len = strlen (name);
1345796c8dcSSimon Schubert 
1355796c8dcSSimon Schubert   /* Search register name space first - always let an architecture
1365796c8dcSSimon Schubert      specific register override the user registers.  */
1375796c8dcSSimon Schubert   {
1385796c8dcSSimon Schubert     int i;
1395796c8dcSSimon Schubert     int maxregs = (gdbarch_num_regs (gdbarch)
1405796c8dcSSimon Schubert 		   + gdbarch_num_pseudo_regs (gdbarch));
141cf7f2e2dSJohn Marino 
1425796c8dcSSimon Schubert     for (i = 0; i < maxregs; i++)
1435796c8dcSSimon Schubert       {
1445796c8dcSSimon Schubert 	const char *regname = gdbarch_register_name (gdbarch, i);
145cf7f2e2dSJohn Marino 
1465796c8dcSSimon Schubert 	if (regname != NULL && len == strlen (regname)
1475796c8dcSSimon Schubert 	    && strncmp (regname, name, len) == 0)
1485796c8dcSSimon Schubert 	  {
1495796c8dcSSimon Schubert 	    return i;
1505796c8dcSSimon Schubert 	  }
1515796c8dcSSimon Schubert       }
1525796c8dcSSimon Schubert   }
1535796c8dcSSimon Schubert 
1545796c8dcSSimon Schubert   /* Search the user name space.  */
1555796c8dcSSimon Schubert   {
1565796c8dcSSimon Schubert     struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
1575796c8dcSSimon Schubert     struct user_reg *reg;
1585796c8dcSSimon Schubert     int nr;
159cf7f2e2dSJohn Marino 
1605796c8dcSSimon Schubert     for (nr = 0, reg = regs->first; reg != NULL; reg = reg->next, nr++)
1615796c8dcSSimon Schubert       {
1625796c8dcSSimon Schubert 	if ((len < 0 && strcmp (reg->name, name))
1635796c8dcSSimon Schubert 	    || (len == strlen (reg->name)
1645796c8dcSSimon Schubert 		&& strncmp (reg->name, name, len) == 0))
1655796c8dcSSimon Schubert 	  return gdbarch_num_regs (gdbarch)
1665796c8dcSSimon Schubert 		 + gdbarch_num_pseudo_regs (gdbarch) + nr;
1675796c8dcSSimon Schubert       }
1685796c8dcSSimon Schubert   }
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert   return -1;
1715796c8dcSSimon Schubert }
1725796c8dcSSimon Schubert 
1735796c8dcSSimon Schubert static struct user_reg *
usernum_to_user_reg(struct gdbarch * gdbarch,int usernum)1745796c8dcSSimon Schubert usernum_to_user_reg (struct gdbarch *gdbarch, int usernum)
1755796c8dcSSimon Schubert {
1765796c8dcSSimon Schubert   struct gdb_user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
1775796c8dcSSimon Schubert   struct user_reg *reg;
178cf7f2e2dSJohn Marino 
1795796c8dcSSimon Schubert   for (reg = regs->first; reg != NULL; reg = reg->next)
1805796c8dcSSimon Schubert     {
1815796c8dcSSimon Schubert       if (usernum == 0)
1825796c8dcSSimon Schubert 	return reg;
1835796c8dcSSimon Schubert       usernum--;
1845796c8dcSSimon Schubert     }
1855796c8dcSSimon Schubert   return NULL;
1865796c8dcSSimon Schubert }
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert const char *
user_reg_map_regnum_to_name(struct gdbarch * gdbarch,int regnum)1895796c8dcSSimon Schubert user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum)
1905796c8dcSSimon Schubert {
1915796c8dcSSimon Schubert   int maxregs = (gdbarch_num_regs (gdbarch)
1925796c8dcSSimon Schubert 		 + gdbarch_num_pseudo_regs (gdbarch));
193cf7f2e2dSJohn Marino 
1945796c8dcSSimon Schubert   if (regnum < 0)
1955796c8dcSSimon Schubert     return NULL;
1965796c8dcSSimon Schubert   else if (regnum < maxregs)
1975796c8dcSSimon Schubert     return gdbarch_register_name (gdbarch, regnum);
1985796c8dcSSimon Schubert   else
1995796c8dcSSimon Schubert     {
2005796c8dcSSimon Schubert       struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
2015796c8dcSSimon Schubert       if (reg == NULL)
2025796c8dcSSimon Schubert 	return NULL;
2035796c8dcSSimon Schubert       else
2045796c8dcSSimon Schubert 	return reg->name;
2055796c8dcSSimon Schubert     }
2065796c8dcSSimon Schubert }
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert struct value *
value_of_user_reg(int regnum,struct frame_info * frame)2095796c8dcSSimon Schubert value_of_user_reg (int regnum, struct frame_info *frame)
2105796c8dcSSimon Schubert {
2115796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (frame);
2125796c8dcSSimon Schubert   int maxregs = (gdbarch_num_regs (gdbarch)
2135796c8dcSSimon Schubert 		 + gdbarch_num_pseudo_regs (gdbarch));
2145796c8dcSSimon Schubert   struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
215cf7f2e2dSJohn Marino 
2165796c8dcSSimon Schubert   gdb_assert (reg != NULL);
2175796c8dcSSimon Schubert   return reg->read (frame, reg->baton);
2185796c8dcSSimon Schubert }
2195796c8dcSSimon Schubert 
2205796c8dcSSimon Schubert extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */
2215796c8dcSSimon Schubert 
2225796c8dcSSimon Schubert void
_initialize_user_regs(void)2235796c8dcSSimon Schubert _initialize_user_regs (void)
2245796c8dcSSimon Schubert {
2255796c8dcSSimon Schubert   user_regs_data = gdbarch_data_register_post_init (user_regs_init);
2265796c8dcSSimon Schubert }
227