Speeding up wineserver syncronization objects with shared memory
David Howells
dhowells at cambridge.redhat.com
Thu Mar 8 02:15:24 CST 2001
> Page alignment is needed for the address in memory, not for the offset
> inside the file on disk; since section virtual addresses in PE files
> are always page-aligned the memory address is never a problem. The
> only problem comes from the alignment of the data inside the PE file,
> and this is where we only need block-size alignment to make mmap
> possible.
Not so... The file offset must also be page aligned!
Try the following program:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(int argc, char **argv)
{
void *addr;
int fd;
fd = open("/bin/sh",O_RDONLY);
if (fd<0) { perror("mmap"); return 1; }
addr = mmap(NULL,512,PROT_READ,MAP_PRIVATE,fd,argc==1?512:4096);
if (addr==MAP_FAILED) { perror("mmap"); return 1; }
return 0;
}
If you don't run it with an argument, it fails (Invalid Argument), and if you
do give it an argument, it works.
If you look at the kernel:
[arch/i386/kernel/sys_i386.c]
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
struct mmap_arg_struct a;
int err = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
goto out;
err = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;
err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
return err;
}
Note that "a.offset" (the file offset) is checked for page alignment. Note
also that the internal kernel routine do_mmap2() deals with the offset in
terms of pages, not bytes.
David
More information about the wine-devel
mailing list