From 43f2b4583f95775b2c0fefd71aab4c773c4f7a7e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 7 Sep 2022 08:58:18 -0600 Subject: Don't emit gdbarch_return_value The previous patch introduced a new overload of gdbarch_return_value. The intent here is that this new overload always be called by the core of gdb -- the previous implementation is effectively deprecated, because a call to the old-style method will not work with any converted architectures (whereas calling the new-style method is will delegate when needed). This patch changes gdbarch.py so that the old gdbarch_return_value wrapper function can be omitted. This will prevent any errors from creeping in. --- gdb/arch-utils.c | 36 ++++++++++++------------ gdb/gdbarch-components.py | 6 ++++ gdb/gdbarch-gen.h | 1 - gdb/gdbarch.c | 10 ------- gdb/gdbarch.py | 70 +++++++++++++++++++++++++---------------------- 5 files changed, 61 insertions(+), 62 deletions(-) diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 3ca1930..e858760 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1098,24 +1098,6 @@ default_get_return_buf_addr (struct type *val_type, frame_info_ptr cur_frame) return 0; } -enum return_value_convention -default_gdbarch_return_value - (struct gdbarch *gdbarch, struct value *function, struct type *valtype, - struct regcache *regcache, struct value **read_value, - const gdb_byte *writebuf) -{ - gdb_byte *readbuf = nullptr; - - if (read_value != nullptr) - { - *read_value = allocate_value (valtype); - readbuf = value_contents_raw (*read_value).data (); - } - - return gdbarch_return_value (gdbarch, function, valtype, regcache, - readbuf, writebuf); -} - /* Non-zero if we want to trace architecture code. */ #ifndef GDBARCH_DEBUG @@ -1186,6 +1168,24 @@ pstring_list (const char *const *list) #include "gdbarch.c" +enum return_value_convention +default_gdbarch_return_value + (struct gdbarch *gdbarch, struct value *function, struct type *valtype, + struct regcache *regcache, struct value **read_value, + const gdb_byte *writebuf) +{ + gdb_byte *readbuf = nullptr; + + if (read_value != nullptr) + { + *read_value = allocate_value (valtype); + readbuf = value_contents_raw (*read_value).data (); + } + + return gdbarch->return_value (gdbarch, function, valtype, regcache, + readbuf, writebuf); +} + obstack *gdbarch_obstack (gdbarch *arch) { return &arch->obstack; diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py index 0e1ca40..76ad283 100644 --- a/gdb/gdbarch-components.py +++ b/gdb/gdbarch-components.py @@ -113,6 +113,9 @@ # 'result' can be used to reference the result of the function/method # implementation. The 'result_checks' can only be used if the 'type' # of this Function/Method is not 'void'. +# +# * "implement" - optional, a boolean. If True (the default), a +# wrapper function for this function will be emitted. Info( type="const struct bfd_arch_info *", @@ -868,6 +871,9 @@ method can properly handle variably-sized types. ("const gdb_byte *", "writebuf"), ], invalid=False, + # We don't want to accidentally introduce calls to this, as gdb + # should only ever call return_value_new (see below). + implement=False, ) Method( diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 128efa1..32b2d96 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -439,7 +439,6 @@ extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_int method can properly handle variably-sized types. */ typedef enum return_value_convention (gdbarch_return_value_ftype) (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf); -extern enum return_value_convention gdbarch_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf); extern void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype *return_value); /* Return the return-value convention that will be used by FUNCTION diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 353040c..41b71ae 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -2571,16 +2571,6 @@ set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch->integer_to_address = integer_to_address; } -enum return_value_convention -gdbarch_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) -{ - gdb_assert (gdbarch != NULL); - gdb_assert (gdbarch->return_value != NULL); - if (gdbarch_debug >= 2) - gdb_printf (gdb_stdlog, "gdbarch_return_value called\n"); - return gdbarch->return_value (gdbarch, function, valtype, regcache, readbuf, writebuf); -} - void set_gdbarch_return_value (struct gdbarch *gdbarch, gdbarch_return_value_ftype return_value) diff --git a/gdb/gdbarch.py b/gdb/gdbarch.py index a1b665f..d2bf860 100755 --- a/gdb/gdbarch.py +++ b/gdb/gdbarch.py @@ -124,6 +124,7 @@ class Function(_Component): printer=None, param_checks=None, result_checks=None, + implement=True, ): super().__init__( comment=comment, @@ -137,6 +138,7 @@ class Function(_Component): params=params, param_checks=param_checks, result_checks=result_checks, + implement=implement, ) def ftype(self): @@ -251,10 +253,11 @@ with open("gdbarch-gen.h", "w") as f: f"typedef {c.type} ({c.ftype()}) ({c.param_list()});", file=f, ) - print( - f"extern {c.type} gdbarch_{c.name} ({c.set_list()});", - file=f, - ) + if c.implement: + print( + f"extern {c.type} gdbarch_{c.name} ({c.set_list()});", + file=f, + ) print( f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});", file=f, @@ -445,38 +448,39 @@ with open("gdbarch.c", "w") as f: print(f" return {c.get_predicate()};", file=f) print("}", file=f) if isinstance(c, Function): - print(file=f) - print(f"{c.type}", file=f) - print(f"gdbarch_{c.name} ({c.set_list()})", file=f) - print("{", file=f) - print(" gdb_assert (gdbarch != NULL);", file=f) - print(f" gdb_assert (gdbarch->{c.name} != NULL);", file=f) - if c.predicate and c.predefault: - # Allow a call to a function with a predicate. + if c.implement: + print(file=f) + print(f"{c.type}", file=f) + print(f"gdbarch_{c.name} ({c.set_list()})", file=f) + print("{", file=f) + print(" gdb_assert (gdbarch != NULL);", file=f) + print(f" gdb_assert (gdbarch->{c.name} != NULL);", file=f) + if c.predicate and c.predefault: + # Allow a call to a function with a predicate. + print( + f" /* Do not check predicate: {c.get_predicate()}, allow call. */", + file=f, + ) + if c.param_checks: + for rule in c.param_checks: + print(f" gdb_assert ({rule});", file=f) + print(" if (gdbarch_debug >= 2)", file=f) print( - f" /* Do not check predicate: {c.get_predicate()}, allow call. */", + f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", file=f, ) - if c.param_checks: - for rule in c.param_checks: - print(f" gdb_assert ({rule});", file=f) - print(" if (gdbarch_debug >= 2)", file=f) - print( - f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", - file=f, - ) - print(" ", file=f, end="") - if c.type != "void": - if c.result_checks: - print("auto result = ", file=f, end="") - else: - print("return ", file=f, end="") - print(f"gdbarch->{c.name} ({c.actuals()});", file=f) - if c.type != "void" and c.result_checks: - for rule in c.result_checks: - print(f" gdb_assert ({rule});", file=f) - print(" return result;", file=f) - print("}", file=f) + print(" ", file=f, end="") + if c.type != "void": + if c.result_checks: + print("auto result = ", file=f, end="") + else: + print("return ", file=f, end="") + print(f"gdbarch->{c.name} ({c.actuals()});", file=f) + if c.type != "void" and c.result_checks: + for rule in c.result_checks: + print(f" gdb_assert ({rule});", file=f) + print(" return result;", file=f) + print("}", file=f) print(file=f) print("void", file=f) setter_name = f"set_gdbarch_{c.name}" -- cgit v1.1