This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: fixincl mmap problem on Solaris
Bruce Korb wrote:
>
> Zack Weinberg wrote:
> >
> > On Tue, Sep 05, 2000 at 09:07:06AM -0700, Bruce Korb wrote:
> > >
> > > Anyway, "data_map_size" is specifically one byte larger
> > > than the specified file, and "man -S2 mmap" says:
> > >...
> > > pa = mmap(addr, len, prot, flags, fd, off);
> > >
> > > .... The address ranges covered by [pa,
> > > pa + len] and [off, off + len] must be legitimate for the possible
> > > (not necessarily current) address space of a process and the
> > > object in question, respectively. mmap cannot grow a file (see
> > > ftruncate(S)).
> >
> > The Solaris version of this manpage does not have the last sentence of
> > that paragraph. Instead there is another paragraph immediately following:
> >
> > The mmap() function allows [pa, pa + len) to extend beyond
> > the end of the object, ...
> > [but] Any reference to addresses beyond
> > the end of the object, however, will result in the delivery
> > of a SIGBUS or SIGSEGV signal. In other words, mmap() can-
> > not be used to implicitly extend the length of files.
>
> Except that this is utter nonsense. What is the possible point
> of extending the map beyond the end of the object if references
> to such addresses result in an addressing exception? This is
> what POSIX says:
>
> Description
>
> The mmap() function establishes a mapping between the process'
> address space and a memory object. The format of the call is as
> follows:
>
> pa = mmap(addr, len, prot, flags, fildes, off);
>
> The mmap() function establishes a mapping between the process'
> address space at an address, pa, for len bytes to the memory
> object represented by the file descriptor fildes at offset off
> for len bytes. The value of pa is a function of the parameter
> addr and the values of flags. A successful mmap() returns pa
> as its result. The address range starting at pa and continuing
> for len bytes is legitimate for the possible (not necessarily
> current) address space of the process. The range of bytes
> starting at off and continuing for len bytes is legitimate for
> the possible (but not necessarily current) offsets in the file or
> shared memory object represented by fildes.
>
> See:
>
> http://slacvx.slac.stanford.edu/HELP/POSIX/CALLABLE_FUNCTIONS/MMAP/DESCRIPTION
>
> The fact that the committee could not come up with consistent,
> unambiguous wording means that there were people on the committee
> that were too stubborn to allow a useful-for-text-files definition.
> Probably because they already had implementations and preferred
> inconsistency to changing their code. Yuck & shame on them.
>
> > My suggestion would be to notice when the file size is an exact
> > multiple of the page size, and map a page of /dev/zero right after it
> > using MAP_FIXED. If that fails, punt and read the file with read(2).
>
> Way too much work. Instead:
>
> data_map_size = stbf.st_size;
> ...
>
> if ((data_map_size & (PAGESIZE-1)) == 0)
> res = BAD_ADDR
> else
> res = (char*)mmap ((void*)NULL, data_map_size, PROT_READ,
> MAP_PRIVATE, data_map_fd, 0);
> if (res == (char*)BAD_ADDR)
> {
> curr_data_mapped = BOOL_FALSE;
> res = load_file_data ( fdopen (data_map_fd, "r"));
> }
Yep that should do the trick. It's simple and we'll still
be using mmap for 99% of the files.
Graham