⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_dep.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 5 页
字号:
#       if defined(SUNOS5SIGS) || defined(IRIX5) \	   || defined(OSF1) || defined(HURD) || defined(NETBSD)	  (void) sigaction(SIGSEGV, &old_segv_act, 0);#	  if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \	     || defined(HPUX) || defined(HURD) || defined(NETBSD)	      (void) sigaction(SIGBUS, &old_bus_act, 0);#	  endif#       else  	  (void) signal(SIGSEGV, old_segv_handler);#	  ifdef SIGBUS	    (void) signal(SIGBUS, old_bus_handler);#	  endif#       endif    }    /* Return the first nonaddressible location > p (up) or 	*/    /* the smallest location q s.t. [q,p) is addressable (!up).	*/    /* We assume that p (up) or p-1 (!up) is addressable.	*/    /* Requires allocation lock.				*/    ptr_t GC_find_limit_with_bound(ptr_t p, GC_bool up, ptr_t bound)    {        static volatile ptr_t result;    		/* Safer if static, since otherwise it may not be	*/    		/* preserved across the longjmp.  Can safely be 	*/    		/* static since it's only called with the		*/    		/* allocation lock held.				*/	GC_ASSERT(I_HOLD_LOCK());	GC_setup_temporary_fault_handler();	if (SETJMP(GC_jmp_buf) == 0) {	    result = (ptr_t)(((word)(p))			      & ~(MIN_PAGE_SIZE-1));	    for (;;) { 	        if (up) {		    result += MIN_PAGE_SIZE;		    if (result >= bound) return bound; 	        } else {		    result -= MIN_PAGE_SIZE;		    if (result <= bound) return bound; 	        }		GC_noop1((word)(*result));	    }	}	GC_reset_fault_handler(); 	if (!up) {	    result += MIN_PAGE_SIZE; 	}	return(result);    }    ptr_t GC_find_limit(ptr_t p, GC_bool up)    {      if (up) {	return GC_find_limit_with_bound(p, up, (ptr_t)(word)(-1));      } else {	return GC_find_limit_with_bound(p, up, 0);      }    }# endif#if defined(ECOS) || defined(NOSYS)  ptr_t GC_get_main_stack_base(void)  {    return STACKBOTTOM;  }#endif#ifdef HPUX_STACKBOTTOM#include <sys/param.h>#include <sys/pstat.h>  ptr_t GC_get_register_stack_base(void)  {    struct pst_vm_status vm_status;    int i = 0;    while (pstat_getprocvm(&vm_status, sizeof(vm_status), 0, i++) == 1) {      if (vm_status.pst_type == PS_RSESTACK) {        return (ptr_t) vm_status.pst_vaddr;      }    }    /* old way to get the register stackbottom */    return (ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1)                   & ~(BACKING_STORE_ALIGNMENT - 1));  }#endif /* HPUX_STACK_BOTTOM */#ifdef LINUX_STACKBOTTOM#include <sys/types.h>#include <sys/stat.h># define STAT_SKIP 27   /* Number of fields preceding startstack	*/			/* field in /proc/self/stat			*/#ifdef USE_LIBC_PRIVATES# pragma weak __libc_stack_end  extern ptr_t __libc_stack_end;#endif# ifdef IA64#   ifdef USE_LIBC_PRIVATES#     pragma weak __libc_ia64_register_backing_store_base      extern ptr_t __libc_ia64_register_backing_store_base;#   endif    ptr_t GC_get_register_stack_base(void)    {      ptr_t result;#     ifdef USE_LIBC_PRIVATES        if (0 != &__libc_ia64_register_backing_store_base	    && 0 != __libc_ia64_register_backing_store_base) {	  /* Glibc 2.2.4 has a bug such that for dynamically linked	*/	  /* executables __libc_ia64_register_backing_store_base is 	*/	  /* defined but uninitialized during constructor calls.  	*/	  /* Hence we check for both nonzero address and value.		*/	  return __libc_ia64_register_backing_store_base;        }#     endif      result = backing_store_base_from_proc();      if (0 == result) {	  result = GC_find_limit(GC_save_regs_in_stack(), FALSE);	  /* Now seems to work better than constant displacement	*/	  /* heuristic used in 6.X versions.  The latter seems to	*/	  /* fail for 2.6 kernels.					*/      }      return result;    }# endif  ptr_t GC_linux_stack_base(void)  {    /* We read the stack base value from /proc/self/stat.  We do this	*/    /* using direct I/O system calls in order to avoid calling malloc   */    /* in case REDIRECT_MALLOC is defined.				*/ #   define STAT_BUF_SIZE 4096#   define STAT_READ read	  /* Should probably call the real read, if read is wrapped.	*/    char stat_buf[STAT_BUF_SIZE];    int f;    char c;    word result = 0;    size_t i, buf_offset = 0;    /* First try the easy way.  This should work for glibc 2.2	*/    /* This fails in a prelinked ("prelink" command) executable */    /* since the correct value of __libc_stack_end never	*/    /* becomes visible to us.  The second test works around 	*/    /* this.							*/  #   ifdef USE_LIBC_PRIVATES      if (0 != &__libc_stack_end && 0 != __libc_stack_end ) {#       if defined(IA64)	  /* Some versions of glibc set the address 16 bytes too	*/	  /* low while the initialization code is running.		*/	  if (((word)__libc_stack_end & 0xfff) + 0x10 < 0x1000) {	    return __libc_stack_end + 0x10;	  } /* Otherwise it's not safe to add 16 bytes and we fall	*/	    /* back to using /proc.					*/#	elif defined(SPARC)	  /* Older versions of glibc for 64-bit Sparc do not set	   * this variable correctly, it gets set to either zero	   * or one.	   */	  if (__libc_stack_end != (ptr_t) (unsigned long)0x1)	    return __libc_stack_end;#	else	  return __libc_stack_end;#	endif      }#   endif    f = open("/proc/self/stat", O_RDONLY);    if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {	ABORT("Couldn't read /proc/self/stat");    }    c = stat_buf[buf_offset++];    /* Skip the required number of fields.  This number is hopefully	*/    /* constant across all Linux implementations.			*/      for (i = 0; i < STAT_SKIP; ++i) {	while (isspace(c)) c = stat_buf[buf_offset++];	while (!isspace(c)) c = stat_buf[buf_offset++];      }    while (isspace(c)) c = stat_buf[buf_offset++];    while (isdigit(c)) {      result *= 10;      result += c - '0';      c = stat_buf[buf_offset++];    }    close(f);    if (result < 0x10000000) ABORT("Absurd stack bottom value");    return (ptr_t)result;  }#endif /* LINUX_STACKBOTTOM */#ifdef FREEBSD_STACKBOTTOM/* This uses an undocumented sysctl call, but at least one expert 	*//* believes it will stay.						*/#include <unistd.h>#include <sys/types.h>#include <sys/sysctl.h>  ptr_t GC_freebsd_stack_base(void)  {    int nm[2] = {CTL_KERN, KERN_USRSTACK};    ptr_t base;    size_t len = sizeof(ptr_t);    int r = sysctl(nm, 2, &base, &len, NULL, 0);        if (r) ABORT("Error getting stack base");    return base;  }#endif /* FREEBSD_STACKBOTTOM */#if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \    && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \    && !defined(CYGWIN32)ptr_t GC_get_main_stack_base(void){#   if defined(HEURISTIC1) || defined(HEURISTIC2)      word dummy;#   endif    ptr_t result;#   define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1)#   ifdef STACKBOTTOM	return(STACKBOTTOM);#   else#	ifdef HEURISTIC1#	   ifdef STACK_GROWS_DOWN	     result = (ptr_t)((((word)(&dummy))	     		       + STACKBOTTOM_ALIGNMENT_M1)			      & ~STACKBOTTOM_ALIGNMENT_M1);#	   else	     result = (ptr_t)(((word)(&dummy))			      & ~STACKBOTTOM_ALIGNMENT_M1);#	   endif#	endif /* HEURISTIC1 */#	ifdef LINUX_STACKBOTTOM	   result = GC_linux_stack_base();#	endif#	ifdef FREEBSD_STACKBOTTOM	   result = GC_freebsd_stack_base();#	endif#	ifdef HEURISTIC2#	    ifdef STACK_GROWS_DOWN		result = GC_find_limit((ptr_t)(&dummy), TRUE);#           	ifdef HEURISTIC2_LIMIT		    if (result > HEURISTIC2_LIMIT		        && (ptr_t)(&dummy) < HEURISTIC2_LIMIT) {		            result = HEURISTIC2_LIMIT;		    }#	        endif#	    else		result = GC_find_limit((ptr_t)(&dummy), FALSE);#           	ifdef HEURISTIC2_LIMIT		    if (result < HEURISTIC2_LIMIT		        && (ptr_t)(&dummy) > HEURISTIC2_LIMIT) {		            result = HEURISTIC2_LIMIT;		    }#	        endif#	    endif#	endif /* HEURISTIC2 */#	ifdef STACK_GROWS_DOWN	    if (result == 0) result = (ptr_t)(signed_word)(-sizeof(ptr_t));#	endif    	return(result);#   endif /* STACKBOTTOM */}# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */#if defined(GC_LINUX_THREADS) && !defined(HAVE_GET_STACK_BASE)#include <pthread.h>#ifdef IA64  ptr_t GC_greatest_stack_base_below(ptr_t bound);  	/* From pthread_support.c */#endifint GC_get_stack_base(struct GC_stack_base *b){    pthread_attr_t attr;    size_t size;    if (pthread_getattr_np(pthread_self(), &attr) != 0) {	WARN("pthread_getattr_np failed\n", 0);	return GC_UNIMPLEMENTED;    }    if (pthread_attr_getstack(&attr, &(b -> mem_base), &size) != 0) {	ABORT("pthread_attr_getstack failed");    }#   ifdef STACK_GROWS_DOWN        b -> mem_base = (char *)(b -> mem_base) + size;#   endif#   ifdef IA64      /* We could try backing_store_base_from_proc, but that's safe	*/      /* only if no mappings are being asynchronously created.		*/      /* Subtracting the size from the stack base doesn't work for at	*/      /* least the main thread.						*/      LOCK();      {	ptr_t bsp = GC_save_regs_in_stack();	ptr_t next_stack = GC_greatest_stack_base_below(bsp);	if (0 == next_stack) {          b -> reg_base = GC_find_limit(bsp, FALSE);	} else {	  /* Avoid walking backwards into preceding memory stack and	*/	  /* growing it.						*/          b -> reg_base = GC_find_limit_with_bound(bsp, FALSE, next_stack);	}      }      UNLOCK();#   endif    return GC_SUCCESS;}#define HAVE_GET_STACK_BASE#endif /* GC_LINUX_THREADS */#ifndef HAVE_GET_STACK_BASE/* Retrieve stack base.						*//* Using the GC_find_limit version is risky.			*//* On IA64, for example, there is no guard page between the	*//* stack of one thread and the register backing store of the 	*//* next.  Thus this is likely to identify way too large a	*//* "stack" and thus at least result in disastrous performance.	*//* FIXME - Implement better strategies here.			*/int GC_get_stack_base(struct GC_stack_base *b){    int dummy;#   ifdef NEED_FIND_LIMIT#     ifdef STACK_GROWS_DOWN    	b -> mem_base = GC_find_limit((ptr_t)(&dummy), TRUE);#       ifdef IA64	  b -> reg_base = GC_find_limit(GC_save_regs_in_stack(), FALSE);#       endif#     else	b -> mem_base = GC_find_limit(&dummy, FALSE);#     endif      return GC_SUCCESS;#   else      return GC_UNIMPLEMENTED;#   endif}#endif/* * Register static data segment(s) as roots. * If more data segments are added later then they need to be registered * add that point (as we do with SunOS dynamic loading), * or GC_mark_roots needs to check for them (as we do with PCR). * Called with allocator lock held. */# ifdef OS2void GC_register_data_segments(void){    PTIB ptib;    PPIB ppib;    HMODULE module_handle;#   define PBUFSIZ 512    UCHAR path[PBUFSIZ];    FILE * myexefile;    struct exe_hdr hdrdos;	/* MSDOS header.	*/    struct e32_exe hdr386;	/* Real header for my executable */    struct o32_obj seg;	/* Currrent segment */    int nsegs;            if (DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) {    	GC_err_printf("DosGetInfoBlocks failed\n");    	ABORT("DosGetInfoBlocks failed\n");    }    module_handle = ppib -> pib_hmte;    if (DosQueryModuleName(module_handle, PBUFSIZ, path) != NO_ERROR) {    	GC_err_printf("DosQueryModuleName failed\n");    	ABORT("DosGetInfoBlocks failed\n");    }    myexefile = fopen(path, "rb");    if (myexefile == 0) {        GC_err_puts("Couldn't open executable ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Failed to open executable\n");    }    if (fread((char *)(&hdrdos), 1, sizeof hdrdos, myexefile) < sizeof hdrdos) {        GC_err_puts("Couldn't read MSDOS header from ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Couldn't read MSDOS header");    }    if (E_MAGIC(hdrdos) != EMAGIC) {        GC_err_puts("Executable has wrong DOS magic number: ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Bad DOS magic number");    }    if (fseek(myexefile, E_LFANEW(hdrdos), SEEK_SET) != 0) {        GC_err_puts("Seek to new header failed in ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Bad DOS magic number");    }    if (fread((char *)(&hdr386), 1, sizeof hdr386, myexefile) < sizeof hdr386) {        GC_err_puts("Couldn't read MSDOS header from ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Couldn't read OS/2 header");    }    if (E32_MAGIC1(hdr386) != E32MAGIC1 || E32_MAGIC2(hdr386) != E32MAGIC2) {        GC_err_puts("Executable has wrong OS/2 magic number:");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Bad OS/2 magic number");    }    if ( E32_BORDER(hdr386) != E32LEBO || E32_WORDER(hdr386) != E32LEWO) {        GC_err_puts("Executable %s has wrong byte order: ");        GC_err_puts(path); GC_err_puts("\n");        ABORT("Bad byte order");    }    if ( E32_CPU(hdr386) == E32CPU286) {        GC_err_puts("GC can't handle 80286 executables: ");        GC_err_puts(path); GC_err_puts("\n");        EXIT();    }    if (fseek(myexefile, E_LFANEW(hdrdos) + E32_OBJTAB(hdr386),    	      SEEK_SET) != 0) {        GC_err_puts("Seek to object table failed: ");        GC_err_puts(path); GC_err_puts("\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -