Skip to content

Commit 0655063

Browse files
rnagyvargaz
authored andcommitted
Add support for the internal boehm-gc on OpenBSD
1 parent f2e095f commit 0655063

13 files changed

+211
-13
lines changed

libgc/Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \
4747
solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \
4848
backgraph.c win32_threads.c \
4949
pthread_support.c pthread_stop_world.c darwin_stop_world.c \
50-
mach_dep.c $(asm_libgc_sources)
50+
openbsd_stop_world.c mach_dep.c $(asm_libgc_sources)
5151

5252
# Include THREADDLLIBS here to ensure that the correct versions of
5353
# linuxthread semaphore functions get linked:

libgc/configure.in

+7
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ case "$THREADS" in
147147
fi
148148
AC_DEFINE(THREAD_LOCAL_ALLOC)
149149
;;
150+
*-*-openbsd*)
151+
AC_DEFINE(GC_OPENBSD_THREADS)
152+
if test "${enable_parallel_mark}" = yes; then
153+
AC_DEFINE(PARALLEL_MARK)
154+
fi
155+
AC_DEFINE(THREAD_LOCAL_ALLOC)
156+
;;
150157
*-*-osf*)
151158
AC_DEFINE(GC_OSF1_THREADS)
152159
if test "${enable_parallel_mark}" = yes; then

