This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] boehm-gc: real x86_64-apple-darwin* support


Hello,

this patch brings real 32 and 64-bit support for (i686-apple|x86_64) darwin in boehm-gc.

I tested this patch in several combinations. x86_64-apple-darwin8, i686-apple-darwin8 and powerpc-apple-darwin8.
The powerpc64 test run is missing ;) People know why.


Tested in terms of 'make check' and the test passes.

Thank goes to Eric C. for testing it on the upcoming wildcat.

A similar patch is already committed to the main cvs repository of bdwgc.

Ok for trunk?

Thanks,
Andreas


2007-01-11 Andreas Tobler <a.tobler@schweiz.org>


	* configure.ac: Replaced HAS_I386_THREAD_STATE_* with
	HAS_X86_THREAD_STATE32_* and HAS_X86_THREAD_STATE64_* respectively.
	* configure: Regenerated.
	* include/private/gcconfig.h (DARWIN): Added X86_64 define for Darwin.
	Added base definitions for the X86_64 Darwin port.
	* include/private/gc_priv.h: Added definitions for Darwin MACH thread
	operations. Moved existing THREAD_STATE info from darwin_stop_world.c.
	* darwin_stop_world.c: Removed THREAD_STATE info. Added
	HAS_X86_THREAD_STATE64___RAX. And replaced HAS_I386_THREAD_STATE___EAX
	with HAS_X86_THREAD_STATE32___EAX.
	(GC_push_all_stacks): Use GC_MACH_THREAD_STATE_COUNT. Add code for
	X86_64 Darwin.
	* dyn_load.c (GC_dyld_name_for_hdr): Use GC_MACH_HEADER.
	(GC_dyld_image_add): Use GC_MACH_HEADER and GC_MACH_SECTION.
	Distinguish between getsectbynamefromheader_64 and
	getsectbynamefromheader.
	(GC_dyld_image_remove): Likewise.
	* os_dep.c (GC_dirty_init): Use GC_MACH_THREAD_STATE.
	(catch_exception_raise): Introduce exception information for I386 and
	X86_64 Darwin. Add X86_64 for exc_state.faultvaddr.


