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