This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: fixincl mmap problem on Solaris
- To: Graham Stott <grahams at redhat dot com>
- Subject: Re: fixincl mmap problem on Solaris
- From: Bruce Korb <bkorb at sco dot COM>
- Date: Tue, 05 Sep 2000 09:07:06 -0700
- CC: bkorb at gnu dot org, GNU Compiler <gcc at gcc dot gnu dot org>
- Organization: The Santa Cruz Operation
- References: <39B4DB2D.8EFE0C77@redhat.com>
Hi Graham,
Long time. So, now you are at Red Hat, & I'm at SCO.
Are you still local to San Jose?
Anyway, "data_map_size" is specifically one byte larger
than the specified file, and "man -S2 mmap" says:
Description
===========
The function mmap establishes a mapping between a process's address space
and a virtual memory object. The format of the call is:
pa = mmap(addr, len, prot, flags, fd, off);
mmap establishes a mapping between the process's address space at an address
pa for len bytes to the memory object represented by the file descriptor
fd at offset off for len bytes. The value of pa is an
implementation-dependent function of the parameter addr and values of flags,
further described below. A successful mmap call returns pa as its result.
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)).
My reading of this is that Solaris may choose to fail if I try
to map more data than there are in the file, but that it would
be an extremely lame implementation were it to do so. What is
*not* an option is to fail to map the page after the file's data.
So, the correct thing is to add configury hacks to test for this
broken implementation and declare that mmap does not work in this
case. Thus, "HAVE_MMAP_FILE" would not be defined. Yuck!
Graham Stott wrote:
> The problem would appear to be this use of mmap
> in gcc/fixinc/fixincl.c:
>
> data_map_size = stbf.st_size+1;
> ...
> curr_data_mapped = BOOL_TRUE;
> 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"));
> }
>
> fixinc expects to be able to read the implied NUL character
> at res[data_map_size-1] but any attempt to do so when mapping
> a fix which is a multiple of the systems page size results in
> a SIGBUS exception. (i.e. If I put a breakpoint after
> the mmap call and try to access res[data_map_size-1] gdb says
> that the address is invalid)
>
> The problem does not show up on Linux and I'm not sure
> which implementation of mmap is correct.
Solaris is definitely wrong. Linus (or agent) chose an
implementation that conforms with the man page cited above.
I think returning "BAD_ADDR" would also be conforming,
just very lame.