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