Use filtered output for gdbarch dump
[binutils-gdb.git] / gdb / gdbarch.py
1 #!/usr/bin/env python3
2
3 # Architecture commands for GDB, the GNU debugger.
4 #
5 # Copyright (C) 1998-2022 Free Software Foundation, Inc.
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
11 # the Free Software Foundation; either version 3 of the License, or
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
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 import textwrap
23
24 # All the components created in gdbarch-components.py.
25 components = []
26
27
28 def join_type_and_name(t, n):
29 "Combine the type T and the name N into a C declaration."
30 if t.endswith("*") or t.endswith("&"):
31 return t + n
32 else:
33 return t + " " + n
34
35
36 def join_params(params):
37 """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated
38 list of declarations."""
39 params = [join_type_and_name(p[0], p[1]) for p in params]
40 return ", ".join(params)
41
42
43 class _Component:
44 "Base class for all components."
45
46 def __init__(self, **kwargs):
47 for key in kwargs:
48 setattr(self, key, kwargs[key])
49 components.append(self)
50
51 def get_predicate(self):
52 "Return the expression used for validity checking."
53 assert self.predicate and not isinstance(self.invalid, str)
54 if self.predefault:
55 predicate = f"gdbarch->{self.name} != {self.predefault}"
56 elif isinstance(c, Value):
57 predicate = f"gdbarch->{self.name} != 0"
58 else:
59 predicate = f"gdbarch->{self.name} != NULL"
60 return predicate
61
62
63 class Info(_Component):
64 "An Info component is copied from the gdbarch_info."
65
66 def __init__(self, *, name, type, printer=None):
67 super().__init__(name=name, type=type, printer=printer)
68 # This little hack makes the generator a bit simpler.
69 self.predicate = None
70
71
72 class Value(_Component):
73 "A Value component is just a data member."
74
75 def __init__(
76 self,
77 *,
78 name,
79 type,
80 comment=None,
81 predicate=None,
82 predefault=None,
83 postdefault=None,
84 invalid=None,
85 printer=None,
86 ):
87 super().__init__(
88 comment=comment,
89 name=name,
90 type=type,
91 predicate=predicate,
92 predefault=predefault,
93 postdefault=postdefault,
94 invalid=invalid,
95 printer=printer,
96 )
97
98
99 class Function(_Component):
100 "A Function component is a function pointer member."
101
102 def __init__(
103 self,
104 *,
105 name,
106 type,
107 params,
108 comment=None,
109 predicate=None,
110 predefault=None,
111 postdefault=None,
112 invalid=None,
113 printer=None,
114 ):
115 super().__init__(
116 comment=comment,
117 name=name,
118 type=type,
119 predicate=predicate,
120 predefault=predefault,
121 postdefault=postdefault,
122 invalid=invalid,
123 printer=printer,
124 params=params,
125 )
126
127 def ftype(self):
128 "Return the name of the function typedef to use."
129 return f"gdbarch_{self.name}_ftype"
130
131 def param_list(self):
132 "Return the formal parameter list as a string."
133 return join_params(self.params)
134
135 def set_list(self):
136 """Return the formal parameter list of the caller function,
137 as a string. This list includes the gdbarch."""
138 arch_arg = ("struct gdbarch *", "gdbarch")
139 arch_tuple = [arch_arg]
140 return join_params(arch_tuple + list(self.params))
141
142 def actuals(self):
143 "Return the actual parameters to forward, as a string."
144 return ", ".join([p[1] for p in self.params])
145
146
147 class Method(Function):
148 "A Method is like a Function but passes the gdbarch through."
149
150 def param_list(self):
151 "See superclass."
152 return self.set_list()
153
154 def actuals(self):
155 "See superclass."
156 result = ["gdbarch"] + [p[1] for p in self.params]
157 return ", ".join(result)
158
159
160 # Read the components.
161 with open("gdbarch-components.py") as fd:
162 exec(fd.read())
163
164 copyright = """/* *INDENT-OFF* */ /* THIS FILE IS GENERATED -*- buffer-read-only: t -*- */
165 /* vi:set ro: */
166
167 /* Dynamic architecture support for GDB, the GNU debugger.
168
169 Copyright (C) 1998-2022 Free Software Foundation, Inc.
170
171 This file is part of GDB.
172
173 This program is free software; you can redistribute it and/or modify
174 it under the terms of the GNU General Public License as published by
175 the Free Software Foundation; either version 3 of the License, or
176 (at your option) any later version.
177
178 This program is distributed in the hope that it will be useful,
179 but WITHOUT ANY WARRANTY; without even the implied warranty of
180 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
181 GNU General Public License for more details.
182
183 You should have received a copy of the GNU General Public License
184 along with this program. If not, see <http://www.gnu.org/licenses/>. */
185
186 /* This file was created with the aid of ``gdbarch.py''. */
187 """
188
189
190 def info(c):
191 "Filter function to only allow Info components."
192 return type(c) is Info
193
194
195 def not_info(c):
196 "Filter function to omit Info components."
197 return type(c) is not Info
198
199
200 with open("gdbarch-gen.h", "w") as f:
201 print(copyright, file=f)
202 print(file=f)
203 print(file=f)
204 print("/* The following are pre-initialized by GDBARCH. */", file=f)
205
206 # Do Info components first.
207 for c in filter(info, components):
208 print(file=f)
209 print(
210 f"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
211 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
212 file=f,
213 )
214
215 print(file=f)
216 print(file=f)
217 print("/* The following are initialized by the target dependent code. */", file=f)
218
219 # Generate decls for accessors, setters, and predicates for all
220 # non-Info components.
221 for c in filter(not_info, components):
222 if c.comment:
223 print(file=f)
224 comment = c.comment.split("\n")
225 if comment[0] == "":
226 comment = comment[1:]
227 if comment[-1] == "":
228 comment = comment[:-1]
229 print("/* ", file=f, end="")
230 print(comment[0], file=f, end="")
231 if len(comment) > 1:
232 print(file=f)
233 print(
234 textwrap.indent("\n".join(comment[1:]), prefix=" "),
235 end="",
236 file=f,
237 )
238 print(" */", file=f)
239
240 if c.predicate:
241 print(file=f)
242 print(f"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f)
243
244 print(file=f)
245 if isinstance(c, Value):
246 print(
247 f"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
248 file=f,
249 )
250 print(
251 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
252 file=f,
253 )
254 else:
255 assert isinstance(c, Function)
256 print(
257 f"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
258 file=f,
259 )
260 print(
261 f"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
262 file=f,
263 )
264 print(
265 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
266 file=f,
267 )
268
269 with open("gdbarch.c", "w") as f:
270 print(copyright, file=f)
271 print(file=f)
272 print("/* Maintain the struct gdbarch object. */", file=f)
273 print(file=f)
274 #
275 # The struct definition body.
276 #
277 print("struct gdbarch", file=f)
278 print("{", file=f)
279 print(" /* Has this architecture been fully initialized? */", file=f)
280 print(" int initialized_p;", file=f)
281 print(file=f)
282 print(" /* An obstack bound to the lifetime of the architecture. */", file=f)
283 print(" struct obstack *obstack;", file=f)
284 print(file=f)
285 print(" /* basic architectural information. */", file=f)
286 for c in filter(info, components):
287 print(f" {c.type} {c.name};", file=f)
288 print(file=f)
289 print(" /* target specific vector. */", file=f)
290 print(" struct gdbarch_tdep *tdep;", file=f)
291 print(" gdbarch_dump_tdep_ftype *dump_tdep;", file=f)
292 print(file=f)
293 print(" /* per-architecture data-pointers. */", file=f)
294 print(" unsigned nr_data;", file=f)
295 print(" void **data;", file=f)
296 print(file=f)
297 for c in filter(not_info, components):
298 if isinstance(c, Value):
299 print(f" {c.type} {c.name};", file=f)
300 else:
301 assert isinstance(c, Function)
302 print(f" gdbarch_{c.name}_ftype *{c.name};", file=f)
303 print("};", file=f)
304 print(file=f)
305 #
306 # Initialization.
307 #
308 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f)
309 print(" ``struct gdbarch_info''. */", file=f)
310 print(file=f)
311 print("struct gdbarch *", file=f)
312 print("gdbarch_alloc (const struct gdbarch_info *info,", file=f)
313 print(" struct gdbarch_tdep *tdep)", file=f)
314 print("{", file=f)
315 print(" struct gdbarch *gdbarch;", file=f)
316 print("", file=f)
317 print(
318 " /* Create an obstack for allocating all the per-architecture memory,", file=f
319 )
320 print(" then use that to allocate the architecture vector. */", file=f)
321 print(" struct obstack *obstack = XNEW (struct obstack);", file=f)
322 print(" obstack_init (obstack);", file=f)
323 print(" gdbarch = XOBNEW (obstack, struct gdbarch);", file=f)
324 print(" memset (gdbarch, 0, sizeof (*gdbarch));", file=f)
325 print(" gdbarch->obstack = obstack;", file=f)
326 print(file=f)
327 print(" alloc_gdbarch_data (gdbarch);", file=f)
328 print(file=f)
329 print(" gdbarch->tdep = tdep;", file=f)
330 print(file=f)
331 for c in filter(info, components):
332 print(f" gdbarch->{c.name} = info->{c.name};", file=f)
333 print(file=f)
334 print(" /* Force the explicit initialization of these. */", file=f)
335 for c in filter(not_info, components):
336 if c.predefault and c.predefault != "0":
337 print(f" gdbarch->{c.name} = {c.predefault};", file=f)
338 print(" /* gdbarch_alloc() */", file=f)
339 print(file=f)
340 print(" return gdbarch;", file=f)
341 print("}", file=f)
342 print(file=f)
343 print(file=f)
344 print(file=f)
345 #
346 # Post-initialization validation and updating
347 #
348 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f)
349 print(file=f)
350 print("static void", file=f)
351 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f)
352 print("{", file=f)
353 print(" string_file log;", file=f)
354 print(file=f)
355 print(" /* fundamental */", file=f)
356 print(" if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)", file=f)
357 print(""" log.puts ("\\n\\tbyte-order");""", file=f)
358 print(" if (gdbarch->bfd_arch_info == NULL)", file=f)
359 print(""" log.puts ("\\n\\tbfd_arch_info");""", file=f)
360 print(
361 " /* Check those that need to be defined for the given multi-arch level. */",
362 file=f,
363 )
364 for c in filter(not_info, components):
365 if c.invalid is False:
366 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
367 elif c.predicate:
368 print(f" /* Skip verify of {c.name}, has predicate. */", file=f)
369 elif isinstance(c.invalid, str) and c.postdefault is not None:
370 print(f" if ({c.invalid})", file=f)
371 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
372 elif c.predefault is not None and c.postdefault is not None:
373 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f)
374 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
375 elif c.postdefault is not None:
376 print(f" if (gdbarch->{c.name} == 0)", file=f)
377 print(f" gdbarch->{c.name} = {c.postdefault};", file=f)
378 elif isinstance(c.invalid, str):
379 print(f" if ({c.invalid})", file=f)
380 print(f""" log.puts ("\\n\\t{c.name}");""", file=f)
381 elif c.predefault is not None:
382 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f)
383 print(f""" log.puts ("\\n\\t{c.name}");""", file=f)
384 print(" if (!log.empty ())", file=f)
385 print(" internal_error (__FILE__, __LINE__,", file=f)
386 print(""" _("verify_gdbarch: the following are invalid ...%s"),""", file=f)
387 print(" log.c_str ());", file=f)
388 print("}", file=f)
389 print(file=f)
390 print(file=f)
391 #
392 # Dumping.
393 #
394 print("/* Print out the details of the current architecture. */", file=f)
395 print(file=f)
396 print("void", file=f)
397 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f)
398 print("{", file=f)
399 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f)
400 print(file=f)
401 print("#if defined (GDB_NM_FILE)", file=f)
402 print(" gdb_nm_file = GDB_NM_FILE;", file=f)
403 print("#endif", file=f)
404 print(" fprintf_filtered (file,", file=f)
405 print(""" "gdbarch_dump: GDB_NM_FILE = %s\\n",""", file=f)
406 print(" gdb_nm_file);", file=f)
407 for c in components:
408 if c.predicate:
409 print(" fprintf_filtered (file,", file=f)
410 print(
411 f""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
412 file=f,
413 )
414 print(f" gdbarch_{c.name}_p (gdbarch));", file=f)
415 if isinstance(c, Function):
416 print(" fprintf_filtered (file,", file=f)
417 print(
418 f""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f
419 )
420 print(
421 f" host_address_to_string (gdbarch->{c.name}));",
422 file=f,
423 )
424 else:
425 if c.printer:
426 printer = c.printer
427 elif c.type == "CORE_ADDR":
428 printer = f"core_addr_to_string_nz (gdbarch->{c.name})"
429 else:
430 printer = f"plongest (gdbarch->{c.name})"
431 print(" fprintf_filtered (file,", file=f)
432 print(
433 f""" "gdbarch_dump: {c.name} = %s\\n",""", file=f
434 )
435 print(f" {printer});", file=f)
436 print(" if (gdbarch->dump_tdep != NULL)", file=f)
437 print(" gdbarch->dump_tdep (gdbarch, file);", file=f)
438 print("}", file=f)
439 print(file=f)
440 #
441 # Bodies of setter, accessor, and predicate functions.
442 #
443 for c in components:
444 if c.predicate:
445 print(file=f)
446 print("bool", file=f)
447 print(f"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f)
448 print("{", file=f)
449 print(" gdb_assert (gdbarch != NULL);", file=f)
450 print(f" return {c.get_predicate()};", file=f)
451 print("}", file=f)
452 if isinstance(c, Function):
453 print(file=f)
454 print(f"{c.type}", file=f)
455 print(f"gdbarch_{c.name} ({c.set_list()})", file=f)
456 print("{", file=f)
457 print(" gdb_assert (gdbarch != NULL);", file=f)
458 print(f" gdb_assert (gdbarch->{c.name} != NULL);", file=f)
459 if c.predicate and c.predefault:
460 # Allow a call to a function with a predicate.
461 print(
462 f" /* Do not check predicate: {c.get_predicate()}, allow call. */",
463 file=f,
464 )
465 print(" if (gdbarch_debug >= 2)", file=f)
466 print(
467 f""" fprintf_unfiltered (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
468 file=f,
469 )
470 print(" ", file=f, end="")
471 if c.type != "void":
472 print("return ", file=f, end="")
473 print(f"gdbarch->{c.name} ({c.actuals()});", file=f)
474 print("}", file=f)
475 print(file=f)
476 print("void", file=f)
477 print(f"set_gdbarch_{c.name} (struct gdbarch *gdbarch,", file=f)
478 print(
479 f" {' ' * len(c.name)} gdbarch_{c.name}_ftype {c.name})",
480 file=f,
481 )
482 print("{", file=f)
483 print(f" gdbarch->{c.name} = {c.name};", file=f)
484 print("}", file=f)
485 elif isinstance(c, Value):
486 print(file=f)
487 print(f"{c.type}", file=f)
488 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
489 print("{", file=f)
490 print(" gdb_assert (gdbarch != NULL);", file=f)
491 if c.invalid is False:
492 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
493 elif isinstance(c.invalid, str):
494 print(" /* Check variable is valid. */", file=f)
495 print(f" gdb_assert (!({c.invalid}));", file=f)
496 elif c.predefault:
497 print(" /* Check variable changed from pre-default. */", file=f)
498 print(f" gdb_assert (gdbarch->{c.name} != {c.predefault});", file=f)
499 print(" if (gdbarch_debug >= 2)", file=f)
500 print(
501 f""" fprintf_unfiltered (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
502 file=f,
503 )
504 print(f" return gdbarch->{c.name};", file=f)
505 print("}", file=f)
506 print(file=f)
507 print("void", file=f)
508 print(f"set_gdbarch_{c.name} (struct gdbarch *gdbarch,", file=f)
509 print(f" {' ' * len(c.name)} {c.type} {c.name})", file=f)
510 print("{", file=f)
511 print(f" gdbarch->{c.name} = {c.name};", file=f)
512 print("}", file=f)
513 else:
514 assert isinstance(c, Info)
515 print(file=f)
516 print(f"{c.type}", file=f)
517 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
518 print("{", file=f)
519 print(" gdb_assert (gdbarch != NULL);", file=f)
520 print(" if (gdbarch_debug >= 2)", file=f)
521 print(
522 f""" fprintf_unfiltered (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
523 file=f,
524 )
525 print(f" return gdbarch->{c.name};", file=f)
526 print("}", file=f)