]> granicus.if.org Git - gc/blob - include/private/gcconfig.h
Refactoring of WoW64 workaround (Win32)
[gc] / 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 #ifdef CPPCHECK
29 # undef CLOCKS_PER_SEC
30 # undef FIXUP_POINTER
31 # undef POINTER_MASK
32 # undef POINTER_SHIFT
33 # undef REDIRECT_REALLOC
34 # undef _MAX_PATH
35 #endif
36
37 #ifndef PTR_T_DEFINED
38   typedef char * ptr_t;
39 # define PTR_T_DEFINED
40 #endif
41
42 #if !defined(sony_news)
43 # include <stddef.h> /* For size_t, etc. */
44 #endif
45
46 /* Note: Only wrap our own declarations, and not the included headers.  */
47 /* In this case, wrap our entire file, but temporarily unwrap/rewrap    */
48 /* around #includes.  Types and macros do not need such wrapping, only  */
49 /* the declared global data and functions.                              */
50 #ifdef __cplusplus
51 # define EXTERN_C_BEGIN extern "C" {
52 # define EXTERN_C_END } /* extern "C" */
53 #else
54 # define EXTERN_C_BEGIN /* empty */
55 # define EXTERN_C_END /* empty */
56 #endif
57
58 EXTERN_C_BEGIN
59
60 /* Convenient internal macro to test version of Clang.  */
61 #if defined(__clang__) && defined(__clang_major__)
62 # define GC_CLANG_PREREQ(major, minor) \
63     ((__clang_major__ << 16) + __clang_minor__ >= ((major) << 16) + (minor))
64 # define GC_CLANG_PREREQ_FULL(major, minor, patchlevel) \
65             (GC_CLANG_PREREQ(major, (minor) + 1) \
66                 || (__clang_major__ == (major) && __clang_minor__ == (minor) \
67                     && __clang_patchlevel__ >= (patchlevel)))
68 #else
69 # define GC_CLANG_PREREQ(major, minor) 0 /* FALSE */
70 # define GC_CLANG_PREREQ_FULL(major, minor, patchlevel) 0
71 #endif
72
73 #ifdef LINT2
74   /* A macro (based on a tricky expression) to prevent false warnings   */
75   /* like "Array compared to 0", "Comparison of identical expressions", */
76   /* "Untrusted loop bound" output by some static code analysis tools.  */
77   /* The argument should not be a literal value.  The result is         */
78   /* converted to word type.  (Actually, GC_word is used instead of     */
79   /* word type as the latter might be undefined at the place of use.)   */
80 # define COVERT_DATAFLOW(w) (~(GC_word)(w)^(~(GC_word)0))
81 #else
82 # define COVERT_DATAFLOW(w) ((GC_word)(w))
83 #endif
84
85 /* Machine dependent parameters.  Some tuning parameters can be found   */
86 /* near the top of gc_private.h.                                        */
87
88 /* Machine specific parts contributed by various people.  See README file. */
89
90 #if defined(__ANDROID__) && !defined(HOST_ANDROID)
91   /* __ANDROID__ macro is defined by Android NDK gcc.   */
92 # define HOST_ANDROID 1
93 #endif
94
95 #if defined(TIZEN) && !defined(HOST_TIZEN)
96 # define HOST_TIZEN 1
97 #endif
98
99 #if defined(__SYMBIAN32__) && !defined(SYMBIAN)
100 # define SYMBIAN
101 # ifdef __WINS__
102 #   pragma data_seg(".data2")
103 # endif
104 #endif
105
106 /* First a unified test for Linux: */
107 # if (defined(linux) || defined(__linux__) || defined(HOST_ANDROID)) \
108      && !defined(LINUX) && !defined(__native_client__)
109 #   define LINUX
110 # endif
111
112 /* And one for NetBSD: */
113 # if defined(__NetBSD__)
114 #    define NETBSD
115 # endif
116
117 /* And one for OpenBSD: */
118 # if defined(__OpenBSD__)
119 #    define OPENBSD
120 # endif
121
122 /* And one for FreeBSD: */
123 # if (defined(__FreeBSD__) || defined(__DragonFly__) \
124       || defined(__FreeBSD_kernel__)) && !defined(FREEBSD) \
125      && !defined(SN_TARGET_ORBIS) /* Orbis compiler defines __FreeBSD__ */
126 #   define FREEBSD
127 # endif
128
129 /* And one for Darwin: */
130 # if defined(macosx) || (defined(__APPLE__) && defined(__MACH__))
131 #   define DARWIN
132     EXTERN_C_END
133 #   include <TargetConditionals.h>
134     EXTERN_C_BEGIN
135 # endif
136
137 /* Determine the machine type: */
138 # if defined(__native_client__)
139 #    define NACL
140 #    if !defined(__portable_native_client__) && !defined(__arm__)
141 #      define I386
142 #      define mach_type_known
143 #    else
144        /* Here we will rely upon arch-specific defines. */
145 #    endif
146 # endif
147 # if defined(__aarch64__)
148 #    define AARCH64
149 #    if !defined(LINUX) && !defined(DARWIN) && !defined(FREEBSD) \
150         && !defined(NETBSD) && !defined(NN_BUILD_TARGET_PLATFORM_NX) \
151         && !defined(OPENBSD)
152 #      define NOSYS
153 #      define mach_type_known
154 #    endif
155 # endif
156 # if defined(__arm) || defined(__arm__) || defined(__thumb__)
157 #    define ARM32
158 #    if defined(NACL)
159 #      define mach_type_known
160 #    elif !defined(LINUX) && !defined(NETBSD) && !defined(FREEBSD) \
161           && !defined(OPENBSD) && !defined(DARWIN) && !defined(_WIN32) \
162           && !defined(__CEGCC__) && !defined(NN_PLATFORM_CTR) \
163           && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) \
164           && !defined(SYMBIAN)
165 #      define NOSYS
166 #      define mach_type_known
167 #    endif
168 # endif
169 # if defined(sun) && defined(mc68000) && !defined(CPPCHECK)
170 #    error SUNOS4 no longer supported
171 # endif
172 # if defined(hp9000s300) && !defined(CPPCHECK)
173 #    error M68K based HP machines no longer supported
174 # endif
175 # if defined(OPENBSD) && defined(m68k)
176 #    define M68K
177 #    define mach_type_known
178 # endif
179 # if defined(OPENBSD) && defined(__sparc__)
180 #    define SPARC
181 #    define mach_type_known
182 # endif
183 # if defined(OPENBSD) && defined(__arm__)
184 #    define ARM32
185 #    define mach_type_known
186 # endif
187 # if defined(OPENBSD) && defined(__aarch64__)
188 #    define AARCH64
189 #    define mach_type_known
190 # endif
191 # if defined(OPENBSD) && defined(__sh__)
192 #    define SH
193 #    define mach_type_known
194 # endif
195 # if defined(NETBSD) && (defined(m68k) || defined(__m68k__))
196 #    define M68K
197 #    define mach_type_known
198 # endif
199 # if defined(NETBSD) && defined(__powerpc__)
200 #    define POWERPC
201 #    define mach_type_known
202 # endif
203 # if defined(NETBSD) && (defined(__arm32__) || defined(__arm__))
204 #    define ARM32
205 #    define mach_type_known
206 # endif
207 # if defined(NETBSD) && defined(__aarch64__)
208 #    define AARCH64
209 #    define mach_type_known
210 # endif
211 # if defined(NETBSD) && defined(__sh__)
212 #    define SH
213 #    define mach_type_known
214 # endif
215 # if defined(vax) || defined(__vax__)
216 #    define VAX
217 #    ifdef ultrix
218 #       define ULTRIX
219 #    else
220 #       define BSD
221 #    endif
222 #    define mach_type_known
223 # endif
224 # if defined(NETBSD) && defined(__vax__)
225 #    define VAX
226 #    define mach_type_known
227 # endif
228 # if defined(mips) || defined(__mips) || defined(_mips)
229 #    define MIPS
230 #    if defined(nec_ews) || defined(_nec_ews)
231 #      define EWS4800
232 #    endif
233 #    if !defined(LINUX) && !defined(EWS4800) && !defined(NETBSD) \
234         && !defined(OPENBSD)
235 #      if defined(ultrix) || defined(__ultrix)
236 #        define ULTRIX
237 #      else
238 #        define IRIX5   /* or IRIX 6.X */
239 #      endif
240 #    endif /* !LINUX */
241 #    if defined(NETBSD) && defined(__MIPSEL__)
242 #      undef ULTRIX
243 #    endif
244 #    define mach_type_known
245 # endif
246 # if defined(__QNX__)
247 #   define I386
248 #   define mach_type_known
249 # endif
250 # if defined(__NIOS2__) || defined(__NIOS2) || defined(__nios2__)
251 #   define NIOS2 /* Altera NIOS2 */
252 #   define mach_type_known
253 # endif
254 # if defined(__or1k__)
255 #    define OR1K        /* OpenRISC/or1k */
256 #    define mach_type_known
257 # endif
258 # if defined(DGUX) && (defined(i386) || defined(__i386__))
259 #    define I386
260 #    ifndef _USING_DGUX
261 #      define _USING_DGUX
262 #    endif
263 #    define mach_type_known
264 # endif
265 # if defined(sequent) && (defined(i386) || defined(__i386__))
266 #    define I386
267 #    define SEQUENT
268 #    define mach_type_known
269 # endif
270 # if (defined(sun) || defined(__sun)) && (defined(i386) || defined(__i386__))
271 #    define I386
272 #    define SOLARIS
273 #    define mach_type_known
274 # endif
275 # if (defined(sun) || defined(__sun)) && defined(__amd64)
276 #    define X86_64
277 #    define SOLARIS
278 #    define mach_type_known
279 # endif
280 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
281 #    define I386
282 #    define OS2
283 #    define mach_type_known
284 # endif
285 # if defined(ibm032) && !defined(CPPCHECK)
286 #   error IBM PC/RT no longer supported
287 # endif
288 # if (defined(sun) || defined(__sun)) && (defined(sparc) || defined(__sparc))
289             /* Test for SunOS 5.x */
290     EXTERN_C_END
291 #   include <errno.h>
292     EXTERN_C_BEGIN
293 #   define SPARC
294 #   define SOLARIS
295 #   define mach_type_known
296 # elif defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
297        && !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD)
298 #   define SPARC
299 #   define DRSNX
300 #   define mach_type_known
301 # endif
302 # if defined(_IBMR2)
303 #   define POWERPC
304 #   define AIX
305 #   define mach_type_known
306 # endif
307 # if defined(NETBSD) && defined(__sparc__)
308 #   define SPARC
309 #   define mach_type_known
310 # endif
311 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
312         /* The above test may need refinement   */
313 #   define I386
314 #   if defined(_SCO_ELF)
315 #     define SCO_ELF
316 #   else
317 #     define SCO
318 #   endif
319 #   define mach_type_known
320 # endif
321 # if defined(_AUX_SOURCE) && !defined(CPPCHECK)
322 #   error A/UX no longer supported
323 # endif
324 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
325      || defined(hppa) || defined(__hppa__)
326 #   define HP_PA
327 #   if !defined(LINUX) && !defined(HPUX) && !defined(OPENBSD)
328 #     define HPUX
329 #   endif
330 #   define mach_type_known
331 # endif
332 # if defined(__ia64) && (defined(_HPUX_SOURCE) || defined(__HP_aCC))
333 #   define IA64
334 #   ifndef HPUX
335 #     define HPUX
336 #   endif
337 #   define mach_type_known
338 # endif
339 # if (defined(__BEOS__) || defined(__HAIKU__)) && defined(_X86_)
340 #    define I386
341 #    define HAIKU
342 #    define mach_type_known
343 # endif
344 # if defined(__HAIKU__) && (defined(__amd64__) || defined(__x86_64__))
345 #    define X86_64
346 #    define HAIKU
347 #    define mach_type_known
348 # endif
349 # if defined(OPENBSD) && defined(__amd64__)
350 #    define X86_64
351 #    define mach_type_known
352 # endif
353 # if defined(LINUX) && (defined(i386) || defined(__i386__))
354 #    define I386
355 #    define mach_type_known
356 # endif
357 # if defined(LINUX) && defined(__x86_64__)
358 #    define X86_64
359 #    define mach_type_known
360 # endif
361 # if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
362 #    define IA64
363 #    define mach_type_known
364 # endif
365 # if defined(LINUX) && defined(__aarch64__)
366 #    define AARCH64
367 #    define mach_type_known
368 # endif
369 # if defined(LINUX) && (defined(__arm) || defined(__arm__))
370 #    define ARM32
371 #    define mach_type_known
372 # endif
373 # if defined(LINUX) && defined(__cris__)
374 #    ifndef CRIS
375 #       define CRIS
376 #    endif
377 #    define mach_type_known
378 # endif
379 # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) \
380                         || defined(powerpc64) || defined(__powerpc64__))
381 #    define POWERPC
382 #    define mach_type_known
383 # endif
384 # if defined(LINUX) && defined(__mc68000__)
385 #    define M68K
386 #    define mach_type_known
387 # endif
388 # if defined(LINUX) && (defined(sparc) || defined(__sparc__))
389 #    define SPARC
390 #    define mach_type_known
391 # endif
392 # if defined(LINUX) && defined(__sh__)
393 #    define SH
394 #    define mach_type_known
395 # endif
396 # if defined(LINUX) && defined(__avr32__)
397 #    define AVR32
398 #    define mach_type_known
399 # endif
400 # if defined(LINUX) && defined(__m32r__)
401 #    define M32R
402 #    define mach_type_known
403 # endif
404 # if defined(__alpha) || defined(__alpha__)
405 #   define ALPHA
406 #   if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \
407        && !defined(FREEBSD)
408 #     define OSF1       /* a.k.a Digital Unix */
409 #   endif
410 #   define mach_type_known
411 # endif
412 # if defined(_AMIGA) && !defined(AMIGA)
413 #   define AMIGA
414 # endif
415 # ifdef AMIGA
416 #   define M68K
417 #   define mach_type_known
418 # endif
419 # if defined(THINK_C) \
420      || (defined(__MWERKS__) && !defined(__powerc) && !defined(SYMBIAN))
421 #   define M68K
422 #   define MACOS
423 #   define mach_type_known
424 # endif
425 # if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__) \
426      && !defined(SYMBIAN)
427 #   define POWERPC
428 #   define MACOS
429 #   define mach_type_known
430 # endif
431 # if defined(OPENBSD) && defined(__powerpc__)
432 #   define POWERPC
433 #   define mach_type_known
434 # endif
435 # if defined(DARWIN)
436 #   if defined(__ppc__)  || defined(__ppc64__)
437 #    define POWERPC
438 #    define mach_type_known
439 #   elif defined(__x86_64__) || defined(__x86_64)
440 #    define X86_64
441 #    define mach_type_known
442 #   elif defined(__i386__)
443 #    define I386
444 #    define mach_type_known
445 #   elif defined(__arm__)
446 #    define ARM32
447 #    define mach_type_known
448 #   elif defined(__aarch64__)
449 #    define AARCH64
450 #    define mach_type_known
451 #   endif
452 # endif
453 # if defined(__rtems__) && (defined(i386) || defined(__i386__))
454 #   define I386
455 #   define RTEMS
456 #   define mach_type_known
457 # endif
458 # if defined(NeXT) && defined(mc68000)
459 #   define M68K
460 #   define NEXT
461 #   define mach_type_known
462 # endif
463 # if defined(NeXT) && (defined(i386) || defined(__i386__))
464 #   define I386
465 #   define NEXT
466 #   define mach_type_known
467 # endif
468 # if defined(OPENBSD) && (defined(i386) || defined(__i386__))
469 #   define I386
470 #   define mach_type_known
471 # endif
472 # if defined(NETBSD) && (defined(i386) || defined(__i386__))
473 #   define I386
474 #   define mach_type_known
475 # endif
476 # if defined(NETBSD) && defined(__x86_64__)
477 #    define X86_64
478 #    define mach_type_known
479 # endif
480 # if defined(FREEBSD) && (defined(i386) || defined(__i386__))
481 #   define I386
482 #   define mach_type_known
483 # endif
484 # if (defined(FREEBSD) || defined(SN_TARGET_ORBIS)) \
485      && (defined(__amd64__) || defined(__x86_64__))
486 #   define X86_64
487 #   define mach_type_known
488 # endif
489 # if defined(FREEBSD) && defined(__sparc__)
490 #   define SPARC
491 #   define mach_type_known
492 # endif
493 # if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__))
494 #   define POWERPC
495 #   define mach_type_known
496 # endif
497 # if defined(FREEBSD) && defined(__arm__)
498 #   define ARM32
499 #   define mach_type_known
500 # endif
501 # if defined(FREEBSD) && defined(__aarch64__)
502 #   define AARCH64
503 #   define mach_type_known
504 # endif
505 # if defined(FREEBSD) && (defined(mips) || defined(__mips) || defined(_mips))
506 #   define MIPS
507 #   define mach_type_known
508 # endif
509 # if defined(bsdi) && (defined(i386) || defined(__i386__))
510 #    define I386
511 #    define BSDI
512 #    define mach_type_known
513 # endif
514 # if !defined(mach_type_known) && defined(__386BSD__)
515 #   define I386
516 #   define THREE86BSD
517 #   define mach_type_known
518 # endif
519 # if defined(_CX_UX) && defined(_M88K)
520 #   define M88K
521 #   define CX_UX
522 #   define mach_type_known
523 # endif
524 # if defined(DGUX) && defined(m88k)
525 #   define M88K
526     /* DGUX defined */
527 #   define mach_type_known
528 # endif
529 # if defined(_WIN32_WCE) || defined(__CEGCC__) || defined(__MINGW32CE__)
530     /* SH3, SH4, MIPS already defined for corresponding architectures */
531 #   if defined(SH3) || defined(SH4)
532 #     define SH
533 #   endif
534 #   if defined(x86) || defined(__i386__)
535 #     define I386
536 #   endif
537 #   if defined(_M_ARM) || defined(ARM) || defined(_ARM_)
538 #     define ARM32
539 #   endif
540 #   define MSWINCE
541 #   define mach_type_known
542 # else
543 #   if ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300)) \
544        || (defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) \
545            && !defined(__INTERIX) && !defined(SYMBIAN))
546 #     if defined(__LP64__) || defined(_M_X64)
547 #       define X86_64
548 #     elif defined(_M_ARM)
549 #       define ARM32
550 #     elif defined(_M_ARM64)
551 #       define AARCH64
552 #     else /* _M_IX86 */
553 #       define I386
554 #     endif
555 #     ifdef _XBOX_ONE
556 #       define MSWIN_XBOX1
557 #     else
558 #       ifndef MSWIN32
559 #         define MSWIN32 /* or Win64 */
560 #       endif
561 #       if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
562 #         define MSWINRT_FLAVOR
563 #       endif
564 #     endif
565 #     define mach_type_known
566 #   endif
567 #   if defined(_MSC_VER) && defined(_M_IA64)
568 #     define IA64
569 #     define MSWIN32    /* Really win64, but we don't treat 64-bit      */
570                         /* variants as a different platform.            */
571 #   endif
572 # endif
573 # if defined(__DJGPP__)
574 #   define I386
575 #   ifndef DJGPP
576 #     define DJGPP  /* MSDOS running the DJGPP port of GCC */
577 #   endif
578 #   define mach_type_known
579 # endif
580 # if defined(__CYGWIN32__) || defined(__CYGWIN__)
581 #   if defined(__LP64__)
582 #     define X86_64
583 #   else
584 #     define I386
585 #   endif
586 #   define CYGWIN32
587 #   define mach_type_known
588 # endif
589 # if defined(__INTERIX)
590 #   define I386
591 #   define INTERIX
592 #   define mach_type_known
593 # endif
594 # if defined(__MINGW32__) && !defined(mach_type_known)
595 #   define I386
596 #   define MSWIN32
597 #   define mach_type_known
598 # endif
599 # if defined(__BORLANDC__)
600 #   define I386
601 #   define MSWIN32
602 #   define mach_type_known
603 # endif
604 # if defined(_UTS) && !defined(mach_type_known)
605 #   define S370
606 #   define UTS4
607 #   define mach_type_known
608 # endif
609 # if defined(__pj__) && !defined(CPPCHECK)
610 #   error PicoJava no longer supported
611     /* The implementation had problems, and I haven't heard of users    */
612     /* in ages.  If you want it resurrected, let me know.               */
613 # endif
614 # if defined(__embedded__) && defined(PPC)
615 #   define POWERPC
616 #   define NOSYS
617 #   define mach_type_known
618 # endif
619
620 # if defined(__WATCOMC__) && defined(__386__)
621 #   define I386
622 #   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
623 #     if defined(__OS2__)
624 #       define OS2
625 #     else
626 #       if defined(__WINDOWS_386__) || defined(__NT__)
627 #         define MSWIN32
628 #       else
629 #         define DOS4GW
630 #       endif
631 #     endif
632 #   endif
633 #   define mach_type_known
634 # endif
635 # if defined(__s390__) && defined(LINUX)
636 #    define S390
637 #    define mach_type_known
638 # endif
639 # if defined(__GNU__)
640 #   if defined(__i386__)
641 /* The Debian Hurd running on generic PC */
642 #     define  HURD
643 #     define  I386
644 #     define  mach_type_known
645 #    endif
646 # endif
647 # if defined(__TANDEM)
648     /* Nonstop S-series */
649     /* FIXME: Should recognize Integrity series? */
650 #   define MIPS
651 #   define NONSTOP
652 #   define mach_type_known
653 # endif
654 # if defined(__hexagon__) && defined(LINUX)
655 #    define HEXAGON
656 #    define mach_type_known
657 # endif
658 # if defined(__tile__) && defined(LINUX)
659 #   ifdef __tilegx__
660 #     define TILEGX
661 #   else
662 #     define TILEPRO
663 #   endif
664 #   define mach_type_known
665 # endif
666 # if defined(__riscv) && defined(LINUX)
667 #   define RISCV
668 #   define mach_type_known
669 # endif
670
671 # if defined(SN_TARGET_PSP2)
672 #   define mach_type_known
673 # endif
674
675 # if defined(NN_PLATFORM_CTR)
676 #   define mach_type_known
677 # endif
678
679 # if defined(NN_BUILD_TARGET_PLATFORM_NX)
680 #   define NINTENDO_SWITCH
681 #   define mach_type_known
682 # endif
683
684 # if defined(SYMBIAN)
685 #   define mach_type_known
686 # endif
687
688 # if defined(__EMSCRIPTEN__)
689 #   define I386
690 #   define mach_type_known
691 # endif
692
693 /* Feel free to add more clauses here */
694
695 /* Or manually define the machine type here.  A machine type is         */
696 /* characterized by the architecture.  Some                             */
697 /* machine types are further subdivided by OS.                          */
698 /* Macros such as LINUX, FREEBSD, etc. distinguish them.                */
699 /* SYSV on an M68K actually means A/UX.                                 */
700 /* The distinction in these cases is usually the stack starting address */
701 # if !defined(mach_type_known) && !defined(CPPCHECK)
702 #   error The collector has not been ported to this machine/OS combination
703 # endif
704                     /* Mapping is: M68K       ==> Motorola 680X0        */
705                     /*             (NEXT, and SYSV (A/UX),              */
706                     /*             MACOS and AMIGA variants)            */
707                     /*             I386       ==> Intel 386             */
708                     /*              (SEQUENT, OS2, SCO, LINUX, NETBSD,  */
709                     /*               FREEBSD, THREE86BSD, MSWIN32,      */
710                     /*               BSDI, SOLARIS, NEXT and others)    */
711                     /*             NS32K      ==> Encore Multimax       */
712                     /*             MIPS       ==> R2000 through R14K    */
713                     /*                  (many variants)                 */
714                     /*             VAX        ==> DEC VAX               */
715                     /*                  (BSD, ULTRIX variants)          */
716                     /*             HP_PA      ==> HP9000/700 & /800     */
717                     /*                            HP/UX, LINUX          */
718                     /*             SPARC      ==> SPARC v7/v8/v9        */
719                     /*                  (SOLARIS, LINUX, DRSNX variants)        */
720                     /*             ALPHA      ==> DEC Alpha             */
721                     /*                  (OSF1 and LINUX variants)       */
722                     /*             M88K       ==> Motorola 88XX0        */
723                     /*                  (CX_UX and DGUX)                */
724                     /*             S370       ==> 370-like machine      */
725                     /*                  running Amdahl UTS4             */
726                     /*             S390       ==> 390-like machine      */
727                     /*                  running LINUX                   */
728                     /*             AARCH64    ==> ARM AArch64           */
729                     /*                  (LP64 and ILP32 variants)       */
730                     /*             ARM32      ==> Intel StrongARM       */
731                     /*             IA64       ==> Intel IPF             */
732                     /*                            (e.g. Itanium)        */
733                     /*                  (LINUX and HPUX)                */
734                     /*             SH         ==> Hitachi SuperH        */
735                     /*                  (LINUX & MSWINCE)               */
736                     /*             X86_64     ==> AMD x86-64            */
737                     /*             POWERPC    ==> IBM/Apple PowerPC     */
738                     /*                  (MACOS(<=9),DARWIN(incl.MACOSX),*/
739                     /*                   LINUX, NETBSD, AIX, NOSYS      */
740                     /*                   variants)                      */
741                     /*                  Handles 32 and 64-bit variants. */
742                     /*             CRIS       ==> Axis Etrax            */
743                     /*             M32R       ==> Renesas M32R          */
744                     /*             HEXAGON    ==> Qualcomm Hexagon      */
745                     /*             TILEPRO    ==> Tilera TILEPro        */
746                     /*             TILEGX     ==> Tilera TILE-Gx        */
747
748
749 /*
750  * For each architecture and OS, the following need to be defined:
751  *
752  * CPP_WORDSZ is a simple integer constant representing the word size.
753  * in bits.  We assume byte addressability, where a byte has 8 bits.
754  * We also assume CPP_WORDSZ is either 32 or 64.
755  * (We care about the length of pointers, not hardware
756  * bus widths.  Thus a 64 bit processor with a C compiler that uses
757  * 32 bit pointers should use CPP_WORDSZ of 32, not 64. Default is 32.)
758  *
759  * MACH_TYPE is a string representation of the machine type.
760  * OS_TYPE is analogous for the OS.
761  *
762  * ALIGNMENT is the largest N, such that
763  * all pointer are guaranteed to be aligned on N byte boundaries.
764  * defining it to be 1 will always work, but perform poorly.
765  *
766  * DATASTART is the beginning of the data segment.
767  * On some platforms SEARCH_FOR_DATA_START is defined.
768  * The latter will cause GC_data_start to
769  * be set to an address determined by accessing data backwards from _end
770  * until an unmapped page is found.  DATASTART will be defined to be
771  * GC_data_start.
772  * On UNIX-like systems, the collector will scan the area between DATASTART
773  * and DATAEND for root pointers.
774  *
775  * DATAEND, if not "end", where "end" is defined as "extern int end[]".
776  * RTH suggests gaining access to linker script synth'd values with
777  * this idiom instead of "&end", where "end" is defined as "extern int end".
778  * Otherwise, "GCC will assume these are in .sdata/.sbss" and it will, e.g.,
779  * cause failures on alpha*-*-* with -msmall-data or -fpic or mips-*-*
780  * without any special options.
781  *
782  * STACKBOTTOM is the cold end of the stack, which is usually the
783  * highest address in the stack.
784  * Under PCR or OS/2, we have other ways of finding thread stacks.
785  * For each machine, the following should:
786  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
787  * 2) define exactly one of
788  *      STACKBOTTOM (should be defined to be an expression)
789  *      LINUX_STACKBOTTOM
790  *      HEURISTIC1
791  *      HEURISTIC2
792  * If STACKBOTTOM is defined, then its value will be used directly (as the
793  * stack bottom).  If LINUX_STACKBOTTOM is defined, then it will be determined
794  * with a method appropriate for most Linux systems.  Currently we look
795  * first for __libc_stack_end (currently only if USE_LIBC_PRIVATES is
796  * defined), and if that fails read it from /proc.  (If USE_LIBC_PRIVATES
797  * is not defined and NO_PROC_STAT is defined, we revert to HEURISTIC2.)
798  * If either of the last two macros are defined, then STACKBOTTOM is computed
799  * during collector startup using one of the following two heuristics:
800  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
801  *              the next multiple of STACK_GRAN.
802  * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly
803  *              in small steps (decrement if STACK_GROWS_UP), and read the value
804  *              at each location.  Remember the value when the first
805  *              Segmentation violation or Bus error is signaled.  Round that
806  *              to the nearest plausible page boundary, and use that instead
807  *              of STACKBOTTOM.
808  *
809  * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines,
810  * the value of environ is a pointer that can serve as STACKBOTTOM.
811  * I expect that HEURISTIC2 can be replaced by this approach, which
812  * interferes far less with debugging.  However it has the disadvantage
813  * that it's confused by a putenv call before the collector is initialized.
814  * This could be dealt with by intercepting putenv ...
815  *
816  * If no expression for STACKBOTTOM can be found, and neither of the above
817  * heuristics are usable, the collector can still be used with all of the above
818  * undefined, provided one of the following is done:
819  * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
820  *    without reference to STACKBOTTOM.  This is appropriate for use in
821  *    conjunction with thread packages, since there will be multiple stacks.
822  *    (Allocating thread stacks in the heap, and treating them as ordinary
823  *    heap data objects is also possible as a last resort.  However, this is
824  *    likely to introduce significant amounts of excess storage retention
825  *    unless the dead parts of the thread stacks are periodically cleared.)
826  * 2) Client code may set GC_stackbottom before calling any GC_ routines.
827  *    If the author of the client code controls the main program, this is
828  *    easily accomplished by introducing a new main program, setting
829  *    GC_stackbottom to the address of a local variable, and then calling
830  *    the original main program.  The new main program would read something
831  *    like (provided real_main() is not inlined by the compiler):
832  *
833  *              #include "gc.h"
834  *
835  *              main(argc, argv, envp)
836  *              int argc;
837  *              char **argv, **envp;
838  *              {
839  *                  volatile int dummy;
840  *
841  *                  GC_stackbottom = (ptr_t)(&dummy);
842  *                  return(real_main(argc, argv, envp));
843  *              }
844  *
845  *
846  * Each architecture may also define the style of virtual dirty bit
847  * implementation to be used:
848  *   MPROTECT_VDB: Write protect the heap and catch faults.
849  *   GWW_VDB: Use win32 GetWriteWatch primitive.
850  *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
851  *
852  * The first and second one may be combined, in which case a runtime
853  * selection will be made, based on GetWriteWatch availability.
854  *
855  * An architecture may define DYNAMIC_LOADING if dyn_load.c
856  * defined GC_register_dynamic_libraries() for the architecture.
857  *
858  * An architecture may define PREFETCH(x) to preload the cache with *x.
859  * This defaults to GCC built-in operation (or a no-op for other compilers).
860  *
861  * GC_PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
862  *
863  * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
864  * clear the two words at GC_malloc-aligned address x.  By default,
865  * word stores of 0 are used instead.
866  *
867  * HEAP_START may be defined as the initial address hint for mmap-based
868  * allocation.
869  */
870
871 /* If available, we can use __builtin_unwind_init() to push the     */
872 /* relevant registers onto the stack.                               */
873 # if GC_GNUC_PREREQ(2, 8) \
874      && !defined(__INTEL_COMPILER) && !defined(__PATHCC__) \
875      && !defined(__FUJITSU) /* for FX10 system */ \
876      && !(defined(POWERPC) && defined(DARWIN)) /* for MacOS X 10.3.9 */ \
877      && !defined(RTEMS) \
878      && !defined(__ARMCC_VERSION) /* does not exist in armcc gnu emu */ \
879      && !defined(__clang__) /* since no-op in clang (3.0) */
880 #   define HAVE_BUILTIN_UNWIND_INIT
881 # endif
882
883 # ifdef SYMBIAN
884 #   define MACH_TYPE "SYMBIAN"
885 #   define OS_TYPE "SYMBIAN"
886 #   define CPP_WORDSZ 32
887 #   define ALIGNMENT 4
888 #   define DATASTART (ptr_t)ALIGNMENT /* cannot be null */
889 #   define DATAEND (ptr_t)ALIGNMENT
890 # endif
891
892 # define STACK_GRAN 0x1000000
893
894 # ifdef M68K
895 #   define MACH_TYPE "M68K"
896 #   define ALIGNMENT 2
897 #   ifdef OPENBSD
898 #       define OS_TYPE "OPENBSD"
899 #       define HEURISTIC2
900 #       ifdef __ELF__
901           extern ptr_t GC_data_start;
902 #         define DATASTART GC_data_start
903 #         define DYNAMIC_LOADING
904 #       else
905           extern char etext[];
906 #         define DATASTART ((ptr_t)(etext))
907 #       endif
908 #   endif
909 #   ifdef NETBSD
910 #       define OS_TYPE "NETBSD"
911 #       define HEURISTIC2
912 #       ifdef __ELF__
913           extern ptr_t GC_data_start;
914 #         define DATASTART GC_data_start
915 #         define DYNAMIC_LOADING
916 #       else
917           extern char etext[];
918 #         define DATASTART ((ptr_t)(etext))
919 #       endif
920 #   endif
921 #   ifdef LINUX
922 #       define OS_TYPE "LINUX"
923 #       define LINUX_STACKBOTTOM
924 #       if !defined(REDIRECT_MALLOC)
925 #         define MPROTECT_VDB
926 #       endif
927 #       ifdef __ELF__
928 #         define DYNAMIC_LOADING
929           EXTERN_C_END
930 #         include <features.h>
931           EXTERN_C_BEGIN
932 #         if defined(__GLIBC__) && __GLIBC__ >= 2
933 #           define SEARCH_FOR_DATA_START
934 #         else /* !GLIBC2 */
935             extern char **__environ;
936 #           define DATASTART ((ptr_t)(&__environ))
937                              /* hideous kludge: __environ is the first */
938                              /* word in crt0.o, and delimits the start */
939                              /* of the data segment, no matter which   */
940                              /* ld options were passed through.        */
941                              /* We could use _etext instead, but that  */
942                              /* would include .rodata, which may       */
943                              /* contain large read-only data tables    */
944                              /* that we'd rather not scan.             */
945 #         endif /* !GLIBC2 */
946           extern int _end[];
947 #         define DATAEND ((ptr_t)(_end))
948 #       else
949           extern int etext[];
950 #         define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
951 #       endif
952 #   endif
953 #   ifdef AMIGA
954 #       define OS_TYPE "AMIGA"
955                 /* STACKBOTTOM and DATASTART handled specially  */
956                 /* in os_dep.c                                  */
957 #       define DATAEND  /* not needed */
958 #       define GETPAGESIZE() 4096
959 #   endif
960 #   ifdef MACOS
961 #     ifndef __LOWMEM__
962         EXTERN_C_END
963 #       include <LowMem.h>
964         EXTERN_C_BEGIN
965 #     endif
966 #     define OS_TYPE "MACOS"
967                 /* see os_dep.c for details of global data segments. */
968 #     define STACKBOTTOM ((ptr_t)LMGetCurStackBase())
969 #     define DATAEND    /* not needed */
970 #     define GETPAGESIZE() 4096
971 #   endif
972 #   ifdef NEXT
973 #       define OS_TYPE "NEXT"
974 #       define DATASTART ((ptr_t)get_etext())
975 #       define DATASTART_IS_FUNC
976 #       define STACKBOTTOM ((ptr_t)0x4000000)
977 #       define DATAEND  /* not needed */
978 #   endif
979 # endif
980
981 # ifdef POWERPC
982 #   define MACH_TYPE "POWERPC"
983 #   ifdef MACOS
984 #     define ALIGNMENT 2  /* Still necessary?  Could it be 4?   */
985 #     ifndef __LOWMEM__
986         EXTERN_C_END
987 #       include <LowMem.h>
988         EXTERN_C_BEGIN
989 #     endif
990 #     define OS_TYPE "MACOS"
991                         /* see os_dep.c for details of global data segments. */
992 #     define STACKBOTTOM ((ptr_t)LMGetCurStackBase())
993 #     define DATAEND  /* not needed */
994 #   endif
995 #   ifdef LINUX
996 #     if defined(__powerpc64__)
997 #       define ALIGNMENT 8
998 #       define CPP_WORDSZ 64
999 #       ifndef HBLKSIZE
1000 #         define HBLKSIZE 4096
1001 #       endif
1002 #     else
1003 #       define ALIGNMENT 4
1004 #     endif
1005 #     define OS_TYPE "LINUX"
1006       /* HEURISTIC1 has been reliably reported to fail for a 32-bit     */
1007       /* executable on a 64 bit kernel.                                 */
1008 #     if defined(__bg__)
1009         /* The Linux Compute Node Kernel (used on BlueGene systems)     */
1010         /* does not support LINUX_STACKBOTTOM way.                      */
1011 #       define HEURISTIC2
1012 #       define NO_PTHREAD_GETATTR_NP
1013 #     else
1014 #       define LINUX_STACKBOTTOM
1015 #     endif
1016 #     define DYNAMIC_LOADING
1017 #     define SEARCH_FOR_DATA_START
1018       extern int _end[];
1019 #     define DATAEND ((ptr_t)(_end))
1020 #   endif
1021 #   ifdef DARWIN
1022 #     define OS_TYPE "DARWIN"
1023 #     define DYNAMIC_LOADING
1024 #     if defined(__ppc64__)
1025 #       define ALIGNMENT 8
1026 #       define CPP_WORDSZ 64
1027 #       define STACKBOTTOM ((ptr_t)0x7fff5fc00000)
1028 #       define CACHE_LINE_SIZE 64
1029 #       ifndef HBLKSIZE
1030 #         define HBLKSIZE 4096
1031 #       endif
1032 #     else
1033 #       define ALIGNMENT 4
1034 #       define STACKBOTTOM ((ptr_t)0xc0000000)
1035 #     endif
1036       /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
1037       /* These aren't used when dyld support is enabled (it is by default). */
1038 #     define DATASTART ((ptr_t)get_etext())
1039 #     define DATAEND   ((ptr_t)get_end())
1040 #     define USE_MMAP_ANON
1041 #     define MPROTECT_VDB
1042       EXTERN_C_END
1043 #     include <unistd.h>
1044       EXTERN_C_BEGIN
1045 #     define GETPAGESIZE() (unsigned)getpagesize()
1046 #     if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
1047         /* The performance impact of prefetches is untested */
1048 #       define PREFETCH(x) \
1049           __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
1050 #       define GC_PREFETCH_FOR_WRITE(x) \
1051           __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
1052 #     endif
1053       /* There seems to be some issues with trylock hanging on darwin.  */
1054       /* This should be looked into some more.                          */
1055 #     define NO_PTHREAD_TRYLOCK
1056 #   endif
1057 #   ifdef OPENBSD
1058 #     define OS_TYPE "OPENBSD"
1059 #     define ALIGNMENT 4
1060 #     ifndef GC_OPENBSD_THREADS
1061         EXTERN_C_END
1062 #       include <sys/param.h>
1063 #       include <uvm/uvm_extern.h>
1064         EXTERN_C_BEGIN
1065         /* USRSTACK is defined in <machine/vmparam.h> but that is       */
1066         /* protected by _KERNEL in <uvm/uvm_param.h> file.              */
1067 #       ifdef USRSTACK
1068 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1069 #       else
1070 #         define HEURISTIC2
1071 #       endif
1072 #     endif
1073       extern int __data_start[];
1074 #     define DATASTART ((ptr_t)__data_start)
1075       extern int _end[];
1076 #     define DATAEND ((ptr_t)(&_end))
1077 #     define DYNAMIC_LOADING
1078 #   endif
1079 #   ifdef FREEBSD
1080 #       if defined(__powerpc64__)
1081 #           define ALIGNMENT 8
1082 #           define CPP_WORDSZ 64
1083 #           ifndef HBLKSIZE
1084 #               define HBLKSIZE 4096
1085 #           endif
1086 #       else
1087 #           define ALIGNMENT 4
1088 #       endif
1089 #       define OS_TYPE "FREEBSD"
1090 #       ifndef GC_FREEBSD_THREADS
1091 #           define MPROTECT_VDB
1092 #       endif
1093 #       define SIG_SUSPEND SIGUSR1
1094 #       define SIG_THR_RESTART SIGUSR2
1095 #       define FREEBSD_STACKBOTTOM
1096 #       define DYNAMIC_LOADING
1097         extern char etext[];
1098 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1099 #       define DATASTART_USES_BSDGETDATASTART
1100 #   endif
1101 #   ifdef NETBSD
1102 #     define ALIGNMENT 4
1103 #     define OS_TYPE "NETBSD"
1104 #     define HEURISTIC2
1105       extern ptr_t GC_data_start;
1106 #     define DATASTART GC_data_start
1107 #     define DYNAMIC_LOADING
1108 #   endif
1109 #   ifdef SN_TARGET_PS3
1110 #     define NO_GETENV
1111 #     define CPP_WORDSZ 32
1112 #     define ALIGNMENT 4
1113       extern int _end[];
1114       extern int __bss_start;
1115 #     define DATASTART ((ptr_t)(__bss_start))
1116 #     define DATAEND ((ptr_t)(_end))
1117 #     define STACKBOTTOM ((ptr_t)ps3_get_stack_bottom())
1118 #     define NO_PTHREAD_TRYLOCK
1119                 /* Current GC LOCK() implementation for PS3 explicitly  */
1120                 /* use pthread_mutex_lock for some reason.              */
1121 #   endif
1122 #   ifdef AIX
1123 #     define OS_TYPE "AIX"
1124 #     undef ALIGNMENT /* in case it's defined   */
1125 #     undef IA64
1126       /* DOB: some AIX installs stupidly define IA64 in */
1127       /* /usr/include/sys/systemcfg.h                   */
1128 #     ifdef __64BIT__
1129 #       define ALIGNMENT 8
1130 #       define CPP_WORDSZ 64
1131 #       define STACKBOTTOM ((ptr_t)0x1000000000000000)
1132 #     else
1133 #       define ALIGNMENT 4
1134 #       define CPP_WORDSZ 32
1135 #       define STACKBOTTOM ((ptr_t)((ulong)&errno))
1136 #     endif
1137 #     define USE_MMAP_ANON
1138         /* From AIX linker man page:
1139         _text Specifies the first location of the program.
1140         _etext Specifies the first location after the program.
1141         _data Specifies the first location of the data.
1142         _edata Specifies the first location after the initialized data
1143         _end or end Specifies the first location after all data.
1144         */
1145       extern int _data[], _end[];
1146 #     define DATASTART ((ptr_t)((ulong)_data))
1147 #     define DATAEND ((ptr_t)((ulong)_end))
1148       extern int errno;
1149 #     define DYNAMIC_LOADING
1150         /* For really old versions of AIX, this may have to be removed. */
1151 #   endif
1152
1153 #   ifdef NOSYS
1154 #     define ALIGNMENT 4
1155 #     define OS_TYPE "NOSYS"
1156       extern void __end[], __dso_handle[];
1157 #     define DATASTART ((ptr_t)__dso_handle) /* OK, that's ugly.    */
1158 #     define DATAEND ((ptr_t)(__end))
1159         /* Stack starts at 0xE0000000 for the simulator.  */
1160 #     undef STACK_GRAN
1161 #     define STACK_GRAN 0x10000000
1162 #     define HEURISTIC1
1163 #   endif
1164 # endif
1165
1166 # ifdef NACL
1167 #   define OS_TYPE "NACL"
1168 #   if defined(__GLIBC__)
1169 #     define DYNAMIC_LOADING
1170 #   endif
1171 #   define DATASTART ((ptr_t)0x10020000)
1172     extern int _end[];
1173 #   define DATAEND ((ptr_t)_end)
1174 #   undef STACK_GRAN
1175 #   define STACK_GRAN 0x10000
1176 #   define HEURISTIC1
1177 #   define NO_PTHREAD_GETATTR_NP
1178 #   define USE_MMAP_ANON
1179 #   define GETPAGESIZE() 65536
1180 #   define MAX_NACL_GC_THREADS 1024
1181 # endif
1182
1183 # ifdef VAX
1184 #   define MACH_TYPE "VAX"
1185 #   define ALIGNMENT 4  /* Pointers are longword aligned by 4.2 C compiler */
1186     extern char etext[];
1187 #   define DATASTART ((ptr_t)(etext))
1188 #   ifdef BSD
1189 #       define OS_TYPE "BSD"
1190 #       define HEURISTIC1
1191                         /* HEURISTIC2 may be OK, but it's hard to test. */
1192 #   endif
1193 #   ifdef ULTRIX
1194 #       define OS_TYPE "ULTRIX"
1195 #       define STACKBOTTOM ((ptr_t)0x7fffc800)
1196 #   endif
1197 # endif
1198
1199 # ifdef SPARC
1200 #   define MACH_TYPE "SPARC"
1201 #   if defined(__arch64__) || defined(__sparcv9)
1202 #     define ALIGNMENT 8
1203 #     define CPP_WORDSZ 64
1204 #     define ELF_CLASS ELFCLASS64
1205 #   else
1206 #     define ALIGNMENT 4        /* Required by hardware */
1207 #     define CPP_WORDSZ 32
1208 #   endif
1209     /* Don't define USE_ASM_PUSH_REGS.  We do use an asm helper, but    */
1210     /* not to push the registers on the mark stack.                     */
1211 #   ifdef SOLARIS
1212 #       define OS_TYPE "SOLARIS"
1213         extern int _etext[];
1214         extern int _end[];
1215         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1216 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1217 #       define DATASTART_IS_FUNC
1218 #       define DATAEND ((ptr_t)(_end))
1219 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1220 #         define USE_MMAP 1
1221             /* Otherwise we now use calloc.  Mmap may result in the     */
1222             /* heap interleaved with thread stacks, which can result in */
1223             /* excessive blacklisting.  Sbrk is unusable since it       */
1224             /* doesn't interact correctly with the system malloc.       */
1225 #       endif
1226 #       ifdef USE_MMAP
1227 #         define HEAP_START (ptr_t)0x40000000
1228 #       else
1229 #         define HEAP_START DATAEND
1230 #       endif
1231 #       define PROC_VDB
1232         /* HEURISTIC1 reportedly no longer works under 2.7.             */
1233         /* HEURISTIC2 probably works, but this appears to be preferable.*/
1234         /* Apparently USRSTACK is defined to be USERLIMIT, but in some  */
1235         /* installations that's undefined.  We work around this with a  */
1236         /* gross hack:                                                  */
1237         EXTERN_C_END
1238 #       include <sys/vmparam.h>
1239 #       include <unistd.h>
1240         EXTERN_C_BEGIN
1241 #       ifdef USERLIMIT
1242           /* This should work everywhere, but doesn't.  */
1243 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1244 #       else
1245 #         define HEURISTIC2
1246 #       endif
1247 #       define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
1248                 /* getpagesize() appeared to be missing from at least one */
1249                 /* Solaris 5.4 installation.  Weird.                      */
1250 #       define DYNAMIC_LOADING
1251 #   endif
1252 #   ifdef DRSNX
1253 #       define OS_TYPE "DRSNX"
1254         extern int etext[];
1255         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1256 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
1257 #       define DATASTART_IS_FUNC
1258 #       define MPROTECT_VDB
1259 #       define STACKBOTTOM ((ptr_t)0xdfff0000)
1260 #       define DYNAMIC_LOADING
1261 #   endif
1262 #   ifdef LINUX
1263 #     define OS_TYPE "LINUX"
1264 #     ifdef __ELF__
1265 #       define DYNAMIC_LOADING
1266 #     elif !defined(CPPCHECK)
1267 #       error Linux SPARC a.out not supported
1268 #     endif
1269       extern int _end[];
1270       extern int _etext[];
1271 #     define DATAEND ((ptr_t)(_end))
1272 #     define SVR4
1273       ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1274 #     ifdef __arch64__
1275 #       define DATASTART GC_SysVGetDataStart(0x100000, (ptr_t)_etext)
1276 #     else
1277 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1278 #     endif
1279 #     define DATASTART_IS_FUNC
1280 #     define LINUX_STACKBOTTOM
1281 #   endif
1282 #   ifdef OPENBSD
1283 #     define OS_TYPE "OPENBSD"
1284 #     ifndef GC_OPENBSD_THREADS
1285         EXTERN_C_END
1286 #       include <sys/param.h>
1287 #       include <uvm/uvm_extern.h>
1288         EXTERN_C_BEGIN
1289 #       ifdef USRSTACK
1290 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1291 #       else
1292 #         define HEURISTIC2
1293 #       endif
1294 #     endif
1295       extern int __data_start[];
1296 #     define DATASTART ((ptr_t)__data_start)
1297       extern int _end[];
1298 #     define DATAEND ((ptr_t)(&_end))
1299 #     define DYNAMIC_LOADING
1300 #   endif
1301 #   ifdef NETBSD
1302 #     define OS_TYPE "NETBSD"
1303 #     define HEURISTIC2
1304 #     ifdef __ELF__
1305         extern ptr_t GC_data_start;
1306 #       define DATASTART GC_data_start
1307 #       define DYNAMIC_LOADING
1308 #     else
1309         extern char etext[];
1310 #       define DATASTART ((ptr_t)(etext))
1311 #     endif
1312 #   endif
1313 #   ifdef FREEBSD
1314 #       define OS_TYPE "FREEBSD"
1315 #       define SIG_SUSPEND SIGUSR1
1316 #       define SIG_THR_RESTART SIGUSR2
1317 #       define FREEBSD_STACKBOTTOM
1318 #       define DYNAMIC_LOADING
1319         extern char etext[];
1320         extern char edata[];
1321 #       if !defined(CPPCHECK)
1322           extern char end[];
1323 #       endif
1324 #       define NEED_FIND_LIMIT
1325 #       define DATASTART ((ptr_t)(&etext))
1326         void * GC_find_limit(void *, int);
1327 #       define DATAEND (ptr_t)GC_find_limit(DATASTART, TRUE)
1328 #       define DATAEND_IS_FUNC
1329 #       define GC_HAVE_DATAREGION2
1330 #       define DATASTART2 ((ptr_t)(&edata))
1331 #       define DATAEND2 ((ptr_t)(&end))
1332 #   endif
1333 # endif
1334
1335 # ifdef I386
1336 #   define MACH_TYPE "I386"
1337 #   if (defined(__LP64__) || defined(_WIN64)) && !defined(CPPCHECK)
1338 #     error This should be handled as X86_64
1339 #   else
1340 #     define CPP_WORDSZ 32
1341 #     define ALIGNMENT 4
1342                         /* Appears to hold for all "32 bit" compilers   */
1343                         /* except Borland.  The -a4 option fixes        */
1344                         /* Borland.  For Watcom the option is -zp4.     */
1345 #   endif
1346 #   ifdef SEQUENT
1347 #       define OS_TYPE "SEQUENT"
1348         extern int etext[];
1349 #       define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1350 #       define STACKBOTTOM ((ptr_t)0x3ffff000)
1351 #   endif
1352 #   if defined(__EMSCRIPTEN__)
1353 #     define OS_TYPE "EMSCRIPTEN"
1354 #     define DATASTART (ptr_t)ALIGNMENT
1355 #     define DATAEND (ptr_t)ALIGNMENT
1356       /* Since JavaScript/asm.js/WebAssembly is not able to access the  */
1357       /* function call stack or the local data stack, it's not possible */
1358       /* for GC to perform its stack walking operation to find roots on */
1359       /* the stack.  To work around that, the clients generally only do */
1360       /* BDWGC steps when the stack is empty so it is known that there  */
1361       /* are no objects that would be found on the stack, and BDWGC is  */
1362       /* compiled with stack walking disabled.                          */
1363 #     define STACK_NOT_SCANNED
1364 #   endif
1365 #   if defined(__QNX__)
1366 #     define OS_TYPE "QNX"
1367 #     define SA_RESTART 0
1368 #     define HEURISTIC1
1369       extern char etext[];
1370       extern int _end[];
1371 #     define DATASTART ((ptr_t)etext)
1372 #     define DATAEND ((ptr_t)_end)
1373 #   endif
1374 #   ifdef HAIKU
1375 #     define OS_TYPE "HAIKU"
1376       EXTERN_C_END
1377 #     include <OS.h>
1378       EXTERN_C_BEGIN
1379 #     define GETPAGESIZE() (unsigned)B_PAGE_SIZE
1380       extern int etext[];
1381 #     define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1382 #     define DYNAMIC_LOADING
1383 #     define MPROTECT_VDB
1384 #   endif
1385 #   ifdef SOLARIS
1386 #       define OS_TYPE "SOLARIS"
1387         extern int _etext[], _end[];
1388         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1389 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
1390 #       define DATASTART_IS_FUNC
1391 #       define DATAEND ((ptr_t)(_end))
1392         /* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,   */
1393         /* but reportedly breaks under 2.8.  It appears that the stack  */
1394         /* base is a property of the executable, so this should not     */
1395         /* break old executables.                                       */
1396         /* HEURISTIC2 probably works, but this appears to be preferable.*/
1397         /* Apparently USRSTACK is defined to be USERLIMIT, but in some  */
1398         /* installations that's undefined.  We work around this with a  */
1399         /* gross hack:                                                  */
1400         EXTERN_C_END
1401 #       include <sys/vmparam.h>
1402         EXTERN_C_BEGIN
1403 #       ifdef USERLIMIT
1404           /* This should work everywhere, but doesn't.  */
1405 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1406 #       else
1407 #         define HEURISTIC2
1408 #       endif
1409 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1410 /* It appears to be fixed in 2.8 and 2.9.                               */
1411 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1412 #         define PROC_VDB
1413 #       endif
1414 #       ifndef GC_THREADS
1415 #         define MPROTECT_VDB
1416 #       endif
1417 #       define DYNAMIC_LOADING
1418 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1419 #         define USE_MMAP 1
1420             /* Otherwise we now use calloc.  Mmap may result in the     */
1421             /* heap interleaved with thread stacks, which can result in */
1422             /* excessive blacklisting.  Sbrk is unusable since it       */
1423             /* doesn't interact correctly with the system malloc.       */
1424 #       endif
1425 #       ifdef USE_MMAP
1426 #         define HEAP_START (ptr_t)0x40000000
1427 #       else
1428 #         define HEAP_START DATAEND
1429 #       endif
1430 #   endif
1431 #   ifdef SCO
1432 #       define OS_TYPE "SCO"
1433         extern int etext[];
1434 #       define DATASTART ((ptr_t)((((word)(etext)) + 0x3fffff) & ~0x3fffff) \
1435                                  + ((word)(etext) & 0xfff))
1436 #       define STACKBOTTOM ((ptr_t)0x7ffffffc)
1437 #   endif
1438 #   ifdef SCO_ELF
1439 #       define OS_TYPE "SCO_ELF"
1440         extern int etext[];
1441 #       define DATASTART ((ptr_t)(etext))
1442 #       define STACKBOTTOM ((ptr_t)0x08048000)
1443 #       define DYNAMIC_LOADING
1444 #       define ELF_CLASS ELFCLASS32
1445 #   endif
1446 #   ifdef DGUX
1447 #       define OS_TYPE "DGUX"
1448         extern int _etext, _end;
1449         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1450 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)(&_etext))
1451 #       define DATASTART_IS_FUNC
1452 #       define DATAEND ((ptr_t)(&_end))
1453 #       define STACK_GROWS_DOWN
1454 #       define HEURISTIC2
1455         EXTERN_C_END
1456 #       include <unistd.h>
1457         EXTERN_C_BEGIN
1458 #       define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
1459 #       define DYNAMIC_LOADING
1460 #       ifndef USE_MMAP
1461 #         define USE_MMAP 1
1462 #       endif
1463 #       define MAP_FAILED (void *) ((word)-1)
1464 #       define HEAP_START (ptr_t)0x40000000
1465 #   endif /* DGUX */
1466 #   ifdef LINUX
1467 #       define OS_TYPE "LINUX"
1468 #       define LINUX_STACKBOTTOM
1469 #       if !defined(REDIRECT_MALLOC)
1470 #           define MPROTECT_VDB
1471 #       else
1472             /* We seem to get random errors in incremental mode,        */
1473             /* possibly because Linux threads is itself a malloc client */
1474             /* and can't deal with the signals.                         */
1475 #       endif
1476 #       define HEAP_START (ptr_t)0x1000
1477                 /* This encourages mmap to give us low addresses,       */
1478                 /* thus allowing the heap to grow to ~3 GB.             */
1479 #       ifdef __ELF__
1480 #           define DYNAMIC_LOADING
1481             EXTERN_C_END
1482 #           include <features.h>
1483             EXTERN_C_BEGIN
1484 #            if defined(__GLIBC__) && __GLIBC__ >= 2 \
1485                 || defined(HOST_ANDROID) || defined(HOST_TIZEN)
1486 #                define SEARCH_FOR_DATA_START
1487 #            else
1488                  extern char **__environ;
1489 #                define DATASTART ((ptr_t)(&__environ))
1490                               /* hideous kludge: __environ is the first */
1491                               /* word in crt0.o, and delimits the start */
1492                               /* of the data segment, no matter which   */
1493                               /* ld options were passed through.        */
1494                               /* We could use _etext instead, but that  */
1495                               /* would include .rodata, which may       */
1496                               /* contain large read-only data tables    */
1497                               /* that we'd rather not scan.             */
1498 #            endif
1499              extern int _end[];
1500 #            define DATAEND ((ptr_t)(_end))
1501 #            if !defined(GC_NO_SIGSETJMP) && (defined(HOST_TIZEN) \
1502                     || (defined(HOST_ANDROID) \
1503                         && !(GC_GNUC_PREREQ(4, 8) || GC_CLANG_PREREQ(3, 2) \
1504                              || __ANDROID_API__ >= 18)))
1505                /* Older Android NDK releases lack sigsetjmp in x86 libc */
1506                /* (setjmp is used instead to find data_start).  The bug */
1507                /* is fixed in Android NDK r8e (so, ok to use sigsetjmp  */
1508                /* if gcc4.8+, clang3.2+ or Android API level 18+).      */
1509 #              define GC_NO_SIGSETJMP 1
1510 #            endif
1511 #       else
1512              extern int etext[];
1513 #            define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1514 #       endif
1515 #       ifdef USE_I686_PREFETCH
1516 #         define PREFETCH(x) \
1517             __asm__ __volatile__ ("prefetchnta %0" : : "m"(*(char *)(x)))
1518             /* Empirically prefetcht0 is much more effective at reducing     */
1519             /* cache miss stalls for the targeted load instructions.  But it */
1520             /* seems to interfere enough with other cache traffic that the   */
1521             /* net result is worse than prefetchnta.                         */
1522 #         ifdef FORCE_WRITE_PREFETCH
1523             /* Using prefetches for write seems to have a slight negative    */
1524             /* impact on performance, at least for a PIII/500.               */
1525 #           define GC_PREFETCH_FOR_WRITE(x) \
1526               __asm__ __volatile__ ("prefetcht0 %0" : : "m"(*(char *)(x)))
1527 #         else
1528 #           define GC_NO_PREFETCH_FOR_WRITE
1529 #         endif
1530 #       elif defined(USE_3DNOW_PREFETCH)
1531 #         define PREFETCH(x) \
1532             __asm__ __volatile__ ("prefetch %0" : : "m"(*(char *)(x)))
1533 #         define GC_PREFETCH_FOR_WRITE(x) \
1534             __asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
1535 #       endif
1536 #       if defined(__GLIBC__) && !defined(__UCLIBC__)
1537           /* Workaround lock elision implementation for some glibc.     */
1538 #         define GLIBC_2_19_TSX_BUG
1539           EXTERN_C_END
1540 #         include <gnu/libc-version.h> /* for gnu_get_libc_version() */
1541           EXTERN_C_BEGIN
1542 #       endif
1543 #   endif
1544 #   ifdef CYGWIN32
1545 #       define OS_TYPE "CYGWIN32"
1546 #       define WOW64_THREAD_CONTEXT_WORKAROUND
1547 #       define DATASTART ((ptr_t)GC_DATASTART)  /* From gc.h */
1548 #       define DATAEND   ((ptr_t)GC_DATAEND)
1549 #       ifdef USE_WINALLOC
1550 #         define GWW_VDB
1551 #       else
1552 #         /* MPROTECT_VDB does not work, it leads to a spurious exit.   */
1553 #         ifdef USE_MMAP
1554 #           define NEED_FIND_LIMIT
1555 #           define USE_MMAP_ANON
1556 #         endif
1557 #       endif
1558 #   endif
1559 #   ifdef INTERIX
1560 #     define OS_TYPE "INTERIX"
1561       extern int _data_start__[];
1562       extern int _bss_end__[];
1563 #     define DATASTART ((ptr_t)_data_start__)
1564 #     define DATAEND   ((ptr_t)_bss_end__)
1565 #     define STACKBOTTOM ({ ptr_t rv; \
1566                             __asm__ __volatile__ ("movl %%fs:4, %%eax" \
1567                                                   : "=a" (rv)); \
1568                             rv; })
1569 #     define USE_MMAP_ANON
1570 #   endif
1571 #   ifdef OS2
1572 #       define OS_TYPE "OS2"
1573                 /* STACKBOTTOM and DATASTART are handled specially in   */
1574                 /* os_dep.c. OS2 actually has the right                 */
1575                 /* system call!                                         */
1576 #       define DATAEND  /* not needed */
1577 #   endif
1578 #   ifdef MSWIN32
1579 #       define OS_TYPE "MSWIN32"
1580 #       define WOW64_THREAD_CONTEXT_WORKAROUND
1581                 /* STACKBOTTOM and DATASTART are handled specially in   */
1582                 /* os_dep.c.                                            */
1583 #       define MPROTECT_VDB
1584 #       define GWW_VDB
1585 #       define DATAEND  /* not needed */
1586 #   endif
1587 #   ifdef MSWINCE
1588 #       define OS_TYPE "MSWINCE"
1589 #       define DATAEND  /* not needed */
1590 #   endif
1591 #   ifdef DJGPP
1592 #       define OS_TYPE "DJGPP"
1593         EXTERN_C_END
1594 #       include "stubinfo.h"
1595         EXTERN_C_BEGIN
1596         extern int etext[];
1597         extern int _stklen;
1598         extern int __djgpp_stack_limit;
1599 #       define DATASTART ((ptr_t)((((word)(etext)) + 0x1ff) & ~0x1ff))
1600 /* #define STACKBOTTOM ((ptr_t)((word)_stubinfo+_stubinfo->size+_stklen)) */
1601 #       define STACKBOTTOM ((ptr_t)((word)__djgpp_stack_limit + _stklen))
1602                 /* This may not be right.  */
1603 #   endif
1604 #   ifdef OPENBSD
1605 #       define OS_TYPE "OPENBSD"
1606 #       ifndef GC_OPENBSD_THREADS
1607           EXTERN_C_END
1608 #         include <sys/param.h>
1609 #         include <uvm/uvm_extern.h>
1610           EXTERN_C_BEGIN
1611 #         ifdef USRSTACK
1612 #           define STACKBOTTOM ((ptr_t)USRSTACK)
1613 #         else
1614 #           define HEURISTIC2
1615 #         endif
1616 #       endif
1617         extern int __data_start[];
1618 #       define DATASTART ((ptr_t)__data_start)
1619         extern int _end[];
1620 #       define DATAEND ((ptr_t)(&_end))
1621 #       define DYNAMIC_LOADING
1622 #   endif
1623 #   ifdef FREEBSD
1624 #       define OS_TYPE "FREEBSD"
1625 #       ifndef GC_FREEBSD_THREADS
1626 #           define MPROTECT_VDB
1627 #       endif
1628 #       ifdef __GLIBC__
1629 #           define SIG_SUSPEND          (32+6)
1630 #           define SIG_THR_RESTART      (32+5)
1631             extern int _end[];
1632 #           define DATAEND ((ptr_t)(_end))
1633 #       else
1634 #           define SIG_SUSPEND SIGUSR1
1635 #           define SIG_THR_RESTART SIGUSR2
1636                 /* SIGTSTP and SIGCONT could be used alternatively.     */
1637 #       endif
1638 #       define FREEBSD_STACKBOTTOM
1639 #       ifdef __ELF__
1640 #           define DYNAMIC_LOADING
1641 #       endif
1642         extern char etext[];
1643 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1644 #       define DATASTART_USES_BSDGETDATASTART
1645 #   endif
1646 #   ifdef NETBSD
1647 #       define OS_TYPE "NETBSD"
1648 #       ifdef __ELF__
1649 #           define DYNAMIC_LOADING
1650 #       endif
1651 #   endif
1652 #   ifdef THREE86BSD
1653 #       define OS_TYPE "THREE86BSD"
1654 #   endif
1655 #   ifdef BSDI
1656 #       define OS_TYPE "BSDI"
1657 #   endif
1658 #   if defined(NETBSD) || defined(THREE86BSD) || defined(BSDI)
1659 #       define HEURISTIC2
1660         extern char etext[];
1661 #       define DATASTART ((ptr_t)(etext))
1662 #   endif
1663 #   ifdef NEXT
1664 #       define OS_TYPE "NEXT"
1665 #       define DATASTART ((ptr_t)get_etext())
1666 #       define DATASTART_IS_FUNC
1667 #       define STACKBOTTOM ((ptr_t)0xc0000000)
1668 #       define DATAEND  /* not needed */
1669 #   endif
1670 #   ifdef RTEMS
1671 #       define OS_TYPE "RTEMS"
1672         EXTERN_C_END
1673 #       include <sys/unistd.h>
1674         EXTERN_C_BEGIN
1675         extern int etext[];
1676         void *rtems_get_stack_bottom(void);
1677 #       define InitStackBottom rtems_get_stack_bottom()
1678 #       define DATASTART ((ptr_t)etext)
1679 #       define STACKBOTTOM ((ptr_t)InitStackBottom)
1680 #       define SIG_SUSPEND SIGUSR1
1681 #       define SIG_THR_RESTART SIGUSR2
1682 #   endif
1683 #   ifdef DOS4GW
1684 #     define OS_TYPE "DOS4GW"
1685       extern long __nullarea;
1686       extern char _end;
1687       extern char *_STACKTOP;
1688       /* Depending on calling conventions Watcom C either precedes      */
1689       /* or does not precedes with underscore names of C-variables.     */
1690       /* Make sure startup code variables always have the same names.   */
1691       #pragma aux __nullarea "*";
1692       #pragma aux _end "*";
1693 #     define STACKBOTTOM ((ptr_t)_STACKTOP)
1694                          /* confused? me too. */
1695 #     define DATASTART ((ptr_t)(&__nullarea))
1696 #     define DATAEND ((ptr_t)(&_end))
1697 #   endif
1698 #   ifdef HURD
1699 #     define OS_TYPE "HURD"
1700 #     define STACK_GROWS_DOWN
1701 #     define HEURISTIC2
1702 #     define SIG_SUSPEND SIGUSR1
1703 #     define SIG_THR_RESTART SIGUSR2
1704 #     define SEARCH_FOR_DATA_START
1705       extern int _end[];
1706 #     define DATAEND ((ptr_t)(_end))
1707 /* #     define MPROTECT_VDB  Not quite working yet? */
1708 #     define DYNAMIC_LOADING
1709 #     define USE_MMAP_ANON
1710 #   endif
1711 #   ifdef DARWIN
1712 #     define OS_TYPE "DARWIN"
1713 #     define DARWIN_DONT_PARSE_STACK 1
1714 #     define DYNAMIC_LOADING
1715       /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
1716       /* These aren't used when dyld support is enabled (it is by default). */
1717 #     define DATASTART ((ptr_t)get_etext())
1718 #     define DATAEND   ((ptr_t)get_end())
1719 #     define STACKBOTTOM ((ptr_t)0xc0000000)
1720 #     define USE_MMAP_ANON
1721 #     define MPROTECT_VDB
1722       EXTERN_C_END
1723 #     include <unistd.h>
1724       EXTERN_C_BEGIN
1725 #     define GETPAGESIZE() (unsigned)getpagesize()
1726       /* There seems to be some issues with trylock hanging on darwin.  */
1727       /* This should be looked into some more.                          */
1728 #     define NO_PTHREAD_TRYLOCK
1729 #     if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
1730         /* iPhone/iPad simulator */
1731 #       define NO_DYLD_BIND_FULLY_IMAGE
1732 #     endif
1733 #   endif /* DARWIN */
1734 # endif
1735
1736 # ifdef NS32K
1737 #   define MACH_TYPE "NS32K"
1738 #   define ALIGNMENT 4
1739     extern char **environ;
1740 #   define DATASTART ((ptr_t)(&environ))
1741                               /* hideous kludge: environ is the first   */
1742                               /* word in crt0.o, and delimits the start */
1743                               /* of the data segment, no matter which   */
1744                               /* ld options were passed through.        */
1745 #   define STACKBOTTOM ((ptr_t)0xfffff000) /* for Encore */
1746 # endif
1747
1748 # ifdef MIPS
1749 #   define MACH_TYPE "MIPS"
1750 #   ifdef LINUX
1751 #     define OS_TYPE "LINUX"
1752 #     define DYNAMIC_LOADING
1753       extern int _end[];
1754 #     pragma weak __data_start
1755       extern int __data_start[];
1756 #     define DATASTART ((ptr_t)(__data_start))
1757 #     define DATAEND ((ptr_t)(_end))
1758 #     ifdef _MIPS_SZPTR
1759 #       define CPP_WORDSZ _MIPS_SZPTR
1760 #       define ALIGNMENT (_MIPS_SZPTR/8)
1761 #     else
1762 #       define ALIGNMENT 4
1763 #     endif
1764 #     ifndef HBLKSIZE
1765 #       define HBLKSIZE 4096
1766 #     endif
1767 #     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
1768 #       define LINUX_STACKBOTTOM
1769 #     else
1770 #       define STACKBOTTOM ((ptr_t)0x7fff8000)
1771 #     endif
1772 #   endif /* Linux */
1773 #   ifdef EWS4800
1774 #     define HEURISTIC2
1775 #     if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1776         extern int _fdata[], _end[];
1777 #       define DATASTART ((ptr_t)_fdata)
1778 #       define DATAEND ((ptr_t)_end)
1779 #       define CPP_WORDSZ _MIPS_SZPTR
1780 #       define ALIGNMENT (_MIPS_SZPTR/8)
1781 #     else
1782         extern int etext[], edata[];
1783 #       if !defined(CPPCHECK)
1784           extern int end[];
1785 #       endif
1786         extern int _DYNAMIC_LINKING[], _gp[];
1787 #       define DATASTART ((ptr_t)((((word)(etext) + 0x3ffff) & ~0x3ffff) \
1788                                   + ((word)(etext) & 0xffff)))
1789 #       define DATAEND ((ptr_t)(edata))
1790 #       define GC_HAVE_DATAREGION2
1791 #       define DATASTART2 (_DYNAMIC_LINKING \
1792                 ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1793                 : (ptr_t)edata)
1794 #       define DATAEND2 ((ptr_t)(end))
1795 #       define ALIGNMENT 4
1796 #     endif
1797 #     define OS_TYPE "EWS4800"
1798 #   endif
1799 #   ifdef ULTRIX
1800 #       define HEURISTIC2
1801 #       define DATASTART ((ptr_t)0x10000000)
1802                               /* Could probably be slightly higher since */
1803                               /* startup code allocates lots of stuff.   */
1804 #       define OS_TYPE "ULTRIX"
1805 #       define ALIGNMENT 4
1806 #   endif
1807 #   ifdef IRIX5
1808 #       define HEURISTIC2
1809         extern int _fdata[];
1810 #       define DATASTART ((ptr_t)(_fdata))
1811 #       ifdef USE_MMAP
1812 #         define HEAP_START (ptr_t)0x30000000
1813 #       else
1814 #         define HEAP_START DATASTART
1815 #       endif
1816                               /* Lowest plausible heap address.         */
1817                               /* In the MMAP case, we map there.        */
1818                               /* In either case it is used to identify  */
1819                               /* heap sections so they're not           */
1820                               /* considered as roots.                   */
1821 #       define OS_TYPE "IRIX5"
1822 /*#       define MPROTECT_VDB DOB: this should work, but there is evidence */
1823 /*              of recent breakage.                                        */
1824 #       ifdef _MIPS_SZPTR
1825 #         define CPP_WORDSZ _MIPS_SZPTR
1826 #         define ALIGNMENT (_MIPS_SZPTR/8)
1827 #       else
1828 #         define ALIGNMENT 4
1829 #       endif
1830 #       define DYNAMIC_LOADING
1831 #   endif
1832 #   ifdef MSWINCE
1833 #       define OS_TYPE "MSWINCE"
1834 #       define ALIGNMENT 4
1835 #       define DATAEND /* not needed */
1836 #   endif
1837 #   ifdef NETBSD
1838 #     define OS_TYPE "NETBSD"
1839 #     define ALIGNMENT 4
1840 #     define HEURISTIC2
1841 #     ifdef __ELF__
1842         extern ptr_t GC_data_start;
1843 #       define DATASTART GC_data_start
1844 #       define NEED_FIND_LIMIT
1845 #       define DYNAMIC_LOADING
1846 #     else
1847 #       define DATASTART ((ptr_t)0x10000000)
1848 #       define STACKBOTTOM ((ptr_t)0x7ffff000)
1849 #     endif /* _ELF_ */
1850 #  endif
1851 #  ifdef OPENBSD
1852 #     define OS_TYPE "OPENBSD"
1853 #     define CPP_WORDSZ 64 /* all OpenBSD/mips platforms are 64-bit */
1854 #     define ALIGNMENT 8
1855 #     ifndef GC_OPENBSD_THREADS
1856         EXTERN_C_END
1857 #       include <sys/param.h>
1858 #       include <uvm/uvm_extern.h>
1859         EXTERN_C_BEGIN
1860 #       ifdef USRSTACK
1861 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1862 #       else
1863 #         define HEURISTIC2
1864 #       endif
1865 #     endif
1866       extern int __data_start[];
1867 #     define DATASTART ((ptr_t)__data_start)
1868       extern int _end[];
1869 #     define DATAEND ((ptr_t)(&_end))
1870 #     define DYNAMIC_LOADING
1871 #  endif
1872 #  ifdef FREEBSD
1873 #    define OS_TYPE "FREEBSD"
1874 #    define ALIGNMENT 4
1875 #    ifndef GC_FREEBSD_THREADS
1876 #      define MPROTECT_VDB
1877 #    endif
1878 #    define SIG_SUSPEND SIGUSR1
1879 #    define SIG_THR_RESTART SIGUSR2
1880 #    define FREEBSD_STACKBOTTOM
1881 #    define DYNAMIC_LOADING
1882      extern char etext[];
1883 #    define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1884 #    define DATASTART_USES_BSDGETDATASTART
1885 #  endif /* FreeBSD */
1886 #  if defined(NONSTOP)
1887 #    define CPP_WORDSZ 32
1888 #    define OS_TYPE "NONSTOP"
1889 #    define ALIGNMENT 4
1890 #    define DATASTART ((ptr_t)0x08000000)
1891      extern char **environ;
1892 #    define DATAEND ((ptr_t)(environ - 0x10))
1893 #    define STACKBOTTOM ((ptr_t)0x4fffffff)
1894 #   endif
1895 # endif
1896
1897 # ifdef NIOS2
1898 #  define CPP_WORDSZ 32
1899 #  define MACH_TYPE "NIOS2"
1900 #  ifdef LINUX
1901 #    define OS_TYPE "LINUX"
1902 #    define DYNAMIC_LOADING
1903      extern int _end[];
1904      extern int __data_start[];
1905 #    define DATASTART ((ptr_t)(__data_start))
1906 #    define DATAEND ((ptr_t)(_end))
1907 #    define ALIGNMENT 4
1908 #    ifndef HBLKSIZE
1909 #      define HBLKSIZE 4096
1910 #    endif
1911 #    define LINUX_STACKBOTTOM
1912 #  endif /* Linux */
1913 # endif
1914
1915 # ifdef OR1K
1916 #   define CPP_WORDSZ 32
1917 #   define MACH_TYPE "OR1K"
1918 #   ifdef LINUX
1919 #     define OS_TYPE "LINUX"
1920 #     define DYNAMIC_LOADING
1921       extern int _end[];
1922       extern int __data_start[];
1923 #     define DATASTART ((ptr_t)(__data_start))
1924 #     define DATAEND ((ptr_t)(_end))
1925 #     define ALIGNMENT 4
1926 #     ifndef HBLKSIZE
1927 #       define HBLKSIZE 4096
1928 #     endif
1929 #     define LINUX_STACKBOTTOM
1930 #   endif /* Linux */
1931 # endif
1932
1933 # ifdef HP_PA
1934 #   define MACH_TYPE "HP_PA"
1935 #   ifdef __LP64__
1936 #     define CPP_WORDSZ 64
1937 #     define ALIGNMENT 8
1938 #   else
1939 #     define CPP_WORDSZ 32
1940 #     define ALIGNMENT 4
1941 #   endif
1942 #   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) \
1943        && !defined(OPENBSD) && !defined(LINUX) /* For now. */
1944 #     define MPROTECT_VDB
1945 #   endif
1946 #   define STACK_GROWS_UP
1947 #   ifdef HPUX
1948 #     define OS_TYPE "HPUX"
1949       extern int __data_start[];
1950 #     define DATASTART ((ptr_t)(__data_start))
1951 #     ifdef USE_HPUX_FIXED_STACKBOTTOM
1952         /* The following appears to work for 7xx systems running HP/UX  */
1953         /* 9.xx.  Furthermore, it might result in much faster           */
1954         /* collections than HEURISTIC2, which may involve scanning      */
1955         /* segments that directly precede the stack.  It is not the     */
1956         /* default, since it may not work on older machine/OS           */
1957         /* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */
1958         /* this.)                                                       */
1959 #       define STACKBOTTOM ((ptr_t)0x7b033000) /* from /etc/conf/h/param.h */
1960 #     else
1961         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1962         /* to this.  Note that the GC must be initialized before the    */
1963         /* first putenv call.                                           */
1964         extern char ** environ;
1965 #       define STACKBOTTOM ((ptr_t)environ)
1966 #     endif
1967 #     define DYNAMIC_LOADING
1968       EXTERN_C_END
1969 #     include <unistd.h>
1970       EXTERN_C_BEGIN
1971 #     define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
1972 #     ifndef __GNUC__
1973 #       define PREFETCH(x)  do { \
1974                               register long addr = (long)(x); \
1975                               (void) _asm ("LDW", 0, 0, addr, 0); \
1976                             } while (0)
1977 #     endif
1978 #   endif /* HPUX */
1979 #   ifdef LINUX
1980 #     define OS_TYPE "LINUX"
1981 #     define LINUX_STACKBOTTOM
1982 #     define DYNAMIC_LOADING
1983 #     define SEARCH_FOR_DATA_START
1984       extern int _end[];
1985 #     define DATAEND ((ptr_t)(&_end))
1986 #   endif /* LINUX */
1987 #  ifdef OPENBSD
1988 #     define OS_TYPE "OPENBSD"
1989 #     ifndef GC_OPENBSD_THREADS
1990         EXTERN_C_END
1991 #       include <sys/param.h>
1992 #       include <uvm/uvm_extern.h>
1993         EXTERN_C_BEGIN
1994 #       ifdef USRSTACK
1995 #         define STACKBOTTOM ((ptr_t)USRSTACK)
1996 #       else
1997 #         define HEURISTIC2
1998 #       endif
1999 #     endif
2000       extern int __data_start[];
2001 #     define DATASTART ((ptr_t)__data_start)
2002       extern int _end[];
2003 #     define DATAEND ((ptr_t)(&_end))
2004 #     define DYNAMIC_LOADING
2005 #  endif
2006 # endif /* HP_PA */
2007
2008 # ifdef ALPHA
2009 #   define MACH_TYPE "ALPHA"
2010 #   define ALIGNMENT 8
2011 #   define CPP_WORDSZ 64
2012 #   ifdef NETBSD
2013 #       define OS_TYPE "NETBSD"
2014 #       define HEURISTIC2
2015         extern ptr_t GC_data_start;
2016 #       define DATASTART GC_data_start
2017 #       define ELFCLASS32 32
2018 #       define ELFCLASS64 64
2019 #       define ELF_CLASS ELFCLASS64
2020 #       define DYNAMIC_LOADING
2021 #   endif
2022 #   ifdef OPENBSD
2023 #       define OS_TYPE "OPENBSD"
2024 #       define ELF_CLASS ELFCLASS64
2025 #       ifndef GC_OPENBSD_THREADS
2026           EXTERN_C_END
2027 #         include <sys/param.h>
2028 #         include <uvm/uvm_extern.h>
2029           EXTERN_C_BEGIN
2030 #         ifdef USRSTACK
2031 #           define STACKBOTTOM ((ptr_t)USRSTACK)
2032 #         else
2033 #           define HEURISTIC2
2034 #         endif
2035 #       endif
2036         extern int __data_start[];
2037 #       define DATASTART ((ptr_t)__data_start)
2038         extern int _end[];
2039 #       define DATAEND ((ptr_t)(&_end))
2040 #       define DYNAMIC_LOADING
2041 #   endif
2042 #   ifdef FREEBSD
2043 #       define OS_TYPE "FREEBSD"
2044 /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */
2045 #       define SIG_SUSPEND SIGUSR1
2046 #       define SIG_THR_RESTART SIGUSR2
2047                 /* SIGTSTP and SIGCONT could be used alternatively.     */
2048 #       define FREEBSD_STACKBOTTOM
2049 #       define DYNAMIC_LOADING
2050 /* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */
2051         extern char etext[];
2052         extern char edata[];
2053 #       if !defined(CPPCHECK)
2054           extern char end[];
2055 #       endif
2056 #       define NEED_FIND_LIMIT
2057 #       define DATASTART ((ptr_t)(&etext))
2058         void * GC_find_limit(void *, int);
2059 #       define DATAEND (ptr_t)GC_find_limit(DATASTART, TRUE)
2060 #       define DATAEND_IS_FUNC
2061 #       define GC_HAVE_DATAREGION2
2062 #       define DATASTART2 ((ptr_t)(&edata))
2063 #       define DATAEND2 ((ptr_t)(&end))
2064 #   endif
2065 #   ifdef OSF1
2066 #       define OS_TYPE "OSF1"
2067 #       define DATASTART ((ptr_t)0x140000000)
2068         extern int _end[];
2069 #       define DATAEND ((ptr_t)(&_end))
2070         extern char ** environ;
2071         /* round up from the value of environ to the nearest page boundary */
2072         /* Probably breaks if putenv is called before collector            */
2073         /* initialization.                                                 */
2074 #       define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
2075 /* #    define HEURISTIC2 */
2076         /* Normally HEURISTIC2 is too conservative, since               */
2077         /* the text segment immediately follows the stack.              */
2078         /* Hence we give an upper pound.                                */
2079         /* This is currently unused, since we disabled HEURISTIC2       */
2080         extern int __start[];
2081 #       define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
2082 #       ifndef GC_OSF1_THREADS
2083           /* Unresolved signal issues with threads.     */
2084 #         define MPROTECT_VDB
2085 #       endif
2086 #       define DYNAMIC_LOADING
2087 #   endif
2088 #   ifdef LINUX
2089 #       define OS_TYPE "LINUX"
2090 #       define LINUX_STACKBOTTOM
2091 #       ifdef __ELF__
2092 #         define SEARCH_FOR_DATA_START
2093 #         define DYNAMIC_LOADING
2094 #       else
2095 #           define DATASTART ((ptr_t)0x140000000)
2096 #       endif
2097         extern int _end[];
2098 #       define DATAEND ((ptr_t)(_end))
2099 #       if !defined(REDIRECT_MALLOC)
2100 #           define MPROTECT_VDB
2101                 /* Has only been superficially tested.  May not */
2102                 /* work on all versions.                        */
2103 #       endif
2104 #   endif
2105 # endif
2106
2107 # ifdef IA64
2108 #   define MACH_TYPE "IA64"
2109 #   ifdef HPUX
2110 #       ifdef _ILP32
2111 #         define CPP_WORDSZ 32
2112             /* Requires 8 byte alignment for malloc */
2113 #         define ALIGNMENT 4
2114 #       else
2115 #         if !defined(_LP64) && !defined(CPPCHECK)
2116 #           error Unknown ABI
2117 #         endif
2118 #         define CPP_WORDSZ 64
2119             /* Requires 16 byte alignment for malloc */
2120 #         define ALIGNMENT 8
2121 #       endif
2122 #       define OS_TYPE "HPUX"
2123         extern int __data_start[];
2124 #       define DATASTART ((ptr_t)(__data_start))
2125         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
2126         /* to this.  Note that the GC must be initialized before the    */
2127         /* first putenv call.                                           */
2128         extern char ** environ;
2129 #       define STACKBOTTOM ((ptr_t)environ)
2130 #       define HPUX_STACKBOTTOM
2131 #       define DYNAMIC_LOADING
2132         EXTERN_C_END
2133 #       include <unistd.h>
2134         EXTERN_C_BEGIN
2135 #       define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
2136         /* The following was empirically determined, and is probably    */
2137         /* not very robust.                                             */
2138         /* Note that the backing store base seems to be at a nice       */
2139         /* address minus one page.                                      */
2140 #       define BACKING_STORE_DISPLACEMENT 0x1000000
2141 #       define BACKING_STORE_ALIGNMENT 0x1000
2142         extern ptr_t GC_register_stackbottom;
2143 #       define BACKING_STORE_BASE GC_register_stackbottom
2144         /* Known to be wrong for recent HP/UX versions!!!       */
2145 #   endif
2146 #   ifdef LINUX
2147 #       define CPP_WORDSZ 64
2148 #       define ALIGNMENT 8
2149 #       define OS_TYPE "LINUX"
2150         /* The following works on NUE and older kernels:        */
2151 /* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)     */
2152         /* This does not work on NUE:                           */
2153 #       define LINUX_STACKBOTTOM
2154         /* We also need the base address of the register stack  */
2155         /* backing store.                                       */
2156         extern ptr_t GC_register_stackbottom;
2157 #       define BACKING_STORE_BASE GC_register_stackbottom
2158 #       define SEARCH_FOR_DATA_START
2159 #       ifdef __GNUC__
2160 #         define DYNAMIC_LOADING
2161 #       else
2162           /* In the Intel compiler environment, we seem to end up with  */
2163           /* statically linked executables and an undefined reference   */
2164           /* to _DYNAMIC                                                */
2165 #       endif
2166 #       if !defined(REDIRECT_MALLOC)
2167 #         define MPROTECT_VDB
2168                 /* Requires Linux 2.3.47 or later.      */
2169 #       endif
2170         extern int _end[];
2171 #       define DATAEND ((ptr_t)(_end))
2172 #       ifdef __GNUC__
2173 #         ifndef __INTEL_COMPILER
2174 #           define PREFETCH(x) \
2175               __asm__ ("        lfetch  [%0]": : "r"(x))
2176 #           define GC_PREFETCH_FOR_WRITE(x) \
2177               __asm__ ("        lfetch.excl     [%0]": : "r"(x))
2178 #           define CLEAR_DOUBLE(x) \
2179               __asm__ ("        stf.spill       [%0]=f0": : "r"((void *)(x)))
2180 #         else
2181             EXTERN_C_END
2182 #           include <ia64intrin.h>
2183             EXTERN_C_BEGIN
2184 #           define PREFETCH(x) __lfetch(__lfhint_none, (x))
2185 #           define GC_PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
2186 #           define CLEAR_DOUBLE(x) __stf_spill((void *)(x), 0)
2187 #         endif /* __INTEL_COMPILER */
2188 #       endif
2189 #   endif
2190 #   ifdef MSWIN32
2191       /* FIXME: This is a very partial guess.  There is no port, yet.   */
2192 #     define OS_TYPE "MSWIN32"
2193                 /* STACKBOTTOM and DATASTART are handled specially in   */
2194                 /* os_dep.c.                                            */
2195 #     define DATAEND  /* not needed */
2196 #     if defined(_WIN64)
2197 #       define CPP_WORDSZ 64
2198 #     else
2199 #       define CPP_WORDSZ 32   /* Is this possible?     */
2200 #     endif
2201 #     define ALIGNMENT 8
2202 #   endif
2203 # endif
2204
2205 # ifdef M88K
2206 #   define MACH_TYPE "M88K"
2207 #   define ALIGNMENT 4
2208     extern int etext[];
2209 #   ifdef CX_UX
2210 #       define OS_TYPE "CX_UX"
2211 #       define DATASTART ((ptr_t)((((word)(etext) + 0x3fffff) & ~0x3fffff) \
2212                                   + 0x10000))
2213 #   endif
2214 #   ifdef DGUX
2215 #       define OS_TYPE "DGUX"
2216         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2217 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
2218 #       define DATASTART_IS_FUNC
2219 #   endif
2220 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
2221 # endif
2222
2223 # ifdef S370
2224     /* If this still works, and if anyone cares, this should probably   */
2225     /* be moved to the S390 category.                                   */
2226 #   define MACH_TYPE "S370"
2227 #   define ALIGNMENT 4  /* Required by hardware */
2228 #   ifdef UTS4
2229 #       define OS_TYPE "UTS4"
2230         extern int etext[];
2231         extern int _etext[];
2232         extern int _end[];
2233         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2234 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
2235 #       define DATASTART_IS_FUNC
2236 #       define DATAEND ((ptr_t)(_end))
2237 #       define HEURISTIC2
2238 #   endif
2239 # endif
2240
2241 # ifdef S390
2242 #   define MACH_TYPE "S390"
2243 #   ifndef __s390x__
2244 #     define ALIGNMENT 4
2245 #     define CPP_WORDSZ 32
2246 #   else
2247 #     define ALIGNMENT 8
2248 #     define CPP_WORDSZ 64
2249 #     ifndef HBLKSIZE
2250 #       define HBLKSIZE 4096
2251 #     endif
2252 #   endif
2253 #   ifdef LINUX
2254 #       define OS_TYPE "LINUX"
2255 #       define LINUX_STACKBOTTOM
2256 #       define DYNAMIC_LOADING
2257         extern int __data_start[] __attribute__((__weak__));
2258 #       define DATASTART ((ptr_t)(__data_start))
2259         extern int _end[] __attribute__((__weak__));
2260 #       define DATAEND ((ptr_t)(_end))
2261 #       define CACHE_LINE_SIZE 256
2262 #       define GETPAGESIZE() 4096
2263 #   endif
2264 # endif
2265
2266 # ifdef AARCH64
2267 #   define MACH_TYPE "AARCH64"
2268 #   ifdef __ILP32__
2269 #     define CPP_WORDSZ 32
2270 #     define ALIGNMENT 4
2271 #   else
2272 #     define CPP_WORDSZ 64
2273 #     define ALIGNMENT 8
2274 #   endif
2275 #   ifndef HBLKSIZE
2276 #     define HBLKSIZE 4096
2277 #   endif
2278 #   ifdef LINUX
2279 #     define OS_TYPE "LINUX"
2280 #     define LINUX_STACKBOTTOM
2281 #     if !defined(REDIRECT_MALLOC)
2282 #       define MPROTECT_VDB
2283 #     endif
2284 #     define DYNAMIC_LOADING
2285 #     if defined(HOST_ANDROID)
2286 #       define SEARCH_FOR_DATA_START
2287 #     else
2288         extern int __data_start[];
2289 #       define DATASTART ((ptr_t)__data_start)
2290 #     endif
2291       extern int _end[];
2292 #     define DATAEND ((ptr_t)(&_end))
2293 #   endif
2294 #   ifdef DARWIN
2295       /* iOS */
2296 #     define OS_TYPE "DARWIN"
2297 #     define DARWIN_DONT_PARSE_STACK 1
2298 #     define DYNAMIC_LOADING
2299 #     define DATASTART ((ptr_t)get_etext())
2300 #     define DATAEND   ((ptr_t)get_end())
2301 #     define STACKBOTTOM ((ptr_t)0x16fdfffff)
2302 #     define USE_MMAP_ANON
2303 #     define MPROTECT_VDB
2304       EXTERN_C_END
2305 #     include <unistd.h>
2306       EXTERN_C_BEGIN
2307 #     define GETPAGESIZE() (unsigned)getpagesize()
2308       /* FIXME: There seems to be some issues with trylock hanging on   */
2309       /* darwin. This should be looked into some more.                  */
2310 #     define NO_PTHREAD_TRYLOCK
2311 #     if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2312 #       define NO_DYLD_BIND_FULLY_IMAGE
2313 #     endif
2314 #   endif
2315 #   ifdef FREEBSD
2316 #     define OS_TYPE "FREEBSD"
2317 #     ifndef GC_FREEBSD_THREADS
2318 #       define MPROTECT_VDB
2319 #     endif
2320 #     define FREEBSD_STACKBOTTOM
2321 #     define DYNAMIC_LOADING
2322       extern char etext[];
2323 #     define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2324 #     define DATASTART_USES_BSDGETDATASTART
2325 #   endif
2326 #   ifdef NETBSD
2327 #     define OS_TYPE "NETBSD"
2328 #     define HEURISTIC2
2329       extern ptr_t GC_data_start;
2330 #     define DATASTART GC_data_start
2331 #     define ELF_CLASS ELFCLASS64
2332 #     define DYNAMIC_LOADING
2333 #   endif
2334 #   ifdef OPENBSD
2335 #     define OS_TYPE "OPENBSD"
2336 #     define ELF_CLASS ELFCLASS64
2337 #     ifndef GC_OPENBSD_THREADS
2338         EXTERN_C_END
2339 #       include <sys/param.h>
2340 #       include <uvm/uvm_extern.h>
2341         EXTERN_C_BEGIN
2342 #       ifdef USRSTACK
2343 #         define STACKBOTTOM ((ptr_t)USRSTACK)
2344 #       else
2345 #         define HEURISTIC2
2346 #       endif
2347 #     endif
2348       extern int __data_start[];
2349 #     define DATASTART ((ptr_t)__data_start)
2350       extern int _end[];
2351 #     define DATAEND ((ptr_t)(&_end))
2352 #     define DYNAMIC_LOADING
2353 #   endif
2354 #   ifdef NINTENDO_SWITCH
2355       extern int __bss_end[];
2356 #     define NO_HANDLE_FORK 1
2357 #     define DATASTART (ptr_t)ALIGNMENT /* cannot be null */
2358 #     define DATAEND (ptr_t)(&__bss_end)
2359       void *switch_get_stack_bottom(void);
2360 #     define STACKBOTTOM ((ptr_t)switch_get_stack_bottom())
2361 #   endif
2362 #   ifdef MSWIN32   /* UWP */
2363 #     define OS_TYPE "MSWIN32"
2364       /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */
2365 #     ifndef DATAEND
2366 #       define DATAEND  /* not needed */
2367 #     endif
2368 #   endif
2369 #   ifdef NOSYS
2370       /* __data_start is usually defined in the target linker script.   */
2371       extern int __data_start[];
2372 #     define DATASTART ((ptr_t)__data_start)
2373       extern void *__stack_base__;
2374 #     define STACKBOTTOM ((ptr_t)__stack_base__)
2375 #   endif
2376 # endif
2377
2378 # ifdef ARM32
2379 #   if defined(NACL)
2380 #     define MACH_TYPE "NACL"
2381 #   else
2382 #     define MACH_TYPE "ARM32"
2383 #   endif
2384 #   define CPP_WORDSZ 32
2385 #   define ALIGNMENT 4
2386 #   ifdef NETBSD
2387 #       define OS_TYPE "NETBSD"
2388 #       define HEURISTIC2
2389 #       ifdef __ELF__
2390            extern ptr_t GC_data_start;
2391 #          define DATASTART GC_data_start
2392 #          define DYNAMIC_LOADING
2393 #       else
2394            extern char etext[];
2395 #          define DATASTART ((ptr_t)(etext))
2396 #       endif
2397 #   endif
2398 #   ifdef LINUX
2399 #       define OS_TYPE "LINUX"
2400 #       define LINUX_STACKBOTTOM
2401 #       if !defined(REDIRECT_MALLOC)
2402 #           define MPROTECT_VDB
2403 #       endif
2404 #       define DYNAMIC_LOADING
2405         EXTERN_C_END
2406 #       include <features.h>
2407         EXTERN_C_BEGIN
2408 #       if defined(__GLIBC__) && __GLIBC__ >= 2 \
2409                 || defined(HOST_ANDROID) || defined(HOST_TIZEN)
2410 #           define SEARCH_FOR_DATA_START
2411 #       else
2412             extern char **__environ;
2413 #           define DATASTART ((ptr_t)(&__environ))
2414                               /* hideous kludge: __environ is the first */
2415                               /* word in crt0.o, and delimits the start */
2416                               /* of the data segment, no matter which   */
2417                               /* ld options were passed through.        */
2418                               /* We could use _etext instead, but that  */
2419                               /* would include .rodata, which may       */
2420                               /* contain large read-only data tables    */
2421                               /* that we'd rather not scan.             */
2422 #       endif
2423         extern int _end[];
2424 #       define DATAEND ((ptr_t)(_end))
2425 #   endif
2426 #   ifdef MSWINCE
2427 #     define OS_TYPE "MSWINCE"
2428 #     define DATAEND /* not needed */
2429 #   endif
2430 #   ifdef FREEBSD
2431       /* FreeBSD/arm */
2432 #     define OS_TYPE "FREEBSD"
2433 #     ifndef GC_FREEBSD_THREADS
2434 #       define MPROTECT_VDB
2435 #     endif
2436 #     define SIG_SUSPEND SIGUSR1
2437 #     define SIG_THR_RESTART SIGUSR2
2438 #     define FREEBSD_STACKBOTTOM
2439 #     define DYNAMIC_LOADING
2440       extern char etext[];
2441 #     define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2442 #     define DATASTART_USES_BSDGETDATASTART
2443 #   endif
2444 #   ifdef DARWIN
2445       /* iOS */
2446 #     define OS_TYPE "DARWIN"
2447 #     define DARWIN_DONT_PARSE_STACK 1
2448 #     define DYNAMIC_LOADING
2449 #     define DATASTART ((ptr_t)get_etext())
2450 #     define DATAEND   ((ptr_t)get_end())
2451 #     define STACKBOTTOM ((ptr_t)0x30000000)
2452 #     define USE_MMAP_ANON
2453 #     define MPROTECT_VDB
2454       EXTERN_C_END
2455 #     include <unistd.h>
2456       EXTERN_C_BEGIN
2457 #     define GETPAGESIZE() (unsigned)getpagesize()
2458       /* FIXME: There seems to be some issues with trylock hanging on   */
2459       /* darwin. This should be looked into some more.                  */
2460 #     define NO_PTHREAD_TRYLOCK
2461 #     if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2462 #       define NO_DYLD_BIND_FULLY_IMAGE
2463 #     endif
2464 #   endif
2465 #   ifdef OPENBSD
2466 #     define OS_TYPE "OPENBSD"
2467 #     ifndef GC_OPENBSD_THREADS
2468         EXTERN_C_END
2469 #       include <sys/param.h>
2470 #       include <uvm/uvm_extern.h>
2471         EXTERN_C_BEGIN
2472 #       ifdef USRSTACK
2473 #         define STACKBOTTOM ((ptr_t)USRSTACK)
2474 #       else
2475 #         define HEURISTIC2
2476 #       endif
2477 #     endif
2478       extern int __data_start[];
2479 #     define DATASTART ((ptr_t)__data_start)
2480       extern int _end[];
2481 #     define DATAEND ((ptr_t)(&_end))
2482 #     define DYNAMIC_LOADING
2483 #   endif
2484 #   ifdef SN_TARGET_PSP2
2485 #     define NO_HANDLE_FORK 1
2486 #     define DATASTART (ptr_t)ALIGNMENT
2487 #     define DATAEND (ptr_t)ALIGNMENT
2488       void *psp2_get_stack_bottom(void);
2489 #     define STACKBOTTOM ((ptr_t)psp2_get_stack_bottom())
2490 #   endif
2491 #   ifdef NN_PLATFORM_CTR
2492       extern unsigned char Image$$ZI$$ZI$$Base[];
2493 #     define DATASTART (ptr_t)(Image$$ZI$$ZI$$Base)
2494       extern unsigned char Image$$ZI$$ZI$$Limit[];
2495 #     define DATAEND (ptr_t)(Image$$ZI$$ZI$$Limit)
2496       void *n3ds_get_stack_bottom(void);
2497 #     define STACKBOTTOM ((ptr_t)n3ds_get_stack_bottom())
2498 #   endif
2499 #   ifdef MSWIN32   /* UWP */
2500 #     define OS_TYPE "MSWIN32"
2501       /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */
2502 #     ifndef DATAEND
2503 #       define DATAEND  /* not needed */
2504 #     endif
2505 #   endif
2506 #   ifdef NOSYS
2507       /* __data_start is usually defined in the target linker script.  */
2508       extern int __data_start[];
2509 #     define DATASTART ((ptr_t)(__data_start))
2510       /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */
2511       extern void *__stack_base__;
2512 #     define STACKBOTTOM ((ptr_t)(__stack_base__))
2513 #   endif
2514 #endif
2515
2516 # ifdef CRIS
2517 #   define MACH_TYPE "CRIS"
2518 #   define CPP_WORDSZ 32
2519 #   define ALIGNMENT 1
2520 #   ifdef LINUX
2521 #     define OS_TYPE "LINUX"
2522 #     define DYNAMIC_LOADING
2523 #     define LINUX_STACKBOTTOM
2524 #     define SEARCH_FOR_DATA_START
2525       extern int _end[];
2526 #     define DATAEND ((ptr_t)(_end))
2527 #   endif
2528 # endif
2529
2530 # if defined(SH) && !defined(SH4)
2531 #   define MACH_TYPE "SH"
2532 #   define ALIGNMENT 4
2533 #   ifdef MSWINCE
2534 #     define OS_TYPE "MSWINCE"
2535 #     define DATAEND /* not needed */
2536 #   endif
2537 #   ifdef LINUX
2538 #     define OS_TYPE "LINUX"
2539 #     define LINUX_STACKBOTTOM
2540 #     define DYNAMIC_LOADING
2541 #     define SEARCH_FOR_DATA_START
2542       extern int _end[];
2543 #     define DATAEND ((ptr_t)(_end))
2544 #   endif
2545 #   ifdef NETBSD
2546 #      define OS_TYPE "NETBSD"
2547 #      define HEURISTIC2
2548        extern ptr_t GC_data_start;
2549 #      define DATASTART GC_data_start
2550 #      define DYNAMIC_LOADING
2551 #   endif
2552 #   ifdef OPENBSD
2553 #     define OS_TYPE "OPENBSD"
2554 #     ifndef GC_OPENBSD_THREADS
2555         EXTERN_C_END
2556 #       include <sys/param.h>
2557 #       include <uvm/uvm_extern.h>
2558         EXTERN_C_BEGIN
2559 #       ifdef USRSTACK
2560 #         define STACKBOTTOM ((ptr_t)USRSTACK)
2561 #       else
2562 #         define HEURISTIC2
2563 #       endif
2564 #     endif
2565       extern int __data_start[];
2566 #     define DATASTART ((ptr_t)__data_start)
2567       extern int _end[];
2568 #     define DATAEND ((ptr_t)(&_end))
2569 #     define DYNAMIC_LOADING
2570 #   endif
2571 # endif
2572
2573 # ifdef SH4
2574 #   define MACH_TYPE "SH4"
2575 #   define ALIGNMENT 4
2576 #   ifdef MSWINCE
2577 #     define OS_TYPE "MSWINCE"
2578 #     define DATAEND /* not needed */
2579 #   endif
2580 # endif
2581
2582 # ifdef AVR32
2583 #   define MACH_TYPE "AVR32"
2584 #   define CPP_WORDSZ 32
2585 #   define ALIGNMENT 4
2586 #   ifdef LINUX
2587 #     define OS_TYPE "LINUX"
2588 #     define DYNAMIC_LOADING
2589 #     define LINUX_STACKBOTTOM
2590 #     define SEARCH_FOR_DATA_START
2591       extern int _end[];
2592 #     define DATAEND ((ptr_t)(_end))
2593 #   endif
2594 # endif
2595
2596 # ifdef M32R
2597 #   define CPP_WORDSZ 32
2598 #   define MACH_TYPE "M32R"
2599 #   define ALIGNMENT 4
2600 #   ifdef LINUX
2601 #     define OS_TYPE "LINUX"
2602 #     define LINUX_STACKBOTTOM
2603 #     define DYNAMIC_LOADING
2604 #     define SEARCH_FOR_DATA_START
2605       extern int _end[];
2606 #     define DATAEND ((ptr_t)(_end))
2607 #   endif
2608 # endif
2609
2610 # ifdef X86_64
2611 #   define MACH_TYPE "X86_64"
2612 #   ifdef __ILP32__
2613 #     define ALIGNMENT 4
2614 #     define CPP_WORDSZ 32
2615 #   else
2616 #     define ALIGNMENT 8
2617 #     define CPP_WORDSZ 64
2618 #   endif
2619 #   ifndef HBLKSIZE
2620 #     define HBLKSIZE 4096
2621 #   endif
2622 #   ifndef CACHE_LINE_SIZE
2623 #     define CACHE_LINE_SIZE 64
2624 #   endif
2625 #   ifdef SN_TARGET_ORBIS
2626 #     define DATASTART (ptr_t)ALIGNMENT
2627 #     define DATAEND (ptr_t)ALIGNMENT
2628       void *ps4_get_stack_bottom(void);
2629 #     define STACKBOTTOM ((ptr_t)ps4_get_stack_bottom())
2630 #   endif
2631 #   ifdef OPENBSD
2632 #       define OS_TYPE "OPENBSD"
2633 #       define ELF_CLASS ELFCLASS64
2634 #       ifndef GC_OPENBSD_THREADS
2635           EXTERN_C_END
2636 #         include <sys/param.h>
2637 #         include <uvm/uvm_extern.h>
2638           EXTERN_C_BEGIN
2639 #         ifdef USRSTACK
2640 #           define STACKBOTTOM ((ptr_t)USRSTACK)
2641 #         else
2642 #           define HEURISTIC2
2643 #         endif
2644 #       endif
2645         extern int __data_start[];
2646         extern int _end[];
2647 #       define DATASTART ((ptr_t)__data_start)
2648 #       define DATAEND ((ptr_t)(&_end))
2649 #       define DYNAMIC_LOADING
2650 #   endif
2651 #   ifdef LINUX
2652 #       define OS_TYPE "LINUX"
2653 #       define LINUX_STACKBOTTOM
2654 #       if !defined(REDIRECT_MALLOC)
2655 #           define MPROTECT_VDB
2656 #       else
2657             /* We seem to get random errors in incremental mode,        */
2658             /* possibly because Linux threads is itself a malloc client */
2659             /* and can't deal with the signals.                         */
2660 #       endif
2661 #       define DYNAMIC_LOADING
2662         EXTERN_C_END
2663 #       include <features.h>
2664         EXTERN_C_BEGIN
2665 #       define SEARCH_FOR_DATA_START
2666         extern int _end[];
2667 #       define DATAEND ((ptr_t)(_end))
2668 #       if defined(__GLIBC__) && !defined(__UCLIBC__)
2669           /* A workaround for GCF (Google Cloud Function) which does    */
2670           /* not support mmap() for "/dev/zero".  Should not cause any  */
2671           /* harm to other targets.                                     */
2672 #         define USE_MMAP_ANON
2673           /* At present, there's a bug in GLibc getcontext() on         */
2674           /* Linux/x64 (it clears FPU exception mask).  We define this  */
2675           /* macro to workaround it.                                    */
2676           /* TODO: This seems to be fixed in GLibc v2.14.               */
2677 #         define GETCONTEXT_FPU_EXCMASK_BUG
2678           /* Workaround lock elision implementation for some glibc.     */
2679 #         define GLIBC_2_19_TSX_BUG
2680           EXTERN_C_END
2681 #         include <gnu/libc-version.h> /* for gnu_get_libc_version() */
2682           EXTERN_C_BEGIN
2683 #       endif
2684 #   endif
2685 #   ifdef DARWIN
2686 #     define OS_TYPE "DARWIN"
2687 #     define DARWIN_DONT_PARSE_STACK 1
2688 #     define DYNAMIC_LOADING
2689       /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
2690       /* These aren't used when dyld support is enabled (it is by default)  */
2691 #     define DATASTART ((ptr_t)get_etext())
2692 #     define DATAEND   ((ptr_t)get_end())
2693 #     define STACKBOTTOM ((ptr_t)0x7fff5fc00000)
2694 #     define USE_MMAP_ANON
2695 #     define MPROTECT_VDB
2696       EXTERN_C_END
2697 #     include <unistd.h>
2698       EXTERN_C_BEGIN
2699 #     define GETPAGESIZE() (unsigned)getpagesize()
2700       /* There seems to be some issues with trylock hanging on darwin.  */
2701       /* This should be looked into some more.                          */
2702 #     define NO_PTHREAD_TRYLOCK
2703 #     if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2704         /* iPhone/iPad simulator */
2705 #       define NO_DYLD_BIND_FULLY_IMAGE
2706 #     endif
2707 #   endif
2708 #   ifdef FREEBSD
2709 #       define OS_TYPE "FREEBSD"
2710 #       ifndef GC_FREEBSD_THREADS
2711 #           define MPROTECT_VDB
2712 #       endif
2713 #       ifdef __GLIBC__
2714 #           define SIG_SUSPEND          (32+6)
2715 #           define SIG_THR_RESTART      (32+5)
2716             extern int _end[];
2717 #           define DATAEND ((ptr_t)(_end))
2718 #       else
2719 #           define SIG_SUSPEND SIGUSR1
2720 #           define SIG_THR_RESTART SIGUSR2
2721                 /* SIGTSTP and SIGCONT could be used alternatively.     */
2722 #       endif
2723 #       define FREEBSD_STACKBOTTOM
2724 #       define DYNAMIC_LOADING
2725         extern char etext[];
2726 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2727 #       define DATASTART_USES_BSDGETDATASTART
2728 #   endif
2729 #   ifdef NETBSD
2730 #       define OS_TYPE "NETBSD"
2731 #       define HEURISTIC2
2732         extern ptr_t GC_data_start;
2733 #       define DATASTART GC_data_start
2734 #       define DYNAMIC_LOADING
2735 #   endif
2736 #   ifdef HAIKU
2737 #     define OS_TYPE "HAIKU"
2738       EXTERN_C_END
2739 #     include <OS.h>
2740       EXTERN_C_BEGIN
2741 #     define GETPAGESIZE() (unsigned)B_PAGE_SIZE
2742 #     define HEURISTIC2
2743 #     define SEARCH_FOR_DATA_START
2744 #     define DYNAMIC_LOADING
2745 #     define MPROTECT_VDB
2746 #   endif
2747 #   ifdef SOLARIS
2748 #       define OS_TYPE "SOLARIS"
2749 #       define ELF_CLASS ELFCLASS64
2750         extern int _etext[], _end[];
2751         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2752 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
2753 #       define DATASTART_IS_FUNC
2754 #       define DATAEND ((ptr_t)(_end))
2755         /* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,   */
2756         /* but reportedly breaks under 2.8.  It appears that the stack  */
2757         /* base is a property of the executable, so this should not     */
2758         /* break old executables.                                       */
2759         /* HEURISTIC2 probably works, but this appears to be preferable.*/
2760         /* Apparently USRSTACK is defined to be USERLIMIT, but in some  */
2761         /* installations that's undefined.  We work around this with a  */
2762         /* gross hack:                                                  */
2763         EXTERN_C_END
2764 #       include <sys/vmparam.h>
2765         EXTERN_C_BEGIN
2766 #       ifdef USERLIMIT
2767           /* This should work everywhere, but doesn't.  */
2768 #         define STACKBOTTOM ((ptr_t)USRSTACK)
2769 #       else
2770 #         define HEURISTIC2
2771 #       endif
2772 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
2773 /* It appears to be fixed in 2.8 and 2.9.                               */
2774 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
2775 #         define PROC_VDB
2776 #       endif
2777 #       ifndef GC_THREADS
2778 #         define MPROTECT_VDB
2779 #       endif
2780 #       define DYNAMIC_LOADING
2781 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
2782 #         define USE_MMAP 1
2783             /* Otherwise we now use calloc.  Mmap may result in the     */
2784             /* heap interleaved with thread stacks, which can result in */
2785             /* excessive blacklisting.  Sbrk is unusable since it       */
2786             /* doesn't interact correctly with the system malloc.       */
2787 #       endif
2788 #       ifdef USE_MMAP
2789 #         define HEAP_START (ptr_t)0x40000000
2790 #       else
2791 #         define HEAP_START DATAEND
2792 #       endif
2793 #   endif
2794 #   ifdef CYGWIN32
2795 #       define OS_TYPE "CYGWIN32"
2796 #       ifdef USE_WINALLOC
2797 #         define GWW_VDB
2798 #       else
2799 #         if defined(THREAD_LOCAL_ALLOC)
2800             /* TODO: For an unknown reason, thread-local allocations    */
2801             /* lead to spurious process exit after the fault handler is */
2802             /* once invoked.                                            */
2803 #         else
2804 #           define MPROTECT_VDB
2805 #         endif
2806 #         ifdef USE_MMAP
2807 #           define USE_MMAP_ANON
2808 #         endif
2809 #       endif
2810 #   endif
2811 #   ifdef MSWIN_XBOX1
2812 #     define NO_GETENV
2813 #     define DATASTART (ptr_t)ALIGNMENT
2814 #     define DATAEND (ptr_t)ALIGNMENT
2815       LONG64 durango_get_stack_bottom(void);
2816 #     define STACKBOTTOM ((ptr_t)durango_get_stack_bottom())
2817 #     define GETPAGESIZE() 4096
2818 #     ifndef USE_MMAP
2819 #       define USE_MMAP 1
2820 #     endif
2821       /* The following is from sys/mman.h:  */
2822 #     define PROT_NONE  0
2823 #     define PROT_READ  1
2824 #     define PROT_WRITE 2
2825 #     define PROT_EXEC  4
2826 #     define MAP_PRIVATE 2
2827 #     define MAP_FIXED  0x10
2828 #     define MAP_FAILED ((void *)-1)
2829 #   endif
2830 #   ifdef MSWIN32
2831 #       define OS_TYPE "MSWIN32"
2832                 /* STACKBOTTOM and DATASTART are handled specially in   */
2833                 /* os_dep.c.                                            */
2834 #       if !defined(__GNUC__) || defined(__INTEL_COMPILER) \
2835            || GC_GNUC_PREREQ(4, 7)
2836           /* Older GCC has not supported SetUnhandledExceptionFilter    */
2837           /* properly on x64 (e.g. SEH unwinding information missed).   */
2838 #         define MPROTECT_VDB
2839 #       endif
2840 #       define GWW_VDB
2841 #       ifndef DATAEND
2842 #         define DATAEND    /* not needed */
2843 #       endif
2844 #   endif
2845 # endif /* X86_64 */
2846
2847 # ifdef HEXAGON
2848 #   define CPP_WORDSZ 32
2849 #   define MACH_TYPE "HEXAGON"
2850 #   define ALIGNMENT 4
2851 #   ifdef LINUX
2852 #     define OS_TYPE "LINUX"
2853 #     define LINUX_STACKBOTTOM
2854 #     if !defined(REDIRECT_MALLOC)
2855 #       define MPROTECT_VDB
2856 #     endif
2857 #     define DYNAMIC_LOADING
2858       EXTERN_C_END
2859 #     include <features.h>
2860       EXTERN_C_BEGIN
2861 #     if defined(__GLIBC__)
2862 #       define SEARCH_FOR_DATA_START
2863 #     elif !defined(CPPCHECK)
2864 #       error Unknown Hexagon libc configuration
2865 #     endif
2866       extern int _end[];
2867 #     define DATAEND ((ptr_t)(_end))
2868 #   endif
2869 # endif
2870
2871 # ifdef TILEPRO
2872 #   define CPP_WORDSZ 32
2873 #   define MACH_TYPE "TILEPro"
2874 #   define ALIGNMENT 4
2875 #   define PREFETCH(x) __insn_prefetch(x)
2876 #   define CACHE_LINE_SIZE 64
2877 #   ifdef LINUX
2878 #     define OS_TYPE "LINUX"
2879       extern int __data_start[];
2880 #     define DATASTART ((ptr_t)__data_start)
2881 #     define LINUX_STACKBOTTOM
2882 #     define DYNAMIC_LOADING
2883 #   endif
2884 # endif
2885
2886 # ifdef TILEGX
2887 #   define CPP_WORDSZ (__SIZEOF_POINTER__ * 8)
2888 #   define MACH_TYPE "TILE-Gx"
2889 #   define ALIGNMENT __SIZEOF_POINTER__
2890 #   if CPP_WORDSZ < 64
2891 #     define CLEAR_DOUBLE(x) (*(long long *)(x) = 0)
2892 #   endif
2893 #   define PREFETCH(x) __insn_prefetch_l1(x)
2894 #   define CACHE_LINE_SIZE 64
2895 #   ifdef LINUX
2896 #     define OS_TYPE "LINUX"
2897       extern int __data_start[];
2898 #     define DATASTART ((ptr_t)__data_start)
2899 #     define LINUX_STACKBOTTOM
2900 #     define DYNAMIC_LOADING
2901 #   endif
2902 # endif
2903
2904 # ifdef RISCV
2905 #   define MACH_TYPE "RISC-V"
2906 #   define CPP_WORDSZ __riscv_xlen /* 32 or 64 */
2907 #   define ALIGNMENT (CPP_WORDSZ/8)
2908 #   ifdef LINUX
2909 #     define OS_TYPE "LINUX"
2910       extern int __data_start[];
2911 #     define DATASTART ((ptr_t)__data_start)
2912 #     define LINUX_STACKBOTTOM
2913 #     define DYNAMIC_LOADING
2914 #   endif
2915 # endif /* RISCV */
2916
2917 #if defined(__GLIBC__) && !defined(DONT_USE_LIBC_PRIVATES)
2918   /* Use glibc's stack-end marker. */
2919 # define USE_LIBC_PRIVATES
2920 #endif
2921
2922 #if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \
2923     && !defined(USE_LIBC_PRIVATES)
2924     /* This combination will fail, since we have no way to get  */
2925     /* the stack bottom.  Use HEURISTIC2 instead.               */
2926 #   undef LINUX_STACKBOTTOM
2927 #   define HEURISTIC2
2928     /* This may still fail on some architectures like IA64.     */
2929     /* We tried ...                                             */
2930 #endif
2931
2932 #if defined(USE_MMAP_ANON) && !defined(USE_MMAP)
2933 #   define USE_MMAP 1
2934 #elif defined(LINUX) && defined(USE_MMAP)
2935     /* The kernel may do a somewhat better job merging mappings etc.    */
2936     /* with anonymous mappings.                                         */
2937 #   define USE_MMAP_ANON
2938 #endif
2939
2940 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
2941     && !defined(USE_PROC_FOR_LIBRARIES)
2942     /* Nptl allocates thread stacks with mmap, which is fine.  But it   */
2943     /* keeps a cache of thread stacks.  Thread stacks contain the       */
2944     /* thread control blocks.  These in turn contain a pointer to       */
2945     /* (sizeof (void *) from the beginning of) the dtv for thread-local */
2946     /* storage, which is calloc allocated.  If we don't scan the cached */
2947     /* thread stacks, we appear to lose the dtv.  This tends to         */
2948     /* result in something that looks like a bogus dtv count, which     */
2949     /* tends to result in a memset call on a block that is way too      */
2950     /* large.  Sometimes we're lucky and the process just dies ...      */
2951     /* There seems to be a similar issue with some other memory         */
2952     /* allocated by the dynamic loader.                                 */
2953     /* This should be avoidable by either:                              */
2954     /* - Defining USE_PROC_FOR_LIBRARIES here.                          */
2955     /*   That performs very poorly, precisely because we end up         */
2956     /*   scanning cached stacks.                                        */
2957     /* - Have calloc look at its callers.                               */
2958     /*   In spite of the fact that it is gross and disgusting.          */
2959     /* In fact neither seems to suffice, probably in part because       */
2960     /* even with USE_PROC_FOR_LIBRARIES, we don't scan parts of stack   */
2961     /* segments that appear to be out of bounds.  Thus we actually      */
2962     /* do both, which seems to yield the best results.                  */
2963 #   define USE_PROC_FOR_LIBRARIES
2964 #endif
2965
2966 #ifndef STACK_GROWS_UP
2967 # define STACK_GROWS_DOWN
2968 #endif
2969
2970 #ifndef CPP_WORDSZ
2971 # define CPP_WORDSZ 32
2972 #endif
2973
2974 #ifndef OS_TYPE
2975 # define OS_TYPE ""
2976 #endif
2977
2978 #ifndef DATAEND
2979 # if !defined(CPPCHECK)
2980     extern int end[];
2981 # endif
2982 # define DATAEND ((ptr_t)(end))
2983 #endif
2984
2985 /* Workaround for Android NDK clang 3.5+ (as of NDK r10e) which does    */
2986 /* not provide correct _end symbol.  Unfortunately, alternate __end__   */
2987 /* symbol is provided only by NDK "bfd" linker.                         */
2988 #if defined(HOST_ANDROID) && defined(__clang__) \
2989     && !defined(BROKEN_UUENDUU_SYM)
2990 # undef DATAEND
2991 # pragma weak __end__
2992   extern int __end__[];
2993 # define DATAEND (__end__ != 0 ? (ptr_t)__end__ : (ptr_t)_end)
2994 #endif
2995
2996 #if (defined(SVR4) || defined(HOST_ANDROID) || defined(HOST_TIZEN)) \
2997     && !defined(GETPAGESIZE)
2998   EXTERN_C_END
2999 # include <unistd.h>
3000   EXTERN_C_BEGIN
3001 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
3002 #endif
3003
3004 #ifndef GETPAGESIZE
3005 # if defined(SOLARIS) || defined(IRIX5) || defined(LINUX) \
3006      || defined(NETBSD) || defined(FREEBSD) || defined(HPUX)
3007     EXTERN_C_END
3008 #   include <unistd.h>
3009     EXTERN_C_BEGIN
3010 # endif
3011 # define GETPAGESIZE() (unsigned)getpagesize()
3012 #endif
3013
3014 #if defined(HOST_ANDROID) && !(__ANDROID_API__ >= 23) \
3015     && ((defined(MIPS) && (CPP_WORDSZ == 32)) \
3016         || defined(ARM32) || defined(I386) /* but not x32 */)
3017   /* tkill() exists only on arm32/mips(32)/x86. */
3018   /* NDK r11+ deprecates tkill() but keeps it for Mono clients. */
3019 # define USE_TKILL_ON_ANDROID
3020 #endif
3021
3022 #if defined(SOLARIS) || defined(DRSNX) || defined(UTS4)
3023         /* OS has SVR4 generic features.        */
3024         /* Probably others also qualify.        */
3025 # define SVR4
3026 #endif
3027
3028 #if defined(SOLARIS) || defined(DRSNX)
3029         /* OS has SOLARIS style semi-undocumented interface     */
3030         /* to dynamic loader.                                   */
3031 # define SOLARISDL
3032         /* OS has SOLARIS style signal handlers.        */
3033 # define SUNOS5SIGS
3034 #endif
3035
3036 #if defined(HPUX)
3037 # define SUNOS5SIGS
3038 #endif
3039
3040 #if defined(FREEBSD) && (defined(__DragonFly__) || __FreeBSD__ >= 4 \
3041                          || (__FreeBSD_kernel__ >= 4))
3042 # define SUNOS5SIGS
3043 #endif
3044
3045 #if !defined(GC_EXPLICIT_SIGNALS_UNBLOCK) && defined(SUNOS5SIGS) \
3046     && !defined(GC_NO_PTHREAD_SIGMASK)
3047 # define GC_EXPLICIT_SIGNALS_UNBLOCK
3048 #endif
3049
3050 #if !defined(NO_SIGNALS_UNBLOCK_IN_MAIN) && defined(GC_NO_PTHREAD_SIGMASK)
3051 # define NO_SIGNALS_UNBLOCK_IN_MAIN
3052 #endif
3053
3054 #if !defined(NO_MARKER_SPECIAL_SIGMASK) \
3055     && (defined(NACL) || defined(GC_WIN32_PTHREADS))
3056   /* Either there is no pthread_sigmask(), or GC marker thread cannot   */
3057   /* steal and drop user signal calls.                                  */
3058 # define NO_MARKER_SPECIAL_SIGMASK
3059 #endif
3060
3061 #ifdef GC_NETBSD_THREADS
3062 # define SIGRTMIN 33
3063 # define SIGRTMAX 63
3064   /* It seems to be necessary to wait until threads have restarted.     */
3065   /* But it is unclear why that is the case.                            */
3066 # define GC_NETBSD_THREADS_WORKAROUND
3067 #endif
3068
3069 #ifdef GC_OPENBSD_THREADS
3070   EXTERN_C_END
3071 # include <sys/param.h>
3072   EXTERN_C_BEGIN
3073   /* Prior to 5.2 release, OpenBSD had user threads and required        */
3074   /* special handling.                                                  */
3075 # if OpenBSD < 201211
3076 #   define GC_OPENBSD_UTHREADS 1
3077 # endif
3078 #endif /* GC_OPENBSD_THREADS */
3079
3080 #if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
3081     || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
3082     || defined(DGUX) || defined(BSD) || defined(HAIKU) || defined(HURD) \
3083     || defined(AIX) || defined(DARWIN) || defined(OSF1)
3084 # define UNIX_LIKE      /* Basic Unix-like system calls work.   */
3085 #endif
3086
3087 #if defined(CPPCHECK)
3088 # undef CPP_WORDSZ
3089 # define CPP_WORDSZ (__SIZEOF_POINTER__ * 8)
3090 #elif CPP_WORDSZ != 32 && CPP_WORDSZ != 64
3091 #   error Bad word size
3092 #endif
3093
3094 #if !defined(ALIGNMENT) && !defined(CPPCHECK)
3095 # error Undefined ALIGNMENT
3096 #endif
3097
3098 #ifdef PCR
3099 # undef DYNAMIC_LOADING
3100 # undef STACKBOTTOM
3101 # undef HEURISTIC1
3102 # undef HEURISTIC2
3103 # undef PROC_VDB
3104 # undef MPROTECT_VDB
3105 # define PCR_VDB
3106 #endif
3107
3108 #if !defined(STACKBOTTOM) && (defined(ECOS) || defined(NOSYS)) \
3109     && !defined(CPPCHECK)
3110 # error Undefined STACKBOTTOM
3111 #endif
3112
3113 #ifdef IGNORE_DYNAMIC_LOADING
3114 # undef DYNAMIC_LOADING
3115 #endif
3116
3117 #if defined(SMALL_CONFIG) && !defined(GC_DISABLE_INCREMENTAL)
3118   /* Presumably not worth the space it takes.   */
3119 # define GC_DISABLE_INCREMENTAL
3120 #endif
3121
3122 #if (defined(MSWIN32) || defined(MSWINCE)) && !defined(USE_WINALLOC)
3123   /* USE_WINALLOC is only an option for Cygwin. */
3124 # define USE_WINALLOC 1
3125 #endif
3126
3127 #ifdef USE_WINALLOC
3128 # undef USE_MMAP
3129 #endif
3130
3131 #if defined(DARWIN) || defined(FREEBSD) || defined(HAIKU) \
3132     || defined(IRIX5) || defined(LINUX) || defined(NETBSD) \
3133     || defined(OPENBSD) || defined(SOLARIS) \
3134     || ((defined(CYGWIN32) || defined(USE_MMAP) || defined(USE_MUNMAP)) \
3135         && !defined(USE_WINALLOC))
3136   /* Try both sbrk and mmap, in that order.     */
3137 # define MMAP_SUPPORTED
3138 #endif
3139
3140 /* Xbox One (DURANGO) may not need to be this aggressive, but the       */
3141 /* default is likely too lax under heavy allocation pressure.           */
3142 /* The platform does not have a virtual paging system, so it does not   */
3143 /* have a large virtual address space that a standard x64 platform has. */
3144 #if defined(USE_MUNMAP) && !defined(MUNMAP_THRESHOLD) \
3145     && (defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \
3146         || defined(SN_TARGET_PSP2) || defined(MSWIN_XBOX1))
3147 # define MUNMAP_THRESHOLD 2
3148 #endif
3149
3150 #if defined(GC_DISABLE_INCREMENTAL) || defined(DEFAULT_VDB)
3151 # undef GWW_VDB
3152 # undef MPROTECT_VDB
3153 # undef PCR_VDB
3154 # undef PROC_VDB
3155 #endif
3156
3157 #ifdef GC_DISABLE_INCREMENTAL
3158 # undef CHECKSUMS
3159 #endif
3160
3161 #ifdef USE_GLOBAL_ALLOC
3162   /* Cannot pass MEM_WRITE_WATCH to GlobalAlloc().      */
3163 # undef GWW_VDB
3164 #endif
3165
3166 #if defined(BASE_ATOMIC_OPS_EMULATED)
3167   /* GC_write_fault_handler() cannot use lock-based atomic primitives   */
3168   /* as this could lead to a deadlock.                                  */
3169 # undef MPROTECT_VDB
3170 #endif
3171
3172 #if defined(USE_PROC_FOR_LIBRARIES) && defined(GC_LINUX_THREADS)
3173   /* Incremental GC is incompatible with /proc roots.   */
3174 # undef MPROTECT_VDB
3175 #endif
3176
3177 #if defined(MPROTECT_VDB) && defined(GC_PREFER_MPROTECT_VDB)
3178   /* Choose MPROTECT_VDB manually (if multiple strategies available).   */
3179 # undef PCR_VDB
3180 # undef PROC_VDB
3181   /* #undef GWW_VDB - handled in os_dep.c       */
3182 #endif
3183
3184 #ifdef PROC_VDB
3185   /* Multi-VDB mode is not implemented. */
3186 # undef MPROTECT_VDB
3187 #endif
3188
3189 #if defined(MPROTECT_VDB) && !defined(MSWIN32) && !defined(MSWINCE)
3190 # include <signal.h> /* for SA_SIGINFO, SIGBUS */
3191 #endif
3192
3193 #if defined(SIGBUS) && !defined(HAVE_SIGBUS) && !defined(CPPCHECK)
3194 # define HAVE_SIGBUS
3195 #endif
3196
3197 #ifndef SA_SIGINFO
3198 # define NO_SA_SIGACTION
3199 #endif
3200
3201 #if defined(NO_SA_SIGACTION) && defined(MPROTECT_VDB) && !defined(DARWIN) \
3202     && !defined(MSWIN32) && !defined(MSWINCE)
3203 # undef MPROTECT_VDB
3204 #endif
3205
3206 #if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) \
3207     && !defined(GWW_VDB) && !defined(DEFAULT_VDB) \
3208     && !defined(GC_DISABLE_INCREMENTAL)
3209 # define DEFAULT_VDB
3210 #endif
3211
3212 #if ((defined(UNIX_LIKE) && (defined(DARWIN) || defined(HAIKU) \
3213                              || defined(HURD) || defined(OPENBSD) \
3214                              || defined(ARM32) \
3215                              || defined(AVR32) || defined(MIPS) \
3216                              || defined(NIOS2) || defined(OR1K))) \
3217      || (defined(LINUX) && !defined(__gnu_linux__)) \
3218      || (defined(RTEMS) && defined(I386)) || defined(HOST_ANDROID)) \
3219     && !defined(NO_GETCONTEXT)
3220 # define NO_GETCONTEXT 1
3221 #endif
3222
3223 #ifndef PREFETCH
3224 # if GC_GNUC_PREREQ(3, 0) && !defined(NO_PREFETCH)
3225 #   define PREFETCH(x) __builtin_prefetch((x), 0, 0)
3226 # else
3227 #   define PREFETCH(x) (void)0
3228 # endif
3229 #endif
3230
3231 #ifndef GC_PREFETCH_FOR_WRITE
3232 # if GC_GNUC_PREREQ(3, 0) && !defined(GC_NO_PREFETCH_FOR_WRITE)
3233 #   define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
3234 # else
3235 #   define GC_PREFETCH_FOR_WRITE(x) (void)0
3236 # endif
3237 #endif
3238
3239 #ifndef CACHE_LINE_SIZE
3240 # define CACHE_LINE_SIZE 32     /* Wild guess   */
3241 #endif
3242
3243 #ifndef STATIC
3244 # ifdef GC_ASSERTIONS
3245 #   define STATIC /* ignore to aid debugging (or profiling) */
3246 # else
3247 #   define STATIC static
3248 # endif
3249 #endif
3250
3251 #if defined(LINUX) && (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64) \
3252                        || !defined(SMALL_CONFIG))
3253 # define NEED_PROC_MAPS
3254 #endif
3255
3256 #if defined(LINUX) || defined(HURD) || defined(__GLIBC__)
3257 # define REGISTER_LIBRARIES_EARLY
3258   /* We sometimes use dl_iterate_phdr, which may acquire an internal    */
3259   /* lock.  This isn't safe after the world has stopped.  So we must    */
3260   /* call GC_register_dynamic_libraries before stopping the world.      */
3261   /* For performance reasons, this may be beneficial on other           */
3262   /* platforms as well, though it should be avoided in win32.           */
3263 #endif /* LINUX */
3264
3265 #if defined(SEARCH_FOR_DATA_START)
3266   extern ptr_t GC_data_start;
3267 # define DATASTART GC_data_start
3268 #endif
3269
3270 #ifndef HEAP_START
3271 # define HEAP_START ((ptr_t)0)
3272 #endif
3273
3274 #ifndef CLEAR_DOUBLE
3275 # define CLEAR_DOUBLE(x) (((word*)(x))[0] = 0, ((word*)(x))[1] = 0)
3276 #endif
3277
3278 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
3279     && !defined(INCLUDE_LINUX_THREAD_DESCR)
3280   /* Will not work, since libc and the dynamic loader use thread        */
3281   /* locals, sometimes as the only reference.                           */
3282 # define INCLUDE_LINUX_THREAD_DESCR
3283 #endif
3284
3285 #if !defined(CPPCHECK)
3286 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
3287 #   error Inconsistent configuration
3288 # endif
3289 # if defined(GC_LINUX_THREADS) && !defined(LINUX) && !defined(NACL)
3290 #   error Inconsistent configuration
3291 # endif
3292 # if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
3293 #   error Inconsistent configuration
3294 # endif
3295 # if defined(GC_FREEBSD_THREADS) && !defined(FREEBSD)
3296 #   error Inconsistent configuration
3297 # endif
3298 # if defined(GC_SOLARIS_THREADS) && !defined(SOLARIS)
3299 #   error Inconsistent configuration
3300 # endif
3301 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
3302 #   error Inconsistent configuration
3303 # endif
3304 # if defined(GC_AIX_THREADS) && !defined(_AIX)
3305 #   error Inconsistent configuration
3306 # endif
3307 # if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) && !defined(MSWIN32) \
3308      && !defined(MSWINCE) && !defined(MSWIN_XBOX1)
3309 #   error Inconsistent configuration
3310 # endif
3311 # if defined(GC_WIN32_PTHREADS) && defined(CYGWIN32)
3312 #   error Inconsistent configuration
3313 # endif
3314 #endif /* !CPPCHECK */
3315
3316 #if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS) \
3317     || ((defined(NN_PLATFORM_CTR) || defined(NINTENDO_SWITCH) \
3318          || defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \
3319          || defined(SN_TARGET_PSP2)) && defined(GC_THREADS))
3320 # define THREADS
3321 #endif
3322
3323 #if defined(PARALLEL_MARK) && !defined(THREADS) && !defined(CPPCHECK)
3324 # error Invalid config: PARALLEL_MARK requires GC_THREADS
3325 #endif
3326
3327 #if defined(GWW_VDB) && !defined(USE_WINALLOC) && !defined(CPPCHECK)
3328 # error Invalid config: GWW_VDB requires USE_WINALLOC
3329 #endif
3330
3331 #if (((defined(MSWIN32) || defined(MSWINCE)) && !defined(__GNUC__)) \
3332         || (defined(MSWIN32) && defined(I386)) /* for Win98 */ \
3333         || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))) \
3334     && !defined(NO_CRT) && !defined(NO_WRAP_MARK_SOME)
3335   /* Under rare conditions, we may end up marking from nonexistent      */
3336   /* memory.  Hence we need to be prepared to recover by running        */
3337   /* GC_mark_some with a suitable handler in place.                     */
3338   /* TODO: Probably replace __GNUC__ above with ndef GC_PTHREADS.       */
3339   /* FIXME: Should we really need it for WinCE?  If yes then            */
3340   /* WRAP_MARK_SOME should be also defined for CeGCC which requires     */
3341   /* CPU/OS-specific code in mark_ex_handler and GC_mark_some (for      */
3342   /* manual stack unwinding and exception handler installation).        */
3343 # define WRAP_MARK_SOME
3344 #endif
3345
3346 #if defined(PARALLEL_MARK) && !defined(DEFAULT_STACK_MAYBE_SMALL) \
3347     && (defined(HPUX) || defined(GC_DGUX386_THREADS) \
3348         || defined(NO_GETCONTEXT) /* e.g. musl */)
3349     /* TODO: Test default stack size in configure. */
3350 # define DEFAULT_STACK_MAYBE_SMALL
3351 #endif
3352
3353 #ifdef PARALLEL_MARK
3354   /* The minimum stack size for a marker thread. */
3355 # define MIN_STACK_SIZE (8 * HBLKSIZE * sizeof(word))
3356 #endif
3357
3358 #if defined(HOST_ANDROID) && !defined(THREADS) \
3359     && !defined(USE_GET_STACKBASE_FOR_MAIN)
3360   /* Always use pthread_attr_getstack on Android ("-lpthread" option is  */
3361   /* not needed to be specified manually) since GC_linux_main_stack_base */
3362   /* causes app crash if invoked inside Dalvik VM.                       */
3363 # define USE_GET_STACKBASE_FOR_MAIN
3364 #endif
3365
3366 /* Outline pthread primitives to use in GC_get_[main_]stack_base.       */
3367 #if ((defined(FREEBSD) && defined(__GLIBC__)) /* kFreeBSD */ \
3368      || defined(LINUX) || defined(NETBSD) || defined(HOST_ANDROID)) \
3369     && !defined(NO_PTHREAD_GETATTR_NP)
3370 # define HAVE_PTHREAD_GETATTR_NP 1
3371 #elif defined(FREEBSD) && !defined(__GLIBC__) \
3372       && !defined(NO_PTHREAD_ATTR_GET_NP)
3373 # define HAVE_PTHREAD_NP_H 1 /* requires include pthread_np.h */
3374 # define HAVE_PTHREAD_ATTR_GET_NP 1
3375 #endif
3376
3377 #if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE) \
3378     && !defined(HOST_ANDROID)
3379   /* Make the code cancellation-safe.  This basically means that we     */
3380   /* ensure that cancellation requests are ignored while we are in      */
3381   /* the collector.  This applies only to Posix deferred cancellation;  */
3382   /* we don't handle Posix asynchronous cancellation.                   */
3383   /* Note that this only works if pthread_setcancelstate is             */
3384   /* async-signal-safe, at least in the absence of asynchronous         */
3385   /* cancellation.  This appears to be true for the glibc version,      */
3386   /* though it is not documented.  Without that assumption, there       */
3387   /* seems to be no way to safely wait in a signal handler, which       */
3388   /* we need to do for thread suspension.                               */
3389   /* Also note that little other code appears to be cancellation-safe.  */
3390   /* Hence it may make sense to turn this off for performance.          */
3391 # define CANCEL_SAFE
3392 #endif
3393
3394 #ifdef CANCEL_SAFE
3395 # define IF_CANCEL(x) x
3396 #else
3397 # define IF_CANCEL(x) /* empty */
3398 #endif
3399
3400 #if !defined(CAN_HANDLE_FORK) && !defined(NO_HANDLE_FORK) \
3401     && !defined(HAVE_NO_FORK) \
3402     && ((defined(GC_PTHREADS) && !defined(NACL) \
3403          && !defined(GC_WIN32_PTHREADS) && !defined(USE_WINALLOC)) \
3404         || (defined(DARWIN) && defined(MPROTECT_VDB)) || defined(HANDLE_FORK))
3405   /* Attempts (where supported and requested) to make GC_malloc work in */
3406   /* a child process fork'ed from a multi-threaded parent.              */
3407 # define CAN_HANDLE_FORK
3408 #endif
3409
3410 #if defined(CAN_HANDLE_FORK) && !defined(CAN_CALL_ATFORK) \
3411     && !defined(HURD) && !defined(SN_TARGET_ORBIS) && !defined(HOST_TIZEN) \
3412     && (!defined(HOST_ANDROID) || __ANDROID_API__ >= 21)
3413   /* Have working pthread_atfork().     */
3414 # define CAN_CALL_ATFORK
3415 #endif
3416
3417 #if !defined(CAN_HANDLE_FORK) && !defined(HAVE_NO_FORK) \
3418     && (defined(MSWIN32) || defined(MSWINCE) || defined(DOS4GW) \
3419         || defined(OS2) || defined(SYMBIAN) /* and probably others ... */)
3420 # define HAVE_NO_FORK
3421 #endif
3422
3423 #if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES) \
3424     && defined(PARALLEL_MARK)
3425    /* Minimize compare-and-swap usage.  */
3426 #  define USE_MARK_BYTES
3427 #endif
3428
3429 #if (defined(MSWINCE) && !defined(__CEGCC__) || defined(MSWINRT_FLAVOR)) \
3430     && !defined(NO_GETENV)
3431 # define NO_GETENV
3432 #endif
3433
3434 #if (defined(NO_GETENV) || defined(MSWINCE)) && !defined(NO_GETENV_WIN32)
3435 # define NO_GETENV_WIN32
3436 #endif
3437
3438 #if !defined(MSGBOX_ON_ERROR) && !defined(NO_MSGBOX_ON_ERROR) \
3439     && !defined(SMALL_CONFIG) && defined(MSWIN32) \
3440     && !defined(MSWINRT_FLAVOR) && !defined(MSWIN_XBOX1)
3441   /* Show Windows message box with "OK" button on a GC fatal error.     */
3442   /* Client application is terminated once the user clicks the button.  */
3443 # define MSGBOX_ON_ERROR
3444 #endif
3445
3446 #ifndef STRTOULL
3447 # if defined(_WIN64) && !defined(__GNUC__)
3448 #   define STRTOULL _strtoui64
3449 # elif defined(_LLP64) || defined(__LLP64__) || defined(_WIN64)
3450 #   define STRTOULL strtoull
3451 # else
3452     /* strtoul() fits since sizeof(long) >= sizeof(word).       */
3453 #   define STRTOULL strtoul
3454 # endif
3455 #endif /* !STRTOULL */
3456
3457 #ifndef GC_WORD_C
3458 # if defined(_WIN64) && !defined(__GNUC__)
3459 #   define GC_WORD_C(val) val##ui64
3460 # elif defined(_LLP64) || defined(__LLP64__) || defined(_WIN64)
3461 #   define GC_WORD_C(val) val##ULL
3462 # else
3463 #   define GC_WORD_C(val) ((word)val##UL)
3464 # endif
3465 #endif /* !GC_WORD_C */
3466
3467 #if defined(__has_feature)
3468   /* __has_feature() is supported.      */
3469 # if __has_feature(address_sanitizer) && !defined(ADDRESS_SANITIZER)
3470 #   define ADDRESS_SANITIZER
3471 # endif
3472 # if __has_feature(memory_sanitizer) && !defined(MEMORY_SANITIZER)
3473 #   define MEMORY_SANITIZER
3474 # endif
3475 # if __has_feature(thread_sanitizer) && !defined(THREAD_SANITIZER)
3476 #   define THREAD_SANITIZER
3477 # endif
3478 #else
3479 # ifdef __SANITIZE_ADDRESS__
3480     /* GCC v4.8+ */
3481 #   define ADDRESS_SANITIZER
3482 # endif
3483 #endif /* !__has_feature */
3484
3485 #if defined(SPARC)
3486 # define ASM_CLEAR_CODE /* Stack clearing is crucial, and we    */
3487                         /* include assembly code to do it well. */
3488 #endif
3489
3490 /* Can we save call chain in objects for debugging?                     */
3491 /* SET NFRAMES (# of saved frames) and NARGS (#of args for each         */
3492 /* frame) to reasonable values for the platform.                        */
3493 /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified     */
3494 /* at build time, though we feel free to adjust it slightly.            */
3495 /* Define NEED_CALLINFO if we either save the call stack or             */
3496 /* GC_ADD_CALLER is defined.                                            */
3497 /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.                              */
3498 #if defined(SPARC)
3499 # define CAN_SAVE_CALL_ARGS
3500 #endif
3501 #if (defined(I386) || defined(X86_64)) \
3502     && (defined(LINUX) || defined(__GLIBC__))
3503   /* SAVE_CALL_CHAIN is supported if the code is compiled to save       */
3504   /* frame pointers by default, i.e. no -fomit-frame-pointer flag.      */
3505 # define CAN_SAVE_CALL_ARGS
3506 #endif
3507
3508 #if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
3509     && defined(GC_CAN_SAVE_CALL_STACKS)
3510 # define SAVE_CALL_CHAIN
3511 #endif
3512 #ifdef SAVE_CALL_CHAIN
3513 # if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
3514 #   define NARGS SAVE_CALL_NARGS
3515 # else
3516 #   define NARGS 0      /* Number of arguments to save for each call.   */
3517 # endif
3518 #endif
3519 #ifdef SAVE_CALL_CHAIN
3520 # if !defined(SAVE_CALL_COUNT) || defined(CPPCHECK)
3521 #   define NFRAMES 6    /* Number of frames to save. Even for   */
3522                         /* alignment reasons.                   */
3523 # else
3524 #   define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
3525 # endif
3526 # define NEED_CALLINFO
3527 #endif /* SAVE_CALL_CHAIN */
3528 #ifdef GC_ADD_CALLER
3529 # define NFRAMES 1
3530 # define NARGS 0
3531 # define NEED_CALLINFO
3532 #endif
3533
3534 #if (defined(FREEBSD) || (defined(DARWIN) && !defined(_POSIX_C_SOURCE)) \
3535         || (defined(SOLARIS) && (!defined(_XOPEN_SOURCE) \
3536                                  || defined(__EXTENSIONS__))) \
3537         || defined(LINUX)) && !defined(HAVE_DLADDR)
3538 # define HAVE_DLADDR 1
3539 #endif
3540
3541 #if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
3542 # define DBG_HDRS_ALL 1
3543 #endif
3544
3545 #if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
3546 # define POINTER_SHIFT 0
3547 #endif
3548
3549 #if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
3550 # define POINTER_MASK ((word)(-1))
3551 #endif
3552
3553 #if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
3554 # define FIXUP_POINTER(p) (p = ((p) & POINTER_MASK) << POINTER_SHIFT)
3555 #endif
3556
3557 #if defined(FIXUP_POINTER)
3558 # define NEED_FIXUP_POINTER
3559 #else
3560 # define FIXUP_POINTER(p)
3561 #endif
3562
3563 #if !defined(MARK_BIT_PER_GRANULE) && !defined(MARK_BIT_PER_OBJ)
3564 # define MARK_BIT_PER_GRANULE   /* Usually faster       */
3565 #endif
3566
3567 /* Some static sanity tests.    */
3568 #if !defined(CPPCHECK)
3569 # if defined(MARK_BIT_PER_GRANULE) && defined(MARK_BIT_PER_OBJ)
3570 #   error Define only one of MARK_BIT_PER_GRANULE and MARK_BIT_PER_OBJ
3571 # endif
3572 # if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
3573 #   error Only one of STACK_GROWS_UP and STACK_GROWS_DOWN should be defined
3574 # endif
3575 # if !defined(STACK_GROWS_UP) && !defined(STACK_GROWS_DOWN)
3576 #   error One of STACK_GROWS_UP and STACK_GROWS_DOWN should be defined
3577 # endif
3578 # if defined(REDIRECT_MALLOC) && defined(THREADS) && !defined(LINUX) \
3579      && !defined(REDIRECT_MALLOC_IN_HEADER)
3580 #   error REDIRECT_MALLOC with THREADS works at most on Linux
3581 # endif
3582 #endif /* !CPPCHECK */
3583
3584 #ifdef GC_PRIVATE_H
3585         /* This relies on some type definitions from gc_priv.h, from    */
3586         /* where it's normally included.                                */
3587         /*                                                              */
3588         /* How to get heap memory from the OS:                          */
3589         /* Note that sbrk()-like allocation is preferred, since it      */
3590         /* usually makes it possible to merge consecutively allocated   */
3591         /* chunks.  It also avoids unintended recursion with            */
3592         /* REDIRECT_MALLOC macro defined.                               */
3593         /* GET_MEM() argument should be of size_t type and have         */
3594         /* no side-effect.  GET_MEM() returns HBLKSIZE-aligned chunk;   */
3595         /* 0 is taken to mean failure.                                  */
3596         /* In case of MMAP_SUPPORTED, the argument must also be         */
3597         /* a multiple of a physical page size.                          */
3598         /* GET_MEM is currently not assumed to retrieve 0 filled space, */
3599         /* though we should perhaps take advantage of the case in which */
3600         /* does.                                                        */
3601         struct hblk;    /* See gc_priv.h.       */
3602 # if defined(PCR)
3603     char * real_malloc(size_t bytes);
3604 #   define GET_MEM(bytes) HBLKPTR(real_malloc(SIZET_SAT_ADD(bytes, \
3605                                                             GC_page_size)) \
3606                                           + GC_page_size-1)
3607 # elif defined(OS2)
3608     void * os2_alloc(size_t bytes);
3609 #   define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc( \
3610                                             SIZET_SAT_ADD(bytes, \
3611                                                           GC_page_size)) \
3612                                   + GC_page_size-1)
3613 # elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) \
3614         || (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) \
3615         || (defined(SOLARIS) && !defined(USE_MMAP)) || defined(RTEMS) \
3616         || defined(__CC_ARM)
3617 #   define GET_MEM(bytes) HBLKPTR((size_t)calloc(1, \
3618                                             SIZET_SAT_ADD(bytes, \
3619                                                           GC_page_size)) \
3620                                   + GC_page_size - 1)
3621 # elif defined(MSWIN_XBOX1)
3622     ptr_t GC_durango_get_mem(size_t bytes);
3623 #   define GET_MEM(bytes) (struct hblk *)GC_durango_get_mem(bytes)
3624 # elif defined(MSWIN32) || defined(CYGWIN32)
3625     ptr_t GC_win32_get_mem(size_t bytes);
3626 #   define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
3627 # elif defined(MACOS)
3628 #   if defined(USE_TEMPORARY_MEMORY)
3629       Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);
3630 #     define GET_MEM(bytes) HBLKPTR(GC_MacTemporaryNewPtr( \
3631                                         SIZET_SAT_ADD(bytes, \
3632                                                       GC_page_size), true) \
3633                         + GC_page_size-1)
3634 #   else
3635 #     define GET_MEM(bytes) HBLKPTR(NewPtrClear(SIZET_SAT_ADD(bytes, \
3636                                                               GC_page_size)) \
3637                                     + GC_page_size-1)
3638 #   endif
3639 # elif defined(MSWINCE)
3640     ptr_t GC_wince_get_mem(size_t bytes);
3641 #   define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
3642 # elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
3643     void *GC_amiga_get_mem(size_t bytes);
3644 #   define GET_MEM(bytes) HBLKPTR((size_t)GC_amiga_get_mem( \
3645                                             SIZET_SAT_ADD(bytes, \
3646                                                           GC_page_size)) \
3647                           + GC_page_size-1)
3648 # elif defined(SN_TARGET_ORBIS)
3649     void *ps4_get_mem(size_t bytes);
3650 #   define GET_MEM(bytes) (struct hblk*)ps4_get_mem(bytes)
3651 # elif defined(SN_TARGET_PS3)
3652     void *ps3_get_mem(size_t bytes);
3653 #   define GET_MEM(bytes) (struct hblk*)ps3_get_mem(bytes)
3654 # elif defined(SN_TARGET_PSP2)
3655     void *psp2_get_mem(size_t bytes);
3656 #   define GET_MEM(bytes) (struct hblk*)psp2_get_mem(bytes)
3657 # elif defined(NINTENDO_SWITCH)
3658     void *switch_get_mem(size_t bytes);
3659 #   define GET_MEM(bytes) (struct hblk*)switch_get_mem(bytes)
3660 # elif defined(HAIKU)
3661     ptr_t GC_haiku_get_mem(size_t bytes);
3662 #   define GET_MEM(bytes) (struct hblk*)GC_haiku_get_mem(bytes)
3663 # else
3664     ptr_t GC_unix_get_mem(size_t bytes);
3665 #   define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
3666 # endif
3667 #endif /* GC_PRIVATE_H */
3668
3669 EXTERN_C_END
3670
3671 #endif /* GCCONFIG_H */