FreeBSD/contrib/binutils/bfd/elflink.c
/* Assign string offsets in .dynstr, update all structures referencing
   them.  */
Assign string offsets in .dynstr, update all structures referencing
them.
Assign string offsets in . dynstr update all structures referencing them .
static bfd_boolean
elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
{
  struct elf_link_hash_table *hash_table = elf_hash_table (info);
  struct elf_link_local_dynamic_entry *entry;
  struct elf_strtab_hash *dynstr = hash_table->dynstr;
  bfd *dynobj = hash_table->dynobj;
  asection *sdyn;
  bfd_size_type size;
  const struct elf_backend_data *bed;
  bfd_byte *extdyn;
  _bfd_elf_strtab_finalize (dynstr);
  size = _bfd_elf_strtab_size (dynstr);
  bed = get_elf_backend_data (dynobj);
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
  BFD_ASSERT (sdyn != NULL);
  for (extdyn = sdyn->contents;
       extdyn < sdyn->contents + sdyn->size;
       extdyn += bed->s->sizeof_dyn)
    {
      Elf_Internal_Dyn dyn;
      bed->s->swap_dyn_in (dynobj, extdyn, &dyn);
      switch (dyn.d_tag)
	{
	case DT_STRSZ:
	  dyn.d_un.d_val = size;
	  break;
	case DT_NEEDED:
	case DT_SONAME:
	case DT_RPATH:
	case DT_RUNPATH:
	case DT_FILTER:
	case DT_AUXILIARY:
	  dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
	  break;
	default:
	  continue;
	}
      bed->s->swap_dyn_out (dynobj, &dyn, extdyn);
    }
  for (entry = hash_table->dynlocal; entry ; entry = entry->next)
    entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
						  entry->isym.st_name);
  elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr);
  if (elf_tdata (output_bfd)->cverdefs)
    {
      asection *s;
      bfd_byte *p;
      bfd_size_type i;
      Elf_Internal_Verdef def;
      Elf_Internal_Verdaux defaux;
      s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
      p = s->contents;
      do
	{
	  _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
				   &def);
	  p += sizeof (Elf_External_Verdef);
	  if (def.vd_aux != sizeof (Elf_External_Verdef))
	    continue;
	  for (i = 0; i < def.vd_cnt; ++i)
	    {
	      _bfd_elf_swap_verdaux_in (output_bfd,
					(Elf_External_Verdaux *) p, &defaux);
	      defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
							defaux.vda_name);
	      _bfd_elf_swap_verdaux_out (output_bfd,
					 &defaux, (Elf_External_Verdaux *) p);
	      p += sizeof (Elf_External_Verdaux);
	    }
	}
      while (def.vd_next);
    }
  if (elf_tdata (output_bfd)->verref)
    {
      asection *s;
      bfd_byte *p;
      bfd_size_type i;
      Elf_Internal_Verneed need;
      Elf_Internal_Vernaux needaux;
      s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
      p = s->contents;
      do
	{
	  _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
				    &need);
	  need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
	  _bfd_elf_swap_verneed_out (output_bfd, &need,
				     (Elf_External_Verneed *) p);
	  p += sizeof (Elf_External_Verneed);
	  for (i = 0; i < need.vn_cnt; ++i)
	    {
	      _bfd_elf_swap_vernaux_in (output_bfd,
					(Elf_External_Vernaux *) p, &needaux);
	      needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
							 needaux.vna_name);
	      _bfd_elf_swap_vernaux_out (output_bfd,
					 &needaux,
					 (Elf_External_Vernaux *) p);
	      p += sizeof (Elf_External_Vernaux);
	    }
	}
      while (need.vn_next);
    }
  return TRUE;
}
static bfd_boolean elf_finalize_dynstr ( bfd * output_bfd , struct bfd_link_info * info ) { struct elf_link_hash_table * hash_table = elf_hash_table ( info ) ; struct elf_link_local_dynamic_entry * entry ; struct elf_strtab_hash * dynstr = hash_table -> dynstr ; bfd * dynobj = hash_table -> dynobj ; asection * sdyn ; bfd_size_type size ; const struct elf_backend_data * bed ; bfd_byte * extdyn ; _bfd_elf_strtab_finalize ( dynstr ) ; size = _bfd_elf_strtab_size ( dynstr ) ; bed = get_elf_backend_data ( dynobj ) ; sdyn = bfd_get_section_by_name ( dynobj , " " ) ; BFD_ASSERT ( sdyn != NULL ) ; for ( extdyn = sdyn -> contents ; extdyn < sdyn -> contents + sdyn -> size ; extdyn += bed -> s -> sizeof_dyn ) { Elf_Internal_Dyn dyn ; bed -> s -> swap_dyn_in ( dynobj , extdyn , & dyn ) ; switch ( dyn . d_tag ) { case DT_STRSZ : dyn . d_un . d_val = size ; break ; case DT_NEEDED : case DT_SONAME : case DT_RPATH : case DT_RUNPATH : case DT_FILTER : case DT_AUXILIARY : dyn . d_un . d_val = _bfd_elf_strtab_offset ( dynstr , dyn . d_un . d_val ) ; break ; default : continue ; } bed -> s -> swap_dyn_out ( dynobj , & dyn , extdyn ) ; } for ( entry = hash_table -> dynlocal ; entry ; entry = entry -> next ) entry -> isym . st_name = _bfd_elf_strtab_offset ( dynstr , entry -> isym . st_name ) ; elf_link_hash_traverse ( hash_table , elf_adjust_dynstr_offsets , dynstr ) ; if ( elf_tdata ( output_bfd ) -> cverdefs ) { asection * s ; bfd_byte * p ; bfd_size_type i ; Elf_Internal_Verdef def ; Elf_Internal_Verdaux defaux ; s = bfd_get_section_by_name ( dynobj , " " ) ; p = s -> contents ; do { _bfd_elf_swap_verdef_in ( output_bfd , ( Elf_External_Verdef * ) p , & def ) ; p += sizeof ( Elf_External_Verdef ) ; if ( def . vd_aux != sizeof ( Elf_External_Verdef ) ) continue ; for ( i = 0 ; i < def . vd_cnt ; ++ i ) { _bfd_elf_swap_verdaux_in ( output_bfd , ( Elf_External_Verdaux * ) p , & defaux ) ; defaux . vda_name = _bfd_elf_strtab_offset ( dynstr , defaux . vda_name ) ; _bfd_elf_swap_verdaux_out ( output_bfd , & defaux , ( Elf_External_Verdaux * ) p ) ; p += sizeof ( Elf_External_Verdaux ) ; } } while ( def . vd_next ) ; } if ( elf_tdata ( output_bfd ) -> verref ) { asection * s ; bfd_byte * p ; bfd_size_type i ; Elf_Internal_Verneed need ; Elf_Internal_Vernaux needaux ; s = bfd_get_section_by_name ( dynobj , " " ) ; p = s -> contents ; do { _bfd_elf_swap_verneed_in ( output_bfd , ( Elf_External_Verneed * ) p , & need ) ; need . vn_file = _bfd_elf_strtab_offset ( dynstr , need . vn_file ) ; _bfd_elf_swap_verneed_out ( output_bfd , & need , ( Elf_External_Verneed * ) p ) ; p += sizeof ( Elf_External_Verneed ) ; for ( i = 0 ; i < need . vn_cnt ; ++ i ) { _bfd_elf_swap_vernaux_in ( output_bfd , ( Elf_External_Vernaux * ) p , & needaux ) ; needaux . vna_name = _bfd_elf_strtab_offset ( dynstr , needaux . vna_name ) ; _bfd_elf_swap_vernaux_out ( output_bfd , & needaux , ( Elf_External_Vernaux * ) p ) ; p += sizeof ( Elf_External_Vernaux ) ; } } while ( need . vn_next ) ; } return TRUE ; }
Assign string offsets in .dynstr, update all structures referencing
them.
Assign string offsets in . dynstr update all structures referencing them .
/* Update all .dynamic entries referencing .dynstr strings.  */ /* Now update local dynamic symbols.  */ /* And the rest of dynamic symbols.  */ /* Adjust version definitions.  */ /* Adjust version references.  */