OSDN Git Service

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