diff options
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/bfd-in.h | 4 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/coff-h8300.c | 55 | ||||
-rw-r--r-- | bfd/elf32-h8300.c | 51 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-h8300/h8300.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-h8300/relax-3-coff.d | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-h8300/relax-3.d | 31 | ||||
-rw-r--r-- | ld/testsuite/ld-h8300/relax-3.s | 32 |
10 files changed, 153 insertions, 76 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index acef36d..cf325a6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,17 @@ 2003-07-11 Richard Sandiford <rsandifo@redhat.com> + * 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. + +2003-07-11 Richard Sandiford <rsandifo@redhat.com> + * elf32-h8300.c: Convert function prototypes and definitions to C90 syntax. * coff-h8300.c: Likewise. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index e800a92..63c86f7 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -821,3 +821,7 @@ extern void bfd_ticoff_set_section_load_page extern int bfd_ticoff_get_section_load_page (struct sec *); +/* H8/300 functions. */ +extern bfd_vma bfd_h8300_pad_address + (bfd *, bfd_vma); + diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index e8151d6..b5e3527 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -828,6 +828,10 @@ extern void bfd_ticoff_set_section_load_page extern int bfd_ticoff_get_section_load_page (struct sec *); +/* H8/300 functions. */ +extern bfd_vma bfd_h8300_pad_address + (bfd *, bfd_vma); + /* Extracted from init.c. */ void bfd_init (void); diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c index 23286f8..bfe31c6 100644 --- a/bfd/coff-h8300.c +++ b/bfd/coff-h8300.c @@ -573,17 +573,11 @@ h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc, case R_MOV16B1: /* Get the address of the data referenced by this mov.b insn. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); + value = bfd_h8300_pad_address (abfd, value); - /* The address is in 0xff00..0xffff inclusive on the h8300 or - 0xffff00..0xffffff inclusive on the h8300h, then we can - relax this mov.b */ - if ((bfd_get_mach (abfd) == bfd_mach_h8300 - && value >= 0xff00 - && value <= 0xffff) - || ((bfd_get_mach (abfd) == bfd_mach_h8300h - || bfd_get_mach (abfd) == bfd_mach_h8300s) - && value >= 0xffff00 - && value <= 0xffffff)) + /* If the address is in the top 256 bytes of the address space + then we can relax this instruction. */ + if (value >= 0xffffff00u) { /* Change the reloc type. */ reloc->howto = reloc->howto + 1; @@ -600,13 +594,9 @@ h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc, case R_MOV24B1: /* Get the address of the data referenced by this mov.b insn. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); + value = bfd_h8300_pad_address (abfd, value); - /* The address is in 0xffff00..0xffffff inclusive on the h8300h, - then we can relax this mov.b */ - if ((bfd_get_mach (abfd) == bfd_mach_h8300h - || bfd_get_mach (abfd) == bfd_mach_h8300s) - && value >= 0xffff00 - && value <= 0xffffff) + if (value >= 0xffffff00u) { /* Change the reloc type. */ reloc->howto = reloc->howto + 1; @@ -627,10 +617,11 @@ h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc, case R_MOVL1: /* Get the address of the data referenced by this mov insn. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); + value = bfd_h8300_pad_address (abfd, value); - /* If this address is in 0x0000..0x7fff inclusive or - 0xff8000..0xffffff inclusive, then it can be relaxed. */ - if (value <= 0x7fff || value >= 0xff8000) + /* If the address is a sign-extended 16-bit value then we can + relax this instruction. */ + if (value <= 0x7fff || value >= 0xffff8000u) { /* Change the reloc type. */ reloc->howto = howto_table + 17; @@ -737,26 +728,9 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info, /* Get the address of the object referenced by this insn. */ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); - /* Sanity check. */ - if (value <= 0xff - || (value >= 0x0000ff00 && value <= 0x0000ffff) - || (value >= 0x00ffff00 && value <= 0x00ffffff) - || (value >= 0xffffff00 && value <= 0xffffffff)) - { - /* Everything looks OK. Apply the relocation and update the - src/dst address appropriately. */ - bfd_put_8 (abfd, value & 0xff, data + dst_address); - dst_address += 1; - src_address += 1; - } - else - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } + bfd_put_8 (abfd, value & 0xff, data + dst_address); + dst_address += 1; + src_address += 1; /* All done. */ break; @@ -798,9 +772,10 @@ h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info, absolute relocation. */ case R_MOVL2: value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); + value = bfd_h8300_pad_address (abfd, value); /* Sanity check. */ - if (value <= 0x7fff || value >= 0xff8000) + if (value <= 0x7fff || value >= 0xffff8000u) { /* Insert the 16bit value into the proper location. */ bfd_put_16 (abfd, value, data + dst_address); diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c index 8d305eb..efd14bb 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; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 21fb9d2..e267928 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-07-11 Richard Sandiford <rsandifo@redhat.com> + + * ld-h8300/relax-3{.s,.d,-coff.d}: New test. + * ld-h8300/h8300.exp: Run it. + 2003-07-10 Alan Modra <amodra@bigpond.net.au> * ld-powerpc/powerpc.exp: Dump output .got section rather than .toc. diff --git a/ld/testsuite/ld-h8300/h8300.exp b/ld/testsuite/ld-h8300/h8300.exp index af457ab..5390961 100644 --- a/ld/testsuite/ld-h8300/h8300.exp +++ b/ld/testsuite/ld-h8300/h8300.exp @@ -28,4 +28,7 @@ run_dump_test relax if {[istarget *-elf]} { run_dump_test relax-2 + run_dump_test relax-3 +} else { + run_dump_test relax-3-coff } diff --git a/ld/testsuite/ld-h8300/relax-3-coff.d b/ld/testsuite/ld-h8300/relax-3-coff.d new file mode 100644 index 0000000..49a68cf --- /dev/null +++ b/ld/testsuite/ld-h8300/relax-3-coff.d @@ -0,0 +1,32 @@ +# name: H8300 Relaxation Test 3 +# source: relax-3.s +# ld: --relax -m h8300s +# objdump: -d --no-show-raw-insn + +.*: file format .*-h8300 + +Disassembly of section .text: + +00000100 <_start>: +# +# Relaxation of aa:16 +# +.*: 6a 08 00 00 * mov.b @0x0:16,r0l +.*: 6a 08 7f ff * mov.b @0x7fff:16,r0l +.*: 6a 08 80 00 * mov.b @0x8000:16,r0l +.*: 6a 08 fe ff * mov.b @0xfeff:16,r0l +.*: 28 00 * mov.b @0x0:8,r0l +.*: 28 ff * mov.b @0xff:8,r0l +# +# Relaxation of aa:32 +# +.*: 6a 08 00 00 * mov.b @0x0:16,r0l +.*: 6a 08 7f ff * mov.b @0x7fff:16,r0l +.*: 6a 28 00 00 80 00 * mov.b @0x8000:32,r0l +.*: 6a 28 00 00 ff 00 * mov.b @0xff00:32,r0l +.*: 6a 28 00 ff ff 00 * mov.b @0xffff00:32,r0l +.*: 6a 28 ff ff 7f ff * mov.b @0xffff7fff:32,r0l +.*: 6a 08 80 00 * mov.b @0x8000:16,r0l +.*: 6a 08 fe ff * mov.b @0xfeff:16,r0l +.*: 28 00 * mov.b @0x0:8,r0l +.*: 28 ff * mov.b @0xff:8,r0l diff --git a/ld/testsuite/ld-h8300/relax-3.d b/ld/testsuite/ld-h8300/relax-3.d new file mode 100644 index 0000000..eb14f6e --- /dev/null +++ b/ld/testsuite/ld-h8300/relax-3.d @@ -0,0 +1,31 @@ +# name: H8300 Relaxation Test 3 +# ld: --relax -m h8300self +# objdump: -d --no-show-raw-insn + +.*: file format .*-h8300 + +Disassembly of section .text: + +00000100 <_start>: +# +# Relaxation of aa:16 +# +.*: 6a 08 00 00 * mov.b @0x0:16,r0l +.*: 6a 08 7f ff * mov.b @0x7fff:16,r0l +.*: 6a 08 80 00 * mov.b @0x8000:16,r0l +.*: 6a 08 fe ff * mov.b @0xfeff:16,r0l +.*: 28 00 * mov.b @0x0:8,r0l +.*: 28 ff * mov.b @0xff:8,r0l +# +# Relaxation of aa:32 +# +.*: 6a 08 00 00 * mov.b @0x0:16,r0l +.*: 6a 08 7f ff * mov.b @0x7fff:16,r0l +.*: 6a 28 00 00 80 00 * mov.b @0x8000:32,r0l +.*: 6a 28 00 00 ff 00 * mov.b @0xff00:32,r0l +.*: 6a 28 00 ff ff 00 * mov.b @0xffff00:32,r0l +.*: 6a 28 ff ff 7f ff * mov.b @0xffff7fff:32,r0l +.*: 6a 08 80 00 * mov.b @0x8000:16,r0l +.*: 6a 08 fe ff * mov.b @0xfeff:16,r0l +.*: 28 00 * mov.b @0x0:8,r0l +.*: 28 ff * mov.b @0xff:8,r0l diff --git a/ld/testsuite/ld-h8300/relax-3.s b/ld/testsuite/ld-h8300/relax-3.s new file mode 100644 index 0000000..f4a2346 --- /dev/null +++ b/ld/testsuite/ld-h8300/relax-3.s @@ -0,0 +1,32 @@ + .h8300s + .globl _start +_start: + # s3-s6 aren't valid 16-bit addresses. + mov.b @s1:16,r0l + mov.b @s2:16,r0l + mov.b @s7:16,r0l + mov.b @s8:16,r0l + mov.b @s9:16,r0l + mov.b @s10:16,r0l + + mov.b @s1:32,r0l + mov.b @s2:32,r0l + mov.b @s3:32,r0l + mov.b @s4:32,r0l + mov.b @s5:32,r0l + mov.b @s6:32,r0l + mov.b @s7:32,r0l + mov.b @s8:32,r0l + mov.b @s9:32,r0l + mov.b @s10:32,r0l + + .equ s1,0 + .equ s2,0x7fff + .equ s3,0x8000 + .equ s4,0xff00 + .equ s5,0xffff00 + .equ s6,0xffff7fff + .equ s7,0xffff8000 + .equ s8,0xfffffeff + .equ s9,0xffffff00 + .equ s10,0xffffffff |