]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbarch.py
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/>.
25 # All the components created in gdbarch-components.py.
29 def indentation(n_columns
):
30 """Return string with tabs and spaces to indent line to N_COLUMNS."""
31 return "\t" * (n_columns
// 8) + " " * (n_columns
% 8)
34 def join_type_and_name(t
, n
):
35 "Combine the type T and the name N into a C declaration."
36 if t
.endswith("*") or t
.endswith("&"):
42 def join_params(params
):
43 """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated
44 list of declarations."""
45 params
= [join_type_and_name(p
[0], p
[1]) for p
in params
]
46 return ", ".join(params
)
50 "Base class for all components."
52 def __init__(self
, **kwargs
):
54 setattr(self
, key
, kwargs
[key
])
55 components
.append(self
)
57 # It doesn't make sense to have a check of the result value
58 # for a function or method with void return type.
59 if self
.type == "void" and self
.result_checks
:
60 raise Exception("can't have result checks with a void return type")
62 def get_predicate(self
):
63 "Return the expression used for validity checking."
64 assert self
.predicate
and not isinstance(self
.invalid
, str)
66 predicate
= f
"gdbarch->{self.name} != {self.predefault}"
67 elif isinstance(c
, Value
):
68 predicate
= f
"gdbarch->{self.name} != 0"
70 predicate
= f
"gdbarch->{self.name} != NULL"
74 class Info(_Component
):
75 "An Info component is copied from the gdbarch_info."
77 def __init__(self
, *, name
, type, printer
=None):
78 super().__init
__(name
=name
, type=type, printer
=printer
)
79 # This little hack makes the generator a bit simpler.
83 class Value(_Component
):
84 "A Value component is just a data member."
103 predefault
=predefault
,
104 postdefault
=postdefault
,
110 class Function(_Component
):
111 "A Function component is a function pointer member."
133 predefault
=predefault
,
134 postdefault
=postdefault
,
138 param_checks
=param_checks
,
139 result_checks
=result_checks
,
143 "Return the name of the function typedef to use."
144 return f
"gdbarch_{self.name}_ftype"
146 def param_list(self
):
147 "Return the formal parameter list as a string."
148 return join_params(self
.params
)
151 """Return the formal parameter list of the caller function,
152 as a string. This list includes the gdbarch."""
153 arch_arg
= ("struct gdbarch *", "gdbarch")
154 arch_tuple
= [arch_arg
]
155 return join_params(arch_tuple
+ list(self
.params
))
158 "Return the actual parameters to forward, as a string."
159 return ", ".join([p
[1] for p
in self
.params
])
162 class Method(Function
):
163 "A Method is like a Function but passes the gdbarch through."
165 def param_list(self
):
167 return self
.set_list()
171 result
= ["gdbarch"] + [p
[1] for p
in self
.params
]
172 return ", ".join(result
)
175 # Read the components.
176 with
open("gdbarch-components.py") as fd
:
179 copyright
= gdbcopyright
.copyright(
180 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger."
185 "Filter function to only allow Info components."
186 return type(c
) is Info
190 "Filter function to omit Info components."
191 return type(c
) is not Info
194 with
open("gdbarch-gen.h", "w") as f
:
195 print(copyright
, file=f
)
198 print("/* The following are pre-initialized by GDBARCH. */", file=f
)
200 # Do Info components first.
201 for c
in filter(info
, components
):
204 f
"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
205 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
211 print("/* The following are initialized by the target dependent code. */", file=f
)
213 # Generate decls for accessors, setters, and predicates for all
214 # non-Info components.
215 for c
in filter(not_info
, components
):
218 comment
= c
.comment
.split("\n")
220 comment
= comment
[1:]
221 if comment
[-1] == "":
222 comment
= comment
[:-1]
223 print("/* ", file=f
, end
="")
224 print(comment
[0], file=f
, end
="")
228 textwrap
.indent("\n".join(comment
[1:]), prefix
=" "),
236 print(f
"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f
)
239 if isinstance(c
, Value
):
241 f
"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
245 f
"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
249 assert isinstance(c
, Function
)
251 f
"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
255 f
"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
259 f
"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
263 with
open("gdbarch.c", "w") as f
:
264 print(copyright
, file=f
)
266 print("/* Maintain the struct gdbarch object. */", file=f
)
269 # The struct definition body.
271 print("struct gdbarch", file=f
)
273 print(" /* Has this architecture been fully initialized? */", file=f
)
274 print(" bool initialized_p = false;", file=f
)
276 print(" /* An obstack bound to the lifetime of the architecture. */", file=f
)
277 print(" auto_obstack obstack;", file=f
)
278 print(" /* Registry. */", file=f
)
279 print(" registry<gdbarch> registry_fields;", file=f
)
281 print(" /* basic architectural information. */", file=f
)
282 for c
in filter(info
, components
):
283 print(f
" {c.type} {c.name};", file=f
)
285 print(" /* target specific vector. */", file=f
)
286 print(" struct gdbarch_tdep_base *tdep = nullptr;", file=f
)
287 print(" gdbarch_dump_tdep_ftype *dump_tdep = nullptr;", file=f
)
289 print(" /* per-architecture data-pointers. */", file=f
)
290 print(" unsigned nr_data = 0;", file=f
)
291 print(" void **data = nullptr;", file=f
)
293 for c
in filter(not_info
, components
):
294 if isinstance(c
, Function
):
295 print(f
" gdbarch_{c.name}_ftype *", file=f
, end
="")
297 print(f
" {c.type} ", file=f
, end
="")
298 print(f
"{c.name} = ", file=f
, end
="")
299 if c
.predefault
is not None:
300 print(f
"{c.predefault};", file=f
)
301 elif isinstance(c
, Value
):
304 assert isinstance(c
, Function
)
305 print("nullptr;", file=f
)
311 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f
)
312 print(" ``struct gdbarch_info''. */", file=f
)
314 print("struct gdbarch *", file=f
)
315 print("gdbarch_alloc (const struct gdbarch_info *info,", file=f
)
316 print(" struct gdbarch_tdep_base *tdep)", file=f
)
318 print(" struct gdbarch *gdbarch;", file=f
)
320 print(" gdbarch = new struct gdbarch;", file=f
)
322 print(" gdbarch->tdep = tdep;", file=f
)
324 for c
in filter(info
, components
):
325 print(f
" gdbarch->{c.name} = info->{c.name};", file=f
)
327 print(" return gdbarch;", file=f
)
333 # Post-initialization validation and updating
335 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f
)
337 print("static void", file=f
)
338 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f
)
340 print(" string_file log;", file=f
)
342 print(" /* fundamental */", file=f
)
343 print(" if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)", file=f
)
344 print(""" log.puts ("\\n\\tbyte-order");""", file=f
)
345 print(" if (gdbarch->bfd_arch_info == NULL)", file=f
)
346 print(""" log.puts ("\\n\\tbfd_arch_info");""", file=f
)
348 " /* Check those that need to be defined for the given multi-arch level. */",
351 for c
in filter(not_info
, components
):
352 if c
.invalid
is False:
353 print(f
" /* Skip verify of {c.name}, invalid_p == 0 */", file=f
)
355 print(f
" /* Skip verify of {c.name}, has predicate. */", file=f
)
356 elif isinstance(c
.invalid
, str) and c
.postdefault
is not None:
357 print(f
" if ({c.invalid})", file=f
)
358 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
359 elif c
.predefault
is not None and c
.postdefault
is not None:
360 print(f
" if (gdbarch->{c.name} == {c.predefault})", file=f
)
361 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
362 elif c
.postdefault
is not None:
363 print(f
" if (gdbarch->{c.name} == 0)", file=f
)
364 print(f
" gdbarch->{c.name} = {c.postdefault};", file=f
)
365 elif isinstance(c
.invalid
, str):
366 print(f
" if ({c.invalid})", file=f
)
367 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
368 elif c
.predefault
is not None:
369 print(f
" if (gdbarch->{c.name} == {c.predefault})", file=f
)
370 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
371 elif c
.invalid
is True:
372 print(f
" if (gdbarch->{c.name} == 0)", file=f
)
373 print(f
""" log.puts ("\\n\\t{c.name}");""", file=f
)
375 # We should not allow ourselves to simply do nothing here
376 # because no other case applies. If we end up here then
377 # either the input data needs adjusting so one of the
378 # above cases matches, or we need additional cases adding
380 raise Exception("unhandled case when generating gdbarch validation")
381 print(" if (!log.empty ())", file=f
)
383 """ internal_error (_("verify_gdbarch: the following are invalid ...%s"),""",
386 print(" log.c_str ());", file=f
)
393 print("/* Print out the details of the current architecture. */", file=f
)
395 print("void", file=f
)
396 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f
)
398 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f
)
400 print("#if defined (GDB_NM_FILE)", file=f
)
401 print(" gdb_nm_file = GDB_NM_FILE;", file=f
)
402 print("#endif", file=f
)
403 print(" gdb_printf (file,", file=f
)
404 print(""" "gdbarch_dump: GDB_NM_FILE = %s\\n",""", file=f
)
405 print(" gdb_nm_file);", file=f
)
408 print(" gdb_printf (file,", file=f
)
410 f
""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
413 print(f
" gdbarch_{c.name}_p (gdbarch));", file=f
)
414 if isinstance(c
, Function
):
415 print(" gdb_printf (file,", file=f
)
416 print(f
""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f
)
418 f
" host_address_to_string (gdbarch->{c.name}));",
424 elif c
.type == "CORE_ADDR":
425 printer
= f
"core_addr_to_string_nz (gdbarch->{c.name})"
427 printer
= f
"plongest (gdbarch->{c.name})"
428 print(" gdb_printf (file,", file=f
)
429 print(f
""" "gdbarch_dump: {c.name} = %s\\n",""", file=f
)
430 print(f
" {printer});", file=f
)
431 print(" if (gdbarch->dump_tdep != NULL)", file=f
)
432 print(" gdbarch->dump_tdep (gdbarch, file);", file=f
)
436 # Bodies of setter, accessor, and predicate functions.
441 print("bool", file=f
)
442 print(f
"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f
)
444 print(" gdb_assert (gdbarch != NULL);", file=f
)
445 print(f
" return {c.get_predicate()};", file=f
)
447 if isinstance(c
, Function
):
449 print(f
"{c.type}", file=f
)
450 print(f
"gdbarch_{c.name} ({c.set_list()})", file=f
)
452 print(" gdb_assert (gdbarch != NULL);", file=f
)
453 print(f
" gdb_assert (gdbarch->{c.name} != NULL);", file=f
)
454 if c
.predicate
and c
.predefault
:
455 # Allow a call to a function with a predicate.
457 f
" /* Do not check predicate: {c.get_predicate()}, allow call. */",
461 for rule
in c
.param_checks
:
462 print(f
" gdb_assert ({rule});", file=f
)
463 print(" if (gdbarch_debug >= 2)", file=f
)
465 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
468 print(" ", file=f
, end
="")
471 print("auto result = ", file=f
, end
="")
473 print("return ", file=f
, end
="")
474 print(f
"gdbarch->{c.name} ({c.actuals()});", file=f
)
475 if c
.type != "void" and c
.result_checks
:
476 for rule
in c
.result_checks
:
477 print(f
" gdb_assert ({rule});", file=f
)
478 print(" return result;", file=f
)
481 print("void", file=f
)
482 setter_name
= f
"set_gdbarch_{c.name}"
483 ftype_name
= f
"gdbarch_{c.name}_ftype"
484 print(f
"{setter_name} (struct gdbarch *gdbarch,", file=f
)
485 indent_columns
= len(f
"{setter_name} (")
486 print(f
"{indentation(indent_columns)}{ftype_name} {c.name})", file=f
)
488 print(f
" gdbarch->{c.name} = {c.name};", file=f
)
490 elif isinstance(c
, Value
):
492 print(f
"{c.type}", file=f
)
493 print(f
"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f
)
495 print(" gdb_assert (gdbarch != NULL);", file=f
)
496 if c
.invalid
is False:
497 print(f
" /* Skip verify of {c.name}, invalid_p == 0 */", file=f
)
498 elif isinstance(c
.invalid
, str):
499 print(" /* Check variable is valid. */", file=f
)
500 print(f
" gdb_assert (!({c.invalid}));", file=f
)
502 print(" /* Check variable changed from pre-default. */", file=f
)
503 print(f
" gdb_assert (gdbarch->{c.name} != {c.predefault});", file=f
)
504 print(" if (gdbarch_debug >= 2)", file=f
)
506 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
509 print(f
" return gdbarch->{c.name};", file=f
)
512 print("void", file=f
)
513 setter_name
= f
"set_gdbarch_{c.name}"
514 print(f
"{setter_name} (struct gdbarch *gdbarch,", file=f
)
515 indent_columns
= len(f
"{setter_name} (")
516 print(f
"{indentation(indent_columns)}{c.type} {c.name})", file=f
)
518 print(f
" gdbarch->{c.name} = {c.name};", file=f
)
521 assert isinstance(c
, Info
)
523 print(f
"{c.type}", file=f
)
524 print(f
"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f
)
526 print(" gdb_assert (gdbarch != NULL);", file=f
)
527 print(" if (gdbarch_debug >= 2)", file=f
)
529 f
""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
532 print(f
" return gdbarch->{c.name};", file=f
)