Branch data Line data Source code
1 : : /* Return a pointer to a zero-size object in memory.
2 : : Copyright (C) 2009-2012 Free Software Foundation, Inc.
3 : :
4 : : This program is free software: you can redistribute it and/or modify
5 : : it under the terms of the GNU General Public License as published by
6 : : the Free Software Foundation; either version 3 of the License, or
7 : : (at your option) any later version.
8 : :
9 : : This program is distributed in the hope that it will be useful,
10 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : GNU General Public License for more details.
13 : :
14 : : You should have received a copy of the GNU General Public License
15 : : along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 : :
17 : : /* ISO C 99 does not allow memcmp(), memchr() etc. to be invoked with a NULL
18 : : argument. Therefore this file produces a non-NULL pointer which cannot
19 : : be dereferenced, if possible. */
20 : :
21 : : #include <stdlib.h>
22 : :
23 : : /* Test whether mmap() and mprotect() are available.
24 : : We don't use HAVE_MMAP, because AC_FUNC_MMAP would not define it on HP-UX.
25 : : HAVE_MPROTECT is not enough, because mingw does not have mmap() but has an
26 : : mprotect() function in libgcc.a. */
27 : : #if HAVE_SYS_MMAN_H && HAVE_MPROTECT
28 : : # include <fcntl.h>
29 : : # include <unistd.h>
30 : : # include <sys/types.h>
31 : : # include <sys/mman.h>
32 : : /* Define MAP_FILE when it isn't otherwise. */
33 : : # ifndef MAP_FILE
34 : : # define MAP_FILE 0
35 : : # endif
36 : : #endif
37 : :
38 : : /* Return a pointer to a zero-size object in memory (that is, actually, a
39 : : pointer to a page boundary where the previous page is readable and writable
40 : : and the next page is neither readable not writable), if possible.
41 : : Return NULL otherwise. */
42 : :
43 : : static void *
44 : 2 : zerosize_ptr (void)
45 : : {
46 : : /* Use mmap and mprotect when they exist. Don't test HAVE_MMAP, because it is
47 : : not defined on HP-UX 11 (since it does not support MAP_FIXED). */
48 : : #if HAVE_SYS_MMAN_H && HAVE_MPROTECT
49 : : # if HAVE_MAP_ANONYMOUS
50 : 2 : const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
51 : 2 : const int fd = -1;
52 : : # else /* !HAVE_MAP_ANONYMOUS */
53 : : const int flags = MAP_FILE | MAP_PRIVATE;
54 : : int fd = open ("/dev/zero", O_RDONLY, 0666);
55 : : if (fd >= 0)
56 : : # endif
57 : : {
58 : 2 : int pagesize = getpagesize ();
59 : 2 : char *two_pages =
60 : 2 : (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
61 : : flags, fd, 0);
62 [ + - ]: 2 : if (two_pages != (char *)(-1)
63 [ + - ]: 2 : && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
64 : 2 : return two_pages + pagesize;
65 : : }
66 : : #endif
67 : 2 : return NULL;
68 : : }
|