if (function_count == 0) { free (fentry); return oldLineTb; }
if (function_count == 0) { xfree (fentry); return oldLineTb; }
arrange_linetable PARAMS ((struct linetable *));static voidrecord_include_end PARAMS ((struct coff_symbol *));static voidprocess_linenos PARAMS ((CORE_ADDR, CORE_ADDR));/* Translate from a COFF section number (target_index) to a SECT_OFF_*   code.  */static int secnum_to_section PARAMS ((int, struct objfile *));struct find_targ_sec_arg {  int targ_index;  int *resultp;};static void find_targ_sec PARAMS ((bfd *, asection *, void *));static void find_targ_sec (abfd, sect, obj)     bfd *abfd;     asection *sect;     PTR obj;{  struct find_targ_sec_arg *args = (struct find_targ_sec_arg *)obj;  if (sect->target_index == args->targ_index)    {      /* This is the section.  Figure out what SECT_OFF_* code it is.  */      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)	*args->resultp = SECT_OFF_TEXT;      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)	*args->resultp = SECT_OFF_DATA;      else	*args->resultp = SECT_OFF_BSS;    }}/* Return the section number (SECT_OFF_*) that CS points to.  */static intsecnum_to_section (secnum, objfile)     int secnum;     struct objfile *objfile;{  int off = SECT_OFF_TEXT;  struct find_targ_sec_arg args;  args.targ_index = secnum;  args.resultp = &off;  bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);  return off;}/* add a given stab string into given stab vector. */#if 0static voidadd_stab_to_list (stabname, stabvector)char *stabname;struct pending_stabs **stabvector;{  if ( *stabvector == NULL) {    *stabvector = (struct pending_stabs *)	xmalloc (sizeof (struct pending_stabs) + 			INITIAL_STABVECTOR_LENGTH * sizeof (char*));    (*stabvector)->count = 0;    (*stabvector)->length = INITIAL_STABVECTOR_LENGTH;  }  else if ((*stabvector)->count >= (*stabvector)->length) {    (*stabvector)->length += INITIAL_STABVECTOR_LENGTH;    *stabvector = (struct pending_stabs *)	xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) + 	(*stabvector)->length * sizeof (char*));  }  (*stabvector)->stab [(*stabvector)->count++] = stabname;}#endif/* Linenos are processed on a file-by-file basis.   Two reasons:    1) xlc (IBM's native c compiler) postpones static function code       emission to the end of a compilation unit. This way it can       determine if those functions (statics) are needed or not, and       can do some garbage collection (I think). This makes line       numbers and corresponding addresses unordered, and we end up       with a line table like:       		lineno	addr        foo()	  10	0x100		  20	0x200		  30	0x300	foo3()	  70	0x400		  80	0x500		  90	0x600	static foo2()		  40	0x700		  50	0x800		  60	0x900			and that breaks gdb's binary search on line numbers, if the	above table is not sorted on line numbers. And that sort	should be on function based, since gcc can emit line numbers	like:			10	0x100	- for the init/test part of a for stmt.		20	0x200		30	0x300		10	0x400	- for the increment part of a for stmt.	arrange_linetable() will do this sorting.		     2)	aix symbol table might look like:		c_file		// beginning of a new file		.bi		// beginning of include file		.ei		// end of include file		.bi		.ei	basically, .bi/.ei pairs do not necessarily encapsulate	their scope. They need to be recorded, and processed later	on when we come the end of the compilation unit.	Include table (inclTable) and process_linenos() handle	that.  *//* compare line table entry addresses. */static intcompare_lte (lte1p, lte2p)     const void *lte1p;     const void *lte2p;{  struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;  struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;  return lte1->pc - lte2->pc;}/* Given a line table with function entries are marked, arrange its functions   in ascending order and strip off function entry markers and return it in   a newly created table. If the old one is good enough, return the old one. *//* FIXME: I think all this stuff can be replaced by just passing   sort_linevec = 1 to end_symtab.  */static struct linetable *arrange_linetable (oldLineTb)     struct linetable *oldLineTb;			/* old linetable */{  int ii, jj,       newline, 					/* new line count */      function_count;				/* # of functions */  struct linetable_entry *fentry;		/* function entry vector */  int fentry_size;				/* # of function entries */  struct linetable *newLineTb;			/* new line table */#define NUM_OF_FUNCTIONS 20  fentry_size = NUM_OF_FUNCTIONS;  fentry = (struct linetable_entry*)    xmalloc (fentry_size * sizeof (struct linetable_entry));  for (function_count=0, ii=0; ii <oldLineTb->nitems; ++ii) {    if (oldLineTb->item[ii].line == 0) {	/* function entry found. */      if (function_count >= fentry_size) {	/* make sure you have room. */	fentry_size *= 2;	fentry = (struct linetable_entry*) 	  xrealloc (fentry, fentry_size * sizeof (struct linetable_entry));      }      fentry[function_count].line = ii;      fentry[function_count].pc = oldLineTb->item[ii].pc;      ++function_count;    }  }  if (function_count == 0) {    free (fentry);    return oldLineTb;  }  else if (function_count > 1)    qsort (fentry, function_count, sizeof(struct linetable_entry), compare_lte);  /* allocate a new line table. */  newLineTb = (struct linetable *)    xmalloc      (sizeof (struct linetable) +        (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry));  /* if line table does not start with a function beginning, copy up until     a function begin. */  newline = 0;  if (oldLineTb->item[0].line != 0)    for (newline=0; 	newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline)      newLineTb->item[newline] = oldLineTb->item[newline];  /* Now copy function lines one by one. */  for (ii=0; ii < function_count; ++ii) {    for (jj = fentry[ii].line + 1;	         jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; 							 ++jj, ++newline)      newLineTb->item[newline] = oldLineTb->item[jj];  }  free (fentry);  newLineTb->nitems = oldLineTb->nitems - function_count;  return newLineTb;  }     