This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC [PATCH] Use .strtab section for section name strings


Hi,

Here is a patch to use .strtab section for section name strings if
there are symbols, otherwise use .shstrtab section.

I tried it on libstdc++.  For src/c++11/limits.o

Old: 93064 bytes
New: 76040 bytes

It reduces file size by 18%.

I also updated binutils tests on users/hjl/pr18599 branch.

Any comments, feedbacks, suggestions or objections?

Thanks.

H.J.
---
 bfd/bfd-in2.h |  12 +++
 bfd/bfd.c     |  12 +++
 bfd/elf-bfd.h |   8 +-
 bfd/elf.c     | 324 ++++++++++++++++++++++++++++++----------------------------
 bfd/elflink.c |  89 +++++++---------
 5 files changed, 233 insertions(+), 212 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 2d32c74..5624835 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6502,6 +6502,18 @@ struct bfd
   /* Set if this is a plugin output file.  */
   unsigned int lto_output : 1;
 
+  /* Set if symbol table is needed.  */
+  unsigned int need_symtab : 1;
+
+  /* Set if .shstrtab setion is needed.  */
+  unsigned int use_shstrtab : 1;
+
+  /* Set if group sections should be handled.  */
+  unsigned int handle_group_sections : 1;
+
+  /* Set if debug and strtab sections are done.  */
+  unsigned int debug_and_strtab_done : 1;
+
   /* Set to dummy BFD created when claimed by a compiler plug-in
      library.  */
   bfd *plugin_dummy_bfd;
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 8d85de5..c3904fd 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -227,6 +227,18 @@ CODE_FRAGMENT
 .  {* Set if this is a plugin output file.  *}
 .  unsigned int lto_output : 1;
 .
+.  {* Set if symbol table is needed.  *}
+.  unsigned int need_symtab : 1;
+.
+.  {* Set if .shstrtab, instead of .strtab, setion is used.  *}
+.  unsigned int use_shstrtab : 1;
+.
+.  {* Set if group sections should be handled.  *}
+.  unsigned int handle_group_sections : 1;
+.
+.  {* Set if debug and strtab sections are done.  *}
+.  unsigned int debug_and_strtab_done : 1;
+.
 .  {* Set to dummy BFD created when claimed by a compiler plug-in
 .     library.  *}
 .  bfd *plugin_dummy_bfd;
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 06a3883..14e162f 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1595,7 +1595,7 @@ struct core_elf_obj_tdata
 struct output_elf_obj_tdata
 {
   struct elf_segment_map *seg_map;
-  struct elf_strtab_hash *strtab_ptr;
+  struct elf_strtab_hash *shstrtab_ptr;
 
   /* STT_SECTION symbols for each section */
   asymbol **section_syms;
@@ -1766,7 +1766,7 @@ struct elf_obj_tdata
 #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
 #define elf_linker(bfd)		(elf_tdata(bfd) -> o->linker)
 #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
-#define elf_shstrtab(bfd)	(elf_tdata(bfd) -> o->strtab_ptr)
+#define elf_shstrtab(bfd)	(elf_tdata(bfd) -> o->shstrtab_ptr)
 #define elf_onesymtab(bfd)	(elf_tdata(bfd) -> symtab_section)
 #define elf_symtab_shndx(bfd)	(elf_tdata(bfd) -> symtab_shndx_section)
 #define elf_strtab_sec(bfd)	(elf_tdata(bfd) -> o->strtab_section)
@@ -1903,8 +1903,6 @@ extern bfd_boolean bfd_elf_is_group_section
   (bfd *, const struct bfd_section *);
 extern bfd_boolean _bfd_elf_section_already_linked
   (bfd *, asection *, struct bfd_link_info *);
-extern void bfd_elf_set_group_contents
-  (bfd *, asection *, void *);
 extern asection *_bfd_elf_check_kept_section
   (asection *, struct bfd_link_info *);
 #define _bfd_elf_link_just_syms _bfd_generic_link_just_syms
@@ -2062,6 +2060,8 @@ extern bfd_boolean _bfd_elf_compute_section_file_positions
   (bfd *, struct bfd_link_info *);
 extern file_ptr _bfd_elf_assign_file_position_for_section
   (Elf_Internal_Shdr *, file_ptr, bfd_boolean);
+extern bfd_boolean _bfd_elf_assign_file_positions_for_debug_and_strtab
+  (bfd *);
 
 extern bfd_boolean _bfd_elf_validate_reloc
   (bfd *, arelent *);
diff --git a/bfd/elf.c b/bfd/elf.c
index 9846046..d9a7b90 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -51,7 +51,7 @@ SECTION
 static int elf_sort_sections (const void *, const void *);
 static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
 static bfd_boolean prep_headers (bfd *);
-static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ;
+static bfd_boolean swap_out_syms (bfd *, int) ;
 static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
 static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
 				    file_ptr offset);
