This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFC [PATCH] Use .strtab section for section name strings
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Sat, 27 Jun 2015 17:00:35 -0700
- Subject: RFC [PATCH] Use .strtab section for section name strings
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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