3 # Architecture commands for GDB, the GNU debugger.
5 # Copyright (C) 1998-2022 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 join_type_and_name(t, n):
30 "Combine the type T and the name N into a C declaration."
31 if t.endswith("*") or t.endswith("&"):
37 def join_params(params):
38 """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated
39 list of declarations."""
40 params = [join_type_and_name(p[0], p[1]) for p in params]
41 return ", ".join(params)
45 "Base class for all components."
47 def __init__(self, **kwargs):
49 setattr(self, key, kwargs[key])
50 components.append(self)
52 def get_predicate(self):
53 "Return the expression used for validity checking."
54 assert self.predicate and not isinstance(self.invalid, str)
56 predicate = f"gdbarch->{self.name} != {self.predefault}"
57 elif isinstance(c, Value):
58 predicate = f"gdbarch->{self.name} != 0"
60 predicate = f"gdbarch->{self.name} != NULL"
64 class Info(_Component):
65 "An Info component is copied from the gdbarch_info."
67 def __init__(self, *, name, type, printer=None):
68 super().__init__(name=name, type=type, printer=printer)
69 # This little hack makes the generator a bit simpler.
73 class Value(_Component):
74 "A Value component is just a data member."
93 predefault=predefault,
94 postdefault=postdefault,
100 class Function(_Component):
101 "A Function component is a function pointer member."
121 predefault=predefault,
122 postdefault=postdefault,
129 "Return the name of the function typedef to use."
130 return f"gdbarch_{self.name}_ftype"
132 def param_list(self):
133 "Return the formal parameter list as a string."
134 return join_params(self.params)
137 """Return the formal parameter list of the caller function,
138 as a string. This list includes the gdbarch."""
139 arch_arg = ("struct gdbarch *", "gdbarch")
140 arch_tuple = [arch_arg]
141 return join_params(arch_tuple + list(self.params))
144 "Return the actual parameters to forward, as a string."
145 return ", ".join([p[1] for p in self.params])
148 class Method(Function):
149 "A Method is like a Function but passes the gdbarch through."
151 def param_list(self):
153 return self.set_list()
157 result = ["gdbarch"] + [p[1] for p in self.params]
158 return ", ".join(result)
161 # Read the components.
162 with open("gdbarch-components.py") as fd:
165 copyright = gdbcopyright.copyright(
166 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger."
171 "Filter function to only allow Info components."
172 return type(c) is Info
176 "Filter function to omit Info components."
177 return type(c) is not Info
180 with open("gdbarch-gen.h", "w") as f:
181 print(copyright, file=f)
184 print("/* The following are pre-initialized by GDBARCH. */", file=f)
186 # Do Info components first.
187 for c in filter(info, components):
190 f"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
191 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
197 print("/* The following are initialized by the target dependent code. */", file=f)
199 # Generate decls for accessors, setters, and predicates for all
200 # non-Info components.
201 for c in filter(not_info, components):
204 comment = c.comment.split("\n")
206 comment = comment[1:]
207 if comment[-1] == "":
208 comment = comment[:-1]
209 print("/* ", file=f, end="")
210 print(comment[0], file=f, end="")
214 textwrap.indent("\n".join(comment[1:]), prefix=" "),
222 print(f"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f)
225 if isinstance(c, Value):
227 f"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
231 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
235 assert isinstance(c, Function)
237 f"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
241 f"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
245 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
249 with open("gdbarch.c", "w") as f:
250 print(copyright, file=f)
252 print("/* Maintain the struct gdbarch object. */", file=f)
255 # The struct definition body.
257 print("struct gdbarch", file=f)
259 print(" /* Has this architecture been fully initialized? */", file=f)
260 print(" int initialized_p;", file=f)
262 print(" /* An obstack bound to the lifetime of the architecture. */", file=f)
263 print(" struct obstack *obstack;", file=f)
265 print(" /* basic architectural information. */", file=f)
266 for c in filter(info, components):
267 print(f" {c.type} {c.name};", file=f)
269 print(" /* target specific vector. */", file=f)
270 print(" struct gdbarch_tdep *tdep;", file=f)
271 print(" gdbarch_dump_tdep_ftype *dump_tdep;", file=f)
273 print(" /* per-architecture data-pointers. */", file=f)
274 print(" unsigned nr_data;", file=f)
275 print(" void **data;", file=f)
277 for c in filter(not_info, components):
278 if isinstance(c, Value):
279 print(f" {c.type} {c.name};", file=f)
281 assert isinstance(c, Function)
282 print(f" gdbarch_{c.name}_ftype *{c.name};", file=f)
288 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f)
289 print(" ``struct gdbarch_info''. */", file=f)
291 print("struct gdbarch *", file=f)
292 print("gdbarch_alloc (const struct gdbarch_info *info,", file=f)
293 print(" struct gdbarch_tdep *tdep)", file=f)
295 print(" struct gdbarch *gdbarch;", file=f)
298 " /* Create an obstack for allocating all the per-architecture memory,", file=f
300 print(" then use that to allocate the architecture vector. */", file=f)
301 print(" struct obstack *obstack = XNEW (struct obstack);", file=f)
302 print(" obstack_init (obstack);", file=f)
303 print(" gdbarch = XOBNEW (obstack, struct gdbarch);", file=f)
304 print(" memset (gdbarch, 0, sizeof (*gdbarch));", file=f)
305 print(" gdbarch->obstack = obstack;", file=f)
307 print(" alloc_gdbarch_data (gdbarch);", file=f)
309 print(" gdbarch->tdep = tdep;", file=f)
311 for c in filter(info, components):
312 print(f" gdbarch->{c.name} = info->{c.name};", file=f)
314 print(" /* Force the explicit initialization of these. */", file=f)
315 for c in filter(not_info, components):
316 if c.predefault and c.predefault != "0":
317 print(f" gdbarch->{c.name} = {c.predefault};", file=f)
318 print(" /* gdbarch_alloc() */", file=f)
320 print(" return gdbarch;", file=f)
326 # Post-initialization validation and updating
328 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f)
330 print("static void", file=f)
331 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f)
333 print(" string_file log;", file=f)
335 print(" /* fundamental */", file=f)
336 print(" if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)", file=f)
337 print(""" log.puts ("\\n\\tbyte-order");""", file=f)
338 print(" if (gdbarch->bfd_arch_info == NULL)", file=f)
339 print(""" log.puts ("\\n\\tbfd_arch_info");""", file=f)
341 " /* Check those that need to be defined for the given multi-arch level. */",
344 for c in filter(not_info, components):
345 if c.invalid is False:
346 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
348 print(f" /* Skip verify of {c.name}, has predicate. */", file=f)
349 elif isinstance(c.invalid, str) and c.postdefault is not None:
350 print(f" if ({c.invalid})", file=f)
351 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
352 elif c.predefault is not None and c.postdefault is not None:
353 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f)
354 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
355 elif c.postdefault is not None:
356 print(f" if (gdbarch->{c.name} == 0)", file=f)
357 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
358 elif isinstance(c.invalid, str):
359 print(f" if ({c.invalid})", file=f)
360 print(f""" log.puts ("\\n\\t{c.name}");""", file=f)
361 elif c.predefault is not None:
362 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f)
363 print(f""" log.puts ("\\n\\t{c.name}");""", file=f)
364 elif c.invalid is True:
365 print(f" if (gdbarch->{c.name} == 0)", file=f)
366 print(f""" log.puts ("\\n\\t{c.name}");""", file=f)
368 # We should not allow ourselves to simply do nothing here
369 # because no other case applies. If we end up here then
370 # either the input data needs adjusting so one of the
371 # above cases matches, or we need additional cases adding
373 raise Exception("unhandled case when generating gdbarch validation")
374 print(" if (!log.empty ())", file=f)
375 print(" internal_error (__FILE__, __LINE__,", file=f)
376 print(""" _("verify_gdbarch: the following are invalid ...%s"),""", file=f)
377 print(" log.c_str ());", file=f)
384 print("/* Print out the details of the current architecture. */", file=f)
386 print("void", file=f)
387 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f)
389 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f)
391 print("#if defined (GDB_NM_FILE)", file=f)
392 print(" gdb_nm_file = GDB_NM_FILE;", file=f)
393 print("#endif", file=f)
394 print(" gdb_printf (file,", file=f)
395 print(""" "gdbarch_dump: GDB_NM_FILE = %s\\n",""", file=f)
396 print(" gdb_nm_file);", file=f)
399 print(" gdb_printf (file,", file=f)
401 f""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
404 print(f" gdbarch_{c.name}_p (gdbarch));", file=f)
405 if isinstance(c, Function):
406 print(" gdb_printf (file,", file=f)
408 f""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f
411 f" host_address_to_string (gdbarch->{c.name}));",
417 elif c.type == "CORE_ADDR":
418 printer = f"core_addr_to_string_nz (gdbarch->{c.name})"
420 printer = f"plongest (gdbarch->{c.name})"
421 print(" gdb_printf (file,", file=f)
423 f""" "gdbarch_dump: {c.name} = %s\\n",""", file=f
425 print(f" {printer});", file=f)
426 print(" if (gdbarch->dump_tdep != NULL)", file=f)
427 print(" gdbarch->dump_tdep (gdbarch, file);", file=f)
431 # Bodies of setter, accessor, and predicate functions.
436 print("bool", file=f)
437 print(f"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f)
439 print(" gdb_assert (gdbarch != NULL);", file=f)
440 print(f" return {c.get_predicate()};", file=f)
442 if isinstance(c, Function):
444 print(f"{c.type}", file=f)
445 print(f"gdbarch_{c.name} ({c.set_list()})", file=f)
447 print(" gdb_assert (gdbarch != NULL);", file=f)
448 print(f" gdb_assert (gdbarch->{c.name} != NULL);", file=f)
449 if c.predicate and c.predefault:
450 # Allow a call to a function with a predicate.
452 f" /* Do not check predicate: {c.get_predicate()}, allow call. */",
455 print(" if (gdbarch_debug >= 2)", file=f)
457 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
460 print(" ", file=f, end="")
462 print("return ", file=f, end="")
463 print(f"gdbarch->{c.name} ({c.actuals()});", file=f)
466 print("void", file=f)
467 print(f"set_gdbarch_{c.name} (struct gdbarch *gdbarch,", file=f)
469 f" {' ' * len(c.name)} gdbarch_{c.name}_ftype {c.name})",
473 print(f" gdbarch->{c.name} = {c.name};", file=f)
475 elif isinstance(c, Value):
477 print(f"{c.type}", file=f)
478 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
480 print(" gdb_assert (gdbarch != NULL);", file=f)
481 if c.invalid is False:
482 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
483 elif isinstance(c.invalid, str):
484 print(" /* Check variable is valid. */", file=f)
485 print(f" gdb_assert (!({c.invalid}));", file=f)
487 print(" /* Check variable changed from pre-default. */", file=f)
488 print(f" gdb_assert (gdbarch->{c.name} != {c.predefault});", file=f)
489 print(" if (gdbarch_debug >= 2)", file=f)
491 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
494 print(f" return gdbarch->{c.name};", file=f)
497 print("void", file=f)
498 print(f"set_gdbarch_{c.name} (struct gdbarch *gdbarch,", file=f)
499 print(f" {' ' * len(c.name)} {c.type} {c.name})", file=f)
501 print(f" gdbarch->{c.name} = {c.name};", file=f)
504 assert isinstance(c, Info)
506 print(f"{c.type}", file=f)
507 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
509 print(" gdb_assert (gdbarch != NULL);", file=f)
510 print(" if (gdbarch_debug >= 2)", file=f)
512 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
515 print(f" return gdbarch->{c.name};", file=f)