cb6a8938ed
progress, largely based on the gcc port in ports/lang/gcc/4.2. Requested by jsg@. It's somewhat usable on i386 (shared lib versions not yet properly under control). Build on amd64 currently fails with -fPIC problems. -- -- lvm-gcc is the LLVM C front end. It is a modified version of gcc that compiles C/C++/ObjC programs into native objects, LLVM bitcode or LLVM assembly language, depending upon the options. By default, llvm-gcc compiles to native objects just like GCC does. If the -emit-llvm option is given then it will generate LLVM bitcode files instead. If -S (assembly) is also given, then it will generate LLVM assembly. Being derived from the GNU Compiler Collection, llvm-gcc has many of gcc's features and accepts most of gcc's options. It handles a number of gcc's extensions to the C programming language. <sthen@zephyr:/usr/ports/mystuff/lang/llvm-gcc4:9>$CVS: ----------------------------------------------------------------------
191 lines
5.2 KiB
Plaintext
191 lines
5.2 KiB
Plaintext
$OpenBSD: patch-boehm-gc_os_dep_c,v 1.1.1.1 2009/06/22 22:37:32 sthen Exp $
|
|
--- boehm-gc/os_dep.c.orig Tue Jan 16 14:44:17 2007
|
|
+++ boehm-gc/os_dep.c Thu Mar 5 17:11:21 2009
|
|
@@ -380,7 +380,7 @@ static void *tiny_sbrk(ptrdiff_t increment)
|
|
#define sbrk tiny_sbrk
|
|
# endif /* ECOS */
|
|
|
|
-#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
|
|
+#if defined(NETBSD) && defined(__ELF__)
|
|
ptr_t GC_data_start;
|
|
|
|
void GC_init_netbsd_elf()
|
|
@@ -393,6 +393,103 @@ static void *tiny_sbrk(ptrdiff_t increment)
|
|
}
|
|
#endif
|
|
|
|
+#if defined(OPENBSD)
|
|
+ static struct sigaction old_segv_act;
|
|
+ sigjmp_buf GC_jmp_buf_openbsd;
|
|
+
|
|
+# if defined(GC_OPENBSD_THREADS)
|
|
+# include <sys/syscall.h>
|
|
+ sigset_t __syscall(quad_t, ...);
|
|
+# endif
|
|
+
|
|
+ /*
|
|
+ * Dont use GC_find_limit() because siglongjmp out of the
|
|
+ * signal handler by-passes our userland pthreads lib, leaving
|
|
+ * SIGSEGV and SIGPROF masked. Instead use this custom one
|
|
+ * that works-around the issues.
|
|
+ */
|
|
+
|
|
+ /*ARGSUSED*/
|
|
+ void GC_fault_handler_openbsd(int sig)
|
|
+ {
|
|
+ siglongjmp(GC_jmp_buf_openbsd, 1);
|
|
+ }
|
|
+
|
|
+ /* Return the first nonaddressible location > p or bound */
|
|
+ /* Requires allocation lock. */
|
|
+ ptr_t GC_find_limit_openbsd(ptr_t p, ptr_t bound)
|
|
+ {
|
|
+ static volatile ptr_t result;
|
|
+ /* Safer if static, since otherwise it may not be */
|
|
+ /* preserved across the longjmp. Can safely be */
|
|
+ /* static since it's only called with the */
|
|
+ /* allocation lock held. */
|
|
+ struct sigaction act;
|
|
+ size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
|
|
+
|
|
+ GC_ASSERT(I_HOLD_LOCK());
|
|
+
|
|
+ act.sa_handler = GC_fault_handler_openbsd;
|
|
+ sigemptyset(&act.sa_mask);
|
|
+ act.sa_flags = SA_NODEFER | SA_RESTART;
|
|
+ sigaction(SIGSEGV, &act, &old_segv_act);
|
|
+
|
|
+ if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) {
|
|
+ result = (ptr_t)(((word)(p)) & ~(pgsz-1));
|
|
+ for (;;) {
|
|
+ result += pgsz;
|
|
+ if (result >= bound) {
|
|
+ result = bound;
|
|
+ break;
|
|
+ }
|
|
+ GC_noop1((word)(*result));
|
|
+ }
|
|
+ }
|
|
+
|
|
+# if defined(GC_OPENBSD_THREADS)
|
|
+ /* due to the siglongjump we need to manually unmask SIGPROF */
|
|
+ __syscall(SYS_sigprocmask, SIG_UNBLOCK, sigmask(SIGPROF));
|
|
+# endif
|
|
+
|
|
+ sigaction(SIGSEGV, &old_segv_act, 0);
|
|
+
|
|
+ return(result);
|
|
+ }
|
|
+
|
|
+ /* Return first addressable location > p or bound */
|
|
+ /* Requires allocation lock. */
|
|
+ ptr_t GC_skip_hole_openbsd(ptr_t p, ptr_t bound)
|
|
+ {
|
|
+ static volatile ptr_t result;
|
|
+ struct sigaction act;
|
|
+ size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
|
|
+ static volatile int firstpass;
|
|
+
|
|
+ GC_ASSERT(I_HOLD_LOCK());
|
|
+
|
|
+ act.sa_handler = GC_fault_handler_openbsd;
|
|
+ sigemptyset(&act.sa_mask);
|
|
+ act.sa_flags = SA_NODEFER | SA_RESTART;
|
|
+ sigaction(SIGSEGV, &act, &old_segv_act);
|
|
+
|
|
+ firstpass = 1;
|
|
+ result = (ptr_t)(((word)(p)) & ~(pgsz-1));
|
|
+ if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) {
|
|
+ firstpass = 0;
|
|
+ result += pgsz;
|
|
+ if (result >= bound) {
|
|
+ result = bound;
|
|
+ } else
|
|
+ GC_noop1((word)(*result));
|
|
+ }
|
|
+
|
|
+ sigaction(SIGSEGV, &old_segv_act, 0);
|
|
+
|
|
+ return(result);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
# ifdef OS2
|
|
|
|
# include <stddef.h>
|
|
@@ -1007,7 +1104,8 @@ ptr_t GC_get_stack_base()
|
|
#endif /* FREEBSD_STACKBOTTOM */
|
|
|
|
#if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \
|
|
- && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS)
|
|
+ && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \
|
|
+ && !defined(GC_OPENBSD_THREADS)
|
|
|
|
ptr_t GC_get_stack_base()
|
|
{
|
|
@@ -1067,6 +1165,23 @@ ptr_t GC_get_stack_base()
|
|
|
|
# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */
|
|
|
|
+#if defined(GC_OPENBSD_THREADS)
|
|
+
|
|
+/* Find the stack using pthread_stackseg_np() */
|
|
+
|
|
+# include <sys/signal.h>
|
|
+# include <pthread.h>
|
|
+# include <pthread_np.h>
|
|
+
|
|
+#define HAVE_GET_STACK_BASE
|
|
+
|
|
+ptr_t GC_get_stack_base()
|
|
+{
|
|
+ stack_t stack;
|
|
+ pthread_stackseg_np(pthread_self(), &stack);
|
|
+ return stack.ss_sp;
|
|
+}
|
|
+#endif /* GC_OPENBSD_THREADS */
|
|
/*
|
|
* Register static data segment(s) as roots.
|
|
* If more data segments are added later then they need to be registered
|
|
@@ -1434,6 +1549,31 @@ int * etext_addr;
|
|
|
|
#else /* !OS2 && !Windows && !AMIGA */
|
|
|
|
+#if defined(OPENBSD)
|
|
+
|
|
+/*
|
|
+ * Depending on arch alignment there can be multiple holes
|
|
+ * between DATASTART & DATAEND. Scan from DATASTART - DATAEND
|
|
+ * and register each region.
|
|
+ */
|
|
+void GC_register_data_segments(void)
|
|
+{
|
|
+ ptr_t region_start, region_end;
|
|
+
|
|
+ region_start = DATASTART;
|
|
+
|
|
+ for(;;) {
|
|
+ region_end = GC_find_limit_openbsd(region_start, DATAEND);
|
|
+ GC_add_roots_inner(region_start, region_end, FALSE);
|
|
+ if (region_end < DATAEND)
|
|
+ region_start = GC_skip_hole_openbsd(region_end, DATAEND);
|
|
+ else
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+# else /* !OS2 && !Windows && !AMIGA && !OPENBSD */
|
|
+
|
|
void GC_register_data_segments()
|
|
{
|
|
# if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
|
|
@@ -1491,6 +1631,7 @@ void GC_register_data_segments()
|
|
/* change. */
|
|
}
|
|
|
|
+# endif /* ! OPENBSD */
|
|
# endif /* ! AMIGA */
|
|
# endif /* ! MSWIN32 && ! MSWINCE*/
|
|
# endif /* ! OS2 */
|