diff options
author | Tiezhu Yang <yangtiezhu@loongson.cn> | 2022-05-09 16:26:47 +0800 |
---|---|---|
committer | Tiezhu Yang <yangtiezhu@loongson.cn> | 2022-05-09 22:33:44 +0800 |
commit | 0b8c95579f78b352cd48cc14e48ea842c64a7a5a (patch) | |
tree | e0825b28a90d0ea6d5db0d732c794ac93b1d5cc4 /gdb/loongarch-tdep.c | |
parent | 205d0542821c91e04e0ed174d8862f486a076950 (diff) | |
download | gdb-0b8c95579f78b352cd48cc14e48ea842c64a7a5a.zip gdb-0b8c95579f78b352cd48cc14e48ea842c64a7a5a.tar.gz gdb-0b8c95579f78b352cd48cc14e48ea842c64a7a5a.tar.bz2 |
gdb: LoongArch: Implement the return_value gdbarch method
When execute the following command on LoongArch:
make check-gdb TESTS="gdb.base/async.exp"
there exist the following failed testcases:
FAIL: gdb.base/async.exp: finish& (timeout)
FAIL: gdb.base/async.exp: jump& (timeout)
FAIL: gdb.base/async.exp: until& (timeout)
FAIL: gdb.base/async.exp: set exec-done-display off (GDB internal error)
we can see the following messages in gdb/testsuite/gdb.log:
finish&
Run till exit from #0 foo () at /home/loongson/gdb.git/gdb/testsuite/gdb.base/async.c:9
(gdb) /home/loongson/gdb.git/gdb/gdbarch.c:2646: internal-error: gdbarch_return_value: Assertion `gdbarch->return_value != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
In order to fix the above failed testcases, implement the return_value
gdbarch method on LoongArch.
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Diffstat (limited to 'gdb/loongarch-tdep.c')
-rw-r--r-- | gdb/loongarch-tdep.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index e30ef80..28f0409 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -247,6 +247,36 @@ static const struct frame_unwind loongarch_frame_unwind = { /*.prev_arch =*/nullptr, }; +/* Implement the return_value gdbarch method for LoongArch. */ + +static enum return_value_convention +loongarch_return_value (struct gdbarch *gdbarch, struct value *function, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch); + auto regs = tdep->regs; + int len = TYPE_LENGTH (type); + int regnum = -1; + + /* See if our value is returned through a register. If it is, then + store the associated register number in REGNUM. */ + switch (type->code ()) + { + case TYPE_CODE_INT: + regnum = regs.r + 4; + break; + } + + /* Extract the return value from the register where it was stored. */ + if (readbuf) + regcache->raw_read_part (regnum, 0, len, readbuf); + if (writebuf) + regcache->raw_write_part (regnum, 0, len, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */ static int @@ -418,6 +448,9 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Finalise the target description registers. */ tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data)); + /* Return value info */ + set_gdbarch_return_value (gdbarch, loongarch_return_value); + /* Advance PC across function entry code. */ set_gdbarch_skip_prologue (gdbarch, loongarch_skip_prologue); |