This is the mail archive of the binutils-cvs@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]

[binutils-gdb/binutils-2_29-branch] PR22626, invalid dynindx used for dynamic relocs against section syms


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4207f3a916969991e9c19a6e27ba504d9e42da6e

commit 4207f3a916969991e9c19a6e27ba504d9e42da6e
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Dec 18 22:27:08 2017 +1030

    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.
    
    (cherry picked from commit 63f452a8bfd9c89b56dcc087cea84151e7a9ec24)

Diff:
---
 bfd/ChangeLog |  8 ++++++++
 bfd/elflink.c | 22 ++++++++++++++--------
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c8bcf8e..874f08d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-19  Alan Modra  <amodra@gmail.com>
+
+	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-11-24  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9e0c1bb..8421777 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -915,7 +915,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,
@@ -923,6 +926,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)
@@ -933,11 +937,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,
@@ -6740,8 +6749,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;
@@ -6783,8 +6790,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,
-					     &section_sym_count) <= 1)
+	  || _bfd_elf_link_renumber_dynsyms (output_bfd, info, NULL) <= 1)
 	{
 	  asection *s;


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