s = bfd_get_section_by_name (dynobj, ".dynamic"); BFD_ASSERT (s != NULL); s->_raw_size = (sizeof (struct external_sun4_dynamic) + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE + sizeof (struct external_sun4_dynamic_link));   s = bfd_get_section_by_name (dynobj, ".dynsym"); BFD_ASSERT (s != NULL); s->_raw_size = dynsymcount * sizeof (struct external_nlist); s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); if (s->contents == NULL && s->_raw_size != 0) return false;
if (sunos_hash_table (info)->dynamic_sections_needed) { *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");   s = *sdynptr; BFD_ASSERT (s != NULL); s->_raw_size = (sizeof (struct external_sun4_dynamic) + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE + sizeof (struct external_sun4_dynamic_link));   s = bfd_get_section_by_name (dynobj, ".dynsym"); BFD_ASSERT (s != NULL); s->_raw_size = dynsymcount * sizeof (struct external_nlist); s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); if (s->contents == NULL && s->_raw_size != 0) return false;
bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr,				 srulesptr)     bfd *output_bfd;     struct bfd_link_info *info;     asection **sdynptr;     asection **sneedptr;     asection **srulesptr;{  bfd *dynobj;  size_t dynsymcount;  struct sunos_link_hash_entry *h;  asection *s;  size_t bucketcount;  size_t hashalloc;  size_t i;  bfd *sub;  *sdynptr = NULL;  *sneedptr = NULL;  *srulesptr = NULL;  if (info->relocateable)    return true;  if (output_bfd->xvec != &MY(vec))    return true;  /* Look through all the input BFD's and read their relocs.  It would     be better if we didn't have to do this, but there is no other way     to determine the number of dynamic relocs we need, and, more     importantly, there is no other way to know which symbols should     get an entry in the procedure linkage table.  */  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)    {      if ((sub->flags & DYNAMIC) == 0	  && sub->xvec == output_bfd->xvec)	{	  if (! sunos_scan_relocs (info, sub, obj_textsec (sub),				   exec_hdr (sub)->a_trsize)	      || ! sunos_scan_relocs (info, sub, obj_datasec (sub),				      exec_hdr (sub)->a_drsize))	    return false;	}    }  dynobj = sunos_hash_table (info)->dynobj;  dynsymcount = sunos_hash_table (info)->dynsymcount;  /* If there were no dynamic objects in the link, and we don't need     to build a global offset table, there is nothing to do here.  */  if (! sunos_hash_table (info)->dynamic_sections_needed)    return true;  /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it.  */  h = sunos_link_hash_lookup (sunos_hash_table (info),			      "__GLOBAL_OFFSET_TABLE_", false, false, false);  if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)    {      h->flags |= SUNOS_DEF_REGULAR;      if (h->dynindx == -1)	{	  ++sunos_hash_table (info)->dynsymcount;	  h->dynindx = -2;	}      h->root.root.type = bfd_link_hash_defined;      h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");      /* If the .got section is more than 0x1000 bytes, we set         __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,         so that 13 bit relocations have a greater chance of working.  */      s = bfd_get_section_by_name (dynobj, ".got");      BFD_ASSERT (s != NULL);      if (s->_raw_size >= 0x1000)	h->root.root.u.def.value = 0x1000;      else	h->root.root.u.def.value = 0;      sunos_hash_table (info)->got_base = h->root.root.u.def.value;    }  /* The .dynamic section is always the same size.  */  s = bfd_get_section_by_name (dynobj, ".dynamic");  BFD_ASSERT (s != NULL);  s->_raw_size = (sizeof (struct external_sun4_dynamic)		  + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE		  + sizeof (struct external_sun4_dynamic_link));  /* Set the size of the .dynsym and .hash sections.  We counted the     number of dynamic symbols as we read the input files.  We will     build the dynamic symbol table (.dynsym) and the hash table     (.hash) when we build the final symbol table, because until then     we do not know the correct value to give the symbols.  We build     the dynamic symbol string table (.dynstr) in a traversal of the     symbol table using sunos_scan_dynamic_symbol.  */  s = bfd_get_section_by_name (dynobj, ".dynsym");  BFD_ASSERT (s != NULL);  s->_raw_size = dynsymcount * sizeof (struct external_nlist);  s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);  if (s->contents == NULL && s->_raw_size != 0)    return false;        /* The number of buckets is just the number of symbols divided by     four.  To compute the final size of the hash table, we must     actually compute the hash table.  Normally we need exactly as     many entries in the hash table as there are dynamic symbols, but     if some of the buckets are not used we will need additional     entries.  In the worst case, every symbol will hash to the same     bucket, and we will need BUCKETCOUNT - 1 extra entries.  */  if (dynsymcount >= 4)    bucketcount = dynsymcount / 4;  else if (dynsymcount > 0)    bucketcount = dynsymcount;  else    bucketcount = 1;  s = bfd_get_section_by_name (dynobj, ".hash");  BFD_ASSERT (s != NULL);  hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;  s->contents = (bfd_byte *) bfd_alloc (dynobj, hashalloc);  if (s->contents == NULL && dynsymcount > 0)    return false;  memset (s->contents, 0, hashalloc);  for (i = 0; i < bucketcount; i++)    PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);  s->_raw_size = bucketcount * HASH_ENTRY_SIZE;  sunos_hash_table (info)->bucketcount = bucketcount;  /* Scan all the symbols, place them in the dynamic symbol table, and     build the dynamic hash table.  We reuse dynsymcount as a counter     for the number of symbols we have added so far.  */  sunos_hash_table (info)->dynsymcount = 0;  sunos_link_hash_traverse (sunos_hash_table (info),			    sunos_scan_dynamic_symbol,			    (PTR) info);  BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);  /* The SunOS native linker seems to align the total size of the     symbol strings to a multiple of 8.  I don't know if this is     important, but it can't hurt much.  */  s = bfd_get_section_by_name (dynobj, ".dynstr");  BFD_ASSERT (s != NULL);  if ((s->_raw_size & 7) != 0)    {      bfd_size_type add;      bfd_byte *contents;      add = 8 - (s->_raw_size & 7);      contents = (bfd_byte *) bfd_realloc (s->contents,					   (size_t) (s->_raw_size + add));      if (contents == NULL)	return false;      memset (contents + s->_raw_size, 0, (size_t) add);      s->contents = contents;      s->_raw_size += add;    }  /* Now that we have worked out the sizes of the procedure linkage     table and the dynamic relocs, allocate storage for them.  */  s = bfd_get_section_by_name (dynobj, ".plt");  BFD_ASSERT (s != NULL);  if (s->_raw_size != 0)    {      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);      if (s->contents == NULL)	return false;      /* Fill in the first entry in the table.  */      switch (bfd_get_arch (dynobj))	{	case bfd_arch_sparc:	  memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);	  break;	case bfd_arch_m68k:	  memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);	  break;	default:	  abort ();	}    }  s = bfd_get_section_by_name (dynobj, ".dynrel");  if (s->_raw_size != 0)    {      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);      if (s->contents == NULL)	return false;    }  /* We use the reloc_count field to keep track of how many of the     relocs we have output so far.  */  s->reloc_count = 0;  /* Make space for the global offset table.  */  s = bfd_get_section_by_name (dynobj, ".got");  s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);  if (s->contents == NULL)    return false;  *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");  *sneedptr = bfd_get_section_by_name (dynobj, ".need");  *srulesptr = bfd_get_section_by_name (dynobj, ".rules");  return true;}