aboutsummaryrefslogtreecommitdiff
path: root/gdb/loongarch-tdep.c
diff options
context:
space:
mode:
authorTiezhu Yang <yangtiezhu@loongson.cn>2022-05-09 16:26:47 +0800
committerTiezhu Yang <yangtiezhu@loongson.cn>2022-05-09 22:33:44 +0800
commit0b8c95579f78b352cd48cc14e48ea842c64a7a5a (patch)
treee0825b28a90d0ea6d5db0d732c794ac93b1d5cc4 /gdb/loongarch-tdep.c
parent205d0542821c91e04e0ed174d8862f486a076950 (diff)
downloadgdb-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.c33
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);