tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

gcc 4.8.1 and precompiled header support for NetBSD hosts



Hey folks,

originating from yet more vax compiler issues I started to look at the newest
gcc we have in pkgsrc - and as a sanity check did so on sparc64 (compiling
natively there).

It did not build - so I did a bit of debugging and filed a few upstream
tickets (58370, 58379, 58381) and am about to commit patches using those
changes for pkgsrc.

However, one bit is still open, and I'd like to get feedback on the hack
before pushing it upstream: for precompiled header files gcc assumes it
can pick a steady (over multiple compiler runs) address and mmap a part of
the precompiled header file at that address. No relocation supported.

I told them what I think of this design 
(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58379)
but we have to live with it for now.

Attached is host-netbsd.c, which picks this address for various archs and
seems to work at least on sparc64, vax, i386 and amd64 (didn't get around to
test others). Also attached is a tiny test program to test the effect without
building gcc.

Is there a better way? Should we pick different VAs? (I mostly cloned the ones
from OpenBSD, adjusting vax and mips for the 2GB border.) I don't know if the
preprocessor symbols are correct (this is about the host of the compiler).

Martin
#include <stdio.h>
#include <sys/mman.h>

#if defined(_LP64)
# define TRY_EMPTY_VM_SPACE     0x400000000000
#elif defined(__mips__) || defined(__vax__)
# define TRY_EMPTY_VM_SPACE     0x60000000
#else
# define TRY_EMPTY_VM_SPACE     0xb0000000
#endif

int main(int argc, char **argv)
{
        void *addr = (void*)TRY_EMPTY_VM_SPACE;
        void *p = mmap(addr, 8*1024, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
        printf("got memory at: %p (%s %p)\n", p, p == addr ? "=" : "!=", addr);
        return 0;
}
/* NetBSD host-specific hook definitions.
   Copyright (C) 2004-2013 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 3, 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 COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "hosthooks.h"
#include "hosthooks-def.h"


#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
#define HOST_HOOKS_GT_PCH_GET_ADDRESS netbsd_gt_pch_get_address
#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
#define HOST_HOOKS_GT_PCH_USE_ADDRESS netbsd_gt_pch_use_address

/* For various ports, try to guess a fixed spot in the vm space
   that's probably free.  */
#if defined(_LP64)
# define TRY_EMPTY_VM_SPACE     0x400000000000
#elif defined(__mips__) || defined(__vax__)
# define TRY_EMPTY_VM_SPACE     0x60000000
#else
# define TRY_EMPTY_VM_SPACE     0xb0000000
#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 *
netbsd_gt_pch_get_address (size_t size, int fd)
{
  void *addr;

  addr = mmap ((void *) TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE,
               MAP_PRIVATE | MAP_FIXED, 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);

  return addr;
}

/* 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
netbsd_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 | MAP_FIXED, fd, 
offset);

  return addr == base ? 1 : -1;
}


const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;


Home | Main Index | Thread Index | Old Index