aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-01-15 19:42:59 +1030
committerAlan Modra <amodra@gmail.com>2015-01-15 19:58:31 +1030
commit8539e4e89eb4c54bb6668582cd709765a3803588 (patch)
tree72e0a4e1e768ea02f057f60f7be427bbe0984464 /bfd
parentbafffb51c4da50881dc5d72ec9bf9b78377ac692 (diff)
downloadgdb-8539e4e89eb4c54bb6668582cd709765a3803588.zip
gdb-8539e4e89eb4c54bb6668582cd709765a3803588.tar.gz
gdb-8539e4e89eb4c54bb6668582cd709765a3803588.tar.bz2
Fix ARM fail of gap test
ld-elf/gap test was failing due to the ARM backend attempting to output arch symbols when ld -s (strip all symbols) is in force. This patch stops that happening and tidies the code a little. PR 17842 * elflink.c (elf_link_output_sym): Assert elf_onesymtab set. (bfd_elf_final_link): Always create a symbol table when emit_relocs. Don't assign symtab file position unless symbols will be output. Merge blocks with condition in common. Don't call elf_backend_output_arch_local_syms or elf_backend_output_arch_syms unless other symbols are output. Move assignment of symtab_shndx file position. Localize variable.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elflink.c88
2 files changed, 55 insertions, 44 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0e83f2e..7dbb299 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2015-01-15 Alan Modra <amodra@gmail.com>
+
+ PR 17842
+ * elflink.c (elf_link_output_sym): Assert elf_onesymtab set.
+ (bfd_elf_final_link): Always create a symbol table when emit_relocs.
+ Don't assign symtab file position unless symbols will be output.
+ Merge blocks with condition in common. Don't call
+ elf_backend_output_arch_local_syms or elf_backend_output_arch_syms
+ unless other symbols are output. Move assignment of symtab_shndx
+ file position. Localize variable.
+
2015-01-14 Jiong Wang <jiong.wang@arm.com>
* elf32-arm.c (elf32_arm_final_link_relocate): Reject R_ARM_32/_NOI when
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 73d2360..4378bb2 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8568,6 +8568,8 @@ elf_link_output_sym (struct elf_final_link_info *flinfo,
struct elf_link_hash_entry *);
const struct elf_backend_data *bed;
+ BFD_ASSERT (elf_onesymtab (flinfo->output_bfd));
+
bed = get_elf_backend_data (flinfo->output_bfd);
output_symbol_hook = bed->elf_backend_link_output_symbol_hook;
if (output_symbol_hook != NULL)
@@ -10609,7 +10611,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
bfd_size_type max_internal_reloc_count;
bfd_size_type max_sym_count;
bfd_size_type max_sym_shndx_count;
- file_ptr off;
Elf_Internal_Sym elfsym;
unsigned int i;
Elf_Internal_Shdr *symtab_hdr;
@@ -10844,7 +10845,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* Figure out the file positions for everything but the symbol table
and the relocs. We set symcount to force assign_section_numbers
to create a symbol table. */
- bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1;
+ bfd_get_symcount (abfd) = info->strip != strip_all || emit_relocs;
BFD_ASSERT (! abfd->output_has_begun);
if (! _bfd_elf_compute_section_file_positions (abfd, info))
goto error_return;
@@ -10885,13 +10886,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* sh_offset is set just below. */
symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
- off = elf_next_file_pos (abfd);
- off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
-
- /* Note that at this point elf_next_file_pos (abfd) is
- incorrect. We do not yet know the size of the .symtab section.
- We correct next_file_pos below, after we do know the size. */
-
/* Allocate a buffer to hold swapped out symbols. This is to avoid
continuously seeking to the right position in the file. */
if (! info->keep_memory || max_sym_count < 20)
@@ -10914,11 +10908,18 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
goto error_return;
}
- /* Start writing out the symbol table. The first symbol is always a
- dummy symbol. */
- if (info->strip != strip_all
- || emit_relocs)
+ if (info->strip != strip_all || emit_relocs)
{
+ file_ptr off = elf_next_file_pos (abfd);
+
+ _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
+
+ /* Note that at this point elf_next_file_pos (abfd) is
+ incorrect. We do not yet know the size of the .symtab section.
+ We correct next_file_pos below, after we do know the size. */
+
+ /* Start writing out the symbol table. The first symbol is always a
+ dummy symbol. */
elfsym.st_value = 0;
elfsym.st_size = 0;
elfsym.st_info = 0;
@@ -10928,16 +10929,13 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
if (elf_link_output_sym (&flinfo, NULL, &elfsym, bfd_und_section_ptr,
NULL) != 1)
goto error_return;
- }
- /* Output a symbol for each section. We output these even if we are
- discarding local symbols, since they are used for relocs. These
- symbols have no names. We store the index of each one in the
- index field of the section, so that we can find it again when
- outputting relocs. */
- if (info->strip != strip_all
- || emit_relocs)
- {
+ /* Output a symbol for each section. We output these even if we are
+ discarding local symbols, since they are used for relocs. These
+ symbols have no names. We store the index of each one in the
+ index field of the section, so that we can find it again when
+ outputting relocs. */
+
elfsym.st_size = 0;
elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
elfsym.st_other = 0;
@@ -11168,7 +11166,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* If backend needs to output some local symbols not present in the hash
table, do it now. */
- if (bed->elf_backend_output_arch_local_syms)
+ if (bed->elf_backend_output_arch_local_syms
+ && (info->strip != strip_all || emit_relocs))
{
typedef int (*out_sym_func)
(void *, const char *, Elf_Internal_Sym *, asection *,
@@ -11278,7 +11277,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* If backend needs to output some symbols not present in the hash
table, do it now. */
- if (bed->elf_backend_output_arch_syms)
+ if (bed->elf_backend_output_arch_syms
+ && (info->strip != strip_all || emit_relocs))
{
typedef int (*out_sym_func)
(void *, const char *, Elf_Internal_Sym *, asection *,
@@ -11294,31 +11294,29 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
return FALSE;
/* Now we know the size of the symtab section. */
- off += symtab_hdr->sh_size;
-
- symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- if (symtab_shndx_hdr->sh_name != 0)
- {
- symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
- symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
- symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
- amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
- symtab_shndx_hdr->sh_size = amt;
-
- off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
- off, TRUE);
-
- if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
- || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt))
- return FALSE;
- }
-
-
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;
+
+ symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (symtab_shndx_hdr->sh_name != 0)
+ {
+ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+ amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_size = amt;
+
+ off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
+ off, TRUE);
+
+ 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. */
@@ -11600,6 +11598,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
{
/* The contents of the .dynstr section are actually in a
stringtab. */
+ file_ptr off;
+
off = elf_section_data (o->output_section)->this_hdr.sh_offset;
if (bfd_seek (abfd, off, SEEK_SET) != 0
|| ! _bfd_elf_strtab_emit (abfd,