This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Wierd sparc sunos4 intermittant SEGV during bootstrap in libgcc2.a
- To: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Subject: Re: Wierd sparc sunos4 intermittant SEGV during bootstrap in libgcc2.a
- From: Jim Wilson <wilson at cygnus dot com>
- Date: Sat, 11 Mar 2000 18:11:48 -0800
- cc: davem at redhat dot com, egcs-bugs at egcs dot cygnus dot com, rth at cygnus dot com
I looked, and found a bad sunos4 cc1plus binary, so I debugged it to get the
exact strncmp call I needed. Then I combined it with the loop-2e.c c-torture
testcase which uses mmap. The resulting program core dumps in w2cmp, a
subroutine of strncmp, when I compile it with gcc. (It doesn't fail for cc
because cc doesn't define __unix__.)
I got the exact circumstances slightly wrong. The first string is unaligned.
It doesn't matter whether the second is aligned or not. strncmp reads enough
bytes to align the first string which unaligns the second string. Then it
starts reading a word ahead to extract an aligned word for the second string.
This testcase can probably be simplified a bit more.
#include <limits.h>
#ifdef __unix__ /* ??? Is that good enough? */
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef MAP_ANON
#ifdef MAP_ANONYMOUS
#define MAP_ANON MAP_ANONYMOUS
#else
#define MAP_ANON MAP_FILE
#endif
#endif
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
#ifndef MAP_FIXED
#define MAP_FIXED 0
#endif
#endif
#define MAP_START (void *)0x7fff8000
#define MAP_LEN 0x10000
main ()
{
#ifdef MAP_ANON
void *p;
int dev_zero;
dev_zero = open ("/dev/zero", O_RDONLY);
/* -1 is OK when we have MAP_ANON; else mmap will flag an error. */
if (INT_MAX != 0x7fffffffL || sizeof (char *) != sizeof (int))
exit (0);
p = mmap (MAP_START, MAP_LEN, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_PRIVATE, dev_zero, 0);
if (p != (void *)-1)
{
char string[] = "__si_type_info";
char *q = p + MAP_LEN - strlen (string) - 2;
char *r = p + 0xe;
strcpy (q, string);
strcpy (r, string);
strncmp (r, q, 14);
}
#endif
exit (0);
}