diff -urN phobos/date.d phobos.new/date.d --- phobos/date.d 2003-05-01 23:44:52.000000000 +0900 +++ phobos.new/date.d 2003-08-23 14:58:43.000000000 +0900 @@ -634,6 +634,7 @@ version (linux) { +extern (C) int getTimeZoneInt(); import linux; @@ -647,14 +648,14 @@ return tv.tv_sec * TicksPerSecond + (tv.tv_usec / (1000000 / TicksPerSecond)); } - d_time getLocalTZA() { int t; - +/* time(&t); localtime(&t); // this will set timezone - return -(timezone * TicksPerSecond); + return -(timezone * TicksPerSecond);*/ + return -(getTimeZoneInt() * TicksPerSecond); } /* diff -urN phobos/gc2/gclinux.d phobos.new/gc2/gclinux.d --- phobos/gc2/gclinux.d 2003-05-01 23:48:32.000000000 +0900 +++ phobos.new/gc2/gclinux.d 2003-08-23 14:29:00.000000000 +0900 @@ -71,10 +71,12 @@ /********************************************** * Determine "bottom" of stack (actually the top on x86 systems). */ +extern (C) char* GC_get_stack_base(); void *os_query_stackBottom() { - return __libc_stack_end; +// return __libc_stack_end; + return GC_get_stack_base(); } @@ -82,8 +84,13 @@ * Determine base address and size of static data segment. */ +extern (C) char* GC_get_data_start(); +extern (C) uint GC_get_data_size(); + void os_query_staticdataseg(void **base, uint *nbytes) { - *base = (void *)&__data_start; - *nbytes = &_end - &__data_start; +/* *base = (void *)&__data_start; + *nbytes = &_end - &__data_start;*/ + *base = (void*) GC_get_data_start(); + *nbytes = GC_get_data_size(); } diff -urN phobos/gc2/linux.mak phobos.new/gc2/linux.mak --- phobos/gc2/linux.mak 2003-05-10 01:59:54.000000000 +0900 +++ phobos.new/gc2/linux.mak 2003-08-23 15:37:54.000000000 +0900 @@ -5,13 +5,13 @@ #DMD=/dmd/bin/dmd CFLAGS=-g #DFLAGS=-unittest -g -release -DFLAGS=-release -O -inline -I.. +DFLAGS=-release -O -inline -I.. -g #DFLAGS=-release -inline -O CC=gcc -OBJS= gc.o gcx.o gcbits.o gclinux.o +OBJS= gc.o gcx.o gcbits.o gclinux.o osdep_netbsdelf.o -SRC= gc.d gcx.d gcbits.d win32.d gclinux.d testgc.d win32.mak linux.mak +SRC= gc.d gcx.d gcbits.d win32.d gclinux.d testgc.d win32.mak linux.mak osdep_netbsdelf.c .c.o: $(CC) -c $(CFLAGS) $* @@ -21,12 +21,15 @@ targets : testgc dmgc.a -testgc : testgc.o $(OBJS) linux.mak ../phobos.a - $(CC) -o $@ testgc.o $(OBJS) ../phobos.a -lpthread -lm -g -Xlinker -M +testgc : testgc.o $(OBJS) linux.mak ../libphobos.a + $(CC) -o $@ testgc.o $(OBJS) ../libphobos.a -lpthread -lm -g -Xlinker -M testgc.o : testgc.d $(DMD) -c $(DFLAGS) testgc.d +osdep_netbsdelf.o: osdep_netbsdelf.c + $(CC) -c osdep_netbsdelf.c + dmgc.a : $(OBJS) linux.mak ar -r $@ $(OBJS) diff -urN phobos/gc2/osdep_netbsdelf.c phobos.new/gc2/osdep_netbsdelf.c --- phobos/gc2/osdep_netbsdelf.c 1970-01-01 09:00:00.000000000 +0900 +++ phobos.new/gc2/osdep_netbsdelf.c 2003-08-23 15:58:52.000000000 +0900 @@ -0,0 +1,268 @@ +// XXX derived from boehm-gc + +#include +#include +#include +#include +#include + +#include + +typedef char* ptr_t; +typedef int GC_bool; +typedef int word; + +#define STACK_GROWS_DOWN +#define VOLATILE volatile +#define HEURISTIC2 +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !(FALSE) +#endif + +void GC_noop1(x) +word x; +{ + static VOLATILE word sink; + + sink = x; +} + +# ifdef __STDC__ + typedef void (*handler)(int); +# else + typedef void (*handler)(); +# endif + +# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) || defined(HURD) + static struct sigaction old_segv_act; +# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) || defined(HURD) + static struct sigaction old_bus_act; +# endif +# else + static handler old_segv_handler, old_bus_handler; +# endif + +# ifdef __STDC__ + void GC_set_and_save_fault_handler(handler h) +# else + void GC_set_and_save_fault_handler(h) + handler h; +# endif + { +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) + struct sigaction act; + + act.sa_handler = h; +# ifdef SUNOS5SIGS + act.sa_flags = SA_RESTART | SA_NODEFER; +# else + act.sa_flags = SA_RESTART; +# endif + /* The presence of SA_NODEFER represents yet another gross */ + /* hack. Under Solaris 2.3, siglongjmp doesn't appear to */ + /* interact correctly with -lthread. We hide the confusion */ + /* by making sure that signal handling doesn't affect the */ + /* signal mask. */ + + (void) sigemptyset(&act.sa_mask); +# ifdef GC_IRIX_THREADS + /* Older versions have a bug related to retrieving and */ + /* and setting a handler at the same time. */ + (void) sigaction(SIGSEGV, 0, &old_segv_act); + (void) sigaction(SIGSEGV, &act, 0); +# else + (void) sigaction(SIGSEGV, &act, &old_segv_act); +# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ + || defined(HPUX) || defined(HURD) + /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ + /* Pthreads doesn't exist under Irix 5.x, so we */ + /* don't have to worry in the threads case. */ + (void) sigaction(SIGBUS, &act, &old_bus_act); +# endif +# endif /* GC_IRIX_THREADS */ +# else + old_segv_handler = signal(SIGSEGV, h); +# ifdef SIGBUS + old_bus_handler = signal(SIGBUS, h); +# endif +# endif + } + +static ptr_t GC_data_start = NULL; +static ptr_t GC_data_end = NULL; +void implicit_GC_init_netbsd_elf() +{ + ptr_t GC_find_limit(); + extern char **environ; + if(GC_data_start != NULL) return; + /* This may need to be environ, without the underscore, for */ + /* some versions. */ + GC_data_start = GC_find_limit((ptr_t)&environ, FALSE); + GC_data_end = GC_find_limit((ptr_t)&environ, TRUE); +} + +ptr_t GC_get_data_start() +{ + implicit_GC_init_netbsd_elf(); + return GC_data_start; +} +ptr_t GC_get_data_end() +{ + implicit_GC_init_netbsd_elf(); + return GC_data_end; +} + +unsigned int GC_get_data_size() +{ + implicit_GC_init_netbsd_elf(); + return (unsigned int)(GC_data_end - GC_data_start); +} + + +# define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */ +/* static */ jmp_buf GC_jmp_buf; + +/*ARGSUSED*/ +void GC_fault_handler(sig) + int sig; +{ + longjmp(GC_jmp_buf, 1); +} + +void GC_setup_temporary_fault_handler() +{ + GC_set_and_save_fault_handler(GC_fault_handler); +} + +void GC_reset_fault_handler() +{ +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) + (void) sigaction(SIGSEGV, &old_segv_act, 0); +# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ + || defined(HPUX) || defined(HURD) + (void) sigaction(SIGBUS, &old_bus_act, 0); +# endif +# else + (void) signal(SIGSEGV, old_segv_handler); +# ifdef SIGBUS + (void) signal(SIGBUS, old_bus_handler); +# endif +# endif +} + +/* Return the first nonaddressible location > p (up) or */ +/* the smallest location q s.t. [q,p] is addressible (!up). */ +ptr_t GC_find_limit(p, up) + ptr_t p; + GC_bool up; +{ + static VOLATILE ptr_t result; + /* Needs to be static, since otherwise it may not be */ + /* preserved across the longjmp. Can safely be */ + /* static since it's only called once, with the */ + /* allocation lock held. */ + + GC_setup_temporary_fault_handler(); + if (setjmp(GC_jmp_buf) == 0) { + result = (ptr_t)(((word)(p)) + & ~(MIN_PAGE_SIZE-1)); + for (;;) { + if (up) { + result += MIN_PAGE_SIZE; + } else { + result -= MIN_PAGE_SIZE; + } + GC_noop1((word)(*result)); + } + } + GC_reset_fault_handler(); + if (!up) { + result += MIN_PAGE_SIZE; + } + return(result); +} + + +ptr_t GC_get_stack_base() +{ + word dummy; + ptr_t result; + +# define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1) + +# ifdef STACKBOTTOM + return(STACKBOTTOM); +# else +# ifdef HEURISTIC1 +# ifdef STACK_GROWS_DOWN + result = (ptr_t)((((word)(&dummy)) + + STACKBOTTOM_ALIGNMENT_M1) + & ~STACKBOTTOM_ALIGNMENT_M1); +# else + result = (ptr_t)(((word)(&dummy)) + & ~STACKBOTTOM_ALIGNMENT_M1); +# endif +# endif /* HEURISTIC1 */ +# ifdef LINUX_STACKBOTTOM + result = GC_linux_stack_base(); +# endif +# ifdef FREEBSD_STACKBOTTOM + result = GC_freebsd_stack_base(); +# endif +# ifdef HEURISTIC2 +# ifdef STACK_GROWS_DOWN + result = GC_find_limit((ptr_t)(&dummy), TRUE); +# ifdef HEURISTIC2_LIMIT + if (result > HEURISTIC2_LIMIT + && (ptr_t)(&dummy) < HEURISTIC2_LIMIT) { + result = HEURISTIC2_LIMIT; + } +# endif +# else + result = GC_find_limit((ptr_t)(&dummy), FALSE); +# ifdef HEURISTIC2_LIMIT + if (result < HEURISTIC2_LIMIT + && (ptr_t)(&dummy) > HEURISTIC2_LIMIT) { + result = HEURISTIC2_LIMIT; + } +# endif +# endif +# endif /* HEURISTIC2 */ +# ifdef STACK_GROWS_DOWN + if (result == 0) result = (ptr_t)(int)(-sizeof(ptr_t)); +# endif + return(result); +# endif /* STACKBOTTOM */ +} + + +int getTimeZoneInt(){ + time_t lt = time(NULL); + struct tm *ltm = localtime(<); + return -ltm->tm_gmtoff; +} + +int osdep_netbsdelf_sigfillset(sigset_t* t) +{ + return sigfillset(t); +} +int osdep_netbsdelf_sigdelset(sigset_t* t , int n) +{ + return sigdelset(t, n); +} + +#ifdef TEST +int main(void) +{ + fprintf(stderr, "Dataseg starts: %x(%d), Stack base: %x\n", + GC_get_data_start(), + GC_get_data_size(), + GC_get_stack_base()); +} + +#endif Binary files phobos/gc2/testgc.core and phobos.new/gc2/testgc.core differ Binary files phobos/libphobos.a and phobos.new/libphobos.a differ diff -urN phobos/linux.mak phobos.new/linux.mak --- phobos/linux.mak 2003-08-11 20:42:54.000000000 +0900 +++ phobos.new/linux.mak 2003-08-23 15:41:10.000000000 +0900 @@ -9,9 +9,9 @@ # make unittest # Build libphobos.a, build and run unit tests -CFLAGS=-O +CFLAGS=-O -Dlinux -g #CFLAGS=-g -DFLAGS=-O -release +DFLAGS=-O -release -g #DFLAGS=-unittest CC=gcc @@ -87,7 +87,7 @@ win32.mak linux.mak libphobos.a : $(OBJS) gc2/dmgc.a linux.mak - ar -r $@ $(OBJS) gc2/gc.o gc2/gcx.o gc2/gcbits.o gc2/gclinux.o + ar -r $@ $(OBJS) gc2/gc.o gc2/gcx.o gc2/gcbits.o gc2/gclinux.o gc2/osdep_netbsdelf.o aaA.o : aaA.d $(DMD) -c $(DFLAGS) aaA.d diff -urN phobos/linuxextern.d phobos.new/linuxextern.d --- phobos/linuxextern.d 2003-05-05 01:25:36.000000000 +0900 +++ phobos.new/linuxextern.d 2003-08-23 14:59:28.000000000 +0900 @@ -9,12 +9,13 @@ extern (C) { - void* __libc_stack_end; - int __data_start; - int _end; - int timezone; +// void* __libc_stack_end; +// int __data_start; +// int _end; +// int timezone; void *_deh_beg; void *_deh_end; + } diff -urN phobos/thread.d phobos.new/thread.d --- phobos/thread.d 2003-05-09 02:07:06.000000000 +0900 +++ phobos.new/thread.d 2003-08-23 15:57:20.000000000 +0900 @@ -335,6 +335,8 @@ version (linux) { +// extern (C) void* os_query_stackBottom(); + extern (C) char* GC_get_stack_base(); import linux; import linuxextern; @@ -386,8 +388,9 @@ int sem_init(sem_t*, int, uint); int sem_post(sem_t*); int sched_yield(); - int sigfillset(sigset_t*); - int sigdelset(sigset_t*, int); + int osdep_netbsdelf_sigfillset(sigset_t*); + int osdep_netbsdelf_sigdelset(sigset_t*, int); + int sigaction(int, sigaction_t*, sigaction_t*); int sigsuspend(sigset_t*); } @@ -716,7 +719,6 @@ /************************************** * Create a Thread for global main(). */ - static this() { threadLock = new Object(); @@ -725,7 +727,8 @@ t.state = TS.RUNNING; t.id = pthread_self(); - t.stackBottom = (void*)__libc_stack_end; +// t.stackBottom = (void*)__libc_stack_end; + t.stackBottom = (void*) GC_get_stack_base(); synchronized (threadLock) { assert(!allThreads[0]); @@ -739,7 +742,7 @@ int result; sigaction_t sigact; - result = sigfillset(&sigact.sa_mask); + result = osdep_netbsdelf_sigfillset(&sigact.sa_mask); if (result) goto Lfail; sigact.sa_handler = pauseHandler; @@ -778,9 +781,9 @@ sem_post(&flagSuspend); sigset_t sigmask; - result = sigfillset(&sigmask); + result = osdep_netbsdelf_sigfillset(&sigmask); assert(result == 0); - result = sigdelset(&sigmask, SIGUSR2); + result = osdep_netbsdelf_sigdelset(&sigmask, SIGUSR2); assert(result == 0); Thread t = getThis();