This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Stabs parsing regression from GDB 6.6 to GDB 6.6.90


Hi,

This afects Cygwin badly, as it still uses stabs by default.
I've seen this problem here, but thought it was caused by a
few gcc changes I was making ...

Pierre Muller wrote:
  As I was unable to understand the current implementation of
the twos_complement_representation

I can't really see how it was supposed to work either. Parsing 000000000 is broken currently.

I rewrote it almost completely.

You are only counting the bits. This function should return the parsed number if it fits in a long:

/* 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. */


  The code now checks that the most significant
bit of the whole octal representation of the huge number
that is being parsed is exactly at the bit position given by
the twos_complement_bits parameter.


  The attached patch (against 6.6.90 source)
fixes the problem that I describe in the previous
email. I get no complaint for the 'unsigned long long' type
compiled with '-gstabs+' option.


Thanks for pointing in the right direction!


(Forgive me for counter patching, but I had started on this
 here too yesterday :( )

What about the attached? Isn't it simpler?

We get passed the max number of bits the number we're parsing
can hold in TWOS_COMPLEMENT_BITS.

Just parse the number as unsigned, if it overflows, it doesn't
matter, we just account for the bits.
If it doesn't overflow (host has a big long),
	and TWOS_COMPLEMENT_BITS < sizeof (long) * HOST_CHAR_BIT
	and number is signed according to TWOS_COMPLEMENT_BITS - 1
	bit being set, sign extend the number into a long.

Just tested that it also fixes the problem.  I'll give it a
testsuite spin for C/C++ on Cygwin tomorrow, but the testcase
that suposedly tests this is in ADA, which I don't have a
setup for...

Cheers,
Pedro Alves


2007-09-22  Pedro Alves  <pedro_alves@portugalmail.pt>

	* stabsread.c (read_huge_number): Remove special parsing of octal
	two's complement representation.  If just parsed a negative number
	in octal two's complement representation, sign extend the result
	to a long.

Index: stabsread.c
===================================================================
RCS file: /cvs/src/src/gdb/stabsread.c,v
retrieving revision 1.95
diff -u -p -r1.95 stabsread.c
--- stabsread.c	10 Aug 2007 22:08:22 -0000	1.95
+++ stabsread.c	22 Sep 2007 02:28:15 -0000
@@ -3737,32 +3737,9 @@ read_huge_number (char **pp, int end, in
     {
       if (n <= upper_limit)
         {
-          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 */
-            }
+	  /* unsigned representation */
+	  n *= radix;
+	  n += c - '0';		/* FIXME this overflows anyway */
         }
       else
         overflow = 1;
@@ -3823,7 +3800,25 @@ read_huge_number (char **pp, int end, in
       if (bits)
 	*bits = 0;
       if (twos_complement_representation)
-        return sn;
+	{
+	  if (nbits == twos_complement_bits)
+	    {
+	      /* N is signed.  TWOS_COMPLEMENT_BITS may be less than
+		 what fits in a long.  Since we can't assume a host
+		 with two's complement long, extract the module value
+		 of N, and multiply it with -1.
+
+		 eg: with TWOS_COMPLEMENT_BITS == 16, and sizeof long == 32,
+		 0x00008111 => 0xffff7eef => 0x00007eef => 0xffff8111.  */
+
+	      unsigned long l = (unsigned long) n;
+	      l = ~l + 1;
+	      l &= (1L << twos_complement_bits) - 1;
+	      l *= -1;
+	      n = l;
+	    }
+	  return n;
+	}
       else
         return n * sign;
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]