]> granicus.if.org Git - gc/commitdiff
2011-02-13 Ivan Maidanski <ivmai@mail.ru>
authorivmai <ivmai>
Sun, 13 Feb 2011 18:44:37 +0000 (18:44 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:56 +0000 (21:06 +0400)
* mark.c (GC_mark_some): Prefix and suffix "asm" and "volatile"
keywords with double underscore.
* os_dep.c (GC_unix_get_mem): Reformat the code.
* os_dep.c (catch_exception_raise, catch_exception_raise_state,
catch_exception_raise_state_identity): Add GC_API_OSCALL to
function definition.
* os_dep.c (catch_exception_raise_state,
catch_exception_raise_state_identity): Move definition to be
before GC_ports.
* os_dep.c (catch_exception_raise): Declare to have the symbol
defined before GC_ports.
* os_dep.c (GC_ports): Store references to catch_exception_raise,
catch_exception_raise_state, catch_exception_raise_state_identity
(to prevent stripping these symbols as dead).
* os_dep.c (catch_exception_raise, catch_exception_raise_state,
catch_exception_raise_state_identity): Mark these symbols as
"referenced dynamically" via an assembler directive (unless
NO_DESC_CATCH_EXCEPTION_RAISE).
* include/private/gc_priv.h (GC_API_OSCALL): New macro (defined
similar to GC_API but as if GC_DLL is always defined).

ChangeLog
include/private/gc_priv.h
mark.c
os_dep.c

index f9570ac94d17e6da8da01f9aa0bb177c6acf6f76..a8c4cacd0033b39797a2a4f5ea304ed067d4e639 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2011-02-13  Ivan Maidanski  <ivmai@mail.ru>
+
+       * mark.c (GC_mark_some): Prefix and suffix "asm" and "volatile"
+       keywords with double underscore.
+       * os_dep.c (GC_unix_get_mem): Reformat the code.
+       * os_dep.c (catch_exception_raise, catch_exception_raise_state,
+       catch_exception_raise_state_identity): Add GC_API_OSCALL to
+       function definition.
+       * os_dep.c (catch_exception_raise_state,
+       catch_exception_raise_state_identity): Move definition to be
+       before GC_ports.
+       * os_dep.c (catch_exception_raise): Declare to have the symbol
+       defined before GC_ports.
+       * os_dep.c (GC_ports): Store references to catch_exception_raise,
+       catch_exception_raise_state, catch_exception_raise_state_identity
+       (to prevent stripping these symbols as dead).
+       * os_dep.c (catch_exception_raise, catch_exception_raise_state,
+       catch_exception_raise_state_identity): Mark these symbols as
+       "referenced dynamically" via an assembler directive (unless
+       NO_DESC_CATCH_EXCEPTION_RAISE).
+       * include/private/gc_priv.h (GC_API_OSCALL): New macro (defined
+       similar to GC_API but as if GC_DLL is always defined).
+
 2011-02-10  Ivan Maidanski  <ivmai@mail.ru> (with input from Dimitry Andric)
 
        * os_dep.c: Don't include signal.h for GC_write_fault_handler on
index 556cf60f19d43e7fc9f6f834a3f9fc2bd8e0806e..f39d0e21b3d812e33b48c4c2b1e44aec12c5acd0 100644 (file)
@@ -149,6 +149,21 @@ typedef char * ptr_t;   /* A generic pointer to which we can add        */
 # define GC_INLINE static
 #endif
 
+#ifndef GC_API_OSCALL
+  /* This is used to identify GC routines called by name from OS.       */
+# if defined(__GNUC__)
+#   if __GNUC__ >= 4
+      /* Same as GC_API if GC_DLL.      */
+#     define GC_API_OSCALL extern __attribute__((__visibility__("default")))
+#   else
+      /* The attribute is unsupported.  */
+#     define GC_API_OSCALL extern
+#   endif
+# else
+#   define GC_API_OSCALL GC_API
+# endif
+#endif
+
 #ifndef GC_API_PRIV
 # define GC_API_PRIV GC_API
 #endif
diff --git a/mark.c b/mark.c
index dd4aca4b39525ad201f0fa95189cabcb24eb3704..19aca9797b0f6ea2b321643d4546ec9ada68566e 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -541,8 +541,8 @@ static void alloc_mark_stack(size_t);
 
       er.alt_path = &&handle_ex;
       er.ex_reg.handler = mark_ex_handler;
-      asm volatile ("movl %%fs:0, %0" : "=r" (er.ex_reg.prev));
-      asm volatile ("movl %0, %%fs:0" : : "r" (&er));
+      __asm__ __volatile__ ("movl %%fs:0, %0" : "=r" (er.ex_reg.prev));
+      __asm__ __volatile__ ("movl %0, %%fs:0" : : "r" (&er));
       ret_val = GC_mark_some_inner(cold_gc_frame);
       /* Prevent GCC from considering the following code unreachable */
       /* and thus eliminating it.                                    */
@@ -550,7 +550,7 @@ static void alloc_mark_stack(size_t);
           goto handle_ex;
     rm_handler:
       /* Uninstall the exception handler */
-      asm volatile ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
+      __asm__ __volatile__ ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
       return ret_val;
 
 #    endif /* __GNUC__ */
index b939d5b1fc424ee20673e167c3c62df433df98b1..e52661f0afcfbe7949720d622c0d4a825ec2e2f9 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -2068,13 +2068,11 @@ STATIC ptr_t GC_unix_mmap_get_mem(word bytes)
 # endif  /* MMAP_SUPPORTED */
 
 #if defined(USE_MMAP)
-
-ptr_t GC_unix_get_mem(word bytes)
-{
+  ptr_t GC_unix_get_mem(word bytes)
+  {
     return GC_unix_mmap_get_mem(bytes);
-}
-
-#else /* Not USE_MMAP */
+  }
+#else /* !USE_MMAP */
 
 STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
 {
@@ -2117,10 +2115,10 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
   return(result);
 }
 
-#if defined(MMAP_SUPPORTED)
-  /* By default, we try both sbrk and mmap, in that order. */
-  ptr_t GC_unix_get_mem(word bytes)
-  {
+ptr_t GC_unix_get_mem(word bytes)
+{
+# if defined(MMAP_SUPPORTED)
+    /* By default, we try both sbrk and mmap, in that order.    */
     static GC_bool sbrk_failed = FALSE;
     ptr_t result = 0;
 
@@ -2130,19 +2128,16 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
         result = GC_unix_mmap_get_mem(bytes);
     }
     if (0 == result) {
-        /* Try sbrk again, in case sbrk memory became available. */
+        /* Try sbrk again, in case sbrk memory became available.        */
         result = GC_unix_sbrk_get_mem(bytes);
     }
     return result;
-  }
-#else /* !MMAP_SUPPORTED */
-  ptr_t GC_unix_get_mem(word bytes)
-  {
+# else /* !MMAP_SUPPORTED */
     return GC_unix_sbrk_get_mem(bytes);
-  }
-#endif
+# endif
+}
 
