diff options
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 16 |
2 files changed, 22 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c351eb1..bbd1200 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,14 @@ 2017-02-02 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-02 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: |