external_relocs = (bfd_byte *) malloc (max_output_reloc_count * relsz);
external_relocs = ((bfd_byte *) bfd_malloc (max_output_reloc_count * relsz));
_bfd_coff_final_link (abfd, info)     bfd *abfd;     struct bfd_link_info *info;{  bfd_size_type symesz;  struct coff_final_link_info finfo;  boolean debug_merge_allocated;  asection *o;  struct bfd_link_order *p;  size_t max_contents_size;  size_t max_sym_count;  size_t max_lineno_count;  size_t max_reloc_count;  size_t max_output_reloc_count;  file_ptr rel_filepos;  unsigned int relsz;  file_ptr line_filepos;  unsigned int linesz;  bfd *sub;  bfd_byte *external_relocs = NULL;  char strbuf[STRING_SIZE_SIZE];  symesz = bfd_coff_symesz (abfd);  finfo.info = info;  finfo.output_bfd = abfd;  finfo.strtab = NULL;  finfo.section_info = NULL;  finfo.last_file_index = -1;  finfo.internal_syms = NULL;  finfo.sec_ptrs = NULL;  finfo.sym_indices = NULL;  finfo.outsyms = NULL;  finfo.linenos = NULL;  finfo.contents = NULL;  finfo.external_relocs = NULL;  finfo.internal_relocs = NULL;  debug_merge_allocated = false;  coff_data (abfd)->link_info = info;  finfo.strtab = _bfd_stringtab_init ();  if (finfo.strtab == NULL)    goto error_return;  if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))    goto error_return;  debug_merge_allocated = true;  /* Compute the file positions for all the sections.  */  if (! abfd->output_has_begun)    bfd_coff_compute_section_file_positions (abfd);  /* Count the line numbers and relocation entries required for the     output file.  Set the file positions for the relocs.  */  rel_filepos = obj_relocbase (abfd);  relsz = bfd_coff_relsz (abfd);  max_contents_size = 0;  max_lineno_count = 0;  max_reloc_count = 0;  for (o = abfd->sections; o != NULL; o = o->next)    {      o->reloc_count = 0;      o->lineno_count = 0;      for (p = o->link_order_head; p != NULL; p = p->next)	{	  if (p->type == bfd_indirect_link_order)	    {	      asection *sec;	      sec = p->u.indirect.section;	      if (info->strip == strip_none		  || info->strip == strip_some)		o->lineno_count += sec->lineno_count;	      if (info->relocateable)		o->reloc_count += sec->reloc_count;	      if (sec->_raw_size > max_contents_size)		max_contents_size = sec->_raw_size;	      if (sec->lineno_count > max_lineno_count)		max_lineno_count = sec->lineno_count;	      if (sec->reloc_count > max_reloc_count)		max_reloc_count = sec->reloc_count;	    }	  else if (info->relocateable		   && (p->type == bfd_section_reloc_link_order		       || p->type == bfd_symbol_reloc_link_order))	    ++o->reloc_count;	}      if (o->reloc_count == 0)	o->rel_filepos = 0;      else	{	  o->flags |= SEC_RELOC;	  o->rel_filepos = rel_filepos;	  rel_filepos += o->reloc_count * relsz;	}    }  /* If doing a relocateable link, allocate space for the pointers we     need to keep.  */  if (info->relocateable)    {      unsigned int i;      /* We use section_count + 1, rather than section_count, because         the target_index fields are 1 based.  */      finfo.section_info = ((struct coff_link_section_info *)			    malloc ((abfd->section_count + 1)				    * sizeof (struct coff_link_section_info)));      if (finfo.section_info == NULL)	{	  bfd_set_error (bfd_error_no_memory);	  goto error_return;	}      for (i = 0; i <= abfd->section_count; i++)	{	  finfo.section_info[i].relocs = NULL;	  finfo.section_info[i].rel_hashes = NULL;	}    }  /* We now know the size of the relocs, so we can determine the file     positions of the line numbers.  */  line_filepos = rel_filepos;  linesz = bfd_coff_linesz (abfd);  max_output_reloc_count = 0;  for (o = abfd->sections; o != NULL; o = o->next)    {      if (o->lineno_count == 0)	o->line_filepos = 0;      else	{	  o->line_filepos = line_filepos;	  line_filepos += o->lineno_count * linesz;	}      if (o->reloc_count != 0)	{	  /* We don't know the indices of global symbols until we have             written out all the local symbols.  For each section in             the output file, we keep an array of pointers to hash             table entries.  Each entry in the array corresponds to a             reloc.  When we find a reloc against a global symbol, we             set the corresponding entry in this array so that we can             fix up the symbol index after we have written out all the             local symbols.	     Because of this problem, we also keep the relocs in	     memory until the end of the link.  This wastes memory,	     but only when doing a relocateable link, which is not the	     common case.  */	  BFD_ASSERT (info->relocateable);	  finfo.section_info[o->target_index].relocs =	    ((struct internal_reloc *)	     malloc (o->reloc_count * sizeof (struct internal_reloc)));	  finfo.section_info[o->target_index].rel_hashes =	    ((struct coff_link_hash_entry **)	     malloc (o->reloc_count		     * sizeof (struct coff_link_hash_entry *)));	  if (finfo.section_info[o->target_index].relocs == NULL	      || finfo.section_info[o->target_index].rel_hashes == NULL)	    {	      bfd_set_error (bfd_error_no_memory);	      goto error_return;	    }	  if (o->reloc_count > max_output_reloc_count)	    max_output_reloc_count = o->reloc_count;	}      /* Reset the reloc and lineno counts, so that we can use them to	 count the number of entries we have output so far.  */      o->reloc_count = 0;      o->lineno_count = 0;    }  obj_sym_filepos (abfd) = line_filepos;  /* Figure out the largest number of symbols in an input BFD.  Take     the opportunity to clear the output_has_begun fields of all the     input BFD's.  */  max_sym_count = 0;  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)    {      size_t sz;      sub->output_has_begun = false;      sz = obj_raw_syment_count (sub);      if (sz > max_sym_count)	max_sym_count = sz;    }  /* Allocate some buffers used while linking.  */  finfo.internal_syms = ((struct internal_syment *)			 malloc (max_sym_count				 * sizeof (struct internal_syment)));  finfo.sec_ptrs = (asection **) malloc (max_sym_count * sizeof (asection *));  finfo.sym_indices = (long *) malloc (max_sym_count * sizeof (long));  finfo.outsyms = ((bfd_byte *)		   malloc ((size_t) ((max_sym_count + 1) * symesz)));  finfo.linenos = (bfd_byte *) malloc (max_lineno_count				       * bfd_coff_linesz (abfd));  finfo.contents = (bfd_byte *) malloc (max_contents_size);  finfo.external_relocs = (bfd_byte *) malloc (max_reloc_count * relsz);  if (! info->relocateable)    finfo.internal_relocs = ((struct internal_reloc *)			     malloc (max_reloc_count				     * sizeof (struct internal_reloc)));  if ((finfo.internal_syms == NULL && max_sym_count > 0)      || (finfo.sec_ptrs == NULL && max_sym_count > 0)      || (finfo.sym_indices == NULL && max_sym_count > 0)      || finfo.outsyms == NULL      || (finfo.linenos == NULL && max_lineno_count > 0)      || (finfo.contents == NULL && max_contents_size > 0)      || (finfo.external_relocs == NULL && max_reloc_count > 0)      || (! info->relocateable	  && finfo.internal_relocs == NULL	  && max_reloc_count > 0))    {      bfd_set_error (bfd_error_no_memory);      goto error_return;    }  /* We now know the position of everything in the file, except that     we don't know the size of the symbol table and therefore we don't     know where the string table starts.  We just build the string     table in memory as we go along.  We process all the relocations     for a single input file at once.  */  obj_raw_syment_count (abfd) = 0;  if (coff_backend_info (abfd)->_bfd_coff_start_final_link)    {      if (! bfd_coff_start_final_link (abfd, info))	goto error_return;    }  for (o = abfd->sections; o != NULL; o = o->next)    {      for (p = o->link_order_head; p != NULL; p = p->next)	{	  if (p->type == bfd_indirect_link_order	      && (bfd_get_flavour (p->u.indirect.section->owner)		  == bfd_target_coff_flavour))	    {	      sub = p->u.indirect.section->owner;	      if (! sub->output_has_begun)		{		  if (! coff_link_input_bfd (&finfo, sub))		    goto error_return;		  sub->output_has_begun = true;		}	    }	  else if (p->type == bfd_section_reloc_link_order		   || p->type == bfd_symbol_reloc_link_order)	    {	      if (! coff_reloc_link_order (abfd, &finfo, o, p))		goto error_return;	    }	  else	    {	      if (! _bfd_default_link_order (abfd, info, o, p))		goto error_return;	    }	}    }  /* Free up the buffers used by coff_link_input_bfd.  */  coff_debug_merge_hash_table_free (&finfo.debug_merge);  debug_merge_allocated = false;  if (finfo.internal_syms != NULL)    {      free (finfo.internal_syms);      finfo.internal_syms = NULL;    }  if (finfo.sec_ptrs != NULL)    {      free (finfo.sec_ptrs);      finfo.sec_ptrs = NULL;    }  if (finfo.sym_indices != NULL)    {      free (finfo.sym_indices);      finfo.sym_indices = NULL;    }  if (finfo.linenos != NULL)    {      free (finfo.linenos);      finfo.linenos = NULL;    }  if (finfo.contents != NULL)    {      free (finfo.contents);      finfo.contents = NULL;    }  if (finfo.external_relocs != NULL)    {      free (finfo.external_relocs);      finfo.external_relocs = NULL;    }  if (finfo.internal_relocs != NULL)    {      free (finfo.internal_relocs);      finfo.internal_relocs = NULL;    }  /* The value of the last C_FILE symbol is supposed to be the symbol     index of the first external symbol.  Write it out again if     necessary.  */  if (finfo.last_file_index != -1      && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))    {      finfo.last_file.n_value = obj_raw_syment_count (abfd);      bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,			     (PTR) finfo.outsyms);      if (bfd_seek (abfd,		    (obj_sym_filepos (abfd)		     + finfo.last_file_index * symesz),		    SEEK_SET) != 0	  || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)	return false;    }  /* Write out the global symbols.  */  finfo.failed = false;  coff_link_hash_traverse (coff_hash_table (info), coff_write_global_sym,			   (PTR) &finfo);  if (finfo.failed)    goto error_return;  /* The outsyms buffer is used by coff_write_global_sym.  */  if (finfo.outsyms != NULL)    {      free (finfo.outsyms);      finfo.outsyms = NULL;    }  if (info->relocateable)    {      /* Now that we have written out all the global symbols, we know	 the symbol indices to use for relocs against them, and we can	 finally write out the relocs.  */      external_relocs = (bfd_byte *) malloc (max_output_reloc_count * relsz);      if (external_relocs == NULL)	{	  bfd_set_error (bfd_error_no_memory);	  goto error_return;	}      for (o = abfd->sections; o != NULL; o = o->next)	{	  struct internal_reloc *irel;	  struct internal_reloc *irelend;	  struct coff_link_hash_entry **rel_hash;	  bfd_byte *erel;	  if (o->reloc_count == 0)	    continue;	  irel = finfo.section_info[o->target_index].relocs;	  irelend = irel + o->reloc_count;	  rel_hash = finfo.section_info[o->target_index].rel_hashes;	  erel = external_relocs;	  for (; irel < irelend; irel++, rel_hash++, erel += relsz)	    {	      if (*rel_hash != NULL)		{		  BFD_ASSERT ((*rel_hash)->indx >= 0);		  irel->r_symndx = (*rel_hash)->indx;		}	      bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);	    }	  if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0	      || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,			    abfd) != relsz * o->reloc_count)	    goto error_return;	}      free (external_relocs);      external_relocs = NULL;    }  /* Free up the section information.  */  if (finfo.section_info != NULL)    {      unsigned int i;      for (i = 0; i < abfd->section_count; i++)	{	  if (finfo.section_info[i].relocs != NULL)	    free (finfo.section_info[i].relocs);	  if (finfo.section_info[i].rel_hashes != NULL)	    free (finfo.section_info[i].rel_hashes);	}      free (finfo.section_info);      finfo.section_info = NULL;    }  /* Write out the string table.  */  if (obj_raw_syment_count (abfd) != 0)    {      if (bfd_seek (abfd,		    (obj_sym_filepos (abfd)		     + obj_raw_syment_count (abfd) * symesz),		    SEEK_SET) != 0)	return false;#if STRING_SIZE_SIZE == 4      bfd_h_put_32 (abfd,		    _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,		    (bfd_byte *) strbuf);#else #error Change bfd_h_put_32#endif      if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)	return false;      if (! _bfd_stringtab_emit (abfd, finfo.strtab))	return false;    }  _bfd_stringtab_free (finfo.strtab);  /* Setting bfd_get_symcount to 0 will cause write_object_contents to     not try to write out the symbols.  */  bfd_get_symcount (abfd) = 0;  return true; error_return:  if (debug_merge_allocated)    coff_debug_merge_hash_table_free (&finfo.debug_merge);  if (finfo.strtab != NULL)    _bfd_stringtab_free (finfo.strtab);  if (finfo.section_info != NULL)    {      unsigned int i;      for (i = 0; i < abfd->section_count; i++)	{	  if (finfo.section_info[i].relocs != NULL)	    free (finfo.section_info[i].relocs);	  if (finfo.section_info[i].rel_hashes != NULL)	    free (finfo.section_info[i].rel_hashes);	}      free (finfo.section_info);    }  if (finfo.internal_syms != NULL)    free (finfo.internal_syms);  if (finfo.sec_ptrs != NULL)    free (finfo.sec_ptrs);  if (finfo.sym_indices != NULL)    free (finfo.sym_indices);  if (finfo.outsyms != NULL)    free (finfo.outsyms);  if (finfo.linenos != NULL)    free (finfo.linenos);  if (finfo.contents != NULL)    free (finfo.contents);  if (finfo.external_relocs != NULL)    free (finfo.external_relocs);  if (finfo.internal_relocs != NULL)    free (finfo.internal_relocs);  if (external_relocs != NULL)    free (external_relocs);  return false;}