-#endif /* Not USE_MMAP */
+#endif /* !USE_MMAP */
 
 # endif /* UN*X */
 
@@ -2189,13 +2184,12 @@ void * os2_alloc(size_t bytes)
 #endif /* MSWIN32 */
 
 #if defined(MSWIN32) || defined(CYGWIN32)
-
-ptr_t GC_win32_get_mem(word bytes)
-{
+  ptr_t GC_win32_get_mem(word bytes)
+  {
     ptr_t result;
 
 # ifdef CYGWIN32
-    result = GC_unix_get_mem (bytes);
+    result = GC_unix_get_mem(bytes);
 # else
     if (GLOBAL_ALLOC_TEST) {
         /* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE.    */
@@ -2244,20 +2238,19 @@ ptr_t GC_win32_get_mem(word bytes)
     if (GC_n_heap_bases >= MAX_HEAP_SECTS) ABORT("Too many heap sections");
     if (0 != result) GC_heap_bases[GC_n_heap_bases++] = result;
     return(result);
-}
+  }
 
-GC_API void GC_CALL GC_win32_free_heap(void)
-{
-# ifndef CYGWIN32
-    if (GC_no_win32_dlls) {
+  GC_API void GC_CALL GC_win32_free_heap(void)
+  {
+#   ifndef CYGWIN32
+      if (GC_no_win32_dlls) {
         while (GC_n_heap_bases > 0) {
-            GlobalFree (GC_heap_bases[--GC_n_heap_bases]);
-            GC_heap_bases[GC_n_heap_bases] = 0;
+          GlobalFree (GC_heap_bases[--GC_n_heap_bases]);
+          GC_heap_bases[GC_n_heap_bases] = 0;
         }
-    }
-# endif
-}
-
+      }
+#   endif
+  }
 #endif /* MSWIN32 || CYGWIN32 */
 
 #ifdef AMIGA
@@ -3831,22 +3824,60 @@ exception_raise_state_identity(mach_port_t, mach_port_t, mach_port_t,
                                thread_state_t, mach_msg_type_number_t,
                                thread_state_t, mach_msg_type_number_t*);
 
+GC_API_OSCALL kern_return_t
+catch_exception_raise(mach_port_t exception_port, mach_port_t thread,
+                      mach_port_t task, exception_type_t exception,
+                      exception_data_t code, mach_msg_type_number_t code_count);
+
+/* These should never be called, but just in case...  */
+GC_API_OSCALL kern_return_t
+catch_exception_raise_state(mach_port_name_t exception_port, int exception,
+                            exception_data_t code,
+                            mach_msg_type_number_t codeCnt, int flavor,
+                            thread_state_t old_state, int old_stateCnt,
+                            thread_state_t new_state, int new_stateCnt)
+{
+  ABORT("catch_exception_raise_state");
+  return(KERN_INVALID_ARGUMENT);
+}
+
+GC_API_OSCALL kern_return_t
+catch_exception_raise_state_identity(mach_port_name_t exception_port,
+                                     mach_port_t thread, mach_port_t task,
+                                     int exception, exception_data_t code,
+                                     mach_msg_type_number_t codeCnt, int flavor,
+                                     thread_state_t old_state, int old_stateCnt,
+                                     thread_state_t new_state, int new_stateCnt)
+{
+  ABORT("catch_exception_raise_state_identity");
+  return(KERN_INVALID_ARGUMENT);
+}
+
 #define MAX_EXCEPTION_PORTS 16
 
 static struct {
-    mach_msg_type_number_t count;
-    exception_mask_t      masks[MAX_EXCEPTION_PORTS];
-    exception_handler_t   ports[MAX_EXCEPTION_PORTS];
-    exception_behavior_t  behaviors[MAX_EXCEPTION_PORTS];
-    thread_state_flavor_t flavors[MAX_EXCEPTION_PORTS];
+  mach_msg_type_number_t count;
+  exception_mask_t      masks[MAX_EXCEPTION_PORTS];
+  exception_handler_t   ports[MAX_EXCEPTION_PORTS];
+  exception_behavior_t  behaviors[MAX_EXCEPTION_PORTS];
+  thread_state_flavor_t flavors[MAX_EXCEPTION_PORTS];
 } GC_old_exc_ports;
 
 STATIC struct {
-    mach_port_t exception;
-#   if defined(THREADS)
-      mach_port_t reply;
-#   endif
-} GC_ports = {0};
+  void (*volatile os_callback[3])(void);
+  mach_port_t exception;
+# if defined(THREADS)
+    mach_port_t reply;
+# endif
+} GC_ports = {
+  {
+    /* This is to prevent stripping these routines as dead.     */
+    (void (*)(void))catch_exception_raise,
+    (void (*)(void))catch_exception_raise_state,
+    (void (*)(void))catch_exception_raise_state_identity
+  },
+  0
+};
 
 typedef struct {
     mach_msg_header_t head;
@@ -4104,7 +4135,7 @@ GC_INNER void GC_dirty_init(void)
 
 # undef pthread_create
   /* This will call the real pthread function, not our wrapper */
-  if(pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0)
+  if (pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0)
     ABORT("pthread_create failed");
   pthread_attr_destroy(&attr);
 
@@ -4115,14 +4146,14 @@ GC_INNER void GC_dirty_init(void)
       sa.sa_handler = (SIG_HNDLR_PTR)GC_darwin_sigbus;
       sigemptyset(&sa.sa_mask);
       sa.sa_flags = SA_RESTART|SA_SIGINFO;
-      if(sigaction(SIGBUS, &sa, &oldsa) < 0)
+      if (sigaction(SIGBUS, &sa, &oldsa) < 0)
         ABORT("sigaction");
       if ((SIG_HNDLR_PTR)oldsa.sa_handler != SIG_DFL) {
         if (GC_print_stats == VERBOSE)
           GC_err_printf("Replaced other SIGBUS handler\n");
       }
     }
