3 # Architecture commands for GDB, the GNU debugger.
5 # Copyright (C) 1998-2023 Free Software Foundation, Inc.
7 # This file is part of GDB.
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
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
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.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # gdbarch_components is imported only for its side-effect of filling
25 # `gdbarch_types.components`.
26 import gdbarch_components
# noqa: F401 # type: ignore
28 from gdbarch_types
import Component
, Function
, Info
, Value
, components
31 def indentation(n_columns
: int):
32 """Return string with tabs and spaces to indent line to N_COLUMNS."""
33 return "\t" * (n_columns
// 8) + " " * (n_columns
% 8)
36 copyright
= gdbcopyright
.copyright(
37 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger."
41 def info(c
: Component
):
42 "Filter function to only allow Info components."
43 return type(c
) is Info
46 def not_info(c
: Component
):
47 "Filter function to omit Info components."
48 return type(c
) is not Info
51 with
open("gdbarch-gen.h", "w") as f
:
52 print(copyright
, file=f
)
55 print("/* The following are pre-initialized by GDBARCH. */", file=f
)
57 # Do Info components first.
58 for c
in filter(info
, components
):
61 f
"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
62 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
68 print("/* The following are initialized by the target dependent code. */", file=f
)
70 # Generate decls for accessors, setters, and predicates for all
71 # non-Info components.
72 for c
in filter(not_info
, components
):
75 comment
= c
.comment
.split("\n")
79 comment
= comment
[:-1]
80 print("/* ", file=f
, end
="")
81 print(comment
[0], file=f
, end
="")
85 textwrap
.indent("\n".join(comment
[1:]), prefix
=" "),
93 print(f
"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f
)
96 if isinstance(c
, Value
):
98 f
"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
102 f
"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
106 assert isinstance(c
, Function
)
108 f
"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
113 f
"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
117 f
"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
121 with
open("gdbarch.c", "w") as f
:
122 print(copyright
, file=f
)
124 print("/* Maintain the struct gdbarch object. */", file=f
)
127 # The struct definition body.
129 print("struct gdbarch", file=f
)
131 print(" /* Has this architecture been fully initialized? */", file=f
)
132 print(" bool initialized_p = false;", file=f
)
134 print(" /* An obstack bound to the lifetime of the architecture. */", file=f
)
135 print(" auto_obstack obstack;", file=f
)
136 print(" /* Registry. */", file=f
)
137 print(" registry<gdbarch> registry_fields;", file=f
)
139 print(" /* basic architectural information. */", file=f
)
140 for c
in filter(info
, components
):
141 print(f
" {c.type} {c.name};", file=f
)
143 print(" /* target specific vector. */", file=f
)
144 print(" gdbarch_tdep_up tdep;", file=f
)
145 print(" gdbarch_dump_tdep_ftype *dump_tdep = nullptr;", file=f
)
147 for c
in filter(not_info
, components
):
148 if isinstance(c
, Function
):
149 print(f
" gdbarch_{c.name}_ftype *", file=f
, end
="")
151 print(f
" {c.type} ", file=f
, end
="")
152 print(f
"{c.name} = ", file=f
, end
="")
153 if c
.predefault
is not None:
154 print(f
"{c.predefault};", file=f
)
155 elif isinstance(c
, Value
):
158 assert isinstance(c
, Function
)
159 print("nullptr;", file=f
)
165 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f
)
166 print(" ``struct gdbarch_info''. */", file=f
)
168 print("struct gdbarch *", file=f
)
169 print("gdbarch_alloc (const struct gdbarch_info *info,", file=f
)
170 print(" gdbarch_tdep_up tdep)", file=f
)
172 print(" struct gdbarch *gdbarch;", file=f
)
174 print(" gdbarch = new struct gdbarch;", file=f
)
176 print(" gdbarch->tdep = std::move (tdep);", file=f
)
178 for c
in filter(info
, components
):
179 print(f
" gdbarch->{c.name} = info->{c.name};", file=f
)
181 print(" return gdbarch;", file=f
)
187 # Post-initialization validation and updating
189 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f
)
191 print("static void", file=f
)
192 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f
)
194 print(" string_file log;", file=f
)
196 print(" /* fundamental */", file=f
)
197 print(" if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)", file=f
)
198 print(""" log.puts ("\\n\\tbyte-order");""", file=f
)
199 print(" if (gdbarch->bfd_arch_info == NULL)", file=f
)
200 print(""" log.puts ("\\n\\tbfd_arch_info");""", file=f
)
202 " /* Check those that need to be defined for the given multi-arch level. */",
205 for c
in filter(not_info
, components
):
206 if c
.invalid
is False:
207 print(f
" /* Skip verify of {c.name}, invalid_p == 0 */", file=f
)
209 print(f
" /* Skip verify of {c.name}, has predicate. */", file=f
)
210 elif isinstance(c
.invalid
, str) and c
.postdefault
is not None:
211 print(f
" if ({c.invalid})", file=f
)
212 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
213 elif c
.predefault
is not None and c
.postdefault
is not None:
214 print(f
" if (gdbarch->{c.name} == {c.predefault})", file=f
)
215 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
216 elif c
.postdefault
is not None:
217 print(f
" if (gdbarch->{c.name} == 0)", file=f
)
218 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
219 elif isinstance(c
.invalid
, str):
220 print(f
" if ({c.invalid})", file=f
)
221 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
222 elif c
.predefault
is not None:
223 print(f
" if (gdbarch->{c.name} == {c.predefault})", file=f
)
224 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
225 elif c
.invalid
is True:
226 print(f
" if (gdbarch->{c.name} == 0)", file=f
)
227 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
229 # We should not allow ourselves to simply do nothing here
230 # because no other case applies. If we end up here then
231 # either the input data needs adjusting so one of the
232 # above cases matches, or we need additional cases adding
234 raise Exception("unhandled case when generating gdbarch validation")
235 print(" if (!log.empty ())", file=f
)
237 """ internal_error (_("verify_gdbarch: the following are invalid ...%s"),""",
240 print(" log.c_str ());", file=f
)
247 print("/* Print out the details of the current architecture. */", file=f
)
249 print("void", file=f
)
250 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f
)
252 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f
)
254 print("#if defined (GDB_NM_FILE)", file=f
)
255 print(" gdb_nm_file = GDB_NM_FILE;", file=f
)
256 print("#endif", file=f
)
257 print(" gdb_printf (file,", file=f
)
258 print(""" "gdbarch_dump: GDB_NM_FILE = %s\\n",""", file=f
)
259 print(" gdb_nm_file);", file=f
)
262 print(" gdb_printf (file,", file=f
)
264 f
""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
267 print(f
" gdbarch_{c.name}_p (gdbarch));", file=f
)
268 if isinstance(c
, Function
):
269 print(" gdb_printf (file,", file=f
)
270 print(f
""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f
)
272 f
" host_address_to_string (gdbarch->{c.name}));",
278 elif c
.type == "CORE_ADDR":
279 printer
= f
"core_addr_to_string_nz (gdbarch->{c.name})"
281 printer
= f
"plongest (gdbarch->{c.name})"
282 print(" gdb_printf (file,", file=f
)
283 print(f
""" "gdbarch_dump: {c.name} = %s\\n",""", file=f
)
284 print(f
" {printer});", file=f
)
285 print(" if (gdbarch->dump_tdep != NULL)", file=f
)
286 print(" gdbarch->dump_tdep (gdbarch, file);", file=f
)
290 # Bodies of setter, accessor, and predicate functions.
295 print("bool", file=f
)
296 print(f
"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f
)
298 print(" gdb_assert (gdbarch != NULL);", file=f
)
299 print(f
" return {c.get_predicate()};", file=f
)
301 if isinstance(c
, Function
):
304 print(f
"{c.type}", file=f
)
305 print(f
"gdbarch_{c.name} ({c.set_list()})", file=f
)
307 print(" gdb_assert (gdbarch != NULL);", file=f
)
308 print(f
" gdb_assert (gdbarch->{c.name} != NULL);", file=f
)
309 if c
.predicate
and c
.predefault
:
310 # Allow a call to a function with a predicate.
312 f
" /* Do not check predicate: {c.get_predicate()}, allow call. */",
316 for rule
in c
.param_checks
:
317 print(f
" gdb_assert ({rule});", file=f
)
318 print(" if (gdbarch_debug >= 2)", file=f
)
320 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
323 print(" ", file=f
, end
="")
326 print("auto result = ", file=f
, end
="")
328 print("return ", file=f
, end
="")
329 print(f
"gdbarch->{c.name} ({c.actuals()});", file=f
)
330 if c
.type != "void" and c
.result_checks
:
331 for rule
in c
.result_checks
:
332 print(f
" gdb_assert ({rule});", file=f
)
333 print(" return result;", file=f
)
336 print("void", file=f
)
337 setter_name
= f
"set_gdbarch_{c.name}"
338 ftype_name
= f
"gdbarch_{c.name}_ftype"
339 print(f
"{setter_name} (struct gdbarch *gdbarch,", file=f
)
340 indent_columns
= len(f
"{setter_name} (")
341 print(f
"{indentation(indent_columns)}{ftype_name} {c.name})", file=f
)
343 print(f
" gdbarch->{c.name} = {c.name};", file=f
)
345 elif isinstance(c
, Value
):
347 print(f
"{c.type}", file=f
)
348 print(f
"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f
)
350 print(" gdb_assert (gdbarch != NULL);", file=f
)
351 if c
.invalid
is False:
352 print(f
" /* Skip verify of {c.name}, invalid_p == 0 */", file=f
)
353 elif isinstance(c
.invalid
, str):
354 print(" /* Check variable is valid. */", file=f
)
355 print(f
" gdb_assert (!({c.invalid}));", file=f
)
357 print(" /* Check variable changed from pre-default. */", file=f
)
358 print(f
" gdb_assert (gdbarch->{c.name} != {c.predefault});", file=f
)
359 print(" if (gdbarch_debug >= 2)", file=f
)
361 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
364 print(f
" return gdbarch->{c.name};", file=f
)
367 print("void", file=f
)
368 setter_name
= f
"set_gdbarch_{c.name}"
369 print(f
"{setter_name} (struct gdbarch *gdbarch,", file=f
)
370 indent_columns
= len(f
"{setter_name} (")
371 print(f
"{indentation(indent_columns)}{c.type} {c.name})", file=f
)
373 print(f
" gdbarch->{c.name} = {c.name};", file=f
)
376 assert isinstance(c
, Info
)
378 print(f
"{c.type}", file=f
)
379 print(f
"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f
)
381 print(" gdb_assert (gdbarch != NULL);", file=f
)
382 print(" if (gdbarch_debug >= 2)", file=f
)
384 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
387 print(f
" return gdbarch->{c.name};", file=f
)