[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: