From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4596 invoked by alias); 6 Jul 2006 23:28:06 -0000 Received: (qmail 4580 invoked by uid 22791); 6 Jul 2006 23:28:04 -0000 X-Spam-Check-By: sourceware.org Received: from smtp113.sbc.mail.mud.yahoo.com (HELO smtp113.sbc.mail.mud.yahoo.com) (68.142.198.212) by sourceware.org (qpsmtpd/0.31) with SMTP; Thu, 06 Jul 2006 23:27:59 +0000 Received: (qmail 67064 invoked from network); 6 Jul 2006 23:27:57 -0000 Received: from unknown (HELO lucon.org) (hjjean@sbcglobal.net@71.146.67.96 with login) by smtp113.sbc.mail.mud.yahoo.com with SMTP; 6 Jul 2006 23:27:57 -0000 Received: by lucon.org (Postfix, from userid 1000) id 5BD4563EEC; Thu, 6 Jul 2006 16:27:56 -0700 (PDT) Date: Thu, 06 Jul 2006 23:28:00 -0000 From: "H. J. Lu" To: binutils@sources.redhat.com Subject: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section Message-ID: <20060706232756.GA20456@lucon.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00064.txt.bz2 The problem is when linker sees a reference and then a versioned dynamic definition, it calls elf_backend_copy_indirect_symbol to copy the symbol info to the versioned dynamic definition. When linker sees a normal definition with non-default visibility, it removes the old dynamic definition without saving the symbol info copied over previously. This patch copies the symbol info from the old versioned dynamic definition to the new one with non-default visibility. H.J. --- 2006-07-06 H.J. Lu PR ld/2884 * elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for hidden and internal visibility. Copy the symbol info from the old versioned dynamic definition to the new one with non-default visibility. --- bfd/elflink.c.foo 2006-07-05 11:50:35.000000000 -0700 +++ bfd/elflink.c 2006-07-06 16:23:17.000000000 -0700 @@ -988,16 +988,20 @@ _bfd_elf_merge_symbol (bfd *abfd, && !bfd_is_und_section (sec)) { *skip = TRUE; - /* Make sure this symbol is dynamic. */ - h->ref_dynamic = 1; /* A protected symbol has external availability. Make sure it is recorded as dynamic. FIXME: Should we check type and size for protected symbol? */ if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) - return bfd_elf_link_record_dynamic_symbol (info, h); + { + h->ref_dynamic = 1; + return bfd_elf_link_record_dynamic_symbol (info, h); + } else - return TRUE; + { + h->ref_dynamic = 0; + return TRUE; + } } else if (!newdyn && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT @@ -1007,7 +1011,25 @@ _bfd_elf_merge_symbol (bfd *abfd, relocatable file and the old definition comes from a dynamic object, we remove the old definition. */ if ((*sym_hash)->root.type == bfd_link_hash_indirect) - h = *sym_hash; + { + /* Handle the case where the old dynamic definition is + versioned. We need to copy the symbol info from the + versioned symbol to the normal one if it is referenced + before. */ + if (h->ref_regular) + { + const struct elf_backend_data *bed + = get_elf_backend_data (abfd); + struct elf_link_hash_entry *vh = *sym_hash; + vh->root.type = h->root.type; + h->root.type = bfd_link_hash_indirect; + (*bed->elf_backend_copy_indirect_symbol) (info, vh, h); + h->root.type = vh->root.type; + h = vh; + } + else + h = *sym_hash; + } if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root) && bfd_is_und_section (sec)) @@ -1030,9 +1052,14 @@ _bfd_elf_merge_symbol (bfd *abfd, if (h->def_dynamic) { h->def_dynamic = 0; - h->ref_dynamic = 1; + /* Hidden and internal symbols aren't available outside. */ + if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED) + h->ref_dynamic = 1; + else + h->ref_dynamic = 0; h->dynamic_def = 1; } + /* FIXME: Should we check type and size for protected symbol? */ h->size = 0; h->type = 0;