@@ -3045,16 +3045,14 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 }
 
 /* Fill in the contents of a SHT_GROUP section.  Called from
-   _bfd_elf_compute_section_file_positions for gas, objcopy, and
-   when ELF targets use the generic linker, ld.  Called for ld -r
-   from bfd_elf_final_link.  */
+   _bfd_elf_write_object_contents.  */
 
-void
+static void
 bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
 {
   bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
   asection *elt, *first;
-  unsigned char *loc;
+  unsigned char *loc, *contents;
   bfd_boolean gas;
 
   /* Ignore linker created group section.  See elfNN_ia64_object_p in
@@ -3108,22 +3106,19 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
     }
 
   /* The contents won't be allocated for "ld -r" or objcopy.  */
-  gas = TRUE;
-  if (sec->contents == NULL)
+  contents = sec->contents;
+  gas = contents != NULL;
+  if (!gas)
     {
-      gas = FALSE;
-      sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
-
-      /* Arrange for the section to be written out.  */
-      elf_section_data (sec)->this_hdr.contents = sec->contents;
-      if (sec->contents == NULL)
+      contents = (unsigned char *) bfd_alloc (abfd, sec->size);
+      if (contents == NULL)
 	{
 	  *failedptr = TRUE;
 	  return;
 	}
     }
 
-  loc = sec->contents + sec->size;
+  loc = contents + sec->size;
 
   /* Get the pointer to the first section in the group that gas
      squirreled away here.  objcopy arranges for this to be set to the
@@ -3154,9 +3149,14 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
 	break;
     }
 
-  if ((loc -= 4) != sec->contents)
+  if ((loc -= 4) != contents)
     abort ();
 
+  /* Arrange for the section to be written out in
+     _bfd_elf_write_object_contents.  */
+  elf_section_data (sec)->this_hdr.contents = contents;
+  sec->contents = NULL;
+
   H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
 }
 
@@ -3290,8 +3290,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 	  if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
 	    return FALSE;
 	}
-      elf_strtab_sec (abfd) = section_number++;
-      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
     }
 
   if (section_number >= SHN_LORESERVE)
@@ -3330,8 +3328,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 	  i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
 	  t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
 	}
-      i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
-      t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
+      t->symtab_hdr.sh_link = elf_shstrtab_sec (abfd);
     }
 
   for (sec = abfd->sections; sec; sec = sec->next)
@@ -3718,14 +3715,20 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   struct fake_section_arg fsargs;
-  bfd_boolean failed;
-  struct elf_strtab_hash *strtab = NULL;
   Elf_Internal_Shdr *shstrtab_hdr;
-  bfd_boolean need_symtab;
 
   if (abfd->output_has_begun)
     return TRUE;
 
+  /* For section name strings, use .shstrtab section if there are no
+     symbols, otherwise use .strtab section.  */
+  abfd->use_shstrtab = ((link_info != NULL
+			  && link_info->strip == strip_all
+			  && !link_info->relocatable
+			  && !link_info->emitrelocations)
+			 || (link_info == NULL
+			     && !bfd_get_symcount (abfd)));
+
   /* Do any elf backend specific processing first.  */
   if (bed->elf_backend_begin_write_processing)
     (*bed->elf_backend_begin_write_processing) (abfd, link_info);
@@ -3746,25 +3749,15 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
     return FALSE;
 
   /* The backend linker builds symbol table information itself.  */
