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  * Copyright (c) 2000-2004 Hewlett-Packard Development Company, L.P.
6  *
7  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9  *
10  * Permission is hereby granted to use or copy this program
11  * for any purpose,  provided the above notices are retained on all copies.
12  * Permission to modify the code and to distribute modified code is granted,
13  * provided the above notices are retained, and a notice that the code was
14  * modified is included with the above copyright notice.
15  */
16 
17 /*
18  * This header is private to the gc.  It is almost always included from
19  * gc_priv.h.  However it is possible to include it by itself if just the
20  * configuration macros are needed.  In that
21  * case, a few declarations relying on types declared in gc_priv.h will be
22  * omitted.
23  */
24 
25 #ifndef GCCONFIG_H
26 
27 # define GCCONFIG_H
28 
29 # ifndef GC_PRIVATE_H
30     /* Fake ptr_t declaration, just to avoid compilation errors.	*/
31     /* This avoids many instances if "ifndef GC_PRIVATE_H" below.	*/
32     typedef struct GC_undefined_struct * ptr_t;
33 #   include <stddef.h>	/* For size_t etc. */
34 # endif
35 
36 /* Machine dependent parameters.  Some tuning parameters can be found	*/
37 /* near the top of gc_private.h.					*/
38 
39 /* Machine specific parts contributed by various people.  See README file. */
40 
41 /* First a unified test for Linux: */
42 # if defined(linux) || defined(__linux__)
43 #  ifndef LINUX
44 #    define LINUX
45 #  endif
46 # endif
47 
48 /* And one for NetBSD: */
49 # if defined(__NetBSD__)
50 #    define NETBSD
51 # endif
52 
53 /* And one for OpenBSD: */
54 # if defined(__OpenBSD__)
55 #    define OPENBSD
56 # endif
57 
58 /* And one for FreeBSD: */
59 # if (defined(__FreeBSD__) || defined(__DragonFly__) || \
60       defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
61 #    define FREEBSD
62 # endif
63 
64 /* Determine the machine type: */
65 # if defined(__arm__) || defined(__thumb__)
66 #    define ARM32
67 #    if !defined(LINUX) && !defined(NETBSD)
68 #      define NOSYS
69 #      define mach_type_known
70 #    endif
71 # endif
72 # if defined(sun) && defined(mc68000)
73 #    error SUNOS4 no longer supported
74 # endif
75 # if defined(hp9000s300)
76 #    error M68K based HP machines no longer supported.
77 # endif
78 # if defined(OPENBSD) && defined(m68k)
79 #    define M68K
80 #    define mach_type_known
81 # endif
82 # if defined(OPENBSD) && defined(__sparc__)
83 #    define SPARC
84 #    define mach_type_known
85 # endif
86 # if defined(NETBSD) && (defined(m68k) || defined(__m68k__))
87 #    define M68K
88 #    define mach_type_known
89 # endif
90 # if defined(NETBSD) && defined(__powerpc__)
91 #    define POWERPC
92 #    define mach_type_known
93 # endif
94 # if defined(NETBSD) && (defined(__arm32__) || defined(__arm__))
95 #    define ARM32
96 #    define mach_type_known
97 # endif
98 # if defined(NETBSD) && defined(__sh__)
99 #    define SH
100 #    define mach_type_known
101 # endif
102 # if defined(vax)
103 #    define VAX
104 #    ifdef ultrix
105 #	define ULTRIX
106 #    else
107 #	define BSD
108 #    endif
109 #    define mach_type_known
110 # endif
111 # if defined(__NetBSD__) && defined(__vax__)
112 #    define VAX
113 #    define mach_type_known
114 # endif
115 # if defined(mips) || defined(__mips) || defined(_mips)
116 #    define MIPS
117 #    if defined(nec_ews) || defined(_nec_ews)
118 #      define EWS4800
119 #    endif
120 #    if !defined(LINUX) && !defined(EWS4800) && !defined(NETBSD)
121 #      if defined(ultrix) || defined(__ultrix)
122 #	 define ULTRIX
123 #      else
124 #	 define IRIX5   /* or IRIX 6.X */
125 #      endif
126 #    endif /* !LINUX */
127 #    if defined(__NetBSD__) && defined(__MIPSEL__)
128 #      undef ULTRIX
129 #    endif
130 #    define mach_type_known
131 # endif
132 # if defined(DGUX) && (defined(i386) || defined(__i386__))
133 #    define I386
134 #    ifndef _USING_DGUX
135 #    define _USING_DGUX
136 #    endif
137 #    define mach_type_known
138 # endif
139 # if defined(sequent) && (defined(i386) || defined(__i386__))
140 #    define I386
141 #    define SEQUENT
142 #    define mach_type_known
143 # endif
144 # if defined(sun) && (defined(i386) || defined(__i386__))
145 #    define I386
146 #    define SOLARIS
147 #    define mach_type_known
148 # endif
149 # if defined(sun) && defined(__amd64)
150 #    define X86_64
151 #    define SOLARIS
152 #    define mach_type_known
153 # endif
154 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
155 #    define I386
156 #    define OS2
157 #    define mach_type_known
158 # endif
159 # if defined(ibm032)
160 #   error IBM PC/RT no longer supported.
161 # endif
162 # if defined(sun) && (defined(sparc) || defined(__sparc))
163 #   define SPARC
164     /* Test for SunOS 5.x */
165 #     include <errno.h>
166 #     define SOLARIS
167 #   define mach_type_known
168 # endif
169 # if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
170      && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) \
171      && !defined(__DragonFly__)
172 #   define SPARC
173 #   define DRSNX
174 #   define mach_type_known
175 # endif
176 # if defined(_IBMR2)
177 #   define POWERPC
178 #   define AIX
179 #   define mach_type_known
180 # endif
181 # if defined(__NetBSD__) && defined(__sparc__)
182 #   define SPARC
183 #   define mach_type_known
184 # endif
185 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
186 	/* The above test may need refinement	*/
187 #   define I386
188 #   if defined(_SCO_ELF)
189 #     define SCO_ELF
190 #   else
191 #     define SCO
192 #   endif
193 #   define mach_type_known
194 # endif
195 # if defined(_AUX_SOURCE)
196 #   error A/UX no longer supported
197 # endif
198 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
199      || defined(hppa) || defined(__hppa__)
200 #   define HP_PA
201 #   if !defined(LINUX) && !defined(HPUX)
202 #     define HPUX
203 #   endif
204 #   define mach_type_known
205 # endif
206 # if defined(__ia64) && defined(_HPUX_SOURCE)
207 #   define IA64
208 #   ifndef HPUX
209 #     define HPUX
210 #   endif
211 #   define mach_type_known
212 # endif
213 # if defined(__BEOS__) && defined(_X86_)
214 #    define I386
215 #    define BEOS
216 #    define mach_type_known
217 # endif
218 # if defined(__HAIKU__) && defined(_X86_)
219 #    define I386
220 #    define HAIKU
221 #    define mach_type_known
222 # if defined(LINUX) && (defined(i386) || defined(__i386__))
223 #    define I386
224 #    define mach_type_known
225 # endif
226 # if defined(LINUX) && defined(__x86_64__)
227 #    define X86_64
228 #    define mach_type_known
229 # endif
230 # if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
231 #    define IA64
232 #    define mach_type_known
233 # endif
234 # if defined(LINUX) && defined(__arm__)
235 #    define ARM32
236 #    define mach_type_known
237 # endif
238 # if defined(LINUX) && defined(__cris__)
239 #    ifndef CRIS
240 #	define CRIS
241 #    endif
242 #    define mach_type_known
243 # endif
244 # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || \
245 		        defined(powerpc64) || defined(__powerpc64__))
246 #    define POWERPC
247 #    define mach_type_known
248 # endif
249 # if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__))
250 #    define POWERPC
251 #    define mach_type_known
252 # endif
253 # if defined(LINUX) && defined(__mc68000__)
254 #    define M68K
255 #    define mach_type_known
256 # endif
257 # if defined(LINUX) && (defined(sparc) || defined(__sparc__))
258 #    define SPARC
259 #    define mach_type_known
260 # endif
261 # if defined(LINUX) && defined(__arm__)
262 #    define ARM32
263 #    define mach_type_known
264 # endif
265 # if defined(LINUX) && defined(__sh__)
266 #    define SH
267 #    define mach_type_known
268 # endif
269 # if defined(LINUX) && defined(__m32r__)
270 #    define M32R
271 #    define mach_type_known
272 # endif
273 # if defined(__alpha) || defined(__alpha__)
274 #   define ALPHA
275 #   if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) && !defined(FREEBSD)
276 #     define OSF1	/* a.k.a Digital Unix */
277 #   endif
278 #   define mach_type_known
279 # endif
280 # if defined(_AMIGA) && !defined(AMIGA)
281 #   define AMIGA
282 # endif
283 # ifdef AMIGA
284 #   define M68K
285 #   define mach_type_known
286 # endif
287 # if defined(THINK_C) || defined(__MWERKS__) && !defined(__powerc)
288 #   define M68K
289 #   define MACOS
290 #   define mach_type_known
291 # endif
292 # if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__)
293 #   define POWERPC
294 #   define MACOS
295 #   define mach_type_known
296 # endif
297 # if defined(macosx) || (defined(__APPLE__) && defined(__MACH__))
298 #   define DARWIN
299 #   if defined(__ppc__)  || defined(__ppc64__)
300 #    define POWERPC
301 #    define mach_type_known
302 #   elif defined(__x86_64__)
303 #    define X86_64
304 #    define mach_type_known
305 #   elif defined(__i386__)
306 #    define I386
307 #    define mach_type_known
308 #   endif
309 # endif
310 # if defined(NeXT) && defined(mc68000)
311 #   define M68K
312 #   define NEXT
313 #   define mach_type_known
314 # endif
315 # if defined(NeXT) && (defined(i386) || defined(__i386__))
316 #   define I386
317 #   define NEXT
318 #   define mach_type_known
319 # endif
320 # if defined(__OpenBSD__) && (defined(i386) || defined(__i386__))
321 #   define I386
322 #   define OPENBSD
323 #   define mach_type_known
324 # endif
325 # if defined(FREEBSD) && (defined(i386) || defined(__i386__))
326 #   define I386
327 #   define mach_type_known
328 # endif
329 # if defined(FREEBSD) && defined(__x86_64__)
330 #   define X86_64
331 #   define mach_type_known
332 # endif
333 # if defined(__NetBSD__) && (defined(i386) || defined(__i386__))
334 #   define I386
335 #   define mach_type_known
336 # endif
337 # if defined(__NetBSD__) && defined(__x86_64__)
338 #    define X86_64
339 #    define mach_type_known
340 # endif
341 # if defined(FREEBSD) && defined(__sparc__)
342 #    define SPARC
343 #    define mach_type_known
344 # endif
345 # if defined(bsdi) && (defined(i386) || defined(__i386__))
346 #    define I386
347 #    define BSDI
348 #    define mach_type_known
349 # endif
350 # if !defined(mach_type_known) && defined(__386BSD__)
351 #   define I386
352 #   define THREE86BSD
353 #   define mach_type_known
354 # endif
355 # if defined(_CX_UX) && defined(_M88K)
356 #   define M88K
357 #   define CX_UX
358 #   define mach_type_known
359 # endif
360 # if defined(DGUX) && defined(m88k)
361 #   define M88K
362     /* DGUX defined */
363 #   define mach_type_known
364 # endif
365 # if defined(_WIN32_WCE)
366     /* SH3, SH4, MIPS already defined for corresponding architectures */
367 #   if defined(SH3) || defined(SH4)
368 #     define SH
369 #   endif
370 #   if defined(x86)
371 #     define I386
372 #   endif
373 #   if defined(ARM)
374 #     define ARM32
375 #   endif
376 #   define MSWINCE
377 #   define mach_type_known
378 # else
379 #   if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
380         || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
381 #     if defined(__LP64__) || defined(_WIN64)
382 #	define X86_64
383 #     else
384 #       define I386
385 #     endif
386 #     define MSWIN32	/* or Win64 */
387 #     define mach_type_known
388 #   endif
389 #   if defined(_MSC_VER) && defined(_M_IA64)
390 #     define IA64
391 #     define MSWIN32	/* Really win64, but we don't treat 64-bit 	*/
392 			/* variants as a differnt platform.		*/
393 #   endif
394 # endif
395 # if defined(__DJGPP__)
396 #   define I386
397 #   ifndef DJGPP
398 #     define DJGPP  /* MSDOS running the DJGPP port of GCC */
399 #   endif
400 #   define mach_type_known
401 # endif
402 # if defined(__CYGWIN32__) || defined(__CYGWIN__)
403 #   define I386
404 #   define CYGWIN32
405 #   define mach_type_known
406 # endif
407 # if defined(__MINGW32__)
408 #   define I386
409 #   define MSWIN32
410 #   define mach_type_known
411 # endif
412 # if defined(__BORLANDC__)
413 #   define I386
414 #   define MSWIN32
415 #   define mach_type_known
416 # endif
417 # if defined(_UTS) && !defined(mach_type_known)
418 #   define S370
419 #   define UTS4
420 #   define mach_type_known
421 # endif
422 # if defined(__pj__)
423 #   error PicoJava no longer supported
424     /* The implementation had problems, and I haven't heard of users	*/
425     /* in ages.  If you want it resurrected, let me know.		*/
426 # endif
427 # if defined(__embedded__) && defined(PPC)
428 #   define POWERPC
429 #   define NOSYS
430 #   define mach_type_known
431 # endif
432 /* Ivan Demakov */
433 # if defined(__WATCOMC__) && defined(__386__)
434 #   define I386
435 #   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
436 #     if defined(__OS2__)
437 #       define OS2
438 #     else
439 #       if defined(__WINDOWS_386__) || defined(__NT__)
440 #         define MSWIN32
441 #       else
442 #         define DOS4GW
443 #       endif
444 #     endif
445 #   endif
446 #   define mach_type_known
447 # endif
448 # if defined(__s390__) && defined(LINUX)
449 #    define S390
450 #    define mach_type_known
451 # endif
452 # if defined(__GNU__)
453 #   if defined(__i386__)
454 /* The Debian Hurd running on generic PC */
455 #     define  HURD
456 #     define  I386
457 #     define  mach_type_known
458 #    endif
459 # endif
460 # if defined(__TANDEM)
461     /* Nonstop S-series */
462     /* FIXME: Should recognize Integrity series? */
463 #   define MIPS
464 #   define NONSTOP
465 #   define mach_type_known
466 # endif
467 
468 /* Feel free to add more clauses here */
469 
470 /* Or manually define the machine type here.  A machine type is 	*/
471 /* characterized by the architecture.  Some				*/
472 /* machine types are further subdivided by OS.				*/
473 /* Macros such as LINUX, FREEBSD, etc. distinguish them.		*/
474 /* SYSV on an M68K actually means A/UX.					*/
475 /* The distinction in these cases is usually the stack starting address */
476 # ifndef mach_type_known
477 #   error "The collector has not been ported to this machine/OS combination."
478 # endif
479 		    /* Mapping is: M68K       ==> Motorola 680X0	*/
480 		    /*		   (NEXT, and SYSV (A/UX),		*/
481 		    /*		   MACOS and AMIGA variants)		*/
482 		    /*             I386       ==> Intel 386	 	*/
483 		    /*		    (SEQUENT, OS2, SCO, LINUX, NETBSD,	*/
484 		    /*		     FREEBSD, THREE86BSD, MSWIN32,	*/
485 		    /* 		     BSDI,SOLARIS, NEXT, other variants)	*/
486                     /*             NS32K      ==> Encore Multimax 	*/
487                     /*             MIPS       ==> R2000 through R14K	*/
488                     /*			(many variants)			*/
489                     /*		   VAX	      ==> DEC VAX		*/
490                     /*			(BSD, ULTRIX variants)		*/
491                     /*		   HP_PA      ==> HP9000/700 & /800	*/
492                     /*				  HP/UX, LINUX		*/
493 		    /*		   SPARC      ==> SPARC	v7/v8/v9	*/
494 		    /*			(SOLARIS, LINUX, DRSNX variants)	*/
495 		    /* 		   ALPHA      ==> DEC Alpha 		*/
496 		    /*			(OSF1 and LINUX variants)	*/
497 		    /* 		   M88K       ==> Motorola 88XX0        */
498 		    /* 		        (CX_UX and DGUX)		*/
499 		    /* 		   S370	      ==> 370-like machine	*/
500 		    /* 			running Amdahl UTS4		*/
501                     /*             S390       ==> 390-like machine      */
502 		    /*                  running LINUX                   */
503 		    /* 		   ARM32      ==> Intel StrongARM	*/
504 		    /* 		   IA64	      ==> Intel IPF		*/
505 		    /*				  (e.g. Itanium)	*/
506 		    /*			(LINUX and HPUX)	        */
507 		    /*		   SH	      ==> Hitachi SuperH	*/
508 		    /* 			(LINUX & MSWINCE)		*/
509 		    /* 		   X86_64     ==> AMD x86-64		*/
510 		    /*		   POWERPC    ==> IBM/Apple PowerPC	*/
511 		    /*			(MACOS(<=9),DARWIN(incl.MACOSX),*/
512 		    /*			 LINUX, NETBSD, AIX, NOSYS	*/
513 		    /*			 variants)			*/
514 		    /*			Handles 32 and 64-bit variants.	*/
515 		    /*		   CRIS       ==> Axis Etrax		*/
516 		    /*		   M32R	      ==> Renesas M32R		*/
517 
518 
519 /*
520  * For each architecture and OS, the following need to be defined:
521  *
522  * CPP_WORDSZ is a simple integer constant representing the word size.
523  * in bits.  We assume byte addressibility, where a byte has 8 bits.
524  * We also assume CPP_WORDSZ is either 32 or 64.
525  * (We care about the length of pointers, not hardware
526  * bus widths.  Thus a 64 bit processor with a C compiler that uses
527  * 32 bit pointers should use CPP_WORDSZ of 32, not 64. Default is 32.)
528  *
529  * MACH_TYPE is a string representation of the machine type.
530  * OS_TYPE is analogous for the OS.
531  *
532  * ALIGNMENT is the largest N, such that
533  * all pointer are guaranteed to be aligned on N byte boundaries.
534  * defining it to be 1 will always work, but perform poorly.
535  *
536  * DATASTART is the beginning of the data segment.
537  * On some platforms SEARCH_FOR_DATA_START is defined.
538  * SEARCH_FOR_DATASTART will cause GC_data_start to
539  * be set to an address determined by accessing data backwards from _end
540  * until an unmapped page is found.  DATASTART will be defined to be
541  * GC_data_start.
542  * On UNIX-like systems, the collector will scan the area between DATASTART
543  * and DATAEND for root pointers.
544  *
545  * DATAEND, if not `end' where `end' is defined as ``extern int end[];''.
546  * RTH suggests gaining access to linker script synth'd values with
547  * this idiom instead of `&end' where `end' is defined as ``extern int end;'' .
548  * Otherwise, ``GCC will assume these are in .sdata/.sbss'' and it will, e.g.,
549  * cause failures on alpha*-*-* with ``-msmall-data or -fpic'' or mips-*-*
550  * without any special options.
551  *
552  * STACKBOTTOM is the cool end of the stack, which is usually the
553  * highest address in the stack.
554  * Under PCR or OS/2, we have other ways of finding thread stacks.
555  * For each machine, the following should:
556  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
557  * 2) define exactly one of
558  *	STACKBOTTOM (should be defined to be an expression)
559  *	LINUX_STACKBOTTOM
560  *	HEURISTIC1
561  *	HEURISTIC2
562  * If STACKBOTTOM is defined, then it's value will be used directly as the
563  * stack base.  If LINUX_STACKBOTTOM is defined, then it will be determined
564  * with a method appropriate for most Linux systems.  Currently we look
565  * first for __libc_stack_end, and if that fails read it from /proc.
566  * If either of the last two macros are defined, then STACKBOTTOM is computed
567  * during collector startup using one of the following two heuristics:
568  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
569  *		the next multiple of STACK_GRAN.
570  * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly
571  *		in small steps (decrement if STACK_GROWS_UP), and read the value
572  *		at each location.  Remember the value when the first
573  *		Segmentation violation or Bus error is signalled.  Round that
574  *		to the nearest plausible page boundary, and use that instead
575  *		of STACKBOTTOM.
576  *
577  * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines,
578  * the value of environ is a pointer that can serve as STACKBOTTOM.
579  * I expect that HEURISTIC2 can be replaced by this approach, which
580  * interferes far less with debugging.  However it has the disadvantage
581  * that it's confused by a putenv call before the collector is initialized.
582  * This could be dealt with by intercepting putenv ...
583  *
584  * If no expression for STACKBOTTOM can be found, and neither of the above
585  * heuristics are usable, the collector can still be used with all of the above
586  * undefined, provided one of the following is done:
587  * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
588  *    without reference to STACKBOTTOM.  This is appropriate for use in
589  *    conjunction with thread packages, since there will be multiple stacks.
590  *    (Allocating thread stacks in the heap, and treating them as ordinary
591  *    heap data objects is also possible as a last resort.  However, this is
592  *    likely to introduce significant amounts of excess storage retention
593  *    unless the dead parts of the thread stacks are periodically cleared.)
594  * 2) Client code may set GC_stackbottom before calling any GC_ routines.
595  *    If the author of the client code controls the main program, this is
596  *    easily accomplished by introducing a new main program, setting
597  *    GC_stackbottom to the address of a local variable, and then calling
598  *    the original main program.  The new main program would read something
599  *    like:
600  *
601  *		# include "gc_private.h"
602  *
603  *		main(argc, argv, envp)
604  *		int argc;
605  *		char **argv, **envp;
606  *		{
607  *		    int dummy;
608  *
609  *		    GC_stackbottom = (ptr_t)(&dummy);
610  *		    return(real_main(argc, argv, envp));
611  *		}
612  *
613  *
614  * Each architecture may also define the style of virtual dirty bit
615  * implementation to be used:
616  *   MPROTECT_VDB: Write protect the heap and catch faults.
617  *   GWW_VDB: Use win32 GetWriteWatch primitive.
618  *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
619  *
620  * The first and second one may be combined, in which case a runtime
621  * selection will be made, based on GetWriteWatch availability.
622  *
623  * An architecture may define DYNAMIC_LOADING if dynamic_load.c
624  * defined GC_register_dynamic_libraries() for the architecture.
625  *
626  * An architecture may define PREFETCH(x) to preload the cache with *x.
627  * This defaults to a no-op.
628  *
629  * PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
630  *
631  * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
632  * clear the two words at GC_malloc-aligned address x.  By default,
633  * word stores of 0 are used instead.
634  *
635  * HEAP_START may be defined as the initial address hint for mmap-based
636  * allocation.
637  */
638 
639 /* If we are using a recent version of gcc, we can use __builtin_unwind_init()
640  * to push the relevant registers onto the stack.
641  */
642 # if defined(__GNUC__) && ((__GNUC__ >= 3) || \
643 			   (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \
644 		       && !defined(__INTEL_COMPILER) && !defined(__PATHCC__)
645 #   define HAVE_BUILTIN_UNWIND_INIT
646 # endif
647 
648 # define STACK_GRAN 0x1000000
649 # ifdef M68K
650 #   define MACH_TYPE "M68K"
651 #   define ALIGNMENT 2
652 #   ifdef OPENBSD
653 #	define OS_TYPE "OPENBSD"
654 #	define HEURISTIC2
655 #	ifdef __ELF__
656 #	  define DATASTART GC_data_start
657 #	  define DYNAMIC_LOADING
658 #	else
659 	  extern char etext[];
660 #	  define DATASTART ((ptr_t)(etext))
661 #       endif
662 #   endif
663 #   ifdef NETBSD
664 #	define OS_TYPE "NETBSD"
665 #	define HEURISTIC2
666 #	ifdef __ELF__
667 #	  define DATASTART GC_data_start
668 #	  define DYNAMIC_LOADING
669 #	else
670 	  extern char etext[];
671 #	  define DATASTART ((ptr_t)(etext))
672 #       endif
673 #   endif
674 #   ifdef LINUX
675 #       define OS_TYPE "LINUX"
676 #       define LINUX_STACKBOTTOM
677 #       define MPROTECT_VDB
678 #       ifdef __ELF__
679 #            define DYNAMIC_LOADING
680 #	     include <features.h>
681 #	     if defined(__GLIBC__)&& __GLIBC__>=2
682 #              define SEARCH_FOR_DATA_START
683 #	     else /* !GLIBC2 */
684                extern char **__environ;
685 #              define DATASTART ((ptr_t)(&__environ))
686                              /* hideous kludge: __environ is the first */
687                              /* word in crt0.o, and delimits the start */
688                              /* of the data segment, no matter which   */
689                              /* ld options were passed through.        */
690                              /* We could use _etext instead, but that  */
691                              /* would include .rodata, which may       */
692                              /* contain large read-only data tables    */
693                              /* that we'd rather not scan.             */
694 #	     endif /* !GLIBC2 */
695              extern int _end[];
696 #            define DATAEND (_end)
697 #       else
698              extern int etext[];
699 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
700 #       endif
701 #   endif
702 #   ifdef AMIGA
703 #	define OS_TYPE "AMIGA"
704  	    	/* STACKBOTTOM and DATASTART handled specially	*/
705  	    	/* in os_dep.c					*/
706 # 	define DATAEND	/* not needed */
707 #	define GETPAGESIZE() 4096
708 #   endif
709 #   ifdef MACOS
710 #     ifndef __LOWMEM__
711 #     include <LowMem.h>
712 #     endif
713 #     define OS_TYPE "MACOS"
714 			/* see os_dep.c for details of global data segments. */
715 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
716 #     define DATAEND	/* not needed */
717 #     define GETPAGESIZE() 4096
718 #   endif
719 #   ifdef NEXT
720 #	define OS_TYPE "NEXT"
721 #	define DATASTART ((ptr_t) get_etext())
722 #	define STACKBOTTOM ((ptr_t) 0x4000000)
723 #	define DATAEND	/* not needed */
724 #   endif
725 # endif
726 
727 # if defined(POWERPC)
728 #   define MACH_TYPE "POWERPC"
729 #   ifdef MACOS
730 #     define ALIGNMENT 2  /* Still necessary?  Could it be 4?	*/
731 #     ifndef __LOWMEM__
732 #     include <LowMem.h>
733 #     endif
734 #     define OS_TYPE "MACOS"
735 			/* see os_dep.c for details of global data segments. */
736 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
737 #     define DATAEND  /* not needed */
738 #   endif
739 #   ifdef LINUX
740 #     if defined(__powerpc64__)
741 #       define ALIGNMENT 8
742 #       define CPP_WORDSZ 64
743 #       ifndef HBLKSIZE
744 #         define HBLKSIZE 4096
745 #       endif
746 #     else
747 #       define ALIGNMENT 4
748 #     endif
749 #     define OS_TYPE "LINUX"
750       /* HEURISTIC1 has been reliably reported to fail for a 32-bit	*/
751       /* executable on a 64 bit kernel.					*/
752 #     define LINUX_STACKBOTTOM
753 #     define DYNAMIC_LOADING
754 #     define SEARCH_FOR_DATA_START
755       extern int _end[];
756 #     define DATAEND (_end)
757 #   endif
758 #   ifdef DARWIN
759 #     define OS_TYPE "DARWIN"
760 #     define DYNAMIC_LOADING
761 #     if defined(__ppc64__)
762 #       define ALIGNMENT 8
763 #       define CPP_WORDSZ 64
764 #       define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
765 #       define CACHE_LINE_SIZE 64
766 #       ifndef HBLKSIZE
767 #         define HBLKSIZE 4096
768 #       endif
769 #     else
770 #       define ALIGNMENT 4
771 #       define STACKBOTTOM ((ptr_t) 0xc0000000)
772 #     endif
773       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
774 	 These aren't used when dyld support is enabled (it is by default) */
775 #     define DATASTART ((ptr_t) get_etext())
776 #     define DATAEND	((ptr_t) get_end())
777 #     define USE_MMAP
778 #     define USE_MMAP_ANON
779 #     ifdef GC_DARWIN_THREADS
780 #       define MPROTECT_VDB
781 #     endif
782 #     include <unistd.h>
783 #     define GETPAGESIZE() getpagesize()
784 #     if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
785 	/* The performance impact of prefetches is untested */
786 #	define PREFETCH(x) \
787 	  __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
788 #	define PREFETCH_FOR_WRITE(x) \
789 	  __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
790 #     endif
791       /* There seems to be some issues with trylock hanging on darwin. This
792 	 should be looked into some more */
793 #     define NO_PTHREAD_TRYLOCK
794 #   endif
795 #   ifdef FREEBSD
796 #       define ALIGNMENT 4
797 #       define OS_TYPE "FREEBSD"
798 #       ifndef GC_FREEBSD_THREADS
799 #           define MPROTECT_VDB
800 #       endif
801 #       define SIG_SUSPEND SIGUSR1
802 #       define SIG_THR_RESTART SIGUSR2
803 #       define FREEBSD_STACKBOTTOM
804 #       ifdef __ELF__
805 #           define DYNAMIC_LOADING
806 #       endif
807         extern char etext[];
808         extern char * GC_FreeBSDGetDataStart();
809 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
810 #   endif
811 #   ifdef NETBSD
812 #     define ALIGNMENT 4
813 #     define OS_TYPE "NETBSD"
814 #     define HEURISTIC2
815       extern char etext[];
816 #     define DATASTART GC_data_start
817 #     define DYNAMIC_LOADING
818 #   endif
819 #   ifdef AIX
820 #     define OS_TYPE "AIX"
821 #     undef ALIGNMENT /* in case it's defined	*/
822 #     ifdef IA64
823 #       undef IA64
824           /* DOB: some AIX installs stupidly define IA64 in */
825           /* /usr/include/sys/systemcfg.h   		    */
826 #     endif
827 #     ifdef __64BIT__
828 #       define ALIGNMENT 8
829 #       define CPP_WORDSZ 64
830 #       define STACKBOTTOM ((ptr_t)0x1000000000000000)
831 #     else
832 #       define ALIGNMENT 4
833 #       define CPP_WORDSZ 32
834 #       define STACKBOTTOM ((ptr_t)((ulong)&errno))
835 #     endif
836 #     define USE_MMAP
837 #     define USE_MMAP_ANON
838 	/* From AIX linker man page:
839 	_text Specifies the first location of the program.
840 	_etext Specifies the first location after the program.
841 	_data Specifies the first location of the data.
842 	_edata Specifies the first location after the initialized data
843 	_end or end Specifies the first location after all data.
844 	*/
845       extern int _data[], _end[];
846 #     define DATASTART ((ptr_t)((ulong)_data))
847 #     define DATAEND ((ptr_t)((ulong)_end))
848       extern int errno;
849 #     define DYNAMIC_LOADING
850 	/* For really old versions of AIX, this may have to be removed. */
851 #   endif
852 
853 #   ifdef NOSYS
854 #     define ALIGNMENT 4
855 #     define OS_TYPE "NOSYS"
856       extern void __end[], __dso_handle[];
857 #     define DATASTART (__dso_handle)  /* OK, that's ugly.  */
858 #     define DATAEND (__end)
859 	/* Stack starts at 0xE0000000 for the simulator.  */
860 #     undef STACK_GRAN
861 #     define STACK_GRAN 0x10000000
862 #     define HEURISTIC1
863 #   endif
864 # endif
865 
866 # ifdef VAX
867 #   define MACH_TYPE "VAX"
868 #   define ALIGNMENT 4	/* Pointers are longword aligned by 4.2 C compiler */
869     extern char etext[];
870 #   define DATASTART ((ptr_t)(etext))
871 #   ifdef BSD
872 #	define OS_TYPE "BSD"
873 #	define HEURISTIC1
874 			/* HEURISTIC2 may be OK, but it's hard to test. */
875 #   endif
876 #   ifdef ULTRIX
877 #	define OS_TYPE "ULTRIX"
878 #	define STACKBOTTOM ((ptr_t) 0x7fffc800)
879 #   endif
880 # endif
881 
882 # ifdef SPARC
883 #   define MACH_TYPE "SPARC"
884 #   if defined(__arch64__) || defined(__sparcv9)
885 #     define ALIGNMENT 8
886 #     define CPP_WORDSZ 64
887 #     define ELF_CLASS ELFCLASS64
888 #   else
889 #     define ALIGNMENT 4	/* Required by hardware	*/
890 #     define CPP_WORDSZ 32
891 #   endif
892     /* Don't define USE_ASM_PUSH_REGS.  We do use an asm helper, but	*/
893     /* not to push the registers on the mark stack.			*/
894 #   ifdef SOLARIS
895 #	define OS_TYPE "SOLARIS"
896 	extern int _etext[];
897 	extern int _end[];
898 	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
899 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
900 #	define DATAEND (_end)
901 #	if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
902 #	    define USE_MMAP
903 	    /* Otherwise we now use calloc.  Mmap may result in the	*/
904 	    /* heap interleaved with thread stacks, which can result in	*/
905 	    /* excessive blacklisting.  Sbrk is unusable since it	*/
906 	    /* doesn't interact correctly with the system malloc.	*/
907 #	endif
908 #       ifdef USE_MMAP
909 #         define HEAP_START (ptr_t)0x40000000
910 #       else
911 #	  define HEAP_START DATAEND
912 #       endif
913 #	define PROC_VDB
914 /*	HEURISTIC1 reportedly no longer works under 2.7.  		*/
915 /*  	HEURISTIC2 probably works, but this appears to be preferable.	*/
916 /*	Apparently USRSTACK is defined to be USERLIMIT, but in some	*/
917 /* 	installations that's undefined.  We work around this with a	*/
918 /*	gross hack:							*/
919 #       include <sys/vmparam.h>
920 #	ifdef USERLIMIT
921 	  /* This should work everywhere, but doesn't.	*/
922 #	  define STACKBOTTOM USRSTACK
923 #       else
924 #	  define HEURISTIC2
925 #       endif
926 #	include <unistd.h>
927 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
928 		/* getpagesize() appeared to be missing from at least one */
929 		/* Solaris 5.4 installation.  Weird.			  */
930 #	define DYNAMIC_LOADING
931 #   endif
932 #   ifdef DRSNX
933 #	define OS_TYPE "DRSNX"
934 	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
935 	extern int etext[];
936 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
937 #	define MPROTECT_VDB
938 #       define STACKBOTTOM ((ptr_t) 0xdfff0000)
939 #	define DYNAMIC_LOADING
940 #   endif
941 #   ifdef LINUX
942 #     define OS_TYPE "LINUX"
943 #     ifdef __ELF__
944 #       define DYNAMIC_LOADING
945 #     else
946           Linux Sparc/a.out not supported
947 #     endif
948       extern int _end[];
949       extern int _etext[];
950 #     define DATAEND (_end)
951 #     define SVR4
952       extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
953 #     ifdef __arch64__
954 #	define DATASTART GC_SysVGetDataStart(0x100000, (ptr_t)_etext)
955 #     else
956 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
957 #     endif
958 #     define LINUX_STACKBOTTOM
959 #   endif
960 #   ifdef OPENBSD
961 #     define OS_TYPE "OPENBSD"
962 #     define STACKBOTTOM ((ptr_t) 0xf8000000)
963       extern int etext[];
964 #     define DATASTART ((ptr_t)(etext))
965 #   endif
966 #   ifdef NETBSD
967 #     define OS_TYPE "NETBSD"
968 #     define HEURISTIC2
969 #     ifdef __ELF__
970 #	define DATASTART GC_data_start
971 #	define DYNAMIC_LOADING
972 #     else
973 	extern char etext[];
974 #	define DATASTART ((ptr_t)(etext))
975 #     endif
976 #   endif
977 #   ifdef FREEBSD
978 #	define OS_TYPE "FREEBSD"
979 #	define SIG_SUSPEND SIGUSR1
980 #	define SIG_THR_RESTART SIGUSR2
981 #	define FREEBSD_STACKBOTTOM
982 #	ifdef __ELF__
983 #	    define DYNAMIC_LOADING
984 #	endif
985 	extern char etext[];
986 	extern char edata[];
987 	extern char end[];
988 #	define NEED_FIND_LIMIT
989 #	define DATASTART ((ptr_t)(&etext))
990 #	define DATAEND (GC_find_limit (DATASTART, TRUE))
991 #	define DATASTART2 ((ptr_t)(&edata))
992 #	define DATAEND2 ((ptr_t)(&end))
993 #   endif
994 # endif
995 
996 # ifdef I386
997 #   define MACH_TYPE "I386"
998 #   if defined(__LP64__) || defined(_WIN64)
999 #     error This should be handled as X86_64
1000 #   else
1001 #     define CPP_WORDSZ 32
1002 #     define ALIGNMENT 4
1003 			/* Appears to hold for all "32 bit" compilers	*/
1004 			/* except Borland.  The -a4 option fixes 	*/
1005 			/* Borland.					*/
1006                         /* Ivan Demakov: For Watcom the option is -zp4. */
1007 #   endif
1008 #   ifdef SEQUENT
1009 #	define OS_TYPE "SEQUENT"
1010 	extern int etext[];
1011 #       define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1012 #       define STACKBOTTOM ((ptr_t) 0x3ffff000)
1013 #   endif
1014 #   ifdef BEOS
1015 #     define OS_TYPE "BEOS"
1016 #     include <OS.h>
1017 #     define GETPAGESIZE() B_PAGE_SIZE
1018       extern int etext[];
1019 #     define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1020 #   endif
1021 #   ifdef HAIKU
1022 #     define OS_TYPE "HAIKU"
1023 #     include <OS.h>
1024 #     define GETPAGESIZE() B_PAGE_SIZE
1025 #     extern int etext[];
1026 #     define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1027 #   endif
1028 #   ifdef SOLARIS
1029 #	define OS_TYPE "SOLARIS"
1030         extern int _etext[], _end[];
1031   	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1032 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
1033 #	define DATAEND (_end)
1034 /*	# define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,  	*/
1035 /*      but reportedly breaks under 2.8.  It appears that the stack	*/
1036 /* 	base is a property of the executable, so this should not break	*/
1037 /* 	old executables.						*/
1038 /*  	HEURISTIC2 probably works, but this appears to be preferable.	*/
1039 #       include <sys/vm.h>
1040 #	define STACKBOTTOM USRSTACK
1041 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1042 /* It appears to be fixed in 2.8 and 2.9.				*/
1043 #	ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1044 #	  define PROC_VDB
1045 #	endif
1046 #	define DYNAMIC_LOADING
1047 #	if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1048 #	    define USE_MMAP
1049 	    /* Otherwise we now use calloc.  Mmap may result in the	*/
1050 	    /* heap interleaved with thread stacks, which can result in	*/
1051 	    /* excessive blacklisting.  Sbrk is unusable since it	*/
1052 	    /* doesn't interact correctly with the system malloc.	*/
1053 #	endif
1054 #       ifdef USE_MMAP
1055 #         define HEAP_START (ptr_t)0x40000000
1056 #       else
1057 #	  define HEAP_START DATAEND
1058 #       endif
1059 #   endif
1060 #   ifdef SCO
1061 #	define OS_TYPE "SCO"
1062 	extern int etext[];
1063 #   	define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \
1064 				  & ~0x3fffff) \
1065 				 +((word)etext & 0xfff))
1066 #	define STACKBOTTOM ((ptr_t) 0x7ffffffc)
1067 #   endif
1068 #   ifdef SCO_ELF
1069 #       define OS_TYPE "SCO_ELF"
1070         extern int etext[];
1071 #       define DATASTART ((ptr_t)(etext))
1072 #       define STACKBOTTOM ((ptr_t) 0x08048000)
1073 #       define DYNAMIC_LOADING
1074 #	define ELF_CLASS ELFCLASS32
1075 #   endif
1076 #   ifdef DGUX
1077 #	define OS_TYPE "DGUX"
1078 	extern int _etext, _end;
1079 	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1080 #	define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)(&_etext))
1081 #	define DATAEND (&_end)
1082 #	define STACK_GROWS_DOWN
1083 #	define HEURISTIC2
1084 #	include <unistd.h>
1085 #	define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
1086 #	define DYNAMIC_LOADING
1087 #	ifndef USE_MMAP
1088 #	  define USE_MMAP
1089 #	endif /* USE_MMAP */
1090 #	define MAP_FAILED (void *) -1
1091 #	ifdef USE_MMAP
1092 #	  define HEAP_START (ptr_t)0x40000000
1093 #	else /* USE_MMAP */
1094 #	  define HEAP_START DATAEND
1095 #	endif /* USE_MMAP */
1096 #   endif /* DGUX */
1097 
1098 #   ifdef LINUX
1099 #	define OS_TYPE "LINUX"
1100 #       define LINUX_STACKBOTTOM
1101 #	if 0
1102 #	  define HEURISTIC1
1103 #         undef STACK_GRAN
1104 #         define STACK_GRAN 0x10000000
1105 	  /* STACKBOTTOM is usually 0xc0000000, but this changes with	*/
1106 	  /* different kernel configurations.  In particular, systems	*/
1107 	  /* with 2GB physical memory will usually move the user	*/
1108 	  /* address space limit, and hence initial SP to 0x80000000.	*/
1109 #       endif
1110 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
1111 #	    define MPROTECT_VDB
1112 #	else
1113 	    /* We seem to get random errors in incremental mode,	*/
1114 	    /* possibly because Linux threads is itself a malloc client */
1115 	    /* and can't deal with the signals.				*/
1116 #	endif
1117 #	define HEAP_START (ptr_t)0x1000
1118 		/* This encourages mmap to give us low addresses,	*/
1119 		/* thus allowing the heap to grow to ~3GB		*/
1120 #       ifdef __ELF__
1121 #            define DYNAMIC_LOADING
1122 #	     ifdef UNDEFINED	/* includes ro data */
1123 	       extern int _etext[];
1124 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
1125 #	     endif
1126 #	     include <features.h>
1127 #	     if defined(__GLIBC__) && __GLIBC__ >= 2
1128 #		 define SEARCH_FOR_DATA_START
1129 #	     else
1130      	         extern char **__environ;
1131 #                define DATASTART ((ptr_t)(&__environ))
1132 			      /* hideous kludge: __environ is the first */
1133 			      /* word in crt0.o, and delimits the start */
1134 			      /* of the data segment, no matter which   */
1135 			      /* ld options were passed through.        */
1136 			      /* We could use _etext instead, but that  */
1137 			      /* would include .rodata, which may       */
1138 			      /* contain large read-only data tables    */
1139 			      /* that we'd rather not scan.		*/
1140 #	     endif
1141 	     extern int _end[];
1142 #	     define DATAEND (_end)
1143 #	else
1144 	     extern int etext[];
1145 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1146 #       endif
1147 #	ifdef USE_I686_PREFETCH
1148 	  /* FIXME: Thus should use __builtin_prefetch, but we'll leave that	*/
1149 	  /* for the next rtelease.						*/
1150 #	  define PREFETCH(x) \
1151 	    __asm__ __volatile__ ("	prefetchnta	%0": : "m"(*(char *)(x)))
1152 	    /* Empirically prefetcht0 is much more effective at reducing	*/
1153 	    /* cache miss stalls for the targetted load instructions.  But it	*/
1154 	    /* seems to interfere enough with other cache traffic that the net	*/
1155 	    /* result is worse than prefetchnta.				*/
1156 #         if 0
1157 	    /* Using prefetches for write seems to have a slight negative	*/
1158 	    /* impact on performance, at least for a PIII/500.			*/
1159 #	    define PREFETCH_FOR_WRITE(x) \
1160 	      __asm__ __volatile__ ("	prefetcht0	%0": : "m"(*(char *)(x)))
1161 #	  endif
1162 #	endif
1163 #	ifdef USE_3DNOW_PREFETCH
1164 #	  define PREFETCH(x) \
1165 	    __asm__ __volatile__ ("	prefetch	%0": : "m"(*(char *)(x)))
1166 #	  define PREFETCH_FOR_WRITE(x) \
1167 	    __asm__ __volatile__ ("	prefetchw	%0": : "m"(*(char *)(x)))
1168 #	endif
1169 #   endif
1170 #   ifdef CYGWIN32
1171 #       define OS_TYPE "CYGWIN32"
1172 #       define DATASTART ((ptr_t)GC_DATASTART)  /* From gc.h */
1173 #       define DATAEND	 ((ptr_t)GC_DATAEND)
1174 #	undef STACK_GRAN
1175 #       define STACK_GRAN 0x10000
1176 #       define HEURISTIC1
1177 #   endif
1178 #   ifdef OS2
1179 #	define OS_TYPE "OS2"
1180  	    	/* STACKBOTTOM and DATASTART are handled specially in 	*/
1181 		/* os_dep.c. OS2 actually has the right			*/
1182 		/* system call!						*/
1183 #	define DATAEND	/* not needed */
1184 #   endif
1185 #   ifdef MSWIN32
1186 #	define OS_TYPE "MSWIN32"
1187 		/* STACKBOTTOM and DATASTART are handled specially in 	*/
1188 		/* os_dep.c.						*/
1189 #       if !defined(__WATCOMC__)
1190 #	  define MPROTECT_VDB
1191 	  /* We also avoided doing this in the past with GC_WIN32_THREADS */
1192 	  /* Hopefully that's fixed.					  */
1193 #	endif
1194 #	if _MSC_VER >= 1300  /* .NET, i.e. > VisualStudio 6	*/
1195 #         define GWW_VDB
1196 #	endif
1197 #       define DATAEND  /* not needed */
1198 #   endif
1199 #   ifdef MSWINCE
1200 #	define OS_TYPE "MSWINCE"
1201 #       define DATAEND  /* not needed */
1202 #   endif
1203 #   ifdef DJGPP
1204 #       define OS_TYPE "DJGPP"
1205 #       include "stubinfo.h"
1206         extern int etext[];
1207         extern int _stklen;
1208         extern int __djgpp_stack_limit;
1209 #       define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff))
1210 /* #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
1211                                                      + _stklen)) */
1212 #       define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen))
1213 		/* This may not be right.  */
1214 #   endif
1215 #   ifdef OPENBSD
1216 #	define OS_TYPE "OPENBSD"
1217 #   endif
1218 #   ifdef FREEBSD
1219 #	define OS_TYPE "FREEBSD"
1220 #	ifndef GC_FREEBSD_THREADS
1221 #	    define MPROTECT_VDB
1222 #	endif
1223 #	ifdef __GLIBC__
1224 #	    define SIG_SUSPEND		(32+6)
1225 #	    define SIG_THR_RESTART	(32+5)
1226 	    extern int _end[];
1227 #	    define DATAEND (_end)
1228 #	else
1229 #	    define SIG_SUSPEND SIGUSR1
1230 #	    define SIG_THR_RESTART SIGUSR2
1231 #	endif
1232 #	define FREEBSD_STACKBOTTOM
1233 #	ifdef __ELF__
1234 #	    define DYNAMIC_LOADING
1235 #	endif
1236 	extern char etext[];
1237 	extern char * GC_FreeBSDGetDataStart(size_t, ptr_t);
1238 #	define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1239 #   endif
1240 #   ifdef NETBSD
1241 #	define OS_TYPE "NETBSD"
1242 #	ifdef __ELF__
1243 #	    define DYNAMIC_LOADING
1244 #	endif
1245 #   endif
1246 #   ifdef THREE86BSD
1247 #	define OS_TYPE "THREE86BSD"
1248 #   endif
1249 #   ifdef BSDI
1250 #	define OS_TYPE "BSDI"
1251 #   endif
1252 #   if defined(OPENBSD) || defined(NETBSD) \
1253         || defined(THREE86BSD) || defined(BSDI)
1254 #	define HEURISTIC2
1255 	extern char etext[];
1256 #	define DATASTART ((ptr_t)(etext))
1257 #   endif
1258 #   ifdef NEXT
1259 #	define OS_TYPE "NEXT"
1260 #	define DATASTART ((ptr_t) get_etext())
1261 #	define STACKBOTTOM ((ptr_t)0xc0000000)
1262 #	define DATAEND	/* not needed */
1263 #   endif
1264 #   ifdef DOS4GW
1265 #     define OS_TYPE "DOS4GW"
1266       extern long __nullarea;
1267       extern char _end;
1268       extern char *_STACKTOP;
1269       /* Depending on calling conventions Watcom C either precedes
1270          or does not precedes with undescore names of C-variables.
1271          Make sure startup code variables always have the same names.  */
1272       #pragma aux __nullarea "*";
1273       #pragma aux _end "*";
1274 #     define STACKBOTTOM ((ptr_t) _STACKTOP)
1275                          /* confused? me too. */
1276 #     define DATASTART ((ptr_t) &__nullarea)
1277 #     define DATAEND ((ptr_t) &_end)
1278 #   endif
1279 #   ifdef HURD
1280 #     define OS_TYPE "HURD"
1281 #     define STACK_GROWS_DOWN
1282 #     define HEURISTIC2
1283 #     define SIG_SUSPEND SIGUSR1
1284 #     define SIG_THR_RESTART SIGUSR2
1285 #     define SEARCH_FOR_DATA_START
1286       extern int _end[];
1287 #     define DATAEND ((ptr_t) (_end))
1288 /* #     define MPROTECT_VDB  Not quite working yet? */
1289 #     define DYNAMIC_LOADING
1290 #   endif
1291 #   ifdef DARWIN
1292 #     define OS_TYPE "DARWIN"
1293 #     define DARWIN_DONT_PARSE_STACK
1294 #     define DYNAMIC_LOADING
1295       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
1296 	 These aren't used when dyld support is enabled (it is by default) */
1297 #     define DATASTART ((ptr_t) get_etext())
1298 #     define DATAEND	((ptr_t) get_end())
1299 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
1300 #     define USE_MMAP
1301 #     define USE_MMAP_ANON
1302 #     ifdef GC_DARWIN_THREADS
1303 #       define MPROTECT_VDB
1304 #     endif
1305 #     include <unistd.h>
1306 #     define GETPAGESIZE() getpagesize()
1307       /* There seems to be some issues with trylock hanging on darwin. This
1308 	 should be looked into some more */
1309 #      define NO_PTHREAD_TRYLOCK
1310 #   endif /* DARWIN */
1311 # endif
1312 
1313 # ifdef NS32K
1314 #   define MACH_TYPE "NS32K"
1315 #   define ALIGNMENT 4
1316     extern char **environ;
1317 #   define DATASTART ((ptr_t)(&environ))
1318 			      /* hideous kludge: environ is the first   */
1319 			      /* word in crt0.o, and delimits the start */
1320 			      /* of the data segment, no matter which   */
1321 			      /* ld options were passed through.        */
1322 #   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */
1323 # endif
1324 
1325 # ifdef MIPS
1326 #   define MACH_TYPE "MIPS"
1327 #   ifdef LINUX
1328       /* This was developed for a linuxce style platform.  Probably	*/
1329       /* needs to be tweaked for workstation class machines.		*/
1330 #     define OS_TYPE "LINUX"
1331 #     define DYNAMIC_LOADING
1332       extern int _end[];
1333 #     define DATAEND (_end)
1334       extern int __data_start[];
1335 #     define DATASTART ((ptr_t)(__data_start))
1336 #     define ALIGNMENT 4
1337 #     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
1338 #        define LINUX_STACKBOTTOM
1339 #     else
1340 #        define STACKBOTTOM 0x80000000
1341 #     endif
1342 #   endif /* Linux */
1343 #   ifdef EWS4800
1344 #      define HEURISTIC2
1345 #      if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1346          extern int _fdata[], _end[];
1347 #        define DATASTART ((ptr_t)_fdata)
1348 #        define DATAEND ((ptr_t)_end)
1349 #        define CPP_WORDSZ _MIPS_SZPTR
1350 #        define ALIGNMENT (_MIPS_SZPTR/8)
1351 #      else
1352          extern int etext[], edata[], end[];
1353          extern int _DYNAMIC_LINKING[], _gp[];
1354 #        define DATASTART ((ptr_t)((((word)etext + 0x3ffff) & ~0x3ffff) \
1355                + ((word)etext & 0xffff)))
1356 #        define DATAEND (edata)
1357 #        define DATASTART2 (_DYNAMIC_LINKING \
1358                ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1359                : (ptr_t)edata)
1360 #        define DATAEND2 (end)
1361 #        define ALIGNMENT 4
1362 #      endif
1363 #      define OS_TYPE "EWS4800"
1364 #   endif
1365 #   ifdef ULTRIX
1366 #	define HEURISTIC2
1367 #       define DATASTART (ptr_t)0x10000000
1368 			      /* Could probably be slightly higher since */
1369 			      /* startup code allocates lots of stuff.   */
1370 #	define OS_TYPE "ULTRIX"
1371 #       define ALIGNMENT 4
1372 #   endif
1373 #   ifdef IRIX5
1374 #	define HEURISTIC2
1375         extern int _fdata[];
1376 #       define DATASTART ((ptr_t)(_fdata))
1377 #       ifdef USE_MMAP
1378 #         define HEAP_START (ptr_t)0x30000000
1379 #       else
1380 #	  define HEAP_START DATASTART
1381 #       endif
1382 			      /* Lowest plausible heap address.		*/
1383 			      /* In the MMAP case, we map there.	*/
1384 			      /* In either case it is used to identify	*/
1385 			      /* heap sections so they're not 		*/
1386 			      /* considered as roots.			*/
1387 #	define OS_TYPE "IRIX5"
1388 /*#       define MPROTECT_VDB DOB: this should work, but there is evidence */
1389 /* 	  	of recent breakage.					   */
1390 #       ifdef _MIPS_SZPTR
1391 #	  define CPP_WORDSZ _MIPS_SZPTR
1392 #	  define ALIGNMENT (_MIPS_SZPTR/8)
1393 #	else
1394 #         define ALIGNMENT 4
1395 #	endif
1396 #	define DYNAMIC_LOADING
1397 #   endif
1398 #   ifdef MSWINCE
1399 #       define OS_TYPE "MSWINCE"
1400 #       define ALIGNMENT 4
1401 #       define DATAEND /* not needed */
1402 #   endif
1403 #   if defined(NETBSD)
1404 #     define OS_TYPE "NETBSD"
1405 #     define ALIGNMENT 4
1406 #     define HEURISTIC2
1407 #     ifdef __ELF__
1408         extern int etext[];
1409 #       define DATASTART GC_data_start
1410 #       define NEED_FIND_LIMIT
1411 #       define DYNAMIC_LOADING
1412 #     else
1413 #       define DATASTART ((ptr_t) 0x10000000)
1414 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
1415 #     endif /* _ELF_ */
1416 #  endif
1417 #  if defined(NONSTOP)
1418 #    define CPP_WORDSZ 32
1419 #    define OS_TYPE "NONSTOP"
1420 #    define ALIGNMENT 4
1421 #    define DATASTART ((ptr_t) 0x08000000)
1422      extern char **environ;
1423 #    define DATAEND ((ptr_t)(environ - 0x10))
1424 #    define STACKBOTTOM ((ptr_t) 0x4fffffff)
1425 #   endif
1426 # endif
1427 
1428 # ifdef HP_PA
1429 #   define MACH_TYPE "HP_PA"
1430 #   ifdef __LP64__
1431 #     define CPP_WORDSZ 64
1432 #     define ALIGNMENT 8
1433 #   else
1434 #     define CPP_WORDSZ 32
1435 #     define ALIGNMENT 4
1436 #   endif
1437 #   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS)
1438 #     ifndef LINUX /* For now. */
1439 #       define MPROTECT_VDB
1440 #     endif
1441 #   else
1442 #     ifdef PARALLEL_MARK
1443 #	define USE_MARK_BYTES
1444 		/* Minimize compare-and-swap usage.		*/
1445 #     endif
1446 #   endif
1447 #   define STACK_GROWS_UP
1448 #   ifdef HPUX
1449 #     define OS_TYPE "HPUX"
1450       extern int __data_start[];
1451 #     define DATASTART ((ptr_t)(__data_start))
1452 #     if 0
1453 	/* The following appears to work for 7xx systems running HP/UX	*/
1454 	/* 9.xx Furthermore, it might result in much faster		*/
1455 	/* collections than HEURISTIC2, which may involve scanning	*/
1456 	/* segments that directly precede the stack.  It is not the	*/
1457 	/* default, since it may not work on older machine/OS		*/
1458 	/* combinations. (Thanks to Raymond X.T. Nijssen for uncovering	*/
1459 	/* this.)							*/
1460 #       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */
1461 #     else
1462 	/* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2	*/
1463 	/* to this.  Note that the GC must be initialized before the	*/
1464     	/* first putenv call.						*/
1465 	extern char ** environ;
1466 #       define STACKBOTTOM ((ptr_t)environ)
1467 #     endif
1468 #     define DYNAMIC_LOADING
1469 #     include <unistd.h>
1470 #     define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1471 #     ifndef __GNUC__
1472 #       define PREFETCH(x)  { \
1473                               register long addr = (long)(x); \
1474                               (void) _asm ("LDW", 0, 0, addr, 0); \
1475                             }
1476 #     endif
1477 #   endif /* HPUX */
1478 #   ifdef LINUX
1479 #     define OS_TYPE "LINUX"
1480 #     define LINUX_STACKBOTTOM
1481 #     define DYNAMIC_LOADING
1482 #     define SEARCH_FOR_DATA_START
1483       extern int _end[];
1484 #     define DATAEND (&_end)
1485 #   endif /* LINUX */
1486 # endif /* HP_PA */
1487 
1488 # ifdef ALPHA
1489 #   define MACH_TYPE "ALPHA"
1490 #   define ALIGNMENT 8
1491 #   define CPP_WORDSZ 64
1492 #   ifdef NETBSD
1493 #	define OS_TYPE "NETBSD"
1494 #	define HEURISTIC2
1495 #	define DATASTART GC_data_start
1496 #	define ELFCLASS32 32
1497 #	define ELFCLASS64 64
1498 #	define ELF_CLASS ELFCLASS64
1499 #       define DYNAMIC_LOADING
1500 #   endif
1501 #   ifdef OPENBSD
1502 #	define OS_TYPE "OPENBSD"
1503 #	define HEURISTIC2
1504 #   	ifdef __ELF__	/* since OpenBSD/Alpha 2.9 */
1505 #	   define DATASTART GC_data_start
1506 #   	   define ELFCLASS32 32
1507 #   	   define ELFCLASS64 64
1508 #   	   define ELF_CLASS ELFCLASS64
1509 #       else		/* ECOFF, until OpenBSD/Alpha 2.7 */
1510 #   	   define DATASTART ((ptr_t) 0x140000000)
1511 #   	endif
1512 #   endif
1513 #   ifdef FREEBSD
1514 #	define OS_TYPE "FREEBSD"
1515 /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */
1516 #	define SIG_SUSPEND SIGUSR1
1517 #	define SIG_THR_RESTART SIGUSR2
1518 #	define FREEBSD_STACKBOTTOM
1519 #	ifdef __ELF__
1520 #	    define DYNAMIC_LOADING
1521 #	endif
1522 /* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */
1523 	extern char etext[];
1524 	extern char edata[];
1525 	extern char end[];
1526 #	define NEED_FIND_LIMIT
1527 #	define DATASTART ((ptr_t)(&etext))
1528 #	define DATAEND (GC_find_limit (DATASTART, TRUE))
1529 #	define DATASTART2 ((ptr_t)(&edata))
1530 #	define DATAEND2 ((ptr_t)(&end))
1531 #   endif
1532 #   ifdef OSF1
1533 #	define OS_TYPE "OSF1"
1534 #   	define DATASTART ((ptr_t) 0x140000000)
1535 	extern int _end[];
1536 #   	define DATAEND ((ptr_t) &_end)
1537  	extern char ** environ;
1538 	/* round up from the value of environ to the nearest page boundary */
1539 	/* Probably breaks if putenv is called before collector 	   */
1540 	/* initialization.						   */
1541 #	define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
1542 /* #   	define HEURISTIC2 */
1543 	/* Normally HEURISTIC2 is too conervative, since		*/
1544 	/* the text segment immediately follows the stack.		*/
1545 	/* Hence we give an upper pound.				*/
1546 	/* This is currently unused, since we disabled HEURISTIC2	*/
1547     	extern int __start[];
1548 #   	define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
1549 #	ifndef GC_OSF1_THREADS
1550 	  /* Unresolved signal issues with threads.	*/
1551 #   	  define MPROTECT_VDB
1552 #       endif
1553 #   	define DYNAMIC_LOADING
1554 #   endif
1555 #   ifdef LINUX
1556 #       define OS_TYPE "LINUX"
1557 #       define LINUX_STACKBOTTOM
1558 #       ifdef __ELF__
1559 #	  define SEARCH_FOR_DATA_START
1560 #         define DYNAMIC_LOADING
1561 #       else
1562 #           define DATASTART ((ptr_t) 0x140000000)
1563 #       endif
1564 	extern int _end[];
1565 #	define DATAEND (_end)
1566 #	define MPROTECT_VDB
1567 		/* Has only been superficially tested.  May not	*/
1568 		/* work on all versions.			*/
1569 #   endif
1570 # endif
1571 
1572 # ifdef IA64
1573 #   define MACH_TYPE "IA64"
1574 #   ifdef HPUX
1575 #	ifdef _ILP32
1576 #	  define CPP_WORDSZ 32
1577 	    /* Requires 8 byte alignment for malloc */
1578 #   	  define ALIGNMENT 4
1579 #       else
1580 #	  ifndef _LP64
1581 		---> unknown ABI
1582 #         endif
1583 #	  define CPP_WORDSZ 64
1584 	    /* Requires 16 byte alignment for malloc */
1585 #         define ALIGNMENT 8
1586 #       endif
1587 #       define OS_TYPE "HPUX"
1588         extern int __data_start[];
1589 #       define DATASTART ((ptr_t)(__data_start))
1590         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2	*/
1591         /* to this.  Note that the GC must be initialized before the	*/
1592     	/* first putenv call.						*/
1593 	extern char ** environ;
1594 #       define STACKBOTTOM ((ptr_t)environ)
1595 #       define HPUX_STACKBOTTOM
1596 #       define DYNAMIC_LOADING
1597 #       include <unistd.h>
1598 #       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1599  	/* The following was empirically determined, and is probably	*/
1600 	/* not very robust.						*/
1601 	/* Note that the backing store base seems to be at a nice 	*/
1602 	/* address minus one page.					*/
1603 #	define BACKING_STORE_DISPLACEMENT 0x1000000
1604 #	define BACKING_STORE_ALIGNMENT 0x1000
1605 	extern ptr_t GC_register_stackbottom;
1606 #	define BACKING_STORE_BASE GC_register_stackbottom
1607 	/* Known to be wrong for recent HP/UX versions!!!	*/
1608 #   endif
1609 #   ifdef LINUX
1610 #   	define CPP_WORDSZ 64
1611 #   	define ALIGNMENT 8
1612 #       define OS_TYPE "LINUX"
1613 	/* The following works on NUE and older kernels:	*/
1614 /* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)	*/
1615 	/* This does not work on NUE:				*/
1616 #       define LINUX_STACKBOTTOM
1617 	/* We also need the base address of the register stack	*/
1618 	/* backing store.  This is computed in 			*/
1619 	/* GC_linux_register_stack_base based on the following	*/
1620 	/* constants:						*/
1621 #       define BACKING_STORE_ALIGNMENT 0x100000
1622 #       define BACKING_STORE_DISPLACEMENT 0x80000000
1623 	extern ptr_t GC_register_stackbottom;
1624 #	define BACKING_STORE_BASE GC_register_stackbottom
1625 #	define SEARCH_FOR_DATA_START
1626 #	ifdef __GNUC__
1627 #         define DYNAMIC_LOADING
1628 #	else
1629 	  /* In the Intel compiler environment, we seem to end up with  */
1630 	  /* statically linked executables and an undefined reference	*/
1631 	  /* to _DYNAMIC						*/
1632 #  	endif
1633 #	define MPROTECT_VDB
1634 		/* Requires Linux 2.3.47 or later.	*/
1635 	extern int _end[];
1636 #	define DATAEND (_end)
1637 #       ifdef __GNUC__
1638 #	  ifndef __INTEL_COMPILER
1639 #	    define PREFETCH(x) \
1640 	      __asm__ ("	lfetch	[%0]": : "r"(x))
1641 #	    define PREFETCH_FOR_WRITE(x) \
1642 	      __asm__ ("	lfetch.excl	[%0]": : "r"(x))
1643 #	    define CLEAR_DOUBLE(x) \
1644 	      __asm__ ("	stf.spill	[%0]=f0": : "r"((void *)(x)))
1645 #	  else
1646 #           include <ia64intrin.h>
1647 #	    define PREFETCH(x) \
1648 	      __lfetch(__lfhint_none, (x))
1649 #	    define PREFETCH_FOR_WRITE(x) \
1650 	      __lfetch(__lfhint_nta,  (x))
1651 #	    define CLEAR_DOUBLE(x) \
1652 	      __stf_spill((void *)(x), 0)
1653 #	  endif // __INTEL_COMPILER
1654 #       endif
1655 #   endif
1656 #   ifdef MSWIN32
1657       /* FIXME: This is a very partial guess.  There is no port, yet.	*/
1658 #     define OS_TYPE "MSWIN32"
1659 		/* STACKBOTTOM and DATASTART are handled specially in 	*/
1660 		/* os_dep.c.						*/
1661 #     define DATAEND  /* not needed */
1662 #     if defined(_WIN64)
1663 #       define CPP_WORDSZ 64
1664 #     else
1665 #       define CPP_WORDSZ 32   /* Is this possible?	*/
1666 #     endif
1667 #     define ALIGNMENT 8
1668 #     define STRTOULL _strtoui64
1669 #   endif
1670 # endif
1671 
1672 # ifdef M88K
1673 #   define MACH_TYPE "M88K"
1674 #   define ALIGNMENT 4
1675     extern int etext[];
1676 #   ifdef CX_UX
1677 #	define OS_TYPE "CX_UX"
1678 #       define DATASTART ((((word)etext + 0x3fffff) & ~0x3fffff) + 0x10000)
1679 #   endif
1680 #   ifdef  DGUX
1681 #	define OS_TYPE "DGUX"
1682 	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1683 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
1684 #   endif
1685 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
1686 # endif
1687 
1688 # ifdef S370
1689     /* If this still works, and if anyone cares, this should probably	*/
1690     /* be moved to the S390 category.					*/
1691 #   define MACH_TYPE "S370"
1692 #   define ALIGNMENT 4	/* Required by hardware	*/
1693 #   ifdef UTS4
1694 #       define OS_TYPE "UTS4"
1695 	extern int etext[];
1696 	extern int _etext[];
1697 	extern int _end[];
1698 	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1699 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1700 #	define DATAEND (_end)
1701 #	define HEURISTIC2
1702 #   endif
1703 # endif
1704 
1705 # ifdef S390
1706 #   define MACH_TYPE "S390"
1707 #   ifndef __s390x__
1708 #   define ALIGNMENT 4
1709 #   define CPP_WORDSZ 32
1710 #   else
1711 #   define ALIGNMENT 8
1712 #   define CPP_WORDSZ 64
1713 #   ifndef HBLKSIZE
1714 #     define HBLKSIZE 4096
1715 #   endif
1716 #   endif
1717 #   ifdef LINUX
1718 #       define OS_TYPE "LINUX"
1719 #       define LINUX_STACKBOTTOM
1720 #       define DYNAMIC_LOADING
1721 	extern int __data_start[];
1722 #       define DATASTART ((ptr_t)(__data_start))
1723     extern int _end[];
1724 #   define DATAEND (_end)
1725 #   define CACHE_LINE_SIZE 256
1726 #   define GETPAGESIZE() 4096
1727 #   endif
1728 # endif
1729 
1730 # ifdef ARM32
1731 #   define CPP_WORDSZ 32
1732 #   define MACH_TYPE "ARM32"
1733 #   define ALIGNMENT 4
1734 #   ifdef NETBSD
1735 #       define OS_TYPE "NETBSD"
1736 #       define HEURISTIC2
1737 #	ifdef __ELF__
1738 #          define DATASTART GC_data_start
1739 #	   define DYNAMIC_LOADING
1740 #	else
1741            extern char etext[];
1742 #          define DATASTART ((ptr_t)(etext))
1743 #	endif
1744 #   endif
1745 #   ifdef LINUX
1746 #       define OS_TYPE "LINUX"
1747 #       define LINUX_STACKBOTTOM
1748 #       undef STACK_GRAN
1749 #       define STACK_GRAN 0x10000000
1750 #       ifdef __ELF__
1751 #            define DYNAMIC_LOADING
1752 #	     include <features.h>
1753 #	     if defined(__GLIBC__) && __GLIBC__ >= 2
1754 #		 define SEARCH_FOR_DATA_START
1755 #	     else
1756      	         extern char **__environ;
1757 #                define DATASTART ((ptr_t)(&__environ))
1758 			      /* hideous kludge: __environ is the first */
1759 			      /* word in crt0.o, and delimits the start */
1760 			      /* of the data segment, no matter which   */
1761 			      /* ld options were passed through.        */
1762 			      /* We could use _etext instead, but that  */
1763 			      /* would include .rodata, which may       */
1764 			      /* contain large read-only data tables    */
1765 			      /* that we'd rather not scan.		*/
1766 #	     endif
1767 	     extern int _end[];
1768 #	     define DATAEND (_end)
1769 #	else
1770 	     extern int etext[];
1771 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1772 #       endif
1773 #   endif
1774 #   ifdef MSWINCE
1775 #     define OS_TYPE "MSWINCE"
1776 #     define DATAEND /* not needed */
1777 #   endif
1778 #   ifdef NOSYS
1779       /* __data_start is usually defined in the target linker script.  */
1780       extern int __data_start[];
1781 #     define DATASTART (ptr_t)(__data_start)
1782       /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */
1783       extern void *__stack_base__;
1784 #     define STACKBOTTOM ((ptr_t) (__stack_base__))
1785 #   endif
1786 #endif
1787 
1788 # ifdef CRIS
1789 #   define MACH_TYPE "CRIS"
1790 #   define CPP_WORDSZ 32
1791 #   define ALIGNMENT 1
1792 #   define OS_TYPE "LINUX"
1793 #   define DYNAMIC_LOADING
1794 #   define LINUX_STACKBOTTOM
1795 #   define SEARCH_FOR_DATA_START
1796       extern int _end[];
1797 #   define DATAEND (_end)
1798 # endif
1799 
1800 # ifdef SH
1801 #   define MACH_TYPE "SH"
1802 #   define ALIGNMENT 4
1803 #   ifdef MSWINCE
1804 #     define OS_TYPE "MSWINCE"
1805 #     define DATAEND /* not needed */
1806 #   endif
1807 #   ifdef LINUX
1808 #     define OS_TYPE "LINUX"
1809 #     define LINUX_STACKBOTTOM
1810 #     define DYNAMIC_LOADING
1811 #     define SEARCH_FOR_DATA_START
1812       extern int _end[];
1813 #     define DATAEND (_end)
1814 #   endif
1815 #   ifdef NETBSD
1816 #      define OS_TYPE "NETBSD"
1817 #      define HEURISTIC2
1818 #      define DATASTART GC_data_start
1819 #      define DYNAMIC_LOADING
1820 #   endif
1821 # endif
1822 
1823 # ifdef SH4
1824 #   define MACH_TYPE "SH4"
1825 #   define OS_TYPE "MSWINCE"
1826 #   define ALIGNMENT 4
1827 #   define DATAEND /* not needed */
1828 # endif
1829 
1830 # ifdef M32R
1831 #   define CPP_WORDSZ 32
1832 #   define MACH_TYPE "M32R"
1833 #   define ALIGNMENT 4
1834 #   ifdef LINUX
1835 #     define OS_TYPE "LINUX"
1836 #     define LINUX_STACKBOTTOM
1837 #     undef STACK_GRAN
1838 #     define STACK_GRAN 0x10000000
1839 #     define DYNAMIC_LOADING
1840 #     define SEARCH_FOR_DATA_START
1841       extern int _end[];
1842 #     define DATAEND (_end)
1843 #   endif
1844 # endif
1845 
1846 # ifdef X86_64
1847 #   define MACH_TYPE "X86_64"
1848 #   define ALIGNMENT 8
1849 #   define CPP_WORDSZ 64
1850 #   ifndef HBLKSIZE
1851 #     define HBLKSIZE 4096
1852 #   endif
1853 #   define CACHE_LINE_SIZE 64
1854 #   ifdef LINUX
1855 #	define OS_TYPE "LINUX"
1856 #       define LINUX_STACKBOTTOM
1857 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
1858 #	    define MPROTECT_VDB
1859 #	else
1860 	    /* We seem to get random errors in incremental mode,	*/
1861 	    /* possibly because Linux threads is itself a malloc client */
1862 	    /* and can't deal with the signals.				*/
1863 #	endif
1864 #       ifdef __ELF__
1865 #            define DYNAMIC_LOADING
1866 #	     ifdef UNDEFINED	/* includes ro data */
1867 	       extern int _etext[];
1868 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
1869 #	     endif
1870 #	     include <features.h>
1871 #	     define SEARCH_FOR_DATA_START
1872 	     extern int _end[];
1873 #	     define DATAEND (_end)
1874 #	else
1875 	     extern int etext[];
1876 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1877 #       endif
1878 #       if defined(__GNUC__) && __GNUC__ >= 3
1879 #	    define PREFETCH(x) __builtin_prefetch((x), 0, 0)
1880 #	    define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
1881 #	endif
1882 #   endif
1883 #   ifdef DARWIN
1884 #     define OS_TYPE "DARWIN"
1885 #     define DARWIN_DONT_PARSE_STACK
1886 #     define DYNAMIC_LOADING
1887       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
1888 	 These aren't used when dyld support is enabled (it is by default) */
1889 #     define DATASTART ((ptr_t) get_etext())
1890 #     define DATAEND	((ptr_t) get_end())
1891 #     define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
1892 #     define USE_MMAP
1893 #     define USE_MMAP_ANON
1894 #     ifdef GC_DARWIN_THREADS
1895 #       define MPROTECT_VDB
1896 #     endif
1897 #     include <unistd.h>
1898 #     define GETPAGESIZE() getpagesize()
1899       /* There seems to be some issues with trylock hanging on darwin. This
1900 	 should be looked into some more */
1901 #     define NO_PTHREAD_TRYLOCK
1902 #   endif
1903 #   ifdef FREEBSD
1904 #	define OS_TYPE "FREEBSD"
1905 #	ifndef GC_FREEBSD_THREADS
1906 #	    define MPROTECT_VDB
1907 #	endif
1908 #	ifdef __GLIBC__
1909 #	    define SIG_SUSPEND		(32+6)
1910 #	    define SIG_THR_RESTART	(32+5)
1911 	    extern int _end[];
1912 #	    define DATAEND (_end)
1913 #	else
1914 #	    define SIG_SUSPEND SIGUSR1
1915 #	    define SIG_THR_RESTART SIGUSR2
1916 #	endif
1917 #	define FREEBSD_STACKBOTTOM
1918 #	ifdef __ELF__
1919 #	    define DYNAMIC_LOADING
1920 #	endif
1921 	extern char etext[];
1922 	extern char * GC_FreeBSDGetDataStart();
1923 #	define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
1924 #   endif
1925 #   ifdef NETBSD
1926 #	define OS_TYPE "NETBSD"
1927 #	ifdef __ELF__
1928 #	    define DYNAMIC_LOADING
1929 #	endif
1930 #	define HEURISTIC2
1931 	extern char etext[];
1932 #	define SEARCH_FOR_DATA_START
1933 #   endif
1934 #   ifdef SOLARIS
1935 #	define OS_TYPE "SOLARIS"
1936 #	define ELF_CLASS ELFCLASS64
1937         extern int _etext[], _end[];
1938   	extern ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1939 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
1940 #	define DATAEND (_end)
1941 /*	# define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,  	*/
1942 /*      but reportedly breaks under 2.8.  It appears that the stack	*/
1943 /* 	base is a property of the executable, so this should not break	*/
1944 /* 	old executables.						*/
1945 /*  	HEURISTIC2 probably works, but this appears to be preferable.	*/
1946 /*	Apparently USRSTACK is defined to be USERLIMIT, but in some	*/
1947 /* 	installations that's undefined.  We work around this with a	*/
1948 /*	gross hack:							*/
1949 #       include <sys/vmparam.h>
1950 #	ifdef USERLIMIT
1951 	  /* This should work everywhere, but doesn't.	*/
1952 #	  define STACKBOTTOM USRSTACK
1953 #       else
1954 #	  define HEURISTIC2
1955 #       endif
1956 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1957 /* It appears to be fixed in 2.8 and 2.9.				*/
1958 #	ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1959 #	  define PROC_VDB
1960 #	endif
1961 #	define DYNAMIC_LOADING
1962 #	if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1963 #	    define USE_MMAP
1964 	    /* Otherwise we now use calloc.  Mmap may result in the	*/
1965 	    /* heap interleaved with thread stacks, which can result in	*/
1966 	    /* excessive blacklisting.  Sbrk is unusable since it	*/
1967 	    /* doesn't interact correctly with the system malloc.	*/
1968 #	endif
1969 #       ifdef USE_MMAP
1970 #         define HEAP_START (ptr_t)0x40000000
1971 #       else
1972 #	  define HEAP_START DATAEND
1973 #       endif
1974 #   endif
1975 #   ifdef MSWIN32
1976 #	define OS_TYPE "MSWIN32"
1977 		/* STACKBOTTOM and DATASTART are handled specially in 	*/
1978 		/* os_dep.c.						*/
1979 #       if !defined(__WATCOMC__)
1980 #	  define MPROTECT_VDB
1981 	  /* We also avoided doing this in the past with GC_WIN32_THREADS */
1982 	  /* Hopefully that's fixed.					  */
1983 #	endif
1984 #	if _MSC_VER >= 1300  /* .NET, i.e. > VisualStudio 6	*/
1985 #         define GWW_VDB
1986 #	endif
1987 #       define DATAEND  /* not needed */
1988 #   endif
1989 # endif
1990 
1991 #if defined(LINUX) && defined(USE_MMAP)
1992     /* The kernel may do a somewhat better job merging mappings etc.	*/
1993     /* with anonymous mappings.						*/
1994 #   define USE_MMAP_ANON
1995 #endif
1996 
1997 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC)
1998     /* Nptl allocates thread stacks with mmap, which is fine.  But it	*/
1999     /* keeps a cache of thread stacks.  Thread stacks contain the	*/
2000     /* thread control blocks.  These in turn contain a pointer to	*/
2001     /* (sizeof (void *) from the beginning of) the dtv for thread-local	*/
2002     /* storage, which is calloc allocated.  If we don't scan the cached	*/
2003     /* thread stacks, we appear to lose the dtv.  This tends to		*/
2004     /* result in something that looks like a bogus dtv count, which	*/
2005     /* tends to result in a memset call on a block that is way too	*/
2006     /* large.  Sometimes we're lucky and the process just dies ...	*/
2007     /* There seems to be a similar issue with some other memory 	*/
2008     /* allocated by the dynamic loader.					*/
2009     /* This can be avoided by either:					*/
2010     /* - Defining USE_PROC_FOR_LIBRARIES here.				*/
2011     /*   That performs very poorly, precisely because we end up 	*/
2012     /*   scanning cached stacks.					*/
2013     /* - Have calloc look at its callers.  That is currently what we do.*/
2014     /*   In spite of the fact that it is gross and disgusting.		*/
2015 /* #   define USE_PROC_FOR_LIBRARIES */
2016 #endif
2017 
2018 # ifndef STACK_GROWS_UP
2019 #   define STACK_GROWS_DOWN
2020 # endif
2021 
2022 # ifndef CPP_WORDSZ
2023 #   define CPP_WORDSZ 32
2024 # endif
2025 
2026 # ifndef OS_TYPE
2027 #   define OS_TYPE ""
2028 # endif
2029 
2030 # ifndef DATAEND
2031     extern int end[];
2032 #   define DATAEND (end)
2033 # endif
2034 
2035 # if defined(SVR4) && !defined(GETPAGESIZE)
2036 #    include <unistd.h>
2037 #    define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
2038 # endif
2039 
2040 # ifndef GETPAGESIZE
2041 #   if defined(SOLARIS) || defined(IRIX5) || defined(LINUX) \
2042        || defined(NETBSD) || defined(FREEBSD) || defined(HPUX)
2043 #	include <unistd.h>
2044 #   endif
2045 #   define GETPAGESIZE() getpagesize()
2046 # endif
2047 
2048 # if defined(SOLARIS) || defined(DRSNX) || defined(UTS4)
2049 	    /* OS has SVR4 generic features.		*/
2050     	    /* Probably others also qualify.		*/
2051 #   define SVR4
2052 # endif
2053 
2054 # if defined(SOLARIS) || defined(DRSNX)
2055 	    /* OS has SOLARIS style semi-undocumented interface */
2056     	    /* to dynamic loader.				*/
2057 #   define SOLARISDL
2058 	    /* OS has SOLARIS style signal handlers.		*/
2059 #   define SUNOS5SIGS
2060 # endif
2061 
2062 # if defined(HPUX)
2063 #   define SUNOS5SIGS
2064 # endif
2065 
2066 # if defined(FREEBSD) && \
2067      (defined(__DragonFly__) || __FreeBSD__ >= 4 || (__FreeBSD_kernel__ >= 4))
2068 #   define SUNOS5SIGS
2069 # endif
2070 
2071 # ifdef GC_NETBSD_THREADS
2072 #   define SIGRTMIN 33
2073 #   define SIGRTMAX 63
2074 # endif
2075 
2076 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
2077 	    || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
2078 	    || defined(DGUX) || defined(BSD) \
2079 	    || defined(AIX) || defined(DARWIN) || defined(OSF1) \
2080 	    || defined(HURD)
2081 #   define UNIX_LIKE   /* Basic Unix-like system calls work.	*/
2082 # endif
2083 
2084 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
2085 	   -> bad word size
2086 # endif
2087 
2088 # ifdef PCR
2089 #   undef DYNAMIC_LOADING
2090 #   undef STACKBOTTOM
2091 #   undef HEURISTIC1
2092 #   undef HEURISTIC2
2093 #   undef PROC_VDB
2094 #   undef MPROTECT_VDB
2095 #   define PCR_VDB
2096 # endif
2097 
2098 # ifdef SMALL_CONFIG
2099 	/* Presumably not worth the space it takes. */
2100 #   undef PROC_VDB
2101 #   undef MPROTECT_VDB
2102 # endif
2103 
2104 # ifdef USE_MUNMAP
2105 #   undef MPROTECT_VDB  /* Can't deal with address space holes. */
2106 # endif
2107 
2108 # ifdef PARALLEL_MARK
2109 #   undef MPROTECT_VDB  /* For now.	*/
2110 # endif
2111 
2112 # if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) \
2113     && !defined(GWW_VDB)
2114 #   define DEFAULT_VDB
2115 # endif
2116 
2117 # ifndef PREFETCH
2118 #   define PREFETCH(x)
2119 #   define NO_PREFETCH
2120 # endif
2121 
2122 # ifndef PREFETCH_FOR_WRITE
2123 #   define PREFETCH_FOR_WRITE(x)
2124 #   define NO_PREFETCH_FOR_WRITE
2125 # endif
2126 
2127 # ifndef CACHE_LINE_SIZE
2128 #   define CACHE_LINE_SIZE 32	/* Wild guess	*/
2129 # endif
2130 
2131 # if defined(LINUX) || defined(HURD) || defined(__GLIBC__)
2132 #   define REGISTER_LIBRARIES_EARLY
2133     /* We sometimes use dl_iterate_phdr, which may acquire an internal	*/
2134     /* lock.  This isn't safe after the world has stopped.  So we must	*/
2135     /* call GC_register_dynamic_libraries before stopping the world.	*/
2136     /* For performance reasons, this may be beneficial on other		*/
2137     /* platforms as well, though it should be avoided in win32.		*/
2138 # endif /* LINUX */
2139 
2140 # if defined(SEARCH_FOR_DATA_START)
2141     extern ptr_t GC_data_start;
2142 #   define DATASTART GC_data_start
2143 # endif
2144 
2145 # ifndef CLEAR_DOUBLE
2146 #   define CLEAR_DOUBLE(x) \
2147 		((word*)x)[0] = 0; \
2148 		((word*)x)[1] = 0;
2149 # endif /* CLEAR_DOUBLE */
2150 
2151 # if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
2152      && !defined(INCLUDE_LINUX_THREAD_DESCR)
2153     /* Will not work, since libc and the dynamic loader use thread 	*/
2154     /* locals, sometimes as the only reference.				*/
2155 #   define INCLUDE_LINUX_THREAD_DESCR
2156 # endif
2157 
2158 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
2159 	--> inconsistent configuration
2160 # endif
2161 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
2162 	--> inconsistent configuration
2163 # endif
2164 # if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
2165 	--> inconsistent configuration
2166 # endif
2167 # if defined(GC_SOLARIS_THREADS) && !defined(SOLARIS)
2168 	--> inconsistent configuration
2169 # endif
2170 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
2171 	--> inconsistent configuration
2172 # endif
2173 # if defined(GC_AIX_THREADS) && !defined(_AIX)
2174 	--> inconsistent configuration
2175 # endif
2176 # if defined(GC_GNU_THREADS) && !defined(HURD)
2177 	--> inconsistent configuration
2178 # endif
2179 # if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32)
2180 	--> inconsistent configuration
2181 # endif
2182 
2183 # if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS)
2184 #   define THREADS
2185 # endif
2186 
2187 # if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES)
2188 #   if defined(THREADS) && defined(PARALLEL_MARK)
2189 #     define USE_MARK_BYTES
2190 #   else
2191 #     define USE_MARK_BITS
2192 #   endif
2193 # endif
2194 
2195 # if defined(MSWINCE)
2196 #   define NO_GETENV
2197 # endif
2198 
2199 # if defined(SPARC)
2200 #   define ASM_CLEAR_CODE	/* Stack clearing is crucial, and we 	*/
2201 				/* include assembly code to do it well.	*/
2202 # endif
2203 
2204   /* Can we save call chain in objects for debugging?   	        */
2205   /* SET NFRAMES (# of saved frames) and NARGS (#of args for each 	*/
2206   /* frame) to reasonable values for the platform.			*/
2207   /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified 	*/
2208   /* at build time, though we feel free to adjust it slightly.		*/
2209   /* Define NEED_CALLINFO if we either save the call stack or 		*/
2210   /* GC_ADD_CALLER is defined.						*/
2211   /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.				*/
2212 
2213 #if defined(SPARC)
2214 # define CAN_SAVE_CALL_ARGS
2215 #endif
2216 #if (defined(I386) || defined(X86_64)) && (defined(LINUX) || defined(__GLIBC__))
2217 	    /* SAVE_CALL_CHAIN is supported if the code is compiled to save	*/
2218 	    /* frame pointers by default, i.e. no -fomit-frame-pointer flag.	*/
2219 # define CAN_SAVE_CALL_ARGS
2220 #endif
2221 
2222 # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
2223 	     && defined(GC_CAN_SAVE_CALL_STACKS)
2224 #   define SAVE_CALL_CHAIN
2225 # endif
2226 # ifdef SAVE_CALL_CHAIN
2227 #   if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
2228 #     define NARGS SAVE_CALL_NARGS
2229 #   else
2230 #     define NARGS 0	/* Number of arguments to save for each call.	*/
2231 #   endif
2232 # endif
2233 # ifdef SAVE_CALL_CHAIN
2234 #   ifndef SAVE_CALL_COUNT
2235 #     define NFRAMES 6	/* Number of frames to save. Even for		*/
2236 			/* alignment reasons.				*/
2237 #   else
2238 #     define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
2239 #   endif
2240 #   define NEED_CALLINFO
2241 # endif /* SAVE_CALL_CHAIN */
2242 # ifdef GC_ADD_CALLER
2243 #   define NFRAMES 1
2244 #   define NARGS 0
2245 #   define NEED_CALLINFO
2246 # endif
2247 
2248 # if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
2249 #   define DBG_HDRS_ALL
2250 # endif
2251 
2252 # if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
2253 #   define POINTER_SHIFT 0
2254 # endif
2255 
2256 # if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
2257 #   define POINTER_MASK ((GC_word)(-1))
2258 # endif
2259 
2260 # if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
2261 #   define FIXUP_POINTER(p) (p) = ((p) & (POINTER_MASK) << POINTER_SHIFT)
2262 # endif
2263 
2264 # if defined(FIXUP_POINTER)
2265 #   define NEED_FIXUP_POINTER 1
2266 # else
2267 #   define NEED_FIXUP_POINTER 0
2268 #   define FIXUP_POINTER(p)
2269 # endif
2270 
2271 # if !defined(MARK_BIT_PER_GRANULE) && !defined(MARK_BIT_PER_OBJ)
2272 #   define MARK_BIT_PER_GRANULE	/* Usually faster */
2273 # endif
2274 
2275 /* Some static sanity tests.	*/
2276 # if defined(MARK_BIT_PER_GRANULE) && defined(MARK_BIT_PER_OBJ)
2277 #   error Define only one of MARK_BIT_PER_GRANULE and MARK_BIT_PER_OBJ.
2278 # endif
2279 
2280 # if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
2281 #   error "Only one of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd."
2282 # endif
2283 # if !defined(STACK_GROWS_UP) && !defined(STACK_GROWS_DOWN)
2284 #   error "One of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd."
2285 # endif
2286 
2287 # if defined(REDIRECT_MALLOC) && defined(THREADS) && !defined(LINUX)
2288 #   error "REDIRECT_MALLOC with THREADS works at most on Linux."
2289 # endif
2290 
2291 #ifdef GC_PRIVATE_H
2292 	/* This relies on some type definitions from gc_priv.h, from	*/
2293         /* where it's normally included.				*/
2294 	/*								*/
2295 	/* How to get heap memory from the OS:				*/
2296 	/* Note that sbrk()-like allocation is preferred, since it 	*/
2297 	/* usually makes it possible to merge consecutively allocated	*/
2298 	/* chunks.  It also avoids unintented recursion with		*/
2299 	/* -DREDIRECT_MALLOC.						*/
2300 	/* GET_MEM() returns a HLKSIZE aligned chunk.			*/
2301 	/* 0 is taken to mean failure. 					*/
2302 	/* In the case os USE_MMAP, the argument must also be a 	*/
2303 	/* physical page size.						*/
2304 	/* GET_MEM is currently not assumed to retrieve 0 filled space, */
2305 	/* though we should perhaps take advantage of the case in which */
2306 	/* does.							*/
2307 	struct hblk;	/* See gc_priv.h.	*/
2308 # if defined(PCR)
2309     char * real_malloc();
2310 #   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
2311 					  + GC_page_size-1)
2312 # elif defined(OS2)
2313     void * os2_alloc(size_t bytes);
2314 #   define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
2315 					    + GC_page_size) \
2316 					    + GC_page_size-1)
2317 # elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) || \
2318 		 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
2319 		 (defined(SOLARIS) && !defined(USE_MMAP))
2320 #   define GET_MEM(bytes) HBLKPTR((size_t) calloc(1, (size_t)bytes + GC_page_size) \
2321 					             + GC_page_size-1)
2322 # elif defined(MSWIN32)
2323     extern ptr_t GC_win32_get_mem();
2324 #   define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
2325 # elif defined(MACOS)
2326 #   if defined(USE_TEMPORARY_MEMORY)
2327       extern Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);
2328 #     define GET_MEM(bytes) HBLKPTR( \
2329 			    GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
2330 			    + GC_page_size-1)
2331 #   else
2332 #     define GET_MEM(bytes) HBLKPTR( \
2333 				NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
2334 #   endif
2335 # elif defined(MSWINCE)
2336     extern ptr_t GC_wince_get_mem();
2337 #   define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
2338 # elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
2339     extern void *GC_amiga_get_mem(size_t size);
2340 #   define GET_MEM(bytes) HBLKPTR((size_t) \
2341 			  GC_amiga_get_mem((size_t)bytes + GC_page_size) \
2342 			  + GC_page_size-1)
2343 # else
2344     extern ptr_t GC_unix_get_mem();
2345 #   define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
2346 # endif
2347 
2348 #endif /* GC_PRIVATE_H */
2349 
2350 # endif /* GCCONFIG_H */
2351