#! /bin/sh -e

# DP: General NetBSD support patches

dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    dir="$3/"
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p0 < $0
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

diff -urN gcc/config/netbsd-elf-gnu.h src/gcc/config/netbsd-elf-gnu.h
--- gcc/config/netbsd-elf-gnu.h	1970-01-01 00:00:00.000000000 +0000
+++ gcc/config/netbsd-elf-gnu.h	2003-04-24 05:42:44.000000000 +0000
@@ -0,0 +1,99 @@
+/* Common configuration file for NetBSD ELF w/ GNU userland targets.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+   Contributed by Wasabi Systems, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* TARGET_OS_CPP_BUILTINS() common to all NetBSD ELF targets.  */
+#define NETBSD_OS_CPP_BUILTINS_ELF()		\
+  do						\
+    {						\
+      NETBSD_OS_CPP_BUILTINS_COMMON();		\
+      builtin_define ("__ELF__");		\
+    }						\
+  while (0)
+
+/* This defines which switch letters take arguments.  On NetBSD, most
+   of the normal cases (defined by gcc.c) apply, and we also have -h*
+   and -z* options (for the linker) (coming from SVR4).  */
+
+#undef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR)			\
+  (DEFAULT_SWITCH_TAKES_ARG (CHAR)		\
+   || (CHAR) == 'h'				\
+   || (CHAR) == 'z'				\
+   || (CHAR) == 'R')
+
+
+/* Provide a STARTFILE_SPEC appropriate for NetBSD ELF.  Here we
+   provide support for the special GCC option -static.  On ELF
+   targets, we also add the crtbegin.o file, which provides part
+   of the support for getting C++ file-scope static objects
+   constructed before entering "main".  */
+
+#define NETBSD_STARTFILE_SPEC	\
+  "%{!shared:			\
+     %{pg:gcrt0%O%s}		\
+     %{!pg:			\
+       %{p:gcrt0%O%s}		\
+       %{!p:crt0%O%s}}}		\
+   %:if-exists(crti%O%s)	\
+   %{static:%:if-exists-else(crtbeginT%O%s crtbegin%O%s)} \
+   %{!static: \
+     %{!shared:crtbegin%O%s} %{shared:crtbeginS%O%s}}"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
+
+
+/* Provide an ENDFILE_SPEC appropriate for NetBSD ELF.  Here we
+   add crtend.o, which provides part of the support for getting
+   C++ file-scope static objects deconstructed after exiting "main".  */
+
+#define NETBSD_ENDFILE_SPEC	\
+  "%{!shared:crtend%O%s} %{shared:crtendS%O%s} \
+   %:if-exists(crtn%O%s)"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC NETBSD_ENDFILE_SPEC
+
+/* Provide a LINK_SPEC appropriate for NetBSD ELF.  Here we provide
+   support for the special GCC options -assert, -R, -rpath, -shared,
+   -nostdlib, -static, -rdynamic, and -dynamic-linker.
+
+   Target-specific code can use this in conjunction with any other
+   target-specific LINK_SPEC options.
+
+   Target-specific code must provide the %(netbsd_entry_point) spec.  */
+
+/* This differs from native NetBSD only in that the linker is expected to
+   live in /lib, rather than /usr/libexec (or /libexec). */
+
+#define NETBSD_LINK_SPEC_ELF \
+  "%{assert*} %{R*} %{rpath*} \
+   %{shared:-shared} \
+   %{symbolic:-Bsymbolic} \
+   %{!shared: \
+     -dc -dp \
+     %{!nostdlib: \
+       %{!r*: \
+	 %{!e*:-e %(netbsd_entry_point)}}} \
+     %{!static: \
+       %{rdynamic:-export-dynamic} \
+       %{!dynamic-linker:-dynamic-linker /lib/ld.elf_so}} \
+     %{static:-static}}"
diff -urN gcc/config/netbsd-gnu.h src/gcc/config/netbsd-gnu.h
--- gcc/config/netbsd-gnu.h	1970-01-01 00:00:00.000000000 +0000
+++ gcc/config/netbsd-gnu.h	2003-04-24 05:41:04.000000000 +0000
@@ -0,0 +1,206 @@
+/* Base configuration file for all NetBSD w/ GNU userland targets.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* TARGET_OS_CPP_BUILTINS() common to all NetBSD targets.  */
+#define NETBSD_OS_CPP_BUILTINS_COMMON()		\
+  do						\
+    {						\
+      builtin_define ("__NetBSD__");		\
+      builtin_assert ("system=unix");		\
+      builtin_assert ("system=NetBSD");		\
+    }						\
+  while (0)
+
+/* TARGET_OS_CPP_BUILTINS() common to all LP64 NetBSD targets.  */
+#define NETBSD_OS_CPP_BUILTINS_LP64()		\
+  do						\
+    {						\
+      builtin_define ("_LP64");			\
+    }						\
+  while (0)
+
+/* CPP_SPEC parts common to all NetBSD targets.  */
+#define NETBSD_CPP_SPEC				\
+  "%{posix:-D_POSIX_SOURCE} \
+   %{pthread:-D_REENTRANT -D_PTHREADS}"
+
+/* NETBSD_NATIVE is defined only when gcc is integrated into a NetBSD
+   system with a NetBSD userland - NetBSD with a GNU userland never defines
+   it, and all references to it have been removed for this system type. */
+
+/* FIXME: This should link to libc, but there are problems with that under
+   3.2 - find out of they still apply under 3.3! */
+
+/* Provide a LIB_SPEC appropriate for NetBSD.  Here we:
+
+   1. Select the appropriate set of libs, depending on whether we're
+      profiling.
+
+   2. Include the pthread library if -pthread is specified (only
+      if threads are enabled).
+
+   3. Include the posix library if -posix is specified.
+
+   FIXME: Could eliminate the duplication here if we were allowed to
+   use string concatenation.  */
+
+#ifdef NETBSD_ENABLE_PTHREADS
+#define NETBSD_LIB_SPEC		\
+  "%{pthread:			\
+     %{!p:			\
+       %{!pg:-lpthread}}	\
+     %{p:-lpthread_p}		\
+     %{pg:-lpthread_p}}		\
+   %{posix:			\
+     %{!p:			\
+       %{!pg:-lposix}}		\
+     %{p:-lposix_p}		\
+     %{pg:-lposix_p}}		\
+   %{!shared:			\
+     %{!symbolic:		\
+       %{!p:			\
+	 %{!pg:-lc}}		\
+       %{p:-lc_p}		\
+       %{pg:-lc_p}}}"
+#else
+#define NETBSD_LIB_SPEC		\
+  "%{posix:			\
+     %{!p:			\
+       %{!pg:-lposix}}		\
+     %{p:-lposix_p}		\
+     %{pg:-lposix_p}}		\
+   %{!shared:			\
+     %{!symbolic:		\
+       %{!p:			\
+	 %{!pg:-lc}}		\
+       %{p:-lc_p}		\
+       %{pg:-lc_p}}}"
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC NETBSD_LIB_SPEC
+
+/* Provide a LIBGCC_SPEC appropriate for NetBSD.  We also want to exclude
+   libgcc with -symbolic.  */
+
+#ifdef NETBSD_NATIVE
+#define NETBSD_LIBGCC_SPEC	\
+  "%{!symbolic:			\
+     %{!shared:			\
+       %{!p:			\
+	 %{!pg: -lgcc}}}	\
+     %{shared: -lgcc_pic}	\
+     %{p: -lgcc_p}		\
+     %{pg: -lgcc_p}}"
+#else
+#define NETBSD_LIBGCC_SPEC "%{!shared:%{!symbolic: -lgcc}}"
+#endif
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
+
+/* When building shared libraries, the initialization and finalization 
+   functions for the library are .init and .fini respectively.  */
+
+#define COLLECT_SHARED_INIT_FUNC(STREAM,FUNC)				\
+  do {									\
+    fprintf ((STREAM), "void __init() __asm__ (\".init\");");		\
+    fprintf ((STREAM), "void __init() {\n\t%s();\n}\n", (FUNC));	\
+  } while (0)
+
+#define COLLECT_SHARED_FINI_FUNC(STREAM,FUNC)				\
+  do {									\
+    fprintf ((STREAM), "void __fini() __asm__ (\".fini\");");		\
+    fprintf ((STREAM), "void __fini() {\n\t%s();\n}\n", (FUNC));	\
+  } while (0)
+
+#undef TARGET_HAS_F_SETLKW
+#define TARGET_HAS_F_SETLKW
+
+/* Implicit library calls should use memcpy, not bcopy, etc.  */
+
+#undef TARGET_MEM_FUNCTIONS
+#define TARGET_MEM_FUNCTIONS 1
+
+/* Handle #pragma weak and #pragma pack.  */
+
+#define HANDLE_SYSV_PRAGMA 1
+
+
+/* Define some types that are the same on all NetBSD platforms,
+   making them agree with <machine/ansi.h>.  */
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+#undef WINT_TYPE
+#define WINT_TYPE "int"
+
+
+/* Attempt to turn on execute permission for the stack.  This may be
+   used by TRANSFER_FROM_TRAMPOLINE of the target needs it (that is,
+   if the target machine can change execute permissions on a page).
+
+   There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.
+
+   Note that we go out of our way to use namespace-non-invasive calls
+   here.  Unfortunately, there is no libc-internal name for mprotect().
+
+   Also note that no errors should be emitted by this code; it is considered
+   dangerous for library calls to send messages to stdout/stderr.  */
+
+#define NETBSD_ENABLE_EXECUTE_STACK					\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (addr)						\
+     void *addr;							\
+{									\
+  extern int mprotect (void *, size_t, int);				\
+  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
+		       void *, size_t);					\
+									\
+  static int size;							\
+  static long mask;							\
+									\
+  char *page, *end;							\
+									\
+  if (size == 0)							\
+    {									\
+      int mib[2];							\
+      size_t len;							\
+									\
+      mib[0] = 6; /* CTL_HW */						\
+      mib[1] = 7; /* HW_PAGESIZE */					\
+      len = sizeof (size);						\
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
+      mask = ~((long) size - 1);					\
+    }									\
+									\
+  page = (char *) (((long) addr) & mask);				\
+  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
+									\
+  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
+  (void) mprotect (page, end - page, 7);				\
+}
diff -urN gcc/config/t-netbsd-gnu src/gcc/config/t-netbsd-gnu
--- gcc/config/t-netbsd-gnu	1970-01-01 00:00:00.000000000 +0000
+++ gcc/config/t-netbsd-gnu	2003-02-21 10:31:17.000000000 +0000
@@ -0,0 +1,5 @@
+# Don't run fixproto
+STMP_FIXPROTO =
+
+# Always build crtstuff with PIC.
+CRTSTUFF_T_CFLAGS = -fPIC
diff -urN gcc/config.gcc src/gcc/config.gcc
--- gcc/config.gcc	2003-03-02 07:39:03.000000000 +0000
+++ gcc/config.gcc	2003-04-24 06:02:55.000000000 +0000
@@ -329,6 +329,45 @@
 		;;
 	esac
 	;;
