This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] a different pch/exec-shield cleanup


This seems to work ok.  I'm somewhat partial to breaking out all the
logic for mapping and whatnot into the hook routines, as it seems to
be easier to follow that way.

The suggestion to allocate a ~32M vm hole comes from Ingo Molnar.
The hint that 1.5G to 2.5G tends to be free on x86 no matter what
the kernel memory model is comes from Arjan van de Ven.

I suppose that leaves the question of what to do with mincore.
Should it get shoved into a Solaris-specific host hook like this,
or should it stay in ggc-common.c as mmap_mincore_gt_pch_use_address?


r~


Index: c-pch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pch.c,v
retrieving revision 1.19
diff -u -p -c -r1.19 c-pch.c
*** c-pch.c	17 Dec 2003 22:04:34 -0000	1.19
--- c-pch.c	6 Mar 2004 20:13:33 -0000
*************** c_common_no_more_pch (void)
*** 401,406 ****
    if (cpp_get_callbacks (parse_in)->valid_pch)
      {
        cpp_get_callbacks (parse_in)->valid_pch = NULL;
!       host_hooks.gt_pch_use_address (NULL, 0);
      }
  }
--- 401,406 ----
    if (cpp_get_callbacks (parse_in)->valid_pch)
      {
        cpp_get_callbacks (parse_in)->valid_pch = NULL;
!       host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
      }
  }
Index: config.host
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.host,v
retrieving revision 2.7
diff -u -p -c -r2.7 config.host
*** config.host	14 Oct 2003 03:41:41 -0000	2.7
--- config.host	6 Mar 2004 20:13:33 -0000
*************** case ${host} in
*** 113,118 ****
--- 113,120 ----
      ;;
    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"
*************** case ${host} in
*** 151,155 ****
--- 153,165 ----
      # powerpc-darwin host support.
      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
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.84
diff -u -p -c -r1.84 ggc-common.c
*** ggc-common.c	5 Mar 2004 01:22:58 -0000	1.84
--- ggc-common.c	6 Mar 2004 20:13:33 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
  #include "toplev.h"
  #include "params.h"
  #include "hosthooks.h"
+ #include "hosthooks-def.h"
  
  #ifdef HAVE_SYS_RESOURCE_H
  # include <sys/resource.h>
*************** gt_pch_save (FILE *f)
*** 459,479 ****
       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);
        
- #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));
--- 460,467 ----
       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, fileno (f));
        
    ggc_pch_this_base (state.d, mmi.preferred_base);
  
    state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
*************** gt_pch_save (FILE *f)
*** 527,533 ****
  				  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);
        if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
  	memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
      }
--- 515,522 ----
  				  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);
        if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
  	memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
      }
*************** gt_pch_restore (FILE *f)
*** 547,554 ****
    const struct ggc_root_tab *rti;
    size_t i;
    struct mmap_info mmi;
!   void *addr;
!   bool needs_read;
  
    /* Delete any deletable objects.  This makes ggc_pch_read much
       faster, as it can be sure that no GCable objects remain other
--- 536,542 ----
    const struct ggc_root_tab *rti;
    size_t i;
    struct mmap_info mmi;
!   int result;
  
    /* Delete any deletable objects.  This makes ggc_pch_read much
       faster, as it can be sure that no GCable objects remain other
*************** gt_pch_restore (FILE *f)
*** 581,691 ****
    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)
!     {
!       if (fseek (f, mmi.offset, SEEK_SET) != 0
! 	  || fread (addr, 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");
!     }
  
!   gt_pch_restore_stringpool ();
  }
  
  /* Modify the bound based on rlimits.  Keep the smallest number found.  */
  static double
--- 569,662 ----
    if (fread (&mmi, sizeof (mmi), 1, f) != 1)
      fatal_error ("can't read PCH file: %m");
  
