ecofflink.c

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

C
2,153
字号
     const struct ecoff_debug_swap *swap;     boolean relocateable;     boolean (*get_extr) PARAMS ((asymbol *, EXTR *));     void (*set_index) PARAMS ((asymbol *, bfd_size_type));{  HDRR * const symhdr = &debug->symbolic_header;  asymbol **sym_ptr_ptr;  size_t c;  sym_ptr_ptr = bfd_get_outsymbols (abfd);  if (sym_ptr_ptr == NULL)    return true;  for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)    {      asymbol *sym_ptr;      EXTR esym;      sym_ptr = *sym_ptr_ptr;      /* Get the external symbol information.  */      if ((*get_extr) (sym_ptr, &esym) == false)	continue;      /* If we're producing an executable, move common symbols into	 bss.  */      if (relocateable == false)	{	  if (esym.asym.sc == scCommon)	    esym.asym.sc = scBss;	  else if (esym.asym.sc == scSCommon)	    esym.asym.sc = scSBss;	}      if (bfd_is_com_section (sym_ptr->section)	  || bfd_is_und_section (sym_ptr->section)	  || sym_ptr->section->output_section == (asection *) NULL)	{	  /* FIXME: gas does not keep the value of a small undefined	     symbol in the symbol itself, because of relocation	     problems.  */	  if (esym.asym.sc != scSUndefined	      || esym.asym.value == 0	      || sym_ptr->value != 0)	    esym.asym.value = sym_ptr->value;	}      else	esym.asym.value = (sym_ptr->value			   + sym_ptr->section->output_offset			   + sym_ptr->section->output_section->vma);      if (set_index)	(*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);      if (! bfd_ecoff_debug_one_external (abfd, debug, swap,					  sym_ptr->name, &esym))	return false;    }  return true;}/* Add a single external symbol to the debugging information.  */booleanbfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)     bfd *abfd;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;     const char *name;     EXTR *esym;{  const bfd_size_type external_ext_size = swap->external_ext_size;  void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))    = swap->swap_ext_out;  HDRR * const symhdr = &debug->symbolic_header;  size_t namelen;  namelen = strlen (name);  if ((size_t) (debug->ssext_end - debug->ssext)      < symhdr->issExtMax + namelen + 1)    {      if (ecoff_add_bytes ((char **) &debug->ssext,			   (char **) &debug->ssext_end,			   symhdr->issExtMax + namelen + 1)	  == false)	return false;    }  if ((size_t) ((char *) debug->external_ext_end		- (char *) debug->external_ext)      < (symhdr->iextMax + 1) * external_ext_size)    {      if (ecoff_add_bytes ((char **) &debug->external_ext,			   (char **) &debug->external_ext_end,			   (symhdr->iextMax + 1) * external_ext_size)	  == false)	return false;    }  esym->asym.iss = symhdr->issExtMax;  (*swap_ext_out) (abfd, esym,		   ((char *) debug->external_ext		    + symhdr->iextMax * swap->external_ext_size));  ++symhdr->iextMax;  strcpy (debug->ssext + symhdr->issExtMax, name);  symhdr->issExtMax += namelen + 1;  return true;}/* Align the ECOFF debugging information.  */static voidecoff_align_debug (abfd, debug, swap)     bfd *abfd ATTRIBUTE_UNUSED;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;{  HDRR * const symhdr = &debug->symbolic_header;  bfd_size_type debug_align, aux_align, rfd_align;  size_t add;  /* Adjust the counts so that structures are aligned.  */  debug_align = swap->debug_align;  aux_align = debug_align / sizeof (union aux_ext);  rfd_align = debug_align / swap->external_rfd_size;  add = debug_align - (symhdr->cbLine & (debug_align - 1));  if (add != debug_align)    {      if (debug->line != (unsigned char *) NULL)	memset ((PTR) (debug->line + symhdr->cbLine), 0, add);      symhdr->cbLine += add;    }  add = debug_align - (symhdr->issMax & (debug_align - 1));  if (add != debug_align)    {      if (debug->ss != (char *) NULL)	memset ((PTR) (debug->ss + symhdr->issMax), 0, add);      symhdr->issMax += add;    }  add = debug_align - (symhdr->issExtMax & (debug_align - 1));  if (add != debug_align)    {      if (debug->ssext != (char *) NULL)	memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);      symhdr->issExtMax += add;    }  add = aux_align - (symhdr->iauxMax & (aux_align - 1));  if (add != aux_align)    {      if (debug->external_aux != (union aux_ext *) NULL)	memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,		add * sizeof (union aux_ext));      symhdr->iauxMax += add;    }  add = rfd_align - (symhdr->crfd & (rfd_align - 1));  if (add != rfd_align)    {      if (debug->external_rfd != (PTR) NULL)	memset ((PTR) ((char *) debug->external_rfd		       + symhdr->crfd * swap->external_rfd_size),		0, (size_t) (add * swap->external_rfd_size));      symhdr->crfd += add;    }}/* Return the size required by the ECOFF debugging information.  */bfd_size_typebfd_ecoff_debug_size (abfd, debug, swap)     bfd *abfd;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;{  bfd_size_type tot;  ecoff_align_debug (abfd, debug, swap);  tot = swap->external_hdr_size;#define ADD(count, size) \  tot += debug->symbolic_header.count * size  ADD (cbLine, sizeof (unsigned char));  ADD (idnMax, swap->external_dnr_size);  ADD (ipdMax, swap->external_pdr_size);  ADD (isymMax, swap->external_sym_size);  ADD (ioptMax, swap->external_opt_size);  ADD (iauxMax, sizeof (union aux_ext));  ADD (issMax, sizeof (char));  ADD (issExtMax, sizeof (char));  ADD (ifdMax, swap->external_fdr_size);  ADD (crfd, swap->external_rfd_size);  ADD (iextMax, swap->external_ext_size);#undef ADD  return tot;}/* Write out the ECOFF symbolic header, given the file position it is   going to be placed at.  This assumes that the counts are set   correctly.  */static booleanecoff_write_symhdr (abfd, debug, swap, where)     bfd *abfd;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;     file_ptr where;{  HDRR * const symhdr = &debug->symbolic_header;  char *buff = NULL;  ecoff_align_debug (abfd, debug, swap);  /* Go to the right location in the file.  */  if (bfd_seek (abfd, where, SEEK_SET) != 0)    return false;  where += swap->external_hdr_size;  symhdr->magic = swap->sym_magic;  /* Fill in the file offsets.  */#define SET(offset, count, size) \  if (symhdr->count == 0) \    symhdr->offset = 0; \  else \    { \      symhdr->offset = where; \      where += symhdr->count * size; \    }  SET (cbLineOffset, cbLine, sizeof (unsigned char));  SET (cbDnOffset, idnMax, swap->external_dnr_size);  SET (cbPdOffset, ipdMax, swap->external_pdr_size);  SET (cbSymOffset, isymMax, swap->external_sym_size);  SET (cbOptOffset, ioptMax, swap->external_opt_size);  SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));  SET (cbSsOffset, issMax, sizeof (char));  SET (cbSsExtOffset, issExtMax, sizeof (char));  SET (cbFdOffset, ifdMax, swap->external_fdr_size);  SET (cbRfdOffset, crfd, swap->external_rfd_size);  SET (cbExtOffset, iextMax, swap->external_ext_size);#undef SET  buff = (PTR) bfd_malloc ((size_t) swap->external_hdr_size);  if (buff == NULL && swap->external_hdr_size != 0)    goto error_return;  (*swap->swap_hdr_out) (abfd, symhdr, buff);  if (bfd_write (buff, 1, swap->external_hdr_size, abfd)      != swap->external_hdr_size)    goto error_return;  if (buff != NULL)    free (buff);  return true; error_return:  if (buff != NULL)    free (buff);  return false;}/* Write out the ECOFF debugging information.  This function assumes   that the information (the pointers and counts) in *DEBUG have been   set correctly.  WHERE is the position in the file to write the   information to.  This function fills in the file offsets in the   symbolic header.  */booleanbfd_ecoff_write_debug (abfd, debug, swap, where)     bfd *abfd;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;     file_ptr where;{  HDRR * const symhdr = &debug->symbolic_header;  if (! ecoff_write_symhdr (abfd, debug, swap, where))    return false;#define WRITE(ptr, count, size, offset) \  BFD_ASSERT (symhdr->offset == 0 \	      || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \  if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \      != size * symhdr->count) \    return false;  WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);  WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);  WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);  WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);  WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);  WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);  WRITE (ss, issMax, sizeof (char), cbSsOffset);  WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);  WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);  WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);  WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);#undef WRITE  return true;}/* Write out a shuffle list.  */static boolean ecoff_write_shuffle PARAMS ((bfd *,					    const struct ecoff_debug_swap *,					    struct shuffle *, PTR space));static booleanecoff_write_shuffle (abfd, swap, shuffle, space)     bfd *abfd;     const struct ecoff_debug_swap *swap;     struct shuffle *shuffle;     PTR space;{  register struct shuffle *l;  unsigned long total;  total = 0;  for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)    {      if (! l->filep)	{	  if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)	    return false;	}      else	{	  if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0	      || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size	      || bfd_write (space, 1, l->size, abfd) != l->size)	    return false;	}      total += l->size;    }  if ((total & (swap->debug_align - 1)) != 0)    {      unsigned int i;      bfd_byte *s;      i = swap->debug_align - (total & (swap->debug_align - 1));      s = (bfd_byte *) bfd_malloc (i);      if (s == NULL && i != 0)	return false;      memset ((PTR) s, 0, i);      if (bfd_write ((PTR) s, 1, i, abfd) != i)	{	  free (s);	  return false;	}      free (s);    }  return true;}/* Write out debugging information using accumulated linker   information.  */booleanbfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)     PTR handle;     bfd *abfd;     struct ecoff_debug_info *debug;     const struct ecoff_debug_swap *swap;     struct bfd_link_info *info;     file_ptr where;{  struct accumulate *ainfo = (struct accumulate *) handle;  PTR space = NULL;  if (! ecoff_write_symhdr (abfd, debug, swap, where))    goto error_return;  space = (PTR) bfd_malloc (ainfo->largest_file_shuffle);  if (space == NULL && ainfo->largest_file_shuffle != 0)    goto error_return;  if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)      || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)      || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)      || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)      || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))    goto error_return;  /* The string table is written out from the hash table if this is a     final link.  */  if (info->relocateable)    {      BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);      if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))	goto error_return;    }  else    {      unsigned long total;      bfd_byte null;      struct string_hash_entry *sh;      BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);      null = 0;      if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)	goto error_return;      total = 1;      BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);      for (sh = ainfo->ss_hash;	   sh != (struct string_hash_entry *) NULL;	   sh = sh->next)	{	  size_t len;	  len = strlen (sh->root.string);	  if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)	    goto error_return;	  total += len + 1;	}

⌨️ 快捷键说明

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