From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30149 invoked by alias); 31 Jan 2011 22:51:04 -0000 Received: (qmail 30127 invoked by uid 22791); 31 Jan 2011 22:51:01 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-iw0-f169.google.com (HELO mail-iw0-f169.google.com) (209.85.214.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 31 Jan 2011 22:47:38 +0000 Received: by iwn40 with SMTP id 40so7033600iwn.0 for ; Mon, 31 Jan 2011 14:47:36 -0800 (PST) Received: by 10.42.221.10 with SMTP id ia10mr8698533icb.100.1296514056416; Mon, 31 Jan 2011 14:47:36 -0800 (PST) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id d13sm10812083ice.16.2011.01.31.14.47.34 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 31 Jan 2011 14:47:35 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 8FAA0170C275; Tue, 1 Feb 2011 09:17:30 +1030 (CST) Date: Mon, 31 Jan 2011 22:51:00 -0000 From: Alan Modra To: binutils@sourceware.org Subject: powerpc64 ld "sibling call" error Message-ID: <20110131224730.GN9489@bubble.grove.modra.org> Mail-Followup-To: binutils@sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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-01/txt/msg00403.txt.bz2 This patch fixes an error seen when compiling current gcc for powerpc64, using -mcmodel=small -mno-minimal-toc. A typical error looks like: libbackend.a(cse.o)(.text.unlikely+0x60): sibling call optimization to `.opd' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `.opd' extern The error is quite confusing since the calls involved aren't sibling calls, and the proper function name isn't given for a local function. I haven't fixed the error message because ld shouldn't be getting there anyway.. What's really happening is that we have a local function call from one section to another section in the same object file, with the two sections being assigned different toc groups. The first section doesn't actually use the toc; ld erroneously decided it could belong to any toc group, but that isn't true for a section that makes local calls. Committed mainline and 2.21 branch. * elf64-ppc.c (ppc64_elf_next_input_section): Use elf_gp value for toc pointer on any section having makes_toc_func_call set. (check_pasted_section): Ensure pasted .init/.fini fragments use the same toc if any has makes_toc_func_call set. Index: bfd/elf64-ppc.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-ppc.c,v retrieving revision 1.339 diff -u -p -r1.339 elf64-ppc.c --- bfd/elf64-ppc.c 25 Oct 2010 15:54:15 -0000 1.339 +++ bfd/elf64-ppc.c 31 Jan 2011 22:10:04 -0000 @@ -10580,14 +10580,28 @@ ppc64_elf_next_input_section (struct bfd if (elf_gp (isec->owner) != 0) htab->toc_curr = elf_gp (isec->owner); } - else if (!isec->call_check_done - && toc_adjusting_stub_needed (info, isec) < 0) - return FALSE; + else + { + if (!isec->call_check_done + && toc_adjusting_stub_needed (info, isec) < 0) + return FALSE; + /* If we make a local call from this section, ie. a branch + without a following nop, then we have no place to put a + toc restoring insn. We must use the same toc group as + the callee. + Testing makes_toc_func_call actually tests for *any* + calls to functions that need a good toc pointer. A more + precise test would be better, as this one will set + incorrect values for pasted .init/.fini fragments. + (Fixed later in check_pasted_section.) */ + if (isec->makes_toc_func_call + && elf_gp (isec->owner) != 0) + htab->toc_curr = elf_gp (isec->owner); + } } /* Functions that don't use the TOC can belong in any TOC group. - Use the last TOC base. This happens to make _init and _fini - pasting work, because the fragments generally don't use the TOC. */ + Use the last TOC base. */ htab->stub_group[isec->id].toc_off = htab->toc_curr; return TRUE; } @@ -10614,6 +10628,15 @@ check_pasted_section (struct bfd_link_in else if (toc_off != htab->stub_group[i->id].toc_off) return FALSE; } + + if (toc_off == 0) + for (i = o->map_head.s; i != NULL; i = i->map_head.s) + if (i->makes_toc_func_call) + { + toc_off = htab->stub_group[i->id].toc_off; + break; + } + /* Make sure the whole pasted function uses the same toc offset. */ if (toc_off != 0) for (i = o->map_head.s; i != NULL; i = i->map_head.s) -- Alan Modra Australia Development Lab, IBM