OSDN Git Service

* include/private/gcconfig.h (alpha-linux): Use LINUX_STACKBOTTOM.
[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         /* libc_stack_end is not set reliably for sparc64 */
928 #       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
929 #     else
930 #       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
931 #       define LINUX_STACKBOTTOM
932 #     endif
933 #   endif
934 #   ifdef OPENBSD
935 #     define OS_TYPE "OPENBSD"
936 #     define STACKBOTTOM ((ptr_t) 0xf8000000)
937       extern int etext[];
938 #     define DATASTART ((ptr_t)(etext))
939 #   endif
940 #   ifdef NETBSD
941 #     define OS_TYPE "NETBSD"
942 #     define HEURISTIC2
943 #     ifdef __ELF__
944 #       define DATASTART GC_data_start
945 #       define DYNAMIC_LOADING
946 #     else
947         extern char etext[];
948 #       define DATASTART ((ptr_t)(etext))
949 #     endif
950 #   endif
951 # endif
952
953 # ifdef I386
954 #   define MACH_TYPE "I386"
955 #   if defined(__LP64__) || defined(_WIN64)
956 #     define CPP_WORDSZ 64
957 #     define ALIGNMENT 8
958 #   else
959 #     define CPP_WORDSZ 32
960 #     define ALIGNMENT 4
961                         /* Appears to hold for all "32 bit" compilers   */
962                         /* except Borland.  The -a4 option fixes        */
963                         /* Borland.                                     */
964                         /* Ivan Demakov: For Watcom the option is -zp4. */
965 #   endif
966 #   ifndef SMALL_CONFIG
967 #     define ALIGN_DOUBLE /* Not strictly necessary, but may give speed   */
968                           /* improvement on Pentiums.                     */
969 #   endif
970 #   ifdef HAVE_BUILTIN_UNWIND_INIT
971 #       define USE_GENERIC_PUSH_REGS
972 #   endif
973 #   ifdef SEQUENT
974 #       define OS_TYPE "SEQUENT"
975         extern int etext[];
976 #       define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
977 #       define STACKBOTTOM ((ptr_t) 0x3ffff000) 
978 #   endif
979 #   ifdef BEOS
980 #     define OS_TYPE "BEOS"
981 #     include <OS.h>
982 #     define GETPAGESIZE() B_PAGE_SIZE
983       extern int etext[];
984 #     define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
985 #   endif
986 #   ifdef SUNOS5
987 #       define OS_TYPE "SUNOS5"
988         extern int _etext[], _end[];
989         extern ptr_t GC_SysVGetDataStart();
990 #       define DATASTART GC_SysVGetDataStart(0x1000, _etext)
991 #       define DATAEND (_end)
992 /*      # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,      */
993 /*      but reportedly breaks under 2.8.  It appears that the stack     */
994 /*      base is a property of the executable, so this should not break  */
995 /*      old executables.                                                */
996 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
997 #       include <sys/vm.h>
998 #       define STACKBOTTOM USRSTACK
999 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1000 /* It appears to be fixed in 2.8 and 2.9.                               */
1001 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1002 #         define PROC_VDB
1003 #       endif
1004 #       define DYNAMIC_LOADING
1005 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1006 #           define USE_MMAP
1007             /* Otherwise we now use calloc.  Mmap may result in the     */
1008             /* heap interleaved with thread stacks, which can result in */
1009             /* excessive blacklisting.  Sbrk is unusable since it       */
1010             /* doesn't interact correctly with the system malloc.       */
1011 #       endif
1012 #       ifdef USE_MMAP
1013 #         define HEAP_START (ptr_t)0x40000000
1014 #       else
1015 #         define HEAP_START DATAEND
1016 #       endif
1017 #   endif
1018 #   ifdef SCO
1019 #       define OS_TYPE "SCO"
1020         extern int etext[];
1021 #       define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \
1022                                   & ~0x3fffff) \
1023                                  +((word)etext & 0xfff))
1024 #       define STACKBOTTOM ((ptr_t) 0x7ffffffc)
1025 #   endif
1026 #   ifdef SCO_ELF
1027 #       define OS_TYPE "SCO_ELF"
1028         extern int etext[];
1029 #       define DATASTART ((ptr_t)(etext))
1030 #       define STACKBOTTOM ((ptr_t) 0x08048000)
1031 #       define DYNAMIC_LOADING
1032 #       define ELF_CLASS ELFCLASS32
1033 #   endif
1034 #   ifdef DGUX
1035 #       define OS_TYPE "DGUX"
1036         extern int _etext, _end;
1037         extern ptr_t GC_SysVGetDataStart();
1038 #       define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
1039 #       define DATAEND (&_end)
1040 #       define STACK_GROWS_DOWN
1041 #       define HEURISTIC2
1042 #       include <unistd.h>
1043 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
1044 #       define DYNAMIC_LOADING
1045 #       ifndef USE_MMAP
1046 #         define USE_MMAP
1047 #       endif /* USE_MMAP */
1048 #       define MAP_FAILED (void *) -1
1049 #       ifdef USE_MMAP
1050 #         define HEAP_START (ptr_t)0x40000000
1051 #       else /* USE_MMAP */
1052 #         define HEAP_START DATAEND
1053 #       endif /* USE_MMAP */
1054 #   endif /* DGUX */
1055
1056 #   ifdef LINUX
1057 #       ifndef __GNUC__
1058           /* The Intel compiler doesn't like inline assembly */
1059 #         define USE_GENERIC_PUSH_REGS
1060 #       endif
1061 #       define OS_TYPE "LINUX"
1062 #       define LINUX_STACKBOTTOM
1063 #       if 0
1064 #         define HEURISTIC1
1065 #         undef STACK_GRAN
1066 #         define STACK_GRAN 0x10000000
1067           /* STACKBOTTOM is usually 0xc0000000, but this changes with   */
1068           /* different kernel configurations.  In particular, systems   */
1069           /* with 2GB physical memory will usually move the user        */
1070           /* address space limit, and hence initial SP to 0x80000000.   */
1071 #       endif
1072 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
1073 #           define MPROTECT_VDB
1074 #       else
1075             /* We seem to get random errors in incremental mode,        */
1076             /* possibly because Linux threads is itself a malloc client */
1077             /* and can't deal with the signals.                         */
1078 #       endif
1079 #       define HEAP_START (ptr_t)0x1000
1080                 /* This encourages mmap to give us low addresses,       */
1081                 /* thus allowing the heap to grow to ~3GB               */
1082 #       ifdef __ELF__
1083 #            define DYNAMIC_LOADING
1084 #            ifdef UNDEFINED    /* includes ro data */
1085                extern int _etext[];
1086 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
1087 #            endif
1088 #            include <features.h>
1089 #            if defined(__GLIBC__) && __GLIBC__ >= 2
1090 #                define SEARCH_FOR_DATA_START
1091 #            else
1092                  extern char **__environ;
1093 #                define DATASTART ((ptr_t)(&__environ))
1094                               /* hideous kludge: __environ is the first */
1095                               /* word in crt0.o, and delimits the start */
1096                               /* of the data segment, no matter which   */
1097                               /* ld options were passed through.        */
1098                               /* We could use _etext instead, but that  */
1099                               /* would include .rodata, which may       */
1100                               /* contain large read-only data tables    */
1101                               /* that we'd rather not scan.             */
1102 #            endif
1103              extern int _end[];
1104 #            define DATAEND (_end)
1105 #       else
1106              extern int etext[];
1107 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1108 #       endif
1109 #       ifdef USE_I686_PREFETCH
1110           /* FIXME: Thus should use __builtin_prefetch, but we'll leave that    */
1111           /* for the next rtelease.                                             */
1112 #         define PREFETCH(x) \
1113             __asm__ __volatile__ ("     prefetchnta     %0": : "m"(*(char *)(x)))
1114             /* Empirically prefetcht0 is much more effective at reducing        */
1115             /* cache miss stalls for the targetted load instructions.  But it   */
1116             /* seems to interfere enough with other cache traffic that the net  */
1117             /* result is worse than prefetchnta.                                */
1118 #         if 0 
1119             /* Using prefetches for write seems to have a slight negative       */
1120             /* impact on performance, at least for a PIII/500.                  */
1121 #           define PREFETCH_FOR_WRITE(x) \
1122               __asm__ __volatile__ ("   prefetcht0      %0": : "m"(*(char *)(x)))
1123 #         endif
1124 #       endif
1125 #       ifdef USE_3DNOW_PREFETCH
1126 #         define PREFETCH(x) \
1127             __asm__ __volatile__ ("     prefetch        %0": : "m"(*(char *)(x)))
1128 #         define PREFETCH_FOR_WRITE(x) \
1129             __asm__ __volatile__ ("     prefetchw       %0": : "m"(*(char *)(x)))
1130 #       endif
1131 #   endif
1132 #   ifdef CYGWIN32
1133 #       define OS_TYPE "CYGWIN32"
1134           extern int _data_start__[];
1135           extern int _data_end__[];
1136           extern int _bss_start__[];
1137           extern int _bss_end__[];
1138         /* For binutils 2.9.1, we have                  */
1139         /*      DATASTART   = _data_start__             */
1140         /*      DATAEND     = _bss_end__                */
1141         /* whereas for some earlier versions it was     */
1142         /*      DATASTART   = _bss_start__              */
1143         /*      DATAEND     = _data_end__               */
1144         /* To get it right for both, we take the        */
1145         /* minumum/maximum of the two.                  */
1146 #     ifndef MAX
1147 #       define MAX(x,y) ((x) > (y) ? (x) : (y))
1148 #     endif
1149 #     ifndef MIN
1150 #       define MIN(x,y) ((x) < (y) ? (x) : (y))
1151 #     endif
1152 #       define DATASTART ((ptr_t) MIN(_data_start__, _bss_start__))
1153 #       define DATAEND   ((ptr_t) MAX(_data_end__, _bss_end__))
1154 #       undef STACK_GRAN
1155 #       define STACK_GRAN 0x10000
1156 #       define HEURISTIC1
1157 #   endif
1158 #   ifdef OS2
1159 #       define OS_TYPE "OS2"
1160                 /* STACKBOTTOM and DATASTART are handled specially in   */
1161                 /* os_dep.c. OS2 actually has the right                 */
1162                 /* system call!                                         */
1163 #       define DATAEND  /* not needed */
1164 #       define USE_GENERIC_PUSH_REGS
1165 #   endif
1166 #   ifdef MSWIN32
1167 #       define OS_TYPE "MSWIN32"
1168                 /* STACKBOTTOM and DATASTART are handled specially in   */
1169                 /* os_dep.c.                                            */
1170 #       ifndef __WATCOMC__
1171 #         define MPROTECT_VDB
1172 #       endif
1173 #       define DATAEND  /* not needed */
1174 #   endif
1175 #   ifdef MSWINCE
1176 #       define OS_TYPE "MSWINCE"
1177 #       define DATAEND  /* not needed */
1178 #   endif
1179 #   ifdef DJGPP
1180 #       define OS_TYPE "DJGPP"
1181 #       include "stubinfo.h"
1182         extern int etext[];
1183         extern int _stklen;
1184         extern int __djgpp_stack_limit;
1185 #       define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff))
1186 /* #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
1187                                                      + _stklen)) */
1188 #       define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen))
1189                 /* This may not be right.  */
1190 #   endif
1191 #   ifdef OPENBSD
1192 #       define OS_TYPE "OPENBSD"
1193 #   endif
1194 #   ifdef FREEBSD
1195 #       define OS_TYPE "FREEBSD"
1196 #       ifndef GC_FREEBSD_THREADS
1197 #           define MPROTECT_VDB
1198 #       endif
1199 #       define SIG_SUSPEND SIGUSR1
1200 #       define SIG_THR_RESTART SIGUSR2
1201 #       define FREEBSD_STACKBOTTOM
1202 #       ifdef __ELF__
1203 #           define DYNAMIC_LOADING
1204 #       endif
1205         extern char etext[];
1206         extern char * GC_FreeBSDGetDataStart();
1207 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
1208 #   endif
1209 #   ifdef NETBSD
1210 #       define OS_TYPE "NETBSD"
1211 #       ifdef __ELF__
1212 #           define DYNAMIC_LOADING
1213 #       endif
1214 #   endif
1215 #   ifdef THREE86BSD
1216 #       define OS_TYPE "THREE86BSD"
1217 #   endif
1218 #   ifdef BSDI
1219 #       define OS_TYPE "BSDI"
1220 #   endif
1221 #   if defined(OPENBSD) || defined(NETBSD) \
1222         || defined(THREE86BSD) || defined(BSDI)
1223 #       define HEURISTIC2
1224         extern char etext[];
1225 #       define DATASTART ((ptr_t)(etext))
1226 #   endif
1227 #   ifdef NEXT
1228 #       define OS_TYPE "NEXT"
1229 #       define DATASTART ((ptr_t) get_etext())
1230 #       define STACKBOTTOM ((ptr_t)0xc0000000)
1231 #       define DATAEND  /* not needed */
1232 #   endif
1233 #   ifdef DOS4GW
1234 #     define OS_TYPE "DOS4GW"
1235       extern long __nullarea;
1236       extern char _end;
1237       extern char *_STACKTOP;
1238       /* Depending on calling conventions Watcom C either precedes
1239          or does not precedes with undescore names of C-variables.
1240          Make sure startup code variables always have the same names.  */
1241       #pragma aux __nullarea "*";
1242       #pragma aux _end "*";
1243 #     define STACKBOTTOM ((ptr_t) _STACKTOP)
1244                          /* confused? me too. */
1245 #     define DATASTART ((ptr_t) &__nullarea)
1246 #     define DATAEND ((ptr_t) &_end)
1247 #   endif
1248 #   ifdef HURD
1249 #     define OS_TYPE "HURD"
1250 #     define STACK_GROWS_DOWN
1251 #     define HEURISTIC2
1252       extern int  __data_start[];
1253 #     define DATASTART ( (ptr_t) (__data_start))
1254       extern int   _end[];
1255 #     define DATAEND ( (ptr_t) (_end))
1256 /* #     define MPROTECT_VDB  Not quite working yet? */
1257 #     define DYNAMIC_LOADING
1258 #   endif
1259 # endif
1260
1261 # ifdef NS32K
1262 #   define MACH_TYPE "NS32K"
1263 #   define ALIGNMENT 4
1264     extern char **environ;
1265 #   define DATASTART ((ptr_t)(&environ))
1266                               /* hideous kludge: environ is the first   */
1267                               /* word in crt0.o, and delimits the start */
1268                               /* of the data segment, no matter which   */
1269                               /* ld options were passed through.        */
1270 #   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */
1271 # endif
1272
1273 # ifdef MIPS
1274 #   define MACH_TYPE "MIPS"
1275 #   ifdef LINUX
1276       /* This was developed for a linuxce style platform.  Probably     */
1277       /* needs to be tweaked for workstation class machines.            */
1278 #     define OS_TYPE "LINUX"
1279 #     define DYNAMIC_LOADING
1280       extern int _end[];
1281 #     define DATAEND (_end)
1282       extern int __data_start[];
1283 #     define DATASTART ((ptr_t)(__data_start))
1284 #     define ALIGNMENT 4
1285 #     define USE_GENERIC_PUSH_REGS
1286 #     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
1287 #        define LINUX_STACKBOTTOM
1288 #     else
1289 #        define STACKBOTTOM 0x80000000
1290 #     endif
1291 #   endif /* Linux */
1292 #   ifdef EWS4800
1293 #      define HEURISTIC2
1294 #      if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1295          extern int _fdata[], _end[];
1296 #        define DATASTART ((ptr_t)_fdata)
1297 #        define DATAEND ((ptr_t)_end)
1298 #        define CPP_WORDSZ _MIPS_SZPTR
1299 #        define ALIGNMENT (_MIPS_SZPTR/8)
1300 #      else
1301          extern int etext[], edata[], end[];
1302          extern int _DYNAMIC_LINKING[], _gp[];
1303 #        define DATASTART ((ptr_t)((((word)etext + 0x3ffff) & ~0x3ffff) \
1304                + ((word)etext & 0xffff)))
1305 #        define DATAEND (edata)
1306 #        define DATASTART2 (_DYNAMIC_LINKING \
1307                ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1308                : (ptr_t)edata)
1309 #        define DATAEND2 (end)
1310 #        define ALIGNMENT 4
1311 #      endif
1312 #      define OS_TYPE "EWS4800"
1313 #      define USE_GENERIC_PUSH_REGS 1
1314 #   endif
1315 #   ifdef ULTRIX
1316 #       define HEURISTIC2
1317 #       define DATASTART (ptr_t)0x10000000
1318                               /* Could probably be slightly higher since */
1319                               /* startup code allocates lots of stuff.   */
1320 #       define OS_TYPE "ULTRIX"
1321 #       define ALIGNMENT 4
1322 #   endif
1323 #   ifdef RISCOS
1324 #       define HEURISTIC2
1325 #       define DATASTART (ptr_t)0x10000000
1326 #       define OS_TYPE "RISCOS"
1327 #       define ALIGNMENT 4  /* Required by hardware */
1328 #   endif
1329 #   ifdef IRIX5
1330 #       define HEURISTIC2
1331         extern int _fdata[];
1332 #       define DATASTART ((ptr_t)(_fdata))
1333 #       ifdef USE_MMAP
1334 #         define HEAP_START (ptr_t)0x30000000
1335 #       else
1336 #         define HEAP_START DATASTART
1337 #       endif
1338                               /* Lowest plausible heap address.         */
1339                               /* In the MMAP case, we map there.        */
1340                               /* In either case it is used to identify  */
1341                               /* heap sections so they're not           */
1342                               /* considered as roots.                   */
1343 #       define OS_TYPE "IRIX5"
1344 /*#       define MPROTECT_VDB DOB: this should work, but there is evidence */
1345 /*              of recent breakage.                                        */
1346 #       ifdef _MIPS_SZPTR
1347 #         define CPP_WORDSZ _MIPS_SZPTR
1348 #         define ALIGNMENT (_MIPS_SZPTR/8)
1349 #         if CPP_WORDSZ != 64
1350 #           define ALIGN_DOUBLE
1351 #         endif
1352 #       else
1353 #         define ALIGNMENT 4
1354 #         define ALIGN_DOUBLE
1355 #       endif
1356 #       define DYNAMIC_LOADING
1357 #   endif
1358 #   ifdef MSWINCE
1359 #       define OS_TYPE "MSWINCE"
1360 #       define ALIGNMENT 4
1361 #       define DATAEND /* not needed */
1362 #   endif
1363 #   if defined(NETBSD)
1364 #     define OS_TYPE "NETBSD"
1365 #     define ALIGNMENT 4
1366 #     define HEURISTIC2
1367 #     define USE_GENERIC_PUSH_REGS
1368 #     ifdef __ELF__
1369         extern int etext[];
1370 #       define DATASTART GC_data_start
1371 #       define NEED_FIND_LIMIT
1372 #       define DYNAMIC_LOADING
1373 #     else
1374 #       define DATASTART ((ptr_t) 0x10000000)
1375 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
1376 #     endif /* _ELF_ */
1377 #  endif
1378 # endif
1379
1380 # ifdef RS6000
1381 #   define MACH_TYPE "RS6000"
1382 #   ifdef ALIGNMENT
1383 #     undef ALIGNMENT
1384 #   endif
1385 #   ifdef IA64
1386 #     undef IA64 /* DOB: some AIX installs stupidly define IA64 in /usr/include/sys/systemcfg.h */
1387 #   endif
1388 #   ifdef __64BIT__
1389 #     define ALIGNMENT 8
1390 #     define CPP_WORDSZ 64
1391 #     define STACKBOTTOM ((ptr_t)0x1000000000000000)
1392 #   else
1393 #     define ALIGNMENT 4
1394 #     define CPP_WORDSZ 32
1395 #     define STACKBOTTOM ((ptr_t)((ulong)&errno))
1396 #   endif
1397  /* From AIX linker man page:
1398  _text Specifies the first location of the program.
1399  _etext Specifies the first location after the program.
1400  _data Specifies the first location of the data.
1401  _edata Specifies the first location after the initialized data
1402  _end or end Specifies the first location after all data.
1403  */
1404     extern int _data[], _end[];
1405 #   define DATASTART ((ptr_t)((ulong)_data))
1406 #   define DATAEND ((ptr_t)((ulong)_end))
1407     extern int errno;
1408 #   define USE_GENERIC_PUSH_REGS
1409 #   define DYNAMIC_LOADING
1410         /* For really old versions of AIX, this may have to be removed. */
1411 # endif
1412
1413 # ifdef HP_PA
1414 #   define MACH_TYPE "HP_PA"
1415 #   ifdef __LP64__
1416 #     define CPP_WORDSZ 64
1417 #     define ALIGNMENT 8
1418 #   else
1419 #     define CPP_WORDSZ 32
1420 #     define ALIGNMENT 4
1421 #     define ALIGN_DOUBLE
1422 #   endif
1423 #   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS)
1424 #     ifndef LINUX /* For now. */
1425 #       define MPROTECT_VDB
1426 #     endif
1427 #   else
1428 #     define GENERIC_COMPARE_AND_SWAP
1429         /* No compare-and-swap instruction.  Use pthread mutexes        */
1430         /* when we absolutely have to.                                  */
1431 #     ifdef PARALLEL_MARK
1432 #       define USE_MARK_BYTES
1433                 /* Minimize compare-and-swap usage.             */
1434 #     endif
1435 #   endif
1436 #   define STACK_GROWS_UP
1437 #   ifdef HPUX
1438 #     define OS_TYPE "HPUX"
1439       extern int __data_start[];
1440 #     define DATASTART ((ptr_t)(__data_start))
1441 #     if 0
1442         /* The following appears to work for 7xx systems running HP/UX  */
1443         /* 9.xx Furthermore, it might result in much faster             */
1444         /* collections than HEURISTIC2, which may involve scanning      */
1445         /* segments that directly precede the stack.  It is not the     */
1446         /* default, since it may not work on older machine/OS           */
1447         /* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */
1448         /* this.)                                                       */
1449 #       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */
1450 #     else
1451         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1452         /* to this.  Note that the GC must be initialized before the    */
1453         /* first putenv call.                                           */
1454         extern char ** environ;
1455 #       define STACKBOTTOM ((ptr_t)environ)
1456 #     endif
1457 #     define DYNAMIC_LOADING
1458 #     include <unistd.h>
1459 #     define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1460 #     ifndef __GNUC__
1461 #       define PREFETCH(x)  { \
1462                               register long addr = (long)(x); \
1463                               (void) _asm ("LDW", 0, 0, addr, 0); \
1464                             }
1465 #     endif
1466 #   endif /* HPUX */
1467 #   ifdef LINUX
1468 #     define OS_TYPE "LINUX"
1469 #     define LINUX_STACKBOTTOM
1470 #     define DYNAMIC_LOADING
1471 #     define SEARCH_FOR_DATA_START
1472       extern int _end[];
1473 #     define DATAEND (&_end)
1474 #   endif /* LINUX */
1475 # endif /* HP_PA */
1476
1477 # ifdef ALPHA
1478 #   define MACH_TYPE "ALPHA"
1479 #   define ALIGNMENT 8
1480 #   define CPP_WORDSZ 64
1481 #   ifndef LINUX
1482 #     define USE_GENERIC_PUSH_REGS
1483       /* Gcc and probably the DEC/Compaq compiler spill pointers to preserved */
1484       /* fp registers in some cases when the target is a 21264.  The assembly */
1485       /* code doesn't handle that yet, and version dependencies make that a   */
1486       /* bit tricky.  Do the easy thing for now.                                    */
1487 #   endif
1488 #   ifdef NETBSD
1489 #       define OS_TYPE "NETBSD"
1490 #       define HEURISTIC2
1491 #       define DATASTART GC_data_start
1492 #       define ELFCLASS32 32
1493 #       define ELFCLASS64 64
1494 #       define ELF_CLASS ELFCLASS64
1495 #       define DYNAMIC_LOADING
1496 #   endif
1497 #   ifdef OPENBSD
1498 #       define OS_TYPE "OPENBSD"
1499 #       define HEURISTIC2
1500 #       ifdef __ELF__   /* since OpenBSD/Alpha 2.9 */
1501 #          define DATASTART GC_data_start
1502 #          define ELFCLASS32 32
1503 #          define ELFCLASS64 64
1504 #          define ELF_CLASS ELFCLASS64
1505 #       else            /* ECOFF, until OpenBSD/Alpha 2.7 */
1506 #          define DATASTART ((ptr_t) 0x140000000)
1507 #       endif
1508 #   endif
1509 #   ifdef FREEBSD
1510 #       define OS_TYPE "FREEBSD"
1511 /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */
1512 #       define SIG_SUSPEND SIGUSR1
1513 #       define SIG_THR_RESTART SIGUSR2
1514 #       define FREEBSD_STACKBOTTOM
1515 #       ifdef __ELF__
1516 #           define DYNAMIC_LOADING
1517 #       endif
1518 /* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */
1519         extern char etext[];
1520         extern char edata[];
1521         extern char end[];
1522 #       define NEED_FIND_LIMIT
1523 #       define DATASTART ((ptr_t)(&etext))
1524 #       define DATAEND (GC_find_limit (DATASTART, TRUE))
1525 #       define DATASTART2 ((ptr_t)(&edata))
1526 #       define DATAEND2 ((ptr_t)(&end))
1527 #   endif
1528 #   ifdef OSF1
1529 #       define OS_TYPE "OSF1"
1530 #       define DATASTART ((ptr_t) 0x140000000)
1531         extern int _end[];
1532 #       define DATAEND ((ptr_t) &_end)
1533         extern char ** environ;
1534         /* round up from the value of environ to the nearest page boundary */
1535         /* Probably breaks if putenv is called before collector            */
1536         /* initialization.                                                 */
1537 #       define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
1538 /* #    define HEURISTIC2 */
1539         /* Normally HEURISTIC2 is too conervative, since                */
1540         /* the text segment immediately follows the stack.              */
1541         /* Hence we give an upper pound.                                */
1542         /* This is currently unused, since we disabled HEURISTIC2       */
1543         extern int __start[];
1544 #       define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
1545 #       ifndef GC_OSF1_THREADS
1546           /* Unresolved signal issues with threads.     */
1547 #         define MPROTECT_VDB
1548 #       endif
1549 #       define DYNAMIC_LOADING
1550 #   endif
1551 #   ifdef LINUX
1552 #       define OS_TYPE "LINUX"
1553 #       define LINUX_STACKBOTTOM
1554 #       ifdef __ELF__
1555 #         define SEARCH_FOR_DATA_START
1556 #         define DYNAMIC_LOADING
1557 #       else
1558 #           define DATASTART ((ptr_t) 0x140000000)
1559 #       endif
1560         extern int _end[];
1561 #       define DATAEND (_end)
1562 #       define MPROTECT_VDB
1563                 /* Has only been superficially tested.  May not */
1564                 /* work on all versions.                        */
1565 #   endif
1566 # endif
1567
1568 # ifdef IA64
1569 #   define MACH_TYPE "IA64"
1570 #   define USE_GENERIC_PUSH_REGS
1571         /* We need to get preserved registers in addition to register   */
1572         /* windows.   That's easiest to do with setjmp.                 */
1573 #   ifdef PARALLEL_MARK
1574 #       define USE_MARK_BYTES
1575             /* Compare-and-exchange is too expensive to use for         */
1576             /* setting mark bits.                                       */
1577 #   endif
1578 #   ifdef HPUX
1579 #       ifdef _ILP32
1580 #         define CPP_WORDSZ 32
1581 #         define ALIGN_DOUBLE
1582             /* Requires 8 byte alignment for malloc */
1583 #         define ALIGNMENT 4
1584 #       else
1585 #         ifndef _LP64
1586                 ---> unknown ABI
1587 #         endif
1588 #         define CPP_WORDSZ 64
1589 #         define ALIGN_DOUBLE
1590             /* Requires 16 byte alignment for malloc */
1591 #         define ALIGNMENT 8
1592 #       endif
1593 #       define OS_TYPE "HPUX"   
1594         extern int __data_start[];
1595 #       define DATASTART ((ptr_t)(__data_start))
1596         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1597         /* to this.  Note that the GC must be initialized before the    */
1598         /* first putenv call.                                           */
1599         extern char ** environ;
1600 #       define STACKBOTTOM ((ptr_t)environ)
1601 #       define HPUX_STACKBOTTOM
1602 #       define DYNAMIC_LOADING
1603 #       include <unistd.h>
1604 #       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1605         /* The following was empirically determined, and is probably    */
1606         /* not very robust.                                             */
1607         /* Note that the backing store base seems to be at a nice       */
1608         /* address minus one page.                                      */
1609 #       define BACKING_STORE_DISPLACEMENT 0x1000000
1610 #       define BACKING_STORE_ALIGNMENT 0x1000
1611         extern ptr_t GC_register_stackbottom;
1612 #       define BACKING_STORE_BASE GC_register_stackbottom
1613         /* Known to be wrong for recent HP/UX versions!!!       */
1614 #   endif
1615 #   ifdef LINUX
1616 #       define CPP_WORDSZ 64
1617 #       define ALIGN_DOUBLE
1618           /* Requires 16 byte alignment for malloc */
1619 #       define ALIGNMENT 8
1620 #       define OS_TYPE "LINUX"
1621         /* The following works on NUE and older kernels:        */
1622 /* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)     */
1623         /* This does not work on NUE:                           */
1624 #       define LINUX_STACKBOTTOM
1625         /* We also need the base address of the register stack  */
1626         /* backing store.  This is computed in                  */
1627         /* GC_linux_register_stack_base based on the following  */
1628         /* constants:                                           */
1629 #       define BACKING_STORE_ALIGNMENT 0x100000
1630 #       define BACKING_STORE_DISPLACEMENT 0x80000000
1631         extern ptr_t GC_register_stackbottom;
1632 #       define BACKING_STORE_BASE GC_register_stackbottom
1633 #       define SEARCH_FOR_DATA_START
1634 #       ifdef __GNUC__
1635 #         define DYNAMIC_LOADING
1636 #       else
1637           /* In the Intel compiler environment, we seem to end up with  */
1638           /* statically linked executables and an undefined reference   */
1639           /* to _DYNAMIC                                                */
1640 #       endif
1641 #       define MPROTECT_VDB
1642                 /* Requires Linux 2.3.47 or later.      */
1643         extern int _end[];
1644 #       define DATAEND (_end)
1645 #       ifdef __GNUC__
1646 #         ifndef __INTEL_COMPILER
1647 #           define PREFETCH(x) \
1648               __asm__ ("        lfetch  [%0]": : "r"(x))
1649 #           define PREFETCH_FOR_WRITE(x) \
1650               __asm__ ("        lfetch.excl     [%0]": : "r"(x))
1651 #           define CLEAR_DOUBLE(x) \
1652               __asm__ ("        stf.spill       [%0]=f0": : "r"((void *)(x)))
1653 #         else
1654 #           include <ia64intrin.h>
1655 #           define PREFETCH(x) \
1656               __lfetch(__lfhint_none, (x))
1657 #           define PREFETCH_FOR_WRITE(x) \
1658               __lfetch(__lfhint_nta,  (x))
1659 #           define CLEAR_DOUBLE(x) \
1660               __stf_spill((void *)(x), 0)
1661 #         endif // __INTEL_COMPILER
1662 #       endif
1663 #   endif
1664 #   ifdef MSWIN32
1665       /* FIXME: This is a very partial guess.  There is no port, yet.   */
1666 #     define OS_TYPE "MSWIN32"
1667                 /* STACKBOTTOM and DATASTART are handled specially in   */
1668                 /* os_dep.c.                                            */
1669 #     define DATAEND  /* not needed */
1670 #     if defined(_WIN64)
1671 #       define CPP_WORDSZ 64
1672 #     else
1673 #       define CPP_WORDSZ 32   /* Is this possible?     */
1674 #     endif
1675 #     define ALIGNMENT 8
1676 #   endif
1677 # endif
1678
1679 # ifdef M88K
1680 #   define MACH_TYPE "M88K"
1681 #   define ALIGNMENT 4
1682 #   define ALIGN_DOUBLE
1683     extern int etext[];
1684 #   ifdef CX_UX
1685 #       define OS_TYPE "CX_UX"
1686 #       define DATASTART ((((word)etext + 0x3fffff) & ~0x3fffff) + 0x10000)
1687 #   endif
1688 #   ifdef  DGUX
1689 #       define OS_TYPE "DGUX"
1690         extern ptr_t GC_SysVGetDataStart();
1691 #       define DATASTART GC_SysVGetDataStart(0x10000, etext)
1692 #   endif
1693 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
1694 # endif
1695
1696 # ifdef S370
1697     /* If this still works, and if anyone cares, this should probably   */
1698     /* be moved to the S390 category.                                   */
1699 #   define MACH_TYPE "S370"
1700 #   define ALIGNMENT 4  /* Required by hardware */
1701 #   define USE_GENERIC_PUSH_REGS
1702 #   ifdef UTS4
1703 #       define OS_TYPE "UTS4"
1704        extern int etext[];
1705         extern int _etext[];
1706         extern int _end[];
1707         extern ptr_t GC_SysVGetDataStart();
1708 #       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
1709 #       define DATAEND (_end)
1710 #       define HEURISTIC2
1711 #   endif
1712 # endif
1713
1714 # ifdef S390
1715 #   define MACH_TYPE "S390"
1716 #   define USE_GENERIC_PUSH_REGS
1717 #   ifndef __s390x__
1718 #   define ALIGNMENT 4
1719 #   define CPP_WORDSZ 32
1720 #   else
1721 #   define ALIGNMENT 8
1722 #   define CPP_WORDSZ 64
1723 #   define HBLKSIZE 4096
1724 #   endif
1725 #   ifdef LINUX
1726 #       define OS_TYPE "LINUX"
1727 #       define LINUX_STACKBOTTOM
1728 #       define DYNAMIC_LOADING
1729        extern int __data_start[];
1730 #       define DATASTART ((ptr_t)(__data_start))
1731     extern int _end[];
1732 #   define DATAEND (_end)
1733 #   define CACHE_LINE_SIZE 256
1734 #   define GETPAGESIZE() 4096
1735 #   endif
1736 # endif
1737
1738 # if defined(PJ)
1739 #   define ALIGNMENT 4
1740     extern int _etext[];
1741 #   define DATASTART ((ptr_t)(_etext))
1742 #   define HEURISTIC1
1743 # endif
1744
1745 # ifdef ARM32
1746 #   define CPP_WORDSZ 32
1747 #   define MACH_TYPE "ARM32"
1748 #   define ALIGNMENT 4
1749 #   ifdef NETBSD
1750 #       define OS_TYPE "NETBSD"
1751 #       define HEURISTIC2
1752 #       ifdef __ELF__
1753 #          define DATASTART GC_data_start
1754 #          define DYNAMIC_LOADING
1755 #       else
1756            extern char etext[];
1757 #          define DATASTART ((ptr_t)(etext))
1758 #       endif
1759 #       define USE_GENERIC_PUSH_REGS
1760 #   endif
1761 #   ifdef LINUX
1762 #       define OS_TYPE "LINUX"
1763 #       define HEURISTIC1
1764 #       undef STACK_GRAN
1765 #       define STACK_GRAN 0x10000000
1766 #       define USE_GENERIC_PUSH_REGS
1767 #       ifdef __ELF__
1768 #            define DYNAMIC_LOADING
1769 #            include <features.h>
1770 #            if defined(__GLIBC__) && __GLIBC__ >= 2
1771 #                define SEARCH_FOR_DATA_START
1772 #            else
1773                  extern char **__environ;
1774 #                define DATASTART ((ptr_t)(&__environ))
1775                               /* hideous kludge: __environ is the first */
1776                               /* word in crt0.o, and delimits the start */
1777                               /* of the data segment, no matter which   */
1778                               /* ld options were passed through.        */
1779                               /* We could use _etext instead, but that  */
1780                               /* would include .rodata, which may       */
1781                               /* contain large read-only data tables    */
1782                               /* that we'd rather not scan.             */
1783 #            endif
1784              extern int _end[];
1785 #            define DATAEND (_end)
1786 #       else
1787              extern int etext[];
1788 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1789 #       endif
1790 #   endif
1791 #   ifdef MSWINCE
1792 #     define OS_TYPE "MSWINCE"
1793 #     define DATAEND /* not needed */
1794 #   endif
1795 #   ifdef NOSYS
1796       /* __data_start is usually defined in the target linker script.  */
1797       extern int __data_start[];
1798 #     define DATASTART (ptr_t)(__data_start)
1799 #     define USE_GENERIC_PUSH_REGS
1800       /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */
1801       extern void *__stack_base__;
1802 #     define STACKBOTTOM ((ptr_t) (__stack_base__))
1803 #   endif
1804 #endif
1805
1806 # ifdef SH
1807 #   define MACH_TYPE "SH"
1808 #   define ALIGNMENT 4
1809 #   ifdef MSWINCE
1810 #     define OS_TYPE "MSWINCE"
1811 #     define DATAEND /* not needed */
1812 #   endif
1813 #   ifdef LINUX
1814 #     define OS_TYPE "LINUX"
1815 #     define STACKBOTTOM ((ptr_t) 0x7c000000)
1816 #     define USE_GENERIC_PUSH_REGS
1817 #     define DYNAMIC_LOADING
1818 #     define SEARCH_FOR_DATA_START
1819       extern int _end[];
1820 #     define DATAEND (_end)
1821 #   endif
1822 # endif
1823  
1824 # ifdef SH4
1825 #   define MACH_TYPE "SH4"
1826 #   define OS_TYPE "MSWINCE"
1827 #   define ALIGNMENT 4
1828 #   define DATAEND /* not needed */
1829 # endif
1830
1831 # ifdef M32R
1832 #   define CPP_WORDSZ 32
1833 #   define MACH_TYPE "M32R"
1834 #   define ALIGNMENT 4
1835 #   ifdef LINUX
1836 #     define OS_TYPE "LINUX"
1837 #     define LINUX_STACKBOTTOM
1838 #     undef STACK_GRAN
1839 #     define STACK_GRAN 0x10000000
1840 #     define USE_GENERIC_PUSH_REGS
1841 #     define DYNAMIC_LOADING
1842 #     define SEARCH_FOR_DATA_START
1843       extern int _end[];
1844 #     define DATAEND (_end)
1845 #   endif
1846 # endif
1847
1848 # ifdef X86_64
1849 #   define MACH_TYPE "X86_64"
1850 #   define ALIGNMENT 8
1851 #   define CPP_WORDSZ 64
1852 #   ifndef HBLKSIZE
1853 #     define HBLKSIZE 4096
1854 #   endif
1855 #   define CACHE_LINE_SIZE 64
1856 #   define USE_GENERIC_PUSH_REGS
1857 #   ifdef LINUX
1858 #       define OS_TYPE "LINUX"
1859 #       define LINUX_STACKBOTTOM
1860 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
1861 #           define MPROTECT_VDB
1862 #       else
1863             /* We seem to get random errors in incremental mode,        */
1864             /* possibly because Linux threads is itself a malloc client */
1865             /* and can't deal with the signals.                         */
1866 #       endif
1867 #       ifdef __ELF__
1868 #            define DYNAMIC_LOADING
1869 #            ifdef UNDEFINED    /* includes ro data */
1870                extern int _etext[];
1871 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
1872 #            endif
1873 #            include <features.h>
1874 #            define SEARCH_FOR_DATA_START
1875              extern int _end[];
1876 #            define DATAEND (_end)
1877 #       else
1878              extern int etext[];
1879 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1880 #       endif
1881 #       if defined(__GNUC__) && __GNUC >= 3
1882 #           define PREFETCH(x) __builtin_prefetch((x), 0, 0)
1883 #           define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
1884 #       endif
1885 #   endif
1886 #   ifdef NETBSD
1887 #       define OS_TYPE "NETBSD"
1888 #       ifdef __ELF__
1889 #           define DYNAMIC_LOADING
1890 #       endif
1891 #       define HEURISTIC2
1892         extern char etext[];
1893 #       define SEARCH_FOR_DATA_START
1894 #   endif
1895 # endif
1896
1897 #if defined(LINUX) && defined(USE_MMAP)
1898     /* The kernel may do a somewhat better job merging mappings etc.    */
1899     /* with anonymous mappings.                                         */
1900 #   define USE_MMAP_ANON
1901 #endif
1902
1903 #if defined(LINUX) && defined(REDIRECT_MALLOC)
1904     /* Rld appears to allocate some memory with its own allocator, and  */
1905     /* some through malloc, which might be redirected.  To make this    */
1906     /* work with collectable memory, we have to scan memory allocated   */
1907     /* by rld's internal malloc.                                        */
1908 #   define USE_PROC_FOR_LIBRARIES
1909 #endif
1910     
1911 # ifndef STACK_GROWS_UP
1912 #   define STACK_GROWS_DOWN
1913 # endif
1914
1915 # ifndef CPP_WORDSZ
1916 #   define CPP_WORDSZ 32
1917 # endif
1918
1919 # ifndef OS_TYPE
1920 #   define OS_TYPE ""
1921 # endif
1922
1923 # ifndef DATAEND
1924     extern int end[];
1925 #   define DATAEND (end)
1926 # endif
1927
1928 # if defined(SVR4) && !defined(GETPAGESIZE)
1929 #    include <unistd.h>
1930 #    define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
1931 # endif
1932
1933 # ifndef GETPAGESIZE
1934 #   if defined(SUNOS5) || defined(IRIX5)
1935 #       include <unistd.h>
1936 #   endif
1937 #   define GETPAGESIZE() getpagesize()
1938 # endif
1939
1940 # if defined(SUNOS5) || defined(DRSNX) || defined(UTS4)
1941             /* OS has SVR4 generic features.  Probably others also qualify.     */
1942 #   define SVR4
1943 # endif
1944
1945 # if defined(SUNOS5) || defined(DRSNX)
1946             /* OS has SUNOS5 style semi-undocumented interface to dynamic       */
1947             /* loader.                                                          */
1948 #   define SUNOS5DL
1949             /* OS has SUNOS5 style signal handlers.                             */
1950 #   define SUNOS5SIGS
1951 # endif
1952
1953 # if defined(HPUX)
1954 #   define SUNOS5SIGS
1955 # endif
1956
1957 # if defined(FREEBSD) && (__FreeBSD__ >= 4)
1958 #   define SUNOS5SIGS
1959 # endif
1960
1961 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
1962             || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
1963             || defined(DGUX) || defined(BSD) || defined(SUNOS4) \
1964             || defined(_AIX) || defined(DARWIN) || defined(OSF1)
1965 #   define UNIX_LIKE   /* Basic Unix-like system calls work.    */
1966 # endif
1967
1968 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
1969            -> bad word size
1970 # endif
1971
1972 # ifdef PCR
1973 #   undef DYNAMIC_LOADING
1974 #   undef STACKBOTTOM
1975 #   undef HEURISTIC1
1976 #   undef HEURISTIC2
1977 #   undef PROC_VDB
1978 #   undef MPROTECT_VDB
1979 #   define PCR_VDB
1980 # endif
1981
1982 # ifdef SRC_M3
1983         /* Postponed for now. */
1984 #   undef PROC_VDB
1985 #   undef MPROTECT_VDB
1986 # endif
1987
1988 # ifdef SMALL_CONFIG
1989         /* Presumably not worth the space it takes. */
1990 #   undef PROC_VDB
1991 #   undef MPROTECT_VDB
1992 # endif
1993
1994 # ifdef USE_MUNMAP
1995 #   undef MPROTECT_VDB  /* Can't deal with address space holes. */
1996 # endif
1997
1998 # ifdef PARALLEL_MARK
1999 #   undef MPROTECT_VDB  /* For now.     */
2000 # endif
2001
2002 # if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB)
2003 #   define DEFAULT_VDB
2004 # endif
2005
2006 # ifndef PREFETCH
2007 #   define PREFETCH(x)
2008 #   define NO_PREFETCH
2009 # endif
2010
2011 # ifndef PREFETCH_FOR_WRITE
2012 #   define PREFETCH_FOR_WRITE(x)
2013 #   define NO_PREFETCH_FOR_WRITE
2014 # endif
2015
2016 # ifndef CACHE_LINE_SIZE
2017 #   define CACHE_LINE_SIZE 32   /* Wild guess   */
2018 # endif
2019
2020 # ifdef LINUX
2021 #   define REGISTER_LIBRARIES_EARLY
2022     /* We sometimes use dl_iterate_phdr, which may acquire an internal  */
2023     /* lock.  This isn't safe after the world has stopped.  So we must  */
2024     /* call GC_register_dynamic_libraries before stopping the world.    */
2025     /* For performance reasons, this may be beneficial on other         */
2026     /* platforms as well, though it should be avoided in win32.         */
2027 # endif /* LINUX */
2028
2029 # if defined(SEARCH_FOR_DATA_START)
2030     extern ptr_t GC_data_start;
2031 #   define DATASTART GC_data_start
2032 # endif
2033
2034 # ifndef CLEAR_DOUBLE
2035 #   define CLEAR_DOUBLE(x) \
2036                 ((word*)x)[0] = 0; \
2037                 ((word*)x)[1] = 0;
2038 # endif /* CLEAR_DOUBLE */
2039
2040         /* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */
2041 # if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
2042 #   define GC_SOLARIS_THREADS
2043 # endif
2044
2045 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
2046         --> inconsistent configuration
2047 # endif
2048 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
2049         --> inconsistent configuration
2050 # endif
2051 # if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
2052         --> inconsistent configuration
2053 # endif
2054 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
2055         --> inconsistent configuration
2056 # endif
2057 # if defined(GC_AIX_THREADS) && !defined(_AIX)
2058         --> inconsistent configuration
2059 # endif
2060 # if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32)
2061         --> inconsistent configuration
2062 # endif
2063
2064 # if defined(PCR) || defined(SRC_M3) || \
2065                 defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \
2066                 defined(GC_PTHREADS)
2067 #   define THREADS
2068 # endif
2069
2070 # if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \
2071              || defined(LINT) || defined(MSWINCE) || defined(ARM32) \
2072              || (defined(I386) && defined(__LCC__))
2073         /* Use setjmp based hack to mark from callee-save registers.    */
2074         /* The define should move to the individual platform            */
2075         /* descriptions.                                                */
2076 #       define USE_GENERIC_PUSH_REGS
2077 # endif
2078
2079 # if defined(MSWINCE)
2080 #   define NO_GETENV
2081 # endif
2082
2083 # if defined(SPARC)
2084 #   define ASM_CLEAR_CODE       /* Stack clearing is crucial, and we    */
2085                                 /* include assembly code to do it well. */
2086 # endif
2087
2088   /* Can we save call chain in objects for debugging?                   */
2089   /* SET NFRAMES (# of saved frames) and NARGS (#of args for each       */
2090   /* frame) to reasonable values for the platform.                      */
2091   /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified   */
2092   /* at build time, though we feel free to adjust it slightly.          */
2093   /* Define NEED_CALLINFO if we either save the call stack or           */
2094   /* GC_ADD_CALLER is defined.                                          */
2095   /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.                            */
2096
2097 #if defined(SPARC)
2098 # define CAN_SAVE_CALL_ARGS
2099 #endif
2100 #if (defined(I386) || defined(X86_64)) && defined(LINUX)
2101             /* SAVE_CALL_CHAIN is supported if the code is compiled to save     */
2102             /* frame pointers by default, i.e. no -fomit-frame-pointer flag.    */
2103 # define CAN_SAVE_CALL_ARGS
2104 #endif
2105
2106 # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
2107              && defined(GC_CAN_SAVE_CALL_STACKS)
2108 #   define SAVE_CALL_CHAIN 
2109 # endif
2110 # ifdef SAVE_CALL_CHAIN
2111 #   if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
2112 #     define NARGS SAVE_CALL_NARGS
2113 #   else
2114 #     define NARGS 0    /* Number of arguments to save for each call.   */
2115 #   endif
2116 # endif
2117 # ifdef SAVE_CALL_CHAIN
2118 #   ifndef SAVE_CALL_COUNT
2119 #     define NFRAMES 6  /* Number of frames to save. Even for           */
2120                                 /* alignment reasons.                           */
2121 #   else
2122 #     define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
2123 #   endif
2124 #   define NEED_CALLINFO
2125 # endif /* SAVE_CALL_CHAIN */
2126 # ifdef GC_ADD_CALLER
2127 #   define NFRAMES 1
2128 #   define NARGS 0
2129 #   define NEED_CALLINFO
2130 # endif
2131
2132 # if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
2133 #   define DBG_HDRS_ALL
2134 # endif
2135
2136 # if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
2137 #   define POINTER_SHIFT 0
2138 # endif
2139
2140 # if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
2141 #   define POINTER_MASK ((GC_word)(-1))
2142 # endif
2143
2144 # if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
2145 #   define FIXUP_POINTER(p) (p) = ((p) & (POINTER_MASK) << POINTER_SHIFT)
2146 # endif
2147
2148 # if defined(FIXUP_POINTER)
2149 #   define NEED_FIXUP_POINTER 1
2150 # else
2151 #   define NEED_FIXUP_POINTER 0
2152 #   define FIXUP_POINTER(p)
2153 # endif
2154
2155 #ifdef GC_PRIVATE_H
2156         /* This relies on some type definitions from gc_priv.h, from    */
2157         /* where it's normally included.                                */
2158         /*                                                              */
2159         /* How to get heap memory from the OS:                          */
2160         /* Note that sbrk()-like allocation is preferred, since it      */
2161         /* usually makes it possible to merge consecutively allocated   */
2162         /* chunks.  It also avoids unintented recursion with            */
2163         /* -DREDIRECT_MALLOC.                                           */
2164         /* GET_MEM() returns a HLKSIZE aligned chunk.                   */
2165         /* 0 is taken to mean failure.                                  */
2166         /* In the case os USE_MMAP, the argument must also be a         */
2167         /* physical page size.                                          */
2168         /* GET_MEM is currently not assumed to retrieve 0 filled space, */
2169         /* though we should perhaps take advantage of the case in which */
2170         /* does.                                                        */
2171         struct hblk;    /* See gc_priv.h.       */
2172 # ifdef PCR
2173             char * real_malloc();
2174 #   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
2175                                           + GC_page_size-1)
2176 # else
2177 #   ifdef OS2
2178               void * os2_alloc(size_t bytes);
2179 #     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
2180                                             + GC_page_size) \
2181                                             + GC_page_size-1)
2182 #   else
2183 #     if defined(NEXT) || defined(DOS4GW) || \
2184                  (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
2185                  (defined(SUNOS5) && !defined(USE_MMAP))
2186 #       define GET_MEM(bytes) HBLKPTR((size_t) \
2187                                               calloc(1, (size_t)bytes + GC_page_size) \
2188                                               + GC_page_size-1)
2189 #     else
2190 #       ifdef MSWIN32
2191           extern ptr_t GC_win32_get_mem();
2192 #         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
2193 #       else
2194 #         ifdef MACOS
2195 #           if defined(USE_TEMPORARY_MEMORY)
2196                         extern Ptr GC_MacTemporaryNewPtr(size_t size,
2197                                                          Boolean clearMemory);
2198 #               define GET_MEM(bytes) HBLKPTR( \
2199                             GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
2200                             + GC_page_size-1)
2201 #           else
2202 #                   define GET_MEM(bytes) HBLKPTR( \
2203                                 NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
2204 #           endif
2205 #         else
2206 #           ifdef MSWINCE
2207               extern ptr_t GC_wince_get_mem();
2208 #             define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
2209 #           else
2210 #             if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
2211                         extern void *GC_amiga_get_mem(size_t size);
2212 #                       define GET_MEM(bytes) HBLKPTR((size_t) \
2213                           GC_amiga_get_mem((size_t)bytes + GC_page_size) \
2214                           + GC_page_size-1)
2215 #             else
2216                 extern ptr_t GC_unix_get_mem();
2217 #               define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
2218 #             endif
2219 #           endif
2220 #         endif
2221 #       endif
2222 #     endif
2223 #   endif
2224 # endif
2225
2226 #endif /* GC_PRIVATE_H */
2227
2228 # endif /* GCCONFIG_H */