This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

#pragma push breaks bootstrap?


This is the kind of problem that makes one down his own sanity.  Before
this message is over, I fully expect at least a few of you to question
my sanity, too.

In the last 24 hours, EGCS has quit bootstrapping on OpenServer.
Jean-Pierre was the one that reported this to me.  I tracked it down to
to a generated file that was being misgenerated and I've even tracked
it down to one source line I can change to make the problem go away.
But this is making less and less sense as I go along.  Yes, I'm running
exactly what's in the repository.  I've reverted the i386.md stuff from
yesterday.   Certainly J-P wasn't running anything that experimental and
he saw this before I did.


Basically, gencodes.o is being miscompiled by the stage1 compiler.
It's trying to do a negative lseek on stdout.  This works OK if you
just type 'gencodes ..blah../i386.md' you can see the outpu just fine.
(Seeks don't work on tty devices.)  When you direct it to a file (as
the build procedure does) this drives the libraries crazy and you don't
get the end of the file redirected into insn-codes.h.  Poking around in
gencodes.c, I found I could "fix" the problem by adding almost any code
to it that touched low numbered file descriptors.

I walked through the patches of the last 24 hours and one of the most
benign looking of the lot seems to be thing that triggers it.  If I
revert i386/i386.h to -D981001 so that HANDLE_PRAGMA_PACK_PUSH_POP isn't
set and redo the bootstrap, it works.  If I walk that lone file forward
to the -D981002 tag and redo the bootstrap, it does the wrong thing.  The
whole thing just reeks of a memory overwrite somewhere.

For "ease" of testing, I've populated stage1/ with a gcc built with
the bad version of i386.h and stage2/ with a gcc built with the good
version.  If I use each with --save-temps to build gencodes.o, the
resulting preprocessor files are identical.  

(robertl) rjlhome:/play/negcs/gcc
$ diff gencodes.1.i gencodes.2.i
(robertl) rjlhome:/play/negcs/gcc
$ sum gencodes.1.i gencodes.2.i
6639 143 gencodes.1.i
6639 143 gencodes.2.i


The difference between the two versions is in the .s files.   When
PRAGMA_PUSH and friends are turned on, egcs emits wrong offsets into
the __iob array that is used by things like the 'fflush(stdout)' that
appears in the gencodes source.

$ diff gencodes.1.s gencodes.2.s
125c125
<       pushl $__iob+48
---
>       pushl $__iob+32
132c132
<       pushl $__iob+48
---
>       pushl $__iob+32
136c136
<       pushl $__iob+48
---
>       pushl $__iob+32
306c306
<       pushl $__iob+24
---
>       pushl $__iob+16
309c309
<       movb __iob+36,%al
---
>       movb __iob+28,%al


Of these differences, most are in fatal().   The one that matters
is the one that's actually called:

$ sdiff -w80 gencodes.1.s gencodes.2.s
        .file   "gencodes.c"                      .file   "gencodes.c"
        .version        "01.01"                   .version        "01.01"
gcc2_compiled.:                           gcc2_compiled.:

[ munch ] 

        incl insn_code_number                     incl insn_code_number
.L18:                                     .L18:
        jmp .L12                                  jmp .L12
        .align 4                                  .align 4
.L13:                                     .L13:
        pushl $.LC10                              pushl $.LC10
        call printf                               call printf
        addl $4,%esp                              addl $4,%esp
        pushl $.LC11                              pushl $.LC11
        call printf                               call printf
        addl $4,%esp                              addl $4,%esp
        pushl $.LC12                              pushl $.LC12
        call printf                               call printf
        addl $4,%esp                              addl $4,%esp
        pushl $__iob+24                |          pushl $__iob+16
        call fflush                               call fflush
        addl $4,%esp                              addl $4,%esp
        movb __iob+36,%al              |          movb __iob+28,%al
        andb $32,%al                              andb $32,%al
        testb %al,%al                             testb %al,%al
        je .L20                                   je .L20
        movl $33,%eax                             movl $33,%eax
        jmp .L21                                  jmp .L21
        .align 4                                  .align 4


All this results in the code doing an fflush() of the wrong file descriptor.


How can I help track this down?   

RJL


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