gdb: Add maint set ignore-prologue-end-flag
[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 import gdbcopyright
24
25 # All the components created in gdbarch-components.py.
26 components = []
27
28
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("&"):
32 return t + n
33 else:
34 return t + " " + n
35
36
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)
42
43
44 class _Component:
45 "Base class for all components."
46
47 def __init__(self, **kwargs):
48 for key in kwargs:
49 setattr(self, key, kwargs[key])
50 components.append(self)
51
52 def get_predicate(self):
53 "Return the expression used for validity checking."
54 assert self.predicate and not isinstance(self.invalid, str)
55 if self.predefault:
56 predicate = f"gdbarch->{self.name} != {self.predefault}"
57 elif isinstance(c, Value):
58 predicate = f"gdbarch->{self.name} != 0"
59 else:
60 predicate = f"gdbarch->{self.name} != NULL"
61 return predicate
62
63
64 class Info(_Component):
65 "An Info component is copied from the gdbarch_info."
66
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.
70 self.predicate = None
71
72
73 class Value(_Component):
74 "A Value component is just a data member."
75
76 def __init__(
77 self,
78 *,
79 name,
80 type,
81 comment=None,
82 predicate=None,
83 predefault=None,
84 postdefault=None,
85 invalid=None,
86 printer=None,
87 ):
88 super().__init__(
89 comment=comment,
90 name=name,
91 type=type,
92 predicate=predicate,
93 predefault=predefault,
94 postdefault=postdefault,
95 invalid=invalid,
96 printer=printer,
97 )
98
99
100 class Function(_Component):
101 "A Function component is a function pointer member."
102
103 def __init__(
104 self,
105 *,
106 name,
107 type,
108 params,
109 comment=None,
110 predicate=None,
111 predefault=None,
112 postdefault=None,
113 invalid=None,
114 printer=None,
115 ):
116 super().__init__(
117 comment=comment,
118 name=name,
119 type=type,
120 predicate=predicate,
121 predefault=predefault,
122 postdefault=postdefault,
123 invalid=invalid,
124 printer=printer,
125 params=params,
126 )
127
128 def ftype(self):
129 "Return the name of the function typedef to use."
130 return f"gdbarch_{self.name}_ftype"
131
132 def param_list(self):
133 "Return the formal parameter list as a string."
134 return join_params(self.params)
135
136 def set_list(self):
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))
142
143 def actuals(self):
144 "Return the actual parameters to forward, as a string."
145 return ", ".join([p[1] for p in self.params])
146
147
148 class Method(Function):
149 "A Method is like a Function but passes the gdbarch through."
150
151 def param_list(self):
152 "See superclass."
153 return self.set_list()
154
155 def actuals(self):
156 "See superclass."
157 result = ["gdbarch"] + [p[1] for p in self.params]
158 return ", ".join(result)
159
160
161 # Read the components.
162 with open("gdbarch-components.py") as fd:
163 exec(fd.read())
164
165 copyright = gdbcopyright.copyright(
166 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger."
167 )
168
169
170 def info(c):
171 "Filter function to only allow Info components."
172 return type(c) is Info
173
174
175 def not_info(c):
176 "Filter function to omit Info components."
177 return type(c) is not Info
178
179
180 with open("gdbarch-gen.h", "w") as f:
181 print(copyright, file=f)
182 print(file=f)
183 print(file=f)
184 print("/* The following are pre-initialized by GDBARCH. */", file=f)
185
186 # Do Info components first.
187 for c in filter(info, components):
188 print(file=f)
189 print(
190 f"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);
191 /* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""",
192 file=f,
193 )
194
195 print(file=f)
196 print(file=f)
197 print("/* The following are initialized by the target dependent code. */", file=f)
198
199 # Generate decls for accessors, setters, and predicates for all
200 # non-Info components.
201 for c in filter(not_info, components):
202 if c.comment:
203 print(file=f)
204 comment = c.comment.split("\n")
205 if comment[0] == "":
206 comment = comment[1:]
207 if comment[-1] == "":
208 comment = comment[:-1]
209 print("/* ", file=f, end="")
210 print(comment[0], file=f, end="")
211 if len(comment) > 1:
212 print(file=f)
213 print(
214 textwrap.indent("\n".join(comment[1:]), prefix=" "),
215 end="",
216 file=f,
217 )
218 print(" */", file=f)
219
220 if c.predicate:
221 print(file=f)
222 print(f"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f)
223
224 print(file=f)
225 if isinstance(c, Value):
226 print(
227 f"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);",
228 file=f,
229 )
230 print(
231 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});",
232 file=f,
233 )
234 else:
235 assert isinstance(c, Function)
236 print(
237 f"typedef {c.type} ({c.ftype()}) ({c.param_list()});",
238 file=f,
239 )
240 print(
241 f"extern {c.type} gdbarch_{c.name} ({c.set_list()});",
242 file=f,
243 )
244 print(
245 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});",
246 file=f,
247 )
248
249 with open("gdbarch.c", "w") as f:
250 print(copyright, file=f)
251 print(file=f)
252 print("/* Maintain the struct gdbarch object. */", file=f)
253 print(file=f)
254 #
255 # The struct definition body.
256 #
257 print("struct gdbarch", file=f)
258 print("{", file=f)
259 print(" /* Has this architecture been fully initialized? */", file=f)
260 print(" int initialized_p;", file=f)
261 print(file=f)
262 print(" /* An obstack bound to the lifetime of the architecture. */", file=f)
263 print(" struct obstack *obstack;", file=f)
264 print(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)
268 print(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)
272 print(file=f)
273 print(" /* per-architecture data-pointers. */", file=f)
274 print(" unsigned nr_data;", file=f)
275 print(" void **data;", file=f)
276 print(file=f)
277 for c in filter(not_info, components):
278 if isinstance(c, Value):
279 print(f" {c.type} {c.name};", file=f)
280 else:
281 assert isinstance(c, Function)
282 print(f" gdbarch_{c.name}_ftype *{c.name};", file=f)
283 print("};", file=f)
284 print(file=f)
285 #
286 # Initialization.
287 #
288 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f)
289 print(" ``struct gdbarch_info''. */", file=f)
290 print(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)
294 print("{", file=f)
295 print(" struct gdbarch *gdbarch;", file=f)
296 print("", file=f)
297 print(
298 " /* Create an obstack for allocating all the per-architecture memory,", file=f
299 )
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)
306 print(file=f)
307 print(" alloc_gdbarch_data (gdbarch);", file=f)
308 print(file=f)
309 print(" gdbarch->tdep = tdep;", file=f)
310 print(file=f)
311 for c in filter(info, components):
312 print(f" gdbarch->{c.name} = info->{c.name};", file=f)
313 print(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)
319 print(file=f)
320 print(" return gdbarch;", file=f)
321 print("}", file=f)
322 print(file=f)
323 print(file=f)
324 print(file=f)
325 #
326 # Post-initialization validation and updating
327 #
328 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f)
329 print(file=f)
330 print("static void", file=f)
331 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f)
332 print("{", file=f)
333 print(" string_file log;", file=f)
334 print(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)
340 print(
341 " /* Check those that need to be defined for the given multi-arch level. */",
342 file=f,
343 )
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)
347 elif c.predicate:
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)
367 else:
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
372 # here.
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)
378 print("}", file=f)
379 print(file=f)
380 print(file=f)
381 #
382 # Dumping.
383 #
384 print("/* Print out the details of the current architecture. */", file=f)
385 print(file=f)
386 print("void", file=f)
387 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f)
388 print("{", file=f)
389 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f)
390 print(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)
397 for c in components:
398 if c.predicate:
399 print(" gdb_printf (file,", file=f)
400 print(
401 f""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""",
402 file=f,
403 )
404 print(f" gdbarch_{c.name}_p (gdbarch));", file=f)
405 if isinstance(c, Function):
406 print(" gdb_printf (file,", file=f)
407 print(
408 f""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f
409 )
410 print(
411 f" host_address_to_string (gdbarch->{c.name}));",
412 file=f,
413 )
414 else:
415 if c.printer:
416 printer = c.printer
417 elif c.type == "CORE_ADDR":
418 printer = f"core_addr_to_string_nz (gdbarch->{c.name})"
419 else:
420 printer = f"plongest (gdbarch->{c.name})"
421 print(" gdb_printf (file,", file=f)
422 print(
423 f""" "gdbarch_dump: {c.name} = %s\\n",""", file=f
424 )
425 print(f" {printer});", file=f)
426 print(" if (gdbarch->dump_tdep != NULL)", file=f)
427 print(" gdbarch->dump_tdep (gdbarch, file);", file=f)
428 print("}", file=f)
429 print(file=f)
430 #
431 # Bodies of setter, accessor, and predicate functions.
432 #
433 for c in components:
434 if c.predicate:
435 print(file=f)
436 print("bool", file=f)
437 print(f"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f)
438 print("{", file=f)
439 print(" gdb_assert (gdbarch != NULL);", file=f)
440 print(f" return {c.get_predicate()};", file=f)
441 print("}", file=f)
442 if isinstance(c, Function):
443 print(file=f)
444 print(f"{c.type}", file=f)
445 print(f"gdbarch_{c.name} ({c.set_list()})", file=f)
446 print("{", 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.
451 print(
452 f" /* Do not check predicate: {c.get_predicate()}, allow call. */",
453 file=f,
454 )
455 print(" if (gdbarch_debug >= 2)", file=f)
456 print(
457 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
458 file=f,
459 )
460 print(" ", file=f, end="")
461 if c.type != "void":
462 print("return ", file=f, end="")
463 print(f"gdbarch->{c.name} ({c.actuals()});", file=f)
464 print("}", file=f)
465 print(file=f)
466 print("void", file=f)
467 print(f"set_gdbarch_{c.name} (struct gdbarch *gdbarch,", file=f)
468 print(
469 f" {' ' * len(c.name)} gdbarch_{c.name}_ftype {c.name})",
470 file=f,
471 )
472 print("{", file=f)
473 print(f" gdbarch->{c.name} = {c.name};", file=f)
474 print("}", file=f)
475 elif isinstance(c, Value):
476 print(file=f)
477 print(f"{c.type}", file=f)
478 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
479 print("{", 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)
486 elif c.predefault:
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)
490 print(
491 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
492 file=f,
493 )
494 print(f" return gdbarch->{c.name};", file=f)
495 print("}", file=f)
496 print(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)
500 print("{", file=f)
501 print(f" gdbarch->{c.name} = {c.name};", file=f)
502 print("}", file=f)
503 else:
504 assert isinstance(c, Info)
505 print(file=f)
506 print(f"{c.type}", file=f)
507 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f)
508 print("{", file=f)
509 print(" gdb_assert (gdbarch != NULL);", file=f)
510 print(" if (gdbarch_debug >= 2)", file=f)
511 print(
512 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""",
513 file=f,
514 )
515 print(f" return gdbarch->{c.name};", file=f)
516 print("}", file=f)