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

📄 os_dep.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved. * Copyright (c) 1999 by Hewlett-Packard Company.  All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program * for any purpose,  provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. */# include "private/gc_priv.h"# if defined(LINUX) && !defined(POWERPC)#   include <linux/version.h>#   if (LINUX_VERSION_CODE <= 0x10400)      /* Ugly hack to get struct sigcontext_struct definition.  Required      */      /* for some early 1.3.X releases.  Will hopefully go away soon. */      /* in some later Linux releases, asm/sigcontext.h may have to   */      /* be included instead.                                         */#     define __KERNEL__#     include <asm/signal.h>#     undef __KERNEL__#   else      /* Kernels prior to 2.1.1 defined struct sigcontext_struct instead of */      /* struct sigcontext.  libc6 (glibc2) uses "struct sigcontext" in     */      /* prototypes, so we have to include the top-level sigcontext.h to    */      /* make sure the former gets defined to be the latter if appropriate. */#     include <features.h>#     if 2 <= __GLIBC__#       if 2 == __GLIBC__ && 0 == __GLIBC_MINOR__	  /* glibc 2.1 no longer has sigcontext.h.  But signal.h	*/	  /* has the right declaration for glibc 2.1.			*/#         include <sigcontext.h>#       endif /* 0 == __GLIBC_MINOR__ */#     else /* not 2 <= __GLIBC__ */        /* libc5 doesn't have <sigcontext.h>: go directly with the kernel   */        /* one.  Check LINUX_VERSION_CODE to see which we should reference. */#       include <asm/sigcontext.h>#     endif /* 2 <= __GLIBC__ */#   endif# endif# if !defined(OS2) && !defined(PCR) && !defined(AMIGA) && !defined(MACOS) \    && !defined(MSWINCE)#   include <sys/types.h>#   if !defined(MSWIN32) && !defined(SUNOS4)#   	include <unistd.h>#   endif# endif# include <stdio.h># if defined(MSWINCE)#   define SIGSEGV 0 /* value is irrelevant */# else#   include <signal.h># endif#if defined(LINUX) || defined(LINUX_STACKBOTTOM)# include <ctype.h>#endif/* Blatantly OS dependent routines, except for those that are related 	*//* to dynamic loading.							*/# if defined(HEURISTIC2) || defined(SEARCH_FOR_DATA_START)#   define NEED_FIND_LIMIT# endif# if !defined(STACKBOTTOM) && defined(HEURISTIC2)#   define NEED_FIND_LIMIT# endif# if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR)#   define NEED_FIND_LIMIT# endif# if (defined(SVR4) || defined(AUX) || defined(DGUX) \      || (defined(LINUX) && defined(SPARC))) && !defined(PCR)#   define NEED_FIND_LIMIT# endif#if defined(FREEBSD) && (defined(I386) || defined(powerpc) || defined(__powerpc__))#  include <machine/trap.h>#  if !defined(PCR)#    define NEED_FIND_LIMIT#  endif#endif#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) \    && !defined(NEED_FIND_LIMIT)   /* Used by GC_init_netbsd_elf() below.	*/#  define NEED_FIND_LIMIT#endif#ifdef NEED_FIND_LIMIT#   include <setjmp.h>#endif#ifdef AMIGA# define GC_AMIGA_DEF# include "AmigaOS.c"# undef GC_AMIGA_DEF#endif#if defined(MSWIN32) || defined(MSWINCE)# define WIN32_LEAN_AND_MEAN# define NOSERVICE# include <windows.h>#endif#ifdef MACOS# include <Processes.h>#endif#ifdef IRIX5# include <sys/uio.h># include <malloc.h>   /* for locking */#endif#if defined(USE_MMAP) || defined(USE_MUNMAP)# ifndef USE_MMAP    --> USE_MUNMAP requires USE_MMAP# endif# include <sys/types.h># include <sys/mman.h># include <sys/stat.h># include <errno.h>#endif#ifdef UNIX_LIKE# include <fcntl.h># if defined(SUNOS5SIGS) && !defined(FREEBSD)#  include <sys/siginfo.h># endif  /* Define SETJMP and friends to be the version that restores	*/  /* the signal mask.						*/# define SETJMP(env) sigsetjmp(env, 1)# define LONGJMP(env, val) siglongjmp(env, val)# define JMP_BUF sigjmp_buf#else# define SETJMP(env) setjmp(env)# define LONGJMP(env, val) longjmp(env, val)# define JMP_BUF jmp_buf#endif#ifdef DARWIN/* for get_etext and friends */#include <mach-o/getsect.h>#endif#ifdef DJGPP  /* Apparently necessary for djgpp 2.01.  May cause problems with	*/  /* other versions.							*/  typedef long unsigned int caddr_t;#endif#ifdef PCR# include "il/PCR_IL.h"# include "th/PCR_ThCtl.h"# include "mm/PCR_MM.h"#endif#if !defined(NO_EXECUTE_PERMISSION)# define OPT_PROT_EXEC PROT_EXEC#else# define OPT_PROT_EXEC 0#endif#if defined(LINUX) && \    (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64) || !defined(SMALL_CONFIG))/* We need to parse /proc/self/maps, either to find dynamic libraries,	*//* and/or to find the register backing store base (IA64).  Do it once	*//* here.								*/#define READ read/* Repeatedly perform a read call until the buffer is filled or	*//* we encounter EOF.						*/ssize_t GC_repeat_read(int fd, char *buf, size_t count){    ssize_t num_read = 0;    ssize_t result;        while (num_read < count) {	result = READ(fd, buf + num_read, count - num_read);	if (result < 0) return result;	if (result == 0) break;	num_read += result;    }    return num_read;}/* * Apply fn to a buffer containing the contents of /proc/self/maps. * Return the result of fn or, if we failed, 0. * We currently do nothing to /proc/self/maps other than simply read * it.  This code could be simplified if we could determine its size * ahead of time. */word GC_apply_to_maps(word (*fn)(char *)){    int f;    int result;    size_t maps_size = 4000;  /* Initial guess. 	*/    static char init_buf[1];    static char *maps_buf = init_buf;    static size_t maps_buf_sz = 1;    /* Read /proc/self/maps, growing maps_buf as necessary.	*/        /* Note that we may not allocate conventionally, and	*/        /* thus can't use stdio.				*/	do {	    if (maps_size >= maps_buf_sz) {	      /* Grow only by powers of 2, since we leak "too small" buffers. */	      while (maps_size >= maps_buf_sz) maps_buf_sz *= 2;	      maps_buf = GC_scratch_alloc(maps_buf_sz);	      if (maps_buf == 0) return 0;	    }	    f = open("/proc/self/maps", O_RDONLY);	    if (-1 == f) return 0;	    maps_size = 0;	    do {	        result = GC_repeat_read(f, maps_buf, maps_buf_sz-1);	        if (result <= 0) return 0;	        maps_size += result;	    } while (result == maps_buf_sz-1);	    close(f);	} while (maps_size >= maps_buf_sz);        maps_buf[maps_size] = '\0';	    /* Apply fn to result. */	return fn(maps_buf);}#endif /* Need GC_apply_to_maps */#if defined(LINUX) && (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64))////  GC_parse_map_entry parses an entry from /proc/self/maps so we can//  locate all writable data segments that belong to shared libraries.//  The format of one of these entries and the fields we care about//  is as follows://  XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537     name of mapping...\n//  ^^^^^^^^ ^^^^^^^^ ^^^^          ^^//  start    end      prot          maj_dev////  Note that since about auguat 2003 kernels, the columns no longer have//  fixed offsets on 64-bit kernels.  Hence we no longer rely on fixed offsets//  anywhere, which is safer anyway.///* * Assign various fields of the first line in buf_ptr to *start, *end, * *prot_buf and *maj_dev.  Only *prot_buf may be set for unwritable maps. */char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,                                char *prot_buf, unsigned int *maj_dev){    char *start_start, *end_start, *prot_start, *maj_dev_start;    char *p;    char *endp;    if (buf_ptr == NULL || *buf_ptr == '\0') {        return NULL;    }    p = buf_ptr;    while (isspace(*p)) ++p;    start_start = p;    GC_ASSERT(isxdigit(*start_start));    *start = strtoul(start_start, &endp, 16); p = endp;    GC_ASSERT(*p=='-');    ++p;    end_start = p;    GC_ASSERT(isxdigit(*end_start));    *end = strtoul(end_start, &endp, 16); p = endp;    GC_ASSERT(isspace(*p));    while (isspace(*p)) ++p;    prot_start = p;    GC_ASSERT(*prot_start == 'r' || *prot_start == '-');    memcpy(prot_buf, prot_start, 4);    prot_buf[4] = '\0';    if (prot_buf[1] == 'w') {/* we can skip the rest if it's not writable. */	/* Skip past protection field to offset field */          while (!isspace(*p)) ++p; while (isspace(*p)) ++p;          GC_ASSERT(isxdigit(*p));	/* Skip past offset field, which we ignore */          while (!isspace(*p)) ++p; while (isspace(*p)) ++p;	maj_dev_start = p;        GC_ASSERT(isxdigit(*maj_dev_start));        *maj_dev = strtoul(maj_dev_start, NULL, 16);    }    while (*p && *p++ != '\n');    return p;}#endif /* Need to parse /proc/self/maps. */	#if defined(SEARCH_FOR_DATA_START)  /* The I386 case can be handled without a search.  The Alpha case	*/  /* used to be handled differently as well, but the rules changed	*/  /* for recent Linux versions.  This seems to be the easiest way to	*/  /* cover all versions.						*/# ifdef LINUX    /* Some Linux distributions arrange to define __data_start.  Some	*/    /* define data_start as a weak symbol.  The latter is technically	*/    /* broken, since the user program may define data_start, in which	*/    /* case we lose.  Nonetheless, we try both, prefering __data_start.	*/    /* We assume gcc-compatible pragmas.	*/#   pragma weak __data_start    extern int __data_start[];#   pragma weak data_start    extern int data_start[];# endif /* LINUX */  extern int _end[];  ptr_t GC_data_start;  void GC_init_linux_data_start()  {    extern ptr_t GC_find_limit();#   ifdef LINUX      /* Try the easy approaches first:	*/      if ((ptr_t)__data_start != 0) {	  GC_data_start = (ptr_t)(__data_start);	  return;      }      if ((ptr_t)data_start != 0) {	  GC_data_start = (ptr_t)(data_start);	  return;      }#   endif /* LINUX */    GC_data_start = GC_find_limit((ptr_t)(_end), FALSE);  }#endif# ifdef ECOS# ifndef ECOS_GC_MEMORY_SIZE# define ECOS_GC_MEMORY_SIZE (448 * 1024)# endif /* ECOS_GC_MEMORY_SIZE */// setjmp() function, as described in ANSI para 7.6.1.1#undef SETJMP#define SETJMP( __env__ )  hal_setjmp( __env__ )// FIXME: This is a simple way of allocating memory which is// compatible with ECOS early releases.  Later releases use a more// sophisticated means of allocating memory than this simple static// allocator, but this method is at least bound to work.static char memory[ECOS_GC_MEMORY_SIZE];static char *brk = memory;static void *tiny_sbrk(ptrdiff_t increment){  void *p = brk;  brk += increment;  if (brk >  memory + sizeof memory)    {      brk -= increment;      return NULL;    }  return p;}#define sbrk tiny_sbrk# endif /* ECOS */#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)  ptr_t GC_data_start;  void GC_init_netbsd_elf()  {    extern ptr_t GC_find_limit();    extern char **environ;	/* This may need to be environ, without the underscore, for	*/	/* some versions.						*/    GC_data_start = GC_find_limit((ptr_t)&environ, FALSE);  }#endif# ifdef OS2# include <stddef.h># if !defined(__IBMC__) && !defined(__WATCOMC__) /* e.g. EMX */struct exe_hdr {    unsigned short      magic_number;    unsigned short      padding[29];    long                new_exe_offset;};#define E_MAGIC(x)      (x).magic_number#define EMAGIC          0x5A4D  #define E_LFANEW(x)     (x).new_exe_offsetstruct e32_exe {    unsigned char       magic_number[2];     unsigned char       byte_order;     unsigned char       word_order;     unsigned long       exe_format_level;    unsigned short      cpu;           unsigned short      os;    unsigned long       padding1[13];    unsigned long       object_table_offset;    unsigned long       object_count;        unsigned long       padding2[31];};#define E32_MAGIC1(x)   (x).magic_number[0]#define E32MAGIC1       'L'#define E32_MAGIC2(x)   (x).magic_number[1]#define E32MAGIC2       'X'#define E32_BORDER(x)   (x).byte_order#define E32LEBO         0#define E32_WORDER(x)   (x).word_order#define E32LEWO         0#define E32_CPU(x)      (x).cpu#define E32CPU286       1#define E32_OBJTAB(x)   (x).object_table_offset#define E32_OBJCNT(x)   (x).object_countstruct o32_obj {    unsigned long       size;      unsigned long       base;    unsigned long       flags;      unsigned long       pagemap;

⌨️ 快捷键说明

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