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

📄 libgcc2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  asm ("	sw	$4,0($30)");  asm ("	sw	$5,4($30)");  asm ("	sw	$6,8($30)");  asm ("	sw	$7,12($30)");  asm ("	j	$31");  asm ("	.end __builtin_saveregs");#else /* not __mips__, etc. */__builtin_saveregs (){  abort ();}#endif /* not __mips__ */#endif /* not __sparc__ */#endif /* not __i860__ */#endif#ifdef L_eprintf#ifndef inhibit_eprintf#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>/* This is used by the `assert' macro.  */void__eprintf (string, expression, line, filename)     const char *string;     const char *expression;     int line;     const char *filename;{  fprintf (stderr, string, expression, line, filename);  fflush (stderr);  abort ();}#endif#endif#ifdef L_bb/* Avoid warning from ranlib about empty object file.  */void__bb_avoid_warning (){}#if defined (__sun__) && defined (__mc68000__)struct bb{  int initialized;  char *filename;  int *counts;  int ncounts;  int zero_word;  int *addresses;};extern int ___tcov_init;__bb_init_func (blocks)	struct bb *blocks;{  if (! ___tcov_init)    ___tcov_init_func ();  ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);}#endif#endif/* frills for C++ */#ifdef L_builtin_new#include <sys/types.h>typedef void (*vfp)(void);extern vfp __new_handler;void *__builtin_new (sz)     size_t sz;{  void *p;  /* malloc (0) is unpredictable; avoid it.  */  if (sz == 0)    sz = 1;  p = (void *) malloc (sz);  if (p == 0)    (*__new_handler) ();  return p;}#endif#ifdef L_caps_New/* This gets us __GNU_LIBRARY__.  */#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>#include <sys/types.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))#endiftypedef void (*vfp)(void);extern void *__builtin_new (size_t);static void default_new_handler (void);vfp __new_handler = default_new_handler;void *__builtin_vec_new (p, maxindex, size, ctor)     void *p;     size_t maxindex;     size_t size;     void (*ctor)(void *);{  size_t i;  size_t nelts = maxindex + 1;  void *rval;  if (p == 0)    p = __builtin_new (nelts * size);  rval = p;  for (i = 0; i < nelts; i++)    {      (*ctor) (p);      p += size;    }  return rval;}vfp__set_new_handler (handler)     vfp handler;{  vfp prev_handler;  prev_handler = __new_handler;  if (handler == 0) handler = default_new_handler;  __new_handler = handler;  return prev_handler;}vfpset_new_handler (handler)     vfp handler;{  return __set_new_handler (handler);}#define MESSAGE "Virtual memory exceeded in `new'\n"static voiddefault_new_handler (){  /* 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));  /* don't call exit () because that may call global destructors which     may cause a loop.  */  _exit (-1);}#endif#ifdef L_builtin_del#include <sys/types.h>typedef void (*vfp)(void);void__builtin_delete (ptr)     void *ptr;{  if (ptr)    free (ptr);}void__builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)     void *ptr;     size_t maxindex;     size_t size;     void (*dtor)(void *, int);     int auto_delete;{  size_t i;  size_t nelts = maxindex + 1;  void *p = ptr;  ptr += nelts * size;  for (i = 0; i < nelts; i++)    {      ptr -= size;      (*dtor) (ptr, auto_delete);    }  if (auto_delete_vec)    __builtin_delete (p);}#endif#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 (beg, end)     char *beg, *end;{#ifdef INSN_CACHE_SIZE  static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];  static int initialized = 0;  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 /* L_clear_cache */#ifdef L_trampoline/* Jump to a trampoline, loading the static chain address.  */#ifdef TRANSFER_FROM_TRAMPOLINE TRANSFER_FROM_TRAMPOLINE #endif#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 __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"/* Run all the global destructors on exit from the program.  */void__do_global_dtors (){#ifdef DO_GLOBAL_DTORS_BODY  DO_GLOBAL_DTORS_BODY;#else  unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];  unsigned i;  /* Some systems place the number of pointers     in the first word of the table.     On other systems, that word is -1.     In all cases, the table is null-terminated.  */  /* If the length is not recorded, count up to the null.  */  if (nptrs == -1)    for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);  /* GNU LD format.  */  for (i = nptrs; i >= 1; i--)    __DTOR_LIST__[i] ();#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.  */void__main (){  /* Support recursive calls to `main': run initializers just once.  */  static int initialized = 0;  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)#ifdef __NeXT__/* 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 volatile void _exit ();void exit (status)     int status;{  __do_global_dtors ();#ifdef EXIT_BODY  EXIT_BODY;#else  _cleanup ();#endif  _exit (status);}#elseint _exit_dummy_decl = 0;	/* prevent compiler & linker warnings */#endif#endif /* L_exit *//* In a.out systems, we need to have these dummy constructor and destructor   lists in the library.   When using `collect', the first link will resolve __CTOR_LIST__   and __DTOR_LIST__ to these symbols.  We will then run "nm" on the   result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.   Since we don't do the second link if no constructors existed, these   dummies must be fully functional empty lists.   When using `gnu ld', these symbols will be used if there are no   constructors.  If there are constructors, the N_SETV symbol defined   by the linker from the N_SETT's in input files will define __CTOR_LIST__   and __DTOR_LIST__ rather than its being allocated as common storage   by the definitions below.   When using a linker that supports constructor and destructor segments,   these definitions will not be used, since crtbegin.o and crtend.o   (from crtstuff.c) will have already defined __CTOR_LIST__ and    __DTOR_LIST__.  The crt*.o files are passed directly to the linker   on its command line, by gcc.  *//* The list needs two elements:  one is ignored (the old count); the   second is the terminating zero.  Since both values are zero, this   declaration is not initialized, and it becomes `common'.  */#ifdef L_ctor_list#include "gbl-ctors.h"func_ptr __CTOR_LIST__[2];#endif#ifdef L_dtor_list#include "gbl-ctors.h"func_ptr __DTOR_LIST__[2];#endif

⌨️ 快捷键说明

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