-  need_symtab = (link_info == NULL
-		 && (bfd_get_symcount (abfd) > 0
-		     || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
-			 == HAS_RELOC)));
-  if (need_symtab)
-    {
-      /* Non-zero if doing a relocatable link.  */
-      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
-
-      if (! swap_out_syms (abfd, &strtab, relocatable_p))
-	return FALSE;
-    }
-
-  failed = FALSE;
   if (link_info == NULL)
     {
-      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
-      if (failed)
-	return FALSE;
+      abfd->handle_group_sections = 1;
+
+      /* Check if symbol table is needed.  */
+      if (bfd_get_symcount (abfd) > 0
+	  || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
+	      == HAS_RELOC))
+	abfd->need_symtab = 1;
     }
 
   shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
@@ -3782,33 +3775,6 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
   if (!assign_file_positions_except_relocs (abfd, link_info))
     return FALSE;
 
-  if (need_symtab)
-    {
-      file_ptr off;
-      Elf_Internal_Shdr *hdr;
-
-      off = elf_next_file_pos (abfd);
-
-      hdr = &elf_tdata (abfd)->symtab_hdr;
-      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
-      hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
-      if (hdr->sh_size != 0)
-	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
-      hdr = &elf_tdata (abfd)->strtab_hdr;
-      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
-      elf_next_file_pos (abfd) = off;
-
-      /* Now that we know where the .strtab section goes, write it
-	 out.  */
-      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
-	  || ! _bfd_elf_strtab_emit (abfd, strtab))
-	return FALSE;
-      _bfd_elf_strtab_free (strtab);
-    }
-
   abfd->output_has_begun = TRUE;
 
   return TRUE;
@@ -5435,6 +5401,9 @@ assign_file_positions_except_relocs (bfd *abfd,
 	  hdr = *hdrpp;
 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 	       && hdr->bfd_section == NULL)
+	      || hdr->sh_type == SHT_GROUP
+	      /* Group sections are handled in
+		 _bfd_elf_write_object_contents.  */
 	      || (hdr->bfd_section != NULL
 		  && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
 		  /* Compress DWARF debug sections.  */
@@ -5577,29 +5546,39 @@ prep_headers (bfd *abfd)
 
   elf_tdata (abfd)->symtab_hdr.sh_name =
     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
-  elf_tdata (abfd)->strtab_hdr.sh_name =
-    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
   elf_tdata (abfd)->shstrtab_hdr.sh_name =
-    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
+    (unsigned int) _bfd_elf_strtab_add (shstrtab,
+					(abfd->use_shstrtab
+					 ? ".shstrtab" : ".strtab"),
+					FALSE);
   if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
-      || elf_tdata (abfd)->strtab_hdr.sh_name == (unsigned int) -1
       || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
     return FALSE;
 
   return TRUE;
 }
 
