summaryrefslogtreecommitdiff
path: root/bfd/elf32-h8300.c
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2003-07-11 14:59:41 +0000
committerRichard Sandiford <rsandifo@nildram.co.uk>2003-07-11 14:59:41 +0000
commitea4e8beb189f6a33a4184df4115cf943971c5751 (patch)
treed87283315d30f574ef4409c459bf0af49018ff9e /bfd/elf32-h8300.c
parentd4617d6fec602034d6b1b34e57c5a30c8b51a3c5 (diff)
downloadbinutils-redhat-ea4e8beb189f6a33a4184df4115cf943971c5751.tar.gz
bfd/
* bfd-in.h (bfd_h8300_pad_address): Declare. * bfd-in2.h: Regenerate. * cpu-h8300.c (bfd_h8300_pad_address): New function. * coff-h8300.c (h8300_reloc16_estimate): Use it to canonicalize addresses before checking whether they can be relaxed. (h8300_reloc16_extra_cases): Likewise for the R_MOVL2 sanity check. Don't complain about overflows in general 8-bit relocations. * elf32-h8300.c (elf32_h8_relax_section): Use bfd_h8300_pad_address. Fix handling of R_H8_DIR24A8. ld/testsuite/ * ld-h8300/relax-3{.s,.d,-coff.d}: New test. * ld-h8300/h8300.exp: Run it.
Diffstat (limited to 'bfd/elf32-h8300.c')
-rw-r--r--bfd/elf32-h8300.c51
1 files changed, 15 insertions, 36 deletions
diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c
index 8d305eb34d..efd14bb582 100644
--- a/bfd/elf32-h8300.c
+++ b/bfd/elf32-h8300.c
@@ -1004,18 +1004,10 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
become an 8 bit absolute address if its in the right range. */
case R_H8_DIR16A8:
{
- bfd_vma value = symval + irel->r_addend;
+ bfd_vma value;
- if ((bfd_get_mach (abfd) == bfd_mach_h8300
- && value >= 0xff00
- && value <= 0xffff)
- || ((bfd_get_mach (abfd) == bfd_mach_h8300h
- /* FIXME: h8300hn? */
- || bfd_get_mach (abfd) == bfd_mach_h8300s
- /* FIXME: h8300sn? */
- || bfd_get_mach (abfd) == bfd_mach_h8300sx)
- && value >= 0xffff00
- && value <= 0xffffff))
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value >= 0xffffff00u)
{
unsigned char code;
@@ -1068,20 +1060,11 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
become an 8 bit absolute address if its in the right range. */
case R_H8_DIR24A8:
{
- bfd_vma value = symval + irel->r_addend;
+ bfd_vma value;
- if ((bfd_get_mach (abfd) == bfd_mach_h8300
- && value >= 0xff00
- && value <= 0xffff)
- || ((bfd_get_mach (abfd) == bfd_mach_h8300h
- /* FIXME: h8300hn? */
- || bfd_get_mach (abfd) == bfd_mach_h8300s
- /* FIXME: h8300sn? */
- || bfd_get_mach (abfd) == bfd_mach_h8300sx)
- && value >= 0xffff00
- && value <= 0xffffff))
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value >= 0xffffff00u)
{
- bfd_boolean skip = FALSE;
unsigned char code;
/* Note that we've changed the relocs, section contents,
@@ -1101,37 +1084,32 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
switch (code & 0xf0)
{
- case 0x00:
+ case 0x20:
bfd_put_8 (abfd, (code & 0xf) | 0x20,
contents + irel->r_offset - 2);
break;
- case 0x80:
+ case 0xa0:
bfd_put_8 (abfd, (code & 0xf) | 0x30,
contents + irel->r_offset - 2);
break;
- case 0x20:
- case 0xa0:
- /* Skip 32bit versions. */
- skip = TRUE;
- break;
default:
abort ();
}
- if (skip)
- break;
-
/* Fix the relocation's type. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
R_H8_DIR8);
+ irel->r_offset--;
/* Delete two bytes of data. */
- if (!elf32_h8_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
+ if (!elf32_h8_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 4))
goto error_return;
/* That will change things, so, we should relax again.
Note that this is not required, and it may be slow. */
*again = TRUE;
+ break;
}
}
@@ -1141,9 +1119,10 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
become a 16bit absoulte address if it is in the right range. */
case R_H8_DIR32A16:
{
- bfd_vma value = symval + irel->r_addend;
+ bfd_vma value;
- if (value <= 0x7fff || value >= 0xff8000)
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value <= 0x7fff || value >= 0xffff8000u)
{
unsigned char code;