]> Git Repo - binutils.git/blob - gdb/gdbarch.py
Unify gdb printf functions
[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 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)
This page took 0.06108 seconds and 4 git commands to generate.