From 94e10a2220867475418f3cb1526e2de6dd3e7488 Mon Sep 17 00:00:00 2001 From: Jerome Guitton Date: Mon, 13 Dec 2004 15:56:47 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 14 ++++++ gdb/stabsread.c | 112 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2b3c3629e84..f47019e6ff1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2004-12-13 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. + 2004-12-13 Randolph Chung * hppa-hpux-tdep.c (internalize_hp_cxx_exception_support): Call diff --git a/gdb/stabsread.c b/gdb/stabsread.c index e91a9809052..c0f0ae3bc31 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -92,7 +92,7 @@ read_one_struct_field (struct field_info *, char **, char *, 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 **, int *); 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 *typenums) 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 *fip, char **pp, struct type *type, 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, char **pp, struct type *type, { 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 *fip, char **pp, char *p, { 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, char **pp, struct type *type, 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, char **pp, struct type *type, 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 *type, enum type_code type_code, { 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 *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 *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 *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 typenums[2], struct objfile *objfile) 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 typenums[2], struct objfile *objfile) /* 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 typenums[2], struct objfile *objfile) 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, int *bits) 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, int *bits) { 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[2], struct objfile *objfile) /* 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[2], struct objfile *objfile) /* 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; -- 2.30.2