2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-23 14:11:05 +08:00

c-pch.c (c_common_no_more_pch): Update for gt_pch_use_address extra arguments.

* c-pch.c (c_common_no_more_pch): Update for gt_pch_use_address
        extra arguments.
        * config.host (*-*-solaris2*, *-*-linux*): Add out_host_hook_obj
        and host_xmake_file fragments.
        * ggc-common.c (gt_pch_save): Update for gt_pch_get_address change.
        (gt_pch_restore): Similarly for gt_pch_use_address.
        (default_gt_pch_get_address): New.
        (mmap_gt_pch_get_address): Split out of gt_pch_save.
        (default_gt_pch_use_address): Split out of gt_pch_restore.
        (mmap_gt_pch_use_address): Likewise.
        * hooks.c (hook_voidp_size_t_null): Remove.
        (hook_bool_voidp_size_t_false): Remove.
        * hooks.h: Likewise.
        * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): Use one of the
        default_ or mmap_ definitions.
        (HOST_HOOKS_GT_PCH_USE_ADDRESS): Likewise.
        * hosthooks.h (struct host_hooks): Update gt_pch_get_address
        and gt_pch_use_address.
        * config/host-linux.c, config/host-solaris.c: New files.
        * config/x-linux, config/x-solaris: New files.
        * config/rs6000/host-darwin.c darwin_rs6000_gt_pch_get_address):
        Update for changed definition.
        (darwin_rs6000_gt_pch_use_address): Likewise.
        * doc/hostconfig.texi: Update docs.

From-SVN: r79295
This commit is contained in:
Richard Henderson 2004-03-10 19:19:04 -08:00 committed by Richard Henderson
parent 20475e78e4
commit 4d0c31e68c
14 changed files with 405 additions and 167 deletions

@ -1,3 +1,30 @@
2004-03-10 Richard Henderson <rth@redhat.com>
* c-pch.c (c_common_no_more_pch): Update for gt_pch_use_address
extra arguments.
* config.host (*-*-solaris2*, *-*-linux*): Add out_host_hook_obj
and host_xmake_file fragments.
* ggc-common.c (gt_pch_save): Update for gt_pch_get_address change.
(gt_pch_restore): Similarly for gt_pch_use_address.
(default_gt_pch_get_address): New.
(mmap_gt_pch_get_address): Split out of gt_pch_save.
(default_gt_pch_use_address): Split out of gt_pch_restore.
(mmap_gt_pch_use_address): Likewise.
* hooks.c (hook_voidp_size_t_null): Remove.
(hook_bool_voidp_size_t_false): Remove.
* hooks.h: Likewise.
* hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): Use one of the
default_ or mmap_ definitions.
(HOST_HOOKS_GT_PCH_USE_ADDRESS): Likewise.
* hosthooks.h (struct host_hooks): Update gt_pch_get_address
and gt_pch_use_address.
* config/host-linux.c, config/host-solaris.c: New files.
* config/x-linux, config/x-solaris: New files.
* config/rs6000/host-darwin.c darwin_rs6000_gt_pch_get_address):
Update for changed definition.
(darwin_rs6000_gt_pch_use_address): Likewise.
* doc/hostconfig.texi: Update docs.
2004-03-10 Richard Henderson <rth@redhat.com>
PR c/14517

@ -401,6 +401,6 @@ c_common_no_more_pch (void)
if (cpp_get_callbacks (parse_in)->valid_pch)
{
cpp_get_callbacks (parse_in)->valid_pch = NULL;
host_hooks.gt_pch_use_address (NULL, 0);
host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
}
}

@ -113,6 +113,8 @@ case ${host} in
;;
i[34567]86-*-solaris2*)
host_xm_defines="SMALL_ARG_MAX"
out_host_hook_obj=host-solaris.o
host_xmake_file=x-solaris
;;
i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
host_xm_defines="SMALL_ARG_MAX"
@ -152,4 +154,12 @@ case ${host} in
out_host_hook_obj=host-darwin.o
host_xmake_file=rs6000/x-darwin
;;
*-*-solaris2*)
out_host_hook_obj=host-solaris.o
host_xmake_file=x-solaris
;;
*-*-linux*)
out_host_hook_obj=host-linux.o
host_xmake_file=x-linux
;;
esac