-#  endif /* BROKEN_EXCEPTION_HANDLING  */
+# endif /* BROKEN_EXCEPTION_HANDLING  */
 }
 
 /* The source code for Apple's GDB was used as a reference for the exception
@@ -4180,7 +4211,6 @@ STATIC kern_return_t GC_forward_exception(mach_port_t thread, mach_port_t task,
     if (r != KERN_SUCCESS)
       ABORT("thread_set_state failed in forward_exception");
   }
-
   return r;
 }
 
@@ -4221,7 +4251,7 @@ STATIC kern_return_t GC_forward_exception(mach_port_t thread, mach_port_t task,
 /* be done about it.  The exception handling stuff is hard coded to     */
 /* call this.  catch_exception_raise, catch_exception_raise_state and   */
 /* and catch_exception_raise_state_identity are called from OS.         */
-kern_return_t
+GC_API_OSCALL kern_return_t
 catch_exception_raise(mach_port_t exception_port, mach_port_t thread,
                       mach_port_t task, exception_type_t exception,
                       exception_data_t code, mach_msg_type_number_t code_count)
@@ -4303,7 +4333,7 @@ catch_exception_raise(mach_port_t exception_port, mach_port_t thread,
       register int index = PHT_HASH(h+i);
       async_set_pht_entry_from_index(GC_dirty_pages, index);
     }
