From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30831 invoked by alias); 8 Oct 2005 07:55:19 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 30818 invoked by uid 22791); 8 Oct 2005 07:55:16 -0000 Received: from s142-179-108-108.bc.hsia.telus.net (HELO takamaka.act-europe.fr) (142.179.108.108) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Sat, 08 Oct 2005 07:55:16 +0000 Received: by takamaka.act-europe.fr (Postfix, from userid 507) id 95F4447E76; Sat, 8 Oct 2005 00:55:13 -0700 (PDT) Date: Sat, 08 Oct 2005 07:55:00 -0000 From: Joel Brobecker To: gdb-patches@sources.redhat.com Subject: [RFA/i386] Functions returning TYPE_CODE_ARRAY types ... Message-ID: <20051008075513.GC22319@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="m51xatjYGsM+13rf" Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2005-10/txt/msg00068.txt.bz2 --m51xatjYGsM+13rf Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2545 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 * 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; --m51xatjYGsM+13rf Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="i386-tdep.diff" Content-length: 2164 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; --m51xatjYGsM+13rf--