new port, Value Returned
Florent DEFAY
spira.inhabitant@gmail.com
Thu Jun 4 12:50:00 GMT 2009
Hi,
I am still working on a new port of GDB.
Most functionality works. I am currently working on 'finish' which
prints the value returned.
The target is 16 bit and
int = 16 bits,
long = 32 bits,
long long = 64 bits.
The value is right in the case of int and long.
int: the value is returned in R0
long: the value is returned in R0 and R1
The problem comes with long long, in this case the value is returned
by reference,
then in the function return_value I return RETURN_VALUE_STRUCT_CONVENTION
for this case. But when I run GDB on an appropriate example, here is
the result :
_______________________________________________________________
Breakpoint 2, b2 (a=123000000, b=456000) at main.c:17
17 long long v = 789;
(gdb) finish
Run till exit from #0 b2 (a=123000000, b=456000) at main.c:17
0x000002c2 in main () at main.c:71
71 ll = b2 (123000000, 456000);
Value returned has type: long long int. Cannot determine contents
_______________________________________________________________
Please, have you a piece of explanation for me?
Regards.
Florent
Here is the source of my function return_value:
_______________________________________________________________
static enum return_value_convention
target_return_value (struct gdbarch *gdbarch,
struct type *func_type,
struct type *type,
struct regcache *regcache,
gdb_byte *readbuf,
const gdb_byte *writebuf)
{
enum type_code rv_type = TYPE_CODE (type);
unsigned int rv_size = TYPE_LENGTH (type);
ULONGEST tmp, tmp2;
fprintf_unfiltered (gdb_stderr, "[ %s ]\n", __func__);
if((TYPE_CODE_STRUCT == rv_type) ||
(TYPE_CODE_UNION == rv_type) ||
(rv_size > 4))
{
if (readbuf)
{
fprintf_unfiltered (gdb_stderr, "[ %s ] readbuf struct\n", __func__);
regcache_cooked_read_unsigned (regcache, TARGET_R0_REGNUM, &tmp);
read_memory (tmp, readbuf, rv_size);
}
if (writebuf)
{
fprintf_unfiltered (gdb_stderr, "[ %s ] writebuf struct\n", __func__);
regcache_cooked_read_unsigned (regcache, TARGET_R0_REGNUM, &tmp);
write_memory (tmp, writebuf, rv_size);
}
return RETURN_VALUE_STRUCT_CONVENTION;
}
/* 1-4 byte scalars are returned in R0:R1 */
if (readbuf)
{
regcache_cooked_read_unsigned (regcache, TARGET_R0_REGNUM, &tmp);
regcache_cooked_read_unsigned (regcache, TARGET_R1_REGNUM, &tmp2);
if (rv_size <= 2)
{
store_unsigned_integer (readbuf, rv_size, tmp);
}
else if (rv_size <= 4)
{
store_unsigned_integer (readbuf, rv_size, tmp2 + (tmp << 16));
}
}
if (writebuf)
{
gdb_byte buf[4];
fprintf_unfiltered (gdb_stderr, "[ %s ] writebuf\n", __func__);
memset (buf, 0, sizeof (buf)); /* Pad with zeros if < 4 bytes */
memcpy (buf + sizeof (buf) - rv_size, writebuf, rv_size);
regcache_cooked_write (regcache, TARGET_R0_REGNUM, buf);
regcache_cooked_write (regcache, TARGET_R1_REGNUM, buf + 2);
}
return RETURN_VALUE_REGISTER_CONVENTION;
} /* target_return_value() */
More information about the Gdb
mailing list