forked from Imagelibrary/binutils-gdb
Fix inferior calls with variably-sized return type
This patch updates the gdbarch_return_value_as_value implementations to work correctly with variably-sized return types.
This commit is contained in:
@@ -2334,6 +2334,9 @@ aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
|
|||||||
int elements;
|
int elements;
|
||||||
struct type *fundamental_type;
|
struct type *fundamental_type;
|
||||||
|
|
||||||
|
if (TYPE_HAS_DYNAMIC_LENGTH (type))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
||||||
&fundamental_type))
|
&fundamental_type))
|
||||||
{
|
{
|
||||||
@@ -2448,13 +2451,6 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
|
|||||||
struct type *valtype, struct regcache *regcache,
|
struct type *valtype, struct regcache *regcache,
|
||||||
struct value **read_value, const gdb_byte *writebuf)
|
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 ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valtype->code () == TYPE_CODE_STRUCT
|
if (valtype->code () == TYPE_CODE_STRUCT
|
||||||
|| valtype->code () == TYPE_CODE_UNION
|
|| valtype->code () == TYPE_CODE_UNION
|
||||||
|| valtype->code () == TYPE_CODE_ARRAY)
|
|| valtype->code () == TYPE_CODE_ARRAY)
|
||||||
@@ -2470,12 +2466,12 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
|
|||||||
|
|
||||||
aarch64_debug_printf ("return value in memory");
|
aarch64_debug_printf ("return value in memory");
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
|
||||||
regcache->cooked_read (AARCH64_STRUCT_RETURN_REGNUM, &addr);
|
regcache->cooked_read (AARCH64_STRUCT_RETURN_REGNUM, &addr);
|
||||||
read_memory (addr, readbuf, valtype->length ());
|
*read_value = value_at_non_lval (valtype, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||||
@@ -2485,8 +2481,12 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
|
|||||||
if (writebuf)
|
if (writebuf)
|
||||||
aarch64_store_return_value (valtype, regcache, writebuf);
|
aarch64_store_return_value (valtype, regcache, writebuf);
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value)
|
||||||
aarch64_extract_return_value (valtype, regcache, readbuf);
|
{
|
||||||
|
*read_value = allocate_value (valtype);
|
||||||
|
aarch64_extract_return_value (valtype, regcache,
|
||||||
|
value_contents_raw (*read_value).data ());
|
||||||
|
}
|
||||||
|
|
||||||
aarch64_debug_printf ("return value in registers");
|
aarch64_debug_printf ("return value in registers");
|
||||||
|
|
||||||
|
|||||||
@@ -801,13 +801,6 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
|
|
||||||
gdb_assert (!(read_value && writebuf));
|
gdb_assert (!(read_value && writebuf));
|
||||||
|
|
||||||
gdb_byte *readbuf = nullptr;
|
|
||||||
if (read_value != nullptr)
|
|
||||||
{
|
|
||||||
*read_value = allocate_value (type);
|
|
||||||
readbuf = value_contents_raw (*read_value).data ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 1. Classify the return type with the classification algorithm. */
|
/* 1. Classify the return type with the classification algorithm. */
|
||||||
amd64_classify (type, theclass);
|
amd64_classify (type, theclass);
|
||||||
|
|
||||||
@@ -824,17 +817,24 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
can always find the return value just after the function has
|
can always find the return value just after the function has
|
||||||
returned. */
|
returned. */
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
ULONGEST addr;
|
ULONGEST addr;
|
||||||
|
|
||||||
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
|
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
|
||||||
read_memory (addr, readbuf, type->length ());
|
*read_value = value_at_non_lval (type, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdb_byte *readbuf = nullptr;
|
||||||
|
if (read_value != nullptr)
|
||||||
|
{
|
||||||
|
*read_value = allocate_value (type);
|
||||||
|
readbuf = value_contents_raw (*read_value).data ();
|
||||||
|
}
|
||||||
|
|
||||||
/* 8. If the class is COMPLEX_X87, the real part of the value is
|
/* 8. If the class is COMPLEX_X87, the real part of the value is
|
||||||
returned in %st0 and the imaginary part in %st1. */
|
returned in %st0 and the imaginary part in %st1. */
|
||||||
if (theclass[0] == AMD64_COMPLEX_X87)
|
if (theclass[0] == AMD64_COMPLEX_X87)
|
||||||
|
|||||||
@@ -360,13 +360,6 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
int len = type->length ();
|
int len = type->length ();
|
||||||
int regnum = -1;
|
int regnum = -1;
|
||||||
|
|
||||||
gdb_byte *readbuf = nullptr;
|
|
||||||
if (read_value != nullptr)
|
|
||||||
{
|
|
||||||
*read_value = allocate_value (type);
|
|
||||||
readbuf = value_contents_raw (*read_value).data ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if our value is returned through a register. If it is, then
|
/* See if our value is returned through a register. If it is, then
|
||||||
store the associated register number in REGNUM. */
|
store the associated register number in REGNUM. */
|
||||||
switch (type->code ())
|
switch (type->code ())
|
||||||
@@ -401,20 +394,24 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
if (regnum < 0)
|
if (regnum < 0)
|
||||||
{
|
{
|
||||||
/* RAX contains the address where the return value has been stored. */
|
/* RAX contains the address where the return value has been stored. */
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
ULONGEST addr;
|
ULONGEST addr;
|
||||||
|
|
||||||
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
|
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
|
||||||
read_memory (addr, readbuf, type->length ());
|
*read_value = value_at_non_lval (type, addr);
|
||||||
}
|
}
|
||||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Extract the return value from the register where it was stored. */
|
/* Extract the return value from the register where it was stored. */
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
regcache->raw_read_part (regnum, 0, len, readbuf);
|
{
|
||||||
|
*read_value = allocate_value (type);
|
||||||
|
regcache->raw_read_part (regnum, 0, len,
|
||||||
|
value_contents_raw (*read_value).data ());
|
||||||
|
}
|
||||||
if (writebuf)
|
if (writebuf)
|
||||||
regcache->raw_write_part (regnum, 0, len, writebuf);
|
regcache->raw_write_part (regnum, 0, len, writebuf);
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
|
|||||||
@@ -8939,6 +8939,9 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
|
|||||||
&& TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
|
&& TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (TYPE_HAS_DYNAMIC_LENGTH (type))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (TYPE_CODE_ARRAY == code && type->is_vector ())
|
if (TYPE_CODE_ARRAY == code && type->is_vector ())
|
||||||
{
|
{
|
||||||
/* Vector values should be returned using ARM registers if they
|
/* Vector values should be returned using ARM registers if they
|
||||||
@@ -9140,13 +9143,6 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
struct type *valtype, struct regcache *regcache,
|
struct type *valtype, struct regcache *regcache,
|
||||||
struct value **read_value, const gdb_byte *writebuf)
|
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 ();
|
|
||||||
}
|
|
||||||
|
|
||||||
arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
|
arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
|
||||||
struct type *func_type = function ? value_type (function) : NULL;
|
struct type *func_type = function ? value_type (function) : NULL;
|
||||||
enum arm_vfp_cprc_base_type vfp_base_type;
|
enum arm_vfp_cprc_base_type vfp_base_type;
|
||||||
@@ -9158,6 +9154,14 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
int reg_char = arm_vfp_cprc_reg_char (vfp_base_type);
|
int reg_char = arm_vfp_cprc_reg_char (vfp_base_type);
|
||||||
int unit_length = arm_vfp_cprc_unit_length (vfp_base_type);
|
int unit_length = arm_vfp_cprc_unit_length (vfp_base_type);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
gdb_byte *readbuf = nullptr;
|
||||||
|
if (read_value != nullptr)
|
||||||
|
{
|
||||||
|
*read_value = allocate_value (valtype);
|
||||||
|
readbuf = value_contents_raw (*read_value).data ();
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < vfp_base_count; i++)
|
for (i = 0; i < vfp_base_count; i++)
|
||||||
{
|
{
|
||||||
if (reg_char == 'q')
|
if (reg_char == 'q')
|
||||||
@@ -9209,12 +9213,12 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
if (tdep->struct_return == pcc_struct_return
|
if (tdep->struct_return == pcc_struct_return
|
||||||
|| arm_return_in_memory (gdbarch, valtype))
|
|| arm_return_in_memory (gdbarch, valtype))
|
||||||
{
|
{
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
|
||||||
regcache->cooked_read (ARM_A1_REGNUM, &addr);
|
regcache->cooked_read (ARM_A1_REGNUM, &addr);
|
||||||
read_memory (addr, readbuf, valtype->length ());
|
*read_value = value_at_non_lval (valtype, addr);
|
||||||
}
|
}
|
||||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||||
}
|
}
|
||||||
@@ -9228,8 +9232,12 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
if (writebuf)
|
if (writebuf)
|
||||||
arm_store_return_value (valtype, regcache, writebuf);
|
arm_store_return_value (valtype, regcache, writebuf);
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
arm_extract_return_value (valtype, regcache, readbuf);
|
{
|
||||||
|
*read_value = allocate_value (valtype);
|
||||||
|
gdb_byte *readbuf = value_contents_raw (*read_value).data ();
|
||||||
|
arm_extract_return_value (valtype, regcache, readbuf);
|
||||||
|
}
|
||||||
|
|
||||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3006,7 +3006,8 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
|
|||||||
|
|
||||||
if (struct_convention == pcc_struct_convention
|
if (struct_convention == pcc_struct_convention
|
||||||
|| (struct_convention == default_struct_convention
|
|| (struct_convention == default_struct_convention
|
||||||
&& tdep->struct_return == pcc_struct_return))
|
&& tdep->struct_return == pcc_struct_return)
|
||||||
|
|| TYPE_HAS_DYNAMIC_LENGTH (type))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Structures consisting of a single `float', `double' or 'long
|
/* Structures consisting of a single `float', `double' or 'long
|
||||||
@@ -3034,13 +3035,6 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
{
|
{
|
||||||
enum type_code code = type->code ();
|
enum type_code code = type->code ();
|
||||||
|
|
||||||
gdb_byte *readbuf = nullptr;
|
|
||||||
if (read_value != nullptr)
|
|
||||||
{
|
|
||||||
*read_value = allocate_value (type);
|
|
||||||
readbuf = value_contents_raw (*read_value).data ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((code == TYPE_CODE_STRUCT
|
if (((code == TYPE_CODE_STRUCT
|
||||||
|| code == TYPE_CODE_UNION
|
|| code == TYPE_CODE_UNION
|
||||||
|| code == TYPE_CODE_ARRAY)
|
|| code == TYPE_CODE_ARRAY)
|
||||||
@@ -3068,12 +3062,12 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
a record, so the convention applied to records also applies
|
a record, so the convention applied to records also applies
|
||||||
to arrays. */
|
to arrays. */
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
ULONGEST addr;
|
ULONGEST addr;
|
||||||
|
|
||||||
regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
|
regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
|
||||||
read_memory (addr, readbuf, type->length ());
|
*read_value = value_at_non_lval (type, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||||
@@ -3097,8 +3091,12 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
i386_extract_return_value (gdbarch, type, regcache, readbuf);
|
{
|
||||||
|
*read_value = allocate_value (type);
|
||||||
|
i386_extract_return_value (gdbarch, type, regcache,
|
||||||
|
value_contents_raw (*read_value).data ());
|
||||||
|
}
|
||||||
if (writebuf)
|
if (writebuf)
|
||||||
i386_store_return_value (gdbarch, type, regcache, writebuf);
|
i386_store_return_value (gdbarch, type, regcache, writebuf);
|
||||||
|
|
||||||
|
|||||||
@@ -2492,7 +2492,8 @@ static void
|
|||||||
riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo,
|
riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo,
|
||||||
struct riscv_call_info *cinfo)
|
struct riscv_call_info *cinfo)
|
||||||
{
|
{
|
||||||
if (ainfo->length > (2 * cinfo->xlen))
|
if (TYPE_HAS_DYNAMIC_LENGTH (ainfo->type)
|
||||||
|
|| ainfo->length > (2 * cinfo->xlen))
|
||||||
{
|
{
|
||||||
/* Argument is going to be passed by reference. */
|
/* Argument is going to be passed by reference. */
|
||||||
ainfo->argloc[0].loc_type
|
ainfo->argloc[0].loc_type
|
||||||
@@ -2910,8 +2911,12 @@ riscv_arg_location (struct gdbarch *gdbarch,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_CODE_STRUCT:
|
case TYPE_CODE_STRUCT:
|
||||||
riscv_call_arg_struct (ainfo, cinfo);
|
if (!TYPE_HAS_DYNAMIC_LENGTH (ainfo->type))
|
||||||
break;
|
{
|
||||||
|
riscv_call_arg_struct (ainfo, cinfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
riscv_call_arg_scalar_int (ainfo, cinfo);
|
riscv_call_arg_scalar_int (ainfo, cinfo);
|
||||||
@@ -3228,13 +3233,6 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
struct riscv_arg_info info;
|
struct riscv_arg_info info;
|
||||||
struct type *arg_type;
|
struct type *arg_type;
|
||||||
|
|
||||||
gdb_byte *readbuf = nullptr;
|
|
||||||
if (read_value != nullptr)
|
|
||||||
{
|
|
||||||
*read_value = allocate_value (type);
|
|
||||||
readbuf = value_contents_raw (*read_value).data ();
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_type = check_typedef (type);
|
arg_type = check_typedef (type);
|
||||||
riscv_arg_location (gdbarch, &info, &call_info, arg_type, false);
|
riscv_arg_location (gdbarch, &info, &call_info, arg_type, false);
|
||||||
|
|
||||||
@@ -3246,15 +3244,15 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
gdb_printf (gdb_stdlog, "\n");
|
gdb_printf (gdb_stdlog, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readbuf != nullptr || writebuf != nullptr)
|
if (read_value != nullptr || writebuf != nullptr)
|
||||||
{
|
{
|
||||||
unsigned int arg_len;
|
unsigned int arg_len;
|
||||||
struct value *abi_val;
|
struct value *abi_val;
|
||||||
gdb_byte *old_readbuf = nullptr;
|
gdb_byte *readbuf = nullptr;
|
||||||
int regnum;
|
int regnum;
|
||||||
|
|
||||||
/* We only do one thing at a time. */
|
/* We only do one thing at a time. */
|
||||||
gdb_assert (readbuf == nullptr || writebuf == nullptr);
|
gdb_assert (read_value == nullptr || writebuf == nullptr);
|
||||||
|
|
||||||
/* In some cases the argument is not returned as the declared type,
|
/* In some cases the argument is not returned as the declared type,
|
||||||
and we need to cast to or from the ABI type in order to
|
and we need to cast to or from the ABI type in order to
|
||||||
@@ -3295,7 +3293,6 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
abi_val = allocate_value (info.type);
|
abi_val = allocate_value (info.type);
|
||||||
old_readbuf = readbuf;
|
|
||||||
readbuf = value_contents_raw (abi_val).data ();
|
readbuf = value_contents_raw (abi_val).data ();
|
||||||
}
|
}
|
||||||
arg_len = info.type->length ();
|
arg_len = info.type->length ();
|
||||||
@@ -3375,8 +3372,17 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
|
|
||||||
regcache_cooked_read_unsigned (regcache, RISCV_A0_REGNUM,
|
regcache_cooked_read_unsigned (regcache, RISCV_A0_REGNUM,
|
||||||
&addr);
|
&addr);
|
||||||
if (readbuf != nullptr)
|
if (read_value != nullptr)
|
||||||
read_memory (addr, readbuf, info.length);
|
{
|
||||||
|
abi_val = value_at_non_lval (type, addr);
|
||||||
|
/* Also reset the expected type, so that the cast
|
||||||
|
later on is a no-op. If the cast is not a no-op,
|
||||||
|
and if the return type is variably-sized, then the
|
||||||
|
type of ABI_VAL will differ from ARG_TYPE due to
|
||||||
|
dynamic type resolution, and so will most likely
|
||||||
|
fail. */
|
||||||
|
arg_type = value_type (abi_val);
|
||||||
|
}
|
||||||
if (writebuf != nullptr)
|
if (writebuf != nullptr)
|
||||||
write_memory (addr, writebuf, info.length);
|
write_memory (addr, writebuf, info.length);
|
||||||
}
|
}
|
||||||
@@ -3391,10 +3397,8 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
/* This completes the cast from abi type back to the declared type
|
/* This completes the cast from abi type back to the declared type
|
||||||
in the case that we are reading from the machine. See the
|
in the case that we are reading from the machine. See the
|
||||||
comment at the head of this block for more details. */
|
comment at the head of this block for more details. */
|
||||||
if (readbuf != nullptr)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
struct value *arg_val;
|
|
||||||
|
|
||||||
if (is_fixed_point_type (arg_type))
|
if (is_fixed_point_type (arg_type))
|
||||||
{
|
{
|
||||||
/* Convert abi_val to the actual return type, but
|
/* Convert abi_val to the actual return type, but
|
||||||
@@ -3405,15 +3409,13 @@ riscv_return_value (struct gdbarch *gdbarch,
|
|||||||
unscaled.read (value_contents (abi_val),
|
unscaled.read (value_contents (abi_val),
|
||||||
type_byte_order (info.type),
|
type_byte_order (info.type),
|
||||||
info.type->is_unsigned ());
|
info.type->is_unsigned ());
|
||||||
arg_val = allocate_value (arg_type);
|
*read_value = allocate_value (arg_type);
|
||||||
unscaled.write (value_contents_raw (arg_val),
|
unscaled.write (value_contents_raw (*read_value),
|
||||||
type_byte_order (arg_type),
|
type_byte_order (arg_type),
|
||||||
arg_type->is_unsigned ());
|
arg_type->is_unsigned ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
arg_val = value_cast (arg_type, abi_val);
|
*read_value = value_cast (arg_type, abi_val);
|
||||||
memcpy (old_readbuf, value_contents_raw (arg_val).data (),
|
|
||||||
arg_type->length ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1500,13 +1500,6 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
{
|
{
|
||||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
|
|
||||||
gdb_byte *readbuf = nullptr;
|
|
||||||
if (read_value != nullptr)
|
|
||||||
{
|
|
||||||
*read_value = allocate_value (type);
|
|
||||||
readbuf = value_contents_raw (*read_value).data ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The psABI says that "...every stack frame reserves the word at
|
/* The psABI says that "...every stack frame reserves the word at
|
||||||
%fp+64. If a function returns a structure, union, or
|
%fp+64. If a function returns a structure, union, or
|
||||||
quad-precision value, this word should hold the address of the
|
quad-precision value, this word should hold the address of the
|
||||||
@@ -1519,11 +1512,11 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
ULONGEST sp;
|
ULONGEST sp;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
{
|
{
|
||||||
regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
|
regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
|
||||||
addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
|
addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
|
||||||
read_memory (addr, readbuf, type->length ());
|
*read_value = value_at_non_lval (type, addr);
|
||||||
}
|
}
|
||||||
if (writebuf)
|
if (writebuf)
|
||||||
{
|
{
|
||||||
@@ -1535,8 +1528,12 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
|
|||||||
return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
|
return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readbuf)
|
if (read_value != nullptr)
|
||||||
sparc32_extract_return_value (type, regcache, readbuf);
|
{
|
||||||
|
*read_value = allocate_value (type);
|
||||||
|
gdb_byte *readbuf = value_contents_raw (*read_value).data ();
|
||||||
|
sparc32_extract_return_value (type, regcache, readbuf);
|
||||||
|
}
|
||||||
if (writebuf)
|
if (writebuf)
|
||||||
sparc32_store_return_value (type, regcache, writebuf);
|
sparc32_store_return_value (type, regcache, writebuf);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user