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

📄 libgcc2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
          bucket->next = *startbucket;          *startbucket = bucket;          bucket->count = 1;        }    }ret:  bb_dst = bb_src;skip:  ;}/* Called upon entering the first function of a file.  */static void__bb_init_file (struct bb *blocks){  const struct bb_func *p;  long blk, ncounts = blocks->ncounts;  const char **functions = blocks->functions;  /* Set up linked list.  */  blocks->zero_word = 1;  blocks->next = bb_head;  bb_head = blocks;  blocks->flags = 0;  if (!bb_func_head      || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))    return;  for (blk = 0; blk < ncounts; blk++)    blocks->flags[blk] = 0;  for (blk = 0; blk < ncounts; blk++)    {      for (p = bb_func_head; p; p = p->next)        {          if (!strcmp (p->funcname, functions[blk])	      && (!p->filename || !strcmp (p->filename, blocks->filename)))            {              blocks->flags[blk] |= p->mode;            }        }    }}/* Called when exiting from a function.  */void__bb_trace_ret (){  MACHINE_STATE_SAVE("2")  if (bb_callcount)    {      if ((bb_mode & 12) && bb_stacksize > bb_callcount)        {          bb_src = bb_stack[bb_callcount];          if (bb_mode & 8)            __bb_trace_func_ret ();        }      bb_callcount -= 1;    }  MACHINE_STATE_RESTORE("2")}/* Called when entering a function.  */void__bb_init_trace_func (struct bb *blocks, unsigned long blockno){  static int trace_init = 0;  MACHINE_STATE_SAVE("3")  if (!blocks->zero_word)    {       if (!trace_init)        {           trace_init = 1;          __bb_init_prg ();        }      __bb_init_file (blocks);    }  if (bb_callcount)    {      bb_callcount += 1;      if (bb_mode & 12)        {          if (bb_callcount >= bb_stacksize)            {              size_t newsize = bb_callcount + 100;              bb_stack = (unsigned long *) realloc (bb_stack, newsize);              if (! bb_stack)                {                  if (!reported)                    {                      fprintf (stderr, "Profiler: out of memory\n");                      reported = 1;                    }                  bb_stacksize = 0;                  goto stack_overflow;                }	      bb_stacksize = newsize;            }          bb_stack[bb_callcount] = bb_src;          if (bb_mode & 4)            bb_src = 0;        }stack_overflow:;    }  else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))    {      bb_callcount = 1;      bb_src = 0;      if (bb_stack)          bb_stack[bb_callcount] = bb_src;    }  MACHINE_STATE_RESTORE("3")}#endif /* not inhibit_libc */#endif /* not BLOCK_PROFILER_CODE */#endif /* L_bb *//* Default free-store management functions for C++, per sections 12.5 and   17.3.3 of the Working Paper.  */#ifdef L_op_new/* operator new (size_t), described in 17.3.3.5.  This function is used by   C++ programs to allocate a block of memory to hold a single object.  */typedef void (*vfp)(void);extern vfp __new_handler;extern void __default_new_handler (void);#ifdef WEAK_ALIASvoid * __builtin_new (size_t sz)     __attribute__ ((weak, alias ("___builtin_new")));void *___builtin_new (size_t sz)#elsevoid *__builtin_new (size_t sz)#endif{  void *p;  vfp handler = (__new_handler) ? __new_handler : __default_new_handler;  /* malloc (0) is unpredictable; avoid it.  */  if (sz == 0)    sz = 1;  p = (void *) malloc (sz);  while (p == 0)    {      (*handler) ();      p = (void *) malloc (sz);    }    return p;}#endif /* L_op_new */#ifdef L_op_vnew/* void * operator new [] (size_t), described in 17.3.3.6.  This function   is used by C++ programs to allocate a block of memory for an array.  */extern void * __builtin_new (size_t);#ifdef WEAK_ALIASvoid * __builtin_vec_new (size_t sz)     __attribute__ ((weak, alias ("___builtin_vec_new")));void *___builtin_vec_new (size_t sz)#elsevoid *__builtin_vec_new (size_t sz)#endif{  return __builtin_new (sz);}#endif /* L_op_vnew */#ifdef L_new_handler/* set_new_handler (fvoid_t *) and the default new handler, described in   17.3.3.2 and 17.3.3.5.  These functions define the result of a failure   to allocate the amount of memory requested from operator new or new [].  */#ifndef inhibit_libc/* This gets us __GNU_LIBRARY__.  */#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>#ifdef __GNU_LIBRARY__  /* Avoid forcing the library's meaning of `write' on the user program     by using the "internal" name (for use within the library)  */#define write(fd, buf, n)	__write((fd), (buf), (n))#endif#endif /* inhibit_libc */typedef void (*vfp)(void);void __default_new_handler (void);vfp __new_handler = (vfp) 0;vfpset_new_handler (vfp handler){  vfp prev_handler;  prev_handler = __new_handler;  if (handler == 0) handler = __default_new_handler;  __new_handler = handler;  return prev_handler;}#define MESSAGE "Virtual memory exceeded in `new'\n"void__default_new_handler (){#ifndef inhibit_libc  /* don't use fprintf (stderr, ...) because it may need to call malloc.  */  /* This should really print the name of the program, but that is hard to     do.  We need a standard, clean way to get at the name.  */  write (2, MESSAGE, sizeof (MESSAGE));#endif  /* don't call exit () because that may call global destructors which     may cause a loop.  */  _exit (-1);}#endif#ifdef L_op_delete/* operator delete (void *), described in 17.3.3.3.  This function is used   by C++ programs to return to the free store a block of memory allocated   as a single object.  */#ifdef WEAK_ALIASvoid __builtin_delete (void *ptr)     __attribute__ ((weak, alias ("___builtin_delete")));void___builtin_delete (void *ptr)#elsevoid__builtin_delete (void *ptr)#endif{  if (ptr)    free (ptr);}#endif#ifdef L_op_vdel/* operator delete [] (void *), described in 17.3.3.4.  This function is   used by C++ programs to return to the free store a block of memory   allocated as an array.  */extern void __builtin_delete (void *);#ifdef WEAK_ALIASvoid __builtin_vec_delete (void *ptr)     __attribute__ ((weak, alias ("___builtin_vec_delete")));void___builtin_vec_delete (void *ptr)#elsevoid__builtin_vec_delete (void *ptr)#endif{  __builtin_delete (ptr);}#endif/* End of C++ free-store management functions */#ifdef L_shtabunsigned int __shtab[] = {    0x00000001, 0x00000002, 0x00000004, 0x00000008,    0x00000010, 0x00000020, 0x00000040, 0x00000080,    0x00000100, 0x00000200, 0x00000400, 0x00000800,    0x00001000, 0x00002000, 0x00004000, 0x00008000,    0x00010000, 0x00020000, 0x00040000, 0x00080000,    0x00100000, 0x00200000, 0x00400000, 0x00800000,    0x01000000, 0x02000000, 0x04000000, 0x08000000,    0x10000000, 0x20000000, 0x40000000, 0x80000000  };#endif#ifdef L_clear_cache/* Clear part of an instruction cache.  */#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)void__clear_cache (char *beg, char *end){#ifdef CLEAR_INSN_CACHE   CLEAR_INSN_CACHE (beg, end);#else#ifdef INSN_CACHE_SIZE  static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];  static int initialized;  int offset;  void *start_addr  void *end_addr;  typedef (*function_ptr) ();#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16  /* It's cheaper to clear the whole cache.     Put in a series of jump instructions so that calling the beginning     of the cache will clear the whole thing.  */  if (! initialized)    {      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)		 & -INSN_CACHE_LINE_WIDTH);      int end_ptr = ptr + INSN_CACHE_SIZE;      while (ptr < end_ptr)	{	  *(INSTRUCTION_TYPE *)ptr	    = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;	  ptr += INSN_CACHE_LINE_WIDTH;	}      *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;      initialized = 1;    }  /* Call the beginning of the sequence.  */  (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)		    & -INSN_CACHE_LINE_WIDTH))   ());#else /* Cache is large.  */  if (! initialized)    {      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)		 & -INSN_CACHE_LINE_WIDTH);      while (ptr < (int) array + sizeof array)	{	  *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;	  ptr += INSN_CACHE_LINE_WIDTH;	}      initialized = 1;    }  /* Find the location in array that occupies the same cache line as BEG.  */  offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);  start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)		 & -INSN_CACHE_PLANE_SIZE)		+ offset);  /* Compute the cache alignment of the place to stop clearing.  */#if 0  /* This is not needed for gcc's purposes.  */  /* If the block to clear is bigger than a cache plane,     we clear the entire cache, and OFFSET is already correct.  */   if (end < beg + INSN_CACHE_PLANE_SIZE)#endif    offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)	       & -INSN_CACHE_LINE_WIDTH)	      & (INSN_CACHE_PLANE_SIZE - 1));#if INSN_CACHE_DEPTH > 1  end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;  if (end_addr <= start_addr)    end_addr += INSN_CACHE_PLANE_SIZE;  for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)    {      int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;      int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;      while (addr != stop)	{	  /* Call the return instruction at ADDR.  */	  ((function_ptr) addr) ();	  addr += INSN_CACHE_LINE_WIDTH;	}    }#else /* just one plane */  do    {      /* Call the return instruction at START_ADDR.  */      ((function_ptr) start_addr) ();      start_addr += INSN_CACHE_LINE_WIDTH;    }  while ((start_addr % INSN_CACHE_SIZE) != offset);#endif /* just one plane */#endif /* Cache is large */#endif /* Cache exists */#endif /* CLEAR_INSN_CACHE */}#endif /* L_clear_cache */#ifdef L_trampoline/* Jump to a trampoline, loading the static chain address.  */#if defined(WINNT) && ! defined(__CYGWIN32__)long getpagesize(){#ifdef _ALPHA_  return 8192;#else  return 4096;#endif}#ifdef i386extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));#endifintmprotect (char *addr, int len, int prot){  int np, op;  if (prot == 7)    np = 0x40;  else if (prot == 5)    np = 0x20;  else if (prot == 4)    np = 0x10;  else if (prot == 3)    np = 0x04;  else if (prot == 1)    np = 0x02;  else if (prot == 0)    np = 0x01;  if (VirtualProtect (addr, len, np, &op))    return 0;  else    return -1;}#endif#ifdef TRANSFER_FROM_TRAMPOLINE TRANSFER_FROM_TRAMPOLINE #endif#if defined (NeXT) && defined (__MACH__)/* Make stack executable so we can call trampolines on stack.   This is called from INITIALIZE_TRAMPOLINE in next.h.  */#ifdef NeXTStep21 #include <mach.h>#else #include <mach/mach.h>#endifvoid__enable_execute_stack (char *addr){  kern_return_t r;  char *eaddr = addr + TRAMPOLINE_SIZE;  vm_address_t a = (vm_address_t) addr;  /* turn on execute access on stack */  r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);  if (r != KERN_SUCCESS)    {      mach_error("vm_protect VM_PROT_ALL", r);      exit(1);    }  /* We inline the i-cache invalidation for speed */#ifdef CLEAR_INSN_CACHE  CLEAR_INSN_CACHE (addr, eaddr);#else  __clear_cache ((int) addr, (int) eaddr);#endif} #endif /* defined (NeXT) && defined (__MACH__) */#ifdef __convex__/* Make stack executable so we can call trampolines on stack.   This is called from INITIALIZE_TRAMPOLINE in convex.h.  */#include <sys/mman.h>#include <sys/vmparam.h>#include <machine/machparam.h>void__enable_execute_stack (){  int fp;  static unsigned lowest = USRSTACK;  unsigned current = (unsigned) &fp & -NBPG;  if (lowest > current)    {      unsigned len = lowest - current;      mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);      lowest = current;    }  /* Clear instruction cache in case an old trampoline is in it.  */  asm ("pich");}#endif /* __convex__ */#ifdef __sysV88__/* Modified from the convex -code above.  */#include <sys/param.h>#include <errno.h>#include <sys/m88kbcs.h>void__enable_execute_stack (){  int save_errno;  static unsigned long lowest = USRSTACK;  unsigned long current = (unsigned long) &save_errno & -NBPC;    /* Ignore errno being set. memctl sets errno to EINVAL whenever the     address is seen as 'negative'. That is the case with the stack.   */  save_errno=errno;  if (lowest > current)    {      unsigned len=lowest-current;      memctl(current,len,MCT_TEXT);      lowest = current;    }  else    memctl(current,NBPC,MCT_TEXT);  errno=save_errno;}#endif /* __sysV88__ */#ifdef __sysV68__#include <sys/signal.h>#include <errno.h>/* Motorola forgot to put memctl.o in the libp version of libc881.a,   so define it here, because we need it in 

⌨️ 快捷键说明

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