From 7a9823f1a9d50e9541153fd77c692f389c8c081c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 11 Jul 2003 14:59:41 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 12 ++++++ bfd/bfd-in.h | 4 ++ bfd/bfd-in2.h | 4 ++ bfd/coff-h8300.c | 55 ++++++++-------------------- bfd/elf32-h8300.c | 51 ++++++++------------------ ld/testsuite/ChangeLog | 5 +++ ld/testsuite/ld-h8300/h8300.exp | 3 ++ ld/testsuite/ld-h8300/relax-3-coff.d | 32 ++++++++++++++++ ld/testsuite/ld-h8300/relax-3.d | 31 ++++++++++++++++ ld/testsuite/ld-h8300/relax-3.s | 32 ++++++++++++++++ 10 files changed, 153 insertions(+), 76 deletions(-) create mode 100644 ld/testsuite/ld-h8300/relax-3-coff.d create mode 100644 ld/testsuite/ld-h8300/relax-3.d create mode 100644 ld/testsuite/ld-h8300/relax-3.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index acef36dfb4..cf325a63ea 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2003-07-11 Richard Sandiford + + * 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 * elf32-h8300.c: Convert function prototypes and definitions diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index e800a92211..63c86f7f91 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 e8151d6534..b5e3527f51 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 23286f8aac..bfe31c6cd4 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 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; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 21fb9d2576..e267928b80 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-07-11 Richard Sandiford + + * ld-h8300/relax-3{.s,.d,-coff.d}: New test. + * ld-h8300/h8300.exp: Run it. + 2003-07-10 Alan Modra * 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 af457abe23..53909619af 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 0000000000..49a68cf36f --- /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 0000000000..eb14f6e40b --- /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 0000000000..f4a2346ab9 --- /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