Re: Patch for bug 567 (sparc-sun-solaris2.8)

Duncan Roe
2002-11-20T22:32:25Z

Hi Andrew,

I posted the debug info the other day, as you requested.

What happens now?

Cheers ... Duncan.

On Fri, Nov 15, 2002 at 07:34:58PM -0500, Andrew Cagney wrote:
> > Hi,
> >
> > Bug 567 complains that when you build gdb for sparc-sun-solaris2.8 as a 64-bit
> > program, then when you use it to debug a 32-bit program things happen like:
> >
> > (gdb) p d1
> > Cannot access memory at address 0xffbef7a0
> > (gdb) x/fg &d1
> > 0xffbef7a0: 3.2999999999999998
> >
> > (Actually 567 shows the wrong value being printed to x/fg, but this seems to be
> > fixed at gcc-3.2 / gdb 5.2.1).
> >
> > It turns out that you can't "p" any kind of variable: the problem isn't limited
> > to double.
> >
> > The problem seemed to me that 32-bit negative stack offsets became +ve 64-bit
> > quantities. This would give a 33-bit address (the wanted address with an extra
> > "1" on the left).
> >
> > Ideally, I think gdb should just mask off the extra bit when debugging 32-bit
> > code. But I couldn't figure out how to do that, so the attached patch
> > sign-extends symbol values as they are read in.
>
> From the point of view of GDB's core, the patch below may be closer to
> correct than you think (don't know how well it fits into the definition
> of the debug info - debug maintainer problem :-).
>
> GDB converts all external (debug info, et.al.) addresses into a
> canonical form. That form won't involve masking but can, on ocasions,
> involve sign extension. This is so that GDB can correctly debug a 32
> bit ABI on a 64 bit target. In such a situtation, while a pointer might
> be 32 bits, registers and the address space would be the full 64 bits,
> gdb extending everything out to the size of CORE_ADDR.
>
> This is what makes it possible for GDB to debug an o32 ABI on a MIPS 64
> platform (eg IRIX 6.5).
>
> BTW, can you post the corresponding debug info?
>
> Andrew
>
>
> > GCC 3.2 configuration:
> >
> > /tmp/gcc-3.2/configure --prefix=/usr/local/gcc-3.2
> >
> > GDB 5.2.1 configuration
> >
> > PATH=/usr/local/gcc-3.2/bin:$PATH
> > export PATH
> > CC="gcc -m64"
> > export CC
> > CFLAGS="-g -O2"
> > export CFLAGS
> > ./configure --prefix=/usr/local/solaris2.8_64
> >
> > You need to put "-m64" in CC rather than CFLAGS else "make install" fails when
> > trying to build "chew". This has the unfortunate side-effect that "make check"
> > also uses "gcc -m64", i.e. it never exercises "gcc" which would build a 32-bit
> > program.
> >
> > Cheers ... Duncan.
> >
> >
> >
> > diff -r -u gdb-5.2.1.bu/gdb/dbxread.c gdb-5.2.1/gdb/dbxread.c
> > --- gdb-5.2.1.bu/gdb/dbxread.c Fri Apr 5 08:33:49 2002
> > +++ gdb-5.2.1/gdb/dbxread.c Thu Nov 14 16:23:40 2002
> > @@ -2591,6 +2591,27 @@
> > fill_symbuf (abfd);
> > bufp = &symbuf[symbuf_idx++];
> > INTERNALIZE_SYMBOL (nlist, bufp, abfd);
> > +
> > + /* ----------------------------------------------- */
> > + /* Horrible fix for when gdb is built with "-m64" */
> > + /* (sparc-sun-solaris2.8): */
> > + /* sign-extend the 32-bit result in nlist.n_value. */
> > + /* */
> > + /* This fixes the testcase in bug 567, */
> > + /* in that you can "p d1" successfully. */
> > + /* Actually you can "p" *anything* */
> > + /* (previously, you couldn't). */
> > + /* */
> > + /* I expect this will break something else, */
> > + /* we'll just have to wait to see what. */
> > + /* */
> > + /* The proper fix is for gdb to know that it's */
> > + /* working on a 32-bit program and */
> > + /* truncate addresses to 32 bits before using them */
> > + /* ----------------------------------------------- */
> > +
> > + nlist.n_value = (long)(int)nlist.n_value;
> > +
> > OBJSTAT (objfile, n_stabs++);
> >
> > type = bfd_h_get_8 (abfd, bufp->e_type);
> >
> >
> >
> > /*
> > * From GDB bug report 567
> > gcc -g -m64 -o double double.c
> > gcc -g -o double double.c
> > *
> > * The report says to breakpoint on the printf line
> > * & print the value of d1
> > */
> > extern int printf(const char *, ...);
> >
> > int
> > main()
> > {
> > double d1;
> >
> > d1 = 3.3;
> > printf("d1 = %f\n", d1);
> >
> > return 0;
> > }
>
>
>