Skip to content

Commit 911627e

Browse files
committed
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.
1 parent 5cb0f2d commit 911627e

File tree

7 files changed

+91
-89
lines changed

7 files changed

+91
-89
lines changed

gdb/aarch64-tdep.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,6 +2334,9 @@ aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
23342334
int elements;
23352335
struct type *fundamental_type;
23362336

2337+
if (TYPE_HAS_DYNAMIC_LENGTH (type))
2338+
return 1;
2339+
23372340
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
23382341
&fundamental_type))
23392342
{
@@ -2448,13 +2451,6 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
24482451
struct type *valtype, struct regcache *regcache,
24492452
struct value **read_value, const gdb_byte *writebuf)
24502453
{
2451-
gdb_byte *readbuf = nullptr;
2452-
if (read_value != nullptr)
2453-
{
2454-
*read_value = allocate_value (valtype);
2455-
readbuf = value_contents_raw (*read_value).data ();
2456-
}
2457-
24582454
if (valtype->code () == TYPE_CODE_STRUCT
24592455
|| valtype->code () == TYPE_CODE_UNION
24602456
|| valtype->code () == TYPE_CODE_ARRAY)
@@ -2470,12 +2466,12 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
24702466

24712467
aarch64_debug_printf ("return value in memory");
24722468

2473-
if (readbuf)
2469+
if (read_value != nullptr)
24742470
{
24752471
CORE_ADDR addr;
24762472

24772473
regcache->cooked_read (AARCH64_STRUCT_RETURN_REGNUM, &addr);
2478-
read_memory (addr, readbuf, valtype->length ());
2474+
*read_value = value_at_non_lval (valtype, addr);
24792475
}
24802476

24812477
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
@@ -2485,8 +2481,12 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
24852481
if (writebuf)
24862482
aarch64_store_return_value (valtype, regcache, writebuf);
24872483

2488-
if (readbuf)
2489-
aarch64_extract_return_value (valtype, regcache, readbuf);
2484+
if (read_value)
2485+
{
2486+
*read_value = allocate_value (valtype);
2487+
aarch64_extract_return_value (valtype, regcache,
2488+
value_contents_raw (*read_value).data ());
2489+
}
24902490

24912491
aarch64_debug_printf ("return value in registers");
24922492

gdb/amd64-tdep.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -801,13 +801,6 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
801801

802802
gdb_assert (!(read_value && writebuf));
803803

804-
gdb_byte *readbuf = nullptr;
805-
if (read_value != nullptr)
806-
{
807-
*read_value = allocate_value (type);
808-
readbuf = value_contents_raw (*read_value).data ();
809-
}
810-
811804
/* 1. Classify the return type with the classification algorithm. */
812805
amd64_classify (type, theclass);
813806

@@ -824,17 +817,24 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
824817
can always find the return value just after the function has
825818
returned. */
826819

827-
if (readbuf)
820+
if (read_value != nullptr)
828821
{
829822
ULONGEST addr;
830823

831824
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
832-
read_memory (addr, readbuf, type->length ());
825+
*read_value = value_at_non_lval (type, addr);
833826
}
834827

835828
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
836829
}
837830

831+
gdb_byte *readbuf = nullptr;
832+
if (read_value != nullptr)
833+
{
834+
*read_value = allocate_value (type);
835+
readbuf = value_contents_raw (*read_value).data ();
836+
}
837+
838838
/* 8. If the class is COMPLEX_X87, the real part of the value is
839839
returned in %st0 and the imaginary part in %st1. */
840840
if (theclass[0] == AMD64_COMPLEX_X87)

gdb/amd64-windows-tdep.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -360,13 +360,6 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
360360
int len = type->length ();
361361
int regnum = -1;
362362

