OSDN Git Service

Imported GC 6.1 Alpha 3. Finally.
[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 by Hewlett-Packard Company.  All rights reserved.
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 #ifndef GCCONFIG_H
18
19 # define GCCONFIG_H
20
21 /* Machine dependent parameters.  Some tuning parameters can be found   */
22 /* near the top of gc_private.h.                                        */
23
24 /* Machine specific parts contributed by various people.  See README file. */
25
26 /* First a unified test for Linux: */
27 # if defined(linux) || defined(__linux__)
28 #    define LINUX
29 # endif
30
31 /* And one for NetBSD: */
32 # if defined(__NetBSD__)
33 #    define NETBSD
34 # endif
35
36 /* And one for OpenBSD: */
37 # if defined(__OpenBSD__)
38 #    define OPENBSD
39 # endif
40
41 /* Determine the machine type: */
42 # if defined(__XSCALE__)
43 #    define ARM32
44 #    if !defined(LINUX)
45 #      define NOSYS
46 #      define mach_type_known
47 #    endif
48 # endif
49 # if defined(sun) && defined(mc68000)
50 #    define M68K
51 #    define SUNOS4
52 #    define mach_type_known
53 # endif
54 # if defined(hp9000s300)
55 #    define M68K
56 #    define HP
57 #    define mach_type_known
58 # endif
59 # if defined(OPENBSD) && defined(m68k)
60 #    define M68K
61 #    define mach_type_known
62 # endif
63 # if defined(OPENBSD) && defined(__sparc__)
64 #    define SPARC
65 #    define mach_type_known
66 # endif
67 # if defined(NETBSD) && defined(m68k)
68 #    define M68K
69 #    define mach_type_known
70 # endif
71 # if defined(NETBSD) && defined(__powerpc__)
72 #    define POWERPC
73 #    define mach_type_known
74 # endif
75 # if defined(NETBSD) && defined(__arm32__)
76 #    define ARM32
77 #    define mach_type_known
78 # endif
79 # if defined(vax)
80 #    define VAX
81 #    ifdef ultrix
82 #       define ULTRIX
83 #    else
84 #       define BSD
85 #    endif
86 #    define mach_type_known
87 # endif
88 # if defined(mips) || defined(__mips) || defined(_mips)
89 #    define MIPS
90 #    if defined(nec_ews) || defined(_nec_ews)
91 #      define EWS4800
92 #    endif
93 #    if !defined(LINUX) && !defined(EWS4800)
94 #      if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
95 #        define ULTRIX
96 #      else
97 #        if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) \
98             || defined(__SYSTYPE_SVR4__)
99 #          define IRIX5   /* or IRIX 6.X */
100 #        else
101 #          define RISCOS  /* or IRIX 4.X */
102 #        endif
103 #      endif
104 #    endif /* !LINUX */
105 #    if defined(__NetBSD__) && defined(__MIPSEL__)
106 #      undef ULTRIX
107 #    endif
108 #    define mach_type_known
109 # endif
110 # if defined(sequent) && (defined(i386) || defined(__i386__))
111 #    define I386
112 #    define SEQUENT
113 #    define mach_type_known
114 # endif
115 # if defined(sun) && (defined(i386) || defined(__i386__))
116 #    define I386
117 #    define SUNOS5
118 #    define mach_type_known
119 # endif
120 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
121 #    define I386
122 #    define OS2
123 #    define mach_type_known
124 # endif
125 # if defined(ibm032)
126 #   define RT
127 #   define mach_type_known
128 # endif
129 # if defined(sun) && (defined(sparc) || defined(__sparc))
130 #   define SPARC
131     /* Test for SunOS 5.x */
132 #     include <errno.h>
133 #     ifdef ECHRNG
134 #       define SUNOS5
135 #     else
136 #       define SUNOS4
137 #     endif
138 #   define mach_type_known
139 # endif
140 # if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
141      && !defined(__OpenBSD__) && !(__NetBSD__)
142 #   define SPARC
143 #   define DRSNX
144 #   define mach_type_known
145 # endif
146 # if defined(_IBMR2)
147 #   define RS6000
148 #   define mach_type_known
149 # endif
150 # if defined(__NetBSD__) && defined(__sparc__)
151 #   define SPARC
152 #   define mach_type_known
153 # endif
154 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
155         /* The above test may need refinement   */
156 #   define I386
157 #   if defined(_SCO_ELF)
158 #     define SCO_ELF
159 #   else
160 #     define SCO
161 #   endif
162 #   define mach_type_known
163 # endif
164 # if defined(_AUX_SOURCE)
165 #   define M68K
166 #   define SYSV
167 #   define mach_type_known
168 # endif
169 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
170      || defined(hppa) || defined(__hppa__)
171 #   define HP_PA
172 #   ifndef LINUX
173 #     define HPUX
174 #   endif
175 #   define mach_type_known
176 # endif
177 # if defined(__ia64) && defined(_HPUX_SOURCE)
178 #   define IA64
179 #   define HPUX
180 #   define mach_type_known
181 # endif
182 # if defined(__BEOS__) && defined(_X86_)
183 #    define I386
184 #    define BEOS
185 #    define mach_type_known
186 # endif
187 # if defined(LINUX) && (defined(i386) || defined(__i386__))
188 #    define I386
189 #    define mach_type_known
190 # endif
191 # if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
192 #    define IA64
193 #    define mach_type_known
194 # endif
195 # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__))
196 #    define POWERPC
197 #    define mach_type_known
198 # endif
199 # if defined(LINUX) && defined(__mc68000__)
200 #    define M68K
201 #    define mach_type_known
202 # endif
203 # if defined(LINUX) && (defined(sparc) || defined(__sparc__))
204 #    define SPARC
205 #    define mach_type_known
206 # endif
207 # if defined(LINUX) && defined(__arm__)
208 #    define ARM32
209 #    define mach_type_known
210 # endif
211 # if defined(LINUX) && defined(__sh__)
212 #    define SH
213 #    define mach_type_known
214 # endif
215 # if defined(__alpha) || defined(__alpha__)
216 #   define ALPHA
217 #   if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD)
218 #     define OSF1       /* a.k.a Digital Unix */
219 #   endif
220 #   define mach_type_known
221 # endif
222 # if defined(_AMIGA) && !defined(AMIGA)
223 #   define AMIGA
224 # endif
225 # ifdef AMIGA 
226 #   define M68K
227 #   define mach_type_known
228 # endif
229 # if defined(THINK_C) || defined(__MWERKS__) && !defined(__powerc)
230 #   define M68K
231 #   define MACOS
232 #   define mach_type_known
233 # endif
234 # if defined(__MWERKS__) && defined(__powerc)
235 #   define POWERPC
236 #   define MACOS
237 #   define mach_type_known
238 # endif
239 # if defined(macosx) || \
240      defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
241 #    define MACOSX
242 #    define POWERPC
243 #    define mach_type_known
244 # endif
245 # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
246 #    define MACOSX
247 #    define I386
248      --> Not really supported, but at least we recognize it.
249 # endif
250 # if defined(NeXT) && defined(mc68000)
251 #   define M68K
252 #   define NEXT
253 #   define mach_type_known
254 # endif
255 # if defined(NeXT) && (defined(i386) || defined(__i386__))
256 #   define I386
257 #   define NEXT
258 #   define mach_type_known
259 # endif
260 # if defined(__OpenBSD__) && (defined(i386) || defined(__i386__))
261 #   define I386
262 #   define OPENBSD
263 #   define mach_type_known
264 # endif
265 # if defined(__FreeBSD__) && (defined(i386) || defined(__i386__))
266 #   define I386
267 #   define FREEBSD
268 #   define mach_type_known
269 # endif
270 # if defined(__NetBSD__) && (defined(i386) || defined(__i386__))
271 #   define I386
272 #   define mach_type_known
273 # endif
274 # if defined(bsdi) && (defined(i386) || defined(__i386__))
275 #    define I386
276 #    define BSDI
277 #    define mach_type_known
278 # endif
279 # if !defined(mach_type_known) && defined(__386BSD__)
280 #   define I386
281 #   define THREE86BSD
282 #   define mach_type_known
283 # endif
284 # if defined(_CX_UX) && defined(_M88K)
285 #   define M88K
286 #   define CX_UX
287 #   define mach_type_known
288 # endif
289 # if defined(DGUX)
290 #   define M88K
291     /* DGUX defined */
292 #   define mach_type_known
293 # endif
294 # if defined(_WIN32_WCE)
295     /* SH3, SH4, MIPS already defined for corresponding architectures */
296 #   if defined(SH3) || defined(SH4)
297 #     define SH
298 #   endif
299 #   if defined(x86)
300 #     define I386
301 #   endif
302 #   if defined(ARM)
303 #     define ARM32
304 #   endif
305 #   define MSWINCE
306 #   define mach_type_known
307 # else
308 #   if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
309         || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
310 #     define I386
311 #     define MSWIN32    /* or Win32s */
312 #     define mach_type_known
313 #   endif
314 # endif
315 # if defined(__DJGPP__)
316 #   define I386
317 #   ifndef DJGPP
318 #     define DJGPP  /* MSDOS running the DJGPP port of GCC */
319 #   endif
320 #   define mach_type_known
321 # endif
322 # if defined(__CYGWIN32__) || defined(__CYGWIN__)
323 #   define I386
324 #   define CYGWIN32
325 #   define mach_type_known
326 # endif
327 # if defined(__MINGW32__)
328 #   define I386
329 #   define MSWIN32
330 #   define mach_type_known
331 # endif
332 # if defined(__BORLANDC__)
333 #   define I386
334 #   define MSWIN32
335 #   define mach_type_known
336 # endif
337 # if defined(_UTS) && !defined(mach_type_known)
338 #   define S370
339 #   define UTS4
340 #   define mach_type_known
341 # endif
342 # if defined(__pj__)
343 #   define PJ
344 #   define mach_type_known
345 # endif
346 # if defined(__embedded__) && defined(PPC)
347 #   define POWERPC
348 #   define NOSYS
349 #   define mach_type_known
350 # endif
351 /* Ivan Demakov */
352 # if defined(__WATCOMC__) && defined(__386__)
353 #   define I386
354 #   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
355 #     if defined(__OS2__)
356 #       define OS2
357 #     else
358 #       if defined(__WINDOWS_386__) || defined(__NT__)
359 #         define MSWIN32
360 #       else
361 #         define DOS4GW
362 #       endif
363 #     endif
364 #   endif
365 #   define mach_type_known
366 # endif
367 # if defined(__s390__) && defined(LINUX)
368 #    define S370
369 #    define mach_type_known
370 # endif
371 # if defined(__GNU__)
372 #   if defined(__i386__)
373 /* The Debian Hurd running on generic PC */  
374 #     define  HURD
375 #     define  I386
376 #     define  mach_type_known
377 #    endif 
378 # endif
379
380 /* Feel free to add more clauses here */
381
382 /* Or manually define the machine type here.  A machine type is         */
383 /* characterized by the architecture.  Some                             */
384 /* machine types are further subdivided by OS.                          */
385 /* the macros ULTRIX, RISCOS, and BSD to distinguish.                   */
386 /* Note that SGI IRIX is treated identically to RISCOS.                 */
387 /* SYSV on an M68K actually means A/UX.                                 */
388 /* The distinction in these cases is usually the stack starting address */
389 # ifndef mach_type_known
390         --> unknown machine type
391 # endif
392                     /* Mapping is: M68K       ==> Motorola 680X0        */
393                     /*             (SUNOS4,HP,NEXT, and SYSV (A/UX),    */
394                     /*             MACOS and AMIGA variants)            */
395                     /*             I386       ==> Intel 386             */
396                     /*              (SEQUENT, OS2, SCO, LINUX, NETBSD,  */
397                     /*               FREEBSD, THREE86BSD, MSWIN32,      */
398                     /*               BSDI,SUNOS5, NEXT, other variants) */
399                     /*             NS32K      ==> Encore Multimax       */
400                     /*             MIPS       ==> R2000 or R3000        */
401                     /*                  (RISCOS, ULTRIX variants)       */
402                     /*             VAX        ==> DEC VAX               */
403                     /*                  (BSD, ULTRIX variants)          */
404                     /*             RS6000     ==> IBM RS/6000 AIX3.X    */
405                     /*             RT         ==> IBM PC/RT             */
406                     /*             HP_PA      ==> HP9000/700 & /800     */
407                     /*                            HP/UX, LINUX          */
408                     /*             SPARC      ==> SPARC v7/v8/v9        */
409                     /*                  (SUNOS4, SUNOS5, LINUX,         */
410                     /*                   DRSNX variants)                */
411                     /*             ALPHA      ==> DEC Alpha             */
412                     /*                  (OSF1 and LINUX variants)       */
413                     /*             M88K       ==> Motorola 88XX0        */
414                     /*                  (CX_UX and DGUX)                */
415                     /*             S370       ==> 370-like machine      */
416                     /*                  running Amdahl UTS4             */
417                     /*                  or a 390 running LINUX          */
418                     /*             ARM32      ==> Intel StrongARM       */
419                     /*             IA64       ==> Intel IPF             */
420                     /*                            (e.g. Itanium)        */
421                     /*                  (LINUX and HPUX)                */
422                     /*             IA64_32    ==> IA64 w/32 bit ABI     */
423                     /*                  (HPUX)                          */
424                     /*             SH         ==> Hitachi SuperH        */
425                     /*                  (LINUX & MSWINCE)               */
426
427
428 /*
429  * For each architecture and OS, the following need to be defined:
430  *
431  * CPP_WORD_SZ is a simple integer constant representing the word size.
432  * in bits.  We assume byte addressibility, where a byte has 8 bits.
433  * We also assume CPP_WORD_SZ is either 32 or 64.
434  * (We care about the length of pointers, not hardware
435  * bus widths.  Thus a 64 bit processor with a C compiler that uses
436  * 32 bit pointers should use CPP_WORD_SZ of 32, not 64. Default is 32.)
437  *
438  * MACH_TYPE is a string representation of the machine type.
439  * OS_TYPE is analogous for the OS.
440  *
441  * ALIGNMENT is the largest N, such that
442  * all pointer are guaranteed to be aligned on N byte boundaries.
443  * defining it to be 1 will always work, but perform poorly.
444  *
445  * DATASTART is the beginning of the data segment.
446  * On UNIX systems, the collector will scan the area between DATASTART
447  * and DATAEND for root pointers.
448  *
449  * DATAEND, if not &end.
450  *
451  * ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice
452  * the pointer size.
453  *
454  * STACKBOTTOM is the cool end of the stack, which is usually the
455  * highest address in the stack.
456  * Under PCR or OS/2, we have other ways of finding thread stacks.
457  * For each machine, the following should:
458  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
459  * 2) define exactly one of
460  *      STACKBOTTOM (should be defined to be an expression)
461  *      HEURISTIC1
462  *      HEURISTIC2
463  * If either of the last two macros are defined, then STACKBOTTOM is computed
464  * during collector startup using one of the following two heuristics:
465  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
466  *              the next multiple of STACK_GRAN.
467  * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly
468  *              in small steps (decrement if STACK_GROWS_UP), and read the value
469  *              at each location.  Remember the value when the first
470  *              Segmentation violation or Bus error is signalled.  Round that
471  *              to the nearest plausible page boundary, and use that instead
472  *              of STACKBOTTOM.
473  *
474  * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines,
475  * the value of environ is a pointer that can serve as STACKBOTTOM.
476  * I expect that HEURISTIC2 can be replaced by this approach, which
477  * interferes far less with debugging.  However it has the disadvantage
478  * that it's confused by a putenv call before the collector is initialized.
479  * This could be dealt with by intercepting putenv ...
480  *
481  * If no expression for STACKBOTTOM can be found, and neither of the above
482  * heuristics are usable, the collector can still be used with all of the above
483  * undefined, provided one of the following is done:
484  * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
485  *    without reference to STACKBOTTOM.  This is appropriate for use in
486  *    conjunction with thread packages, since there will be multiple stacks.
487  *    (Allocating thread stacks in the heap, and treating them as ordinary
488  *    heap data objects is also possible as a last resort.  However, this is
489  *    likely to introduce significant amounts of excess storage retention
490  *    unless the dead parts of the thread stacks are periodically cleared.)
491  * 2) Client code may set GC_stackbottom before calling any GC_ routines.
492  *    If the author of the client code controls the main program, this is
493  *    easily accomplished by introducing a new main program, setting
494  *    GC_stackbottom to the address of a local variable, and then calling
495  *    the original main program.  The new main program would read something
496  *    like:
497  *
498  *              # include "gc_private.h"
499  *
500  *              main(argc, argv, envp)
501  *              int argc;
502  *              char **argv, **envp;
503  *              {
504  *                  int dummy;
505  *
506  *                  GC_stackbottom = (ptr_t)(&dummy);
507  *                  return(real_main(argc, argv, envp));
508  *              }
509  *
510  *
511  * Each architecture may also define the style of virtual dirty bit
512  * implementation to be used:
513  *   MPROTECT_VDB: Write protect the heap and catch faults.
514  *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
515  *
516  * An architecture may define DYNAMIC_LOADING if dynamic_load.c
517  * defined GC_register_dynamic_libraries() for the architecture.
518  *
519  * An architecture may define PREFETCH(x) to preload the cache with *x.
520  * This defaults to a no-op.
521  *
522  * PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
523  *
524  * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
525  * clear the two words at GC_malloc-aligned address x.  By default,
526  * word stores of 0 are used instead.
527  */
528
529 /* If we are using a recent version of gcc, we can use __builtin_unwind_init()
530  * to push the relevant registers onto the stack.  This generally makes
531  * USE_GENERIC_PUSH_REGS the preferred approach for marking from registers.
532  */
533 # if defined(__GNUC__) && ((__GNUC__ >= 3) || \
534                            (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
535 #   define HAVE_BUILTIN_UNWIND_INIT
536 # endif
537
538 # define STACK_GRAN 0x1000000
539 # ifdef M68K
540 #   define MACH_TYPE "M68K"
541 #   define ALIGNMENT 2
542 #   ifdef OPENBSD
543 #       define OS_TYPE "OPENBSD"
544 #       define HEURISTIC2
545         extern char etext;
546 #       define DATASTART ((ptr_t)(&etext))
547 #   endif
548 #   ifdef NETBSD
549 #       define OS_TYPE "NETBSD"
550 #       define HEURISTIC2
551         extern char etext;
552 #       define DATASTART ((ptr_t)(&etext))
553 #   endif
554 #   ifdef LINUX
555 #       define OS_TYPE "LINUX"
556 #       define STACKBOTTOM ((ptr_t)0xf0000000)
557 /* #       define MPROTECT_VDB - Reported to not work  9/17/01 */
558 #       ifdef __ELF__
559 #            define DYNAMIC_LOADING
560 #            include <features.h>
561 #            if defined(__GLIBC__)&& __GLIBC__>=2
562 #              define LINUX_DATA_START
563 #            else /* !GLIBC2 */
564                extern char **__environ;
565 #              define DATASTART ((ptr_t)(&__environ))
566                              /* hideous kludge: __environ is the first */
567                              /* word in crt0.o, and delimits the start */
568                              /* of the data segment, no matter which   */
569                              /* ld options were passed through.        */
570                              /* We could use _etext instead, but that  */
571                              /* would include .rodata, which may       */
572                              /* contain large read-only data tables    */
573                              /* that we'd rather not scan.             */
574 #            endif /* !GLIBC2 */
575              extern int _end;
576 #            define DATAEND (&_end)
577 #       else
578              extern int etext;
579 #            define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
580 #       endif
581 #   endif
582 #   ifdef SUNOS4
583 #       define OS_TYPE "SUNOS4"
584         extern char etext;
585 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ffff) & ~0x1ffff))
586 #       define HEURISTIC1       /* differs      */
587 #       define DYNAMIC_LOADING
588 #   endif
589 #   ifdef HP
590 #       define OS_TYPE "HP"
591         extern char etext;
592 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
593 #       define STACKBOTTOM ((ptr_t) 0xffeffffc)
594                               /* empirically determined.  seems to work. */
595 #       include <unistd.h>
596 #       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
597 #   endif
598 #   ifdef SYSV
599 #       define OS_TYPE "SYSV"
600         extern etext;
601 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \
602                                    & ~0x3fffff) \
603                                   +((word)&etext & 0x1fff))
604         /* This only works for shared-text binaries with magic number 0413.
605            The other sorts of SysV binaries put the data at the end of the text,
606            in which case the default of &etext would work.  Unfortunately,
607            handling both would require having the magic-number available.
608                                 -- Parag
609            */
610 #       define STACKBOTTOM ((ptr_t)0xFFFFFFFE)
611                         /* The stack starts at the top of memory, but   */
612                         /* 0x0 cannot be used as setjump_test complains */
613                         /* that the stack direction is incorrect.  Two  */
614                         /* bytes down from 0x0 should be safe enough.   */
615                         /*              --Parag                         */
616 #       include <sys/mmu.h>
617 #       define GETPAGESIZE() PAGESIZE   /* Is this still right? */
618 #   endif
619 #   ifdef AMIGA
620 #       define OS_TYPE "AMIGA"
621                 /* STACKBOTTOM and DATASTART handled specially  */
622                 /* in os_dep.c                                  */
623 #       define DATAEND  /* not needed */
624 #       define GETPAGESIZE() 4096
625 #   endif
626 #   ifdef MACOS
627 #     ifndef __LOWMEM__
628 #     include <LowMem.h>
629 #     endif
630 #     define OS_TYPE "MACOS"
631                         /* see os_dep.c for details of global data segments. */
632 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
633 #     define DATAEND    /* not needed */
634 #     define GETPAGESIZE() 4096
635 #   endif
636 #   ifdef NEXT
637 #       define OS_TYPE "NEXT"
638 #       define DATASTART ((ptr_t) get_etext())
639 #       define STACKBOTTOM ((ptr_t) 0x4000000)
640 #       define DATAEND  /* not needed */
641 #   endif
642 # endif
643
644 # ifdef POWERPC
645 #   define MACH_TYPE "POWERPC"
646 #   ifdef MACOS
647 #     define ALIGNMENT 2  /* Still necessary?  Could it be 4?   */
648 #     ifndef __LOWMEM__
649 #     include <LowMem.h>
650 #     endif
651 #     define OS_TYPE "MACOS"
652                         /* see os_dep.c for details of global data segments. */
653 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
654 #     define DATAEND  /* not needed */
655 #   endif
656 #   ifdef LINUX
657 #     define ALIGNMENT 4        /* Guess.  Can someone verify?  */
658                                 /* This was 2, but that didn't sound right. */
659 #     define OS_TYPE "LINUX"
660 #     define HEURISTIC1
661 #     define DYNAMIC_LOADING
662 #     undef STACK_GRAN
663 #     define STACK_GRAN 0x10000000
664         /* Stack usually starts at 0x80000000 */
665 #     define LINUX_DATA_START
666       extern int _end;
667 #     define DATAEND (&_end)
668 #   endif
669 #   ifdef MACOSX
670       /* There are reasons to suspect this may not be reliable.         */
671 #     define ALIGNMENT 4
672 #     define OS_TYPE "MACOSX"
673 #     define DATASTART ((ptr_t) get_etext())
674 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
675 #     define DATAEND    /* not needed */
676 #     define MPROTECT_VDB
677 #     include <unistd.h>
678 #     define GETPAGESIZE() getpagesize()
679 #   endif
680 #   ifdef NETBSD
681 #     define ALIGNMENT 4
682 #     define OS_TYPE "NETBSD"
683 #     define HEURISTIC2
684       extern char etext;
685 #     define DATASTART GC_data_start
686 #     define DYNAMIC_LOADING
687 #   endif
688 #   ifdef NOSYS
689 #     define ALIGNMENT 4
690 #     define OS_TYPE "NOSYS"
691       extern void __end, __dso_handle;
692 #     define DATASTART (&__dso_handle)  /* OK, that's ugly.  */
693 #     define DATAEND (&__end)
694         /* Stack starts at 0xE0000000 for the simulator.  */
695 #     undef STACK_GRAN
696 #     define STACK_GRAN 0x10000000
697 #     define HEURISTIC1
698 #   endif
699 # endif
700
701 # ifdef VAX
702 #   define MACH_TYPE "VAX"
703 #   define ALIGNMENT 4  /* Pointers are longword aligned by 4.2 C compiler */
704     extern char etext;
705 #   define DATASTART ((ptr_t)(&etext))
706 #   ifdef BSD
707 #       define OS_TYPE "BSD"
708 #       define HEURISTIC1
709                         /* HEURISTIC2 may be OK, but it's hard to test. */
710 #   endif
711 #   ifdef ULTRIX
712 #       define OS_TYPE "ULTRIX"
713 #       define STACKBOTTOM ((ptr_t) 0x7fffc800)
714 #   endif
715 # endif
716
717 # ifdef RT
718 #   define MACH_TYPE "RT"
719 #   define ALIGNMENT 4
720 #   define DATASTART ((ptr_t) 0x10000000)
721 #   define STACKBOTTOM ((ptr_t) 0x1fffd800)
722 # endif
723
724 # ifdef SPARC
725 #   define MACH_TYPE "SPARC"
726 #   if defined(__arch64__) || defined(__sparcv9)
727 #     define ALIGNMENT 8
728 #     define CPP_WORDSZ 64
729 #     define ELF_CLASS ELFCLASS64
730 #   else
731 #     define ALIGNMENT 4        /* Required by hardware */
732 #     define CPP_WORDSZ 32
733 #   endif
734 #   define ALIGN_DOUBLE
735 #   ifdef SUNOS5
736 #       define OS_TYPE "SUNOS5"
737         extern int _etext;
738         extern int _end;
739         extern char * GC_SysVGetDataStart();
740 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
741 #       define DATAEND (&_end)
742 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
743 #           define USE_MMAP
744             /* Otherwise we now use calloc.  Mmap may result in the     */
745             /* heap interleaved with thread stacks, which can result in */
746             /* excessive blacklisting.  Sbrk is unusable since it       */
747             /* doesn't interact correctly with the system malloc.       */
748 #       endif
749 #       ifdef USE_MMAP
750 #         define HEAP_START (ptr_t)0x40000000
751 #       else
752 #         define HEAP_START DATAEND
753 #       endif
754 #       define PROC_VDB
755 /*      HEURISTIC1 reportedly no longer works under 2.7.                */
756 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
757 /*      Apparently USRSTACK is defined to be USERLIMIT, but in some     */
758 /*      installations that's undefined.  We work around this with a     */
759 /*      gross hack:                                                     */
760 #       include <sys/vmparam.h>
761 #       ifdef USERLIMIT
762           /* This should work everywhere, but doesn't.  */
763 #         define STACKBOTTOM USRSTACK
764 #       else
765 #         define HEURISTIC2
766 #       endif
767 #       include <unistd.h>
768 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
769                 /* getpagesize() appeared to be missing from at least one */
770                 /* Solaris 5.4 installation.  Weird.                      */
771 #       if CPP_WORDSZ == 32
772 #         define DYNAMIC_LOADING
773 #       endif
774 #   endif
775 #   ifdef SUNOS4
776 #       define OS_TYPE "SUNOS4"
777         /* [If you have a weak stomach, don't read this.]               */
778         /* We would like to use:                                        */
779 /* #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x1fff) & ~0x1fff)) */
780         /* This fails occasionally, due to an ancient, but very         */
781         /* persistent ld bug.  &etext is set 32 bytes too high.         */
782         /* We instead read the text segment size from the a.out         */
783         /* header, which happens to be mapped into our address space    */
784         /* at the start of the text segment.  The detective work here   */
785         /* was done by Robert Ehrlich, Manuel Serrano, and Bernard      */
786         /* Serpette of INRIA.                                           */
787         /* This assumes ZMAGIC, i.e. demand-loadable executables.       */
788 #       define TEXTSTART 0x2000
789 #       define DATASTART ((ptr_t)(*(int *)(TEXTSTART+0x4)+TEXTSTART))
790 #       define MPROTECT_VDB
791 #       define HEURISTIC1
792 #       define DYNAMIC_LOADING
793 #   endif
794 #   ifdef DRSNX
795 #       define OS_TYPE "DRSNX"
796         extern char * GC_SysVGetDataStart();
797         extern int etext;
798 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext)
799 #       define MPROTECT_VDB
800 #       define STACKBOTTOM ((ptr_t) 0xdfff0000)
801 #       define DYNAMIC_LOADING
802 #   endif
803 #   ifdef LINUX
804 #     define OS_TYPE "LINUX"
805 #     ifdef __ELF__
806 #       define DYNAMIC_LOADING
807 #     else
808           Linux Sparc/a.out not supported
809 #     endif
810       extern int _end;
811       extern int _etext;
812 #     define DATAEND (&_end)
813 #     define SVR4
814 #     ifdef __arch64__
815 #       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
816 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, &_etext)
817 #     else
818 #       define STACKBOTTOM ((ptr_t) 0xf0000000)
819 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
820 #     endif
821 #   endif
822 #   ifdef OPENBSD
823 #     define OS_TYPE "OPENBSD"
824 #     define STACKBOTTOM ((ptr_t) 0xf8000000)
825       extern int etext;
826 #     define DATASTART ((ptr_t)(&etext))
827 #   endif
828 #   ifdef NETBSD
829 #     define OS_TYPE "NETBSD"
830 #     define HEURISTIC2
831 #     ifdef __ELF__
832 #       define DATASTART GC_data_start
833 #       define DYNAMIC_LOADING
834 #     else
835         extern char etext;
836 #       define DATASTART ((ptr_t)(&etext))
837 #     endif
838 #   endif
839 # endif
840
841 # ifdef I386
842 #   define MACH_TYPE "I386"
843 #   define ALIGNMENT 4  /* Appears to hold for all "32 bit" compilers   */
844                         /* except Borland.  The -a4 option fixes        */
845                         /* Borland.                                     */
846                         /* Ivan Demakov: For Watcom the option is -zp4. */
847 #   ifndef SMALL_CONFIG
848 #     define ALIGN_DOUBLE /* Not strictly necessary, but may give speed   */
849                           /* improvement on Pentiums.                     */
850 #   endif
851 #   ifdef HAVE_BUILTIN_UNWIND_INIT
852 #       define USE_GENERIC_PUSH_REGS
853 #   endif
854 #   ifdef SEQUENT
855 #       define OS_TYPE "SEQUENT"
856         extern int etext;
857 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
858 #       define STACKBOTTOM ((ptr_t) 0x3ffff000) 
859 #   endif
860 #   ifdef BEOS
861 #     define OS_TYPE "BEOS"
862 #     include <OS.h>
863 #     define GETPAGESIZE() B_PAGE_SIZE
864       extern int etext;
865 #     define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
866 #   endif
867 #   ifdef SUNOS5
868 #       define OS_TYPE "SUNOS5"
869         extern int _etext, _end;
870         extern char * GC_SysVGetDataStart();
871 #       define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
872 #       define DATAEND (&_end)
873 /*      # define STACKBOTTOM ((ptr_t)(&_start)) worked through 2.7,     */
874 /*      but reportedly breaks under 2.8.  It appears that the stack     */
875 /*      base is a property of the executable, so this should not break  */
876 /*      old executables.                                                */
877 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
878 #       include <sys/vm.h>
879 #       define STACKBOTTOM USRSTACK
880 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
881 /* It appears to be fixed in 2.8 and 2.9.                               */
882 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
883 #         define PROC_VDB
884 #       endif
885 #       define DYNAMIC_LOADING
886 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
887 #           define USE_MMAP
888             /* Otherwise we now use calloc.  Mmap may result in the     */
889             /* heap interleaved with thread stacks, which can result in */
890             /* excessive blacklisting.  Sbrk is unusable since it       */
891             /* doesn't interact correctly with the system malloc.       */
892 #       endif
893 #       ifdef USE_MMAP
894 #         define HEAP_START (ptr_t)0x40000000
895 #       else
896 #         define HEAP_START DATAEND
897 #       endif
898 #   endif
899 #   ifdef SCO
900 #       define OS_TYPE "SCO"
901         extern int etext;
902 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \
903                                   & ~0x3fffff) \
904                                  +((word)&etext & 0xfff))
905 #       define STACKBOTTOM ((ptr_t) 0x7ffffffc)
906 #   endif
907 #   ifdef SCO_ELF
908 #       define OS_TYPE "SCO_ELF"
909         extern int etext;
910 #       define DATASTART ((ptr_t)(&etext))
911 #       define STACKBOTTOM ((ptr_t) 0x08048000)
912 #       define DYNAMIC_LOADING
913 #       define ELF_CLASS ELFCLASS32
914 #   endif
915 #   ifdef LINUX
916 #       ifndef __GNUC__
917           /* The Intel compiler doesn't like inline assembly */
918 #         define USE_GENERIC_PUSH_REGS
919 #       endif
920 #       define OS_TYPE "LINUX"
921 #       define LINUX_STACKBOTTOM
922 #       if 0
923 #         define HEURISTIC1
924 #         undef STACK_GRAN
925 #         define STACK_GRAN 0x10000000
926           /* STACKBOTTOM is usually 0xc0000000, but this changes with   */
927           /* different kernel configurations.  In particular, systems   */
928           /* with 2GB physical memory will usually move the user        */
929           /* address space limit, and hence initial SP to 0x80000000.   */
930 #       endif
931 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
932 #           define MPROTECT_VDB
933 #       else
934             /* We seem to get random errors in incremental mode,        */
935             /* possibly because Linux threads is itself a malloc client */
936             /* and can't deal with the signals.                         */
937 #       endif
938 #       ifdef __ELF__
939 #            define DYNAMIC_LOADING
940 #            ifdef UNDEFINED    /* includes ro data */
941                extern int _etext;
942 #              define DATASTART ((ptr_t)((((word) (&_etext)) + 0xfff) & ~0xfff))
943 #            endif
944 #            include <features.h>
945 #            if defined(__GLIBC__) && __GLIBC__ >= 2
946 #                define LINUX_DATA_START
947 #            else
948                  extern char **__environ;
949 #                define DATASTART ((ptr_t)(&__environ))
950                               /* hideous kludge: __environ is the first */
951                               /* word in crt0.o, and delimits the start */
952                               /* of the data segment, no matter which   */
953                               /* ld options were passed through.        */
954                               /* We could use _etext instead, but that  */
955                               /* would include .rodata, which may       */
956                               /* contain large read-only data tables    */
957                               /* that we'd rather not scan.             */
958 #            endif
959              extern int _end;
960 #            define DATAEND (&_end)
961 #       else
962              extern int etext;
963 #            define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
964 #       endif
965 #       ifdef USE_I686_PREFETCH
966 #         define PREFETCH(x) \
967             __asm__ __volatile__ ("     prefetchnta     %0": : "m"(*(char *)(x)))
968             /* Empirically prefetcht0 is much more effective at reducing        */
969             /* cache miss stalls for the targetted load instructions.  But it   */
970             /* seems to interfere enough with other cache traffic that the net  */
971             /* result is worse than prefetchnta.                                */
972 #         if 0 
973             /* Using prefetches for write seems to have a slight negative       */
974             /* impact on performance, at least for a PIII/500.                  */
975 #           define PREFETCH_FOR_WRITE(x) \
976               __asm__ __volatile__ ("   prefetcht0      %0": : "m"(*(char *)(x)))
977 #         endif
978 #       endif
979 #       ifdef USE_3DNOW_PREFETCH
980 #         define PREFETCH(x) \
981             __asm__ __volatile__ ("     prefetch        %0": : "m"(*(char *)(x)))
982 #         define PREFETCH_FOR_WRITE(x) \
983             __asm__ __volatile__ ("     prefetchw       %0": : "m"(*(char *)(x)))
984 #       endif
985 #   endif
986 #   ifdef CYGWIN32
987 #       define OS_TYPE "CYGWIN32"
988           extern int _data_start__;
989           extern int _data_end__;
990           extern int _bss_start__;
991           extern int _bss_end__;
992         /* For binutils 2.9.1, we have                  */
993         /*      DATASTART   = _data_start__             */
994         /*      DATAEND     = _bss_end__                */
995         /* whereas for some earlier versions it was     */
996         /*      DATASTART   = _bss_start__              */
997         /*      DATAEND     = _data_end__               */
998         /* To get it right for both, we take the        */
999         /* minumum/maximum of the two.                  */
1000 #       define MAX(x,y) ((x) > (y) ? (x) : (y))
1001 #       define MIN(x,y) ((x) < (y) ? (x) : (y))
1002 #       define DATASTART ((ptr_t) MIN(&_data_start__, &_bss_start__))
1003 #       define DATAEND   ((ptr_t) MAX(&_data_end__, &_bss_end__))
1004 #       undef STACK_GRAN
1005 #       define STACK_GRAN 0x10000
1006 #       define HEURISTIC1
1007 #   endif
1008 #   ifdef OS2
1009 #       define OS_TYPE "OS2"
1010                 /* STACKBOTTOM and DATASTART are handled specially in   */
1011                 /* os_dep.c. OS2 actually has the right                 */
1012                 /* system call!                                         */
1013 #       define DATAEND  /* not needed */
1014 #       define USE_GENERIC_PUSH_REGS
1015 #   endif
1016 #   ifdef MSWIN32
1017 #       define OS_TYPE "MSWIN32"
1018                 /* STACKBOTTOM and DATASTART are handled specially in   */
1019                 /* os_dep.c.                                            */
1020 #       ifndef __WATCOMC__
1021 #         define MPROTECT_VDB
1022 #       endif
1023 #       define DATAEND  /* not needed */
1024 #   endif
1025 #   ifdef MSWINCE
1026 #       define OS_TYPE "MSWINCE"
1027 #       define DATAEND  /* not needed */
1028 #   endif
1029 #   ifdef DJGPP
1030 #       define OS_TYPE "DJGPP"
1031 #       include "stubinfo.h"
1032         extern int etext;
1033         extern int _stklen;
1034         extern int __djgpp_stack_limit;
1035 #       define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ff) & ~0x1ff))
1036 /* #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
1037                                                      + _stklen)) */
1038 #       define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen))
1039                 /* This may not be right.  */
1040 #   endif
1041 #   ifdef OPENBSD
1042 #       define OS_TYPE "OPENBSD"
1043 #   endif
1044 #   ifdef FREEBSD
1045 #       define OS_TYPE "FREEBSD"
1046 #       ifndef GC_FREEBSD_THREADS
1047 #           define MPROTECT_VDB
1048 #       endif
1049 #       define SIG_SUSPEND SIGUSR1
1050 #       define SIG_THR_RESTART SIGUSR2
1051 #       define FREEBSD_STACKBOTTOM
1052 #       ifdef __ELF__
1053 #           define DYNAMIC_LOADING
1054 #       endif
1055         extern char etext;
1056 #       define DATASTART ((ptr_t)(&etext))
1057 #   endif
1058 #   ifdef NETBSD
1059 #       define OS_TYPE "NETBSD"
1060 #   endif
1061 #   ifdef THREE86BSD
1062 #       define OS_TYPE "THREE86BSD"
1063 #   endif
1064 #   ifdef BSDI
1065 #       define OS_TYPE "BSDI"
1066 #   endif
1067 #   if defined(OPENBSD) || defined(NETBSD) \
1068         || defined(THREE86BSD) || defined(BSDI)
1069 #       define HEURISTIC2
1070         extern char etext;
1071 #       define DATASTART ((ptr_t)(&etext))
1072 #   endif
1073 #   ifdef NEXT
1074 #       define OS_TYPE "NEXT"
1075 #       define DATASTART ((ptr_t) get_etext())
1076 #       define STACKBOTTOM ((ptr_t)0xc0000000)
1077 #       define DATAEND  /* not needed */
1078 #   endif
1079 #   ifdef DOS4GW
1080 #     define OS_TYPE "DOS4GW"
1081       extern long __nullarea;
1082       extern char _end;
1083       extern char *_STACKTOP;
1084       /* Depending on calling conventions Watcom C either precedes
1085          or does not precedes with undescore names of C-variables.
1086          Make sure startup code variables always have the same names.  */
1087       #pragma aux __nullarea "*";
1088       #pragma aux _end "*";
1089 #     define STACKBOTTOM ((ptr_t) _STACKTOP)
1090                          /* confused? me too. */
1091 #     define DATASTART ((ptr_t) &__nullarea)
1092 #     define DATAEND ((ptr_t) &_end)
1093 #   endif
1094 #   ifdef HURD
1095 #     define OS_TYPE "HURD"
1096 #     define STACK_GROWS_DOWN
1097 #     define HEURISTIC2
1098       extern int  __data_start;
1099 #     define DATASTART ( (ptr_t) (&__data_start))
1100       extern int   _end;
1101 #     define DATAEND ( (ptr_t) (&_end))
1102 /* #     define MPROTECT_VDB  Not quite working yet? */
1103 #     define DYNAMIC_LOADING
1104 #   endif
1105 # endif
1106
1107 # ifdef NS32K
1108 #   define MACH_TYPE "NS32K"
1109 #   define ALIGNMENT 4
1110     extern char **environ;
1111 #   define DATASTART ((ptr_t)(&environ))
1112                               /* hideous kludge: environ is the first   */
1113                               /* word in crt0.o, and delimits the start */
1114                               /* of the data segment, no matter which   */
1115                               /* ld options were passed through.        */
1116 #   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */
1117 # endif
1118
1119 # ifdef MIPS
1120 #   define MACH_TYPE "MIPS"
1121 #   ifdef LINUX
1122       /* This was developed for a linuxce style platform.  Probably     */
1123       /* needs to be tweaked for workstation class machines.            */
1124 #     define OS_TYPE "LINUX"
1125       extern int __data_start;
1126 #     define DATASTART ((ptr_t)(&__data_start))
1127 #     define ALIGNMENT 4
1128 #     define USE_GENERIC_PUSH_REGS
1129 #     define STACKBOTTOM ((ptr_t)0x7fff8000)
1130         /* Older toolchains may need 0x80000000.        */
1131         /* In many cases, this should probably use LINUX_STACKBOTTOM    */
1132         /* instead. But some kernel versions seem to give the wrong     */
1133         /* value from /proc.                                            */
1134 #   endif /* Linux */
1135 #   ifdef EWS4800
1136 #      define HEURISTIC2
1137 #      if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1138          extern int _fdata[], _end[];
1139 #        define DATASTART ((ptr_t)_fdata)
1140 #        define DATAEND ((ptr_t)_end)
1141 #        define CPP_WORDSZ _MIPS_SZPTR
1142 #        define ALIGNMENT (_MIPS_SZPTR/8)
1143 #      else
1144          extern int etext, edata, end;
1145          extern int _DYNAMIC_LINKING, _gp;
1146 #        define DATASTART ((ptr_t)((((word)&etext + 0x3ffff) & ~0x3ffff) \
1147                + ((word)&etext & 0xffff)))
1148 #        define DATAEND (&edata)
1149 #        define DATASTART2 (&_DYNAMIC_LINKING \
1150                ? (ptr_t)(((word)&_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1151                : (ptr_t)&edata)
1152 #        define DATAEND2 (&end)
1153 #        define ALIGNMENT 4
1154 #      endif
1155 #      define OS_TYPE "EWS4800"
1156 #      define USE_GENERIC_PUSH_REGS 1
1157 #   endif
1158 #   ifdef ULTRIX
1159 #       define HEURISTIC2
1160 #       define DATASTART (ptr_t)0x10000000
1161                               /* Could probably be slightly higher since */
1162                               /* startup code allocates lots of stuff.   */
1163 #       define OS_TYPE "ULTRIX"
1164 #       define ALIGNMENT 4
1165 #   endif
1166 #   ifdef RISCOS
1167 #       define HEURISTIC2
1168 #       define DATASTART (ptr_t)0x10000000
1169 #       define OS_TYPE "RISCOS"
1170 #       define ALIGNMENT 4  /* Required by hardware */
1171 #   endif
1172 #   ifdef IRIX5
1173 #       define HEURISTIC2
1174         extern int _fdata;
1175 #       define DATASTART ((ptr_t)(&_fdata))
1176 #       ifdef USE_MMAP
1177 #         define HEAP_START (ptr_t)0x30000000
1178 #       else
1179 #         define HEAP_START DATASTART
1180 #       endif
1181                               /* Lowest plausible heap address.         */
1182                               /* In the MMAP case, we map there.        */
1183                               /* In either case it is used to identify  */
1184                               /* heap sections so they're not           */
1185                               /* considered as roots.                   */
1186 #       define OS_TYPE "IRIX5"
1187 #       define MPROTECT_VDB
1188 #       ifdef _MIPS_SZPTR
1189 #         define CPP_WORDSZ _MIPS_SZPTR
1190 #         define ALIGNMENT (_MIPS_SZPTR/8)
1191 #         if CPP_WORDSZ != 64
1192 #           define ALIGN_DOUBLE
1193 #         endif
1194 #       else
1195 #         define ALIGNMENT 4
1196 #         define ALIGN_DOUBLE
1197 #       endif
1198 #       define DYNAMIC_LOADING
1199 #   endif
1200 #   ifdef MSWINCE
1201 #       define OS_TYPE "MSWINCE"
1202 #       define ALIGNMENT 4
1203 #       define DATAEND /* not needed */
1204 #   endif
1205 #   if defined(NETBSD)
1206       /* This also checked for __MIPSEL__ .  Why?  NETBSD recognition   */
1207       /* should be handled at the top of the file.                      */
1208 #     define ALIGNMENT 4
1209 #     define OS_TYPE "NETBSD"
1210 #     define HEURISTIC2
1211 #     define USE_GENERIC_PUSH_REGS
1212 #     ifdef __ELF__
1213         extern int etext;
1214 #       define DATASTART GC_data_start
1215 #       define NEED_FIND_LIMIT
1216 #       define DYNAMIC_LOADING
1217 #     else
1218 #       define DATASTART ((ptr_t) 0x10000000)
1219 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
1220 #     endif /* _ELF_ */
1221 #  endif
1222 # endif
1223
1224 # ifdef RS6000
1225 #   define MACH_TYPE "RS6000"
1226 #   ifdef __64BIT__
1227 #     define ALIGNMENT 8
1228 #     define CPP_WORDSZ 64
1229 #   else
1230 #     define ALIGNMENT 4
1231 #     define CPP_WORDSZ 32
1232 #   endif
1233     extern int _data, _end;
1234 #   define DATASTART ((ptr_t)((ulong)&_data))
1235 #   define DATAEND ((ptr_t)((ulong)&_end))
1236     extern int errno;
1237 #   define STACKBOTTOM ((ptr_t)((ulong)&errno))
1238 #   define USE_GENERIC_PUSH_REGS
1239 #   define DYNAMIC_LOADING
1240         /* For really old versions of AIX, this may have to be removed. */
1241 # endif
1242
1243 # ifdef HP_PA
1244 #   define MACH_TYPE "HP_PA"
1245 #   ifdef __LP64__
1246 #     define CPP_WORDSZ 64
1247 #     define ALIGNMENT 8
1248 #   else
1249 #     define CPP_WORDSZ 32
1250 #     define ALIGNMENT 4
1251 #     define ALIGN_DOUBLE
1252 #   endif
1253 #   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS)
1254 #     ifndef LINUX /* For now. */
1255 #       define MPROTECT_VDB
1256 #     endif
1257 #   else
1258 #     define GENERIC_COMPARE_AND_SWAP
1259         /* No compare-and-swap instruction.  Use pthread mutexes        */
1260         /* when we absolutely have to.                                  */
1261 #     ifdef PARALLEL_MARK
1262 #       define USE_MARK_BYTES
1263                 /* Minimize compare-and-swap usage.             */
1264 #     endif
1265 #   endif
1266 #   define STACK_GROWS_UP
1267 #   ifdef HPUX
1268 #     define OS_TYPE "HPUX"
1269       extern int __data_start;
1270 #     define DATASTART ((ptr_t)(&__data_start))
1271 #     if 0
1272         /* The following appears to work for 7xx systems running HP/UX  */
1273         /* 9.xx Furthermore, it might result in much faster             */
1274         /* collections than HEURISTIC2, which may involve scanning      */
1275         /* segments that directly precede the stack.  It is not the     */
1276         /* default, since it may not work on older machine/OS           */
1277         /* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */
1278         /* this.)                                                       */
1279 #       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */
1280 #     else
1281         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1282         /* to this.  Note that the GC must be initialized before the    */
1283         /* first putenv call.                                           */
1284         extern char ** environ;
1285 #       define STACKBOTTOM ((ptr_t)environ)
1286 #     endif
1287 #     define DYNAMIC_LOADING
1288 #     include <unistd.h>
1289 #     define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1290 #     ifndef __GNUC__
1291 #       define PREFETCH(x)  { \
1292                               register long addr = (long)(x); \
1293                               (void) _asm ("LDW", 0, 0, addr, 0); \
1294                             }
1295 #     endif
1296 #   endif /* HPUX */
1297 #   ifdef LINUX
1298 #     define OS_TYPE "LINUX"
1299 #     define LINUX_STACKBOTTOM
1300 #     define DYNAMIC_LOADING
1301 #     define LINUX_DATA_START
1302       extern int _end;
1303 #     define DATAEND (&_end)
1304 #   endif /* LINUX */
1305 # endif /* HP_PA */
1306
1307 # ifdef ALPHA
1308 #   define MACH_TYPE "ALPHA"
1309 #   define ALIGNMENT 8
1310 #   ifdef NETBSD
1311 #       define OS_TYPE "NETBSD"
1312 #       define HEURISTIC2
1313 #       define DATASTART GC_data_start
1314 #       define ELFCLASS32 32
1315 #       define ELFCLASS64 64
1316 #       define ELF_CLASS ELFCLASS64
1317 #       define CPP_WORDSZ 64
1318 #       define DYNAMIC_LOADING
1319 #   endif
1320 #   ifdef OPENBSD
1321 #       define OS_TYPE "OPENBSD"
1322 #       define HEURISTIC2
1323 #       define CPP_WORDSZ 64
1324 #       ifdef __ELF__   /* since OpenBSD/Alpha 2.9 */
1325 #          define DATASTART GC_data_start
1326 #          define ELFCLASS32 32
1327 #          define ELFCLASS64 64
1328 #          define ELF_CLASS ELFCLASS64
1329 #       else            /* ECOFF, until OpenBSD/Alpha 2.7 */
1330 #          define DATASTART ((ptr_t) 0x140000000)
1331 #       endif
1332 #   endif
1333 #   ifdef OSF1
1334 #       define OS_TYPE "OSF1"
1335 #       define DATASTART ((ptr_t) 0x140000000)
1336         extern int _end;
1337 #       define DATAEND ((ptr_t) &_end)
1338         extern char ** environ;
1339         /* round up from the value of environ to the nearest page boundary */
1340         /* Probably breaks if putenv is called before collector            */
1341         /* initialization.                                                 */
1342 #       define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
1343 /* #    define HEURISTIC2 */
1344         /* Normally HEURISTIC2 is too conervative, since                */
1345         /* the text segment immediately follows the stack.              */
1346         /* Hence we give an upper pound.                                */
1347         /* This is currently unused, since we disabled HEURISTIC2       */
1348         extern int __start;
1349 #       define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1)))
1350 #       define CPP_WORDSZ 64
1351 #       define MPROTECT_VDB
1352 #       define DYNAMIC_LOADING
1353 #   endif
1354 #   ifdef LINUX
1355 #       define OS_TYPE "LINUX"
1356 #       define CPP_WORDSZ 64
1357 #       define STACKBOTTOM ((ptr_t) 0x120000000)
1358 #       ifdef __ELF__
1359 #         define SEARCH_FOR_DATA_START
1360 #         define DATASTART GC_data_start
1361 #         define DYNAMIC_LOADING
1362 #       else
1363 #           define DATASTART ((ptr_t) 0x140000000)
1364 #       endif
1365         extern int _end;
1366 #       define DATAEND (&_end)
1367 #       define MPROTECT_VDB
1368                 /* Has only been superficially tested.  May not */
1369                 /* work on all versions.                        */
1370 #   endif
1371 # endif
1372
1373 # ifdef IA64
1374 #   define MACH_TYPE "IA64"
1375 #   define USE_GENERIC_PUSH_REGS
1376         /* We need to get preserved registers in addition to register   */
1377         /* windows.   That's easiest to do with setjmp.                 */
1378 #   ifdef PARALLEL_MARK
1379 #       define USE_MARK_BYTES
1380             /* Compare-and-exchange is too expensive to use for         */
1381             /* setting mark bits.                                       */
1382 #   endif
1383 #   ifdef HPUX
1384 #       ifdef _ILP32
1385 #         define CPP_WORDSZ 32
1386 #         define ALIGN_DOUBLE
1387             /* Requires 8 byte alignment for malloc */
1388 #         define ALIGNMENT 4
1389 #       else
1390 #         ifndef _LP64
1391                 ---> unknown ABI
1392 #         endif
1393 #         define CPP_WORDSZ 64
1394 #         define ALIGN_DOUBLE
1395             /* Requires 16 byte alignment for malloc */
1396 #         define ALIGNMENT 8
1397 #       endif
1398 #       define OS_TYPE "HPUX"   
1399         extern int __data_start;
1400 #       define DATASTART ((ptr_t)(&__data_start))
1401         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1402         /* to this.  Note that the GC must be initialized before the    */
1403         /* first putenv call.                                           */
1404         extern char ** environ;
1405 #       define STACKBOTTOM ((ptr_t)environ)
1406 #       define DYNAMIC_LOADING
1407 #       include <unistd.h>
1408 #       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1409         /* The following was empirically determined, and is probably    */
1410         /* not very robust.                                             */
1411         /* Note that the backing store base seems to be at a nice       */
1412         /* address minus one page.                                      */
1413 #       define BACKING_STORE_DISPLACEMENT 0x1000000
1414 #       define BACKING_STORE_ALIGNMENT 0x1000
1415 #       define BACKING_STORE_BASE \
1416           (ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) \
1417                         & ~(BACKING_STORE_ALIGNMENT - 1))
1418 #   endif
1419 #   ifdef LINUX
1420 #       define CPP_WORDSZ 64
1421 #       define ALIGN_DOUBLE
1422           /* Requires 16 byte alignment for malloc */
1423 #       define ALIGNMENT 8
1424 #       define OS_TYPE "LINUX"
1425         /* The following works on NUE and older kernels:        */
1426 /* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)     */
1427         /* This does not work on NUE:                           */
1428 #       define LINUX_STACKBOTTOM
1429         /* We also need the base address of the register stack  */
1430         /* backing store.  This is computed in                  */
1431         /* GC_linux_register_stack_base based on the following  */
1432         /* constants:                                           */
1433 #       define BACKING_STORE_ALIGNMENT 0x100000
1434 #       define BACKING_STORE_DISPLACEMENT 0x80000000
1435         extern char * GC_register_stackbottom;
1436 #       define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom)
1437 #       define SEARCH_FOR_DATA_START
1438 #       define DATASTART GC_data_start
1439 #       ifdef __GNUC__
1440 #         define DYNAMIC_LOADING
1441 #       else
1442           /* In the Intel compiler environment, we seem to end up with  */
1443           /* statically linked executables and an undefined reference   */
1444           /* to _DYNAMIC                                                */
1445 #       endif
1446 #       define MPROTECT_VDB
1447                 /* Requires Linux 2.3.47 or later.      */
1448         extern int _end;
1449 #       define DATAEND (&_end)
1450 #       ifdef __GNUC__
1451 #         define PREFETCH(x) \
1452             __asm__ ("  lfetch  [%0]": : "r"((void *)(x)))
1453 #         define PREFETCH_FOR_WRITE(x) \
1454             __asm__ ("  lfetch.excl     [%0]": : "r"((void *)(x)))
1455 #         define CLEAR_DOUBLE(x) \
1456             __asm__ ("  stf.spill       [%0]=f0": : "r"((void *)(x)))
1457 #       endif
1458 #   endif
1459 # endif
1460
1461 # ifdef M88K
1462 #   define MACH_TYPE "M88K"
1463 #   define ALIGNMENT 4
1464 #   define ALIGN_DOUBLE
1465     extern int etext;
1466 #   ifdef CX_UX
1467 #       define OS_TYPE "CX_UX"
1468 #       define DATASTART ((((word)&etext + 0x3fffff) & ~0x3fffff) + 0x10000)
1469 #   endif
1470 #   ifdef  DGUX
1471 #       define OS_TYPE "DGUX"
1472         extern char * GC_SysVGetDataStart();
1473 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext)
1474 #   endif
1475 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
1476 # endif
1477
1478 # ifdef S370
1479 #   define MACH_TYPE "S370"
1480 #   define ALIGNMENT 4  /* Required by hardware */
1481 #   define USE_GENERIC_PUSH_REGS
1482 #   ifdef UTS4
1483 #       define OS_TYPE "UTS4"
1484         extern int etext;
1485         extern int _etext;
1486         extern int _end;
1487         extern char * GC_SysVGetDataStart();
1488 #       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
1489 #       define DATAEND (&_end)
1490 #       define HEURISTIC2
1491 #   endif
1492 #   ifdef LINUX
1493 #       define OS_TYPE "LINUX"
1494 #       define HEURISTIC1
1495 #       define DYNAMIC_LOADING
1496         extern int __data_start;
1497 #       define DATASTART ((ptr_t)(&__data_start))
1498 #   endif
1499 # endif
1500
1501 # if defined(PJ)
1502 #   define ALIGNMENT 4
1503     extern int _etext;
1504 #   define DATASTART ((ptr_t)(&_etext))
1505 #   define HEURISTIC1
1506 # endif
1507
1508 # ifdef ARM32
1509 #   define CPP_WORDSZ 32
1510 #   define MACH_TYPE "ARM32"
1511 #   define ALIGNMENT 4
1512 #   ifdef NETBSD
1513 #       define OS_TYPE "NETBSD"
1514 #       define HEURISTIC2
1515         extern char etext;
1516 #       define DATASTART ((ptr_t)(&etext))
1517 #       define USE_GENERIC_PUSH_REGS
1518 #   endif
1519 #   ifdef LINUX
1520 #       define OS_TYPE "LINUX"
1521 #       define HEURISTIC1
1522 #       undef STACK_GRAN
1523 #       define STACK_GRAN 0x10000000
1524 #       define USE_GENERIC_PUSH_REGS
1525 #       ifdef __ELF__
1526 #            define DYNAMIC_LOADING
1527 #            include <features.h>
1528 #            if defined(__GLIBC__) && __GLIBC__ >= 2
1529 #                define LINUX_DATA_START
1530 #            else
1531                  extern char **__environ;
1532 #                define DATASTART ((ptr_t)(&__environ))
1533                               /* hideous kludge: __environ is the first */
1534                               /* word in crt0.o, and delimits the start */
1535                               /* of the data segment, no matter which   */
1536                               /* ld options were passed through.        */
1537                               /* We could use _etext instead, but that  */
1538                               /* would include .rodata, which may       */
1539                               /* contain large read-only data tables    */
1540                               /* that we'd rather not scan.             */
1541 #            endif
1542              extern int _end;
1543 #            define DATAEND (&_end)
1544 #       else
1545              extern int etext;
1546 #            define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
1547 #       endif
1548 #   endif
1549 #   ifdef MSWINCE
1550 #     define OS_TYPE "MSWINCE"
1551 #     define DATAEND /* not needed */
1552 #   endif
1553 #   ifdef NOSYS
1554       /* __data_start is usually defined in the target linker script.  */
1555       extern int __data_start;
1556 #     define DATASTART (ptr_t)(&__data_start)
1557 #     define USE_GENERIC_PUSH_REGS
1558       /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */
1559       extern void *__stack_base__;
1560 #     define STACKBOTTOM ((ptr_t) (__stack_base__))
1561 #   endif
1562 #endif
1563
1564 # ifdef SH
1565 #   define MACH_TYPE "SH"
1566 #   define ALIGNMENT 4
1567 #   ifdef MSWINCE
1568 #     define OS_TYPE "MSWINCE"
1569 #     define DATAEND /* not needed */
1570 #   endif
1571 #   ifdef LINUX
1572 #     define OS_TYPE "LINUX"
1573 #     define STACKBOTTOM ((ptr_t) 0x7c000000)
1574 #     define USE_GENERIC_PUSH_REGS
1575 #     define DYNAMIC_LOADING
1576 #     define LINUX_DATA_START
1577       extern int _end;
1578 #     define DATAEND (&_end)
1579 #   endif
1580 # endif
1581  
1582 # ifdef SH4
1583 #   define MACH_TYPE "SH4"
1584 #   define OS_TYPE "MSWINCE"
1585 #   define ALIGNMENT 4
1586 #   define DATAEND /* not needed */
1587 # endif
1588
1589 #ifdef LINUX_DATA_START
1590     /* Some Linux distributions arrange to define __data_start.  Some   */
1591     /* define data_start as a weak symbol.  The latter is technically   */
1592     /* broken, since the user program may define data_start, in which   */
1593     /* case we lose.  Nonetheless, we try both, prefering __data_start. */
1594     /* We assume gcc.   */
1595 #   pragma weak __data_start
1596     extern int __data_start;
1597 #   pragma weak data_start
1598     extern int data_start;
1599 #   define DATASTART ((ptr_t)(&__data_start != 0? &__data_start : &data_start))
1600 #endif
1601
1602 #if defined(LINUX) && defined(REDIRECT_MALLOC)
1603     /* Rld appears to allocate some memory with its own allocator, and  */
1604     /* some through malloc, which might be redirected.  To make this    */
1605     /* work with collectable memory, we have to scan memory allocated   */
1606     /* by rld's internal malloc.                                        */
1607 #   define USE_PROC_FOR_LIBRARIES
1608 #endif
1609     
1610 # ifndef STACK_GROWS_UP
1611 #   define STACK_GROWS_DOWN
1612 # endif
1613
1614 # ifndef CPP_WORDSZ
1615 #   define CPP_WORDSZ 32
1616 # endif
1617
1618 # ifndef OS_TYPE
1619 #   define OS_TYPE ""
1620 # endif
1621
1622 # ifndef DATAEND
1623     extern int end;
1624 #   define DATAEND (&end)
1625 # endif
1626
1627 # if defined(SVR4) && !defined(GETPAGESIZE)
1628 #    include <unistd.h>
1629 #    define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
1630 # endif
1631
1632 # ifndef GETPAGESIZE
1633 #   if defined(SUNOS5) || defined(IRIX5)
1634 #       include <unistd.h>
1635 #   endif
1636 #   define GETPAGESIZE() getpagesize()
1637 # endif
1638
1639 # if defined(SUNOS5) || defined(DRSNX) || defined(UTS4)
1640     /* OS has SVR4 generic features.  Probably others also qualify.     */
1641 #   define SVR4
1642 # endif
1643
1644 # if defined(SUNOS5) || defined(DRSNX)
1645     /* OS has SUNOS5 style semi-undocumented interface to dynamic       */
1646     /* loader.                                                          */
1647 #   define SUNOS5DL
1648     /* OS has SUNOS5 style signal handlers.                             */
1649 #   define SUNOS5SIGS
1650 # endif
1651
1652 # if defined(HPUX)
1653 #   define SUNOS5SIGS
1654 # endif
1655
1656 # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
1657     || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
1658     || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1)
1659 #   define UNIX_LIKE   /* Basic Unix-like system calls work.    */
1660 # endif
1661
1662 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
1663    -> bad word size
1664 # endif
1665
1666 # ifdef PCR
1667 #   undef DYNAMIC_LOADING
1668 #   undef STACKBOTTOM
1669 #   undef HEURISTIC1
1670 #   undef HEURISTIC2
1671 #   undef PROC_VDB
1672 #   undef MPROTECT_VDB
1673 #   define PCR_VDB
1674 # endif
1675
1676 # ifdef SRC_M3
1677 /* Postponed for now. */
1678 #   undef PROC_VDB
1679 #   undef MPROTECT_VDB
1680 # endif
1681
1682 # ifdef SMALL_CONFIG
1683 /* Presumably not worth the space it takes. */
1684 #   undef PROC_VDB
1685 #   undef MPROTECT_VDB
1686 # endif
1687
1688 # ifdef USE_MUNMAP
1689 #   undef MPROTECT_VDB  /* Can't deal with address space holes. */
1690 # endif
1691
1692 # ifdef PARALLEL_MARK
1693 #   undef MPROTECT_VDB  /* For now.     */
1694 # endif
1695
1696 # if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB)
1697 #   define DEFAULT_VDB
1698 # endif
1699
1700 # ifndef PREFETCH
1701 #   define PREFETCH(x)
1702 #   define NO_PREFETCH
1703 # endif
1704
1705 # ifndef PREFETCH_FOR_WRITE
1706 #   define PREFETCH_FOR_WRITE(x)
1707 #   define NO_PREFETCH_FOR_WRITE
1708 # endif
1709
1710 # ifndef CACHE_LINE_SIZE
1711 #   define CACHE_LINE_SIZE 32   /* Wild guess   */
1712 # endif
1713
1714 # ifndef CLEAR_DOUBLE
1715 #   define CLEAR_DOUBLE(x) \
1716         ((word*)x)[0] = 0; \
1717         ((word*)x)[1] = 0;
1718 # endif /* CLEAR_DOUBLE */
1719
1720 /* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */
1721 # if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
1722 #   define GC_SOLARIS_THREADS
1723 # endif
1724
1725 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
1726 --> inconsistent configuration
1727 # endif
1728 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
1729 --> inconsistent configuration
1730 # endif
1731 # if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
1732 --> inconsistent configuration
1733 # endif
1734 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
1735 --> inconsistent configuration
1736 # endif
1737 # if defined(GC_WIN32_THREADS) && !defined(MSWIN32)
1738     /* Ideally CYGWIN32 should work, in addition to MSWIN32.  I suspect */
1739     /* the necessary code is mostly there, but nobody has actually made */
1740     /* sure the right combination of pieces is compiled in, etc.        */
1741 --> inconsistent configuration
1742 # endif
1743
1744 # if defined(PCR) || defined(SRC_M3) || \
1745         defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \
1746         defined(GC_PTHREADS)
1747 #   define THREADS
1748 # endif
1749
1750 # if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \
1751      || defined(LINT) || defined(MSWINCE) \
1752      || (defined(I386) && defined(__LCC__))
1753         /* Use setjmp based hack to mark from callee-save registers.    */
1754         /* The define should move to the individual platform            */
1755         /* descriptions.                                                */
1756 #       define USE_GENERIC_PUSH_REGS
1757 # endif
1758
1759 # if defined(SPARC)
1760 #   define ASM_CLEAR_CODE       /* Stack clearing is crucial, and we    */
1761                                 /* include assembly code to do it well. */
1762 # endif
1763
1764 /* Can we save call chain in objects for debugging?                     */
1765 /* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame)  */
1766 /* to reasonable values for the platform.                               */
1767 /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified at  */
1768 /* build time, though we feel free to adjust it slightly.               */
1769 /* Define NEED_CALLINFO if we either save the call stack or             */
1770 /* GC_ADD_CALLER is defined.                                            */
1771 #ifdef LINUX
1772 # include <features.h>
1773 # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
1774 #   define HAVE_BUILTIN_BACKTRACE
1775 # endif
1776 #endif
1777
1778 #if defined(SPARC)
1779 # define CAN_SAVE_CALL_STACKS
1780 # define CAN_SAVE_CALL_ARGS
1781 #endif
1782 #if defined(I386) && defined(LINUX)
1783     /* SAVE_CALL_CHAIN is supported if the code is compiled to save     */
1784     /* frame pointers by default, i.e. no -fomit-frame-pointer flag.    */
1785 # define CAN_SAVE_CALL_STACKS
1786 # define CAN_SAVE_CALL_ARGS
1787 #endif
1788 #if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS)
1789 # define CAN_SAVE_CALL_STACKS
1790 #endif
1791
1792 # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
1793      && defined(CAN_SAVE_CALL_STACKS)
1794 #   define SAVE_CALL_CHAIN 
1795 # endif
1796 # ifdef SAVE_CALL_CHAIN
1797 #   if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
1798 #     define NARGS SAVE_CALL_NARGS
1799 #   else
1800 #     define NARGS 0    /* Number of arguments to save for each call.   */
1801 #   endif
1802 # endif
1803 # ifdef SAVE_CALL_CHAIN
1804 #   ifndef SAVE_CALL_COUNT
1805 #     define NFRAMES 6  /* Number of frames to save. Even for           */
1806                         /* alignment reasons.                           */
1807 #   else
1808 #     define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
1809 #   endif
1810 #   define NEED_CALLINFO
1811 # endif /* SAVE_CALL_CHAIN */
1812 # ifdef GC_ADD_CALLER
1813 #   define NFRAMES 1
1814 #   define NARGS 0
1815 #   define NEED_CALLINFO
1816 # endif
1817
1818 # if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
1819 #   define DBG_HDRS_ALL
1820 # endif
1821
1822 # endif /* GCCONFIG_H */