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