pat@wang.UUCP (Pat Knight) (06/28/89)
The following file shows up a code generation bug in gcc 1.35 for the 80386.
I have marked the offending source line in the standard and expanded source
files with ======= lines. The offending assembler statements are similarly
marked.
The configuration and compilation options are
gcc version 1.35
/usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dunix -Di386 -D__unix__ -D__i386__ gnubug.c /tmp/cca01561.cpp
GNU CPP version 1.35
/usr/local/lib/gcc-cc1 /tmp/cca01561.cpp -quiet -dumpbase gnubug.c -g -version -o /tmp/cca01561.s
GNU C version 1.35 (80386, ATT syntax) compiled by GNU C version 1.35.
as -o gnubug.o /tmp/cca01561.s
ld -o gbc /lib/crt1.o gnubug.o /usr/local/lib/gcc-gnulib -lg -lc /lib/crtn.o
Pat Knight
=====================================Source File==============================
#include <syms.h>
static SYMENT mysymtab[201];
int xsymcnt = 1;
static SYMENT *xsymptr[100];
SYMENT *getsym();
main ()
{
xsymptr[0] = (SYMENT *) malloc(100 * sizeof(SYMENT));
printf ("xsymptr[0] = %x\n", xsymptr[0]);
printf ("mysymtab address = %x\n", mysymtab);
printf ("acid = %d, getsym = %x\n", 50, getsym(50));
printf ("acid = %d, getsym = %x\n", 202, getsym(202));
exit(0);
}
SYMENT
*getsym(acid)
register int acid;
{
if (acid <= 0)
printf("acid negative");
if (acid <= 200)
return(&mysymtab[acid]);
acid -= (200 + 1);
if (acid < xsymcnt * 100)
===========================================================================
return( (SYMENT *) ( (long) xsymptr[acid/100] +
((acid % 100) * sizeof(SYMENT))) );
===========================================================================
printf("invalid value for acid");
}
=========================Expanded Source File (gcc -E)=====================
# 1 "gnubug.c"
# 1 "/usr/include/syms.h"
#ident "@(#)syms.h 10.1"
# 1 "/usr/include/storclass.h"
#ident "@(#)storclass.h 10.1"
# 13 "/usr/include/syms.h"
struct syment
{
union
{
char _n_name[8 ];
struct
{
long _n_zeroes;
long _n_offset;
} _n_n;
char *_n_nptr[2];
} _n;
long n_value;
short n_scnum;
unsigned short n_type;
char n_sclass;
char n_numaux;
};
union auxent
{
struct
{
long x_tagndx;
union
{
struct
{
unsigned short x_lnno;
unsigned short x_size;
} x_lnsz;
long x_fsize;
} x_misc;
union
{
struct
{
long x_lnnoptr;
long x_endndx;
} x_fcn;
struct
{
unsigned short x_dimen[ 4 ];
} x_ary;
} x_fcnary;
unsigned short x_tvndx;
} x_sym;
struct
{
char x_fname[14 ];
} x_file;
struct
{
long x_scnlen;
unsigned short x_nreloc;
unsigned short x_nlinno;
} x_scn;
struct
{
long x_tvfill;
unsigned short x_tvlen;
unsigned short x_tvran[2];
} x_tv;
};
# 1 "gnubug.c"
static struct syment mysymtab[201];
int xsymcnt = 1;
static struct syment *xsymptr[100];
struct syment *getsym();
main ()
{
xsymptr[0] = (struct syment *) malloc(100 * sizeof(struct syment ));
printf ("xsymptr[0] = %x\n", xsymptr[0]);
printf ("mysymtab address = %x\n", mysymtab);
printf ("acid = %d, getsym = %x\n", 50, getsym(50));
printf ("acid = %d, getsym = %x\n", 202, getsym(202));
exit(0);
}
struct syment
*getsym(acid)
register int acid;
{
if (acid <= 0)
printf("acid negative");
if (acid <= 200)
return(&mysymtab[acid]);
acid -= (200 + 1);
===========================================================================
if (acid < xsymcnt * 100)
return( (struct syment *) ( (long) xsymptr[acid/100] +
((acid % 100) * sizeof(struct syment ))) );
===========================================================================
printf("invalid value for acid");
}
===========================Assembler output by gcc -g -S=====================
.file "gnubug.c"
gcc_compiled.:
.text
.ident "@(#)syms.h 10.1"
.ident "@(#)storclass.h 10.1"
.def auxent; .scl 12; .type 011; .size 20; .endef
.def x_sym; .val 0; .scl 11; .size 20; .type 010; .endef
.def x_file; .val 0; .scl 11; .size 14; .type 010; .endef
.def x_scn; .val 0; .scl 11; .size 8; .type 010; .endef
.def x_tv; .val 0; .scl 11; .size 12; .type 010; .endef
.def .eos; .val 20; .scl 102; .tag auxent; .size 20; .endef
.def syment; .scl 10; .type 010; .size 20; .endef
.def _n; .val 0; .scl 8; .size 8; .type 011; .endef
.def n_value; .val 8; .scl 8; .type 04; .endef
.def n_scnum; .val 12; .scl 8; .type 03; .endef
.def n_type; .val 14; .scl 8; .type 015; .endef
.def n_sclass; .val 16; .scl 8; .type 02; .endef
.def n_numaux; .val 17; .scl 8; .type 02; .endef
.def .eos; .val 20; .scl 102; .tag syment; .size 20; .endef
.def .3fake; .scl 10; .type 010; .size 12; .endef
.def x_tvfill; .val 0; .scl 8; .type 04; .endef
.def x_tvlen; .val 4; .scl 8; .type 015; .endef
.def x_tvran; .val 6; .scl 8; .dim 2; .size 4; .type 075; .endef
.def .eos; .val 12; .scl 102; .tag .3fake; .size 12; .endef
.def .2fake; .scl 10; .type 010; .size 8; .endef
.def x_scnlen; .val 0; .scl 8; .type 04; .endef
.def x_nreloc; .val 4; .scl 8; .type 015; .endef
.def x_nlinno; .val 6; .scl 8; .type 015; .endef
.def .eos; .val 8; .scl 102; .tag .2fake; .size 8; .endef
.def .1fake; .scl 10; .type 010; .size 14; .endef
.def x_fname; .val 0; .scl 8; .dim 14; .size 14; .type 062; .endef
.def .eos; .val 14; .scl 102; .tag .1fake; .size 14; .endef
.def .0fake; .scl 10; .type 010; .size 20; .endef
.def x_tagndx; .val 0; .scl 8; .type 04; .endef
.def x_misc; .val 4; .scl 8; .size 4; .type 011; .endef
.def x_fcnary; .val 8; .scl 8; .size 8; .type 011; .endef
.def x_tvndx; .val 16; .scl 8; .type 015; .endef
.def .eos; .val 20; .scl 102; .tag .0fake; .size 20; .endef
.def .6fake; .scl 12; .type 011; .size 8; .endef
.def x_fcn; .val 0; .scl 11; .size 8; .type 010; .endef
.def x_ary; .val 0; .scl 11; .size 8; .type 010; .endef
.def .eos; .val 8; .scl 102; .tag .6fake; .size 8; .endef
.def .8fake; .scl 10; .type 010; .size 8; .endef
.def x_dimen; .val 0; .scl 8; .dim 4; .size 8; .type 075; .endef
.def .eos; .val 8; .scl 102; .tag .8fake; .size 8; .endef
.def .7fake; .scl 10; .type 010; .size 8; .endef
.def x_lnnoptr; .val 0; .scl 8; .type 04; .endef
.def x_endndx; .val 4; .scl 8; .type 04; .endef
.def .eos; .val 8; .scl 102; .tag .7fake; .size 8; .endef
.def .5fake; .scl 12; .type 011; .size 4; .endef
.def x_lnsz; .val 0; .scl 11; .size 4; .type 010; .endef
.def x_fsize; .val 0; .scl 11; .type 04; .endef
.def .eos; .val 4; .scl 102; .tag .5fake; .size 4; .endef
.def .9fake; .scl 10; .type 010; .size 4; .endef
.def x_lnno; .val 0; .scl 8; .type 015; .endef
.def x_size; .val 2; .scl 8; .type 015; .endef
.def .eos; .val 4; .scl 102; .tag .9fake; .size 4; .endef
.def .4fake; .scl 12; .type 011; .size 8; .endef
.def _n_name; .val 0; .scl 11; .dim 8; .size 8; .type 062; .endef
.def _n_n; .val 0; .scl 11; .size 8; .type 010; .endef
.def _n_nptr; .val 0; .scl 11; .dim 2; .size 8; .type 0162; .endef
.def .eos; .val 8; .scl 102; .tag .4fake; .size 8; .endef
.def .10fake; .scl 10; .type 010; .size 8; .endef
.def _n_zeroes; .val 0; .scl 8; .type 04; .endef
.def _n_offset; .val 4; .scl 8; .type 04; .endef
.def .eos; .val 8; .scl 102; .tag .10fake; .size 8; .endef
.def xsymcnt; .val xsymcnt; .scl 2; .type 04; .endef
.globl xsymcnt
.data
.align 4
xsymcnt:
.long 1
.text
.LC0:
.byte 0x78,0x73,0x79,0x6d,0x70,0x74,0x72,0x5b,0x30,0x5d
.byte 0x20,0x3d,0x20,0x25,0x78,0xa,0x0
.LC1:
.byte 0x6d,0x79,0x73,0x79,0x6d,0x74,0x61,0x62,0x20,0x61
.byte 0x64,0x64,0x72,0x65,0x73,0x73,0x20,0x3d,0x20,0x25
.byte 0x78,0xa,0x0
.LC2:
.byte 0x61,0x63,0x69,0x64,0x20,0x3d,0x20,0x25,0x64,0x2c
.byte 0x20,0x67,0x65,0x74,0x73,0x79,0x6d,0x20,0x3d,0x20
.byte 0x25,0x78,0xa,0x0
.align 4
.def main; .val main; .scl 2; .type 044; .endef
.globl main
main:
.ln 1
pushl %ebp
movl %esp,%ebp
.def .bf; .val .; .scl 101; .line 8; .endef
.ln 2
pushl $2000
call malloc
movl %eax,%eax
movl %eax,xsymptr
.ln 3
pushl xsymptr
pushl $.LC0
call printf
.ln 4
pushl $mysymtab
pushl $.LC1
call printf
.ln 5
pushl $50
call getsym
movl %eax,%eax
pushl %eax
pushl $50
pushl $.LC2
call printf
.ln 6
leal 36(%esp),%esp
pushl $202
call getsym
movl %eax,%eax
pushl %eax
pushl $202
pushl $.LC2
call printf
.ln 7
pushl $0
call exit
.ln 8
.L1:
.def .ef; .val .; .scl 101; .line 8; .endef
leave
ret
.def main; .val .; .scl -1; .endef
.LC3:
.byte 0x61,0x63,0x69,0x64,0x20,0x6e,0x65,0x67,0x61,0x74
.byte 0x69,0x76,0x65,0x0
.LC4:
.byte 0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x76,0x61
.byte 0x6c,0x75,0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x63
.byte 0x69,0x64,0x0
.align 4
.def getsym; .val getsym; .scl 2; .tag syment; .size 20; .type 0150; .endef
.globl getsym
getsym:
.ln 1
pushl %ebp
movl %esp,%ebp
subl $4,%esp
pushl %esi
pushl %ebx
.def .bf; .val .; .scl 101; .line 19; .endef
.def acid; .val 8; .scl 9; .type 04; .endef
.def acid; .val 3; .scl 4; .type 04; .endef
movl 8(%ebp),%ebx
.ln 4
testl %ebx,%ebx
jg .L3
.ln 5
pushl $.LC3
call printf
leal 4(%esp),%esp
.L3:
.ln 6
cmpl $200,%ebx
jg .L4
.ln 7
movl %ebx,%eax
leal (,%eax,4),%eax
movl %eax,-4(%ebp)
leal (%ebx,%eax),%esi
movl %esi,-4(%ebp)
leal (,%esi,4),%esi
movl %esi,-4(%ebp)
leal mysymtab(%esi),%eax
jmp .L2
.L4:
.ln 8
leal -201(%ebx),%ebx
.ln 9
imull $100,xsymcnt,%eax
movl %eax,-4(%ebp)
cmpl -4(%ebp),%ebx
jge .L5
===========================================================================
.ln 11
pushl $100
pushl %ebx
call __divsi3
leal 8(%esp),%esp
movl %eax,-4(%ebp)
movl %ebx,%eax
movl $100,%esi
cltd
idivl %esi
movl %eax,%ecx
movl %edx,%ecx
leal (,%ecx,4),%ecx
leal (%edx,%ecx),%edx
leal (,%edx,4),%edx
movl -4(%ebp),%eax
movl %edx,%eax
addl xsymptr(,%eax,4),%eax
===========================================================================
jmp .L2
.L5:
.ln 12
pushl $.LC4
call printf
.ln 13
.L2:
.def .ef; .val .; .scl 101; .line 13; .endef
leal -12(%ebp),%esp
popl %ebx
popl %esi
leave
ret
.def getsym; .val .; .scl -1; .endef
.def xsymptr; .val xsymptr; .scl 3; .tag syment; .size 20; .dim 100; .size 400; .type 0170; .endef
.data
xsymptr:
.set .,.+400
.text
.def mysymtab; .val mysymtab; .scl 3; .tag syment; .size 20; .dim 201; .size 4020; .type 070; .endef
.data
mysymtab:
.set .,.+4020
.text