host-solaris.c revision 1.1.1.1.4.2
1/* Solaris host-specific hook definitions. 2 Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published 8 by the Free Software Foundation; either version 3, or (at your 9 option) any later version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20#include "config.h" 21#include "system.h" 22#include "coretypes.h" 23#include <sys/mman.h> 24#include "hosthooks.h" 25#include "hosthooks-def.h" 26 27 28#undef HOST_HOOKS_GT_PCH_GET_ADDRESS 29#define HOST_HOOKS_GT_PCH_GET_ADDRESS sol_gt_pch_get_address 30#undef HOST_HOOKS_GT_PCH_USE_ADDRESS 31#define HOST_HOOKS_GT_PCH_USE_ADDRESS sol_gt_pch_use_address 32 33/* Before Solaris 11, the mmap ADDR parameter is mostly ignored without 34 MAP_FIXED set. Before we give up, search the desired address space with 35 mincore to see if the space is really free. */ 36 37static void * 38mmap_fixed (void *addr, size_t len, int prot, int flags, int fd, off_t off) 39{ 40 void *base; 41 42 base = mmap ((caddr_t) addr, len, prot, flags, fd, off); 43 44 if (base != addr) 45 { 46 size_t page_size = getpagesize(); 47 char one_byte; 48 size_t i; 49 50 if (base != (void *) MAP_FAILED) 51 munmap ((caddr_t) base, len); 52 53 errno = 0; 54 for (i = 0; i < len; i += page_size) 55 if (mincore ((char *)addr + i, page_size, (char *) &one_byte) == -1 56 && errno == ENOMEM) 57 continue; /* The page is not mapped. */ 58 else 59 break; 60 61 if (i >= len) 62 base = mmap ((caddr_t) addr, len, prot, flags | MAP_FIXED, fd, off); 63 } 64 65 return base; 66} 67 68/* For various ports, try to guess a fixed spot in the vm space 69 that's probably free. Based on McDougall, Mauro, Solaris Internals, 2nd 70 ed., p.460-461, fig. 9-3, 9-4, 9-5. */ 71#if defined(__sparcv9__) 72/* This low to avoid VA hole on UltraSPARC I/II. */ 73# define TRY_EMPTY_VM_SPACE 0x70000000000 74#elif defined(__sparc__) 75# define TRY_EMPTY_VM_SPACE 0x80000000 76#elif defined(__x86_64__) 77# define TRY_EMPTY_VM_SPACE 0x8000000000000000 78#elif defined(__i386__) 79# define TRY_EMPTY_VM_SPACE 0xB0000000 80#else 81# define TRY_EMPTY_VM_SPACE 0 82#endif 83 84/* Determine a location where we might be able to reliably allocate 85 SIZE bytes. FD is the PCH file, though we should return with the 86 file unmapped. */ 87 88static void * 89sol_gt_pch_get_address (size_t size, int fd) 90{ 91 void *addr; 92 93 addr = mmap_fixed ((caddr_t) TRY_EMPTY_VM_SPACE, size, 94 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 95 96 /* If we failed the map, that means there's *no* free space. */ 97 if (addr == (void *) MAP_FAILED) 98 return NULL; 99 /* Unmap the area before returning. */ 100 munmap ((caddr_t) addr, size); 101 102 return addr; 103} 104 105/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at 106 mapping the data at BASE, -1 if we couldn't. */ 107 108static int 109sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) 110{ 111 void *addr; 112 113 /* We're called with size == 0 if we're not planning to load a PCH 114 file at all. This allows the hook to free any static space that 115 we might have allocated at link time. */ 116 if (size == 0) 117 return -1; 118 119 addr = mmap_fixed ((caddr_t) base, size, 120 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset); 121 122 return addr == base ? 1 : -1; 123} 124 125 126const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; 127