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