From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19753 invoked by alias); 15 Aug 2011 15:22:38 -0000 Received: (qmail 19745 invoked by uid 22791); 15 Aug 2011 15:22:37 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,TW_CP,TW_EG X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 15 Aug 2011 15:22:22 +0000 Received: (qmail 1361 invoked from network); 15 Aug 2011 15:22:21 -0000 Received: from unknown (HELO ?192.168.0.101?) (yao@127.0.0.2) by mail.codesourcery.com with ESMTPA; 15 Aug 2011 15:22:21 -0000 Message-ID: <4E4939A9.70000@codesourcery.com> Date: Mon, 15 Aug 2011 15:22:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.18) Gecko/20110617 Lightning/1.0b2 Thunderbird/3.1.11 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: [patch] Handle return small struct in rs600 (size is not 4/8) Content-Type: multipart/mixed; boundary="------------090009080802060301030805" X-IsSubscribed: yes 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: 2011-08/txt/msg00298.txt.bz2 This is a multi-part message in MIME format. --------------090009080802060301030805 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content-length: 1270 Hi, It looks to me that ppc-sysv-tdep.c:do_ppc_sysv_return_value doesn't consider the case that returning a small struct (size <= 8) whose size is not 4 or 8. Supposing we have a struct defined as below, struct C {char c1; char c2; char c3;}; struct C c; c.c1 = 'a'; c.c2 = 'b'; c.c3 = 'c'; The raw memory content of c is 0x616263XX (big-endian) or 0xXX636261 (little-endian). When returning c, according to Power Arch ABI: "Aggregates or unions whose size is less than or equal to eight bytes shall be returned in r3 and r4, as if they were first stored in memory area and then the low-addressed word were loaded in r3 and the high-addressed word were loaded into r4.", the content of r3 should be 0x616263 (big-endian) or 0x636261 (little-endian). When gdb reads r3's content via regcache_cooked_read into a buf, the content of buf looks like this, buf: [0] [1] [2] [3] big-endian : 00 61 62 63 little-endian : 61 62 63 00 later, when we copy the contents of buf to readbuf, we should skip 00. Current code in gdb doesn't consider this, but it works in little-endian. This patch is going to fix this issue. Regression tested on a powerpc variant board. Many fails in gdb.base/structs.exp are fixed. Is this patch OK? -- Yao (齐尧) --------------090009080802060301030805 Content-Type: text/x-patch; name="0001-return_value-read-write-endianess.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-return_value-read-write-endianess.patch" Content-length: 1889 gdb/ * ppc-sysv-tdep.c (do_ppc_sysv_return_value): Handle return small struct whose size is not 4 or 8. --- gdb/ppc-sysv-tdep.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index afe3bd2..48afc7a 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -795,12 +795,18 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct value *function, /* The value is right-padded to 8 bytes and then loaded, as two "words", into r3/r4. */ gdb_byte regvals[MAX_REGISTER_SIZE * 2]; + int offset = (2 * tdep->wordsize - TYPE_LENGTH (type)) % tdep->wordsize; + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (TYPE_LENGTH (type) > tdep->wordsize) regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, regvals + 1 * tdep->wordsize); - memcpy (readbuf, regvals, TYPE_LENGTH (type)); + + if (byte_order == BFD_ENDIAN_BIG) + memcpy (readbuf, regvals + offset, TYPE_LENGTH (type)); + else + memcpy (readbuf, regvals, TYPE_LENGTH (type)); } if (writebuf) { @@ -808,8 +814,14 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct value *function, /* The value is padded out to 8 bytes and then loaded, as two "words" into r3/r4. */ gdb_byte regvals[MAX_REGISTER_SIZE * 2]; + int offset = (2 * tdep->wordsize - TYPE_LENGTH (type)) % tdep->wordsize; + memset (regvals, 0, sizeof regvals); - memcpy (regvals, writebuf, TYPE_LENGTH (type)); + if (byte_order == BFD_ENDIAN_BIG) + memcpy (regvals + offset, writebuf, TYPE_LENGTH (type)); + else + memcpy (regvals, writebuf, TYPE_LENGTH (type)); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (TYPE_LENGTH (type) > tdep->wordsize) -- 1.7.0.4 --------------090009080802060301030805--