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