]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbarch.py
Update copyright year range in header of all files managed by GDB
[thirdparty/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-2023 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 import gdbcopyright
24
25 # All the components created in gdbarch-components.py.
26 components = []
27
28
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)
32
33
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("&"):
37 return t + n
38 else:
39 return t + " " + n
40
41
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)
47
48
49 class _Component:
50 "Base class for all components."
51
52 def __init__(self, **kwargs):
53 for key in kwargs:
54 setattr(self, key, kwargs[key])
55 components.append(self)
56
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")
61
62 def get_predicate(self):
63 "Return the expression used for validity checking."
64 assert self.predicate and not isinstance(self.invalid, str)
65 if self.predefault:
66 predicate = f"gdbarch->{self.name} != {self.predefault}"
67 elif isinstance(c, Value):
68 predicate = f"gdbarch->{self.name} != 0"
69 else:
70 predicate = f"gdbarch->{self.name} != NULL"
71 return predicate
72
73
74 class Info(_Component):
75 "An Info component is copied from the gdbarch_info."
76
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.
80 self.predicate = None
81
82
83 class Value(_Component):
84 "A Value component is just a data member."
85
86 def __init__(
87 self,
88 *,
89 name,
90 type,
91 comment=None,
92 predicate=None,
93 predefault=None,
94 postdefault=None,
95 invalid=None,
96 printer=None,
97 ):
98 super().__init__(
99 comment=comment,
100 name=name,
101 type=type,
102 predicate=predicate,
103 predefault=predefault,
104 postdefault=postdefault,
105 invalid=invalid,
106 printer=printer,
107 )
108
109
110 class Function(_Component):
111 "A Function component is a function pointer member."
112
113 def __init__(
114 self,
115 *,
116 name,
117 type,
118 params,
119 comment=None,
120 predicate=None,
121 predefault=None,
122 postdefault=None,
123 invalid=None,
124 printer=None,
125 param_checks=None,
126 result_checks=None,
127 ):
128 super().__init__(
129 comment=comment,
130 name=name,
131 type=type,
132 predicate=predicate,
133 predefault=predefault,
134 postdefault=postdefault,
135 invalid=invalid,
136 printer=printer,
137 params=params,
138 param_checks=param_checks,
139 result_checks=result_checks,
140 )
141
142 def ftype(self):
143 "Return the name of the function typedef to use."
144 return f"gdbarch_{self.name}_ftype"
145
146 def param_list(self):
147 "Return the formal parameter list as a string."
148 return join_params(self.params)
149
150 def set_list(self):
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))
156
157 def actuals(self):
158 "Return the actual parameters to forward, as a string."
159 return ", ".join([p[1] for p in self.params])
160
161
162 class Method(Function):
163 "A Method is like a Function but passes the gdbarch through."
164
165 def param_list(self):
166 "See superclass."
167 return self.set_list()
168
169 def actuals(self):
170 "See superclass."
171 result = ["gdbarch"] + [p[1] for p in self.params]
172 return ", ".join(result)
173
174
175 # Read the components.
176 with open("gdbarch-components.py") as fd:
177 exec(fd.read())
178
179 copyright = gdbcopyright.copyright(
180 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger."
181 )
182
183
184 def info(c):
185 "Filter function to only allow Info components."
186 return type(c) is Info
187
188
189 def not_info(c):
190 "Filter function to omit Info components."
191 return type(c) is not Info
192
193
194 with open("gdbarch-gen.h", "w") as f:
195 print(copyright, file=f)
196 print(file=f)
197 print(file=f)
198 print("/* The following are pre-initialized by GDBARCH. */", file=f)
199
200 # Do Info components first.
201 for c in filter(info, components):
202 print(file=f)
203 print(
204 f"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
205 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
206 file=f,
207 )
208
209 print(file=f)
210 print(file=f)
211 print("/* The following are initialized by the target dependent code. */", file=f)
212
213 # Generate decls for accessors, setters, and predicates for all
214 # non-Info components.
215 for c in filter(not_info, components):
216 if c.comment:
217 print(file=f)
218 comment = c.comment.split("\n")
219 if comment[0] == "":
220 comment = comment[1:]
221 if comment[-1] == "":
222 comment = comment[:-1]
223 print("/* ", file=f, end="")
224 print(comment[0], file=f, end="")
225 if len(comment) > 1:
226 print(file=f)
227 print(
228 textwrap.indent("\n".join(comment[1:]), prefix=" "),
229 end="",
230 file=f,
231 )
232 print(" */", file=f)
233
234 if c.predicate:
235 print(file=f)
236 print(f"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f)
237
238 print(file=f)
239 if isinstance(c, Value):
240 print(
241 f"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
242 file=f,
243 )
244 print(
245 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
246 file=f,
247 )
248 else:
249 assert isinstance(c, Function)
250 print(
251 f"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
252 file=f,
253 )
254 print(
255 f"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
256 file=f,
257 )
258 print(
259 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
260 file=f,
261 )
262
263 with open("gdbarch.c", "w") as f:
264 print(copyright, file=f)
265 print(file=f)
266 print("/* Maintain the struct gdbarch object. */", file=f)
267 print(file=f)
268 #
269 # The struct definition body.
270 #
271 print("struct gdbarch", file=f)
272 print("{", file=f)
273 print(" /* Has this architecture been fully initialized? */", file=f)
274 print(" bool initialized_p = false;", file=f)
275 print(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)
280 print(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)
284 print(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)
288 print(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)
292 print(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="")
296 else:
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):
302 print("0;", file=f)
303 else:
304 assert isinstance(c, Function)
305 print("nullptr;", file=f)
306 print("};", file=f)
307 print(file=f)
308 #
309 # Initialization.
310 #
311 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f)
312 print(" ``struct gdbarch_info''. */", file=f)
313 print(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)
317 print("{", file=f)
318 print(" struct gdbarch *gdbarch;", file=f)
319 print("", file=f)
320 print(" gdbarch = new struct gdbarch;", file=f)
321 print(file=f)
322 print(" gdbarch->tdep = tdep;", file=f)
323 print(file=f)
324 for c in filter(info, components):
325 print(f" gdbarch->{c.name} = info->{c.name};", file=f)
326 print(file=f)
327 print(" return gdbarch;", file=f)
328 print("}", file=f)
329 print(file=f)
330 print(file=f)
331 print(file=f)
332 #
333 # Post-initialization validation and updating
334 #
335 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f)
336 print(file=f)
337 print("static void", file=f)
338 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f)
339 print("{", file=f)
340 print(" string_file log;", file=f)
341 print(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)
347 print(
348 " /* Check those that need to be defined for the given multi-arch level. */",
349 file=f,
350 )
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)
354 elif c.predicate:
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)
374 else:
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
379 # here.
380 raise Exception("unhandled case when generating gdbarch validation")
381 print(" if (!log.empty ())", file=f)
382 print(
383 """ internal_error (_("verify_gdbarch: the following are invalid ...%s"),""",
384 file=f,
385 )
386 print(" log.c_str ());", file=f)
387 print("}", file=f)
388 print(file=f)
389 print(file=f)
390 #
391 # Dumping.
392 #
393 print("/* Print out the details of the current architecture. */", file=f)
394 print(file=f)
395 print("void", file=f)
396 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f)
397 print("{", file=f)
398 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f)
399 print(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)
406 for c in components:
407 if c.predicate:
408 print(" gdb_printf (file,", file=f)
409 print(
410 f""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
411 file=f,
412 )
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)
417 print(
418 f" host_address_to_string (gdbarch->{c.name}));",
419 file=f,
420 )
421 else:
422 if c.printer:
423 printer = c.printer
424 elif c.type == "CORE_ADDR":
425 printer = f"core_addr_to_string_nz (gdbarch->{c.name})"
426 else:
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)
433 print("}", file=f)
434 print(file=f)
435 #
436 # Bodies of setter, accessor, and predicate functions.
437 #
438 for c in components:
439 if c.predicate:
440 print(file=f)
441 print("bool", file=f)
442 print(f"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f)
443 print("{", file=f)
444 print(" gdb_assert (gdbarch != NULL);", file=f)
445 print(f" return {c.get_predicate()};", file=f)
446 print("}", file=f)
447 if isinstance(c, Function):
448 print(file=f)
449 print(f"{c.type}", file=f)
450 print(f"gdbarch_{c.name} ({c.set_list()})", file=f)
451 print("{", 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.
456 print(
457 f" /* Do not check predicate: {c.get_predicate()}, allow call. */",
458 file=f,
459 )
460 if c.param_checks:
461 for rule in c.param_checks:
462 print(f" gdb_assert ({rule});", file=f)
463 print(" if (gdbarch_debug >= 2)", file=f)
464 print(
465 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
466 file=f,
467 )
468 print(" ", file=f, end="")
469 if c.type != "void":
470 if c.result_checks:
471 print("auto result = ", file=f, end="")
472 else:
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)
479 print("}", file=f)
480 print(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)
487 print("{", file=f)
488 print(f" gdbarch->{c.name} = {c.name};", file=f)
489 print("}", file=f)
490 elif isinstance(c, Value):
491 print(file=f)
492 print(f"{c.type}", file=f)
493 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
494 print("{", 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)
501 elif c.predefault:
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)
505 print(
506 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
507 file=f,
508 )
509 print(f" return gdbarch->{c.name};", file=f)
510 print("}", file=f)
511 print(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)
517 print("{", file=f)
518 print(f" gdbarch->{c.name} = {c.name};", file=f)
519 print("}", file=f)
520 else:
521 assert isinstance(c, Info)
522 print(file=f)
523 print(f"{c.type}", file=f)
524 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
525 print("{", file=f)
526 print(" gdb_assert (gdbarch != NULL);", file=f)
527 print(" if (gdbarch_debug >= 2)", file=f)
528 print(
529 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
530 file=f,
531 )
532 print(f" return gdbarch->{c.name};", file=f)
533 print("}", file=f)