-/* Assign file positions for all the reloc sections which are not part
-   of the loadable file image, and the file position of section headers.  */
+/* Assign file positions for debug and strtab sections.  Called from
+   bfd_elf_final_link for ld before swapping out symbols into strtab.
+   Called from _bfd_elf_write_object_contents for ld, gas and objcopy.
+   We check debug_and_strtab_done to avoid performing the same task
+   twice for ld.
 
-static bfd_boolean
-_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
+   Since we use the same strtab section for both symbol names as well
+   as section names, we delay finalizing the strtab section after debug
+   sections are compressed, which may change debug section names.  */
+
+bfd_boolean
+_bfd_elf_assign_file_positions_for_debug_and_strtab (bfd *abfd)
 {
   file_ptr off;
   Elf_Internal_Shdr **shdrpp, **end_shdrpp;
   Elf_Internal_Shdr *shdrp;
-  Elf_Internal_Ehdr *i_ehdrp;
-  const struct elf_backend_data *bed;
+
+  if (abfd->debug_and_strtab_done)
+    return TRUE;
+
+  abfd->debug_and_strtab_done = 1;
 
   off = elf_next_file_pos (abfd);
 
@@ -5611,57 +5590,47 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
       if (shdrp->sh_offset == -1)
 	{
 	  asection *sec = shdrp->bfd_section;
-	  bfd_boolean is_rel = (shdrp->sh_type == SHT_REL
-				|| shdrp->sh_type == SHT_RELA);
-	  if (is_rel
-	      || (sec != NULL && (sec->flags & SEC_ELF_COMPRESS)))
+	  if (sec != NULL && (sec->flags & SEC_ELF_COMPRESS))
 	    {
-	      if (!is_rel)
-		{
-		  const char *name = sec->name;
-		  struct bfd_elf_section_data *d;
+	      const char *name = sec->name;
+	      struct bfd_elf_section_data *d;
 
-		  /* Compress DWARF debug sections.  */
-		  if (!bfd_compress_section (abfd, sec,
-					     shdrp->contents))
-		    return FALSE;
+	      /* Compress DWARF debug sections.  */
+	      if (!bfd_compress_section (abfd, sec, shdrp->contents))
+		return FALSE;
 
-		  if (sec->compress_status == COMPRESS_SECTION_DONE
-		      && (abfd->flags & BFD_COMPRESS_GABI) == 0)
-		    {
-		      /* If section is compressed with zlib-gnu, convert
-			 section name from .debug_* to .zdebug_*.  */
-		      char *new_name
-			= convert_debug_to_zdebug (abfd, name);
-		      if (new_name == NULL)
-			return FALSE;
-		      name = new_name;
-		    }
-		  /* Add setion name to section name section.  */
-		  if (shdrp->sh_name != (unsigned int) -1)
-		    abort ();
-		  shdrp->sh_name
-		    = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-							  name, FALSE);
-		  d = elf_section_data (sec);
-
-		  /* Add reloc setion name to section name section.  */
-		  if (d->rel.hdr
-		      && !_bfd_elf_set_reloc_sh_name (abfd,
-						      d->rel.hdr,
-						      name, FALSE))
-		    return FALSE;
-		  if (d->rela.hdr
-		      && !_bfd_elf_set_reloc_sh_name (abfd,
-						      d->rela.hdr,
-						      name, FALSE))
+	      if (sec->compress_status == COMPRESS_SECTION_DONE
+		  && (abfd->flags & BFD_COMPRESS_GABI) == 0)
+		{
+		  /* If section is compressed with zlib-gnu, convert
+		     section name from .debug_* to .zdebug_*.  */
+		  char *new_name = convert_debug_to_zdebug (abfd, name);
+		  if (new_name == NULL)
 		    return FALSE;
-
-		  /* Update section size and contents.  */
-		  shdrp->sh_size = sec->size;
-		  shdrp->contents = sec->contents;
-		  shdrp->bfd_section->contents = NULL;
+		  name = new_name;
 		}
+	      /* Add setion name to section name section.  */
+	      if (shdrp->sh_name != (unsigned int) -1)
+		abort ();
+	      shdrp->sh_name
+		= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+						      name, FALSE);
+	      d = elf_section_data (sec);
+
+	      /* Add reloc setion name to section name section.  */
+	      if (d->rel.hdr
+		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rel.hdr,
+						  name, FALSE))
+		return FALSE;
+	      if (d->rela.hdr
+		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rela.hdr,
+						  name, FALSE))
+		return FALSE;
+
+	      /* Update section size and contents.  */
+	      shdrp->sh_size = sec->size;
+	      shdrp->contents = sec->contents;
+	      shdrp->bfd_section->contents = NULL;
 	      off = _bfd_elf_assign_file_position_for_section (shdrp,
 							       off,
 							       TRUE);
@@ -5669,13 +5638,67 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
 	}
     }
 
+  if (abfd->need_symtab)
+    {
+      Elf_Internal_Shdr *hdr;
+      /* Non-zero if doing a relocatable link.  */
+      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
+
+      /* swap_out_syms calls _bfd_elf_strtab_finalize after swapping
+	 out symbols into strtab.  */
+      if (! swap_out_syms (abfd, relocatable_p))
+	return FALSE;
+
+      hdr = &elf_tdata (abfd)->symtab_hdr;
+      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+
+      hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+      if (hdr->sh_size != 0)
+	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+    }
+  else
+    /* Call _bfd_elf_strtab_finalize on strtab for ld and for objcopy
+       without symbol table.  */
+    _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
+
   /* Place section name section after DWARF debug sections have been
      compressed.  */
