From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 60313 invoked by alias); 2 Feb 2017 23:05:11 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 60303 invoked by uid 89); 2 Feb 2017 23:05:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=grave, sk:_bfd_el, Respect, 3157 X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 02 Feb 2017 23:05:09 +0000 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Forcepoint Email with ESMTPS id D5645637284C3 for ; Thu, 2 Feb 2017 23:05:01 +0000 (GMT) Received: from [10.20.78.60] (10.20.78.60) by hhmail02.hh.imgtec.org (10.100.10.21) with Microsoft SMTP Server id 14.3.294.0; Thu, 2 Feb 2017 23:05:05 +0000 Date: Thu, 02 Feb 2017 23:05:00 -0000 From: "Maciej W. Rozycki" To: CC: James Cowgill Subject: [committed] MIPS/BFD: Respect the ELF gABI dynamic symbol table sort requirement Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" X-SW-Source: 2017-02/txt/msg00025.txt.bz2 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) : For forced local symbols bump up `max_local_dynindx' rather than `max_non_got_dynindx'. --- binutils-mips-bfd-dynsym-sort.diff Index: binutils/bfd/elfxx-mips.c =================================================================== --- binutils.orig/bfd/elfxx-mips.c 2017-02-02 00:56:37.742249694 +0000 +++ binutils/bfd/elfxx-mips.c 2017-02-02 00:56:42.271630635 +0000 @@ -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, str 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_ 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: