This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
#pragma push breaks bootstrap?
- To: nickc at cygnus dot com, egcs at cygnus dot com
- Subject: #pragma push breaks bootstrap?
- From: Robert Lipe <robertl at dgii dot com>
- Date: Fri, 2 Oct 1998 12:47:45 -0500
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