syms.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,302 行 · 第 1/3 页

C
1,302
字号
#define STRDXOFF (0)#define TYPEOFF (4)#define OTHEROFF (5)#define DESCOFF (6)#define VALOFF (8)#define STABSIZE (12)  info = (struct stab_find_info *) *pinfo;  if (info != NULL)    {      if (info->stabsec == NULL || info->strsec == NULL)	{	  /* No stabs debugging information.  */	  return true;	}      stabsize = info->stabsec->_raw_size;      strsize = info->strsec->_raw_size;    }  else    {      long reloc_size, reloc_count;      arelent **reloc_vector;      int i;      char *name;      char *file_name;      char *directory_name;      char *function_name;      info = (struct stab_find_info *) bfd_zalloc (abfd, sizeof *info);      if (info == NULL)	return false;      /* FIXME: When using the linker --split-by-file or	 --split-by-reloc options, it is possible for the .stab and	 .stabstr sections to be split.  We should handle that.  */      info->stabsec = bfd_get_section_by_name (abfd, ".stab");      info->strsec = bfd_get_section_by_name (abfd, ".stabstr");      if (info->stabsec == NULL || info->strsec == NULL)	{	  /* No stabs debugging information.  Set *pinfo so that we             can return quickly in the info != NULL case above.  */	  *pinfo = (PTR) info;	  return true;	}      stabsize = info->stabsec->_raw_size;      strsize = info->strsec->_raw_size;      info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize);      info->strs = (bfd_byte *) bfd_alloc (abfd, strsize);      if (info->stabs == NULL || info->strs == NULL)	return false;      if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs, 0,				      stabsize)	  || ! bfd_get_section_contents (abfd, info->strsec, info->strs, 0,					 strsize))	return false;      /* If this is a relocateable object file, we have to relocate	 the entries in .stab.  This should always be simple 32 bit	 relocations against symbols defined in this object file, so	 this should be no big deal.  */      reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);      if (reloc_size < 0)	return false;      reloc_vector = (arelent **) bfd_malloc (reloc_size);      if (reloc_vector == NULL && reloc_size != 0)	return false;      reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,					    symbols);      if (reloc_count < 0)	{	  if (reloc_vector != NULL)	    free (reloc_vector);	  return false;	}      if (reloc_count > 0)	{	  arelent **pr;	  for (pr = reloc_vector; *pr != NULL; pr++)	    {	      arelent *r;	      unsigned long val;	      asymbol *sym;	      r = *pr;	      if (r->howto->rightshift != 0		  || r->howto->size != 2		  || r->howto->bitsize != 32		  || r->howto->pc_relative		  || r->howto->bitpos != 0		  || r->howto->dst_mask != 0xffffffff)		{		  (*_bfd_error_handler)		    (_("Unsupported .stab relocation"));		  bfd_set_error (bfd_error_invalid_operation);		  if (reloc_vector != NULL)		    free (reloc_vector);		  return false;		}	      val = bfd_get_32 (abfd, info->stabs + r->address);	      val &= r->howto->src_mask;	      sym = *r->sym_ptr_ptr;	      val += sym->value + sym->section->vma + r->addend;	      bfd_put_32 (abfd, val, info->stabs + r->address);	    }	}      if (reloc_vector != NULL)	free (reloc_vector);      /* First time through this function, build a table matching	 function VM addresses to stabs, then sort based on starting	 VM address.  Do this in two passes: once to count how many	 table entries we'll need, and a second to actually build the	 table.  */      info->indextablesize = 0;      saw_fun = 1;      for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)	{	  if (stab[TYPEOFF] == N_SO)	    {	      /* N_SO with null name indicates EOF */	      if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)		continue;	      /* if we did not see a function def, leave space for one.  */	      if (saw_fun == 0)		++info->indextablesize;	      saw_fun = 0;	      /* two N_SO's in a row is a filename and directory. Skip */	      if (stab + STABSIZE < info->stabs + stabsize		  && *(stab + STABSIZE + TYPEOFF) == N_SO)		{		  stab += STABSIZE;		}	    }	  else if (stab[TYPEOFF] == N_FUN)	    {	      saw_fun = 1;	      ++info->indextablesize;	    }	}      if (saw_fun == 0)	++info->indextablesize;      if (info->indextablesize == 0)	return true;      ++info->indextablesize;      info->indextable = ((struct indexentry *)			  bfd_alloc (abfd,				     (sizeof (struct indexentry)				      * info->indextablesize)));      if (info->indextable == NULL)	return false;      file_name = NULL;      directory_name = NULL;      saw_fun = 1;      for (i = 0, stroff = 0, stab = info->stabs, str = info->strs;	   i < info->indextablesize && stab < info->stabs + stabsize;	   stab += STABSIZE)	{	  switch (stab[TYPEOFF])	    {	    case 0:	      /* This is the first entry in a compilation unit.  */	      if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)		break;	      str += stroff;	      stroff = bfd_get_32 (abfd, stab + VALOFF);	      break;	    case N_SO:	      /* The main file name.  */	      /* The following code creates a new indextable entry with	         a NULL function name if there were no N_FUNs in a file.	         Note that a N_SO without a file name is an EOF and	         there could be 2 N_SO following it with the new filename	         and directory.  */	      if (saw_fun == 0)		{		  info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);		  info->indextable[i].stab = last_stab;		  info->indextable[i].str = str;		  info->indextable[i].directory_name = directory_name;		  info->indextable[i].file_name = file_name;		  info->indextable[i].function_name = NULL;		  ++i;		}	      saw_fun = 0;	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);	      if (*file_name == '\0')		{		  directory_name = NULL;		  file_name = NULL;		  saw_fun = 1;		}	      else		{		  last_stab = stab;		  if (stab + STABSIZE >= info->stabs + stabsize		      || *(stab + STABSIZE + TYPEOFF) != N_SO)		    {		      directory_name = NULL;		    }		  else		    {		      /* Two consecutive N_SOs are a directory and a			 file name.  */		      stab += STABSIZE;		      directory_name = file_name;		      file_name = ((char *) str				   + bfd_get_32 (abfd, stab + STRDXOFF));		    }		}	      break;	    case N_SOL:	      /* The name of an include file.  */	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);	      break;	    case N_FUN:	      /* A function name.  */	      saw_fun = 1;	      name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);	      if (*name == '\0')		name = NULL;	      function_name = name;	      if (name == NULL)		continue;	      info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);	      info->indextable[i].stab = stab;	      info->indextable[i].str = str;	      info->indextable[i].directory_name = directory_name;	      info->indextable[i].file_name = file_name;	      info->indextable[i].function_name = function_name;	      ++i;	      break;	    }	}      if (saw_fun == 0)	{	  info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);	  info->indextable[i].stab = last_stab;	  info->indextable[i].str = str;	  info->indextable[i].directory_name = directory_name;	  info->indextable[i].file_name = file_name;	  info->indextable[i].function_name = NULL;	  ++i;	}      info->indextable[i].val = (bfd_vma) -1;      info->indextable[i].stab = info->stabs + stabsize;      info->indextable[i].str = str;      info->indextable[i].directory_name = NULL;      info->indextable[i].file_name = NULL;      info->indextable[i].function_name = NULL;      ++i;      info->indextablesize = i;      qsort (info->indextable, i, sizeof (struct indexentry), cmpindexentry);      *pinfo = (PTR) info;    }  /* We are passed a section relative offset.  The offsets in the     stabs information are absolute.  */  offset += bfd_get_section_vma (abfd, section);#ifdef ENABLE_CACHING  if (info->cached_indexentry != NULL      && offset >= info->cached_offset      && offset < (info->cached_indexentry + 1)->val)    {      stab = info->cached_stab;      indexentry = info->cached_indexentry;      file_name = info->cached_file_name;    }  else#endif    {      /* Cache non-existant or invalid.  Do binary search on         indextable.  */      long low, high;      long mid = -1;      indexentry = NULL;      low = 0;      high = info->indextablesize - 1;      while (low != high)	{	  mid = (high + low) / 2;	  if (offset >= info->indextable[mid].val	      && offset < info->indextable[mid + 1].val)	    {	      indexentry = &info->indextable[mid];	      break;	    }	  if (info->indextable[mid].val > offset)	    high = mid;	  else	    low = mid + 1;	}      if (indexentry == NULL)	return true;      stab = indexentry->stab + STABSIZE;      file_name = indexentry->file_name;    }  directory_name = indexentry->directory_name;  str = indexentry->str;  for (; stab < (indexentry+1)->stab; stab += STABSIZE)    {      boolean done;      bfd_vma val;      done = false;      switch (stab[TYPEOFF])	{	case N_SOL:	  /* The name of an include file.  */	  val = bfd_get_32 (abfd, stab + VALOFF);	  if (val <= offset)	    {	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);	      *pline = 0;	    }	  break;	case N_SLINE:	case N_DSLINE:	case N_BSLINE:	  /* A line number.  The value is relative to the start of the             current function.  */	  val = indexentry->val + bfd_get_32 (abfd, stab + VALOFF);	  if (val <= offset)	    {	      *pline = bfd_get_16 (abfd, stab + DESCOFF);#ifdef ENABLE_CACHING	      info->cached_stab = stab;	      info->cached_offset = val;	      info->cached_file_name = file_name;	      info->cached_indexentry = indexentry;#endif	    }	  if (val > offset)	    done = true;	  break;	case N_FUN:	case N_SO:	  done = true;	  break;	}      if (done)	break;    }  *pfound = true;  if (IS_ABSOLUTE_PATH(file_name) || directory_name == NULL)    *pfilename = file_name;  else    {      size_t dirlen;      dirlen = strlen (directory_name);      if (info->filename == NULL	  || strncmp (info->filename, directory_name, dirlen) != 0	  || strcmp (info->filename + dirlen, file_name) != 0)	{	  if (info->filename != NULL)	    free (info->filename);	  info->filename = (char *) bfd_malloc (dirlen +						strlen (file_name)						+ 1);	  if (info->filename == NULL)	    return false;	  strcpy (info->filename, directory_name);	  strcpy (info->filename + dirlen, file_name);	}      *pfilename = info->filename;    }  if (indexentry->function_name != NULL)    {      char *s;      /* This will typically be something like main:F(0,1), so we want         to clobber the colon.  It's OK to change the name, since the         string is in our own local storage anyhow.  */      s = strchr (indexentry->function_name, ':');      if (s != NULL)	*s = '\0';      *pfnname = indexentry->function_name;    }  return true;}

⌨️ 快捷键说明

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