2007-09-24 Pedro Alves * stabsread.c (read_huge_number): Fix handling of octal representation when the bit width is known. (read_range_type): Record unsigned integral types with their size, when the type size is known. --- gdb/stabsread.c | 82 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 28 deletions(-) Index: src/gdb/stabsread.c =================================================================== --- src.orig/gdb/stabsread.c 2007-09-23 17:08:30.000000000 +0100 +++ src/gdb/stabsread.c 2007-09-24 00:41:12.000000000 +0100 @@ -3704,14 +3704,14 @@ read_huge_number (char **pp, int end, in char *p = *pp; int sign = 1; int sign_bit; + int saw_first = 0; long n = 0; - long sn = 0; int radix = 10; char overflow = 0; int nbits = 0; int c; long upper_limit; - int twos_complement_representation; + int twos_complement_representation = 0; if (*p == '-') { @@ -3727,7 +3727,30 @@ read_huge_number (char **pp, int end, in p++; } - twos_complement_representation = radix == 8 && twos_complement_bits > 0; + /* Skip extra zeros. */ + while (*p == '0') + p++; + + if (sign > 0 && radix == 8 && twos_complement_bits > 0) + { + /* Octal, possibly signed. Check if we have enough chars for a + negative number. */ + + size_t len; + char *p1 = p; + while ((c = *p1) >= '0' && c < '8') + p1++; + + len = p1 - p; + if (len > twos_complement_bits / 3 + || (twos_complement_bits % 3 == 0 && len == twos_complement_bits / 3)) + { + /* Ok, we have enough characters for a signed value. */ + twos_complement_representation = 1; + sign_bit = (twos_complement_bits % 3 + 2) % 3; + } + } + upper_limit = LONG_MAX / radix; while ((c = *p++) >= '0' && c < ('0' + radix)) @@ -3736,23 +3759,23 @@ read_huge_number (char **pp, int end, in { 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)); - } + /* Octal, signed, twos complement representation. In + this case, n is the corresponding absolute value. + signed_bit is the position of the sign bit in the + first three bits. */ + if (!saw_first && (c & (1 << sign_bit))) + { + long sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit)); + sign = -1; + n = -sn; + } else { - sn *= radix; - sn += c - '0'; + n *= radix; + n += sign * (c - '0'); } - if (sn < 0) - n = -sn; + saw_first = 1; } else { @@ -3809,8 +3832,9 @@ read_huge_number (char **pp, int end, in } /* -0x7f is the same as 0x80. So deal with it by adding one to - the number of bits. */ - if (sign == -1) + the number of bits. Two's complement represantion octals can't + have a '-' in front. */ + if (sign == -1 && !twos_complement_representation) ++nbits; if (bits) *bits = nbits; @@ -3819,10 +3843,7 @@ read_huge_number (char **pp, int end, in { if (bits) *bits = 0; - if (twos_complement_representation) - return sn; - else - return n * sign; + return n * sign; } /* It's *BITS which has the interesting information. */ return 0; @@ -3947,15 +3968,20 @@ read_range_type (char **pp, int typenums return float_type; } - /* If the upper bound is -1, it must really be an unsigned int. */ + /* If the upper bound is -1, it must really be an unsigned integral. */ else if (n2 == 0 && n3 == -1) { - /* It is unsigned int or unsigned long. */ - /* GCC 2.3.3 uses this for long long too, but that is just a GDB 3.5 - compatibility hack. */ - return init_type (TYPE_CODE_INT, - gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT, + int bits = type_size; + if (bits <= 0) + { + /* We don't know it's size. It is unsigned int or unsigned + long. GCC 2.3.3 uses this for long long too, but that is + just a GDB 3.5 compatibility hack. */ + bits = gdbarch_int_bit (current_gdbarch); + } + + return init_type (TYPE_CODE_INT, bits / TARGET_CHAR_BIT, TYPE_FLAG_UNSIGNED, NULL, objfile); }