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

📄 libgcc2.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 4 页
字号:
	{	  *(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.  */#ifdef WINNTlong getpagesize(){#ifdef _ALPHA_  return 8192;#else  return 4096;#endif}int mprotect(addr, len, prot)  char *addr;  int len, 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 (addr)     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 __DOLPHIN__/* 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 /* __DOLPHIN__ */#ifdef __pyr__#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/param.h>#include <sys/vmmac.h>/* Modified from the convex -code above.   mremap promises to clear the i-cache. */void__enable_execute_stack (){  int fp;  if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,		PROT_READ|PROT_WRITE|PROT_EXEC))    {      perror ("mprotect in __enable_execute_stack");      fflush (stderr);      abort ();    }}#endif /* __pyr__ */#endif /* L_trampoline */#ifdef L__main#include "gbl-ctors.h"/* Some systems use __main in a way incompatible with its use in gcc, in these   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to   give the same symbol without quotes for an alternative entry point.  You   must define both, or neither. */#ifndef NAME__MAIN#define NAME__MAIN "__main"#define SYMBOL__MAIN __main#endif#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)/* Run all the global destructors on exit from the program.  */void__do_global_dtors (){#ifdef DO_GLOBAL_DTORS_BODY  DO_GLOBAL_DTORS_BODY;#else  func_ptr *p;  for (p = __DTOR_LIST__ + 1; *p; )    (*p++) ();#endif}#endif#ifndef INIT_SECTION_ASM_OP/* Run all the global constructors on entry to the program.  */#ifndef ON_EXIT#define ON_EXIT(a, b)#else/* Make sure the exit routine is pulled in to define the globals as   bss symbols, just in case the linker does not automatically pull   bss definitions from the library.  */extern int _exit_dummy_decl;int *_exit_dummy_ref = &_exit_dummy_decl;#endif /* ON_EXIT */void__do_global_ctors (){  DO_GLOBAL_CTORS_BODY;  ON_EXIT (__do_global_dtors, 0);}#endif /* no INIT_SECTION_ASM_OP */#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)/* Subroutine called automatically by `main'.   Compiling a global function named `main'   produces an automatic call to this function at the beginning.   For many systems, this routine calls __do_global_ctors.   For systems which support a .init section we use the .init section   to run __do_global_ctors, so we need not do anything here.  */voidSYMBOL__MAIN (){  /* Support recursive calls to `main': run initializers just once.  */  static int initialized;  if (! initialized)    {      initialized = 1;      __do_global_ctors ();    }}#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */#endif /* L__main */#ifdef L_ctors#include "gbl-ctors.h"/* Provide default definitions for the lists of constructors and   destructors, so that we don't get linker errors.  These symbols are   intentionally bss symbols, so that gld and/or collect will provide   the right values.  *//* We declare the lists here with two elements each,   so that they are valid empty lists if no other definition is loaded.  */#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)#if defined(__NeXT__) || defined(_AIX)/* After 2.3, try this definition on all systems.  */func_ptr __CTOR_LIST__[2] = {0, 0};func_ptr __DTOR_LIST__[2] = {0, 0};#elsefunc_ptr __CTOR_LIST__[2];func_ptr __DTOR_LIST__[2];#endif#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */#endif /* L_ctors */#ifdef L_exit#include "gbl-ctors.h"#ifndef ON_EXIT/* If we have no known way of registering our own __do_global_dtors   routine so that it will be invoked at program exit time, then we   have to define our own exit routine which will get this to happen.  */extern void __do_global_dtors ();extern void _cleanup ();extern void _exit () __attribute__ ((noreturn));void exit (status)     int status;{#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)  __do_global_dtors ();#endif#ifdef EXIT_BODY  EXIT_BODY;#else  _cleanup ();#endif  _exit (status);}#elseint _exit_dummy_decl = 0;	/* prevent compiler & linker warnings */#endif#endif /* L_exit */#ifdef L_ehtypedef struct {  void *start;  void *end;  void *exception_handler;} exception_table;struct exception_table_node {  exception_table *table;  void *start;  void *end;  struct exception_table_node *next;};static int except_table_pos;static void *except_pc;static struct exception_table_node *exception_table_list;static exception_table *find_exception_table (pc)     void* pc;{  register struct exception_table_node *table = exception_table_list;  for ( ; table != 0; table = table->next)    {      if (table->start <= pc && table->end > pc)	return table->table;    }  return 0;}/* this routine takes a pc, and the address of the exception handler associated   with the closest exception table handler entry associated with that PC,   or 0 if there are no table entries the PC fits in.  The algorithm works   something like this:    while(current_entry exists) {        if(current_entry.start < pc )            current_entry = next_entry;        else {            if(prev_entry.start <= pc && prev_entry.end > pc) {                save pointer to prev_entry;                return prev_entry.exception_handler;             }            else return 0;         }     }    return 0;   Assuming a correctly sorted table (ascending order) this routine should   return the tightest match...   In the advent of a tie, we have to give the last entry, as it represents   an inner block. */void *__find_first_exception_table_match(pc)void *pc;{  exception_table *table = find_exception_table (pc);  int pos = 0;  int best = 0;  if (table == 0)    return (void*)0;#if 0  printf("find_first_exception_table_match(): pc = %x!\n",pc);#endif  except_pc = pc;#if 0  /* We can't do this yet, as we don't know that the table is sorted.  */  do {    ++pos;    if (table[pos].start > except_pc)      /* found the first table[pos].start > except_pc, so the previous	 entry better be the one we want! */      break;  } while(table[pos].exception_handler != (void*)-1);  --pos;  if (table[pos].start <= except_pc && table[pos].end > except_pc)    {      except_table_pos = pos;#if 0      printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);#endif      return table[pos].exception_handler;    }#else  while (table[++pos].exception_handler != (void*)-1) {    if (table[pos].start <= except_pc && table[pos].end > except_pc)      {	/* This can apply.  Make sure it is better or as good as the previous	   best.  */	/* The best one ends first. */	if (best == 0 || (table[pos].end <= table[best].end			  /* The best one starts last.  */			  && table[pos].start >= table[best].start))	  best = pos;      }  }  if (best != 0)    return table[best].exception_handler;#endif#if 0  printf("find_first_eh_table_match(): else: returning NULL!\n");#endif  return (void*)0;}void *__throw_type_match (void *catch_type, void *throw_type, void* obj){#if 0 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",	catch_type, throw_type);#endif if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)   return obj; return 0;}void__register_exceptions (exception_table *table){  struct exception_table_node *node;  exception_table *range = table + 1;  if (range->start == (void*)-1)    return;  node = (struct exception_table_node*)    malloc (sizeof (struct exception_table_node));  node->table = table;  /* This look can be optimized away either if the table     is sorted, or if we pass in extra parameters. */  node->start = range->start;  node->end = range->end;  for (range++ ; range->start != (void*)(-1); range++)    {      if (range->start < node->start)	node->start = range->start;      if (range->end > node->end)	node->end = range->end;    }  node->next = exception_table_list;  exception_table_list = node;}#if #machine(i386)void__unwind_function(void *ptr){  asm("movl 8(%esp),%ecx");  /* Undo current frame */  asm("movl %ebp,%esp");  asm("popl %ebp");  /* like ret, but stay here */  asm("addl $4,%esp");    /* Now, undo previous frame. */  /* This is a test routine, as we have to dynamically probe to find out     what to pop for certain, this is just a guess. */  asm("leal -16(%ebp),%esp");  asm("pop %ebx");  asm("pop %esi");  asm("pop %edi");  asm("movl %ebp,%esp");  asm("popl %ebp");  asm("movl %ecx,0(%esp)");  asm("ret");}#elif #machine(rs6000)__unwind_function(void *ptr){  asm("mr 31,1");  asm("l 1,0(1)");  asm("l 31,-4(1)");  asm("# br");  asm("mr 31,1");  asm("l 1,0(1)");  /* use 31 as a scratch register to restore the link register. */  asm("l 31, 8(1);mtlr 31 # l lr,8(1)");  asm("l 31,-4(1)");  asm("# br");  asm("mtctr 3;bctr # b 3");}#elif #machine(powerpc)__unwind_function(void *ptr){  asm("mr 31,1");  asm("lwz 1,0(1)");  asm("lwz 31,-4(1)");  asm("# br");  asm("mr 31,1");  asm("lwz 1,0(1)");  /* use 31 as a scratch register to restore the link register. */  asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");  asm("lwz 31,-4(1)");  asm("# br");  asm("mtctr 3;bctr # b 3");}#elif #machine(vax)__unwind_function(void *ptr){  __label__ return_again;  /* Replace our frame's return address with the label below.     During execution, we will first return here instead of to     caller, then second return takes caller's frame off the stack.     Two returns matches two actual calls, so is less likely to     confuse debuggers.  `16' corresponds to RETURN_ADDRESS_OFFSET.  */  __asm ("movl %0,16(fp)" : : "p" (&& return_again));  return; return_again:  return;}#else__unwind_function(void *ptr){  abort ();}#endif /* powerpc */#endif /* L_eh */#ifdef L_pure#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 */#define MESSAGE "pure virtual method called\n"void__pure_virtual (){#ifndef inhibit_libc  write (2, MESSAGE, sizeof (MESSAGE) - 1);#endif  _exit (-1);}#endif

⌨️ 快捷键说明

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