From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26648 invoked by alias); 23 Nov 2004 14:10:12 -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 25979 invoked from network); 23 Nov 2004 14:09:13 -0000 Received: from unknown (HELO dublin.act-europe.fr) (212.157.227.154) by sourceware.org with SMTP; 23 Nov 2004 14:09:13 -0000 Received: from localhost (province.act-europe.fr [10.10.0.214]) by filtered-dublin.act-europe.fr (Postfix) with ESMTP id 92F19229E4C for ; Tue, 23 Nov 2004 15:09:12 +0100 (MET) Received: from dublin.act-europe.fr ([10.10.0.154]) by localhost (province.act-europe.fr [10.10.0.214]) (amavisd-new, port 10024) with ESMTP id 88807-08 for ; Tue, 23 Nov 2004 15:09:12 +0100 (CET) Received: from berne.act-europe.fr (berne.act-europe.fr [10.10.0.165]) by dublin.act-europe.fr (Postfix) with ESMTP id 41A16229E4B for ; Tue, 23 Nov 2004 15:09:12 +0100 (MET) Received: by berne.act-europe.fr (Postfix, from userid 560) id 452B3592B; Tue, 23 Nov 2004 09:09:12 -0500 (EST) Date: Tue, 23 Nov 2004 14:10:00 -0000 From: Jerome Guitton To: gdb-patches@sources.redhat.com Subject: Re: [RFA] stabs: octal negative numbers Message-ID: <20041123140912.GA16691@adacore.com> References: <20041026173953.GA31663@act-europe.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20041026173953.GA31663@act-europe.fr> User-Agent: Mutt/1.4i X-Virus-Scanned: by amavisd-new at act-europe.fr X-SW-Source: 2004-11/txt/msg00448.txt.bz2 Ping? Jerome Guitton (guitton@act-europe.fr): > The patch in attachment adds support for parsing stabs that contains > negative numbers in octal, two's complement form. I have never > experienced the problem with C programs, but GCC generates those kind > of numbers for some Ada subtypes: > > procedure Test_Case is > > type Base_Fixed_Point_Type is > delta 1.0 / 16.0 > range (System.Min_Int / 2) * 1.0 / 16.0 .. > (System.Max_Int / 2) * 1.0 / 16.0; > > subtype Fixed_Point_Subtype is > Base_Fixed_Point_Type range -50.0 .. 50.0; > > begin > null; > end Test_Case; > > The stabs generated for Fixed_Point_Subtype is: > > .stabs "test_case__fixed_point_subtype___XF_1_16:t(0,14)=@s64;r(0,12);01777777777777777776340;0000000001440;",128,0,10,0 > > (01777777777777777776340 is -800 on 64-bits). > > Tested on an i686-linux host, with stabs+ format, no regressions. > Worth submitting an Ada test case, I guess. > > Comments? OK to apply? > > -- > Jerome > 2004-10-26 Jerome Guitton > > * stabsread.c (read_huge_number): Add support for reading octal > signed number in twos complement, based on the size of this > number. > (read_range_type): Add support for reading octal signed bounds > in twos complements, based on the size of the type. > (read_type_number, read_cpp_abbrev, read_member_functions, > read_cpp_abbrev, read_one_struct_field, read_baseclasses, > read_struct_type, read_array_type, read_enum_type, > read_sun_builtin_type, read_sun_floating_type): Update calls to > read_huge_number. > (read_type): Update call to read_range_type. > > Index: stabsread.c > =================================================================== > RCS file: /cvs/src/src/gdb/stabsread.c,v > retrieving revision 1.77 > diff -u -p -r1.77 stabsread.c > --- stabsread.c 30 Apr 2004 14:40:54 -0000 1.77 > +++ stabsread.c 26 Oct 2004 17:11:31 -0000 > @@ -92,7 +92,7 @@ read_one_struct_field (struct field_info > > static struct type *dbx_alloc_type (int[2], struct objfile *); > > -static long read_huge_number (char **, int, int *); > +static long read_huge_number (char **, int, int *, int); > > static struct type *error_type (char **, struct objfile *); > > @@ -106,7 +106,7 @@ static int read_type_number (char **, in > > static struct type *read_type (char **, struct objfile *); > > -static struct type *read_range_type (char **, int[2], struct objfile *); > +static struct type *read_range_type (char **, int[2], int, struct objfile *); > > static struct type *read_sun_builtin_type (char **, int[2], struct objfile *); > > @@ -435,17 +435,17 @@ read_type_number (char **pp, int *typenu > if (**pp == '(') > { > (*pp)++; > - typenums[0] = read_huge_number (pp, ',', &nbits); > + typenums[0] = read_huge_number (pp, ',', &nbits, 0); > if (nbits != 0) > return -1; > - typenums[1] = read_huge_number (pp, ')', &nbits); > + typenums[1] = read_huge_number (pp, ')', &nbits, 0); > if (nbits != 0) > return -1; > } > else > { > typenums[0] = 0; > - typenums[1] = read_huge_number (pp, 0, &nbits); > + typenums[1] = read_huge_number (pp, 0, &nbits, 0); > if (nbits != 0) > return -1; > } > @@ -1811,7 +1811,7 @@ again: > break; > > case 'r': /* Range type */ > - type = read_range_type (pp, typenums, objfile); > + type = read_range_type (pp, typenums, type_size, objfile); > if (typenums[0] != -1) > *dbx_lookup_type (typenums) = type; > break; > @@ -2291,7 +2291,7 @@ read_member_functions (struct field_info > the sign bit out, and usable as a valid index into > the array. Remove the sign bit here. */ > new_sublist->fn_field.voffset = > - (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2; > + (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2; > if (nbits != 0) > return 0; > > @@ -2656,7 +2656,8 @@ read_cpp_abbrev (struct field_info *fip, > > { > int nbits; > - FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits); > + FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits, > + 0); > if (nbits != 0) > return 0; > } > @@ -2729,13 +2730,13 @@ read_one_struct_field (struct field_info > > { > int nbits; > - FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits); > + FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits, 0); > if (nbits != 0) > { > stabs_general_complaint ("bad structure-type format"); > return; > } > - FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits); > + FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > { > stabs_general_complaint ("bad structure-type format"); > @@ -2931,7 +2932,7 @@ read_baseclasses (struct field_info *fip > ALLOCATE_CPLUS_STRUCT_TYPE (type); > { > int nbits; > - TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits); > + TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0); > if (nbits != 0) > return 0; > } > @@ -3005,7 +3006,7 @@ read_baseclasses (struct field_info *fip > corresponding to this baseclass. Always zero in the absence of > multiple inheritance. */ > > - FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits); > + FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits, 0); > if (nbits != 0) > return 0; > } > @@ -3310,7 +3311,7 @@ read_struct_type (char **pp, struct type > > { > int nbits; > - TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits); > + TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > } > @@ -3368,7 +3369,7 @@ read_array_type (char **pp, struct type > (*pp)++; > adjustable = 1; > } > - lower = read_huge_number (pp, ';', &nbits); > + lower = read_huge_number (pp, ';', &nbits, 0); > > if (nbits != 0) > return error_type (pp, objfile); > @@ -3378,7 +3379,7 @@ read_array_type (char **pp, struct type > (*pp)++; > adjustable = 1; > } > - upper = read_huge_number (pp, ';', &nbits); > + upper = read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > @@ -3452,7 +3453,7 @@ read_enum_type (char **pp, struct type * > p++; > name = obsavestring (*pp, p - *pp, &objfile->objfile_obstack); > *pp = p + 1; > - n = read_huge_number (pp, ',', &nbits); > + n = read_huge_number (pp, ',', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > @@ -3564,17 +3565,17 @@ read_sun_builtin_type (char **pp, int ty > by this type, except that unsigned short is 4 instead of 2. > Since this information is redundant with the third number, > we will ignore it. */ > - read_huge_number (pp, ';', &nbits); > + read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > /* The second number is always 0, so ignore it too. */ > - read_huge_number (pp, ';', &nbits); > + read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > /* The third number is the number of bits for this type. */ > - type_bits = read_huge_number (pp, 0, &nbits); > + type_bits = read_huge_number (pp, 0, &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > /* The type *should* end with a semicolon. If it are embedded > @@ -3607,12 +3608,12 @@ read_sun_floating_type (char **pp, int t > > /* The first number has more details about the type, for example > FN_COMPLEX. */ > - details = read_huge_number (pp, ';', &nbits); > + details = read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > /* The second number is the number of bytes occupied by this type */ > - nbytes = read_huge_number (pp, ';', &nbits); > + nbytes = read_huge_number (pp, ';', &nbits, 0); > if (nbits != 0) > return error_type (pp, objfile); > > @@ -3635,22 +3636,30 @@ read_sun_floating_type (char **pp, int t > and that character is skipped if it does match. > If END is zero, *PP is left pointing to that character. > > + If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if > + the number is represented in an octal representation, assume that > + it is represented in a 2's complement representation with a size of > + TWOS_COMPLEMENT_BITS. > + > If the number fits in a long, set *BITS to 0 and return the value. > If not, set *BITS to be the number of bits in the number and return 0. > > If encounter garbage, set *BITS to -1 and return 0. */ > > static long > -read_huge_number (char **pp, int end, int *bits) > +read_huge_number (char **pp, int end, int *bits, int twos_complement_bits) > { > char *p = *pp; > int sign = 1; > + int sign_bit; > long n = 0; > + long sn = 0; > int radix = 10; > char overflow = 0; > int nbits = 0; > int c; > long upper_limit; > + int twos_complement_representation = radix == 8 && twos_complement_bits > 0; > > if (*p == '-') > { > @@ -3671,12 +3680,36 @@ read_huge_number (char **pp, int end, in > while ((c = *p++) >= '0' && c < ('0' + radix)) > { > if (n <= upper_limit) > - { > - n *= radix; > - n += c - '0'; /* FIXME this overflows anyway */ > - } > + { > + if (twos_complement_representation) > + { > + /* Octal, signed, twos complement representation. In this case, > + sn is the signed value, n is the corresponding absolute > + value. signed_bit is the position of the sign bit in the > + first three bits. */ > + if (sn == 0) > + { > + sign_bit = (twos_complement_bits % 3 + 2) % 3; > + sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit)); > + } > + else > + { > + sn *= radix; > + sn += c - '0'; > + } > + > + if (sn < 0) > + n = -sn; > + } > + else > + { > + /* unsigned representation */ > + n *= radix; > + n += c - '0'; /* FIXME this overflows anyway */ > + } > + } > else > - overflow = 1; > + overflow = 1; > > /* This depends on large values being output in octal, which is > what GCC does. */ > @@ -3733,14 +3766,18 @@ read_huge_number (char **pp, int end, in > { > if (bits) > *bits = 0; > - return n * sign; > + if (twos_complement_representation) > + return sn; > + else > + return n * sign; > } > /* It's *BITS which has the interesting information. */ > return 0; > } > > static struct type * > -read_range_type (char **pp, int typenums[2], struct objfile *objfile) > +read_range_type (char **pp, int typenums[2], int type_size, > + struct objfile *objfile) > { > char *orig_pp = *pp; > int rangenums[2]; > @@ -3769,8 +3806,8 @@ read_range_type (char **pp, int typenums > > /* The remaining two operands are usually lower and upper bounds > of the range. But in some special cases they mean something else. */ > - n2 = read_huge_number (pp, ';', &n2bits); > - n3 = read_huge_number (pp, ';', &n3bits); > + n2 = read_huge_number (pp, ';', &n2bits, type_size); > + n3 = read_huge_number (pp, ';', &n3bits, type_size); > > if (n2bits == -1 || n3bits == -1) > return error_type (pp, objfile); > @@ -3786,8 +3823,19 @@ read_range_type (char **pp, int typenums > /* Number of bits in the type. */ > int nbits = 0; > > + /* If a type size attribute has been specified, the bounds of > + the range should fit in this size. If the lower bounds needs > + more bits than the upper bound, then the type is signed. */ > + if (n2bits <= type_size && n3bits <= type_size) > + { > + if (n2bits == type_size && n2bits > n3bits) > + got_signed = 1; > + else > + got_unsigned = 1; > + nbits = type_size; > + } > /* Range from 0 to is an unsigned large integral type. */ > - if ((n2bits == 0 && n2 == 0) && n3bits != 0) > + else if ((n2bits == 0 && n2 == 0) && n3bits != 0) > { > got_unsigned = 1; > nbits = n3bits;