From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12062 invoked by alias); 28 Dec 2010 04:43:31 -0000 Received: (qmail 12049 invoked by uid 22791); 28 Dec 2010 04:43:30 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_CP,TW_EG,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; Tue, 28 Dec 2010 04:43:24 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 12C532BABDB; Mon, 27 Dec 2010 23:43:23 -0500 (EST) 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 ACJLTx4PnD9V; Mon, 27 Dec 2010 23:43:23 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 86D9B2BAB2A; Mon, 27 Dec 2010 23:43:22 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id EDC281457BD; Tue, 28 Dec 2010 05:43:13 +0100 (CET) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [PATCH 2/8] small integral parameters and return values Date: Tue, 28 Dec 2010 04:43:00 -0000 Message-Id: <1293511386-7384-3-git-send-email-brobecker@adacore.com> In-Reply-To: <1293511386-7384-1-git-send-email-brobecker@adacore.com> References: <1293511386-7384-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-12/txt/msg00480.txt.bz2 This patch fixes a small problem on ia64-hpux when calling functions whose parameter are small integral values (less than 8 bytes). In that case, the parameter value was stored on the wrong side of the register. Same problem for return values. With this patch, the results for gdb.base/callfuncs.exp improve from # of expected passes 41 # of unexpected failures 78 To: # of expected passes 95 # of unexpected failures 24 gdb/ChangeLog: * ia64-tdep.c (ia64_struct_type_p): New function. (ia64_extract_return_value): Handle integral values that are less than 8 bytes long. (ia64_push_dummy_call): Likewise. Tested on both ia64-hpux and ia64-linux. --- gdb/ia64-tdep.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 48 insertions(+), 1 deletions(-) diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 6e24c9e..1cd6a38 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -3143,6 +3143,15 @@ ia64_use_struct_convention (struct type *type) return TYPE_LENGTH (type) > 32; } +/* Return non-zero if TYPE is a structure or union type. */ + +static int +ia64_struct_type_p (const struct type *type) +{ + return (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION); +} + static void ia64_extract_return_value (struct type *type, struct regcache *regcache, gdb_byte *valbuf) @@ -3167,6 +3176,21 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache, regnum++; } } + else if (!ia64_struct_type_p (type) && TYPE_LENGTH (type) < 8) + { + /* This is an integral value, and its size is less than 8 bytes. + These values are LSB-aligned, so extract the relevant bytes, + and copy them into VALBUF. */ + /* brobecker/2005-12-30: Actually, all integral values are LSB aligned, + so I suppose we should also add handling here for integral values + whose size is greater than 8. But I wasn't able to create such + a type, neither in C nor in Ada, so not worrying about these yet. */ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + ULONGEST val; + + regcache_cooked_read_unsigned (regcache, IA64_GR8_REGNUM, &val); + store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, val); + } else { ULONGEST val; @@ -3671,7 +3695,30 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, char val_buf[8]; memset (val_buf, 0, 8); - memcpy (val_buf, value_contents (arg) + argoffset, (len > 8) ? 8 : len); + if (!ia64_struct_type_p (type) && len < 8) + { + /* Integral types are LSB-aligned, so we have to be careful + to insert the argument on the correct side of the buffer. + This is why we use store_unsigned_integer. */ + store_unsigned_integer + (val_buf, 8, byte_order, + extract_unsigned_integer (value_contents (arg), len, + byte_order)); + } + else + { + /* This is either an 8bit integral type, or an aggregate. + For 8bit integral type, there is no problem, we just + copy the value over. + + For aggregates, the only potentially tricky portion + is to write the last one if it is less than 8 bytes. + In this case, the data is Byte0-aligned. Happy news, + this means that we don't need to differentiate the + handling of 8byte blocks and less-than-8bytes blocks. */ + memcpy (val_buf, value_contents (arg) + argoffset, + (len > 8) ? 8 : len); + } if (slotnum < rseslots) write_memory (rse_address_add (bsp, slotnum), val_buf, 8); -- 1.7.1