From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3306 invoked by alias); 30 Apr 2010 22:30:40 -0000 Received: (qmail 3285 invoked by uid 22791); 30 Apr 2010 22:30:36 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 30 Apr 2010 22:30:27 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id C7E192BAB1C for ; Fri, 30 Apr 2010 18:30:25 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id MhK+s7nqdppm for ; Fri, 30 Apr 2010 18:30:25 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 8EAD02BAB03 for ; Fri, 30 Apr 2010 18:30:25 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id C4380F58F9; Fri, 30 Apr 2010 15:30:21 -0700 (PDT) From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [RFA/sparc] "finish" does not work if function returns array. Date: Fri, 30 Apr 2010 22:30:00 -0000 Message-Id: <1272666620-10914-1-git-send-email-brobecker@adacore.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg01023.txt.bz2 This is something that is not explicitly covered by the ABI, which would explain why it's not covered by the code yet. In Ada, functions can return arrays, for instance: type Data_Small is array (1 .. 2) of Integer; function Create_Small return Data_Small; Trying to do a "finish" from Create_Small just runs-away: (gdb) b create_small Breakpoint 1 at 0x18b30: file pck.adb, line 5. (gdb) run Starting program: /[...]/p Breakpoint 1, pck.create_small () at pck.adb:5 5 return (others => 1); (gdb) fin Run till exit from #0 pck.create_small () at pck.adb:5 Program exited normally. What happens is that functions returning an array are like functions returning a structure. As such, the ABI requires the caller to setup an "unimp" instruction right after the delay slot of the call instruction. For instance, in our case above, the code in the caller looks like this: 0x00018e78 <+12>: call 0x18de0 0x00018e7c <+16>: nop 0x00018e80 <+20>: illtrap 0x8 Before this patch, GDB would place the finish breakpoint where the unimp/illtrap instruction is located, instead of placing it on the next instruction. As a result, the finish breakpoint never gets hit, and the program runs away... Interestingly, another symptom of the same problem is trying to step over that function: (gdb) start Breakpoint 1 at 0x18e70: file p.adb, line 8. Starting program: /[...]/p p () at p.adb:8 8 Small := Create_Small; (gdb) next Program exited normally. Ooops! 2010-04-30 Joel Brobecker * sparc-tdep.c (sparc_structure_or_union_p): Return non-zero for array types. * sparc64-tdep.c (sparc64_structure_or_union_p): Likewise. Fixed thusly. I don't think that the same situation applies to sparc64, since I don't believe that they kept that "unimp" convention for functions returning a struct or a union. However, the fact that arrays are like struct should still apply on sparc64 - hence the decision to fix sparc64-tdep as well. I have tested this patch on sparc-solaris and sparc64-solaris (2.8). The issue is that I still am forbidden from running the GDB testsuite on solaris machines (it causes our machine to crash pretty badly). So it's been tested with AdaCore's testsuite only. I would appreciate if anyone running OpenSolaris could test it; But I have otherwise done my best to test it. OK to apply? thanks, -- Joel --- gdb/sparc-tdep.c | 7 ++++++- gdb/sparc64-tdep.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index a2bae9f..f882505 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -221,7 +221,11 @@ sparc_floating_p (const struct type *type) return 0; } -/* Check whether TYPE is "Structure or Union". */ +/* Check whether TYPE is "Structure or Union". + + In terms of subprogram calls, arrays are treated the same as struct + and union types. So this function also returns non-zero for array + types. */ static int sparc_structure_or_union_p (const struct type *type) @@ -230,6 +234,7 @@ sparc_structure_or_union_p (const struct type *type) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: + case TYPE_CODE_ARRAY: return 1; default: break; diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index 9a34834..08d6f1a 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -103,7 +103,11 @@ sparc64_floating_p (const struct type *type) return 0; } -/* Check whether TYPE is "Structure or Union". */ +/* Check whether TYPE is "Structure or Union". + + In terms of subprogram calls, arrays are treated the same as struct + and union types. So this function also returns non-zero for array + types. */ static int sparc64_structure_or_union_p (const struct type *type) @@ -112,6 +116,7 @@ sparc64_structure_or_union_p (const struct type *type) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: + case TYPE_CODE_ARRAY: return 1; default: break; -- 1.6.3.3