!   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 (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, 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
Index: hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hooks.c,v
retrieving revision 1.26
diff -u -p -c -r1.26 hooks.c
*** hooks.c	4 Mar 2004 00:18:51 -0000	1.26
--- hooks.c	6 Mar 2004 20:13:33 -0000
*************** hook_rtx_tree_int_null (tree a ATTRIBUTE
*** 205,225 ****
    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)
--- 205,210 ----
Index: hooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hooks.h,v
retrieving revision 1.27
diff -u -p -c -r1.27 hooks.h
*** hooks.h	4 Mar 2004 00:18:51 -0000	1.27
--- hooks.h	6 Mar 2004 20:13:33 -0000
*************** extern bool hook_bool_tree_tree_false (t
*** 57,64 ****
  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
--- 57,62 ----
Index: hosthooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hosthooks-def.h,v
retrieving revision 1.3
diff -u -p -c -r1.3 hosthooks-def.h
*** hosthooks-def.h	29 Jul 2003 23:36:46 -0000	1.3
--- hosthooks-def.h	6 Mar 2004 20:13:33 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 24,31 ****
  #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
  
  /* The structure is defined in hosthooks.h.  */
  #define HOST_HOOKS_INITIALIZER {		\
--- 24,41 ----
  #include "hooks.h"
  
  #define HOST_HOOKS_EXTRA_SIGNALS hook_void_void
! #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 {		\
Index: hosthooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hosthooks.h,v
retrieving revision 1.4
diff -u -p -c -r1.4 hosthooks.h
*** hosthooks.h	29 Jul 2003 23:36:46 -0000	1.4
--- hosthooks.h	6 Mar 2004 20:13:33 -0000
*************** struct host_hooks
*** 25,32 ****
  {
    void (*extra_signals) (void);
  
!   void * (*gt_pch_get_address) (size_t);
!   bool (*gt_pch_use_address) (void *, size_t);
  
    /* Whenever you add entries here, make sure you adjust hosthooks-def.h.  */
  };
--- 25,32 ----
  {
    void (*extra_signals) (void);
  
!   void * (*gt_pch_get_address) (size_t, int);
!   int (*gt_pch_use_address) (void *, size_t, int, size_t);
  
    /* Whenever you add entries here, make sure you adjust hosthooks-def.h.  */
  };
Index: config/host-linux.c
===================================================================
RCS file: config/host-linux.c
diff -N config/host-linux.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/host-linux.c	6 Mar 2004 20:13:35 -0000
***************
*** 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;
Index: config/host-solaris.c
===================================================================
RCS file: config/host-solaris.c
diff -N config/host-solaris.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/host-solaris.c	6 Mar 2004 20:13:35 -0000
***************
*** 0 ****
--- 1,81 ----
+ /* 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;
+ 
+       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)
+ 	{
+ 	  if (addr != (void *) MAP_FAILED)
+ 	    munmap (addr, 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;
Index: config/x-linux
===================================================================
RCS file: config/x-linux
diff -N config/x-linux
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/x-linux	6 Mar 2004 20:13:35 -0000
***************
*** 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
Index: config/x-solaris
===================================================================
RCS file: config/x-solaris
diff -N config/x-solaris
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/x-solaris	6 Mar 2004 20:13:35 -0000
***************
*** 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
Index: config/rs6000/host-darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/host-darwin.c,v
retrieving revision 1.7
diff -u -p -c -r1.7 host-darwin.c
*** config/rs6000/host-darwin.c	29 Jul 2003 23:36:53 -0000	1.7
--- config/rs6000/host-darwin.c	6 Mar 2004 20:13:35 -0000
*************** darwin_rs6000_extra_signals (void)
*** 137,158 ****
      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)
  {
    if (sz <= sizeof (pch_address_space))
      return pch_address_space;
--- 137,154 ----
      fatal_error ("While setting up signal handler: %m");
  }
  
  #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, int fd ATTRIBUTE_UNUSED)
  {
    if (sz <= sizeof (pch_address_space))
      return pch_address_space;
*************** darwin_rs6000_gt_pch_get_address (size_t
*** 163,173 ****
  /* 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)
  {
    const size_t pagesize = getpagesize();
!   bool result;
  
    if ((size_t)pch_address_space % pagesize != 0
        || sizeof (pch_address_space) % pagesize != 0)
--- 159,170 ----
  /* Check ADDR and SZ for validity, and deallocate (using munmap) that part of
     pch_address_space beyond SZ.  */
  
! static int
! darwin_rs6000_gt_pch_use_address (void *addr, size_t sz, int fd, size_t off)
  {
    const size_t pagesize = getpagesize();
!   void *mmap_result;
!   int ret;
  
    if ((size_t)pch_address_space % pagesize != 0
        || sizeof (pch_address_space) % pagesize != 0)
*************** darwin_rs6000_gt_pch_use_address (void *
*** 183,189 ****
    if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
      fatal_error ("couldn't unmap pch_address_space: %m\n");
  
!   return result;
  }
  
  const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
--- 180,198 ----
    if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
      fatal_error ("couldn't unmap pch_address_space: %m\n");
  
!   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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]