jhh%sprite.Berkeley.EDU@GINGER.BERKELEY.EDU (John H. Hartman) (04/05/89)
I've enclosed a file that causes cc1 to crash when compiled for the spur. cc -O -mspur -mlong-jumps -c foo.c" will do it. I tried to debug it but didn't get very far and decided to leave it for the experts. I did track it down to equiv_constant() indexing the mode_size array by a bogus value. Omitting the "-O" option avoids the problem. John H. Hartman --- cut here --- # 1 "vfprintf.c" static char rcsid[] = "$Header: /sprite/src/lib/c/stdio/RCS/vfprintf.c,v 1.5 88/10/23 15:39:51 ouster Exp $ SPRITE (Berkeley)"; # 1 "/sprite/lib/include/ctype.h" extern int isalnum(); extern int isalpha(); extern int isascii(); extern int iscntrl(); extern int isdigit(); extern int isgraph(); extern int islower(); extern int isprint(); extern int ispunct(); extern int isspace(); extern int isupper(); extern int isxdigit(); extern int tolower(); extern int toupper(); extern char _ctype_bits[]; # 20 "vfprintf.c" # 1 "/sprite/lib/include/stdio.h" typedef int *ClientData; typedef struct _file { unsigned char *lastAccess; int readCount; int writeCount; unsigned char *buffer; int bufSize; void (*readProc)(); void (*writeProc)(); int (*closeProc)(); ClientData clientData; int status; int flags; struct _file *nextPtr; } FILE; extern FILE stdioInFile, stdioOutFile, stdioErrFile; extern void clearerr(); extern int fclose(); extern FILE * fdopen(); extern int fflush(); extern int fgetc(); extern char * fgets(); extern int fileno(); extern FILE * fopen(); extern int fprintf(); extern int fputc(); extern int fputs(); extern int fread(); extern FILE * freopen(); extern int fscanf(); extern long fseek(); extern long ftell(); extern int fwrite(); extern char * gets(); extern int getw(); extern void perror(); extern int printf(); extern int puts(); extern int putw(); extern void rewind(); extern int scanf(); extern void setbuf(); extern void setbuffer(); extern void setlinebuf(); extern int setvbuf(); extern char * sprintf(); extern int sscanf(); extern FILE * tmpfile(); extern char * tmpnam(); extern char * tempnam(); extern int ungetc(); extern int vfprintf(); extern int vfscanf(); extern int vprintf(); extern char * vsprintf(); extern void _cleanup(); extern void Stdio_Setup(); # 21 "vfprintf.c" # 1 "/sprite/lib/include/stdlib.h" extern double atof(); extern int atoi(); extern long int atol(); extern double strtod(); extern long int strtol(); extern unsigned long strtoul(); extern char * alloca(); extern char * calloc(); extern char * malloc(); extern char * realloc(); extern void Mem_Bin(); extern char * Mem_CallerPC(); extern void Mem_DumpTrace(); extern void Mem_PrintConfig(); extern void Mem_PrintInUse(); extern void Mem_PrintStats(); extern void Mem_PrintStatsInt(); extern void Mem_SetPrintProc(); extern void Mem_SetTraceSizes(); extern int Mem_Size(); # 66 "/sprite/lib/include/stdlib.h" extern free(); typedef struct { int size; int flags; } Mem_TraceInfo; extern int mem_SmallMinNum; extern int mem_LargeMinNum; extern int mem_LargeMaxSize; extern int mem_NumAllocs; extern int mem_NumFrees; typedef struct div_t { int quot; int rem; } div_t; typedef struct { long int quot; long int rem; } ldiv_t; extern int abs(); extern div_t div(); extern long int labs(); extern ldiv_t ldiv(); extern void abort(); extern int atexit(); extern exit(); extern char * getenv(); extern void qsort(); extern int rand(); extern long random(); extern void setenv(); extern srand(); extern srandom(); extern int system(); # 22 "vfprintf.c" # 1 "/sprite/lib/include/string.h" extern char * memchr(); extern int memcmp(); extern char * memcpy(); extern char * memset(); extern char * strcat(); extern char * strchr(); extern int strcmp(); extern char * strcpy(); extern int strcspn(); extern char * strerror(); extern int strlen(); extern char * strncat(); extern int strncmp(); extern char * strncpy(); extern char * strpbrk(); extern char * strrchr(); extern int strspn(); extern char * strstr(); extern char * strtok(); extern char *index(); extern char *rindex(); # 23 "vfprintf.c" # 1 "/sprite/lib/include/spur.md/varargs.h" struct va_struct { char regs[20]; }; typedef struct { int pnt; char *regs; char *stack; } va_list; # 128 "/sprite/lib/include/spur.md/varargs.h" # 24 "vfprintf.c" static char * CvtUtoA(i, base, buf, lengthPtr) register unsigned i; register int base; register char *buf; int *lengthPtr; { register char *p; if (i == 0) { buf[0] = '0'; buf[1] = 0; *lengthPtr = 1; return buf; } p = &buf[33 -1]; *p = 0; switch (base) { case 2: while (i != 0) { p -= 1; *p = '0' + (i & 01); i >>= 1; } break; case 8: while (i != 0) { p -= 1; *p = '0' + (i & 07); i >>= 3; } break; case 16: while (i !=0) { p -= 1; *p = '0' + (i & 0xf); if (*p > '9') { *p += 'a' - '9' - 1; } i >>= 4; } break; default: while (i != 0) { p -= 1; *p = '0' + (i % base); if (*p > '9') { *p += 'a' - '9' - 1; } i /= base; } break; } *lengthPtr = (&buf[33 -1] - p); return p; } static int CvtFtoA(value, numDigits, afterPoint, pointPtr, signPtr, buf) double value; int numDigits; int afterPoint; int *pointPtr; int *signPtr; char *buf; { extern double modf(); register char *p; double fraction, intPart; int i, numDigits2; char tmpBuf[320 ]; if (value < 0.0) { *signPtr = 1 ; value = -value; } else { *signPtr = 0 ; } fraction = modf(value, &intPart); *pointPtr = 0; for (p = &tmpBuf[320 -1]; intPart != 0; p -= 1) { double tmp; char digit; tmp = modf(intPart/10.0, &intPart); digit = (tmp * 10.0) + .2; *p = digit + '0'; *pointPtr += 1; } p++; for (i = 0; (i <= numDigits) && (p <= &tmpBuf[320 -1]); i++, p++) { buf[i] = *p; } if (value == 0.0) { buf[0] = '0'; i = 1; *pointPtr = 1; } if ((i == 0) && (fraction > 0)) { while (fraction < .1) { fraction *= 10.0; *pointPtr -= 1; }; } numDigits2 = afterPoint + *pointPtr; if ((afterPoint < 0) || (numDigits2 > numDigits)) { numDigits2 = numDigits; } for ( ; i <= numDigits2; i++) { double tmp; char digit; fraction = modf(fraction*10.0, &tmp); digit = tmp; buf[i] = digit + '0'; } if ((numDigits2 >= 0) && (buf[numDigits2] >= '5')) { for (i = numDigits2-1; ; i--) { if (i < 0) { int j; for (j = numDigits2; j > 0; j--) { buf[j] = buf[j-1]; } if (numDigits2 < numDigits) { numDigits2++; } (*pointPtr)++; buf[0] = '1'; break; } buf[i] += 1; if (buf[i] <= '9') { break; } buf[i] = '0'; } } if (numDigits2 <= 0) { numDigits2 = 0; *pointPtr = -afterPoint; } buf[numDigits2] = 0; return numDigits2; } int vfprintf(stream, format, args) register FILE *stream; register char *format; va_list args; { int leftAdjust; int minWidth; int precision; int altForm; register char c; char pad; char buf[320 +10]; char expBuf[33 ]; char *prefix; register char *field; int actualLength; int point; int sign; int i, tmp; int charsPrinted = 0; char *end; for (c = *format; c != 0; format++, c = *format) { if (c != '%') { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(c, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = c)) ; charsPrinted += 1; continue; } leftAdjust = 0 ; pad = ' '; minWidth = 0; precision = -1; altForm = 0 ; prefix = ""; format++; c = *format; while (1 ) { if (c == '-') { leftAdjust = 1 ; } else if (c == '0') { pad = '0'; } else if (c == '#') { altForm = 1 ; } else { break; } format++; c = *format; } if (((_ctype_bits+1)[c] & 0x04 ) ) { minWidth = strtoul(format, &end, 10); format = end; c = *format; } else if (c == '*') { minWidth = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( int *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; format++; c = *format; } if (c == '.') { format++; c = *format; } if (((_ctype_bits+1)[c] & 0x04 ) ) { precision = strtoul(format, &end, 10); format = end; c = *format; } else if (c == '*') { precision = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( int *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; format++; c = *format; } if (c == 'l') { format++; c = *format; } field = buf; actualLength = 0; switch (c) { case 'D': case 'd': i = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( int *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; if (i < 0) { prefix = "-"; i = -i; actualLength = 1; } field = CvtUtoA((unsigned) i, 10, buf, &tmp); actualLength += tmp; break; case 'O': case 'o': i = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( int *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; if (altForm && (i != 0)) { prefix = "0"; actualLength = 1; } field = CvtUtoA((unsigned) i, 8, buf, &tmp); actualLength += tmp; break; case 'X': case 'x': i = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( int *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; field = CvtUtoA((unsigned) i, 16, buf, &actualLength); if (altForm) { char *p; if (c == 'X') { if (i != 0) { prefix = "0X"; actualLength += 2; } for (p = field; *p != 0; p++) { if (*p >= 'a') { *p += 'A' - 'a'; } } } else if (i != 0) { prefix = "0x"; actualLength += 2; } } break; case 'U': case 'u': field = CvtUtoA(({ unsigned va_result; if ((args).pnt >= 20) { va_result = *( ( unsigned *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( unsigned) + 7) & ~7; } else if ((args).pnt + sizeof( unsigned) > 20) { va_result = * ( unsigned *) (args).stack; (args).pnt = 20 + ( (sizeof( unsigned) + 7) & ~7); } else if (sizeof( unsigned) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( unsigned *) & u; (args).pnt += 8; } else { va_result = * ( unsigned *) ((args).regs + (args).pnt); (args).pnt += (sizeof( unsigned) + 3) & ~3; } va_result; }) , 10, buf, &actualLength); break; case 's': field = ({ char * va_result; if ((args).pnt >= 20) { va_result = *( ( char * *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( char *) + 7) & ~7; } else if ((args).pnt + sizeof( char *) > 20) { va_result = * ( char * *) (args).stack; (args).pnt = 20 + ( (sizeof( char *) + 7) & ~7); } else if (sizeof( char *) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( char * *) &u; (args).pnt += 8; } el se { va_result = * ( char * *) ((args).regs + (args).pnt); (args).pnt += (sizeof( char *) + 3) & ~3; } va_result; }) ; if (field == (char *) 0 ) { field = "(NULL)"; } actualLength = strlen(field); if ((precision > 0) && (precision < actualLength)) { actualLength = precision; } pad = ' '; break; case 'c': buf[0] = ({ int va_result; if ((args).pnt >= 20) { va_result = *( ( int *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( int) + 7) & ~7; } else if ((args).pnt + sizeof( int) > 20) { va_result = * ( int *) (args).stack; (args).pnt = 20 + ( (sizeof( int) + 7) & ~7); } else if (sizeof( int) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( int *) &u; (args).pnt += 8; } else { va_result = * ( in t *) ((args).regs + (args).pnt); (args).pnt += (sizeof( int) + 3) & ~3; } va_result; }) ; actualLength = 1; pad = ' '; break; case 'F': case 'f': if (precision < 0) { precision = 6; } else if (precision > 320 ) { precision = 320 ; } actualLength = CvtFtoA(({ double va_result; if ((args).pnt >= 20) { va_result = *( ( double *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( double) + 7) & ~7; } else if ((args).pnt + sizeof( double) > 20) { va_result = * ( double *) (args).stack; (args).pnt = 20 + ( (sizeof( double) + 7) & ~7); } else if (sizeof( double) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( double *) &u; (args) pnt += 8; } else { va_result = * ( double *) ((args).regs + (args).pnt); (args).pnt += (sizeof( double) + 3) & ~3; } va_result; }) , 320 , precision, &point, &sign, field); if (point <= 0) { actualLength += 1 - point; } if ((precision != 0) || (altForm)) { actualLength += 1; } if (sign) { prefix = "-"; actualLength += 1; } c = 'f'; break; case 'E': case 'e': if (precision < 0) { precision = 6; } else if (precision > 320 -1) { precision = 320 -1; } (void) CvtFtoA(({ double va_result; if ((args).pnt >= 20) { va_result = *( ( double *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( double) + 7) & ~7; } else if ((args).pnt + sizeof( double) > 20) { va_result = * ( double *) (args).stack; (args).pnt = 20 + ( (sizeof( double) + 7) & ~7); } else if (sizeof( double) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( double *) &u; (args).pnt += 8; } else { va_result = * ( double *) ((args).regs + (args).pnt); (args).pnt += (sizeof( double) + 3) & ~3; } va_result; }) , precision+1, -1, &point, &sign, &buf[1]); eFromG: buf[0] = buf[1]; buf[1] = '.'; if ((precision != 0) || (altForm)) { field = buf + precision + 2; } else { field = &buf[1]; } *field = c; field++; point--; if (point < 0) { *field = '-'; point = -point; } else { *field = '+'; } field++; if (point < 10) { *field = '0'; field++; } strcpy(field, CvtUtoA((unsigned) point, 10, expBuf, &i)); actualLength = (field - buf) + i; field = buf; if (sign) { prefix = "-"; actualLength += 1; } break; case 'G': case 'g': { int eLength, fLength; if (precision < 0) { precision = 6; } else if (precision > 320 -1) { precision = 320 -1; } else if (precision == 0) { precision = 1; } actualLength = CvtFtoA(({ double va_result; if ((args).pnt >= 20) { va_result = *( ( double *) ((args).stack + (args).pnt - 20)); (args).pnt += (sizeof( double) + 7) & ~7; } else if ((args).pnt + sizeof( double) > 20) { va_result = * ( double *) (args).stack; (args).pnt = 20 + ( (sizeof( double) + 7) & ~7); } else if (sizeof( double) == 8) { union {double d; int i[2];} u; u.i[0] = *(int *) ((args).regs + (args).pnt); u.i[1] = *(int *) ((args).regs + (args).pnt + 4); va_result = * ( double *) &u; (args) pnt += 8; } else { va_result = * ( double *) ((args).regs + (args).pnt); (args).pnt += (sizeof( double) + 3) & ~3; } va_result; }) , precision, -1, &point, &sign, &buf[1]); if (!altForm) { for ( ; actualLength > 1; actualLength--) { if (buf[actualLength] != '0') { break; } } } if ((actualLength > 1) || altForm) { eLength = actualLength + 5; } else { eLength = actualLength + 4; } if (point <= 0) { fLength = actualLength + 2 - point; } else { fLength = actualLength; if (point < actualLength) { fLength += 1; } else if (altForm) { fLength = point + 1; } else { fLength = point; } } if ((eLength < fLength) || (point > precision)) { c += 'E' - 'G'; precision = actualLength-1; goto eFromG; } c = 'f'; field = &buf[1]; actualLength = fLength; if (sign) { prefix = "-"; actualLength += 1; } break; } case '%': (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc('%', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = '%')) ; charsPrinted += 1; goto endOfField; case 0: return charsPrinted; default: (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(c, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = c)) ; charsPrinted += 1; goto endOfField; } if (!leftAdjust) { if (pad == '0') { for ( ; *prefix != 0; prefix++) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(*prefix, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = *prefix)) ; charsPrinted += 1; actualLength--; minWidth--; } } while (minWidth > actualLength) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(pad, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = pad)) ; charsPrinted += 1; minWidth --; } } minWidth -= actualLength; for ( ; *prefix != 0; prefix++) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(*prefix, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = *prefix)) ; charsPrinted += 1; actualLength--; } if (c == 'f') { if (point <= 0) { if (actualLength > 0) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc('0', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = '0')) ; charsPrinted += 1; point++; actualLength--; } if (actualLength > 0) { charsPrinted += 1; (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc('.', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = '.')) ; actualLength--; } while ((point <= 0) && (actualLength > 0)) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc('0', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = '0')) ; charsPrinted += 1; point++; actualLength--; } } else { while ((point > 0) && (actualLength > 0)) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(*field, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = *field)) ; charsPrinted += 1; field++; point--; actualLength--; } if (actualLength > 0) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc('.', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = '.')) ; charsPrinted += 1; actualLength--; } } } charsPrinted += actualLength; for ( ; actualLength > 0; actualLength--, field++) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(*field, stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = *field)) ; } while (minWidth > 0) { (((( stream)->writeCount <= 1) || (( stream)->flags & 8 )) ? fputc(' ', stream) : (( stream)->writeCount -= 1, ( stream)->lastAccess += 1, *( stream)->lastAccess = ' ')) ; charsPrinted += 1; minWidth --; } endOfField: continue; } return charsPrinted; }