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

📄 syscalls.c

📁 如文件名
💻 C
字号:
/* DMW: This isn't MINE! It's from NewLib but it was modified by me. *//* Support files for GNU libc.  Files in the system namespace go here.   Files in the C namespace (ie those that do not start with an   underscore) go in .c.  */#include <_ansi.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <stdio.h>#include <time.h>#include <sys/time.h>#include <sys/times.h>#include <errno.h>#include <reent.h>#include <unistd.h>#include "swi.h"#include "system.h"/* Forward prototypes.  */int     _system     _PARAMS ((const char *));int     _rename     _PARAMS ((const char *, const char *));int     isatty		_PARAMS ((int));clock_t _times		_PARAMS ((struct tms *));int     _gettimeofday	_PARAMS ((struct timeval *, struct timezone *));void    _raise 		_PARAMS ((void));int     _unlink		_PARAMS ((void));int     _link 		_PARAMS ((void));int     _stat 		_PARAMS ((const char *, struct stat *));int     _fstat 		_PARAMS ((int, struct stat *));caddr_t _sbrk		_PARAMS ((int));int     _getpid		_PARAMS ((int));int     _kill		_PARAMS ((int, int));void    _exit		_PARAMS ((int));int     _close		_PARAMS ((int));int     _swiclose	_PARAMS ((int));int     _open		_PARAMS ((const char *, int, ...));int     _swiopen	_PARAMS ((const char *, int));int     _write 		_PARAMS ((int, char *, int));int     _swiwrite	_PARAMS ((int, char *, int));int     _lseek		_PARAMS ((int, int, int));int     _swilseek	_PARAMS ((int, int, int));int     _read		_PARAMS ((int, char *, int));int     _swiread	_PARAMS ((int, char *, int));void    initialise_monitor_handles _PARAMS ((void));static int	wrap		_PARAMS ((int));static int	error		_PARAMS ((int));static int	get_errno	_PARAMS ((void));static int	remap_handle	_PARAMS ((int));static int	do_AngelSWI	_PARAMS ((int, void *));static int 	findslot	_PARAMS ((int));/* Register name faking - works in collusion with the linker.  */register char * stack_ptr asm ("sp");/* following is copied from libc/stdio/local.h to check std streams */extern void   _EXFUN(__sinit,(struct _reent *));#define CHECK_INIT(ptr) \  do						\    {						\      if ((ptr) && !(ptr)->__sdidinit)		\	__sinit (ptr);				\    }						\  while (0)/* Adjust our internal handles to stay away from std* handles.  */#define FILE_HANDLE_OFFSET (0x20)static int monitor_stdin;static int monitor_stdout;static int monitor_stderr;/* Struct used to keep track of the file position, just so we   can implement fseek(fh,x,SEEK_CUR).  */typedef struct{  int handle;  int pos;}poslog;#define MAX_OPEN_FILES 20static poslog openfiles [MAX_OPEN_FILES];static intfindslot (int fh){  int i;  for (i = 0; i < MAX_OPEN_FILES; i ++)    if (openfiles[i].handle == fh)      break;  return i;}#ifdef ARM_RDI_MONITORstatic inline intdo_AngelSWI (int reason, void * arg){  int value;  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"       : "=r" (value) /* Outputs */       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"		/* Clobbers r0 and r1, and lr if in supervisor mode */);                /* Accordingly to page 13-77 of ARM DUI 0040D other registers                   can also be clobbered.  Some memory positions may also be                   changed by a system call, so they should not be kept in                   registers. Note: we are assuming the manual is right and                   Angel is respecting the APCS.  */  return value;}#endif /* ARM_RDI_MONITOR *//* Function to convert std(in|out|err) handles to internal versions.  */static intremap_handle (int fh){  CHECK_INIT(_REENT);  if (fh == STDIN_FILENO)    return monitor_stdin;  if (fh == STDOUT_FILENO)    return monitor_stdout;  if (fh == STDERR_FILENO)    return monitor_stderr;  return fh - FILE_HANDLE_OFFSET;}voidinitialise_monitor_handles (void){  int i;  #ifdef ARM_RDI_MONITOR  int volatile block[3];    block[0] = (int) ":tt";  block[2] = 3;     /* length of filename */  block[1] = 0;     /* mode "r" */  monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);  block[0] = (int) ":tt";  block[2] = 3;     /* length of filename */  block[1] = 4;     /* mode "w" */  monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);#else  int fh;  const char * name;  name = ":tt";  asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"       : "=r"(fh)       : "i" (SWI_Open),"r"(name)       : "r0","r1");  monitor_stdin = fh;  name = ":tt";  asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"       : "=r"(fh)       : "i" (SWI_Open),"r"(name)       : "r0","r1");  monitor_stdout = monitor_stderr = fh;#endif  for (i = 0; i < MAX_OPEN_FILES; i ++)    openfiles[i].handle = -1;  openfiles[0].handle = monitor_stdin;  openfiles[0].pos = 0;  openfiles[1].handle = monitor_stdout;  openfiles[1].pos = 0;}static intget_errno (void){#ifdef ARM_RDI_MONITOR  return do_AngelSWI (AngelSWI_Reason_Errno, NULL);#else  asm ("swi %a0" :: "i" (SWI_GetErrno));#endif}static interror (int result){  errno = get_errno ();  return result;}static intwrap (int result){  if (result == -1)    return error (-1);  return result;}/* Returns # chars not! written.  */int_swiread (int file,	  char * ptr,	  int len){  int fh = remap_handle (file);#ifdef ARM_RDI_MONITOR  int block[3];    block[0] = fh;  block[1] = (int) ptr;  block[2] = len;    return do_AngelSWI (AngelSWI_Reason_Read, block);#else  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"       : /* No outputs */       : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)       : "r0","r1","r2");#endif}int_read (int file,       char * ptr,       int len){  int slot = findslot (remap_handle (file));  int x = _swiread (file, ptr, len);  if (x < 0)    return error (-1);  if (slot != MAX_OPEN_FILES)    openfiles [slot].pos += len - x;  /* x == len is not an error, at least if we want feof() to work.  */  return len - x;}int_swilseek (int file,	   int ptr,	   int dir){  int res;  int fh = remap_handle (file);  int slot = findslot (fh);#ifdef ARM_RDI_MONITOR  int block[2];#endif  if (dir == SEEK_CUR)    {      if (slot == MAX_OPEN_FILES)	return -1;      ptr = openfiles[slot].pos + ptr;      dir = SEEK_SET;    }  #ifdef ARM_RDI_MONITOR  if (dir == SEEK_END)    {      block[0] = fh;      ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);    }    /* This code only does absolute seeks.  */  block[0] = remap_handle (file);  block[1] = ptr;  res = do_AngelSWI (AngelSWI_Reason_Seek, block);#else  if (dir == SEEK_END)    {      asm ("mov r0, %2; swi %a1; mov %0, r0"	   : "=r" (res)	   : "i" (SWI_Flen), "r" (fh)	   : "r0");      ptr += res;    }  /* This code only does absolute seeks.  */  asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"       : "=r" (res)       : "i" (SWI_Seek), "r" (fh), "r" (ptr)       : "r0", "r1");#endif  if (slot != MAX_OPEN_FILES && res == 0)    openfiles[slot].pos = ptr;  /* This is expected to return the position in the file.  */  return res == 0 ? ptr : -1;}int_lseek (int file,	int ptr,	int dir){  return wrap (_swilseek (file, ptr, dir));}/* Returns #chars not! written.  */int_swiwrite (	   int    file,	   char * ptr,	   int    len){  int fh = remap_handle (file);#ifdef ARM_RDI_MONITOR  int block[3];    block[0] = fh;  block[1] = (int) ptr;  block[2] = len;    return do_AngelSWI (AngelSWI_Reason_Write, block);#else  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"       : /* No outputs */       : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)       : "r0","r1","r2");#endif}int_write (int    file,	char * ptr,	int    len){  int fil;  for(fil = 0; fil < len; fil++)    __putchar(*ptr++);  return 0;}extern int strlen (const char *);  int_swiopen (const char * path,    int          flags){  int aflags = 0, fh;#ifdef ARM_RDI_MONITOR  int block[3];#endif  int i = findslot (-1);  if (i == MAX_OPEN_FILES)    return -1;  /* The flags are Unix-style, so we need to convert them.  */#ifdef O_BINARY  if (flags & O_BINARY)    aflags |= 1;#endif  if (flags & O_RDWR)    aflags |= 2;  if (flags & O_CREAT)    aflags |= 4;  if (flags & O_TRUNC)    aflags |= 4;  if (flags & O_APPEND)  {    aflags &= ~4;     /* Can't ask for w AND a; means just 'a'.  */    aflags |= 8;  }#ifdef ARM_RDI_MONITOR  block[0] = (int) path;  block[2] = strlen (path);  block[1] = aflags;  fh = do_AngelSWI (AngelSWI_Reason_Open, block);#else  asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"      : "=r"(fh)      : "i" (SWI_Open),"r"(path),"r"(aflags)      : "r0","r1");#endif  if (fh >= 0)  {    openfiles[i].handle = fh;    openfiles[i].pos = 0;  }  return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);}  int_open (const char * path,    int          flags,    ...){  return 0;}  int_swiclose (int file){  int myhan = remap_handle (file);  int slot = findslot (myhan);  if (slot != MAX_OPEN_FILES)    openfiles[slot].handle = -1;#ifdef ARM_RDI_MONITOR  return do_AngelSWI (AngelSWI_Reason_Close, & myhan);#else  asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");#endif}  int_close (int file){  return 0;}  void_exit (int n){  /* FIXME: return code is thrown away.  */  _write(0,"EXIT!\n\r",7);#ifdef ARM_RDI_MONITOR  do_AngelSWI (AngelSWI_Reason_ReportException,      (void *) ADP_Stopped_ApplicationExit);#else  asm ("swi %a0" :: "i" (SWI_Exit));#endif  n = n;}  int_kill (int n, int m){#ifdef ARM_RDI_MONITOR  return do_AngelSWI (AngelSWI_Reason_ReportException,      (void *) ADP_Stopped_ApplicationExit);#else  asm ("swi %a0" :: "i" (SWI_Exit));#endif  n = n; m = m;}  int_getpid (int n){  return 1;  n = n;}#define HEAPSIZE 0x01000extern void _end;caddr_t _sbrk ( int incr ){  static unsigned char *heap_end = 0;  unsigned char *prev_heap_end;  /* initialize */  if( heap_end == 0 )   {    heap_end = &_end;   }  prev_heap_end = heap_end;  if( ((int)heap_end - (int)&_end + incr) > HEAPSIZE ) {    /* heap overflowannounce on stderr */    _write( 0, "Heap overflow!\n", 15 );    abort();    _exit(0);  }  heap_end += incr;/*  _write(0,"sbrk: ",6);*//*  _write(0,hexify((int)heap_end),10);*//*   _write(0,"\n\r",2);*/  return (caddr_t) prev_heap_end;}extern void memset (struct stat *, int, unsigned int);  int_fstat (int file, struct stat * st){  memset (st, 0, sizeof (* st));  st->st_mode = S_IFCHR;  st->st_blksize = 1024;  return 0;  file = file;}int _stat (const char *fname, struct stat *st){  int file;  /* The best we can do is try to open the file readonly.  If it exists,     then we can guess a few things about it.  */  if ((file = _open (fname, O_RDONLY)) < 0)    return -1;  memset (st, 0, sizeof (* st));  st->st_mode = S_IFREG | S_IREAD;  st->st_blksize = 1024;  _swiclose (file); /* Not interested in the error.  */  return 0;}  int_link (void){  return -1;}  int_unlink (void){  return -1;}  void_raise (void){  return;}  int_gettimeofday (struct timeval * tp, struct timezone * tzp){  if (tp)  {    /* Ask the host for the seconds since the Unix epoch.  */#ifdef ARM_RDI_MONITOR    tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);#else    {      int value;      asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");      tp->tv_sec = value;    }#endif    tp->tv_usec = 0;  }  /* Return fixed data for the timezone.  */  if (tzp)  {    tzp->tz_minuteswest = 0;    tzp->tz_dsttime = 0;  }  return 0;}/* Return a clock that ticks at 100Hz.  */  clock_t _times (struct tms * tp){  clock_t timeval;#ifdef ARM_RDI_MONITOR  timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);#else  asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");#endif  if (tp)  {    tp->tms_utime  = timeval;	/* user time */    tp->tms_stime  = 0;	/* system time */    tp->tms_cutime = 0;	/* user time, children */    tp->tms_cstime = 0;	/* system time, children */  }  return timeval;};  intisatty (int fd){  return 1;  fd = fd;}  int_system (const char *s){  if (s == NULL)    return 0;  errno = ENOSYS;  return -1;}  int_rename (const char * oldpath, const char * newpath){  errno = ENOSYS;  return -1;}

⌨️ 快捷键说明

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