From 63f452a8bfd9c89b56dcc087cea84151e7a9ec24 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 18 Dec 2017 22:27:08 +1030 Subject: [PATCH] PR22626, invalid dynindx used for dynamic relocs against section syms _bfd_elf_link_renumber_dynsyms is called twice by the linker. The first call in bfd_elf_size_dynamic_sections is just to answer the question as to whether there are there any dynamic symbols. The second call in bfd_elf_size_dynsym_hash_dynstr sets the st_shndx value that dynamic symbols will have. strip_excluded_output_sections is called between these two calls. So sections seen on the first _bfd_elf_link_renumber_dynsyms pass might differ from those seen on the second pass. Unfortunately, that can result in a stripped section's dynamic symbol being assigned a dynindx on the first pass but not corrected to the final value (of zero, ie. not dynamic) on the second pass. PowerPC, x86, mips, and most other targets that emit dynamic section symbols, just test that section symbol dynindx is non-zero before using a given section symbol in dynamic relocations. This patch prevents _bfd_elf_link_renumber_dynsyms from setting any section symbol dynindx on the first pass. PR 22626 * elflink.c (_bfd_elf_link_renumber_dynsyms): Don't set section dynindx when section_sym_count is NULL. (bfd_elf_size_dynamic_sections): Pass NULL section_sym_count to preliminary _bfd_elf_link_renumber_dynsyms call. --- bfd/ChangeLog | 8 ++++++++ bfd/elflink.c | 22 ++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4d4b10f278a..e994da3ed6d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2017-12-19 Alan Modra + + PR 22626 + * elflink.c (_bfd_elf_link_renumber_dynsyms): Don't set section + dynindx when section_sym_count is NULL. + (bfd_elf_size_dynamic_sections): Pass NULL section_sym_count to + preliminary _bfd_elf_link_renumber_dynsyms call. + 2017-12-15 Nick Clifton PR 22571 diff --git a/bfd/elflink.c b/bfd/elflink.c index b9597cb6e14..b3cbbbb8a62 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -917,7 +917,10 @@ _bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, symbol for each output section, which come first. Next come symbols which have been forced to local binding. Then all of the back-end allocated local dynamic syms, followed by the rest of the global - symbols. */ + symbols. If SECTION_SYM_COUNT is NULL, section dynindx is not set. + (This prevents the early call before elf_backend_init_index_section + and strip_excluded_output_sections setting dynindx for sections + that are stripped.) */ static unsigned long _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, @@ -925,6 +928,7 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, unsigned long *section_sym_count) { unsigned long dynsymcount = 0; + bfd_boolean do_sec = section_sym_count != NULL; if (bfd_link_pic (info) || elf_hash_table (info)->is_relocatable_executable) @@ -935,11 +939,16 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, if ((p->flags & SEC_EXCLUDE) == 0 && (p->flags & SEC_ALLOC) != 0 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) - elf_section_data (p)->dynindx = ++dynsymcount; - else + { + ++dynsymcount; + if (do_sec) + elf_section_data (p)->dynindx = dynsymcount; + } + else if (do_sec) elf_section_data (p)->dynindx = 0; } - *section_sym_count = dynsymcount; + if (do_sec) + *section_sym_count = dynsymcount; elf_link_hash_traverse (elf_hash_table (info), elf_link_renumber_local_hash_table_dynsyms, @@ -6831,8 +6840,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) { - unsigned long section_sym_count; - if (elf_tdata (output_bfd)->cverdefs) { unsigned int crefs = elf_tdata (output_bfd)->cverdefs; @@ -6874,8 +6881,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if ((elf_tdata (output_bfd)->cverrefs == 0 && elf_tdata (output_bfd)->cverdefs == 0) - || _bfd_elf_link_renumber_dynsyms (output_bfd, info, - §ion_sym_count) <= 1) + || _bfd_elf_link_renumber_dynsyms (output_bfd, info, NULL) <= 1) { asection *s; -- 2.30.2