137
gcc/config/host-linux.c Normal file

@ -0,0 +1,137 @@
/* Linux host-specific hook definitions.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include <sys/mman.h>
#include "hosthooks.h"
#include "hosthooks-def.h"
/* Linux has a feature called exec-shield-randomize that perturbs the
address of non-fixed mapped segments by a (relatively) small amount.
The feature is intended to make it harder to attack the system with
buffer overflow attacks, since every invocation of a program will
have its libraries and data segments at slightly different addresses.
This feature causes us problems with PCH because it makes it that
much harder to acquire a stable location at which to map our PCH
data file.
[ The feature causes other points of non-determinism within the
compiler as well, so we'd *really* like to be able to have the
driver disable exec-shield-randomize for the process group, but
that isn't possible at present. ]
We're going to try several things:
* Select an architecture specific address as "likely" and see
if that's free. For our 64-bit hosts, we can easily choose
an address in Never Never Land.
* If exec-shield-randomize is disabled, then just use the
address chosen by mmap in step one.
* If exec-shield-randomize is enabled, then temporarily allocate
32M of memory as a buffer, then allocate PCH memory, then
free the buffer. The theory here is that the perturbation is
no more than 16M, and so by allocating our buffer larger than
that we make it considerably more likely that the address will
be free when we want to load the data back.
*/
#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
#define HOST_HOOKS_GT_PCH_GET_ADDRESS linux_gt_pch_get_address
/* For various ports, try to guess a fixed spot in the vm space
that's probably free. */
#if defined(__alpha)
# define TRY_EMPTY_VM_SPACE 0x10000000000
#elif defined(__ia64)
# define TRY_EMPTY_VM_SPACE 0x2000000100000000
#elif defined(__x86_64)
# define TRY_EMPTY_VM_SPACE 0x1000000000
#elif defined(__i386)
# define TRY_EMPTY_VM_SPACE 0x60000000
#else
# define TRY_EMPTY_VM_SPACE 0
#endif
/* Determine a location where we might be able to reliably allocate SIZE
bytes. FD is the PCH file, though we should return with the file
unmapped. */
static void *
linux_gt_pch_get_address (size_t size, int fd)
{
size_t buffer_size = 32 * 1024 * 1024;
void *addr, *buffer;
FILE *f;
bool randomize_on;
addr = mmap ((void *)TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
/* If we failed the map, that means there's *no* free space. */
if (addr == (void *) MAP_FAILED)
return NULL;
/* Unmap the area before returning. */
munmap (addr, size);
/* If we got the exact area we requested, then that's great. */
if (TRY_EMPTY_VM_SPACE && addr == (void *) TRY_EMPTY_VM_SPACE)
return addr;
/* If we didn't, then we need to look to see if randomization is on. */
f = fopen ("/proc/sys/kernel/exec-shield-randomize", "r");
randomize_on = false;
if (f != NULL)
{
char buf[100];
size_t c;
c = fread (buf, 1, sizeof buf - 1, f);
if (c > 0)
{
buf[c] = '\0';
randomize_on = (atoi (buf) > 0);
}
fclose (f);
}
/* If it isn't, then accept the address that mmap selected as fine. */
if (!randomize_on)
return addr;
/* Otherwise, we need to try again with buffer space. */
buffer = mmap (0, buffer_size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (buffer != (void *) MAP_FAILED)
munmap (buffer, buffer_size);
if (addr == (void *) MAP_FAILED)
return NULL;
munmap (addr, size);
return addr;
}
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;

79
gcc/config/host-solaris.c Normal file

@ -0,0 +1,79 @@
/* Solaris host-specific hook definitions.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include <sys/mman.h>
#include "hosthooks.h"
#include "hosthooks-def.h"
#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
#define HOST_HOOKS_GT_PCH_USE_ADDRESS sol_gt_pch_use_address
/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at
mapping the data at BASE, -1 if we couldn't. */
static int
sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
{
void *addr;
/* We're called with size == 0 if we're not planning to load a PCH
file at all. This allows the hook to free any static space that
we might have allocated at link time. */
if (size == 0)
return -1;
addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
/* Solaris isn't good about honoring the mmap START parameter
without MAP_FIXED set. Before we give up, search the desired
address space with mincore to see if the space is really free.
if (addr != base)
{
size_t page_size = getpagesize();
char one_byte;
size_t i;
if (addr != (void *) MAP_FAILED)
munmap (addr, size);
errno = 0;
for (i = 0; i < size; i += page_size)
if (mincore ((char *)base + i, page_size, (void *)&one_byte) == -1
&& errno == ENOMEM)
continue; /* The page is not mapped. */
else
break;
if (i >= size)
addr = mmap (base, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fd, offset);
}
return addr == base ? 1 : -1;
}
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;

@ -137,22 +137,18 @@ darwin_rs6000_extra_signals (void)
fatal_error ("While setting up signal handler: %m");
}
static void * darwin_rs6000_gt_pch_get_address (size_t);
static bool darwin_rs6000_gt_pch_use_address (void *, size_t);
#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
#define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address
#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
#define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address
/* Yes, this is really supposed to work. */
static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096)));
/* Return the address of the PCH address space, if the PCH will fit in it. */
static void *
darwin_rs6000_gt_pch_get_address (size_t sz)
darwin_rs6000_gt_pch_get_address (size_t sz, int fd ATTRIBUTE_UNUSED)
{
if (sz <= sizeof (pch_address_space))
return pch_address_space;
@ -163,11 +159,12 @@ darwin_rs6000_gt_pch_get_address (size_t sz)
/* Check ADDR and SZ for validity, and deallocate (using munmap) that part of
pch_address_space beyond SZ. */
static bool
darwin_rs6000_gt_pch_use_address (void *addr, size_t sz)
static int
darwin_rs6000_gt_pch_use_address (void *addr, size_t sz, int fd, size_t off)
{
const size_t pagesize = getpagesize();
bool result;
void *mmap_result;
int ret;
if ((size_t)pch_address_space % pagesize != 0
|| sizeof (pch_address_space) % pagesize != 0)
@ -183,7 +180,19 @@ darwin_rs6000_gt_pch_use_address (void *addr, size_t sz)
if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
fatal_error ("couldn't unmap pch_address_space: %m\n");
return result;
mmap_result = mmap (addr, sz,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fd, off);
/* The file might not be mmap-able. */
ret = mmap_result == (void *) MAP_FAILED;
/* Sanity check for broken MAP_FIXED. */
if (ret && mmap_result != base)
abort ();
return ret;
}
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;

4
gcc/config/x-linux Normal file

@ -0,0 +1,4 @@
host-linux.o : $(srcdir)/config/host-linux.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/host-linux.c

4
gcc/config/x-solaris Normal file

@ -0,0 +1,4 @@
host-solaris.o : $(srcdir)/config/host-solaris.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/host-solaris.c

@ -42,35 +42,31 @@ This host hook is used to set up handling for extra signals. The most
common thing to do in this hook is to detect stack overflow.
@end deftypefn
@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size})
This host hook returns the address of some space in which a PCH may be
loaded with @samp{HOST_HOOKS_PCH_LOAD_PCH}. The space will need to
have @var{size} bytes. If insufficient space is available,
@samp{NULL} may be returned; the PCH machinery will try to find a
suitable address using a heuristic.
The memory does not have to be available now. In fact, usually
@samp{HOST_HOOKS_PCH_LOAD_PCH} will already have been called. The memory
need only be available in future invocations of GCC.
@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size}, int @var{fd})
This host hook returns the address of some space that is likely to be
free in some subsequent invocation of the compiler. We intend to load
the PCH data at this address such that the data need not be relocated.
The area should be able to hold @var{size} bytes. If the host uses
@code{mmap}, @var{fd} is an open file descriptor that can be used for
probing.
@end deftypefn
@deftypefn {Host Hook} bool HOST_HOOKS_GT_PCH_USE_ADDRESS (size_t @var{size}, void * @var{address})
This host hook is called when a PCH file is about to be loaded. If
@var{address} is the address that would have been returned by
@samp{HOST_HOOKS_PCH_MEMORY_ADDRESS}, and @var{size} is smaller than
the maximum than @samp{HOST_HOOKS_PCH_MEMORY_ADDRESS} would have
accepted, return true, otherwise return false.
@deftypefn {Host Hook} int HOST_HOOKS_GT_PCH_USE_ADDRESS (void * @var{address}, size_t @var{size}, int @var{fd}, size_t @var{offset})
This host hook is called when a PCH file is about to be loaded.
We want to load @var{size} bytes from @var{fd} at @var{offset}
into memory at @var{address}. The given address will be the result of
a previous invocation of @code{HOST_HOOKS_GT_PCH_GET_ADDRESS}.
Return @minus{}1 if we couldn't allocate @var{size} bytes at @var{address}.
Return 0 if the memory is allocated but the data is not loaded. Return 1
if the hook has performed everything.
In addition, free any address space reserved that isn't needed to hold
@var{size} bytes (whether or not true is returned). The PCH machinery will
use @samp{mmap} with @samp{MAP_FIXED} to load the PCH if @samp{HAVE_MMAP_FILE},
or will use @samp{fread} otherwise.
If no PCH will be loaded, this hook may be called with @var{size}
zero, in which case all reserved address space should be freed.
If the implementation uses reserved address space, free any reserved
space beyond @var{size}, regardless of the return value. If no PCH will
be loaded, this hook may be called with @var{size} zero, in which case
all reserved address space should be freed.
Do not try to handle values of @var{address} that could not have been
returned by this executable; just return false. Such values usually
returned by this executable; just return @minus{}1. Such values usually
indicate an out-of-date PCH file (built by some other GCC executable),
and such a PCH file won't work.
@end deftypefn

