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_28-branch] MIPS/BFD: Respect the ELF gABI dynamic symbol table sort requirement


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

commit e7ec0c47c5500b572b847cddd5b0868ef3784473
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Thu Feb 2 22:05:46 2017 +0000

    MIPS/BFD: Respect the ELF gABI dynamic symbol table sort requirement
    
    Ensure all local symbols precede external symbols in the dynamic symbol
    table.
    
    No local symbols are expected to make it to the dynamic symbol table
    except for section symbols already taken care of, so this is really a
    safeguard only against a potential BFD bug otherwise not so harmful,
    which may become a grave one due to a symbol table sorting requirement
    violation (see PR ld/20828 for an example).  This means however that no
    test suite coverage is possible for this change as code introduced here
    is not normally expected to trigger.
    
    Logically split then the part of the dynamic symbol table which is not
    global offset table mapped, into a local area at the beginning and an
    external area following.  By the time `mips_elf_sort_hash_table' is
    called we have the number of local dynamic symbol table entries (section
    and non-section) already counted in `local_dynsymcount', so use it to
    offset the external area from the beginning.
    
    	bfd/
    	* elfxx-mips.c (mips_elf_hash_sort_data): Add
    	`max_local_dynindx'.
    	(mips_elf_sort_hash_table): Handle it.
    	(mips_elf_sort_hash_table_f) <GGA_NONE>: For forced local
    	symbols bump up `max_local_dynindx' rather than
    	`max_non_got_dynindx'.
    
    (cherry picked from commit e17b0c351f0b22fb42edf34e5a6e486d72e9ee05)

Diff:
---
 bfd/ChangeLog    |  9 +++++++++
 bfd/elfxx-mips.c | 16 +++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3f972d2..8ceba71 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
 2017-02-13  Maciej W. Rozycki  <macro@imgtec.com>
 
+	* elfxx-mips.c (mips_elf_hash_sort_data): Add
+	`max_local_dynindx'.
+	(mips_elf_sort_hash_table): Handle it.
+	(mips_elf_sort_hash_table_f) <GGA_NONE>: For forced local
+	symbols bump up `max_local_dynindx' rather than
+	`max_non_got_dynindx'.
+
+2017-02-13  Maciej W. Rozycki  <macro@imgtec.com>
+
 	* elfxx-mips.c (mips_elf_hash_sort_data): Convert the
 	`min_got_dynindx', `max_unref_got_dynindx' and
 	`max_non_got_dynindx' members to the `bfd_size_type' data type.
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 1b93a95..c184d2e 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -315,7 +315,10 @@ struct mips_elf_hash_sort_data
      with a GOT entry that is not referenced (e.g., a dynamic symbol
      with dynamic relocations pointing to it from non-primary GOTs).  */
   bfd_size_type max_unref_got_dynindx;
-  /* The greatest dynamic symbol table index not corresponding to a
+  /* The greatest dynamic symbol table index corresponding to a local
+     symbol.  */
+  bfd_size_type max_local_dynindx;
+  /* The greatest dynamic symbol table index corresponding to an external
      symbol without a GOT entry.  */
   bfd_size_type max_non_got_dynindx;
 };
@@ -3846,11 +3849,15 @@ mips_elf_sort_hash_table (bfd *abfd, struct bfd_link_info *info)
   hsd.max_unref_got_dynindx
     = hsd.min_got_dynindx
     = (htab->root.dynsymcount - g->reloc_only_gotno);
-  hsd.max_non_got_dynindx = count_section_dynsyms (abfd, info) + 1;
+  /* Add 1 to local symbol indices to account for the mandatory NULL entry
+     at the head of the table; see `_bfd_elf_link_renumber_dynsyms'.  */
+  hsd.max_local_dynindx = count_section_dynsyms (abfd, info) + 1;
+  hsd.max_non_got_dynindx = htab->root.local_dynsymcount + 1;
   mips_elf_link_hash_traverse (htab, mips_elf_sort_hash_table_f, &hsd);
 
   /* There should have been enough room in the symbol table to
      accommodate both the GOT and non-GOT symbols.  */
+  BFD_ASSERT (hsd.max_local_dynindx <= htab->root.local_dynsymcount + 1);
   BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
   BFD_ASSERT (hsd.max_unref_got_dynindx == htab->root.dynsymcount);
   BFD_ASSERT (htab->root.dynsymcount - hsd.min_got_dynindx == g->global_gotno);
@@ -3879,7 +3886,10 @@ mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
   switch (h->global_got_area)
     {
     case GGA_NONE:
-      h->root.dynindx = hsd->max_non_got_dynindx++;
+      if (h->root.forced_local)
+	h->root.dynindx = hsd->max_local_dynindx++;
+      else
+	h->root.dynindx = hsd->max_non_got_dynindx++;
       break;
 
     case GGA_NORMAL:


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