libgc/dyn_load.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
!defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
5858
!defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \
5959
!(defined(FREEBSD) && defined(__ELF__)) && \
60+
!(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
6061
!(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
6162
!defined(DARWIN)
6263
--> We only know how to find data segments of dynamic libraries for the
@@ -92,9 +93,12 @@
9293

9394
#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
9495
(defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
96+
(defined(OPENBSD) && defined(__ELF__)) || \
9597
(defined(NETBSD) && defined(__ELF__)) || defined(HURD)
9698
# include <stddef.h>
99+
# if !defined(OPENBSD)
97100
# include <elf.h>
101+
# endif
98102
# include <link.h>
99103
#endif
100104

@@ -295,6 +299,7 @@ void GC_register_dynamic_libraries()
295299

296300
#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
297301
(defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
302+
(defined(OPENBSD) && defined(__ELF__)) || \
298303
(defined(NETBSD) && defined(__ELF__)) || defined(HURD)
299304

300305

@@ -473,8 +478,10 @@ GC_bool GC_register_main_static_data()
473478
/* This doesn't necessarily work in all cases, e.g. with preloaded
474479
* dynamic libraries. */
475480

476-
#if defined(NETBSD)
481+
#if defined(NETBSD) || defined(OPENBSD)
482+
# if !defined(OPENBSD)
477483
# include <sys/exec_elf.h>
484+
# endif
478485
/* for compatibility with 1.4.x */
479486
# ifndef DT_DEBUG
480487
# define DT_DEBUG 21

libgc/include/gc_config_macros.h

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
5858
defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
5959
defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \
60+
defined(GC_OPENBSD_THREADS) || \
6061
(defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
6162
# define GC_PTHREADS
6263
# endif
@@ -87,6 +88,10 @@
8788
# define GC_DARWIN_THREADS
8889
# define GC_PTHREADS
8990
# endif
91+
# if !defined(GC_PTHREADS) && defined(__OpenBSD__)
92+
# define GC_OPENBSD_THREADS
93+
# define GC_PTHREADS
94+
# endif
9095
# if !defined(GC_PTHREADS) && defined(__FreeBSD__)
9196
# define GC_FREEBSD_THREADS
9297
# define GC_PTHREADS

libgc/include/private/gcconfig.h

+32
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@
231231
# define I386
232232
# define mach_type_known
233233
# endif
234+
# if defined(OPENBSD) && defined(__amd64__)
235+
# define X86_64
236+
# define mach_type_known
237+
# endif
234238
# if defined(LINUX) && defined(__x86_64__)
235239
# define X86_64
236240
# define mach_type_known
@@ -1304,6 +1308,18 @@
13041308
# endif
13051309
# ifdef OPENBSD
13061310
# define OS_TYPE "OPENBSD"
1311+
# ifdef GC_OPENBSD_THREADS
1312+
# define UTHREAD_SP_OFFSET 192
1313+
# else
1314+
# include <sys/param.h>
1315+
# include <uvm/uvm_extern.h>
1316+
# define STACKBOTTOM USRSTACK
1317+
# endif
1318+
extern int __data_start[];
1319+
# define DATASTART ((ptr_t)(__data_start))
1320+
extern char _end[];
1321+
# define DATAEND ((ptr_t)(&_end))
1322+
# define DYNAMIC_LOADING
13071323
# endif
13081324
# ifdef FREEBSD
13091325
# define OS_TYPE "FREEBSD"
@@ -2086,6 +2102,22 @@
20862102
extern char etext[];
20872103
# define SEARCH_FOR_DATA_START
20882104
# endif
2105+
# ifdef OPENBSD
2106+
# define OS_TYPE "OPENBSD"
2107+
# define ELF_CLASS ELFCLASS64
2108+
# ifdef GC_OPENBSD_THREADS
2109+
# define UTHREAD_SP_OFFSET 400
2110+
# else
2111+
# include <sys/param.h>
2112+
# include <uvm/uvm_extern.h>
2113+
# define STACKBOTTOM USRSTACK
2114+
# endif
2115+
extern int __data_start[];
2116+
# define DATASTART ((ptr_t)(__data_start))
2117+
extern char _end[];
2118+
# define DATAEND ((ptr_t)(&_end))
2119+
# define DYNAMIC_LOADING
2120+
# endif
20892121
# endif
20902122

20912123
#if defined(LINUX) && defined(USE_MMAP)

libgc/include/private/pthread_support.h

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#if defined(GC_DARWIN_THREADS)
1010
# include "private/darwin_stop_world.h"
11+
#elif defined(GC_OPENBSD_THREADS)
12+
# include "private/openbsd_stop_world.h"
1113
#else
1214
# include "private/pthread_stop_world.h"
1315
#endif

libgc/mach_dep.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ ptr_t cold_gc_frame;
492492
/* the stack. Return sp. */
493493
# ifdef SPARC
494494
asm(" .seg \"text\"");
495-
# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD)
495+
# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD)
496496
asm(" .globl GC_save_regs_in_stack");
497497
asm("GC_save_regs_in_stack:");
498498
asm(" .type GC_save_regs_in_stack,#function");

libgc/misc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ size_t GC_get_total_bytes GC_PROTO(())
473473

474474
int GC_get_suspend_signal GC_PROTO(())
475475
{
476-
#if defined(SIG_SUSPEND) && defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS)
476+
#if defined(SIG_SUSPEND) && defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS) && !defined(GC_OPENBSD_THREADS)
477477
return SIG_SUSPEND;
478478
#else
479479
return -1;
@@ -684,7 +684,7 @@ void GC_init_inner()
684684
# if defined(SEARCH_FOR_DATA_START)
685685
GC_init_linux_data_start();
686686
# endif
687-
# if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
687+
# if defined(NETBSD) && defined(__ELF__)
688688
GC_init_netbsd_elf();
689689
# endif
690690
# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \

libgc/os_dep.c

+144-2
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ static void *tiny_sbrk(ptrdiff_t increment)
392392
#define sbrk tiny_sbrk
393393
# endif /* ECOS */
394394

395-
#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
395+
#if defined(NETBSD) && defined(__ELF__)
396396
ptr_t GC_data_start;
397397

398398
void GC_init_netbsd_elf()
@@ -405,6 +405,102 @@ static void *tiny_sbrk(ptrdiff_t increment)
405405
}
406406
#endif
407407

408+
#if defined(OPENBSD)
409+
static struct sigaction old_segv_act;
410+
sigjmp_buf GC_jmp_buf_openbsd;
411+
412+
# if defined(GC_OPENBSD_THREADS)
413+
# include <sys/syscall.h>
414+
sigset_t __syscall(quad_t, ...);
415+
# endif
416+
417+
/*
418+
* Dont use GC_find_limit() because siglongjmp out of the
419+
* signal handler by-passes our userland pthreads lib, leaving
420+
* SIGSEGV and SIGPROF masked. Instead use this custom one
421+
* that works-around the issues.
422+
*/
423+
424+
/*ARGSUSED*/
425+
void GC_fault_handler_openbsd(int sig)
426+
{
427+
siglongjmp(GC_jmp_buf_openbsd, 1);
428+
}
429+
430+
/* Return the first nonaddressible location > p or bound */
431+
/* Requires allocation lock. */
432+
ptr_t GC_find_limit_openbsd(ptr_t p, ptr_t bound)
433+
{
434+
static volatile ptr_t result;
435+
/* Safer if static, since otherwise it may not be */
436+
/* preserved across the longjmp. Can safely be */
437+
/* static since it's only called with the */
438+
/* allocation lock held. */
439+
struct sigaction act;
440+
size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
441+
442+
GC_ASSERT(I_HOLD_LOCK());
443+
444+
act.sa_handler = GC_fault_handler_openbsd;
445+
sigemptyset(&act.sa_mask);
446+
act.sa_flags = SA_NODEFER | SA_RESTART;
447+
sigaction(SIGSEGV, &act, &old_segv_act);
448+
449+
if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) {
450+
result = (ptr_t)(((word)(p)) & ~(pgsz-1));
451+
for (;;) {
452+
result += pgsz;
453+
if (result >= bound) {
454+
result = bound;
455+
break;
456+
}
457+
GC_noop1((word)(*result));
458+
}
459+
}
460+
461+
# if defined(GC_OPENBSD_THREADS)
462+
/* due to the siglongjump we need to manually unmask SIGPROF */
463+
__syscall(SYS_sigprocmask, SIG_UNBLOCK, sigmask(SIGPROF));
464+
# endif
465+
466+
sigaction(SIGSEGV, &old_segv_act, 0);
467+
468+
return(result);
469+
}
470+
471+
/* Return first addressable location > p or bound */
472+
/* Requires allocation lock. */
473+
ptr_t GC_skip_hole_openbsd(ptr_t p, ptr_t bound)
474+
{
475+
static volatile ptr_t result;
476+
struct sigaction act;
477+
size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
478+
static volatile int firstpass;
479+
480+
GC_ASSERT(I_HOLD_LOCK());
481+
482+
act.sa_handler = GC_fault_handler_openbsd;
483+
sigemptyset(&act.sa_mask);
484+
act.sa_flags = SA_NODEFER | SA_RESTART;
485+
sigaction(SIGSEGV, &act, &old_segv_act);
486+
487+
firstpass = 1;
488+
result = (ptr_t)(((word)(p)) & ~(pgsz-1));
489+
if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) {
490+
firstpass = 0;
491+
result += pgsz;
492+
if (result >= bound) {
493+
result = bound;
494+
} else
495+
GC_noop1((word)(*result));
496+
}
497+
498+
sigaction(SIGSEGV, &old_segv_act, 0);
499+
500+
return(result);
501+
}
502+
#endif
503+
408504
# ifdef OS2
409505

410506
# include <stddef.h>
@@ -1021,7 +1117,8 @@ void *GC_set_stackbottom = NULL;
10211117
#endif /* FREEBSD_STACKBOTTOM */
10221118

10231119
#if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \
1024-
&& !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS)
1120+
&& !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \
1121+
&& !defined(GC_OPENBSD_THREADS)
10251122

10261123
ptr_t GC_get_stack_base()
10271124
{
@@ -1081,6 +1178,25 @@ ptr_t GC_get_stack_base()
10811178

10821179
# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */
10831180

1181+
#if defined(GC_OPENBSD_THREADS)
1182+
1183+
/* Find the stack using pthread_stackseg_np() */
1184+
1185+
# include <sys/signal.h>
1186+
# include <pthread.h>
1187+
# include <pthread_np.h>
1188+
1189+
#define HAVE_GET_STACK_BASE
1190+
1191+
ptr_t GC_get_stack_base()
1192+
{
1193+
stack_t stack;
1194+
pthread_stackseg_np(pthread_self(), &stack);
1195+
return stack.ss_sp;
1196+
}
1197+
1198+
#endif /* GC_OPENBSD_THREADS */
1199+
10841200
/*
10851201
* Register static data segment(s) as roots.
10861202
* If more data segments are added later then they need to be registered
@@ -1445,6 +1561,31 @@ int * etext_addr;
14451561

14461562
#else /* !OS2 && !Windows && !AMIGA */
14471563

1564+
#if defined(OPENBSD)
1565+
1566+
/*
1567+
* Depending on arch alignment there can be multiple holes
1568+
* between DATASTART & DATAEND. Scan from DATASTART - DATAEND
1569+
* and register each region.
1570+
*/
1571+
void GC_register_data_segments(void)
1572+
{
1573+
ptr_t region_start, region_end;
1574+
1575+
region_start = DATASTART;
1576+
1577+
for(;;) {
1578+
region_end = GC_find_limit_openbsd(region_start, DATAEND);
1579+
GC_add_roots_inner(region_start, region_end, FALSE);
1580+
if (region_end < DATAEND)
1581+
region_start = GC_skip_hole_openbsd(region_end, DATAEND);
1582+
else
1583+
break;
1584+
}
1585+
}
1586+
1587+
# else /* !OS2 && !Windows && !AMIGA && !OPENBSD */
1588+
14481589
void GC_register_data_segments()
14491590
{
14501591
# if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
@@ -1504,6 +1645,7 @@ void GC_register_data_segments()
15041645
/* change. */
15051646
}
15061647

1648+
# endif /* ! OPENBSD */
15071649
# endif /* ! AMIGA */
15081650
# endif /* ! MSWIN32 && ! MSWINCE*/
15091651
# endif /* ! OS2 */

libgc/pthread_stop_world.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
44
&& !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \
5-
&& !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS)
5+
&& !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS) \
6+
&& !defined(GC_OPENBSD_THREADS)
67

78
#include <signal.h>
89
#include <semaphore.h>

0 commit comments

Comments
 (0)