@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "params.h"
#include "hosthooks.h"
#include "hosthooks-def.h"
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
@ -459,21 +460,8 @@ gt_pch_save (FILE *f)
and on the rest it's a lot of work to do better.
(The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
HOST_HOOKS_GT_PCH_USE_ADDRESS.) */
mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size);
mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f));
#if HAVE_MMAP_FILE
if (mmi.preferred_base == NULL)
{
mmi.preferred_base = mmap (NULL, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE,
fileno (state.f), 0);
if (mmi.preferred_base == (void *) MAP_FAILED)
mmi.preferred_base = NULL;
else
munmap (mmi.preferred_base, mmi.size);
}
#endif /* HAVE_MMAP_FILE */
ggc_pch_this_base (state.d, mmi.preferred_base);
state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
@ -527,7 +515,8 @@ gt_pch_save (FILE *f)
state.ptrs[i]->note_ptr_cookie,
relocate_ptrs, &state);
ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
state.ptrs[i]->new_addr, state.ptrs[i]->size, state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
state.ptrs[i]->new_addr, state.ptrs[i]->size,
state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
}
@ -547,8 +536,7 @@ gt_pch_restore (FILE *f)
const struct ggc_root_tab *rti;
size_t i;
struct mmap_info mmi;
void *addr;
bool needs_read;
int result;
/* Delete any deletable objects. This makes ggc_pch_read much
faster, as it can be sure that no GCable objects remain other
@ -581,112 +569,95 @@ gt_pch_restore (FILE *f)
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
fatal_error ("can't read PCH file: %m");
if (host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size))
{
#if HAVE_MMAP_FILE
void *mmap_result;
mmap_result = mmap (mmi.preferred_base, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fileno (f), mmi.offset);
/* The file might not be mmap-able. */
needs_read = mmap_result == (void *) MAP_FAILED;
/* Sanity check for broken MAP_FIXED. */
if (! needs_read && mmap_result != mmi.preferred_base)
abort ();
#else
needs_read = true;
#endif
addr = mmi.preferred_base;
}
else
{
#if HAVE_MMAP_FILE
addr = mmap (mmi.preferred_base, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE,
fileno (f), mmi.offset);
#if HAVE_MINCORE
if (addr != mmi.preferred_base)
{
size_t page_size = getpagesize();
char one_byte;
/* We really want to be mapped at mmi.preferred_base
so we're going to resort to MAP_FIXED. But before,
make sure that we can do so without destroying a
previously mapped area, by looping over all pages
that would be affected by the fixed mapping. */
errno = 0;
for (i = 0; i < mmi.size; i+= page_size)
if (mincore ((char *)mmi.preferred_base + i, page_size,
(void *)&one_byte) == -1
&& errno == ENOMEM)
continue; /* The page is not mapped. */
else
break;
if (i >= mmi.size)
{
if (addr != (void *) MAP_FAILED)
munmap (addr, mmi.size);
addr = mmap (mmi.preferred_base, mmi.size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fileno (f), mmi.offset);
}
}
#endif /* HAVE_MINCORE */
needs_read = addr == (void *) MAP_FAILED;
#else /* HAVE_MMAP_FILE */
needs_read = true;
#endif /* HAVE_MMAP_FILE */
if (needs_read)
addr = xmalloc (mmi.size);
}
if (needs_read)
result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size,
fileno (f), mmi.offset);
if (result < 0)
fatal_error ("had to relocate PCH");
if (result == 0)
{
if (fseek (f, mmi.offset, SEEK_SET) != 0
|| fread (addr, mmi.size, 1, f) != 1)
|| fread (mmi.preferred_base, mmi.size, 1, f) != 1)
fatal_error ("can't read PCH file: %m");
}
else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
fatal_error ("can't read PCH file: %m");
ggc_pch_read (f, addr);
if (addr != mmi.preferred_base)
{
for (rt = gt_ggc_rtab; *rt; rt++)
for (rti = *rt; rti->base != NULL; rti++)
for (i = 0; i < rti->nelt; i++)
{
char **ptr = (char **)((char *)rti->base + rti->stride * i);
if (*ptr != NULL)
*ptr += (size_t)addr - (size_t)mmi.preferred_base;
}
for (rt = gt_pch_cache_rtab; *rt; rt++)
for (rti = *rt; rti->base != NULL; rti++)
for (i = 0; i < rti->nelt; i++)
{
char **ptr = (char **)((char *)rti->base + rti->stride * i);
if (*ptr != NULL)
*ptr += (size_t)addr - (size_t)mmi.preferred_base;
}
fatal_error ("had to relocate PCH");
}
ggc_pch_read (f, mmi.preferred_base);
gt_pch_restore_stringpool ();
}
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
Select no address whatsoever, and let gt_pch_save choose what it will with
malloc, presumably. */
void *
default_gt_pch_get_address (size_t size ATTRIBUTE_UNUSED,
int fd ATTRIBUTE_UNUSED)
{
return NULL;
}
/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is not present.
Allocate SIZE bytes with malloc. Return 0 if the address we got is the
same as base, indicating that the memory has been allocated but needs to
be read in from the file. Return -1 if the address differs, to relocation
of the PCH file would be required. */
int
default_gt_pch_use_address (void *base, size_t size, int fd ATTRIBUTE_UNUSED,
size_t offset ATTRIBUTE_UNUSED)
{
void *addr = xmalloc (size);
return (addr == base) - 1;
}
#if HAVE_MMAP_FILE
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present.
We temporarily allocate SIZE bytes, and let the kernel place the data
whereever it will. If it worked, that's our spot, if not we're likely
to be in trouble. */
void *
mmap_gt_pch_get_address (size_t size, int fd)
{
void *ret;
ret = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (ret == (void *) MAP_FAILED)
ret = NULL;
else
munmap (ret, size);
return ret;
}
/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is present.
Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at
mapping the data at BASE, -1 if we couldn't.
This version assumes that the kernel honors the START operand of mmap
even without MAP_FIXED if START through START+SIZE are not currently
mapped with something. */
int
mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
{
void *addr;
/* We're called with size == 0 if we're not planning to load a PCH
file at all. This allows the hook to free any static space that
we might have allocated at link time. */
if (size == 0)
return -1;
addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
return addr == base ? 1 : -1;
}
#endif /* HAVE_MMAP_FILE */
/* Modify the bound based on rlimits. Keep the smallest number found. */
static double
ggc_rlimit_bound (double limit)