+*-*-netbsd*-gnu*)
+	tmake_file="t-slibgcc-elf-ver t-libc-ok t-netbsd"
+	xm_defines=POSIX
+	gas=yes
+	gnu_ld=yes
+
+	# This section MUST go above the matches for Hurd and native NetBSD,
+	# or they will catch the value, due to using excessively permissive 
+	# match values. Also, $machine doesn't contain any version data, on
+	# a NetBSD w/ GNU userland machine, so we use uname -r instead.
+
+	osr=`uname -r`
+
+	# NetBSD 2.0 and later get POSIX threads enabled by default.
+	# Allow them to be explicitly enabled on any other version.
+	case x${enable_threads} in
+	x)
+		case $osr in
+		[2-9]*)
+			thread_file='posix'
+			tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
+			;;
+		esac
+		;;
+	xyes | xposix)
+		thread_file='posix'
+		tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
+		;;
+	esac
+
+	# NetBSD 1.7 and later are set up to use GCC's crtstuff for
+	# ELF configurations.  We will clear extra_parts in the
+	# a.out configurations.
+	case $osr in
+	1.[7-9]* | [2-9]*)
+		extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
+		;;
+	esac
+	;;
 *-*-gnu*)
 	# On the Hurd, the setup is just about the same on
 	# each different CPU.  The specific machines that we
