[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