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