bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Fri, 11 Jul 2003 14:59:41 +0000 (14:59 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Fri, 11 Jul 2003 14:59:41 +0000 (14:59 +0000)
* 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
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/coff-h8300.c
bfd/elf32-h8300.c
ld/testsuite/ChangeLog
ld/testsuite/ld-h8300/h8300.exp
ld/testsuite/ld-h8300/relax-3-coff.d [new file with mode: 0644]
ld/testsuite/ld-h8300/relax-3.d [new file with mode: 0644]
ld/testsuite/ld-h8300/relax-3.s [new file with mode: 0644]

index acef36dfb47513e22d956643acdc0cf030f40eca..cf325a63eaa0651519fbf3bceaea85948e67442e 100644 (file)
@@ -1,3 +1,15 @@
+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
index e800a922119b4e13bb7836e24c14bfb8be0d9099..63c86f7f91fed3c3c203af5de582fadd0fa4494c 100644 (file)
@@ -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);
+
index e8151d65340e64ba7e8162ad16616e9bbbe1e487..b5e3527f5104fe27be6c3e8ee95e612094478468 100644 (file)
@@ -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);
 
index 23286f8aac61628c385164db21ec9549cfdb3e4c..bfe31c6cd4ee10bb34d4a5ad94027c2ac5048e40 100644 (file)
@@ -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);
index 8d305eb34ddd8ba045ae8fcedc457e33c1636c57..efd14bb582fb0f763548979dec3d32e94640f19f 100644 (file)
@@ -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;
 
index 21fb9d2576835579732f0a277f1e5f405eba98e7..e267928b8059630980cd6e259ba76bc845464cfd 100644 (file)
@@ -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.
index af457abe2354c7cac89d96d27e3e3aa7072d56d0..53909619af31b3a982506977fb68ab37f40e2151 100644 (file)
@@ -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 (file)
index 0000000..49a68cf
--- /dev/null
@@ -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 (file)
index 0000000..eb14f6e
--- /dev/null
@@ -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 (file)
index 0000000..f4a2346
--- /dev/null
@@ -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