From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22116 invoked by alias); 1 Nov 2004 11:17:53 -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 22089 invoked from network); 1 Nov 2004 11:17:50 -0000 Received: from unknown (HELO nile.gnat.com) (205.232.38.5) by sourceware.org with SMTP; 1 Nov 2004 11:17:50 -0000 Received: from localhost (localhost [127.0.0.1]) by nile.gnat.com (Postfix) with ESMTP id CFF4CF2B93; Mon, 1 Nov 2004 06:17:49 -0500 (EST) Received: from nile.gnat.com ([127.0.0.1]) by localhost (nile.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 08805-01-7; Mon, 1 Nov 2004 06:17:49 -0500 (EST) Received: by nile.gnat.com (Postfix, from userid 1345) id 8CB08F2B98; Mon, 1 Nov 2004 06:17:49 -0500 (EST) From: Paul Hilfinger To: cagney@gnu.org Cc: gdb-patches@sources.redhat.com In-reply-to: <41852B2B.6030305@gnu.org> (message from Andrew Cagney on Sun, 31 Oct 2004 13:12:59 -0500) Subject: Re: [RFA] Setting long long bitfields References: <20041031090847.2E303F2985@nile.gnat.com> <41852B2B.6030305@gnu.org> Message-Id: <20041101111749.8CB08F2B98@nile.gnat.com> Date: Mon, 01 Nov 2004 11:17:00 -0000 X-Virus-Scanned: by amavisd-new at nile.gnat.com X-SW-Source: 2004-11/txt/msg00010.txt.bz2 I have committed the revised version of this patch, below. Paul Hilfinger 2004-11-01 Paul N. Hilfinger * values.c (modify_field): Correct handling of bit-fields that don't fit in 32 bits. Use unsigned operations throughout and simplify the code a bit. Document preconditions. Index: gdb/values.c =================================================================== RCS file: /cvs/src/src/gdb/values.c,v retrieving revision 1.71 diff -u -p -r1.71 values.c --- gdb/values.c 28 Jul 2004 02:46:24 -0000 1.71 +++ gdb/values.c 1 Nov 2004 10:42:29 -0000 @@ -1070,45 +1070,42 @@ unpack_field_as_long (struct type *type, /* Modify the value of a bitfield. ADDR points to a block of memory in target byte order; the bitfield starts in the byte pointed to. FIELDVAL is the desired value of the field, in host byte order. BITPOS and BITSIZE - indicate which bits (in target bit order) comprise the bitfield. */ + indicate which bits (in target bit order) comprise the bitfield. + Requires 0 < BITSIZE <= lbits, 0 <= BITPOS+BITSIZE <= lbits, and + 0 <= BITPOS, where lbits is the size of a LONGEST in bits. */ void modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize) { - LONGEST oword; + ULONGEST oword; + ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize); /* If a negative fieldval fits in the field in question, chop off the sign extension bits. */ - if (bitsize < (8 * (int) sizeof (fieldval)) - && (~fieldval & ~((1 << (bitsize - 1)) - 1)) == 0) - fieldval = fieldval & ((1 << bitsize) - 1); + if ((~fieldval & ~(mask >> 1)) == 0) + fieldval &= mask; /* Warn if value is too big to fit in the field in question. */ - if (bitsize < (8 * (int) sizeof (fieldval)) - && 0 != (fieldval & ~((1 << bitsize) - 1))) + if (0 != (fieldval & ~mask)) { /* FIXME: would like to include fieldval in the message, but we don't have a sprintf_longest. */ warning ("Value does not fit in %d bits.", bitsize); /* Truncate it, otherwise adjoining fields may be corrupted. */ - fieldval = fieldval & ((1 << bitsize) - 1); + fieldval &= mask; } - oword = extract_signed_integer (addr, sizeof oword); + oword = extract_unsigned_integer (addr, sizeof oword); /* Shifting for bit field depends on endianness of the target machine. */ if (BITS_BIG_ENDIAN) bitpos = sizeof (oword) * 8 - bitpos - bitsize; - /* Mask out old value, while avoiding shifts >= size of oword */ - if (bitsize < 8 * (int) sizeof (oword)) - oword &= ~(((((ULONGEST) 1) << bitsize) - 1) << bitpos); - else - oword &= ~((~(ULONGEST) 0) << bitpos); + oword &= ~(mask << bitpos); oword |= fieldval << bitpos; - store_signed_integer (addr, sizeof oword, oword); + store_unsigned_integer (addr, sizeof oword, oword); } /* Convert C numbers into newly allocated values */