-  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
   shdrp = &elf_tdata (abfd)->shstrtab_hdr;
   shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
   off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
 
+  elf_next_file_pos (abfd) = off;
+
+  return TRUE;
+}
+
+/* Assign file positions for all the reloc sections which are not part
+   of the loadable file image, and the file position of section headers.  */
+
+static bfd_boolean
+_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
+{
+  file_ptr off;
+  Elf_Internal_Shdr **shdrpp, **end_shdrpp;
+  Elf_Internal_Shdr *shdrp;
+  Elf_Internal_Ehdr *i_ehdrp;
+  const struct elf_backend_data *bed;
+
+  off = elf_next_file_pos (abfd);
+
+  shdrpp = elf_elfsections (abfd);
+  end_shdrpp = shdrpp + elf_numsections (abfd);
+  for (shdrpp++; shdrpp < end_shdrpp; shdrpp++)
+    {
+      shdrp = *shdrpp;
+      if (shdrp->sh_offset == -1
+	  && (shdrp->sh_type == SHT_GROUP
+	      || shdrp->sh_type == SHT_REL
+	      || shdrp->sh_type == SHT_RELA))
+	off = _bfd_elf_assign_file_position_for_section (shdrp, off,
+							 TRUE);
+    }
+
   /* Place the section headers.  */
   i_ehdrp = elf_elfheader (abfd);
   bed = get_elf_backend_data (abfd);
@@ -5702,6 +5725,17 @@ _bfd_elf_write_object_contents (bfd *abfd)
 
   i_shdrp = elf_elfsections (abfd);
 
+  if (!_bfd_elf_assign_file_positions_for_debug_and_strtab (abfd))
+    return FALSE;
+
+  failed = FALSE;
+  if (abfd->handle_group_sections)
+    {
+      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
+      if (failed)
+	return FALSE;
+    }
+
   failed = FALSE;
   bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
   if (failed)
@@ -7041,17 +7075,13 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd,
 /* Swap out the symbols.  */
 
 static bfd_boolean
-swap_out_syms (bfd *abfd,
-	       struct elf_strtab_hash **sttp,
-	       int relocatable_p)
+swap_out_syms (bfd *abfd, int relocatable_p)
 {
   const struct elf_backend_data *bed;
   int symcount;
   asymbol **syms;
-  struct elf_strtab_hash *stt;
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Shdr *symtab_shndx_hdr;
-  Elf_Internal_Shdr *symstrtab_hdr;
   struct elf_sym_strtab *symstrtab;
   bfd_byte *outbound_syms;
   bfd_byte *outbound_shndx;
@@ -7066,10 +7096,6 @@ swap_out_syms (bfd *abfd,
     return FALSE;
 
   /* Dump out the symtabs.  */
-  stt = _bfd_elf_strtab_init ();
-  if (stt == NULL)
-    return FALSE;
-
   bed = get_elf_backend_data (abfd);
   symcount = bfd_get_symcount (abfd);
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -7079,24 +7105,17 @@ swap_out_syms (bfd *abfd,
   symtab_hdr->sh_info = num_locals + 1;
   symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
-  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
-  symstrtab_hdr->sh_type = SHT_STRTAB;
-
   /* Allocate buffer to swap out the .strtab section.  */
   symstrtab = (struct elf_sym_strtab *) bfd_malloc ((symcount + 1)
 						    * sizeof (*symstrtab));
   if (symstrtab == NULL)
-    {
-      _bfd_elf_strtab_free (stt);
-      return FALSE;
-    }
+    return FALSE;
 
   outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
                                            bed->s->sizeof_sym);
   if (outbound_syms == NULL)
     {
 error_return:
-      _bfd_elf_strtab_free (stt);
       free (symstrtab);
       return FALSE;
     }
@@ -7164,7 +7183,8 @@ error_return:
 	  /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
 	     to get the final offset for st_name.  */
 	  sym.st_name
-	    = (unsigned long) _bfd_elf_strtab_add (stt, syms[idx]->name,
+	    = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+						   syms[idx]->name,
 						   FALSE);
 	  if (sym.st_name == (unsigned long) -1)
 	    goto error_return;
@@ -7354,7 +7374,7 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
     }
 
   /* Finalize the .strtab section.  */
-  _bfd_elf_strtab_finalize (stt);
+  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
 
   /* Swap out the .strtab section.  */
   for (idx = 0; idx <= symcount; idx++)
@@ -7363,7 +7383,7 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
       if (elfsym->sym.st_name == (unsigned long) -1)
 	elfsym->sym.st_name = 0;
       else
-	elfsym->sym.st_name = _bfd_elf_strtab_offset (stt,
+	elfsym->sym.st_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
 						      elfsym->sym.st_name);
       bed->s->swap_symbol_out (abfd, &elfsym->sym,
 			       (outbound_syms
@@ -7375,17 +7395,6 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
     }
   free (symstrtab);
 
-  *sttp = stt;
-  symstrtab_hdr->sh_size = _bfd_elf_strtab_size (stt);
-  symstrtab_hdr->sh_type = SHT_STRTAB;
-
-  symstrtab_hdr->sh_flags = 0;
-  symstrtab_hdr->sh_addr = 0;
-  symstrtab_hdr->sh_entsize = 0;
-  symstrtab_hdr->sh_link = 0;
-  symstrtab_hdr->sh_info = 0;
-  symstrtab_hdr->sh_addralign = 1;
-
   return TRUE;
 }
 
@@ -8144,6 +8153,11 @@ _bfd_elf_set_section_contents (bfd *abfd,
     return TRUE;
 
   hdr = &elf_section_data (section)->this_hdr;
+
+  /* Group sections are handled in _bfd_elf_write_object_contents.  */
+  if (hdr->sh_type == SHT_GROUP)
+    return TRUE;
+
   if (hdr->sh_offset == (file_ptr) -1)
     {
       /* We must compress this section.  Write output to the buffer.  */
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1c0861b..f5377e8 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -7443,8 +7443,6 @@ struct elf_final_link_info
   struct bfd_link_info *info;
   /* Output BFD.  */
   bfd *output_bfd;
-  /* Symbol string table.  */
-  struct elf_strtab_hash *symstrtab;
   /* .dynsym section.  */
   asection *dynsym_sec;
   /* .hash section.  */
@@ -8598,8 +8596,8 @@ elf_link_output_symstrtab (struct elf_final_link_info *flinfo,
       /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
 	 to get the final offset for st_name.  */
       elfsym->st_name
-	= (unsigned long) _bfd_elf_strtab_add (flinfo->symstrtab,
-					       name, FALSE);
+	= (unsigned long) _bfd_elf_strtab_add
+	    (elf_shstrtab (flinfo->output_bfd), name, FALSE);
       if (elfsym->st_name == (unsigned long) -1)
 	return 0;
     }
@@ -8674,8 +8672,8 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo)
 	elfsym->sym.st_name = 0;
       else
 	elfsym->sym.st_name
-	  = (unsigned long) _bfd_elf_strtab_offset (flinfo->symstrtab,
-						    elfsym->sym.st_name);
+	  = (unsigned long) _bfd_elf_strtab_offset
+	      (elf_shstrtab (flinfo->output_bfd), elfsym->sym.st_name);
       bed->s->swap_symbol_out (flinfo->output_bfd, &elfsym->sym,
 			       ((bfd_byte *) symbuf
 				+ (elfsym->dest_index
@@ -10673,8 +10671,6 @@ elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo)
 {
   asection *o;
 
-  if (flinfo->symstrtab != NULL)
-    _bfd_elf_strtab_free (flinfo->symstrtab);
   if (flinfo->contents != NULL)
     free (flinfo->contents);
   if (flinfo->external_relocs != NULL)
@@ -10748,9 +10744,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
   flinfo.info = info;
   flinfo.output_bfd = abfd;
-  flinfo.symstrtab = _bfd_elf_strtab_init ();
-  if (flinfo.symstrtab == NULL)
-    return FALSE;
 
   if (! dynamic)
     {
@@ -10976,7 +10969,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       esdo->rel.count = 0;
       esdo->rela.count = 0;
 
-      if (esdo->this_hdr.sh_offset == (file_ptr) -1)
+      if (esdo->this_hdr.sh_type == SHT_GROUP)
+	/* Inform _bfd_elf_write_object_contents that there are group
+	   sections.  */
+	abfd->handle_group_sections = 1;
+      else if (esdo->this_hdr.sh_offset == (file_ptr) -1)
 	{
 	  /* Cache the section contents so that they can be compressed
 	     later.  Use bfd_malloc since it will be freed by
@@ -11397,21 +11394,35 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	return FALSE;
     }
 
-  /* Finalize the .strtab section.  */
-  _bfd_elf_strtab_finalize (flinfo.symstrtab);
-
-  /* Swap out the .strtab section. */
-  if (!elf_link_swap_symbols_out (&flinfo))
-    return FALSE;
-
-  /* Now we know the size of the symtab section.  */
   if (bfd_get_symcount (abfd) > 0)
     {
-      /* Finish up and write out the symbol string table (.strtab)
-	 section.  */
-      Elf_Internal_Shdr *symstrtab_hdr;
-      file_ptr off = symtab_hdr->sh_offset + symtab_hdr->sh_size;
+      bfd_size_type symtab_size;
+      file_ptr off;
+
+      /* This mush match the size of the symtab section written out by
+	 elf_link_swap_symbols_out.  */
+      symtab_size = bfd_get_symcount (abfd) * bed->s->sizeof_sym;
+
+      off = symtab_hdr->sh_offset + symtab_size;
+      elf_next_file_pos (abfd) = off;
+
+      /* Finalize the .strtab section.  */
+      if (!_bfd_elf_assign_file_positions_for_debug_and_strtab (abfd))
+	return FALSE;
+
+      off = elf_next_file_pos (abfd);
+
+      /* Swap out the .strtab section.  */
+      if (!elf_link_swap_symbols_out (&flinfo))
+	return FALSE;
 
+      /* Verify that the size of the symtab section written out by
+	 elf_link_swap_symbols_out matches STMTAB_SIZE.  */
+      if (symtab_size != symtab_hdr->sh_size)
+	abort ();
+
+      /* Finish up and write out the symbol table section index
+	 (.symtab_shndx) section.  */
       symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
       if (symtab_shndx_hdr->sh_name != 0)
 	{
@@ -11423,31 +11434,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
 	  off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
 							   off, TRUE);
+	  elf_next_file_pos (abfd) = off;
 
 	  if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
 	      || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt))
 	    return FALSE;
 	}
-
-      symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
-      /* sh_name was set in prep_headers.  */
-      symstrtab_hdr->sh_type = SHT_STRTAB;
-      symstrtab_hdr->sh_flags = 0;
-      symstrtab_hdr->sh_addr = 0;
-      symstrtab_hdr->sh_size = _bfd_elf_strtab_size (flinfo.symstrtab);
-      symstrtab_hdr->sh_entsize = 0;
-      symstrtab_hdr->sh_link = 0;
-      symstrtab_hdr->sh_info = 0;
-      /* sh_offset is set just below.  */
-      symstrtab_hdr->sh_addralign = 1;
-
-      off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr,
-						       off, TRUE);
-      elf_next_file_pos (abfd) = off;
-
-      if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
-	  || ! _bfd_elf_strtab_emit (abfd, flinfo.symstrtab))
-	return FALSE;
     }
 
   /* Adjust the relocs to have the correct symbol indices.  */
@@ -11720,15 +11712,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	}
     }
 
-  if (info->relocatable)
-    {
-      bfd_boolean failed = FALSE;
-
-      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
-      if (failed)
-	goto error_return;
-    }
-
   /* If we have optimized stabs strings, output them.  */
   if (elf_hash_table (info)->stab_info.stabstr != NULL)
     {
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]