@ -205,21 +205,6 @@ hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
return NULL;
}
/* Generic hook that takes a size_t and returns NULL. */
void *
hook_voidp_size_t_null (size_t a ATTRIBUTE_UNUSED)
{
return NULL;
}
/* Generic hook that takes a size_t and a pointer and returns false. */
bool
hook_bool_voidp_size_t_false (void * a ATTRIBUTE_UNUSED,
size_t b ATTRIBUTE_UNUSED)
{
return false;
}
/* Generic hook that takes a tree and returns it as is. */
tree
hook_tree_tree_identity (tree a)

@ -57,8 +57,6 @@ extern bool hook_bool_tree_tree_false (tree, tree);
extern rtx hook_rtx_rtx_identity (rtx);
extern rtx hook_rtx_rtx_null (rtx);
extern rtx hook_rtx_tree_int_null (tree, int);
extern void * hook_voidp_size_t_null (size_t);
extern bool hook_bool_voidp_size_t_false (void *, size_t);
extern tree hook_tree_tree_identity (tree a);
#endif

@ -24,8 +24,18 @@ Boston, MA 02111-1307, USA. */
#include "hooks.h"
#define HOST_HOOKS_EXTRA_SIGNALS hook_void_void
#define HOST_HOOKS_GT_PCH_GET_ADDRESS hook_voidp_size_t_null
#define HOST_HOOKS_GT_PCH_USE_ADDRESS hook_bool_voidp_size_t_false
#if HAVE_MMAP_FILE
#define HOST_HOOKS_GT_PCH_GET_ADDRESS mmap_gt_pch_get_address
#define HOST_HOOKS_GT_PCH_USE_ADDRESS mmap_gt_pch_use_address
#else
#define HOST_HOOKS_GT_PCH_GET_ADDRESS default_gt_pch_get_address
#define HOST_HOOKS_GT_PCH_USE_ADDRESS default_gt_pch_use_address
#endif
extern void* default_gt_pch_get_address (size_t, int);
extern int default_gt_pch_use_address (void *, size_t, int, size_t);
extern void* mmap_gt_pch_get_address (size_t, int);
extern int mmap_gt_pch_use_address (void *, size_t, int, size_t);
/* The structure is defined in hosthooks.h. */
#define HOST_HOOKS_INITIALIZER { \

@ -25,8 +25,16 @@ struct host_hooks
{
void (*extra_signals) (void);
void * (*gt_pch_get_address) (size_t);
bool (*gt_pch_use_address) (void *, size_t);
/* Identify an address that's likely to be free in a subsequent invocation
of the compiler. The area should be able to hold SIZE bytes. FD is an
open file descriptor if the host would like to probe with mmap. */
void * (*gt_pch_get_address) (size_t size, int fd);
/* ADDR is an address returned by gt_pch_get_address. Attempt to allocate
SIZE bytes at the same address and load it with the data from FD at
OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0
if the memory is allocated but the data not loaded, return 1 if done. */
int (*gt_pch_use_address) (void *addr, size_t size, int fd, size_t offset);
/* Whenever you add entries here, make sure you adjust hosthooks-def.h. */
};