From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9772 invoked by alias); 9 Feb 2011 08:20:47 -0000 Received: (qmail 9762 invoked by uid 22791); 9 Feb 2011 08:20:45 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,TW_BJ,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-pw0-f41.google.com (HELO mail-pw0-f41.google.com) (209.85.160.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 09 Feb 2011 08:20:40 +0000 Received: by pwj8 with SMTP id 8so118858pwj.0 for ; Wed, 09 Feb 2011 00:20:38 -0800 (PST) Received: by 10.142.216.1 with SMTP id o1mr18074416wfg.419.1297239638517; Wed, 09 Feb 2011 00:20:38 -0800 (PST) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id b11sm56278wff.21.2011.02.09.00.20.35 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 09 Feb 2011 00:20:37 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 6E7ED16DE62A; Wed, 9 Feb 2011 18:50:28 +1030 (CST) Date: Wed, 09 Feb 2011 08:20:00 -0000 From: Alan Modra To: binutils@sourceware.org Subject: Re: PowerPC64 toc edit segfault Message-ID: <20110209082028.GA7651@bubble.grove.modra.org> Mail-Followup-To: binutils@sourceware.org References: <20110208030151.GM9489@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110208030151.GM9489@bubble.grove.modra.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes 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 X-SW-Source: 2011-02/txt/msg00082.txt.bz2 This fixes two segfaults in ppc64_elf_edit_toc, found when simply running the binutils testsuite using an -mcmodel=medium ppc64 compiler. Embarrassing. My binutils testsuite runs weren't using a new bleeding edge compiler as I thought, but the old 4.4.1 system compiler. Also fixes a number of ld tests that fail/xpass with a new ppc64 gcc. I'm disabling the non-PIC visibility tests entirely for powerpc*-linux. See the comment for why. Applied mainline and 2.21 branch. bfd/ * elf64-ppc.c (ppc64_elf_edit_toc): Don't free toc relocs until we are done. When optimising large toc, check that a global symbol on a toc reloc is defined in a kept section. ld/testsuite/ * ld-elfvsb/elfvsb.exp: Don't run any non-PIC tests on powerpc*-linux. * ld-gc/gc.exp: Ensure powerpc64 test continues to fail. * ld-srec/srec.exp: Don't edit toc on powerpc64. Index: bfd/elf64-ppc.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-ppc.c,v retrieving revision 1.341 diff -u -p -r1.341 elf64-ppc.c --- bfd/elf64-ppc.c 8 Feb 2011 02:54:42 -0000 1.341 +++ bfd/elf64-ppc.c 9 Feb 2011 06:52:20 -0000 @@ -7907,7 +7908,7 @@ ppc64_elf_edit_toc (struct bfd_link_info asection *toc, *sec; Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Sym *local_syms; - Elf_Internal_Rela *relstart, *rel; + Elf_Internal_Rela *relstart, *rel, *toc_relocs; unsigned long *skip, *drop; unsigned char *used; unsigned char *keep, last, some_unused; @@ -7922,6 +7923,7 @@ ppc64_elf_edit_toc (struct bfd_link_info || elf_discarded_section (toc)) continue; + toc_relocs = NULL; local_syms = NULL; symtab_hdr = &elf_symtab_hdr (ibfd); @@ -8017,12 +8019,12 @@ ppc64_elf_edit_toc (struct bfd_link_info && toc->reloc_count != 0) { /* Read toc relocs. */ - relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL, - info->keep_memory); - if (relstart == NULL) + toc_relocs = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL, + info->keep_memory); + if (toc_relocs == NULL) goto error_ret; - for (rel = relstart; rel < relstart + toc->reloc_count; ++rel) + for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel) { enum elf_ppc64_reloc_type r_type; unsigned long r_symndx; @@ -8040,6 +8042,10 @@ ppc64_elf_edit_toc (struct bfd_link_info r_symndx, ibfd)) goto error_ret; + if (sym_sec == NULL + || elf_discarded_section (sym_sec)) + continue; + if (!SYMBOL_CALLS_LOCAL (info, h)) continue; @@ -8078,11 +8084,8 @@ ppc64_elf_edit_toc (struct bfd_link_info } skip[rel->r_offset >> 3] - |= can_optimize | ((rel - relstart) << 2); + |= can_optimize | ((rel - toc_relocs) << 2); } - - if (elf_section_data (toc)->relocs != relstart) - free (relstart); } if (skip == NULL) @@ -8099,6 +8102,9 @@ ppc64_elf_edit_toc (struct bfd_link_info && relstart != NULL && elf_section_data (sec)->relocs != relstart) free (relstart); + if (toc_relocs != NULL + && elf_section_data (toc)->relocs != toc_relocs) + free (toc_relocs); if (skip != NULL) free (skip); return FALSE; @@ -8338,7 +8344,7 @@ ppc64_elf_edit_toc (struct bfd_link_info else if ((skip[val >> 3] & can_optimize) != 0) { Elf_Internal_Rela *tocrel - = elf_section_data (toc)->relocs + (skip[val >> 3] >> 2); + = toc_relocs + (skip[val >> 3] >> 2); unsigned long tsym = ELF64_R_SYM (tocrel->r_info); switch (r_type) @@ -8418,15 +8424,9 @@ ppc64_elf_edit_toc (struct bfd_link_info Elf_Internal_Rela *wrel; bfd_size_type sz; - /* Read toc relocs. */ - relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL, - TRUE); - if (relstart == NULL) - goto error_ret; - /* Remove unused toc relocs, and adjust those we keep. */ - wrel = relstart; - for (rel = relstart; rel < relstart + toc->reloc_count; ++rel) + wrel = toc_relocs; + for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel) if ((skip[rel->r_offset >> 3] & (ref_from_discarded | can_optimize)) == 0) { @@ -8439,12 +8439,15 @@ ppc64_elf_edit_toc (struct bfd_link_info &local_syms, NULL, NULL)) goto error_ret; - toc->reloc_count = wrel - relstart; + elf_section_data (toc)->relocs = toc_relocs; + toc->reloc_count = wrel - toc_relocs; rel_hdr = _bfd_elf_single_rel_hdr (toc); sz = rel_hdr->sh_entsize; rel_hdr->sh_size = toc->reloc_count * sz; } } + else if (elf_section_data (toc)->relocs != toc_relocs) + free (toc_relocs); if (local_syms != NULL && symtab_hdr->contents != (unsigned char *) local_syms) Index: ld/testsuite/ld-elfvsb/elfvsb.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-elfvsb/elfvsb.exp,v retrieving revision 1.34 diff -u -p -r1.34 elfvsb.exp --- ld/testsuite/ld-elfvsb/elfvsb.exp 8 Nov 2010 06:43:37 -0000 1.34 +++ ld/testsuite/ld-elfvsb/elfvsb.exp 9 Feb 2011 07:54:30 -0000 @@ -249,6 +249,14 @@ proc visibility_run {visibility} { set VSBCFLAG "" }}}}}}}}} + if { [istarget powerpc*-*-linux*] } { + # Testing non-PIC libraries is a waste of effort on any target. + # If you don't pass -fpic or -fPIC to gcc, gcc will assume quite + # reasonably that you are not compiling for a shared library. + # It can then make optimisations that result in shared library + # functions and variables not being overridable. Newer versions + # of gcc are more likely to do this. + } else { # Compile the main program. if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] { unresolved "visibility ($visibility) (non PIC)" @@ -369,8 +377,11 @@ proc visibility_run {visibility} { visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o elfvsb } } } - } + }} + if { [istarget powerpc*-*-linux*] } { + # Don't bother. + } else { # Now do the same tests again, but this time compile main.c PIC. if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG -DSHARED $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] { unresolved "visibility ($visibility) (PIC main, non PIC so)" @@ -433,7 +444,7 @@ proc visibility_run {visibility} { } else { unresolved "visibility ($visibility) (PIC main)" } - } + }} } if [istarget mips*-*-*] { Index: ld/testsuite/ld-gc/gc.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-gc/gc.exp,v retrieving revision 1.10 diff -u -p -r1.10 gc.exp --- ld/testsuite/ld-gc/gc.exp 8 Nov 2010 06:43:37 -0000 1.10 +++ ld/testsuite/ld-gc/gc.exp 9 Feb 2011 07:54:30 -0000 @@ -27,6 +27,11 @@ if ![check_gc_sections_available] { set cflags "-ffunction-sections -fdata-sections" set objfile "tmpdir/gc.o" +if [istarget powerpc64*-*-*] { + # otherwise with -mcmodel=medium gcc we get XPASSes. + set cflags "$cflags -mminimal-toc" +} + if { [is_remote host] || [which $CC] != 0 } { ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/gc.c $objfile } Index: ld/testsuite/ld-srec/srec.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-srec/srec.exp,v retrieving revision 1.33 diff -u -p -r1.33 srec.exp --- ld/testsuite/ld-srec/srec.exp 1 Oct 2009 23:29:28 -0000 1.33 +++ ld/testsuite/ld-srec/srec.exp 9 Feb 2011 07:54:31 -0000 @@ -271,6 +271,10 @@ proc run_srec_test { test objs } { set flags "$flags -no-relax" } + if [istarget powerpc64*-*-*] { + set flags "$flags --no-toc-optimize" + } + if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \ || ![ld_simple_link $ld tmpdir/sr2.sr "$flags --oformat srec $objs"] } { fail $test -- Alan Modra Australia Development Lab, IBM