https://gcc.gnu.org/g:a0ff4b6bba5e898e3cd7df277232ad5a495da38a

commit r16-6819-ga0ff4b6bba5e898e3cd7df277232ad5a495da38a
Author: Rainer Orth <[email protected]>
Date:   Fri Jan 16 13:12:03 2026 +0100

    Provide gt_pch_get_address etc. on FreeBSD [PR110746]
    
    On FreeBSD/amd64, more than 700 tests FAIL like
    
    FAIL: gcc.dg/pch/common-1.c  -O0 -g -I. -Dwith_PCH (test for excess errors)
    Excess errors:
    gcc/testsuite/gcc.dg/pch/common-1.c:1: sorry, unimplemented: PCH allocation 
failure
    
    This can easily be fixed by implementing the
    host_hooks.gt_pch_get_address hook.  The code is shamelessly stolen from
    the openbsd implementation, only changing the names and omitting the
    hppa and i386 code.  The former isn't supported by FreeBSD at all AFAIK,
    while the latter has just been removed in FreeBSD 15.0.
    
    Bootstrapped without regressions on x86_64-unknown-freebsd14.3: all PCH
    failures are gone.
    
    2026-01-15  Rainer Orth  <[email protected]>
    
            gcc:
            PR pch/110746
            * config/host-freebsd.cc: New file.
            * config.host <*-*-freebsd*>: Use it.
            * config/x-freebsd: New file.

Diff:
---
 gcc/config.host            |  4 ++
 gcc/config/host-freebsd.cc | 95 ++++++++++++++++++++++++++++++++++++++++++++++
 gcc/config/x-freebsd       |  4 ++
 3 files changed, 103 insertions(+)

diff --git a/gcc/config.host b/gcc/config.host
index 6c569726b006..8b809a8d5ddc 100644
--- a/gcc/config.host
+++ b/gcc/config.host
@@ -271,6 +271,10 @@ case ${host} in
     out_host_hook_obj=host-linux.o
     host_xmake_file="${host_xmake_file} x-linux"
     ;;
+  *-*-freebsd*)
+    out_host_hook_obj=host-freebsd.o
+    host_xmake_file="${host_xmake_file} x-freebsd"
+    ;;
   *-*-openbsd*)
     out_host_hook_obj=host-openbsd.o
     host_xmake_file="${host_xmake_file} x-openbsd"
diff --git a/gcc/config/host-freebsd.cc b/gcc/config/host-freebsd.cc
new file mode 100644
index 000000000000..d1e5de141e24
--- /dev/null
+++ b/gcc/config/host-freebsd.cc
@@ -0,0 +1,95 @@
+/* FreeBSD host-specific hook definitions.
+   Copyright (C) 2004-2026 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 freebsd_gt_pch_get_address
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS freebsd_gt_pch_use_address
+
+/* For various ports, try to guess a fixed spot in the vm space
+   that's probably free.  */
+#if defined(__amd64__)
+# define TRY_EMPTY_VM_SPACE    0x400000000000
+#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 *
+freebsd_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, 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
+freebsd_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);
+
+  if (addr == base)
+    return 1;
+
+  if (addr != (void *) MAP_FAILED)
+    munmap(addr, size);
+
+  addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | 
MAP_ANONYMOUS, -1, 0);
+
+  if (addr == (void *) MAP_FAILED)
+    return -1;
+
+  /* Signal to the caller that whilst memory has been allocated, it
+     must read the PCH data */
+  base = addr;
+  return 0;
+}
+
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/gcc/config/x-freebsd b/gcc/config/x-freebsd
new file mode 100644
index 000000000000..bc0f66db4606
--- /dev/null
+++ b/gcc/config/x-freebsd
@@ -0,0 +1,4 @@
+host-freebsd.o : $(srcdir)/config/host-freebsd.cc $(CONFIG_H) $(SYSTEM_H) \
+  coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H)
+       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+               $(srcdir)/config/host-freebsd.cc

Reply via email to