From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16376 invoked by alias); 26 Oct 2004 17:39:57 -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 16353 invoked from network); 26 Oct 2004 17:39:55 -0000 Received: from unknown (HELO dublin.act-europe.fr) (212.157.227.154) by sourceware.org with SMTP; 26 Oct 2004 17:39:55 -0000 Received: from localhost (province.act-europe.fr [10.10.0.214]) by filtered-dublin.act-europe.fr (Postfix) with ESMTP id 8FBAC229E04 for ; Tue, 26 Oct 2004 19:39:54 +0200 (MET DST) 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 10140-05 for ; Tue, 26 Oct 2004 19:39:54 +0200 (CEST) Received: from berne.act-europe.fr (berne.act-europe.fr [10.10.0.165]) by dublin.act-europe.fr (Postfix) with ESMTP id 1DCDB229E02 for ; Tue, 26 Oct 2004 19:39:54 +0200 (MET DST) Received: by berne.act-europe.fr (Postfix, from userid 560) id D7F5B592B; Tue, 26 Oct 2004 13:39:53 -0400 (EDT) Date: Tue, 26 Oct 2004 17:39:00 -0000 From: Jerome Guitton To: gdb-patches@sources.redhat.com Subject: [RFA] stabs: octal negative numbers Message-ID: <20041026173953.GA31663@act-europe.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="x+6KMIRAuhnl3hBn" Content-Disposition: inline User-Agent: Mutt/1.4i X-Virus-Scanned: by amavisd-new at act-europe.fr X-SW-Source: 2004-10/txt/msg00440.txt.bz2 --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 892 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 --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="stabsread.dif" Content-length: 11149 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; --x+6KMIRAuhnl3hBn--