--- /dev/null
+--- boehm-gc/Makefile.direct Mon Feb 11 20:37:53 2002
++++ boehm-gc/Makefile.direct Mon Jun 16 01:19:56 2003
+@@ -441,7 +441,7 @@
+ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
+- ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
++ ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
+ # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
+ # alpha_mach_dep.s assumes that pointers are not saved in fp registers.
+ # Gcc on a 21264 can spill pointers to fp registers. Oops.
+@@ -491,7 +491,7 @@
+ ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs`
+ ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld `./threadlibs`
+ ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
+- ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
++ ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
+ ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+ ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+ ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+diff -ur boehm-gc/Makefile.dist gcc-3.3+/boehm-gc/Makefile.dist
+--- boehm-gc/Makefile.dist Fri Aug 17 11:30:44 2001
++++ boehm-gc/Makefile.dist Mon Jun 16 01:19:56 2003
+@@ -415,7 +415,7 @@
+ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
+- ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
++ ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
+ # ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
+ # alpha_mach_dep.s assumes that pointers are not saved in fp registers.
+ # Gcc on a 21264 can spill pointers to fp registers. Oops.
+@@ -462,7 +462,7 @@
+ ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs`
+ ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld `./threadlibs`
+ ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses
+- ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
++ ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a
+ ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+ ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+ ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs`
+diff -ur boehm-gc/Makefile.dj gcc-3.3+/boehm-gc/Makefile.dj
+--- boehm-gc/Makefile.dj Tue Oct 16 02:01:34 2001
++++ boehm-gc/Makefile.dj Mon Jun 16 01:19:56 2003
+@@ -291,7 +291,7 @@
+ ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
+ ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
+- ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
++ ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s
+ ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
+ ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s
+ ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
+diff -ur boehm-gc/configure gcc-3.3+/boehm-gc/configure
+--- boehm-gc/configure Tue May 13 17:18:14 2003
++++ boehm-gc/configure Mon Jun 16 01:19:56 2003
+@@ -2818,6 +2818,23 @@
+ *-*-cygwin*)
+ THREADLIBS=
+ ;;
++ *-*-darwin*)
++ cat >> confdefs.h <<\EOF
++#define GC_DARWIN_THREADS 1
++EOF
++
++ cat >> confdefs.h <<\EOF
++#define THREAD_LOCAL_ALLOC 1
++EOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >> confdefs.h <<\EOF
++#define PARALLEL_MARK 1
++EOF
++
++ fi
++
++ ;;
+ esac
+ ;;
+ win32)
+diff -ur boehm-gc/configure.in gcc-3.3+/boehm-gc/configure.in
+--- boehm-gc/configure.in Mon Apr 28 13:55:07 2003
++++ boehm-gc/configure.in Mon Jun 16 01:19:56 2003
+@@ -111,6 +111,14 @@
+ *-*-cygwin*)
+ THREADLIBS=
+ ;;
++ *-*-darwin*)
++ AC_DEFINE(GC_DARWIN_THREADS)
++ AC_DEFINE(THREAD_LOCAL_ALLOC)
++ if test "${enable_parallel_mark}" = yes; then
++ AC_DEFINE(PARALLEL_MARK)
++ fi
++
++ ;;
+ esac
+ ;;
+ win32)
+@@ -129,7 +137,12 @@
+ esac
+ AC_SUBST(THREADLIBS)
+
+-AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
++ ;;
++esac
+ AC_SUBST(EXTRA_TEST_LIBS)
+
+ target_all=libgcjgc.la
+Only in boehm-gc: configure.in.orig
+Only in boehm-gc: configure.orig
+Only in boehm-gc: configure.rej
+diff -ur boehm-gc/dyn_load.c gcc-3.3+/boehm-gc/dyn_load.c
+--- boehm-gc/dyn_load.c Mon Mar 3 22:38:30 2003
++++ boehm-gc/dyn_load.c Mon Jun 16 01:19:56 2003
+@@ -57,7 +57,8 @@
+ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
+ !defined(RS6000) && !defined(SCO_ELF) && \
+ !(defined(FREEBSD) && defined(__ELF__)) && \
+- !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
++ !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
++ !defined(DARWIN)
+ --> We only know how to find data segments of dynamic libraries for the
+ --> above. Additional SVR4 variants might not be too
+ --> hard to add.
+@@ -1056,7 +1057,122 @@
+ }
+ #endif /* RS6000 */
+
++#ifdef DARWIN
+
++#warning FIXME __private_extern__ support in gcc
++#define __private_extern__
++#include <mach-o/dyld.h>
++#include <mach-o/getsect.h>
++
++/*#define DARWIN_DEBUG*/
++
++const static struct {
++ const char *seg;
++ const char *sect;
++} GC_dyld_sections[] = {
++ { SEG_DATA, SECT_DATA },
++ { SEG_DATA, SECT_BSS },
++ { SEG_DATA, SECT_COMMON }
++};
++
++#ifdef DARWIN_DEBUG
++static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) {
++ unsigned long i,c;
++ c = _dyld_image_count();
++ for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
++ return _dyld_get_image_name(i);
++ return NULL;
++}
++#endif
++
++/* This should never be called by a thread holding the lock */
++static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) {
++ unsigned long start,end,i;
++ const struct section *sec;
++ for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
++ sec = getsectbynamefromheader(
++ hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
++ if(sec == NULL || sec->size == 0) continue;
++ start = slide + sec->addr;
++ end = start + sec->size;
++# ifdef DARWIN_DEBUG
++ GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n",
++ start,end,sec->size,GC_dyld_name_for_hdr(hdr));
++# endif
++ GC_add_roots((char*)start,(char*)end);
++ }
++# ifdef DARWIN_DEBUG
++ GC_print_static_roots();
++# endif
++}
++
++/* This should never be called by a thread holding the lock */
++static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) {
++ unsigned long start,end,i;
++ const struct section *sec;
++ for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
++ sec = getsectbynamefromheader(
++ hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
++ if(sec == NULL || sec->size == 0) continue;
++ start = slide + sec->addr;
++ end = start + sec->size;
++# ifdef DARWIN_DEBUG
++ GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n",
++ start,end,sec->size,GC_dyld_name_for_hdr(hdr));
++# endif
++ GC_remove_roots((char*)start,(char*)end);
++ }
++# ifdef DARWIN_DEBUG
++ GC_print_static_roots();
++# endif
++}
++
++void GC_register_dynamic_libraries() {
++ /* Currently does nothing. The callbacks are setup by GC_init_dyld()
++ The dyld library takes it from there. */
++}
++
++/* The _dyld_* functions have an internal lock so no _dyld functions
++ can be called while the world is stopped without the risk of a deadlock.
++ Because of this we MUST setup callbacks BEFORE we ever stop the world.
++ This should be called BEFORE any thread in created and WITHOUT the
++ allocation lock held. */
++
++void GC_init_dyld() {
++ static unsigned long dummy;
++# ifdef DARWIN_DEBUG
++ GC_printf0("Forcing full bind of GC code...\n");
++# endif
++
++ if(!_dyld_bind_fully_image_containing_address(&dummy))
++ GC_abort("_dyld_bind_fully_image_containing_addres failed");
++
++# ifdef DARWIN_DEBUG
++ GC_printf0("Registering dyld callbacks...\n");
++# endif
++
++ /* Apple's Documentation:
++ When you call _dyld_register_func_for_add_image, the dynamic linker runtime calls
++ the specified callback (func) once for each of the images that is currently loaded
++ into the program. When a new image is added to the program, your callback is called
++ again with the mach_header for the new image, and the virtual memory slide amount
++ of the new image.
++
++ This WILL properly register existing and all future libraries
++ */
++
++ _dyld_register_func_for_add_image(GC_dyld_image_add);
++ _dyld_register_func_for_remove_image(GC_dyld_image_remove);
++}
++
++#define HAVE_REGISTER_MAIN_STATIC_DATA
++GC_bool GC_register_main_static_data()
++{
++ /* Already done through dyld callbacks */
++ return FALSE;
++}
++
++#endif /* DARWIN */
+
+ #else /* !DYNAMIC_LOADING */
+
+diff -ur boehm-gc/gc_dlopen.c gcc-3.3+/boehm-gc/gc_dlopen.c
+--- boehm-gc/gc_dlopen.c Tue Oct 16 02:01:35 2001
++++ boehm-gc/gc_dlopen.c Mon Jun 16 01:19:56 2003
+@@ -24,7 +24,8 @@
+
+ #include "private/gc_priv.h"
+
+-# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
++# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
++ || defined(GC_SOLARIS_THREADS)
+
+ # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
+ /* To support various threads pkgs, gc.h interposes on dlopen by */
+diff -ur boehm-gc/include/gc.h gcc-3.3+/boehm-gc/include/gc.h
+--- boehm-gc/include/gc.h Mon Feb 11 20:37:56 2002
++++ boehm-gc/include/gc.h Mon Jun 16 01:19:56 2003
+@@ -74,7 +74,8 @@
+
+ # if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
+ defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
+- defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
++ defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
++ defined(GC_DARWIN_THREADS)
+ # define GC_PTHREADS
+ # endif
+
+@@ -419,6 +420,10 @@
+ GC_API void GC_add_roots GC_PROTO((char * low_address,
+ char * high_address_plus_1));
+
++/* Remove a root segment. Wizards only. */
++GC_API void GC_remove_roots GC_PROTO((char * low_address,
++ char * high_address_plus_1));
++
+ /* Add a displacement to the set of those considered valid by the */
+ /* collector. GC_register_displacement(n) means that if p was returned */
+ /* by GC_malloc, then (char *)p + n will be considered to be a valid */
+@@ -920,7 +925,11 @@
+ */
+ # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); }
+ # else
+-# define GC_INIT()
++# if defined(__APPLE__) && defined(__MACH__)
++# define GC_INIT() { GC_init(); }
++# else
++# define GC_INIT()
++# endif
+ # endif
+ #endif
+
+diff -ur boehm-gc/include/gc_pthread_redirects.h gcc-3.3+/boehm-gc/include/gc_pthread_redirects.h
+--- boehm-gc/include/gc_pthread_redirects.h Tue Oct 16 21:55:28 2001
++++ boehm-gc/include/gc_pthread_redirects.h Mon Jun 16 01:19:56 2003
+@@ -52,15 +52,21 @@
+ int GC_pthread_create(pthread_t *new_thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg);
++#ifndef GC_DARWIN_THREADS
+ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
++#endif
+ int GC_pthread_join(pthread_t thread, void **retval);
+ int GC_pthread_detach(pthread_t thread);
+
+ # define pthread_create GC_pthread_create
++#ifndef GC_DARWIN_THREADS
+ # define pthread_sigmask GC_pthread_sigmask
++#endif
+ # define pthread_join GC_pthread_join
+ # define pthread_detach GC_pthread_detach
++#ifndef GC_DARWIN_THREADS
+ # define dlopen GC_dlopen
++#endif
+
+ #endif /* GC_xxxxx_THREADS */
+
+diff -ur boehm-gc/include/private/gc_locks.h gcc-3.3+/boehm-gc/include/private/gc_locks.h
+--- boehm-gc/include/private/gc_locks.h Fri Sep 27 13:40:06 2002
++++ boehm-gc/include/private/gc_locks.h Mon Jun 16 01:19:56 2003
+@@ -145,23 +145,24 @@
+ # if defined(POWERPC)
+ inline static int GC_test_and_set(volatile unsigned int *addr) {
+ int oldval;
+- int temp = 1; // locked value
++ int temp = 1; /* locked value */
+
+ __asm__ __volatile__(
+- "1:\tlwarx %0,0,%3\n" // load and reserve
+- "\tcmpwi %0, 0\n" // if load is
+- "\tbne 2f\n" // non-zero, return already set
+- "\tstwcx. %2,0,%1\n" // else store conditional
+- "\tbne- 1b\n" // retry if lost reservation
+- "2:\t\n" // oldval is zero if we set
++ "1:\tlwarx %0,0,%3\n" /* load and reserve */
++ "\tcmpwi %0, 0\n" /* if load is */
++ "\tbne 2f\n" /* non-zero, return already set */
++ "\tstwcx. %2,0,%1\n" /* else store conditional */
++ "\tbne- 1b\n" /* retry if lost reservation */
++ "\tsync\n" /* import barrier */
++ "2:\t\n" /* oldval is zero if we set */
+ : "=&r"(oldval), "=p"(addr)
+ : "r"(temp), "1"(addr)
+- : "memory");
+- return (int)oldval;
++ : "cr0","memory");
++ return oldval;
+ }
+ # define GC_TEST_AND_SET_DEFINED
+ inline static void GC_clear(volatile unsigned int *addr) {
+- __asm__ __volatile__("eieio" ::: "memory");
++ __asm__ __volatile__("eieio" : : : "memory");
+ *(addr) = 0;
+ }
+ # define GC_CLEAR_DEFINED
+@@ -323,6 +324,37 @@
+ __asm__ __volatile__("" : : : "memory");
+ }
+ # endif /* I386 */
++
++# if defined(POWERPC)
++# if !defined(GENERIC_COMPARE_AND_SWAP)
++ /* Returns TRUE if the comparison succeeded. */
++ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
++ GC_word old, GC_word new_val)
++ {
++ int result, dummy;
++ __asm__ __volatile__(
++ "1:\tlwarx %0,0,%5\n"
++ "\tcmpw %0,%4\n"
++ "\tbne 2f\n"
++ "\tstwcx. %3,0,%2\n"
++ "\tbne- 1b\n"
++ "\tsync\n"
++ "\tli %1, 1\n"
++ "\tb 3f\n"
++ "2:\tli %1, 0\n"
++ "3:\t\n"
++ : "=&r" (dummy), "=r" (result), "=p" (addr)
++ : "r" (new_val), "r" (old), "2"(addr)
++ : "cr0","memory");
++ return (GC_bool) result;
++ }
++# endif /* !GENERIC_COMPARE_AND_SWAP */
++ inline static void GC_memory_barrier()
++ {
++ __asm__ __volatile__("sync" : : : "memory");
++ }
++# endif /* POWERPC */
++
+ # if defined(IA64)
+ # if !defined(GENERIC_COMPARE_AND_SWAP)
+ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+Only in boehm-gc/include/private: gc_locks.h.orig
+diff -ur boehm-gc/include/private/gc_priv.h gcc-3.3+/boehm-gc/include/private/gc_priv.h
+--- boehm-gc/include/private/gc_priv.h Tue Mar 4 09:56:49 2003
++++ boehm-gc/include/private/gc_priv.h Mon Jun 16 01:19:56 2003
+@@ -347,7 +347,8 @@
+ # include <string.h>
+ # define BCOPY_EXISTS
+ # endif
+-# if defined(MACOSX)
++# if defined(DARWIN)
++# include <string.h>
+ # define BCOPY_EXISTS
+ # endif
+
+@@ -379,7 +380,8 @@
+ + GC_page_size) \
+ + GC_page_size-1)
+ # else
+-# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
++/* FIXME: Darwin mmap works properly in 6.2alpha4, backport the mmap code */
++# if defined(NEXT) || defined(DOS4GW) || defined(DARWIN) || \
+ (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
+ (defined(SUNOS5) && !defined(USE_MMAP))
+ # define GET_MEM(bytes) HBLKPTR((size_t) \
+@@ -1452,6 +1454,7 @@
+ /* Set all mark bits associated with */
+ /* a free list. */
+ void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));
++void GC_remove_roots_inner GC_PROTO((char * b, char * e));
+ GC_bool GC_is_static_root GC_PROTO((ptr_t p));
+ /* Is the address p in one of the registered static */
+ /* root sections? */
+diff -ur boehm-gc/include/private/gcconfig.h gcc-3.3+/boehm-gc/include/private/gcconfig.h
+--- boehm-gc/include/private/gcconfig.h Wed Apr 9 17:08:01 2003
++++ boehm-gc/include/private/gcconfig.h Mon Jun 16 01:19:56 2003
+@@ -244,12 +244,12 @@
+ # endif
+ # if defined(macosx) || \
+ defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
+-# define MACOSX
++# define DARWIN
+ # define POWERPC
+ # define mach_type_known
+ # endif
+ # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
+-# define MACOSX
++# define DARWIN
+ # define I386
+ --> Not really supported, but at least we recognize it.
+ # endif
+@@ -676,16 +676,34 @@
+ extern int _end[];
+ # define DATAEND (_end)
+ # endif
+-# ifdef MACOSX
++# ifdef DARWIN
+ /* There are reasons to suspect this may not be reliable. */
+ # define ALIGNMENT 4
+-# define OS_TYPE "MACOSX"
++# define OS_TYPE "DARWIN"
++# define DYNAMIC_LOADING
++ /* XXX: see get_end(3), get_etext() and get_end() should not be used */
+ # define DATASTART ((ptr_t) get_etext())
+ # define STACKBOTTOM ((ptr_t) 0xc0000000)
+-# define DATAEND /* not needed */
+-# undef MPROTECT_VDB
++# define DATAEND ((ptr_t) get_end())
++/*
++/*
++MMAP support in this version of the collector is broken. It works properly
++in 6.2alpha4. FIXME backport the MMAP changes.
++# define USE_MMAP
++# define USE_MMAP_ANON
++*/
++/* # define MPROTECT_VDB -- There is some evidence that this breaks
++ * on some minor versions of DARWIN, i.e. 10.2.3. In theory,
++ * it should be OK */
+ # include <unistd.h>
+ # define GETPAGESIZE() getpagesize()
++# if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
++ /* The performance impact of prefetches is untested */
++# define PREFETCH(x) \
++ __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
++# define PREFETCH_FOR_WRITE(x) \
++ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
++# endif
+ # endif
+ # ifdef NETBSD
+ # define ALIGNMENT 4
+@@ -1743,7 +1761,7 @@
+
+ # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
+ || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
+- || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1)
++ || defined(BSD) || defined(_AIX) || defined(DARWIN) || defined(OSF1)
+ # define UNIX_LIKE /* Basic Unix-like system calls work. */
+ # endif
+
+@@ -1848,7 +1866,7 @@
+ # define THREADS
+ # endif
+
+-# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \
++# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \
+ || defined(LINT) || defined(MSWINCE) \
+ || (defined(I386) && defined(__LCC__))
+ /* Use setjmp based hack to mark from callee-save registers. */
+Only in boehm-gc/include/private: gcconfig.h.orig
+diff -ur boehm-gc/linux_threads.c gcc-3.3+/boehm-gc/linux_threads.c
+--- boehm-gc/linux_threads.c Fri Mar 29 14:52:12 2002
++++ boehm-gc/linux_threads.c Mon Jun 16 01:19:56 2003
+@@ -57,11 +57,15 @@
+
+ # include "private/gc_priv.h"
+
+-# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
++# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_IFIC) \
+ && !defined(USE_HPUX_TLS)
+ # define USE_HPUX_TLS
+ # endif
+
++#if defined(GC_DARWIN_THREADS)
++# define USE_PTHREAD_SPECIFIC
++#endif
++
+ # ifdef THREAD_LOCAL_ALLOC
+ # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_HPUX_TLS)
+ # include "private/specific.h"
+@@ -87,12 +91,22 @@
+ # include <unistd.h>
+ # include <sys/mman.h>
+ # include <sys/time.h>
+-# include <semaphore.h>
+ # include <signal.h>
+ # include <sys/types.h>
+ # include <sys/stat.h>
+ # include <fcntl.h>
+
++#if !defined(GC_DARWIN_THREADS)
++/* We have our own simple semaphore implementation of darwin */
++# include <semaphore.h>
++#endif /* !GC_DARWIN_THREADS */
++
++#if defined(GC_DARWIN_THREADS)
++# include <sys/sysctl.h>
++# include <mach/mach_types.h>
++# include <mach/thread_act.h>
++#endif /* GC_DARWIN_THREADS */
++
+ #ifndef __GNUC__
+ # define __inline__
+ #endif
+@@ -104,11 +118,91 @@
+ # define WRAP_FUNC(f) GC_##f
+ # define REAL_FUNC(f) f
+ # undef pthread_create
++# if !defined(GC_DARWIN_THREADS)
+ # undef pthread_sigmask
++# endif
+ # undef pthread_join
+ # undef pthread_detach
+ #endif
+
++#if defined(GC_DARWIN_THREADS)
++
++/*
++ This is a very simple semaphore implementation for darwin. It
++ is implemented in terms of pthreads calls so it isn't async signal
++ safe. This isn't a problem because signals aren't used in to
++ suspend threads on darwin.
++*/
++
++typedef struct {
++ pthread_mutex_t mutex;
++ pthread_cond_t cond;
++ int value;
++} sem_t;
++
++static int sem_init(sem_t *sem, int pshared, int value) {
++ int ret;
++ if(pshared)
++ GC_abort("sem_init with pshared set");
++ sem->value = value;
++
++ ret = pthread_mutex_init(&sem->mutex,NULL);
++ if(ret < 0) return -1;
++ ret = pthread_cond_init(&sem->cond,NULL);
++ if(ret < 0) return -1;
++ return 0;
++}
++
++static int sem_post(sem_t *sem) {
++ if(pthread_mutex_lock(&sem->mutex) < 0)
++ return -1;
++ sem->value++;
++ if(pthread_cond_signal(&sem->cond) < 0) {
++ pthread_mutex_unlock(&sem->mutex);
++ return -1;
++ }
++ if(pthread_mutex_unlock(&sem->mutex) < 0)
++ return -1;
++ return 0;
++}
++
++static int sem_wait(sem_t *sem) {
++ if(pthread_mutex_lock(&sem->mutex) < 0)
++ return -1;
++ while(sem->value == 0) {
++ pthread_cond_wait(&sem->cond,&sem->mutex);
++ }
++ sem->value--;
++ if(pthread_mutex_unlock(&sem->mutex) < 0)
++ return -1;
++ return 0;
++}
++
++static int sem_destroy(sem_t *sem) {
++ int ret;
++ ret = pthread_cond_destroy(&sem->cond);
++ if(ret < 0) return -1;
++ ret = pthread_mutex_destroy(&sem->mutex);
++ if(ret < 0) return -1;
++ return 0;
++}
++
++#ifdef POWERPC
++/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
++ Page 49:
++ "The space beneath the stack pointer, where a new stack frame would normally
++ be allocated, is called the red zone. This area as shown in Figure 3-2 may
++ be used for any purpose as long as a new stack frame does not need to be
++ added to the stack."
++
++ Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then
++ it must set up a stack frame just like routines that call other routines."
++*/
++#define DARWIN_PPC_RED_ZONE 224
++#endif POWERPC
++
++#endif /* !GC_DARWIN_THREADS */
++
+
+ void GC_thr_init();
+
+@@ -143,6 +237,9 @@
+ /* guaranteed to be dead, but we may */
+ /* not yet have registered the join.) */
+ pthread_t id;
++#ifdef GC_DARWIN_THREADS
++ mach_port_t mach_thread;
++#endif
+ short flags;
+ # define FINISHED 1 /* Thread has exited. */
+ # define DETACHED 2 /* Thread is intended to be detached. */
+@@ -160,7 +257,9 @@
+ ptr_t backing_store_end;
+ ptr_t backing_store_ptr;
+ # endif
++#ifndef GC_DARWIN_THREADS
+ int signal;
++#endif
+ void * status; /* The value returned from the thread. */
+ /* Used only to avoid premature */
+ /* reclamation of any data it might */
+@@ -447,6 +546,7 @@
+ * pointer(s) and acknowledge.
+ */
+
++#if !defined(GC_DARWIN_THREADS)
+ #ifndef SIG_THR_RESTART
+ # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+ # define SIG_THR_RESTART _SIGRTMIN + 5
+@@ -454,8 +554,11 @@
+ # define SIG_THR_RESTART SIGXCPU
+ # endif
+ #endif
++#endif
+
++#if !defined(GC_DARWIN_THREADS)
+ sem_t GC_suspend_ack_sem;
++#endif /* !GC_DARWIN_THREADS */
+
+ #if 0
+ /*
+@@ -571,6 +674,7 @@
+
+ #endif /* !PARALLEL_MARK */
+
++#if !defined(GC_DARWIN_THREADS)
+ void GC_suspend_handler(int sig)
+ {
+ int dummy;
+@@ -633,7 +737,9 @@
+ GC_printf1("Continuing 0x%x\n", my_thread);
+ #endif
+ }
++#endif /* !GC_DARWIN_THREADS */
+
++#if !defined(GC_DARWIN_THREADS)
+ void GC_restart_handler(int sig)
+ {
+ GC_thread me;
+@@ -660,6 +766,7 @@
+ GC_printf1("In GC_restart_handler for 0x%x\n", pthread_self());
+ #endif
+ }
++#endif /* !GC_DARWIN_THREADS */
+
+ /* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to */
+ /* result in an infinite loop in a signal handler. This can be very */
+@@ -807,6 +914,16 @@
+ register GC_thread p;
+ register int n_live_threads = 0;
+ register int result;
++# if defined(GC_DARWIN_THREADS)
++ kern_return_t kern_result;
++# if defined(POWERPC)
++ struct ppc_thread_state thread_state;
++ thread_state_flavor_t flavor = PPC_THREAD_STATE;
++ mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT;
++# else
++# error FIXME for non-ppc OS X
++# endif
++# endif
+
+ GC_stopping_thread = my_thread; /* debugging only. */
+ GC_stopping_pid = getpid(); /* debugging only. */
+@@ -828,6 +945,56 @@
+ #if DEBUG_THREADS
+ GC_printf1("Sending suspend signal to 0x%x\n", p -> id);
+ #endif
++# if defined(GC_DARWIN_THREADS)
++ GC_ASSERT(p->mach_thread != 0 && p->id != 0);
++ kern_result = thread_suspend(p->mach_thread);
++ if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
++ kern_result = thread_abort_safely(p->mach_thread);
++ /* This shouldn't really be fatal, I don't think. The documentation is kind of unclear */
++ if(kern_result != KERN_SUCCESS) GC_printf1("thread_abort_safely failed (%ul)",kern_result);
++ kern_result = thread_get_state(p->mach_thread,flavor,(natural_t*)&thread_state,&thread_state_count);
++ if(kern_result != KERN_SUCCESS) ABORT("thread_get_state failed");
++# if defined(POWERPC)
++ /* The space just below the stack pointer can also be used.
++ See the comment about the red zone at the top of the file */
++ p->stack_ptr = (void*)(thread_state.r1 - DARWIN_PPC_RED_ZONE);
++ /* Push all the general purpose registers, except the stack pointer. */
++ GC_push_one(thread_state.r0);
++ GC_push_one(thread_state.r2);
++ GC_push_one(thread_state.r3);
++ GC_push_one(thread_state.r4);
++ GC_push_one(thread_state.r5);
++ GC_push_one(thread_state.r6);
++ GC_push_one(thread_state.r7);
++ GC_push_one(thread_state.r8);
++ GC_push_one(thread_state.r9);
++ GC_push_one(thread_state.r10);
++ GC_push_one(thread_state.r11);
++ GC_push_one(thread_state.r12);
++ GC_push_one(thread_state.r13);
++ GC_push_one(thread_state.r14);
++ GC_push_one(thread_state.r15);
++ GC_push_one(thread_state.r16);
++ GC_push_one(thread_state.r17);
++ GC_push_one(thread_state.r18);
++ GC_push_one(thread_state.r19);
++ GC_push_one(thread_state.r20);
++ GC_push_one(thread_state.r21);
++ GC_push_one(thread_state.r22);
++ GC_push_one(thread_state.r23);
++ GC_push_one(thread_state.r24);
++ GC_push_one(thread_state.r25);
++ GC_push_one(thread_state.r26);
++ GC_push_one(thread_state.r27);
++ GC_push_one(thread_state.r28);
++ GC_push_one(thread_state.r29);
++ GC_push_one(thread_state.r30);
++ GC_push_one(thread_state.r31);
++# else
++# error fixme for non ppc os x
++# endif
++
++# else /* GC_DARWIN_THREADS */
+ result = pthread_kill(p -> id, SIG_SUSPEND);
+ switch(result) {
+ case ESRCH:
+@@ -839,13 +1006,16 @@
+ default:
+ ABORT("pthread_kill failed");
+ }
++# endif /* !GC_DARWIN_THREADS */
+ }
+ }
+ }
++# if !defined(GC_DARWIN_THREADS)
+ for (i = 0; i < n_live_threads; i++) {
+ if (0 != sem_wait(&GC_suspend_ack_sem))
+ ABORT("sem_wait in handler failed");
+ }
++# endif /* GC_DARWIN_THREADS */
+ # ifdef PARALLEL_MARK
+ GC_release_mark_lock();
+ # endif
+@@ -864,7 +1034,9 @@
+ register GC_thread p;
+ register int n_live_threads = 0;
+ register int result;
+-
++# if defined(GC_DARWIN_THREADS)
++ kern_return_t kern_result;
++# endif
+ # if DEBUG_THREADS
+ GC_printf0("World starting\n");
+ # endif
+@@ -878,6 +1050,12 @@
+ #if DEBUG_THREADS
+ GC_printf1("Sending restart signal to 0x%x\n", p -> id);
+ #endif
++# if defined(GC_DARWIN_THREADS)
++
++ kern_result = thread_resume(p->mach_thread);
++ if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed");
++
++# else /* GC_DARWIN_THREADS */
+ result = pthread_kill(p -> id, SIG_THR_RESTART);
+ switch(result) {
+ case ESRCH:
+@@ -889,6 +1067,7 @@
+ default:
+ ABORT("pthread_kill failed");
+ }
++# endif /* !GC_DARWIN_THREADS */
+ }
+ }
+ }
+@@ -1039,8 +1218,10 @@
+ if (GC_thr_initialized) return;
+ GC_thr_initialized = TRUE;
+
++# if !defined(GC_DARWIN_THREADS)
+ if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
+ ABORT("sem_init failed");
++ #endif
+
+ act.sa_flags = SA_RESTART;
+ if (sigfillset(&act.sa_mask) != 0) {
+@@ -1055,6 +1236,7 @@
+ }
+ # endif
+
++# if !defined(GC_DARWIN_THREADS)
+ /* SIG_THR_RESTART is unmasked by the handler when necessary. */
+ act.sa_handler = GC_suspend_handler;
+ if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
+@@ -1065,6 +1247,7 @@
+ if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
+ ABORT("Cannot set SIG_THR_RESTART handler");
+ }
++# endif /* !GC_DARWIN_THREADS */
+ # ifdef INSTALL_LOOPING_SEGV_HANDLER
+ act.sa_handler = GC_looping_handler;
+ if (sigaction(SIGSEGV, &act, NULL) != 0
+@@ -1075,6 +1258,9 @@
+
+ /* Add the initial thread, so we can stop it. */
+ t = GC_new_thread(pthread_self());
++# ifdef GC_DARWIN_THREADS
++ t -> mach_thread = mach_thread_self();
++# endif
+ t -> stack_ptr = (ptr_t)(&dummy);
+ t -> flags = DETACHED | MAIN_THREAD;
+
+@@ -1091,6 +1277,12 @@
+ # if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS)
+ GC_nprocs = 1;
+ # endif
++# if defined(GC_DARWIN_THREADS)
++ int ncpus = 1;
++ size_t len = sizeof(ncpus);
++ sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
++ GC_nprocs = ncpus;
++# endif
+ # if defined(GC_LINUX_THREADS)
+ GC_nprocs = GC_get_nprocs();
+ # endif
+@@ -1150,7 +1342,7 @@
+ # endif
+ }
+
+-
++#if !defined(GC_DARWIN_THREADS)
+ int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
+ {
+ sigset_t fudged_set;
+@@ -1162,6 +1354,7 @@
+ }
+ return(REAL_FUNC(pthread_sigmask)(how, set, oset));
+ }
++#endif /* !GC_DARWIN_THREADS */
+
+ /* Wrappers for functions that are likely to block for an appreciable */
+ /* length of time. Must be called in pairs, if at all. */
+@@ -1331,6 +1524,9 @@
+ # endif
+ LOCK();
+ me = GC_new_thread(my_pthread);
++#ifdef GC_DARWIN_THREADS
++ me -> mach_thread = mach_thread_self();
++#endif
+ me -> flags = si -> flags;
+ me -> stack_ptr = 0;
+ /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */
+diff -ur boehm-gc/mark_rts.c gcc-3.3+/boehm-gc/mark_rts.c
+--- boehm-gc/mark_rts.c Mon Mar 3 22:38:29 2003
++++ boehm-gc/mark_rts.c Mon Jun 16 01:19:56 2003
+@@ -275,33 +275,72 @@
+ }
+
+ /* Internal use only; lock held. */
++static void GC_remove_root_at_pos(i)
++int i;
++{
++ GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
++ GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
++ GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
++ GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
++ n_root_sets--;
++}
++
++#if !defined(MSWIN32) && !defined(MSWINCE)
++static void GC_rebuild_root_index()
++{
++ register int i;
++
++ for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
++ for (i = 0; i < n_root_sets; i++)
++ add_roots_to_index(GC_static_roots + i);
++}
++#endif
++
++/* Internal use only; lock held. */
+ void GC_remove_tmp_roots()
+ {
+ register int i;
+
+ for (i = 0; i < n_root_sets; ) {
+ if (GC_static_roots[i].r_tmp) {
+- GC_root_size -=
+- (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
+- GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
+- GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
+- GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
+- n_root_sets--;
++ GC_remove_root_at_pos(i);
+ } else {
+ i++;
+ }
+ }
+-# if !defined(MSWIN32) && !defined(MSWINCE)
+- {
+- register int i;
+-
+- for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
+- for (i = 0; i < n_root_sets; i++)
+- add_roots_to_index(GC_static_roots + i);
+- }
+-# endif
++ #if !defined(MSWIN32) && !defined(MSWINCE)
++ GC_rebuild_root_index();
++ #endif
++}
++
++#if !defined(MSWIN32) && !defined(MSWINCE)
++void GC_remove_roots(b, e)
++char * b; char * e;
++{
++ DCL_LOCK_STATE;
+
++ DISABLE_SIGNALS();
++ LOCK();
++ GC_remove_roots_inner(b, e);
++ UNLOCK();
++ ENABLE_SIGNALS();
++}
++
++/* Should only be called when the lock is held */
++void GC_remove_roots_inner(b,e)
++char * b; char * e;
++{
++ int i;
++ for (i = 0; i < n_root_sets; ) {
++ if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) {
++ GC_remove_root_at_pos(i);
++ } else {
++ i++;
++ }
++ }
++ GC_rebuild_root_index();
+ }
++#endif /* !defined(MSWIN32) && !defined(MSWINCE) */
+
+ #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
+ /* Workaround for the OS mapping and unmapping behind our back: */
+diff -ur boehm-gc/misc.c gcc-3.3+/boehm-gc/misc.c
+--- boehm-gc/misc.c Mon Mar 3 22:38:30 2003
++++ boehm-gc/misc.c Mon Jun 16 01:19:56 2003
+@@ -473,6 +473,14 @@
+ GC_init_parallel();
+ }
+ # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
++# if defined(DYNAMIC_LOADING) && defined(DARWIN)
++ {
++ /* This must be called WITHOUT the allocation lock held
++ and before any threads are created */
++ extern void GC_init_dyld();
++ GC_init_dyld();
++ }
++# endif
+ }
+
+ #if defined(MSWIN32) || defined(MSWINCE)
+diff -ur boehm-gc/os_dep.c gcc-3.3+/boehm-gc/os_dep.c
+--- boehm-gc/os_dep.c Fri Jul 19 01:54:43 2002
++++ boehm-gc/os_dep.c Mon Jun 16 01:19:56 2003
+@@ -1087,7 +1087,7 @@
+ void GC_register_data_segments()
+ {
+ # if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \
+- && !defined(MACOSX)
++ && !defined(DARWIN)
+ # if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
+ /* As of Solaris 2.3, the Solaris threads implementation */
+ /* allocates the data structure for the initial thread with */
+@@ -1104,7 +1104,7 @@
+ # endif
+ # endif
+ # endif
+-# if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
++# if !defined(PCR) && (defined(NEXT) || defined(DARWIN))
+ GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE);
+ # endif
+ # if defined(MACOS)
+@@ -1829,7 +1829,7 @@
+ typedef void (* SIG_PF)();
+ #endif
+ #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
+- || defined(MACOSX) || defined(HURD)
++ || defined(DARWIN) || defined(HURD)
+ # ifdef __STDC__
+ typedef void (* SIG_PF)(int);
+ # else
+@@ -1897,9 +1897,10 @@
+ # endif /* !ALPHA */
+ # endif
+
+-# if defined(MACOSX) /* Should also test for PowerPC? */
++# if defined(DARWIN)
+ typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
+
++# if defined(PPC)
+ /* Decodes the machine instruction which was responsible for the sending of the
+ SIGBUS signal. Sadly this is the only way to find the faulting address because
+ the signal handler doesn't get it directly from the kernel (although it is
+@@ -2022,7 +2023,10 @@
+ #endif
+ return (char *)addr;
+ }
+-#endif /* MACOSX */
++#else /* non-ppc */
++--> FIXME for non-ppc os x
++#endif
++#endif /* DARWIN */
+
+ SIG_PF GC_old_bus_handler;
+ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
+@@ -2146,7 +2150,7 @@
+ # endif
+ # endif
+
+-# if defined(MACOSX)
++# if defined(DARWIN)
+ void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
+ # define SIG_OK (sig == SIGBUS)
+ # define CODE_OK (code == 0 /* experimentally determined */)
+@@ -2225,7 +2229,7 @@
+ # endif
+ # endif
+ # endif
+-# if defined(MACOSX)
++# if defined(DARWIN)
+ char * addr = get_fault_addr(scp);
+ # endif
+ # if defined(MSWIN32) || defined(MSWINCE)
+@@ -2291,7 +2295,7 @@
+ (*(REAL_SIG_PF)old_handler) (sig, code, scp);
+ return;
+ # endif
+-# ifdef MACOSX
++# ifdef DARWIN
+ (*(REAL_SIG_PF)old_handler) (sig, code, scp);
+ # endif
+ # ifdef MSWIN32
+@@ -2389,7 +2393,7 @@
+ (void)sigaddset(&act.sa_mask, SIG_SUSPEND);
+ # endif /* SIG_SUSPEND */
+ # endif
+-# if defined(MACOSX)
++# if defined(DARWIN)
+ struct sigaction act, oldact;
+
+ act.sa_flags = SA_RESTART;
+@@ -2458,7 +2462,7 @@
+ # endif
+ }
+ # endif
+-# if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD)
++# if defined(DARWIN) || defined(HPUX) || defined(LINUX) || defined(HURD)
+ sigaction(SIGBUS, &act, &oldact);
+ GC_old_bus_handler = oldact.sa_handler;
+ if (GC_old_bus_handler == SIG_IGN) {
+diff -ur boehm-gc/tests/test.c gcc-3.3+/boehm-gc/tests/test.c
+--- boehm-gc/tests/test.c Mon Feb 11 20:37:57 2002
++++ boehm-gc/tests/test.c Mon Jun 16 01:19:56 2003
+@@ -1326,6 +1326,10 @@
+ int dummy;
+ # endif
+ n_tests = 0;
++
++#if defined(__APPLE__) && defined(__MACH__)
++ GC_INIT();
++#endif
+
+ # if defined(DJGPP)
+ /* No good way to determine stack base from library; do it */
+@@ -1625,6 +1629,10 @@
+ (void)GC_printf0("pthread_default_stacksize_np failed.\n");
+ }
+ # endif /* GC_HPUX_THREADS */
++# if defined(__APPLE__) && defined(__MACH__)
++ GC_INIT();
++# endif
++
+ pthread_attr_init(&attr);
+ # if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS)
+ pthread_attr_setstacksize(&attr, 1000000);
+diff -ur boehm-gc/tests/test_cpp.cc gcc-3.3+/boehm-gc/tests/test_cpp.cc
+--- boehm-gc/tests/test_cpp.cc Fri Aug 17 11:30:51 2001
++++ boehm-gc/tests/test_cpp.cc Mon Jun 16 01:19:56 2003
+@@ -189,6 +189,8 @@
+ # endif
+ #endif
+
++ GC_init();
++
+ # if defined(MACOS) // MacOS
+ char* argv_[] = {"test_cpp", "10"}; // doesn't
+ argv = argv_; // have a
+diff -ur boehm-gc/threadlibs.c gcc-3.3+/boehm-gc/threadlibs.c
+--- boehm-gc/threadlibs.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/threadlibs.c Mon Jun 16 01:19:56 2003
+@@ -10,7 +10,8 @@
+ "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n");
+ # endif
+ # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \
+- || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS)
++ || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \
++ || defined(GC_DARWIN_THREADS)
+ printf("-lpthread\n");
+ # endif
+ # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
--- /dev/null
+--- gcc/config/mips/mips.md Thu Aug 21 12:04:35 2003
++++ gcc/config/mips/mips.md Thu Aug 21 12:05:59 2003
+@@ -4843,155 +4843,6 @@
+ ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
+ ;; It isn't clear whether this will give better code.
+
+-;; Only specify the mode operand 1, the rest are assumed to be word_mode.
+-(define_expand "extv"
+- [(set (match_operand 0 "register_operand" "")
+- (sign_extract (match_operand:QI 1 "memory_operand" "")
+- (match_operand 2 "immediate_operand" "")
+- (match_operand 3 "immediate_operand" "")))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[3]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[2]) != 64
+- && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when extracting a value from
+- a 64 bit union member. extract_bit_field doesn't verify that our
+- source matches the predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[1]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[1] = adjust_address (operands[1], BLKmode, 0);
+- set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
+- if (INTVAL (operands[2]) == 64)
+- emit_insn (gen_movdi_uld (operands[0], operands[1]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[0] = gen_lowpart (SImode, operands[0]);
+- if (operands[0] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+- }
+- DONE;
+-}")
+-
+-;; Only specify the mode operand 1, the rest are assumed to be word_mode.
+-(define_expand "extzv"
+- [(set (match_operand 0 "register_operand" "")
+- (zero_extract (match_operand:QI 1 "memory_operand" "")
+- (match_operand 2 "immediate_operand" "")
+- (match_operand 3 "immediate_operand" "")))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[3]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[2]) != 64
+- && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when extracting a value from
+- a 64 bit union member. extract_bit_field doesn't verify that our
+- source matches the predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[1]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[1] = adjust_address (operands[1], BLKmode, 0);
+- set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a lwl/lwr pair to load the value. */
+- if (INTVAL (operands[2]) == 64)
+- emit_insn (gen_movdi_uld (operands[0], operands[1]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[0] = gen_lowpart (SImode, operands[0]);
+- if (operands[0] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+- }
+- DONE;
+-}")
+-
+-;; Only specify the mode operands 0, the rest are assumed to be word_mode.
+-(define_expand "insv"
+- [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
+- (match_operand 1 "immediate_operand" "")
+- (match_operand 2 "immediate_operand" ""))
+- (match_operand 3 "register_operand" ""))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[2]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[1]) != 64
+- && INTVAL (operands[1]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when storing into a 32 bit union
+- member. store_bit_field doesn't verify that our target matches the
+- predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[0]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[0] = adjust_address (operands[0], BLKmode, 0);
+- set_mem_size (operands[0], GEN_INT (INTVAL (operands[1]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
+- if (INTVAL (operands[1]) == 64)
+- emit_insn (gen_movdi_usd (operands[0], operands[3]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[3] = gen_lowpart (SImode, operands[3]);
+- if (operands[3] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_usw (operands[0], operands[3]));
+- }
+- DONE;
+-}")
+-
+-;; unaligned word moves generated by the bit field patterns
+-
+ (define_insn "movsi_ulw"
+ [(set (match_operand:SI 0 "register_operand" "=&d,&d")
+ (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
+--- gcc/config/mips/mips.c Fri Jan 31 15:51:23 2003
++++ gcc/config/mips/mips.c Thu Aug 21 20:04:19 2003
+@@ -4027,34 +4027,6 @@
+ bytes -= 8;
+ }
+
+- /* ??? Fails because of a MIPS assembler bug? */
+- else if (TARGET_64BIT && bytes >= 8
+- && ! TARGET_SR71K
+- && ! TARGET_MIPS16)
+- {
+- if (BYTES_BIG_ENDIAN)
+- {
+- load_store[num].load = "ldl\t%0,%1\n\tldr\t%0,%2";
+- load_store[num].load_nop = "ldl\t%0,%1\n\tldr\t%0,%2%#";
+- load_store[num].store = "sdl\t%0,%1\n\tsdr\t%0,%2";
+- load_store[num].last_store = "sdr\t%0,%2";
+- load_store[num].final = "sdl\t%0,%1";
+- }
+- else
+- {
+- load_store[num].load = "ldl\t%0,%2\n\tldr\t%0,%1";
+- load_store[num].load_nop = "ldl\t%0,%2\n\tldr\t%0,%1%#";
+- load_store[num].store = "sdl\t%0,%2\n\tsdr\t%0,%1";
+- load_store[num].last_store = "sdr\t%0,%1";
+- load_store[num].final = "sdl\t%0,%2";
+- }
+-
+- load_store[num].mode = DImode;
+- offset += 8;
+- bytes -= 8;
+- use_lwl_lwr = 1;
+- }
+-
+ else if (bytes >= 4 && align >= 4)
+ {
+ load_store[num].load = "lw\t%0,%1";
+@@ -4065,33 +4037,6 @@
+ load_store[num].mode = SImode;
+ offset += 4;
+ bytes -= 4;
+- }
+-
+- else if (bytes >= 4
+- && ! TARGET_SR71K
+- && ! TARGET_MIPS16)
+- {
+- if (BYTES_BIG_ENDIAN)
+- {
+- load_store[num].load = "lwl\t%0,%1\n\tlwr\t%0,%2";
+- load_store[num].load_nop = "lwl\t%0,%1\n\tlwr\t%0,%2%#";
+- load_store[num].store = "swl\t%0,%1\n\tswr\t%0,%2";
+- load_store[num].last_store = "swr\t%0,%2";
+- load_store[num].final = "swl\t%0,%1";
+- }
+- else
+- {
+- load_store[num].load = "lwl\t%0,%2\n\tlwr\t%0,%1";
+- load_store[num].load_nop = "lwl\t%0,%2\n\tlwr\t%0,%1%#";
+- load_store[num].store = "swl\t%0,%2\n\tswr\t%0,%1";
+- load_store[num].last_store = "swr\t%0,%1";
+- load_store[num].final = "swl\t%0,%2";
+- }
+-
+- load_store[num].mode = SImode;
+- offset += 4;
+- bytes -= 4;
+- use_lwl_lwr = 1;
+ }
+
+ else if (bytes >= 2 && align >= 2)