-  } else if(GC_mprotect_state == GC_MP_DISCARDING) {
+  } else if (GC_mprotect_state == GC_MP_DISCARDING) {
     /* Lie to the thread for now. No sense UNPROTECT()ing the memory
        when we're just going to PROTECT() it again later. The thread
        will just fault again once it resumes */
@@ -4316,29 +4346,13 @@ catch_exception_raise(mach_port_t exception_port, mach_port_t thread,
 }
 #undef FWD
 
-/* These should never be called, but just in case...  */
-kern_return_t
-catch_exception_raise_state(mach_port_name_t exception_port, int exception,
-                            exception_data_t code,
-                            mach_msg_type_number_t codeCnt, int flavor,
-                            thread_state_t old_state, int old_stateCnt,
-                            thread_state_t new_state, int new_stateCnt)
-{
-  ABORT("catch_exception_raise_state");
-  return(KERN_INVALID_ARGUMENT);
-}
-
-kern_return_t
-catch_exception_raise_state_identity(mach_port_name_t exception_port,
-                                     mach_port_t thread, mach_port_t task,
-                                     int exception, exception_data_t code,
-                                     mach_msg_type_number_t codeCnt, int flavor,
-                                     thread_state_t old_state, int old_stateCnt,
-                                     thread_state_t new_state, int new_stateCnt)
-{
-  ABORT("catch_exception_raise_state_identity");
-  return(KERN_INVALID_ARGUMENT);
-}
+#ifndef NO_DESC_CATCH_EXCEPTION_RAISE
+  /* These symbols should have REFERENCED_DYNAMICALLY (0x10) bit set to */
+  /* let strip know they are not to be stripped.                        */
+  __asm__(".desc _catch_exception_raise, 0x10");
+  __asm__(".desc _catch_exception_raise_state, 0x10");
+  __asm__(".desc _catch_exception_raise_state_identity, 0x10");
+#endif
 
 #endif /* DARWIN && MPROTECT_VDB */