From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30573 invoked by alias); 19 Dec 2004 23:25:49 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 30493 invoked from network); 19 Dec 2004 23:25:36 -0000 Received: from unknown (HELO gizmo07ps.bigpond.com) (144.140.71.42) by sourceware.org with SMTP; 19 Dec 2004 23:25:36 -0000 Received: (qmail 27796 invoked from network); 19 Dec 2004 23:25:34 -0000 Received: from unknown (HELO psmam12.bigpond.com) (144.135.25.103) by gizmo07ps.bigpond.com with SMTP; 19 Dec 2004 23:25:34 -0000 Received: from cpe-144-136-221-26.sa.bigpond.net.au ([144.136.221.26]) by psmam12.bigpond.com(MAM REL_3_4_2a 234/13422274) with SMTP id 13422274; Mon, 20 Dec 2004 09:25:34 +1000 Received: by bubble.modra.org (Postfix, from userid 500) id 3DEDF150B83; Mon, 20 Dec 2004 09:55:34 +1030 Date: Sun, 19 Dec 2004 23:25:00 -0000 From: Alan Modra To: binutils@sources.redhat.com Cc: Janis Johnson , gsmith@us.ibm.com, Yaakov Yaari Subject: Re: problems building with -Wl,-q on RHEL4 Message-ID: <20041219232534.GC9840@bubble.modra.org> Mail-Followup-To: binutils@sources.redhat.com, Janis Johnson , gsmith@us.ibm.com, Yaakov Yaari Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2004-12/txt/msg00232.txt.bz2 On Mon, Dec 13, 2004 at 05:28:42PM -0800, Janis Johnson wrote: > When building eon, a C++ program from SPEC CPU2000, on RHEL4 with the > fixed binutils using "-m64 -Wl,-q" I get several errors that start with > "relocation truncated to fit: R_PPC64_REL24". In the past I've always > been able to work around that problem by using one of the options > -mno-fp-in-toc, -mno-sum-in-toc, or -mminimal-toc, but none of those > allow me to build eon with -Wl,-q on RHEL4. The same problem exists in > GCC mainline and in the gcc-3_4-rhl-branch of the GCC CVS tree. This > isn't caused by Alan's new ld patch, just exposed by it; both are Actually, I reckon my ld patch isn't quite right. The problem being that .opd may have been edited which necessarily means the .opd relocs will be edited too. Thus re-reading the original .opd relocs won't give correct results. This is likely to happen with C++ when linkonce sections are used. After fixing that, I found that attempting to link eon hit a ld segfault due to the toc editing code not adjusting the output reloc size. Committed. * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add opd_relocs. (opd_entry_value): Use opd_relocs if available. (ppc64_elf_relocate_section): Don't set reloc_done. Instead copy .opd relocations to opd_relocs. (ppc64_elf_edit_toc): Set rel_hdr.sh_size after editing relocs. Index: bfd/elf64-ppc.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-ppc.c,v retrieving revision 1.181 diff -u -p -r1.181 elf64-ppc.c --- bfd/elf64-ppc.c 11 Dec 2004 03:56:43 -0000 1.181 +++ bfd/elf64-ppc.c 19 Dec 2004 23:08:35 -0000 @@ -2380,6 +2380,9 @@ struct ppc64_elf_obj_tdata bfd_signed_vma refcount; bfd_vma offset; } tlsld_got; + + /* A copy of relocs before they are modified for --emit-relocs. */ + Elf_Internal_Rela *opd_relocs; }; #define ppc64_elf_tdata(bfd) \ @@ -4696,7 +4699,7 @@ opd_entry_value (asection *opd_sec, bfd_vma *code_off) { bfd *opd_bfd = opd_sec->owner; - Elf_Internal_Rela *relocs, *save_relocs = NULL; + Elf_Internal_Rela *relocs; Elf_Internal_Rela *lo, *hi, *look; bfd_vma val; @@ -4726,17 +4729,12 @@ opd_entry_value (asection *opd_sec, return val; } - /* If the .opd relocs have been adjusted for output, then we need to - re-read the original relocs rather than use the cached ones. */ - if (opd_sec->reloc_done) - { - save_relocs = elf_section_data (opd_sec)->relocs; - elf_section_data (opd_sec)->relocs = NULL; - } + relocs = ppc64_elf_tdata (opd_bfd)->opd_relocs; + if (relocs == NULL) + relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE); /* Go find the opd reloc at the sym address. */ - lo = relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, - !opd_sec->reloc_done); + lo = relocs; BFD_ASSERT (lo != NULL); hi = lo + opd_sec->reloc_count - 1; /* ignore last reloc */ val = (bfd_vma) -1; @@ -4807,11 +4805,6 @@ opd_entry_value (asection *opd_sec, } } - if (opd_sec->reloc_done) - { - elf_section_data (opd_sec)->relocs = save_relocs; - free (relocs); - } return val; } @@ -6996,6 +6989,9 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_ ++wrel; } toc->reloc_count = wrel - relstart; + elf_section_data (toc)->rel_hdr.sh_size + = toc->reloc_count * elf_section_data (toc)->rel_hdr.sh_entsize; + BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL); /* Adjust addends for relocs against the toc section sym. */ for (sec = ibfd->sections; sec != NULL; sec = sec->next) @@ -10440,8 +10436,19 @@ ppc64_elf_relocate_section (bfd *output_ /* If we're emitting relocations, then shortly after this function returns, reloc offsets and addends for this section will be adjusted. Worse, reloc symbol indices will be for the output - file rather than the input. Let opd_entry_value know. */ - input_section->reloc_done = info->emitrelocations; + file rather than the input. Save a copy of the relocs for + opd_entry_value. */ + if (is_opd && info->emitrelocations) + { + bfd_size_type amt; + amt = input_section->reloc_count * sizeof (Elf_Internal_Rela); + rel = bfd_alloc (input_bfd, amt); + BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd_relocs == NULL); + ppc64_elf_tdata (input_bfd)->opd_relocs = rel; + if (rel == NULL) + return FALSE; + memcpy (rel, relocs, amt); + } return ret; } -- Alan Modra IBM OzLabs - Linux Technology Centre