From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3627 invoked by alias); 25 Jul 2006 21:25:59 -0000 Received: (qmail 3617 invoked by uid 22791); 25 Jul 2006 21:25:57 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 25 Jul 2006 21:25:54 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k6PLPq7X023318 for ; Tue, 25 Jul 2006 17:25:52 -0400 Received: from post-office.corp.redhat.com (post-office.corp.redhat.com [172.16.52.227]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k6PLPqks003518 for ; Tue, 25 Jul 2006 17:25:52 -0400 Received: from greed.delorie.com (dj.cipe.redhat.com [10.0.0.222]) by post-office.corp.redhat.com (8.11.6/8.11.6) with ESMTP id k6PLPqR09774 for ; Tue, 25 Jul 2006 17:25:52 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.13.1/8.13.1) with ESMTP id k6PLPpcX031726 for ; Tue, 25 Jul 2006 17:25:51 -0400 Received: (from dj@localhost) by greed.delorie.com (8.13.1/8.13.1/Submit) id k6PLPkqX031723; Tue, 25 Jul 2006 17:25:46 -0400 Date: Tue, 25 Jul 2006 21:25:00 -0000 Message-Id: <200607252125.k6PLPkqX031723@greed.delorie.com> From: DJ Delorie To: binutils@sourceware.org Subject: [patch] sh relaxing X-IsSubscribed: yes 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/msg00309.txt.bz2 A couple of patches to fix ld's sh-relax failures. The BFD bug caused relaxed jumps to jump to the wrong place. The GAS one caused offset tables to be deleted while they were still in use. Ok? bfd/ChangeLog 2006-07-25 DJ Delorie * elf32-sh.c (sh_elf_relax_section): Allow for branches across non-moving .align directives. Preserve any DIR32 offset when converting bsr's to jsr's. gas/ChangeLog 2006-07-25 DJ Delorie * config/tc-sh.c (sh_frob_section): Canonicalize pointers to local vs full symbols so that we never have more than one pointer value for any given symbol in our symbol table. Index: bfd/elf32-sh.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-sh.c,v retrieving revision 1.138 diff -p -U3 -r1.138 bfd/elf32-sh.c --- bfd/elf32-sh.c 23 Jun 2006 02:58:00 -0000 1.138 +++ bfd/elf32-sh.c 25 Jul 2006 21:22:30 -0000 @@ -2284,7 +2284,11 @@ sh_elf_relax_section (bfd *abfd, asectio + sec->output_section->vma + sec->output_offset + 4)); - if (foff < -0x1000 || foff >= 0x1000) + /* A branch to an address beyond ours might be increased by an + .align that doesn't move when bytes behind us are deleted. + So, we add some slop in this calculation to allow for + that. */ + if (foff < -0x1000 || foff >= 0x1000 - 8) { /* After all that work, we can't shorten this function call. */ continue; @@ -2322,6 +2326,12 @@ sh_elf_relax_section (bfd *abfd, asectio irel->r_addend = -4; + /* When we calculated the symbol "value" we had an offset in the + DIR32's word in memory (we read and add it above). However, + the jsr we create does NOT have this offset encoded, so we + have to add it to the addend to preserve it. */ + irel->r_addend += bfd_get_32 (abfd, contents + paddr); + /* See if there is another R_SH_USES reloc referring to the same register load. */ for (irelscan = internal_relocs; irelscan < irelend; irelscan++) Index: gas/config/tc-sh.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-sh.c,v retrieving revision 1.119 diff -p -U3 -r1.119 gas/config/tc-sh.c --- gas/config/tc-sh.c 21 Jul 2006 09:46:15 -0000 1.119 +++ gas/config/tc-sh.c 25 Jul 2006 21:22:32 -0000 @@ -3318,6 +3318,21 @@ sh_frob_section (bfd *abfd ATTRIBUTE_UNU for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next) { symbolS *sym; + + sym = fix->fx_addsy; + /* Check for a local_symbol. */ + if (sym && sym->bsym == NULL) + { + struct local_symbol *ls = (struct local_symbol *)sym; + /* See if it's been converted. If so, canonicalize. */ + if (local_symbol_converted_p (ls)) + fix->fx_addsy = local_symbol_get_real_symbol (ls); + } + } + + for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next) + { + symbolS *sym; bfd_vma val; fixS *fscan; struct sh_count_relocs info;