Index: configure.ac
===================================================================
--- configure.ac	(revision 120671)
+++ configure.ac	(working copy)
@@ -248,33 +248,46 @@
 case "$host" in
   powerpc*-*-darwin*)
     AC_CHECK_MEMBER(ppc_thread_state_t.r0,
-      AC_DEFINE(HAS_PPC_THREAD_STATE_R0,,[ppc_thread_state_t has field r0]),,
+      AC_DEFINE(HAS_PPC_THREAD_STATE_R0,1,
+	[ppc_thread_state_t has field r0]),,
       [#include <mach/thread_status.h>])
     AC_CHECK_MEMBER(ppc_thread_state_t.__r0,
-      AC_DEFINE(HAS_PPC_THREAD_STATE___R0,,dnl
-        [ppc_thread_state_t has field __r0]),,
+      AC_DEFINE(HAS_PPC_THREAD_STATE___R0,1,dnl
+	[ppc_thread_state_t has field __r0]),,
       [#include <mach/thread_status.h>])
     AC_CHECK_MEMBER(ppc_thread_state64_t.r0,
-      AC_DEFINE(HAS_PPC_THREAD_STATE64_R0,,dnl
-        [ppc_thread_state64_t has field r0]),,
+      AC_DEFINE(HAS_PPC_THREAD_STATE64_R0,1,dnl
+	[ppc_thread_state64_t has field r0]),,
       [#include <mach/thread_status.h>])
     AC_CHECK_MEMBER(ppc_thread_state64_t.__r0,
-      AC_DEFINE(HAS_PPC_THREAD_STATE64___R0,,dnl
-        [ppc_thread_state64_t has field __r0]),,
+      AC_DEFINE(HAS_PPC_THREAD_STATE64___R0,1,dnl
+	[ppc_thread_state64_t has field __r0]),,
       [#include <mach/thread_status.h>])
     ;;
   i?86*-*-darwin*)
-    AC_CHECK_MEMBER(i386_thread_state_t.eax,
-      AC_DEFINE(HAS_I386_THREAD_STATE_EAX,,dnl
-        [i386_thread_state_t has field eax]),,
+    AC_CHECK_MEMBER(x86_thread_state32_t.eax,
+      AC_DEFINE(HAS_X86_THREAD_STATE32_EAX,1,dnl
+	[x86_thread_state32_t has field eax]),,
       [#include <sys/cdefs.h>
-#include <mach/thread_status.h>])
-    AC_CHECK_MEMBER(i386_thread_state_t.__eax,
-      AC_DEFINE(HAS_I386_THREAD_STATE___EAX,,dnl
-        [i386_thread_state_t has field __eax]),,
+      #include <mach/thread_status.h>])
+    AC_CHECK_MEMBER(x86_thread_state32_t.__eax,
+      AC_DEFINE(HAS_X86_THREAD_STATE32___EAX,1,dnl
+	[x86_thread_state32_t has field __eax]),,
       [#include <sys/cdefs.h>
-#include <mach/thread_status.h>])
+      #include <mach/thread_status.h>])
     ;;
+  x86_64-*-darwin*)
+    AC_CHECK_MEMBER(x86_thread_state64_t.rax,
+      AC_DEFINE(HAS_X86_THREAD_STATE64_RAX,1,dnl
+	[x86_thread_state64_t has field rax]),,
+      [#include <sys/cdefs.h>
+      #include <mach/thread_status.h>])
+    AC_CHECK_MEMBER(x86_thread_state64_t.__rax,
+      AC_DEFINE(HAS_X86_THREAD_STATE64___RAX,1,dnl
+	[x86_thread_state64_t has field __rax]),,
+      [#include <sys/cdefs.h>
+      #include <mach/thread_status.h>])
+     ;;
   *) ;;
 esac
 
Index: darwin_stop_world.c
===================================================================
--- darwin_stop_world.c	(revision 120671)
+++ darwin_stop_world.c	(working copy)
@@ -10,7 +10,7 @@
    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."
 */
@@ -22,44 +22,15 @@
 
 /* Try to work out the right way to access thread state structure members.
    The structure has changed its definition in different Darwin versions.  */
-#if defined(__ppc__)
-# define THREAD_STATE ppc_thread_state_t
-# if defined (HAS_PPC_THREAD_STATE_R0)
-#  define THREAD_FLD(x) x
-# elif defined (HAS_PPC_THREAD_STATE___R0)
+/* This now defaults to the (older) names without __, thus hopefully    */
+/* not breaking any existing Makefile.direct builds.                    */
+#if defined (HAS_PPC_THREAD_STATE___R0) ||	\
+    defined (HAS_PPC_THREAD_STATE64___R0) ||	\
+    defined (HAS_X86_THREAD_STATE32___EAX) ||	\
+    defined (HAS_X86_THREAD_STATE64___RAX)
 #  define THREAD_FLD(x) __ ## x
-# else
-#  error can not work out how to access fields of ppc_thread_state_t
-# endif
-#elif defined(__ppc64__)
-# define THREAD_STATE ppc_thread_state64_t
-# if defined (HAS_PPC_THREAD_STATE64_R0)
-#  define THREAD_FLD(x) x
-# elif defined (HAS_PPC_THREAD_STATE64___R0)
-#  define THREAD_FLD(x) __ ## x
-# else
-#  error can not work out how to access fields of ppc_thread_state64_t
-# endif
-#elif defined(__i386__)
-# define THREAD_STATE i386_thread_state_t
-# if defined (HAS_I386_THREAD_STATE_EAX)
-#  define THREAD_FLD(x) x
-# elif defined (HAS_I386_THREAD_STATE___EAX)
-#  define THREAD_FLD(x) __ ## x
-# else
-#  error can not work out how to access fields of i386_thread_state_t
-# endif
-#elif defined(__x86_64__)
-# define THREAD_STATE i386_thread_state_t
-# if defined (HAS_I386_THREAD_STATE_EAX)
-#  define THREAD_FLD(x) x
-# elif defined (HAS_I386_THREAD_STATE___EAX)
-#  define THREAD_FLD(x) __ ## x
-# else
-#  error can not work out how to access fields of i386_thread_state_t
-# endif
 #else
-# error unknown architecture
+#  define THREAD_FLD(x) x
 #endif
 
 typedef struct StackFrame {
@@ -115,8 +86,8 @@
   GC_thread p;
   pthread_t me;
   ptr_t lo, hi;
-  THREAD_STATE state;
-  mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
+  GC_THREAD_STATE_T state;
+  mach_msg_type_number_t thread_state_count = GC_MACH_THREAD_STATE_COUNT;
   
   me = pthread_self();
   if (!GC_thr_initialized) GC_thr_init();
@@ -128,11 +99,8 @@
 	lo = GC_approx_sp();
       } else {
 	/* Get the thread state (registers, etc) */
-	r = thread_get_state(
-			     p->stop_info.mach_thread,
-			     MACHINE_THREAD_STATE,
-			     (natural_t*)&state,
-			     &thread_state_count);
+	r = thread_get_state(p->stop_info.mach_thread, GC_MACH_THREAD_STATE,
+			     (natural_t*)&state, &thread_state_count);
 	if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
 
 #if defined(I386)
@@ -144,7 +112,33 @@
 	GC_push_one(state . THREAD_FLD (edx)); 
 	GC_push_one(state . THREAD_FLD (edi)); 
 	GC_push_one(state . THREAD_FLD (esi)); 
-	GC_push_one(state . THREAD_FLD (ebp)); 
+	GC_push_one(state . THREAD_FLD (ebp));
+
+#elif defined(X86_64)
+	lo = (void*)state . THREAD_FLD (rsp);
+
+	GC_push_one(state . THREAD_FLD (rax));
+	GC_push_one(state . THREAD_FLD (rbx));
+	GC_push_one(state . THREAD_FLD (rcx));
+	GC_push_one(state . THREAD_FLD (rdx));
+	GC_push_one(state . THREAD_FLD (rdi));
+	GC_push_one(state . THREAD_FLD (rsi));
+	GC_push_one(state . THREAD_FLD (rbp));
+	GC_push_one(state . THREAD_FLD (rsp));
+	GC_push_one(state . THREAD_FLD (r8));
+	GC_push_one(state . THREAD_FLD (r9));
+	GC_push_one(state . THREAD_FLD (r10));
+	GC_push_one(state . THREAD_FLD (r11));
+	GC_push_one(state . THREAD_FLD (r12));
+	GC_push_one(state . THREAD_FLD (r13));
+	GC_push_one(state . THREAD_FLD (r14));
+	GC_push_one(state . THREAD_FLD (r15));
+	GC_push_one(state . THREAD_FLD (rip));
+	GC_push_one(state . THREAD_FLD (rflags));
+	GC_push_one(state . THREAD_FLD (cs));
+	GC_push_one(state . THREAD_FLD (fs));
+	GC_push_one(state . THREAD_FLD (gs));
+
 #elif defined(POWERPC)
 	lo = (void*)(state . THREAD_FLD (r1) - PPC_RED_ZONE_SIZE);
         
@@ -221,9 +215,9 @@
 	hi = (ptr_t)FindTopOfStack(0);
       } else {
 #     if defined(__ppc__) || defined(__ppc64__)
-	THREAD_STATE info;
+	GC_THREAD_STATE_T info;
 	mach_msg_type_number_t outCount = THREAD_STATE_MAX;
-	r = thread_get_state(thread, MACHINE_THREAD_STATE,
+	r = thread_get_state(thread, GC_MACH_THREAD_STATE,
 			     (natural_t *)&info, &outCount);
 	if(r != KERN_SUCCESS) ABORT("task_get_state failed");
 
@@ -264,10 +258,10 @@
 #      else
 	/* FIXME: Remove after testing:	*/
 	WARN("This is completely untested and likely will not work\n", 0);
-	THREAD_STATE info;
+	GC_THREAD_STATE_T info;
 	mach_msg_type_number_t outCount = THREAD_STATE_MAX;
-	r = thread_get_state(thread, MACHINE_THREAD_STATE,
-			     (natural_t *)&info, &outCount);
+	r = thread_get_state(thread, GC_MACH_THREAD_STATE, (natural_t *)&info,
+			     &outCount);
 	if(r != KERN_SUCCESS) ABORT("task_get_state failed");
 
 	lo = (void*)info . THREAD_FLD (esp);
Index: dyn_load.c
===================================================================
--- dyn_load.c	(revision 120671)
+++ dyn_load.c	(working copy)
@@ -1152,7 +1152,7 @@
 };
     
 #ifdef DARWIN_DEBUG
-static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) {
+static const char *GC_dyld_name_for_hdr(const struct GC_MACH_HEADER *hdr) {
     unsigned long i,c;
     c = _dyld_image_count();
     for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
@@ -1162,12 +1162,17 @@
 #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) {
+static void GC_dyld_image_add(const struct GC_MACH_HEADER *hdr, intptr_t slide)
+{
     unsigned long start,end,i;
-    const struct section *sec;
+    const struct GC_MACH_SECTION *sec;
     if (GC_no_dls) return;
     for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
-        sec = getsectbynamefromheader(
+#   if defined (__LP64__)
+      sec = getsectbynamefromheader_64(
+#   else
+      sec = getsectbynamefromheader(
+#   endif
             hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
         if(sec == NULL || sec->size == 0) continue;
         start = slide + sec->addr;
@@ -1184,11 +1189,16 @@
 }
 
 /* This should never be called by a thread holding the lock */
-static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) {
+static void GC_dyld_image_remove(const struct GC_MACH_HEADER *hdr,
+				 intptr_t slide) {
     unsigned long start,end,i;
-    const struct section *sec;
+    const struct GC_MACH_SECTION *sec;
     for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
-        sec = getsectbynamefromheader(
+#   if defined (__LP64__)
+      sec = getsectbynamefromheader_64(
+#   else
+      sec = getsectbynamefromheader(
+#   endif
             hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
         if(sec == NULL || sec->size == 0) continue;
         start = slide + sec->addr;
Index: os_dep.c
===================================================================
--- os_dep.c	(revision 120671)
+++ os_dep.c	(working copy)
@@ -3683,7 +3683,7 @@
         mask,
         GC_ports.exception,
         EXCEPTION_DEFAULT,
-        MACHINE_THREAD_STATE
+        GC_MACH_THREAD_STATE
     );
     if(r != KERN_SUCCESS) ABORT("task_set_exception_ports failed");
 
@@ -3802,10 +3802,16 @@
         mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT;
         ppc_exception_state64_t exc_state;
 #     endif
-#   elif defined(I386)
-        thread_state_flavor_t flavor = i386_EXCEPTION_STATE;
-        mach_msg_type_number_t exc_state_count = i386_EXCEPTION_STATE_COUNT;
-        i386_exception_state_t exc_state;
+#   elif defined(I386) || defined(X86_64)
+#     if CPP_WORDSZ == 32
+	thread_state_flavor_t flavor = x86_EXCEPTION_STATE32;
+	mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE32_COUNT;
+	x86_exception_state_t exc_state;
+#     else
+	thread_state_flavor_t flavor = x86_EXCEPTION_STATE64;
+	mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE64_COUNT;
+	x86_exception_state64_t exc_state;
+#     endif
 #   else
 #	error FIXME for non-ppc darwin
 #   endif
@@ -3839,7 +3845,7 @@
     /* This is the address that caused the fault */
 #if defined(POWERPC)
     addr = (char*) exc_state.dar;
-#elif defined (I386)
+#elif defined (I386) || defined (X86_64)
     addr = (char*) exc_state.faultvaddr;
 #else
 #   error FIXME for non POWERPC/I386
Index: include/private/gc_priv.h
===================================================================
--- include/private/gc_priv.h	(revision 120671)
+++ include/private/gc_priv.h	(working copy)
@@ -468,6 +468,39 @@
 #   define GETENV(name) 0
 #endif
 
+#if defined(DARWIN)
+#      if defined(POWERPC)
+#              if CPP_WORDSZ == 32
+#                define GC_THREAD_STATE_T ppc_thread_state_t
+#                define GC_MACH_HEADER mach_header
+#                define GC_MACH_SECTION section
+#              else
+#                define GC_THREAD_STATE_T ppc_thread_state64_t
+#                define GC_MACH_HEADER mach_header_64
+#                define GC_MACH_SECTION section_64
+#              endif
+#              define GC_MACH_THREAD_STATE PPC_THREAD_STATE
+#              define GC_MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
+#      elif defined(I386) || defined(X86_64)
+#              if CPP_WORDSZ == 32
+#                define GC_THREAD_STATE_T x86_thread_state32_t
+#                define GC_MACH_THREAD_STATE x86_THREAD_STATE32
+#                define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT
+#                define GC_MACH_HEADER mach_header
+#                define GC_MACH_SECTION section
+#              else
+#                define GC_THREAD_STATE_T x86_thread_state64_t
+#                define GC_MACH_THREAD_STATE x86_THREAD_STATE64
+#                define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
+#                define GC_MACH_HEADER mach_header_64
+#                define GC_MACH_SECTION section_64
+#              endif
+#      else
+#              error define GC_THREAD_STATE_T
+#              define GC_MACH_THREAD_STATE MACHINE_THREAD_STATE
+#              define GC_MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT
+#      endif
+#endif
 /*********************************/
 /*                               */
 /* Word-size-dependent defines   */
Index: include/private/gcconfig.h
===================================================================
--- include/private/gcconfig.h	(revision 120671)
+++ include/private/gcconfig.h	(working copy)
@@ -302,7 +302,10 @@
 #   if defined(__ppc__)  || defined(__ppc64__)
 #    define POWERPC
 #    define mach_type_known
-#   elif defined(__i386__) || defined(__x86_64)
+#   elif defined(__x86_64__)
+#    define X86_64
+#    define mach_type_known
+#   elif defined(__i386__)
 #    define I386
 #    define mach_type_known
 #   endif
@@ -787,7 +790,7 @@
 #     define DATAEND (_end)
 #   endif
 #   ifdef DARWIN
-#     if defined(__ppc64__) || defined(__x86_64)
+#     if defined(__ppc64__)
 #       define ALIGNMENT 8
 #       define CPP_WORDSZ 64
 #     else
@@ -796,7 +799,7 @@
 #     define OS_TYPE "DARWIN"
 #     define DYNAMIC_LOADING
       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
-         These aren't used when dyld support is enabled (it is by default) */
+	 These aren't used when dyld support is enabled (it is by default) */
 #     define DATASTART ((ptr_t) get_etext())
 #     define DATAEND	((ptr_t) get_end())
 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
@@ -804,9 +807,9 @@
 #     define USE_MMAP_ANON
 #     define USE_ASM_PUSH_REGS
       /* This is potentially buggy. It needs more testing. See the comments in
-         os_dep.c.  It relies on threads to track writes. */
+	 os_dep.c.  It relies on threads to track writes. */
 #     ifdef GC_DARWIN_THREADS
-/* #       define MPROTECT_VDB -- diabled for now.  May work for some apps. */
+/*#       define MPROTECT_VDB -- diabled for now.  May work for some apps. */
 #     endif
 #     include <unistd.h>
 #     define GETPAGESIZE() getpagesize()
@@ -818,7 +821,7 @@
 	  __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
 #     endif
       /* There seems to be some issues with trylock hanging on darwin. This
-         should be looked into some more */
+	 should be looked into some more */
 #     define NO_PTHREAD_TRYLOCK
 #   endif
 #   ifdef FREEBSD
@@ -1313,7 +1316,7 @@
 #     define DARWIN_DONT_PARSE_STACK
 #     define DYNAMIC_LOADING
       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
-        These aren't used when dyld support is enabled (it is by default) */
+	 These aren't used when dyld support is enabled (it is by default) */
 #     define DATASTART ((ptr_t) get_etext())
 #     define DATAEND	((ptr_t) get_end())
 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
@@ -1321,15 +1324,15 @@
 #     define USE_MMAP_ANON
 #     define USE_ASM_PUSH_REGS
       /* This is potentially buggy. It needs more testing. See the comments in
-        os_dep.c.  It relies on threads to track writes. */
+	 os_dep.c.  It relies on threads to track writes. */
 #     ifdef GC_DARWIN_THREADS
 /* #       define MPROTECT_VDB -- disabled for now.  May work for some apps. */
 #     endif
 #     include <unistd.h>
 #     define GETPAGESIZE() getpagesize()
       /* There seems to be some issues with trylock hanging on darwin. This
-         should be looked into some more */
-#      define NO_PTHREAD_TRYLOCK
+	 should be looked into some more */
+#     define NO_PTHREAD_TRYLOCK
 #   endif /* DARWIN */
 # endif
 
@@ -1982,6 +1985,28 @@
 #	    define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
 #	endif
 #   endif
+#   ifdef DARWIN
+#     define OS_TYPE "DARWIN"
+#     define DARWIN_DONT_PARSE_STACK
+#     define DYNAMIC_LOADING
+      /* XXX: see get_end(3), get_etext() and get_end() should not be used.
+	 These aren't used when dyld support is enabled (it is by default) */
+#     define DATASTART ((ptr_t) get_etext())
+#     define DATAEND	((ptr_t) get_end())
+#     define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
+#     define USE_MMAP
+#     define USE_MMAP_ANON
+#     ifdef GC_DARWIN_THREADS
+       /* This is potentially buggy. It needs more testing. See the comments in
+	  os_dep.c.  It relies on threads to track writes. */
+#       define MPROTECT_VDB
+#     endif
+#     include <unistd.h>
+#     define GETPAGESIZE() getpagesize()
+      /* There seems to be some issues with trylock hanging on darwin. This
+	 should be looked into some more */
+#     define NO_PTHREAD_TRYLOCK
+#   endif
 #   ifdef FREEBSD
 #	define OS_TYPE "FREEBSD"
 #	ifndef GC_FREEBSD_THREADS

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]