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

📄 xcoffread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     of course, but in corresponding .s files.) */  if (inclDepth)    fatal ("xcoff internal: pending include file exists.");  ++inclDepth;  /* allocate an include file, or make room for the new entry */  if (inclLength == 0) {    inclTable = (InclTable*) 	xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);    bzero (inclTable, sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);    inclLength = INITIAL_INCLUDE_TABLE_LENGTH;    inclIndx = 0;  }  else if (inclIndx >= inclLength) {    inclLength += INITIAL_INCLUDE_TABLE_LENGTH;    inclTable = (InclTable*) 	xrealloc (inclTable, sizeof (InclTable) * inclLength);    bzero (inclTable+inclLength-INITIAL_INCLUDE_TABLE_LENGTH, 			sizeof (InclTable)*INITIAL_INCLUDE_TABLE_LENGTH);  }  inclTable [inclIndx].name  = cs->c_name;  inclTable [inclIndx].begin = cs->c_value;}static voidrecord_include_end (cs)struct coff_symbol *cs;{  InclTable *pTbl;    if (inclDepth == 0)    fatal ("xcoff internal: Mismatch C_BINCL/C_EINCL pair found.");  pTbl = &inclTable [inclIndx];  pTbl->end = cs->c_value;  --inclDepth;  ++inclIndx;}/* given the start and end addresses of a compilation unit (or a csect, at times)   process its lines and create appropriate line vectors. */static voidprocess_linenos (start, end)  CORE_ADDR start, end;{  char *pp;  int offset, ii;  struct subfile main_subfile;		/* subfile structure for the main  					   compilation unit. */  /* in the main source file, any time we see a function entry, we reset     this variable to function's absolute starting line number. All the     following line numbers in the function are relative to this, and     we record absolute line numbers in record_line(). */  int main_source_baseline = 0;    unsigned *firstLine;  CORE_ADDR addr;  if (!(offset = first_fun_line_offset))    goto return_after_cleanup;  bzero (&main_subfile, sizeof (main_subfile));  first_fun_line_offset = 0;  if (inclIndx == 0)    /* All source lines were in the main source file. None in include files. */    enter_line_range (&main_subfile, offset, 0, start, end,     						&main_source_baseline);  /* else, there was source with line numbers in include files */  else {    main_source_baseline = 0;    for (ii=0; ii < inclIndx; ++ii) {      struct subfile *tmpSubfile;      /* if there is main file source before include file, enter it. */      if (offset < inclTable[ii].begin) {	enter_line_range	  (&main_subfile, offset, inclTable[ii].begin - LINESZ, start, 0, 	  					&main_source_baseline);      }      /* Have a new subfile for the include file */      tmpSubfile = inclTable[ii].subfile = (struct subfile*)       				xmalloc (sizeof (struct subfile));      bzero (tmpSubfile, sizeof (struct subfile));      firstLine = &(inclTable[ii].funStartLine);      /* enter include file's lines now. */      enter_line_range (tmpSubfile, inclTable[ii].begin,       				inclTable[ii].end, start, 0, firstLine);      offset = inclTable[ii].end + LINESZ;    }    /* all the include files' line have been processed at this point. Now,       enter remaining lines of the main file, if any left. */    if (offset < (linetab_offset + linetab_size + 1 - LINESZ)) {      enter_line_range (&main_subfile, offset, 0, start, end,       						&main_source_baseline);    }  }  /* Process main file's line numbers. */  if (main_subfile.line_vector) {    struct linetable *lineTb, *lv;    lv = main_subfile.line_vector;    /* Line numbers are not necessarily ordered. xlc compilation will       put static function to the end. */    lineTb = arrange_linetable (lv);    if (lv == lineTb) {      current_subfile->line_vector = (struct linetable *)	xrealloc (lv, (sizeof (struct linetable)			+ lv->nitems * sizeof (struct linetable_entry)));    }    else {	free (lv);	current_subfile->line_vector = lineTb;    }    current_subfile->line_vector_length =     			current_subfile->line_vector->nitems;  }    /* Now, process included files' line numbers. */    for (ii=0; ii < inclIndx; ++ii) {      if ( (inclTable[ii].subfile)->line_vector) { /* Useless if!!! FIXMEmgo */        struct linetable *lineTb, *lv;        lv = (inclTable[ii].subfile)->line_vector;        /* Line numbers are not necessarily ordered. xlc compilation will           put static function to the end. */        lineTb = arrange_linetable (lv);	push_subfile ();	/* For the same include file, we might want to have more than one subfile.	   This happens if we have something like:     		......	        #include "foo.h"		......	 	#include "foo.h"		......	   while foo.h including code in it. (stupid but possible)	   Since start_subfile() looks at the name and uses an existing one if finds,	   we need to provide a fake name and fool it. *//*	start_subfile (inclTable[ii].name, (char*)0);  */	start_subfile (" ?", (char*)0);	current_subfile->name = 		obsavestring (inclTable[ii].name, strlen (inclTable[ii].name),			      &current_objfile->symbol_obstack);        if (lv == lineTb) {	  current_subfile->line_vector = (struct linetable *)		xrealloc (lv, (sizeof (struct linetable)			+ lv->nitems * sizeof (struct linetable_entry)));	}	else {	  free (lv);	  current_subfile->line_vector = lineTb;	}	current_subfile->line_vector_length =     			current_subfile->line_vector->nitems;	start_subfile (pop_subfile (), (char*)0);      }    }return_after_cleanup:  /* We don't want to keep alloc/free'ing the global include file table. */  inclIndx = 0;  /* start with a fresh subfile structure for the next file. */  bzero (&main_subfile, sizeof (struct subfile));}voidaix_process_linenos (){  /* process line numbers and enter them into line vector */  process_linenos (last_source_start_addr, cur_src_end_addr);}/* Enter a given range of lines into the line vector.   can be called in the following two ways:     enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine)  or     enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine) */static voidenter_line_range (subfile, beginoffset, endoffset, startaddr, endaddr, firstLine)  struct subfile *subfile;  unsigned   beginoffset, endoffset;	/* offsets to line table */  CORE_ADDR  startaddr, endaddr;  unsigned   *firstLine;{  char		*pp, *limit;  CORE_ADDR	addr;/* Do Byte swapping, if needed. FIXME! */#define	P_LINENO(PP)  (*(unsigned short*)((struct external_lineno*)(PP))->l_lnno)#define	P_LINEADDR(PP)	(*(long*)((struct external_lineno*)(PP))->l_addr.l_paddr)#define	P_LINESYM(PP)	    (*(long*)((struct external_lineno*)(PP))->l_addr.l_symndx)  pp = &linetab [beginoffset - linetab_offset];  limit = endoffset ? &linetab [endoffset - linetab_offset]  		      : &linetab [linetab_size -1];  while (pp <= limit) {    /* find the address this line represents */    addr = P_LINENO(pp) ?       P_LINEADDR(pp) : read_symbol_nvalue (symtbl, P_LINESYM(pp));     if (addr < startaddr || (endaddr && addr > endaddr))      return;    if (P_LINENO(pp) == 0) {      *firstLine = read_symbol_lineno (symtbl, P_LINESYM(pp));      record_line (subfile, 0, addr);      --(*firstLine);    }    else      record_line (subfile, *firstLine + P_LINENO(pp), addr);    pp += LINESZ;  }}typedef struct {  int fsize;				/* file size */  int fixedparms;			/* number of fixed parms */  int floatparms;			/* number of float parms */  unsigned int parminfo;		/* parameter info.   					   See /usr/include/sys/debug.h					   tbtable_ext.parminfo */  int framesize;			/* function frame size */} TracebackInfo;/* Given a function symbol, return its traceback information. */  TracebackInfo *retrieve_tracebackinfo (abfd, textsec, cs)  bfd *abfd;  sec_ptr textsec;  struct coff_symbol *cs;{#define TBTABLE_BUFSIZ  2000#define	MIN_TBTABSIZ	50		/* minimum buffer size to hold a					   traceback table. */  static TracebackInfo tbInfo;  struct tbtable *ptb;  static char buffer [TBTABLE_BUFSIZ];  int  *pinsn;  int  bytesread=0;			/* total # of bytes read so far */  int  bufferbytes;			/* number of bytes in the buffer */  int functionstart = cs->c_value - textsec->vma;  bzero (&tbInfo, sizeof (tbInfo));  /* keep reading blocks of data from the text section, until finding a zero     word and a traceback table. */  while (	bufferbytes = (		(TBTABLE_BUFSIZ < (textsec->_raw_size - functionstart - bytesread)) ? 		 TBTABLE_BUFSIZ : (textsec->_raw_size - functionstart - bytesread))	&& bfd_get_section_contents (abfd, textsec, buffer, 				(file_ptr)(functionstart + bytesread), bufferbytes))  {    bytesread += bufferbytes;    pinsn = (int*) buffer;    /* if this is the first time we filled the buffer, retrieve function       framesize info. */    if (bytesread == bufferbytes) {      /* skip over unrelated instructions */      if (*pinsn == 0x7c0802a6)			/* mflr r0 */        ++pinsn;      if ((*pinsn & 0xfc00003e) == 0x7c000026)	/* mfcr Rx */	++pinsn;      if ((*pinsn & 0xfc000000) == 0x48000000)	/* bl foo, save fprs */        ++pinsn;      if ((*pinsn  & 0xfc1f0000) == 0xbc010000)	/* stm Rx, NUM(r1) */        ++pinsn;      do {	int tmp = (*pinsn >> 16) & 0xffff;	if (tmp ==  0x9421) {			/* stu  r1, NUM(r1) */	  tbInfo.framesize = 0x10000 - (*pinsn & 0xffff);	  break;	}	else if ((*pinsn == 0x93e1fffc) ||	/* st   r31,-4(r1) */		 (tmp == 0x9001))		/* st   r0, NUM(r1) */	;	/* else, could not find a frame size. */	else	  return NULL;      } while (++pinsn && *pinsn);      if (!tbInfo.framesize)        return NULL;          }    /* look for a zero word. */    while (*pinsn && (pinsn < (int*)(buffer + bufferbytes - sizeof(int))))      ++pinsn;    if (pinsn >= (int*)(buffer + bufferbytes))      continue;    if (*pinsn == 0) {      /* function size is the amount of bytes we have skipped so far. */      tbInfo.fsize = bytesread - (buffer + bufferbytes - (char*)pinsn);      ++pinsn;      /* if we don't have the whole traceback table in the buffer, re-read         the whole thing. */      if ((char*)pinsn > (buffer + bufferbytes - MIN_TBTABSIZ)) {	/* In case if we are *very* close to the end of the text section	   and cannot read properly from that point on, abort by returning	   NULL.	   Handle this case more graciously -- FIXME */	if (!bfd_get_section_contents (		abfd, textsec, buffer, 		(file_ptr)(functionstart + 		 bytesread - (buffer + bufferbytes - (char*)pinsn)),MIN_TBTABSIZ))	  { printf ("Abnormal return!..\n"); return NULL; }	ptb = (struct tbtable *)buffer;      }      else        ptb = (struct tbtable *)pinsn;      tbInfo.fixedparms = ptb->tb.fixedparms;      tbInfo.floatparms = ptb->tb.floatparms;      tbInfo.parminfo = ptb->tb_ext.parminfo;      return &tbInfo;    }  }  return NULL;}#if 0/* Given a function symbol, return a pointer to its traceback table. */  struct tbtable *retrieve_traceback (abfd, textsec, cs, size)  bfd *abfd;  sec_ptr textsec;  struct coff_symbol *cs;  int *size;				/* return function size */{#define TBTABLE_BUFSIZ  2000#define	MIN_TBTABSIZ	50		/* minimum buffer size to hold a					   traceback table. */  static char buffer [TBTABLE_BUFSIZ];  int  *pinsn;  int  bytesread=0;			/* total # of bytes read so far */  int  bufferbytes;			/* number of bytes in the buffer */  int functionstart = cs->c_value - textsec->filepos + textsec->vma;  *size = 0;  /* keep reading blocks of data from the text section, until finding a zero     word and a traceback table. */  while (bfd_get_section_contents (abfd, textsec, buffer, 	(file_ptr)(functionstart + bytesread), 	bufferbytes = (		(TBTABLE_BUFSIZ < (textsec->size - functionstart - bytesread)) ? 		 TBTABLE_BUFSIZ : (textsec->size - functionstart - bytesread))))  {    bytesread += bufferbytes;    pinsn = (int*) buffer;    /* look for a zero word. */    while (*pinsn && (pinsn < (int*)(buffer + bufferbytes - sizeof(int))))      ++pinsn;    if (pinsn >= (int*)(buffer + bufferbytes))      continue;    if (*pinsn == 0) {      /* function size is the amount of bytes we have skipped so far. */      *size = bytesread - (buffer + bufferbytes - pinsn);      ++pinsn;      /* if we don't have the whole traceback table in the buffer, re-read         the whole thing. */      if ((char*)pinsn > (buffer + bufferbytes - MIN_TBTABSIZ)) {	/* In case if we are *very* close to the end of the text section	   and cannot read properly from that point on, abort for now.	   Handle this case more graciously -- FIXME */	if (!bfd_get_section_contents (		abfd, textsec, buffer, 		(file_ptr)(functionstart + 		 bytesread - (buffer + bufferbytes - pinsn)),MIN_TBTABSIZ))	/*   abort (); */ { printf ("abort!!!\n"); return NULL; }	return (struct tbtable *)buffer;      }      else        return (struct tbtable *)pinsn;    }  }

⌨️ 快捷键说明

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