]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/user-regs.c
Finalized intl-update patches
[thirdparty/binutils-gdb.git] / gdb / user-regs.c
CommitLineData
eb8bc282
AC
1/* User visible, per-frame registers, for GDB, the GNU debugger.
2
213516ef 3 Copyright (C) 2002-2023 Free Software Foundation, Inc.
eb8bc282
AC
4
5 Contributed by Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
eb8bc282
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
eb8bc282
AC
21
22#include "defs.h"
23#include "user-regs.h"
24#include "gdbtypes.h"
eb8bc282 25#include "frame.h"
f5b95c01
AA
26#include "arch-utils.h"
27#include "command.h"
28#include "cli/cli-cmds.h"
eb8bc282
AC
29
30/* A table of user registers.
31
32 User registers have regnum's that live above of the range [0
f57d151a
UW
33 .. gdbarch_num_regs + gdbarch_num_pseudo_regs)
34 (which is controlled by the target).
eb8bc282
AC
35 The target should never see a user register's regnum value.
36
37 Always append, never delete. By doing this, the relative regnum
f57d151a
UW
38 (offset from gdbarch_num_regs + gdbarch_num_pseudo_regs)
39 assigned to each user register never changes. */
eb8bc282
AC
40
41struct user_reg
42{
43 const char *name;
5ccd2fb7
KR
44 /* Avoid the "read" symbol name as it conflicts with a preprocessor symbol
45 in the NetBSD header for Stack Smashing Protection, that wraps the read(2)
46 syscall. */
9efe17a3 47 struct value *(*xread) (frame_info_ptr frame, const void *baton);
123dc839 48 const void *baton;
63022984 49 struct user_reg *next;
eb8bc282
AC
50};
51
8b9740d8
DJ
52/* This structure is named gdb_user_regs instead of user_regs to avoid
53 conflicts with any "struct user_regs" in system headers. For instance,
54 on ARM GNU/Linux native builds, nm-linux.h includes <signal.h> includes
55 <sys/ucontext.h> includes <sys/procfs.h> includes <sys/user.h>, which
56 declares "struct user_regs". */
57
58struct gdb_user_regs
eb8bc282 59{
cb275538
TT
60 struct user_reg *first = nullptr;
61 struct user_reg **last = nullptr;
eb8bc282
AC
62};
63
64static void
8b9740d8 65append_user_reg (struct gdb_user_regs *regs, const char *name,
5ccd2fb7 66 user_reg_read_ftype *xread, const void *baton,
123dc839 67 struct user_reg *reg)
eb8bc282 68{
63022984
AC
69 /* The caller is responsible for allocating memory needed to store
70 the register. By doing this, the function can operate on a
71 register list stored in the common heap or a specific obstack. */
72 gdb_assert (reg != NULL);
73 reg->name = name;
5ccd2fb7 74 reg->xread = xread;
123dc839 75 reg->baton = baton;
63022984 76 reg->next = NULL;
411c7e04
TV
77 if (regs->last == nullptr)
78 regs->last = &regs->first;
63022984
AC
79 (*regs->last) = reg;
80 regs->last = &(*regs->last)->next;
eb8bc282
AC
81}
82
83/* An array of the builtin user registers. */
84
411c7e04 85static struct gdb_user_regs builtin_user_regs;
eb8bc282
AC
86
87void
5ccd2fb7 88user_reg_add_builtin (const char *name, user_reg_read_ftype *xread,
123dc839 89 const void *baton)
eb8bc282 90{
5ccd2fb7 91 append_user_reg (&builtin_user_regs, name, xread, baton,
70ba0933 92 XNEW (struct user_reg));
eb8bc282
AC
93}
94
95/* Per-architecture user registers. Start with the builtin user
96 registers and then, again, append. */
97
cb275538 98static const registry<gdbarch>::key<gdb_user_regs> user_regs_data;
eb8bc282 99
cb275538
TT
100static gdb_user_regs *
101get_user_regs (struct gdbarch *gdbarch)
eb8bc282 102{
cb275538
TT
103 struct gdb_user_regs *regs = user_regs_data.get (gdbarch);
104 if (regs == nullptr)
105 {
106 regs = new struct gdb_user_regs;
107
108 struct obstack *obstack = gdbarch_obstack (gdbarch);
109 regs->last = &regs->first;
110 for (user_reg *reg = builtin_user_regs.first;
111 reg != NULL;
112 reg = reg->next)
113 append_user_reg (regs, reg->name, reg->xread, reg->baton,
114 OBSTACK_ZALLOC (obstack, struct user_reg));
115 user_regs_data.set (gdbarch, regs);
116 }
5d502164 117
eb8bc282
AC
118 return regs;
119}
120
eb8bc282
AC
121void
122user_reg_add (struct gdbarch *gdbarch, const char *name,
5ccd2fb7 123 user_reg_read_ftype *xread, const void *baton)
eb8bc282 124{
cb275538 125 struct gdb_user_regs *regs = get_user_regs (gdbarch);
3bc98c0c 126 gdb_assert (regs != NULL);
5ccd2fb7 127 append_user_reg (regs, name, xread, baton,
63022984 128 GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
eb8bc282
AC
129}
130
131int
132user_reg_map_name_to_regnum (struct gdbarch *gdbarch, const char *name,
133 int len)
134{
135 /* Make life easy, set the len to something reasonable. */
136 if (len < 0)
137 len = strlen (name);
138
139 /* Search register name space first - always let an architecture
140 specific register override the user registers. */
141 {
f6efe3f8 142 int maxregs = gdbarch_num_cooked_regs (gdbarch);
5d502164 143
637b2f86 144 for (int i = 0; i < maxregs; i++)
eb8bc282
AC
145 {
146 const char *regname = gdbarch_register_name (gdbarch, i);
5d502164 147
637b2f86
AB
148 if (len == strlen (regname) && strncmp (regname, name, len) == 0)
149 return i;
eb8bc282
AC
150 }
151 }
152
153 /* Search the user name space. */
154 {
cb275538 155 struct gdb_user_regs *regs = get_user_regs (gdbarch);
63022984
AC
156 struct user_reg *reg;
157 int nr;
5d502164 158
63022984 159 for (nr = 0, reg = regs->first; reg != NULL; reg = reg->next, nr++)
eb8bc282 160 {
63022984
AC
161 if ((len < 0 && strcmp (reg->name, name))
162 || (len == strlen (reg->name)
163 && strncmp (reg->name, name, len) == 0))
f6efe3f8 164 return gdbarch_num_cooked_regs (gdbarch) + nr;
eb8bc282
AC
165 }
166 }
167
168 return -1;
169}
170
63022984
AC
171static struct user_reg *
172usernum_to_user_reg (struct gdbarch *gdbarch, int usernum)
173{
cb275538 174 struct gdb_user_regs *regs = get_user_regs (gdbarch);
63022984 175 struct user_reg *reg;
5d502164 176
63022984
AC
177 for (reg = regs->first; reg != NULL; reg = reg->next)
178 {
179 if (usernum == 0)
180 return reg;
181 usernum--;
182 }
183 return NULL;
184}
185
eb8bc282
AC
186const char *
187user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum)
188{
f6efe3f8 189 int maxregs = gdbarch_num_cooked_regs (gdbarch);
5d502164 190
eb8bc282
AC
191 if (regnum < 0)
192 return NULL;
63022984 193 else if (regnum < maxregs)
eb8bc282 194 return gdbarch_register_name (gdbarch, regnum);
63022984
AC
195 else
196 {
197 struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
198 if (reg == NULL)
199 return NULL;
200 else
201 return reg->name;
202 }
eb8bc282
AC
203}
204
205struct value *
bd2b40ac 206value_of_user_reg (int regnum, frame_info_ptr frame)
eb8bc282
AC
207{
208 struct gdbarch *gdbarch = get_frame_arch (frame);
f6efe3f8 209 int maxregs = gdbarch_num_cooked_regs (gdbarch);
63022984 210 struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
5d502164 211
63022984 212 gdb_assert (reg != NULL);
5ccd2fb7 213 return reg->xread (frame, reg->baton);
eb8bc282
AC
214}
215
f5b95c01 216static void
4d4589ef 217maintenance_print_user_registers (const char *args, int from_tty)
f5b95c01
AA
218{
219 struct gdbarch *gdbarch = get_current_arch ();
f5b95c01
AA
220 struct user_reg *reg;
221 int regnum;
222
cb275538 223 struct gdb_user_regs *regs = get_user_regs (gdbarch);
f6efe3f8 224 regnum = gdbarch_num_cooked_regs (gdbarch);
f5b95c01 225
6cb06a8c 226 gdb_printf (" %-11s %3s\n", "Name", "Nr");
f5b95c01 227 for (reg = regs->first; reg != NULL; reg = reg->next, ++regnum)
6cb06a8c 228 gdb_printf (" %-11s %3d\n", reg->name, regnum);
f5b95c01
AA
229}
230
6c265988 231void _initialize_user_regs ();
eb8bc282 232void
6c265988 233_initialize_user_regs ()
eb8bc282 234{
f5b95c01
AA
235 add_cmd ("user-registers", class_maintenance,
236 maintenance_print_user_registers,
89549d7f 237 _("List the names of the current user registers."),
f5b95c01 238 &maintenanceprintlist);
eb8bc282 239}