]> Git Repo - binutils.git/blob - gdb/gdbarch.py
gdb: remove SYMBOL_CLASS macro, add getter
[binutils.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)
This page took 0.056953 seconds and 4 git commands to generate.