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