Re: HPPA and Squeeze
On Mon, Jul 6, 2009 at 9:28 AM, John David
Anglin<dave@hiauly1.hia.nrc.ca> 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;
}
Reply to: