1 /*
2  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
4  * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
5  *
6  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
8  *
9  * Permission is hereby granted to use or copy this program
10  * for any purpose,  provided the above notices are retained on all copies.
11  * Permission to modify the code and to distribute modified code is granted,
12  * provided the above notices are retained, and a notice that the code was
13  * modified is included with the above copyright notice.
14  */
15 
16 #ifndef CONFIG_H
17 
18 # define CONFIG_H
19 
20 /* Machine dependent parameters.  Some tuning parameters can be found	*/
21 /* near the top of gc_private.h.					*/
22 
23 /* Machine specific parts contributed by various people.  See README file. */
24 
25 /* Determine the machine type: */
26 # if defined(sun) && defined(mc68000)
27 #    define M68K
28 #    define SUNOS4
29 #    define mach_type_known
30 # endif
31 # if defined(hp9000s300)
32 #    define M68K
33 #    define HP
34 #    define mach_type_known
35 # endif
36 # if defined(__NetBSD__) && defined(m68k)
37 #    define M68K
38 #    define NETBSD
39 #    define mach_type_known
40 # endif
41 # if defined(vax)
42 #    define VAX
43 #    ifdef ultrix
44 #	define ULTRIX
45 #    else
46 #	define BSD
47 #    endif
48 #    define mach_type_known
49 # endif
50 # if defined(mips) || defined(__mips)
51 #    define MIPS
52 #    if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
53 #	define ULTRIX
54 #    else
55 #	if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) || defined(__SYSTYPE_SVR4__)
56 #	  define IRIX5   /* or IRIX 6.X */
57 #	else
58 #	  define RISCOS  /* or IRIX 4.X */
59 #	endif
60 #    endif
61 #    define mach_type_known
62 # endif
63 # if defined(sequent) && defined(i386)
64 #    define I386
65 #    define SEQUENT
66 #    define mach_type_known
67 # endif
68 # if defined(sun) && defined(i386)
69 #    define I386
70 #    define SUNOS5
71 #    define mach_type_known
72 # endif
73 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
74 #    define I386
75 #    define OS2
76 #    define mach_type_known
77 # endif
78 # if defined(ibm032)
79 #   define RT
80 #   define mach_type_known
81 # endif
82 # if defined(sun) && (defined(sparc) || defined(__sparc))
83 #   define SPARC
84     /* Test for SunOS 5.x */
85 #     include <errno.h>
86 #     ifdef ECHRNG
87 #       define SUNOS5
88 #     else
89 #	define SUNOS4
90 #     endif
91 #   define mach_type_known
92 # endif
93 # if defined(sparc) && defined(unix) && !defined(sun)
94 #   define SPARC
95 #   define DRSNX
96 #   define mach_type_known
97 # endif
98 # if defined(_IBMR2)
99 #   define RS6000
100 #   define mach_type_known
101 # endif
102 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
103 	/* The above test may need refinement	*/
104 #   define I386
105 #   define SCO
106 #   define mach_type_known
107 # endif
108 # if defined(_AUX_SOURCE)
109 #   define M68K
110 #   define SYSV
111 #   define mach_type_known
112 # endif
113 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1)
114 #   define HP_PA
115 #   define mach_type_known
116 # endif
117 # if defined(linux) && defined(i386)
118 #    define I386
119 #    define LINUX
120 #    define mach_type_known
121 # endif
122 # if defined(linux) && defined(powerpc)
123 #    define POWERPC
124 #    define LINUX
125 #    define mach_type_known
126 # endif
127 # if defined(__alpha) || defined(__alpha__)
128 #   define ALPHA
129 #   if defined(linux) || defined(__linux__)
130 #     define LINUX
131 #   else
132 #     define OSF1	/* a.k.a Digital Unix */
133 #   endif
134 #   define mach_type_known
135 # endif
136 # if defined(_AMIGA)
137 #   define M68K
138 #   define AMIGA
139 #   define mach_type_known
140 # endif
141 # if defined(THINK_C) || defined(__MWERKS__) && !defined(__powerc)
142 #   define M68K
143 #   define MACOS
144 #   define mach_type_known
145 # endif
146 # if defined(__MWERKS__) && defined(__powerc)
147 #   define POWERPC
148 #   define MACOS
149 #   define mach_type_known
150 # endif
151 # if defined(NeXT) && defined(mc68000)
152 #   define M68K
153 #   define NEXT
154 #   define mach_type_known
155 # endif
156 # if defined(NeXT) && defined(i386)
157 #   define I386
158 #   define NEXT
159 #   define mach_type_known
160 # endif
161 # if defined(__FreeBSD__) && defined(i386)
162 #   define I386
163 #   define FREEBSD
164 #   define mach_type_known
165 # endif
166 # if defined(__NetBSD__) && defined(i386)
167 #   define I386
168 #   define NETBSD
169 #   define mach_type_known
170 # endif
171 # if defined(bsdi) && defined(i386)
172 #    define I386
173 #    define BSDI
174 #    define mach_type_known
175 # endif
176 # if !defined(mach_type_known) && defined(__386BSD__)
177 #   define I386
178 #   define THREE86BSD
179 #   define mach_type_known
180 # endif
181 # if defined(_CX_UX) && defined(_M88K)
182 #   define M88K
183 #   define CX_UX
184 #   define mach_type_known
185 # endif
186 # if defined(DGUX)
187 #   define M88K
188     /* DGUX defined */
189 #   define mach_type_known
190 # endif
191 # if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300)
192 #   define I386
193 #   define MSWIN32	/* or Win32s */
194 #   define mach_type_known
195 # endif
196 # if defined(__DJGPP__)
197 #   define I386
198 #   define DJGPP  /* MSDOS running the DJGPP port of GCC */
199 #   define mach_type_known
200 # endif
201 # if defined(__CYGWIN32__)
202 #   define I386
203 #   define CYGWIN32
204 #   define mach_type_known
205 # endif
206 # if defined(__BORLANDC__)
207 #   define I386
208 #   define MSWIN32
209 #   define mach_type_known
210 # endif
211 # if defined(_UTS) && !defined(mach_type_known)
212 #   define S370
213 #   define UTS4
214 #   define mach_type_known
215 # endif
216 /* Ivan Demakov */
217 # if defined(__WATCOMC__) && defined(__386__)
218 #   define I386
219 #   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
220 #     if defined(__OS2__)
221 #       define OS2
222 #     else
223 #       if defined(__WINDOWS_386__) || defined(__NT__)
224 #         define MSWIN32
225 #       else
226 #         define DOS4GW
227 #       endif
228 #     endif
229 #   endif
230 #   define mach_type_known
231 # endif
232 
233 /* Feel free to add more clauses here */
234 
235 /* Or manually define the machine type here.  A machine type is 	*/
236 /* characterized by the architecture.  Some				*/
237 /* machine types are further subdivided by OS.				*/
238 /* the macros ULTRIX, RISCOS, and BSD to distinguish.			*/
239 /* Note that SGI IRIX is treated identically to RISCOS.			*/
240 /* SYSV on an M68K actually means A/UX.					*/
241 /* The distinction in these cases is usually the stack starting address */
242 # ifndef mach_type_known
243 	--> unknown machine type
244 # endif
245 		    /* Mapping is: M68K       ==> Motorola 680X0	*/
246 		    /*		   (SUNOS4,HP,NEXT, and SYSV (A/UX),	*/
247 		    /*		   MACOS and AMIGA variants)		*/
248 		    /*             I386       ==> Intel 386	 	*/
249 		    /*		    (SEQUENT, OS2, SCO, LINUX, NETBSD,	*/
250 		    /*		     FREEBSD, THREE86BSD, MSWIN32,	*/
251 		    /* 		     BSDI, SUNOS5, NEXT	variants)	*/
252                     /*             NS32K      ==> Encore Multimax 	*/
253                     /*             MIPS       ==> R2000 or R3000	*/
254                     /*			(RISCOS, ULTRIX variants)	*/
255                     /*		   VAX	      ==> DEC VAX		*/
256                     /*			(BSD, ULTRIX variants)		*/
257                     /*		   RS6000     ==> IBM RS/6000 AIX3.X	*/
258                     /*		   RT	      ==> IBM PC/RT		*/
259                     /*		   HP_PA      ==> HP9000/700 & /800	*/
260                     /*				  HP/UX			*/
261 		    /*		   SPARC      ==> SPARC under SunOS	*/
262 		    /*			(SUNOS4, SUNOS5,		*/
263 		    /*			 DRSNX variants)		*/
264 		    /* 		   ALPHA      ==> DEC Alpha 		*/
265 		    /*			(OSF1 and LINUX variants)	*/
266 		    /* 		   M88K       ==> Motorola 88XX0        */
267 		    /* 		        (CX_UX and DGUX)		*/
268 		    /* 		   S370	      ==> 370-like machine	*/
269 		    /* 			running Amdahl UTS4		*/
270 
271 
272 /*
273  * For each architecture and OS, the following need to be defined:
274  *
275  * CPP_WORD_SZ is a simple integer constant representing the word size.
276  * in bits.  We assume byte addressibility, where a byte has 8 bits.
277  * We also assume CPP_WORD_SZ is either 32 or 64.
278  * (We care about the length of pointers, not hardware
279  * bus widths.  Thus a 64 bit processor with a C compiler that uses
280  * 32 bit pointers should use CPP_WORD_SZ of 32, not 64. Default is 32.)
281  *
282  * MACH_TYPE is a string representation of the machine type.
283  * OS_TYPE is analogous for the OS.
284  *
285  * ALIGNMENT is the largest N, such that
286  * all pointer are guaranteed to be aligned on N byte boundaries.
287  * defining it to be 1 will always work, but perform poorly.
288  *
289  * DATASTART is the beginning of the data segment.
290  * On UNIX systems, the collector will scan the area between DATASTART
291  * and DATAEND for root pointers.
292  *
293  * DATAEND, if not &end.
294  *
295  * ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice
296  * the pointer size.
297  *
298  * STACKBOTTOM is the cool end of the stack, which is usually the
299  * highest address in the stack.
300  * Under PCR or OS/2, we have other ways of finding thread stacks.
301  * For each machine, the following should:
302  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
303  * 2) define exactly one of
304  *	STACKBOTTOM (should be defined to be an expression)
305  *	HEURISTIC1
306  *	HEURISTIC2
307  * If either of the last two macros are defined, then STACKBOTTOM is computed
308  * during collector startup using one of the following two heuristics:
309  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
310  *		the next multiple of STACK_GRAN.
311  * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly
312  *		in small steps (decrement if STACK_GROWS_UP), and read the value
313  *		at each location.  Remember the value when the first
314  *		Segmentation violation or Bus error is signalled.  Round that
315  *		to the nearest plausible page boundary, and use that instead
316  *		of STACKBOTTOM.
317  *
318  * If no expression for STACKBOTTOM can be found, and neither of the above
319  * heuristics are usable, the collector can still be used with all of the above
320  * undefined, provided one of the following is done:
321  * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
322  *    without reference to STACKBOTTOM.  This is appropriate for use in
323  *    conjunction with thread packages, since there will be multiple stacks.
324  *    (Allocating thread stacks in the heap, and treating them as ordinary
325  *    heap data objects is also possible as a last resort.  However, this is
326  *    likely to introduce significant amounts of excess storage retention
327  *    unless the dead parts of the thread stacks are periodically cleared.)
328  * 2) Client code may set GC_stackbottom before calling any GC_ routines.
329  *    If the author of the client code controls the main program, this is
330  *    easily accomplished by introducing a new main program, setting
331  *    GC_stackbottom to the address of a local variable, and then calling
332  *    the original main program.  The new main program would read something
333  *    like:
334  *
335  *		# include "gc_private.h"
336  *
337  *		main(argc, argv, envp)
338  *		int argc;
339  *		char **argv, **envp;
340  *		{
341  *		    int dummy;
342  *
343  *		    GC_stackbottom = (ptr_t)(&dummy);
344  *		    return(real_main(argc, argv, envp));
345  *		}
346  *
347  *
348  * Each architecture may also define the style of virtual dirty bit
349  * implementation to be used:
350  *   MPROTECT_VDB: Write protect the heap and catch faults.
351  *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
352  *
353  * An architecture may define DYNAMIC_LOADING if dynamic_load.c
354  * defined GC_register_dynamic_libraries() for the architecture.
355  */
356 
357 
358 # define STACK_GRAN 0x1000000
359 # ifdef M68K
360 #   define MACH_TYPE "M68K"
361 #   define ALIGNMENT 2
362 #   ifdef NETBSD
363 #	define OS_TYPE "NETBSD"
364 #	define HEURISTIC2
365 	extern char etext;
366 #	define DATASTART ((ptr_t)(&etext))
367 #   endif
368 #   ifdef SUNOS4
369 #	define OS_TYPE "SUNOS4"
370 	extern char etext;
371 #	define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ffff) & ~0x1ffff))
372 #	define HEURISTIC1	/* differs	*/
373 #	define DYNAMIC_LOADING
374 #   endif
375 #   ifdef HP
376 #	define OS_TYPE "HP"
377 	extern char etext;
378 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
379 #       define STACKBOTTOM ((ptr_t) 0xffeffffc)
380 			      /* empirically determined.  seems to work. */
381 #  	include <unistd.h>
382 #	define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
383 #   endif
384 #   ifdef SYSV
385 #	define OS_TYPE "SYSV"
386 	extern etext;
387 #   	define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \
388 				   & ~0x3fffff) \
389 				  +((word)&etext & 0x1fff))
390 	/* This only works for shared-text binaries with magic number 0413.
391 	   The other sorts of SysV binaries put the data at the end of the text,
392 	   in which case the default of &etext would work.  Unfortunately,
393 	   handling both would require having the magic-number available.
394 	   	   		-- Parag
395 	   */
396 #	define STACKBOTTOM ((ptr_t)0xFFFFFFFE)
397 			/* The stack starts at the top of memory, but   */
398 			/* 0x0 cannot be used as setjump_test complains */
399 			/* that the stack direction is incorrect.  Two  */
400 			/* bytes down from 0x0 should be safe enough.   */
401 			/* 		--Parag				*/
402 #   	include <sys/mmu.h>
403 #	define GETPAGESIZE() PAGESIZE	/* Is this still right? */
404 #   endif
405 #   ifdef AMIGA
406 #	define OS_TYPE "AMIGA"
407  	    	/* STACKBOTTOM and DATASTART handled specially	*/
408  	    	/* in os_dep.c					*/
409 # 	define DATAEND	/* not needed */
410 #	define GETPAGESIZE() 4096
411 #   endif
412 #   ifdef MACOS
413 #     ifndef __LOWMEM__
414 #     include <LowMem.h>
415 #     endif
416 #     define OS_TYPE "MACOS"
417 			/* see os_dep.c for details of global data segments. */
418 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
419 #     define DATAEND	/* not needed */
420 #     define GETPAGESIZE() 4096
421 #   endif
422 #   ifdef NEXT
423 #	define OS_TYPE "NEXT"
424 #	define DATASTART ((ptr_t) get_etext())
425 #	define STACKBOTTOM ((ptr_t) 0x4000000)
426 #	define DATAEND	/* not needed */
427 #   endif
428 # endif
429 
430 # ifdef POWERPC
431 #   define MACH_TYPE "POWERPC"
432 #   define ALIGNMENT 2
433 #   ifdef MACOS
434 #     ifndef __LOWMEM__
435 #     include <LowMem.h>
436 #     endif
437 #     define OS_TYPE "MACOS"
438 			/* see os_dep.c for details of global data segments. */
439 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
440 #     define DATAEND  /* not needed */
441 #   endif
442 #   ifdef LINUX
443 #     define OS_TYPE "LINUX"
444 #     define STACKBOTTOM ((ptr_t)0x80000000)
445 #     define DATASTART GC_data_start
446       extern int _end;
447 #     define DATAEND (&_end)
448 #   endif
449 # endif
450 
451 # ifdef VAX
452 #   define MACH_TYPE "VAX"
453 #   define ALIGNMENT 4	/* Pointers are longword aligned by 4.2 C compiler */
454     extern char etext;
455 #   define DATASTART ((ptr_t)(&etext))
456 #   ifdef BSD
457 #	define OS_TYPE "BSD"
458 #	define HEURISTIC1
459 			/* HEURISTIC2 may be OK, but it's hard to test. */
460 #   endif
461 #   ifdef ULTRIX
462 #	define OS_TYPE "ULTRIX"
463 #	define STACKBOTTOM ((ptr_t) 0x7fffc800)
464 #   endif
465 # endif
466 
467 # ifdef RT
468 #   define MACH_TYPE "RT"
469 #   define ALIGNMENT 4
470 #   define DATASTART ((ptr_t) 0x10000000)
471 #   define STACKBOTTOM ((ptr_t) 0x1fffd800)
472 # endif
473 
474 # ifdef SPARC
475 #   define MACH_TYPE "SPARC"
476 #   define ALIGNMENT 4	/* Required by hardware	*/
477 #   define ALIGN_DOUBLE
478     extern int etext;
479 #   ifdef SUNOS5
480 #	define OS_TYPE "SUNOS5"
481 	extern int _etext;
482 	extern int _end;
483 	extern char * GC_SysVGetDataStart();
484 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
485 #	define DATAEND (&_end)
486 #	ifndef USE_MMAP
487 #	    define USE_MMAP
488 #	endif
489 #       ifdef USE_MMAP
490 #         define HEAP_START (ptr_t)0x40000000
491 #       else
492 #	  define HEAP_START DATAEND
493 #       endif
494 #	define PROC_VDB
495 #	define HEURISTIC1
496 #	include <unistd.h>
497 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
498 		/* getpagesize() appeared to be missing from at least one */
499 		/* Solaris 5.4 installation.  Weird.			  */
500 #   endif
501 #   ifdef SUNOS4
502 #	define OS_TYPE "SUNOS4"
503 	/* [If you have a weak stomach, don't read this.]		*/
504 	/* We would like to use:					*/
505 /* #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x1fff) & ~0x1fff)) */
506 	/* This fails occasionally, due to an ancient, but very 	*/
507 	/* persistent ld bug.  &etext is set 32 bytes too high.		*/
508 	/* We instead read the text segment size from the a.out		*/
509 	/* header, which happens to be mapped into our address space	*/
510 	/* at the start of the text segment.  The detective work here	*/
511 	/* was done by Robert Ehrlich, Manuel Serrano, and Bernard	*/
512 	/* Serpette of INRIA.						*/
513 	/* This assumes ZMAGIC, i.e. demand-loadable executables.	*/
514 #	define TEXTSTART 0x2000
515 #       define DATASTART ((ptr_t)(*(int *)(TEXTSTART+0x4)+TEXTSTART))
516 #	define MPROTECT_VDB
517 #	define HEURISTIC1
518 #   endif
519 #   ifdef DRSNX
520 #       define CPP_WORDSZ 32
521 #	define OS_TYPE "DRSNX"
522 	extern char * GC_SysVGetDataStart();
523 	extern int etext;
524 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext)
525 #	define MPROTECT_VDB
526 #       define STACKBOTTOM ((ptr_t) 0xdfff0000)
527 #   endif
528 #   define DYNAMIC_LOADING
529 # endif
530 
531 # ifdef I386
532 #   define MACH_TYPE "I386"
533 #   define ALIGNMENT 4	/* Appears to hold for all "32 bit" compilers	*/
534 			/* except Borland.  The -a4 option fixes 	*/
535 			/* Borland.					*/
536                         /* Ivan Demakov: For Watcom the option is -zp4. */
537 #   ifndef SMALL_CONFIG
538 #     define ALIGN_DOUBLE /* Not strictly necessary, but may give speed   */
539 			  /* improvement on Pentiums.			  */
540 #   endif
541 #   ifdef SEQUENT
542 #	define OS_TYPE "SEQUENT"
543 	extern int etext;
544 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
545 #       define STACKBOTTOM ((ptr_t) 0x3ffff000)
546 #   endif
547 #   ifdef SUNOS5
548 #	define OS_TYPE "SUNOS5"
549   	extern int etext, _start;
550   	extern char * GC_SysVGetDataStart();
551 #       define DATASTART GC_SysVGetDataStart(0x1000, &etext)
552 #	define STACKBOTTOM ((ptr_t)(&_start))
553 /** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
554 /*#	define PROC_VDB*/
555 #	define DYNAMIC_LOADING
556 #	ifndef USE_MMAP
557 #	    define USE_MMAP
558 #	endif
559 #       ifdef USE_MMAP
560 #         define HEAP_START (ptr_t)0x40000000
561 #       else
562 #	  define HEAP_START DATAEND
563 #       endif
564 #   endif
565 #   ifdef SCO
566 #	define OS_TYPE "SCO"
567 	extern int etext;
568 #   	define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \
569 				  & ~0x3fffff) \
570 				 +((word)&etext & 0xfff))
571 #	define STACKBOTTOM ((ptr_t) 0x7ffffffc)
572 #   endif
573 #   ifdef LINUX
574 #	define OS_TYPE "LINUX"
575 #	define STACKBOTTOM ((ptr_t)0xc0000000)
576 #	define MPROTECT_VDB
577 #       ifdef __ELF__
578 #            define DYNAMIC_LOADING
579 #	     ifdef UNDEFINED	/* includes ro data */
580 	       extern int _etext;
581 #              define DATASTART ((ptr_t)((((word) (&_etext)) + 0xfff) & ~0xfff))
582 #	     endif
583 #	     include <linux/version.h>
584 #	     include <features.h>
585 #	     if LINUX_VERSION_CODE >= 0x20000 && defined(__GLIBC__) && __GLIBC__ >= 2
586 		 extern int __data_start;
587 #		 define DATASTART ((ptr_t)(&__data_start))
588 #	     else
589      	         extern char **__environ;
590 #                define DATASTART ((ptr_t)(&__environ))
591 			      /* hideous kludge: __environ is the first */
592 			      /* word in crt0.o, and delimits the start */
593 			      /* of the data segment, no matter which   */
594 			      /* ld options were passed through.        */
595 			      /* We could use _etext instead, but that  */
596 			      /* would include .rodata, which may       */
597 			      /* contain large read-only data tables    */
598 			      /* that we'd rather not scan.		*/
599 #	     endif
600 	     extern int _end;
601 #	     define DATAEND (&_end)
602 #	else
603 	     extern int etext;
604 #            define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
605 #       endif
606 #   endif
607 #   ifdef CYGWIN32
608 #       define OS_TYPE "CYGWIN32"
609         extern int _bss_start__;
610 #       define DATASTART       ((ptr_t)&_bss_start__)
611         extern int _data_end__;
612 #       define DATAEND          ((ptr_t)&_data_end__)
613 #	undef STACK_GRAN
614 #       define STACK_GRAN 0x10000
615 #       define HEURISTIC1
616 #   endif
617 #   ifdef OS2
618 #	define OS_TYPE "OS2"
619  	    	/* STACKBOTTOM and DATASTART are handled specially in 	*/
620 		/* os_dep.c. OS2 actually has the right			*/
621 		/* system call!						*/
622 #	define DATAEND	/* not needed */
623 #   endif
624 #   ifdef MSWIN32
625 #	define OS_TYPE "MSWIN32"
626 		/* STACKBOTTOM and DATASTART are handled specially in 	*/
627 		/* os_dep.c.						*/
628 #       ifndef __WATCOMC__
629 #	  define MPROTECT_VDB
630 #	endif
631 #       define DATAEND  /* not needed */
632 #   endif
633 #   ifdef DJGPP
634 #       define OS_TYPE "DJGPP"
635 #       include "stubinfo.h"
636         extern int etext;
637         extern int _stklen;
638 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ff) & ~0x1ff))
639 #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
640                                                      + _stklen))
641 		/* This may not be right.  */
642 #   endif
643 #   ifdef FREEBSD
644 #	define OS_TYPE "FREEBSD"
645 #	define MPROTECT_VDB
646 #   endif
647 #   ifdef NETBSD
648 #	define OS_TYPE "NETBSD"
649 #   endif
650 #   ifdef THREE86BSD
651 #	define OS_TYPE "THREE86BSD"
652 #   endif
653 #   ifdef BSDI
654 #	define OS_TYPE "BSDI"
655 #   endif
656 #   if defined(FREEBSD) || defined(NETBSD) \
657         || defined(THREE86BSD) || defined(BSDI)
658 #	define HEURISTIC2
659 	extern char etext;
660 #	define DATASTART ((ptr_t)(&etext))
661 #   endif
662 #   ifdef NEXT
663 #	define OS_TYPE "NEXT"
664 #	define DATASTART ((ptr_t) get_etext())
665 #	define STACKBOTTOM ((ptr_t)0xc0000000)
666 #	define DATAEND	/* not needed */
667 #   endif
668 #   ifdef DOS4GW
669 #     define OS_TYPE "DOS4GW"
670       /* Get_DATASTART, Get_DATAEND, Get_STACKBOTTOM
671        *      Defined in gc-watcom.asm
672        */
673       extern char* Get_DATASTART (void);
674       extern char* Get_DATAEND (void);
675       extern char* Get_STACKBOTTOM (void);
676 #     pragma aux Get_DATASTART "*" value [eax];
677 #     pragma aux Get_DATAEND "*" value [eax];
678 #     pragma aux Get_STACKBOTTOM "*" value [eax];
679 #     define DATASTART ((ptr_t) Get_DATASTART())
680 #     define STACKBOTTOM ((ptr_t) Get_STACKBOTTOM())
681 #     define DATAEND ((ptr_t) Get_DATAEND())
682 #   endif
683 # endif
684 
685 # ifdef NS32K
686 #   define MACH_TYPE "NS32K"
687 #   define ALIGNMENT 4
688     extern char **environ;
689 #   define DATASTART ((ptr_t)(&environ))
690 			      /* hideous kludge: environ is the first   */
691 			      /* word in crt0.o, and delimits the start */
692 			      /* of the data segment, no matter which   */
693 			      /* ld options were passed through.        */
694 #   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */
695 # endif
696 
697 # ifdef MIPS
698 #   define MACH_TYPE "MIPS"
699 #   ifndef IRIX5
700 #     define DATASTART (ptr_t)0x10000000
701 			      /* Could probably be slightly higher since */
702 			      /* startup code allocates lots of stuff.   */
703 #   else
704       extern int _fdata;
705 #     define DATASTART ((ptr_t)(&_fdata))
706 #     ifdef USE_MMAP
707 #         define HEAP_START (ptr_t)0x40000000
708 #     else
709 #	  define HEAP_START DATASTART
710 #     endif
711 			      /* Lowest plausible heap address.		*/
712 			      /* In the MMAP case, we map there.	*/
713 			      /* In either case it is used to identify	*/
714 			      /* heap sections so they're not 		*/
715 			      /* considered as roots.			*/
716 #   endif /* IRIX5 */
717 #   define HEURISTIC2
718 /* #   define STACKBOTTOM ((ptr_t)0x7fff8000)  sometimes also works.  */
719 #   ifdef ULTRIX
720 #	define OS_TYPE "ULTRIX"
721 #       define ALIGNMENT 4
722 #   endif
723 #   ifdef RISCOS
724 #	define OS_TYPE "RISCOS"
725 #   	define ALIGNMENT 4  /* Required by hardware */
726 #   endif
727 #   ifdef IRIX5
728 #	define OS_TYPE "IRIX5"
729 #       ifndef IRIX_THREADS
730 #	    define MPROTECT_VDB
731 #       endif
732 #       ifdef _MIPS_SZPTR
733 #	  define CPP_WORDSZ _MIPS_SZPTR
734 #	  define ALIGNMENT (_MIPS_SZPTR/8)
735 #	  if CPP_WORDSZ != 64
736 #	    define ALIGN_DOUBLE
737 #	  endif
738 #	else
739 #         define ALIGNMENT 4
740 #	  define ALIGN_DOUBLE
741 #	endif
742 #	define DYNAMIC_LOADING
743 #   endif
744 # endif
745 
746 # ifdef RS6000
747 #   define MACH_TYPE "RS6000"
748 #   define ALIGNMENT 4
749 #   define DATASTART ((ptr_t)0x20000000)
750     extern int errno;
751 #   define STACKBOTTOM ((ptr_t)((ulong)&errno + 2*sizeof(int)))
752 #   define DYNAMIC_LOADING
753 	/* For really old versions of AIX, this may have to be removed. */
754 # endif
755 
756 # ifdef HP_PA
757 #   define MACH_TYPE "HP_PA"
758 #   define ALIGNMENT 4
759 #   define ALIGN_DOUBLE
760     extern int __data_start;
761 #   define DATASTART ((ptr_t)(&__data_start))
762 #   if 0
763 	/* The following appears to work for 7xx systems running HP/UX	*/
764 	/* 9.xx Furthermore, it might result in much faster		*/
765 	/* collections than HEURISTIC2, which may involve scanning	*/
766 	/* segments that directly precede the stack.  It is not the	*/
767 	/* default, since it may not work on older machine/OS		*/
768 	/* combinations. (Thanks to Raymond X.T. Nijssen for uncovering	*/
769 	/* this.)							*/
770 #       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */
771 #   else
772 #       define HEURISTIC2
773 #   endif
774 #   define STACK_GROWS_UP
775 #   define DYNAMIC_LOADING
776 #   include <unistd.h>
777 #   define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
778 	/* They misspelled the Posix macro?	*/
779 # endif
780 
781 # ifdef ALPHA
782 #   define MACH_TYPE "ALPHA"
783 #   define ALIGNMENT 8
784 #   ifdef OSF1
785 #	define OS_TYPE "OSF1"
786 #   	define DATASTART ((ptr_t) 0x140000000)
787 #   	define HEURISTIC2
788 	/* Normally HEURISTIC2 is too conervative, since		*/
789 	/* the text segment immediately follows the stack.		*/
790 	/* Hence we give an upper pound.				*/
791     	extern __start;
792 #   	define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1)))
793 #   	define CPP_WORDSZ 64
794 #   	define MPROTECT_VDB
795 #   	define DYNAMIC_LOADING
796 #   endif
797 #   ifdef LINUX
798 #       define OS_TYPE "LINUX"
799 #       define CPP_WORDSZ 64
800 #       define STACKBOTTOM ((ptr_t) 0x120000000)
801 #       ifdef __ELF__
802             extern int __data_start;
803 #           define DATASTART &__data_start
804 #           define DYNAMIC_LOADING
805 #       else
806 #           define DATASTART ((ptr_t) 0x140000000)
807 #       endif
808 	extern int _end;
809 #	define DATAEND (&_end)
810 	/* As of 1.3.90, I couldn't find a way to retrieve the correct	*/
811 	/* fault address from a signal handler.				*/
812 	/* Hence MPROTECT_VDB is broken.				*/
813 #   endif
814 # endif
815 
816 # ifdef M88K
817 #   define MACH_TYPE "M88K"
818 #   define ALIGNMENT 4
819 #   define ALIGN_DOUBLE
820     extern int etext;
821 #   ifdef CX_UX
822 #	define OS_TYPE "CX_UX"
823 #       define DATASTART ((((word)&etext + 0x3fffff) & ~0x3fffff) + 0x10000)
824 #   endif
825 #   ifdef  DGUX
826 #	define OS_TYPE "DGUX"
827 	extern char * GC_SysVGetDataStart();
828 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext)
829 #   endif
830 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
831 # endif
832 
833 # ifdef S370
834 #   define MACH_TYPE "S370"
835 #   define OS_TYPE "UTS4"
836 #   define ALIGNMENT 4	/* Required by hardware	*/
837     extern int etext;
838 	extern int _etext;
839 	extern int _end;
840 	extern char * GC_SysVGetDataStart();
841 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
842 #	define DATAEND (&_end)
843 #	define HEURISTIC2
844 # endif
845 
846 # ifndef STACK_GROWS_UP
847 #   define STACK_GROWS_DOWN
848 # endif
849 
850 # ifndef CPP_WORDSZ
851 #   define CPP_WORDSZ 32
852 # endif
853 
854 # ifndef OS_TYPE
855 #   define OS_TYPE ""
856 # endif
857 
858 # ifndef DATAEND
859     extern int end;
860 #   define DATAEND (&end)
861 # endif
862 
863 # if defined(SVR4) && !defined(GETPAGESIZE)
864 #    include <unistd.h>
865 #    define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
866 # endif
867 
868 # ifndef GETPAGESIZE
869 #   if defined(SUNOS5) || defined(IRIX5)
870 #	include <unistd.h>
871 #   endif
872 #   define GETPAGESIZE() getpagesize()
873 # endif
874 
875 # if defined(SUNOS5) || defined(DRSNX) || defined(UTS4)
876     /* OS has SVR4 generic features.  Probably others also qualify.	*/
877 #   define SVR4
878 # endif
879 
880 # if defined(SUNOS5) || defined(DRSNX)
881     /* OS has SUNOS5 style semi-undocumented interface to dynamic 	*/
882     /* loader.								*/
883 #   define SUNOS5DL
884     /* OS has SUNOS5 style signal handlers.				*/
885 #   define SUNOS5SIGS
886 # endif
887 
888 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
889    -> bad word size
890 # endif
891 
892 # ifdef PCR
893 #   undef DYNAMIC_LOADING
894 #   undef STACKBOTTOM
895 #   undef HEURISTIC1
896 #   undef HEURISTIC2
897 #   undef PROC_VDB
898 #   undef MPROTECT_VDB
899 #   define PCR_VDB
900 # endif
901 
902 # ifdef SRC_M3
903 /* Postponed for now. */
904 #   undef PROC_VDB
905 #   undef MPROTECT_VDB
906 # endif
907 
908 # ifdef SMALL_CONFIG
909 /* Presumably not worth the space it takes. */
910 #   undef PROC_VDB
911 #   undef MPROTECT_VDB
912 # endif
913 
914 # if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB)
915 #   define DEFAULT_VDB
916 # endif
917 
918 # if defined(IRIX_THREADS) && !defined(IRIX5)
919 --> inconsistent configuration
920 # endif
921 # if defined(SOLARIS_THREADS) && !defined(SUNOS5)
922 --> inconsistent configuration
923 # endif
924 # if defined(PCR) || defined(SRC_M3) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(IRIX_THREADS)
925 #   define THREADS
926 # endif
927 
928 # if defined(SPARC)
929 #   define SAVE_CALL_CHAIN
930 #   define ASM_CLEAR_CODE	/* Stack clearing is crucial, and we 	*/
931 				/* include assembly code to do it well.	*/
932 # endif
933 
934 # endif
935