ecofflink.c

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

C
2,153
字号
		  value = internal_sym.value;		  for (adjust = input_debug->adjust;		       adjust != (struct ecoff_value_adjust *) NULL;		       adjust = adjust->next)		    if (value >= adjust->start			&& value < adjust->end)		      internal_sym.value += adjust->adjust;		}	      internal_sym.value += section_adjust[internal_sym.sc];	      break;	    default:	      break;	    }	  /* If we are doing a final link, we hash all the strings in	     the local symbol table together.  This reduces the amount	     of space required by debugging information.  We don't do	     this when performing a relocateable link because it would	     prevent us from easily merging different FDR's.  */	  if (! info->relocateable)	    {	      boolean ffilename;	      const char *name;	      if (! fgotfilename && internal_sym.iss == fdr.rss)		ffilename = true;	      else		ffilename = false;	      /* Hash the name into the string table.  */	      name = input_debug->ss + fdr.issBase + internal_sym.iss;	      if (*name == '\0')		internal_sym.iss = 0;	      else		{		  struct string_hash_entry *sh;		  sh = string_hash_lookup (&ainfo->str_hash, name, true, true);		  if (sh == (struct string_hash_entry *) NULL)		    return false;		  if (sh->val == -1)		    {		      sh->val = output_symhdr->issMax;		      output_symhdr->issMax += strlen (name) + 1;		      if (ainfo->ss_hash == (struct string_hash_entry *) NULL)			ainfo->ss_hash = sh;		      if (ainfo->ss_hash_end			  != (struct string_hash_entry *) NULL)			ainfo->ss_hash_end->next = sh;		      ainfo->ss_hash_end = sh;		    }		  internal_sym.iss = sh->val;		}	      if (ffilename)		{		  fdr.rss = internal_sym.iss;		  fgotfilename = true;		}	    }	  (*swap_sym_out) (output_bfd, &internal_sym, sym_out);	  sym_out += external_sym_size;	}      fdr.isymBase = output_symhdr->isymMax;      output_symhdr->isymMax += fdr.csym;      /* Copy the information that does not need swapping.  */      /* FIXME: If we are relaxing, we need to adjust the line	 numbers.  Frankly, forget it.  Anybody using stabs debugging	 information will not use this line number information, and	 stabs are adjusted correctly.  */      if (fdr.cbLine > 0)	{	  if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,				 input_bfd,				 input_symhdr->cbLineOffset + fdr.cbLineOffset,				 fdr.cbLine))	    return false;	  fdr.ilineBase = output_symhdr->ilineMax;	  fdr.cbLineOffset = output_symhdr->cbLine;	  output_symhdr->ilineMax += fdr.cline;	  output_symhdr->cbLine += fdr.cbLine;	}      if (fdr.caux > 0)	{	  if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,				 input_bfd,				 (input_symhdr->cbAuxOffset				  + fdr.iauxBase * sizeof (union aux_ext)),				 fdr.caux * sizeof (union aux_ext)))	    return false;	  fdr.iauxBase = output_symhdr->iauxMax;	  output_symhdr->iauxMax += fdr.caux;	}      if (! info->relocateable)	{	  /* When are are hashing strings, we lie about the number of	     strings attached to each FDR.  We need to set cbSs	     because some versions of dbx apparently use it to decide	     how much of the string table to read in.  */	  fdr.issBase = 0;	  fdr.cbSs = output_symhdr->issMax;	}      else if (fdr.cbSs > 0)	{	  if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,				 input_bfd,				 input_symhdr->cbSsOffset + fdr.issBase,				 fdr.cbSs))	    return false;	  fdr.issBase = output_symhdr->issMax;	  output_symhdr->issMax += fdr.cbSs;	}      if ((output_bfd->xvec->header_byteorder	   == input_bfd->xvec->header_byteorder)	  && input_debug->adjust == (struct ecoff_value_adjust *) NULL)	{	  /* The two BFD's have the same endianness, and we don't have	     to adjust the PDR addresses, so simply copying the	     information will suffice.  */	  BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);	  if (fdr.cpd > 0)	    {	      if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,				     input_bfd,				     (input_symhdr->cbPdOffset				      + fdr.ipdFirst * external_pdr_size),				     fdr.cpd * external_pdr_size))		return false;	    }	  BFD_ASSERT (external_opt_size == input_swap->external_opt_size);	  if (fdr.copt > 0)	    {	      if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,				     input_bfd,				     (input_symhdr->cbOptOffset				      + fdr.ioptBase * external_opt_size),				     fdr.copt * external_opt_size))		return false;	    }	}      else	{	  bfd_size_type outsz, insz;	  bfd_byte *in;	  bfd_byte *end;	  bfd_byte *out;	  /* The two BFD's have different endianness, so we must swap	     everything in and out.  This code would always work, but	     it would be unnecessarily slow in the normal case.  */	  outsz = external_pdr_size;	  insz = input_swap->external_pdr_size;	  in = ((bfd_byte *) input_debug->external_pdr		+ fdr.ipdFirst * insz);	  end = in + fdr.cpd * insz;	  sz = fdr.cpd * outsz;	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);	  if (!out)	    {	      bfd_set_error (bfd_error_no_memory);	      return false;	    }	  if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,				   sz))	    return false;	  for (; in < end; in += insz, out += outsz)	    {	      PDR pdr;	      (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);	      /* If we have been relaxing, we may have to adjust the		 address.  */	      if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)		{		  bfd_vma adr;		  struct ecoff_value_adjust *adjust;		  adr = fdr_adr + pdr.adr;		  for (adjust = input_debug->adjust;		       adjust != (struct ecoff_value_adjust *) NULL;		       adjust = adjust->next)		    if (adr >= adjust->start			&& adr < adjust->end)		      pdr.adr += adjust->adjust;		}	      (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);	    }	  /* Swap over the optimization information.  */	  outsz = external_opt_size;	  insz = input_swap->external_opt_size;	  in = ((bfd_byte *) input_debug->external_opt		+ fdr.ioptBase * insz);	  end = in + fdr.copt * insz;	  sz = fdr.copt * outsz;	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);	  if (!out)	    {	      bfd_set_error (bfd_error_no_memory);	      return false;	    }	  if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,				   sz))	    return false;	  for (; in < end; in += insz, out += outsz)	    {	      OPTR opt;	      (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);	      (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);	    }	}      fdr.ipdFirst = output_symhdr->ipdMax;      output_symhdr->ipdMax += fdr.cpd;      fdr.ioptBase = output_symhdr->ioptMax;      output_symhdr->ioptMax += fdr.copt;      if (fdr.crfd <= 0)	{	  /* Point this FDR at the table of RFD's we created.  */	  fdr.rfdBase = newrfdbase;	  fdr.crfd = input_symhdr->ifdMax;	}      else	{	  /* Point this FDR at the remapped RFD's.  */	  fdr.rfdBase += oldrfdbase;	}      (*swap_fdr_out) (output_bfd, &fdr, fdr_out);      fdr_out += external_fdr_size;      ++output_symhdr->ifdMax;    }  return true;}/* Add a string to the debugging information we are accumulating.   Return the offset from the fdr string base.  */static long ecoff_add_string PARAMS ((struct accumulate *,				      struct bfd_link_info *,				      struct ecoff_debug_info *,				      FDR *fdr, const char *string));static longecoff_add_string (ainfo, info, debug, fdr, string)     struct accumulate *ainfo;     struct bfd_link_info *info;     struct ecoff_debug_info *debug;     FDR *fdr;     const char *string;{  HDRR *symhdr;  size_t len;  bfd_size_type ret;  symhdr = &debug->symbolic_header;  len = strlen (string);  if (info->relocateable)    {      if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,			       len + 1))	return -1;      ret = symhdr->issMax;      symhdr->issMax += len + 1;      fdr->cbSs += len + 1;    }  else    {      struct string_hash_entry *sh;      sh = string_hash_lookup (&ainfo->str_hash, string, true, true);      if (sh == (struct string_hash_entry *) NULL)	return -1;      if (sh->val == -1)	{	  sh->val = symhdr->issMax;	  symhdr->issMax += len + 1;	  if (ainfo->ss_hash == (struct string_hash_entry *) NULL)	    ainfo->ss_hash = sh;	  if (ainfo->ss_hash_end	      != (struct string_hash_entry *) NULL)	    ainfo->ss_hash_end->next = sh;	  ainfo->ss_hash_end = sh;	}      ret = sh->val;    }  return ret;}/* Add debugging information from a non-ECOFF file.  */booleanbfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,				  output_swap, input_bfd, info)     PTR handle;     bfd *output_bfd;     struct ecoff_debug_info *output_debug;     const struct ecoff_debug_swap *output_swap;     bfd *input_bfd;     struct bfd_link_info *info;{  struct accumulate *ainfo = (struct accumulate *) handle;  void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))    = output_swap->swap_sym_out;  HDRR *output_symhdr = &output_debug->symbolic_header;  FDR fdr;  asection *sec;  asymbol **symbols;  asymbol **sym_ptr;  asymbol **sym_end;  long symsize;  long symcount;  PTR external_fdr;  memset ((PTR) &fdr, 0, sizeof fdr);  sec = bfd_get_section_by_name (input_bfd, ".text");  if (sec != NULL)    fdr.adr = sec->output_section->vma + sec->output_offset;  else    {      /* FIXME: What about .init or .fini?  */      fdr.adr = 0;    }  fdr.issBase = output_symhdr->issMax;  fdr.cbSs = 0;  fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,			      bfd_get_filename (input_bfd));  if (fdr.rss == -1)    return false;  fdr.isymBase = output_symhdr->isymMax;  /* Get the local symbols from the input BFD.  */  symsize = bfd_get_symtab_upper_bound (input_bfd);  if (symsize < 0)    return false;  symbols = (asymbol **) bfd_alloc (output_bfd, symsize);  if (symbols == (asymbol **) NULL)    return false;  symcount = bfd_canonicalize_symtab (input_bfd, symbols);  if (symcount < 0)    return false;  sym_end = symbols + symcount;  /* Handle the local symbols.  Any external symbols are handled     separately.  */  fdr.csym = 0;  for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)    {      SYMR internal_sym;      PTR external_sym;      if (((*sym_ptr)->flags & BSF_EXPORT) != 0)	continue;      memset ((PTR) &internal_sym, 0, sizeof internal_sym);      internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,					   (*sym_ptr)->name);      if (internal_sym.iss == -1)	return false;      if (bfd_is_com_section ((*sym_ptr)->section)	  || bfd_is_und_section ((*sym_ptr)->section))	internal_sym.value = (*sym_ptr)->value;      else	internal_sym.value = ((*sym_ptr)->value			      + (*sym_ptr)->section->output_offset			      + (*sym_ptr)->section->output_section->vma);      internal_sym.st = stNil;      internal_sym.sc = scUndefined;      internal_sym.index = indexNil;      external_sym = (PTR) objalloc_alloc (ainfo->memory,					   output_swap->external_sym_size);      if (!external_sym)	{	  bfd_set_error (bfd_error_no_memory);	  return false;	}      (*swap_sym_out) (output_bfd, &internal_sym, external_sym);      add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,			  external_sym, output_swap->external_sym_size);      ++fdr.csym;      ++output_symhdr->isymMax;    }  bfd_release (output_bfd, (PTR) symbols);  /* Leave everything else in the FDR zeroed out.  This will cause     the lang field to be langC.  The fBigendian field will     indicate little endian format, but it doesn't matter because     it only applies to aux fields and there are none.  */  external_fdr = (PTR) objalloc_alloc (ainfo->memory,				       output_swap->external_fdr_size);  if (!external_fdr)    {      bfd_set_error (bfd_error_no_memory);      return false;    }  (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);  add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,		      external_fdr, output_swap->external_fdr_size);  ++output_symhdr->ifdMax;  return true;}/* Set up ECOFF debugging information for the external symbols.   FIXME: This is done using a memory buffer, but it should be   probably be changed to use a shuffle structure.  The assembler uses   this interface, so that must be changed to do something else.  */booleanbfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,			   set_index)     bfd *abfd;     struct ecoff_debug_info *debug;

⌨️ 快捷键说明

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