[RFA/i386] Functions returning TYPE_CODE_ARRAY types ...
Joel Brobecker
brobecker@adacore.com
Sat Oct 8 07:55:00 GMT 2005
Hello,
One of our users just came across this on an i386-linux machine.
He tried to do a "finish" on a function that returns an array whose
size is statically known. This is not possible in C, but this can be
done in Ada. Consider the following code:
package Pck is
type Data_Small is array (1 .. 2) of Integer;
type Data_Large is array (1 .. 4) of Integer;
function Create_Small return Data_Small;
function Create_Large return Data_Large;
end Pck;
(the body of that package is pasted at the end of this message,
for better clarity)
And a main procedure that uses that package:
with Pck; use Pck;
procedure P is
Small : Data_Small;
Large : Data_Large;
begin
Small := Create_Small;
Large := Create_Large;
Small (1) := Large (1);
end P;
To build this example program, simply do:
% gnatmake -g p
Doing a "finish" off function Create_Small and Create_Large
currently yield these two results:
(gdb) b create_small
(gdb) b create_large
(gdb) run
(gdb) fin
[...]
Value returned is $1 = (-1073743720, 134566260)
(gdb) c
(gdb) fin
[...]
i386-tdep.c:1337: internal-error: Cannot extract return value of 16 bytes long.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) n
i386-tdep.c:1337: internal-error: Cannot extract return value of 16 bytes long.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
The problem is that the the i386 struct-return code did not expect
a function whose return type is a TYPE_CODE_ARRAY. This case is not
mentioned as far as I could tell in the ABI, but the array is returned
the same way records would be.
The attached patch implements this.
2005-10-07 Joel Brobecker <brobecker@adacore.com>
* i386-tdep.c (i386_reg_struct_return_p): Allow array types as well.
(i386_return_value): Add handling for functions that return array
types.
Tested on x86-linux, no regression. Testcase to follow shortly in
a separate email.
OK to apply?
Thanks,
--
Joel
package body Pck is
function Create_Small return Data_Small is
begin
return (others => 1);
end Create_Small;
function Create_Large return Data_Large is
begin
return (others => 2);
end Create_Large;
end Pck;
-------------- next part --------------
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.218
diff -u -p -r1.218 i386-tdep.c
--- i386-tdep.c 26 Sep 2005 06:59:39 -0000 1.218
+++ i386-tdep.c 8 Oct 2005 02:50:24 -0000
@@ -1424,9 +1424,9 @@ static const char *valid_conventions[] =
};
static const char *struct_convention = default_struct_convention;
-/* Return non-zero if TYPE, which is assumed to be a structure or
- union type, should be returned in registers for architecture
- GDBARCH. */
+/* Return non-zero if TYPE, which is assumed to be a structure,
+ a union type, or an array type, should be returned in registers
+ for architecture GDBARCH. */
static int
i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
@@ -1435,7 +1435,9 @@ i386_reg_struct_return_p (struct gdbarch
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
- gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
+ gdb_assert (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION
+ || code == TYPE_CODE_ARRAY);
if (struct_convention == pcc_struct_convention
|| (struct_convention == default_struct_convention
@@ -1467,7 +1469,9 @@ i386_return_value (struct gdbarch *gdbar
{
enum type_code code = TYPE_CODE (type);
- if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+ if ((code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION
+ || code == TYPE_CODE_ARRAY)
&& !i386_reg_struct_return_p (gdbarch, type))
{
/* The System V ABI says that:
@@ -1481,6 +1485,12 @@ i386_return_value (struct gdbarch *gdbar
So the ABI guarantees that we can always find the return
value just after the function has returned. */
+ /* Note that the ABI doesn't mention functions returning arrays,
+ which is something possible in certain languages such as Ada.
+ In this case, the value is returned as if it was wrapped in
+ a record, so the convention applied to records also applies
+ to arrays. */
+
if (readbuf)
{
ULONGEST addr;
More information about the Gdb-patches
mailing list