363-
gdb_byte *readbuf = nullptr;
364-
if (read_value != nullptr)
365-
{
366-
*read_value = allocate_value (type);
367-
readbuf = value_contents_raw (*read_value).data ();
368-
}
369-
370363
/* See if our value is returned through a register. If it is, then
371364
store the associated register number in REGNUM. */
372365
switch (type->code ())
@@ -401,20 +394,24 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function,
401394
if (regnum < 0)
402395
{
403396
/* RAX contains the address where the return value has been stored. */
404-
if (readbuf)
397+
if (read_value != nullptr)
405398
{
406399
ULONGEST addr;
407400

408401
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
409-
read_memory (addr, readbuf, type->length ());
402+
*read_value = value_at_non_lval (type, addr);
410403
}
411404
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
412405
}
413406
else
414407
{
415408
/* Extract the return value from the register where it was stored. */
416-
if (readbuf)
417-
regcache->raw_read_part (regnum, 0, len, readbuf);
409+
if (read_value != nullptr)
410+
{
411+
*read_value = allocate_value (type);
412+
regcache->raw_read_part (regnum, 0, len,
413+
value_contents_raw (*read_value).data ());
414+
}
418415
if (writebuf)
419416
regcache->raw_write_part (regnum, 0, len, writebuf);
420417
return RETURN_VALUE_REGISTER_CONVENTION;

gdb/arm-tdep.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8939,6 +8939,9 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
89398939
&& TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
89408940
return 0;
89418941

8942+
if (TYPE_HAS_DYNAMIC_LENGTH (type))
8943+
return 1;
8944+
89428945
if (TYPE_CODE_ARRAY == code && type->is_vector ())
89438946
{
89448947
/* Vector values should be returned using ARM registers if they
@@ -9140,13 +9143,6 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
91409143
struct type *valtype, struct regcache *regcache,
91419144
struct value **read_value, const gdb_byte *writebuf)
91429145
{
9143-
gdb_byte *readbuf = nullptr;
9144-
if (read_value != nullptr)
9145-
{
9146-
*read_value = allocate_value (valtype);
9147-
readbuf = value_contents_raw (*read_value).data ();
9148-
}
9149-
91509146
arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
91519147
struct type *func_type = function ? value_type (function) : NULL;
91529148
enum arm_vfp_cprc_base_type vfp_base_type;
@@ -9158,6 +9154,14 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
91589154
int reg_char = arm_vfp_cprc_reg_char (vfp_base_type);
91599155
int unit_length = arm_vfp_cprc_unit_length (vfp_base_type);
91609156
int i;
9157+
9158+
gdb_byte *readbuf = nullptr;
9159+
if (read_value != nullptr)
9160+
{
9161+
*read_value = allocate_value (valtype);
9162+
readbuf = value_contents_raw (*read_value).data ();
9163+
}
9164+
91619165
for (i = 0; i < vfp_base_count; i++)
91629166
{
91639167
if (reg_char == 'q')
@@ -9209,12 +9213,12 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
92099213
if (tdep->struct_return == pcc_struct_return
92109214
|| arm_return_in_memory (gdbarch, valtype))
92119215
{
9212-
if (readbuf)
9216+
if (read_value != nullptr)
92139217
{
92149218
CORE_ADDR addr;
92159219

92169220
regcache->cooked_read (ARM_A1_REGNUM, &addr);
9217-
read_memory (addr, readbuf, valtype->length ());
9221+
*read_value = value_at_non_lval (valtype, addr);
92189222
}
92199223
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
92209224
}
@@ -9228,8 +9232,12 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
92289232
if (writebuf)
92299233
arm_store_return_value (valtype, regcache, writebuf);
92309234

9231-
if (readbuf)
9232-
arm_extract_return_value (valtype, regcache, readbuf);
9235+
if (read_value != nullptr)
9236+
{
9237+
*read_value = allocate_value (valtype);
9238+
gdb_byte *readbuf = value_contents_raw (*read_value).data ();
9239+
arm_extract_return_value (valtype, regcache, readbuf);
9240+
}
92339241

92349242
return RETURN_VALUE_REGISTER_CONVENTION;
92359243
}

gdb/i386-tdep.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,7 +3006,8 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
30063006

30073007
if (struct_convention == pcc_struct_convention
30083008
|| (struct_convention == default_struct_convention
3009-
&& tdep->struct_return == pcc_struct_return))
3009+
&& tdep->struct_return == pcc_struct_return)
3010+
|| TYPE_HAS_DYNAMIC_LENGTH (type))
30103011
return 0;
30113012

30123013
/* Structures consisting of a single `float', `double' or 'long
@@ -3034,13 +3035,6 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
30343035
{
30353036
enum type_code code = type->code ();
30363037

3037-
gdb_byte *readbuf = nullptr;
3038-
if (read_value != nullptr)
3039-
{
3040-
*read_value = allocate_value (type);
3041-
readbuf = value_contents_raw (*read_value).data ();
3042-
}
3043-
30443038
if (((code == TYPE_CODE_STRUCT
30453039
|| code == TYPE_CODE_UNION
30463040
|| code == TYPE_CODE_ARRAY)
@@ -3068,12 +3062,12 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
30683062
a record, so the convention applied to records also applies
30693063
to arrays. */
30703064

3071-
if (readbuf)
3065+
if (read_value != nullptr)
30723066
{
30733067
ULONGEST addr;
30743068

30753069
regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
3076-
read_memory (addr, readbuf, type->length ());
3070+
*read_value = value_at_non_lval (type, addr);
30773071
}
30783072

30793073
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
@@ -3097,8 +3091,12 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
30973091
return result;
30983092
}
30993093

3100-
if (readbuf)
3101-
i386_extract_return_value (gdbarch, type, regcache, readbuf);
3094+
if (read_value != nullptr)
3095+
{
3096+
*read_value = allocate_value (type);
3097+
i386_extract_return_value (gdbarch, type, regcache,
3098+
value_contents_raw (*read_value).data ());
3099+
}
31023100
if (writebuf)
31033101
i386_store_return_value (gdbarch, type, regcache, writebuf);
31043102

gdb/riscv-tdep.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,7 +2492,8 @@ static void
24922492
riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo,
24932493
struct riscv_call_info *cinfo)
24942494
{
2495-
if (ainfo->length > (2 * cinfo->xlen))
2495+
if (TYPE_HAS_DYNAMIC_LENGTH (ainfo->type)
2496+
|| ainfo->length > (2 * cinfo->xlen))
24962497
{
24972498
/* Argument is going to be passed by reference. */
24982499
ainfo->argloc[0].loc_type
@@ -2910,8 +2911,12 @@ riscv_arg_location (struct gdbarch *gdbarch,
29102911
break;
29112912

29122913
case TYPE_CODE_STRUCT:
2913-
riscv_call_arg_struct (ainfo, cinfo);
2914-
break;
2914+
if (!TYPE_HAS_DYNAMIC_LENGTH (ainfo->type))
2915+
{
2916+
riscv_call_arg_struct (ainfo, cinfo);
2917+
break;
2918+
}
2919+
/* FALLTHROUGH */
29152920

29162921
default:
29172922
riscv_call_arg_scalar_int (ainfo, cinfo);
@@ -3228,13 +3233,6 @@ riscv_return_value (struct gdbarch *gdbarch,
32283233
struct riscv_arg_info info;
32293234
struct type *arg_type;
32303235

3231-
gdb_byte *readbuf = nullptr;
3232-
if (read_value != nullptr)
3233-
{
3234-
*read_value = allocate_value (type);
3235-
readbuf = value_contents_raw (*read_value).data ();
3236-
}
3237-
32383236
arg_type = check_typedef (type);
32393237
riscv_arg_location (gdbarch, &info, &call_info, arg_type, false);
32403238

@@ -3246,15 +3244,15 @@ riscv_return_value (struct gdbarch *gdbarch,
32463244
gdb_printf (gdb_stdlog, "\n");
32473245
}
32483246

3249-
if (readbuf != nullptr || writebuf != nullptr)
3247+
if (read_value != nullptr || writebuf != nullptr)
32503248
{
32513249
unsigned int arg_len;
32523250
struct value *abi_val;
3253-
gdb_byte *old_readbuf = nullptr;
3251+
gdb_byte *readbuf = nullptr;
32543252
int regnum;
32553253

32563254
/* We only do one thing at a time. */
3257-
gdb_assert (readbuf == nullptr || writebuf == nullptr);
3255+
gdb_assert (read_value == nullptr || writebuf == nullptr);
32583256

32593257
/* In some cases the argument is not returned as the declared type,
32603258
and we need to cast to or from the ABI type in order to
@@ -3295,7 +3293,6 @@ riscv_return_value (struct gdbarch *gdbarch,
32953293
else
32963294
{
32973295
abi_val = allocate_value (info.type);
3298-
old_readbuf = readbuf;
32993296
readbuf = value_contents_raw (abi_val).data ();
33003297
}
33013298
arg_len = info.type->length ();
@@ -3375,8 +3372,17 @@ riscv_return_value (struct gdbarch *gdbarch,
33753372

33763373
regcache_cooked_read_unsigned (regcache, RISCV_A0_REGNUM,
33773374
&addr);
3378-
if (readbuf != nullptr)
3379-
read_memory (addr, readbuf, info.length);
3375+
if (read_value != nullptr)
3376+
{
3377+
abi_val = value_at_non_lval (type, addr);
3378+
/* Also reset the expected type, so that the cast
3379+
later on is a no-op. If the cast is not a no-op,
3380+
and if the return type is variably-sized, then the
3381+
type of ABI_VAL will differ from ARG_TYPE due to
3382+
dynamic type resolution, and so will most likely
3383+
fail. */
3384+
arg_type = value_type (abi_val);
3385+
}
33803386
if (writebuf != nullptr)
33813387
write_memory (addr, writebuf, info.length);
33823388
}
@@ -3391,10 +3397,8 @@ riscv_return_value (struct gdbarch *gdbarch,
33913397
/* This completes the cast from abi type back to the declared type
33923398
in the case that we are reading from the machine. See the
33933399
comment at the head of this block for more details. */
3394-
if (readbuf != nullptr)
3400+
if (read_value != nullptr)
33953401
{
3396-
struct value *arg_val;
3397-
33983402
if (is_fixed_point_type (arg_type))
33993403
{
34003404
/* Convert abi_val to the actual return type, but
@@ -3405,15 +3409,13 @@ riscv_return_value (struct gdbarch *gdbarch,
34053409
unscaled.read (value_contents (abi_val),
34063410
type_byte_order (info.type),
34073411
info.type->is_unsigned ());
3408-
arg_val = allocate_value (arg_type);
3409-
unscaled.write (value_contents_raw (arg_val),
3412+
*read_value = allocate_value (arg_type);
3413+
unscaled.write (value_contents_raw (*read_value),
34103414
type_byte_order (arg_type),
34113415
arg_type->is_unsigned ());
34123416
}
34133417
else
3414-
arg_val = value_cast (arg_type, abi_val);
3415-
memcpy (old_readbuf, value_contents_raw (arg_val).data (),
3416-
arg_type->length ());
3418+
*read_value = value_cast (arg_type, abi_val);
34173419
}
34183420
}
34193421

0 commit comments

Comments
 (0)