aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2006-08-08 17:21:55 +0000
committerDJ Delorie <dj@redhat.com>2006-08-08 17:21:55 +0000
commitf725025bcba912bb1cc099662f106f7dd870bdde (patch)
treeb387ed0ed79633ea747f6419ec0f081a2db6b1bb
parente14e52f868afc2266920640776b7e54bc214ee91 (diff)
downloadgdb-f725025bcba912bb1cc099662f106f7dd870bdde.zip
gdb-f725025bcba912bb1cc099662f106f7dd870bdde.tar.gz
gdb-f725025bcba912bb1cc099662f106f7dd870bdde.tar.bz2
* 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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-sh.c12
2 files changed, 17 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7270c5f..f2b4ad4 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2006-08-08 DJ Delorie <dj@redhat.com>
+
+ * 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.
+
2006-08-08 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_build_stubs): Clear relbrlt reloc_count
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 849c9c7..a410901 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -614,7 +614,11 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
+ 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;
@@ -652,6 +656,12 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
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++)