diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 12 |
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++) |