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.
This commit is contained in:
Tom Tromey 2022-09-07 08:58:18 -06:00
parent 4e1d2f5814
commit 43f2b4583f
5 changed files with 61 additions and 62 deletions

View File

@ -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;

View File

@ -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(

View File

@ -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

View File

@ -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)

View File

@ -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}"