On Mon, Jul 6, 2009 at 9:28 AM, John David Anglin<dave@xxxxxxxxxxxxxxxxxx> wrote: > Not that I am aware of. The situation is essentially the reverse of > the above. Data is written from a region of memory. Then, in another > instance of gcc, it needs to be mmap'ed back to the same location in > memory. In theory, it could be brought back to a different location > but this would require a fairly complex set of relocations. GCC does not read() and write to the mmap()'d file. The dynamic loader uses MAP_DENYWRITE to avoid writing into the mmap()'d memory. I will reiterate my point here that the dynamic linker the first user of mmap in a newly started process, and the first program to read and process data from the mmap'd files. Therefore the dynamic linker is always the first to suffer if a mapped region of memory is not correct. What we need to do here is create a test case. I tried this: 1. cp /lib/libc.so.6 original.so 2. cp /lib/libc.so.6 map.so 3. gcc -O2 -g -o test-mmap test-mmap.c 4. while true; do ./test-mmap ./original.so ./map.so; done; The test mmap's a file and compares it to the original, aborting if the comparison fails. I've yet to see it abort on my a500, and I've run 20-30 instances of the test simultaneously. Then again I don't see any serious segv's like others do (2.6.26-1-parisc64-smp). What might be a better testcase? Cheers, Carlos.
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> /* mmap */ #include <sys/types.h> /* open */ #include <sys/stat.h> /* open */ #include <fcntl.h> /* open */ #include <unistd.h> /* lseek */ #define BMAX 4096 int main (int argc, char **argv) { void *mappref; int fd, fdc; off_t maplength, index, j; char *original = argv[1], *copy = argv[2]; char buf[BMAX], *mbuf; ssize_t ret; /* Open original file to compute size. We open the original file to simulate having the fd open before mmap as the dynamic loader does. */ fd = open (original, O_RDONLY); if (fd == -1) { perror ("open"); abort (); } maplength = lseek (fd, 0, SEEK_END); if (fd == -1) { perror ("lseek"); abort (); } /* Now mmap the open file. */ mappref = mmap ((void *)mappref, maplength, PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_DENYWRITE | MAP_FILE, fd, 0); if (mappref == (void *)-1) { perror ("mmap"); abort (); } mbuf = (char *)mappref; /* Compare mmap to copy. */ fdc = open (copy, O_RDONLY); if (fdc == -1) { perror ("open #2"); abort (); } for (index = 0; index < maplength; index += BMAX) { ret = read (fdc, &buf[0], BMAX); if ((ret != BMAX) && (ret == -1)) { perror ("read"); abort (); } for (j = 0; ((j < BMAX) && ((index + j) < maplength)); j++) { if (mbuf[index + j] != buf[j]) { fprintf(stderr, "Mismatch at %ld, read %d, expected %d\n", index + j, (unsigned int)mbuf[index + j], (unsigned int)buf[j]); abort (); } if (DEBUG) printf ("Match at %ld, read %d, expected %d\n", index + j, (unsigned int)mbuf[index + j], (unsigned int)buf[j]); } } return 0; }