From a221c4369b3bc859af597794459a92e3cc73862b Mon Sep 17 00:00:00 2001 From: ivmai Date: Sun, 13 Feb 2011 18:44:37 +0000 Subject: [PATCH] 2011-02-13 Ivan Maidanski * 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 | 23 ++++++ include/private/gc_priv.h | 15 ++++ mark.c | 6 +- os_dep.c | 158 +++++++++++++++++++++----------------- 4 files changed, 127 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9570ac9..a8c4cacd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2011-02-13 Ivan Maidanski + + * 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 (with input from Dimitry Andric) * os_dep.c: Don't include signal.h for GC_write_fault_handler on diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 556cf60f..f39d0e21 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -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 dd4aca4b..19aca979 100644 --- 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__ */ diff --git a/os_dep.c b/os_dep.c index b939d5b1..e52661f0 100644 --- 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 */ -- 2.40.0