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

📄 run.c

📁 Linux下嵌入式开发工具源代码
💻 C
字号:
/* Load and run a MIPS position independent ECOFF file.   Written by Ian Lance Taylor <ian@cygnus.com>   Public domain.  *//* This program will load an ECOFF file into memory and execute it.   The file must have been compiled using the GNU -membedded-pic   switch to produce position independent code.  This will only work   if this program is run on a MIPS system with the same endianness as   the ECOFF file.  The ECOFF file must be complete.  System calls may   not work correctly.   There are further restrictions on the file (they could be removed   by doing some additional programming).  The file must be aligned   such that it does not require any gaps introduced in the data   segment; the GNU linker produces such files by default.  However,   the file must not assume that the text or data segment is aligned   on a page boundary.  The start address must be at the start of the   text segment.   The ECOFF file is run by calling it as though it were a function.   The address of the data segment is passed as the only argument.   The file is expected to return an integer value, which will be   printed.  */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>/* Structures used in ECOFF files.  We assume that a short is two   bytes and an int is four bytes.  This is not much of an assumption,   since we already assume that we are running on a MIPS host with the   same endianness as the file we are examining.  */struct ecoff_filehdr {  unsigned short f_magic;	/* magic number                 */  unsigned short f_nscns;	/* number of sections           */  unsigned int f_timdat;	/* time & date stamp            */  unsigned int f_symptr;	/* file pointer to symtab       */  unsigned int f_nsyms;		/* number of symtab entries     */  unsigned short f_opthdr;	/* sizeof(optional hdr)         */  unsigned short f_flags;	/* flags                        */};struct ecoff_aouthdr{  unsigned short magic;		/* type of file				*/  unsigned short vstamp;	/* version stamp			*/  unsigned int tsize;		/* text size in bytes, padded to FW bdry*/  unsigned int dsize;		/* initialized data "  "		*/  unsigned int bsize;		/* uninitialized data "   "		*/  unsigned int entry;		/* entry pt.				*/  unsigned int text_start;	/* base of text used for this file */  unsigned int data_start;	/* base of data used for this file */  unsigned int bss_start;	/* base of bss used for this file */  unsigned int gprmask;		/* ?? */  unsigned int cprmask[4];	/* ?? */  unsigned int gp_value;	/* value for gp register */};#define ECOFF_SCNHDR_SIZE (40)static voiddie (s)     char *s;{  perror (s);  exit (1);}intmain (argc, argv)     int argc;     char **argv;{  FILE *f;  struct stat s;  char *z;  struct ecoff_filehdr *fh;  struct ecoff_aouthdr *ah;  unsigned int toff;  char *t, *d;  int (*pfn) ();  int ret;  if (argc != 2)    {      fprintf (stderr, "Usage: %s file\n", argv[0]);      exit (1);    }  f = fopen (argv[1], "r");  if (f == NULL)    die (argv[1]);  if (stat (argv[1], &s) < 0)    die ("stat");  z = (char *) malloc (s.st_size);  if (z == NULL)    die ("malloc");  if (fread (z, 1, s.st_size, f) != s.st_size)    die ("fread");  /* We need to figure out the start of the text segment, which is the     location we are going to call, and the start of the data segment,     which we are going to pass as an argument.  We also need the size     and start address of the bss segment.  This information is all in     the ECOFF a.out header.  */  fh = (struct ecoff_filehdr *) z;  if (fh->f_opthdr != sizeof (struct ecoff_aouthdr))    {      fprintf (stderr, "%s: unexpected opthdr size: is %u, want %u\n",	       argv[1], (unsigned int) fh->f_opthdr,	       (unsigned int) sizeof (struct ecoff_aouthdr));      exit (1);    }  ah = (struct ecoff_aouthdr *) (z + sizeof (struct ecoff_filehdr));  if (ah->magic != 0413)    {      fprintf (stderr, "%s: bad aouthdr magic number 0%o (want 0413)\n",	       argv[1], (unsigned int) ah->magic);      exit (1);    }  /* We should clear the bss segment at this point.  This is the     ah->bsize bytes starting at ah->bss_start, To do this correctly,     we would have to make sure our memory block is large enough.  It     so happens that our test case does not have any additional pages     for the bss segment--it is contained within the data segment.     So, we don't bother.  */  if (ah->bsize != 0)    {      fprintf (stderr,	       "%s: bss segment is %u bytes; non-zero sizes not supported\n",	       argv[1], ah->bsize);      exit (1);    }  /* The text section starts just after all the headers, rounded to a     16 byte boundary.  */  toff = (sizeof (struct ecoff_filehdr) + sizeof (struct ecoff_aouthdr)	  + fh->f_nscns * ECOFF_SCNHDR_SIZE);  toff += 15;  toff &=~ 15;  t = z + toff;  /* The tsize field gives us the start of the data segment.  */  d = z + ah->tsize;  /* Call the code as a function.  */  pfn = (int (*) ()) t;  ret = (*pfn) (d);  printf ("%s ran and returned %d\n", argv[1], ret);  exit (0);}

⌨️ 快捷键说明

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