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