* alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types.
[binutils-gdb.git] / bfd / elf32-h8300.c
index 1d643cbf0a9c7322c16551fc781de04f1f430f04..f272dc8e084a5f8c3020a5e992d1d736db9d8176 100644 (file)
@@ -1,22 +1,22 @@
-/* Generic support for 32-bit ELF
-   Copyright 1993, 1995, 1998, 1999, 2001, 2002
+/* BFD back-end for Renesas H8/300 ELF binaries.
+   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -29,29 +29,29 @@ static reloc_howto_type *elf32_h8_reloc_type_lookup
 static void elf32_h8_info_to_howto
   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
 static void elf32_h8_info_to_howto_rel
-  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
 static unsigned long elf32_h8_mach
   PARAMS ((flagword));
 static void elf32_h8_final_write_processing
-  PARAMS ((bfd *, boolean));
-static boolean elf32_h8_object_p
+  PARAMS ((bfd *, bfd_boolean));
+static bfd_boolean elf32_h8_object_p
   PARAMS ((bfd *));
-static boolean elf32_h8_merge_private_bfd_data
+static bfd_boolean elf32_h8_merge_private_bfd_data
   PARAMS ((bfd *, bfd *));
-static boolean elf32_h8_relax_section
-  PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
-static boolean elf32_h8_relax_delete_bytes
+static bfd_boolean elf32_h8_relax_section
+  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
+static bfd_boolean elf32_h8_relax_delete_bytes
   PARAMS ((bfd *, asection *, bfd_vma, int));
-static boolean elf32_h8_symbol_address_p
+static bfd_boolean elf32_h8_symbol_address_p
   PARAMS ((bfd *, asection *, bfd_vma));
 static bfd_byte *elf32_h8_get_relocated_section_contents
   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
-          bfd_byte *, boolean, asymbol **));
+          bfd_byte *, bfd_boolean, asymbol **));
 static bfd_reloc_status_type elf32_h8_final_link_relocate
   PARAMS ((unsigned long, bfd *, bfd *, asection *,
           bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
           struct bfd_link_info *, asection *, int));
-static boolean elf32_h8_relocate_section
+static bfd_boolean elf32_h8_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
           bfd_byte *, Elf_Internal_Rela *,
           Elf_Internal_Sym *, asection **));
@@ -67,155 +67,155 @@ static reloc_howto_type h8_elf_howto_table[] = {
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_dont,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_NONE",           /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR32_X (R_H8_NONE_X + 1)
   HOWTO (R_H8_DIR32,           /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_dont,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_DIR32",          /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR16_X (R_H8_DIR32_X + 1)
   HOWTO (R_H8_DIR16,           /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_dont,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_DIR16",          /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR8_X (R_H8_DIR16_X + 1)
   HOWTO (R_H8_DIR8,            /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        special,                       /* special_function */
-        "R_H8_DIR16",          /* name */
-        false,                 /* partial_inplace */
+        complain_overflow_dont,/* complain_on_overflow */
+        special,               /* special_function */
+        "R_H8_DIR8",           /* name */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x000000ff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
   HOWTO (R_H8_DIR16A8,         /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        special,                       /* special_function */
+        special,               /* special_function */
         "R_H8_DIR16A8",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
   HOWTO (R_H8_DIR16R8,         /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        special,                       /* special_function */
+        special,               /* special_function */
         "R_H8_DIR16R8",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
   HOWTO (R_H8_DIR24A8,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        special,                       /* special_function */
+        special,               /* special_function */
         "R_H8_DIR24A8",        /* name */
-        true,                  /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0xff000000,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
   HOWTO (R_H8_DIR24R8,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        special,                       /* special_function */
+        special,               /* special_function */
         "R_H8_DIR24R8",        /* name */
-        true,                  /* partial_inplace */
+        TRUE,                  /* partial_inplace */
         0xff000000,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
   HOWTO (R_H8_DIR32A16,                /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_dont,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_DIR32",          /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 #define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
   HOWTO (R_H8_PCREL16,         /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_signed,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_PCREL16",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0xffff,                /* src_mask */
         0xffff,                /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 #define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
   HOWTO (R_H8_PCREL8,          /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        special,                       /* special_function */
+        complain_overflow_signed,/* complain_on_overflow */
+        special,               /* special_function */
         "R_H8_PCREL8",         /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0xff,                  /* src_mask */
         0xff,                  /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 };
 
 /* This structure is used to map BFD reloc codes to H8 ELF relocs.  */
@@ -261,7 +261,7 @@ static void
 elf32_h8_info_to_howto (abfd, bfd_reloc, elf_reloc)
      bfd *abfd ATTRIBUTE_UNUSED;
      arelent *bfd_reloc;
-     Elf32_Internal_Rela *elf_reloc;
+     Elf_Internal_Rela *elf_reloc;
 {
   unsigned int r;
   unsigned int i;
@@ -280,7 +280,7 @@ static void
 elf32_h8_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
      bfd *abfd ATTRIBUTE_UNUSED;
      arelent *bfd_reloc;
-     Elf32_Internal_Rel *elf_reloc ATTRIBUTE_UNUSED;
+     Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED;
 {
   unsigned int r;
 
@@ -410,7 +410,7 @@ elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
 }
 \f
 /* Relocate an H8 ELF section.  */
-static boolean
+static bfd_boolean
 elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
                           contents, relocs, local_syms, local_sections)
      bfd *output_bfd;
@@ -427,7 +427,7 @@ elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
   Elf_Internal_Rela *rel, *relend;
 
   if (info->relocateable)
-    return true;
+    return TRUE;
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -476,8 +476,8 @@ elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset, true)))
-               return false;
+                     input_section, rel->r_offset, TRUE)))
+               return FALSE;
              relocation = 0;
            }
        }
@@ -514,14 +514,14 @@ elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
              if (! ((*info->callbacks->reloc_overflow)
                     (info, name, howto->name, (bfd_vma) 0,
                      input_bfd, input_section, rel->r_offset)))
-               return false;
+               return FALSE;
              break;
 
            case bfd_reloc_undefined:
              if (! ((*info->callbacks->undefined_symbol)
                     (info, name, input_bfd, input_section,
-                     rel->r_offset, true)))
-               return false;
+                     rel->r_offset, TRUE)))
+               return FALSE;
              break;
 
            case bfd_reloc_outofrange:
@@ -544,13 +544,13 @@ elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
              if (!((*info->callbacks->warning)
                    (info, msg, name, input_bfd, input_section,
                     rel->r_offset)))
-               return false;
+               return FALSE;
              break;
            }
        }
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Object files encode the specific H8 model they were compiled
@@ -573,6 +573,15 @@ elf32_h8_mach (flags)
 
     case E_H8_MACH_H8300S:
       return bfd_mach_h8300s;
+
+    case E_H8_MACH_H8300HN:
+      return bfd_mach_h8300hn;
+
+    case E_H8_MACH_H8300SN:
+      return bfd_mach_h8300sn;
+
+    case E_H8_MACH_H8300SX:
+      return bfd_mach_h8300sx;
     }
 }
 
@@ -583,7 +592,7 @@ elf32_h8_mach (flags)
 static void
 elf32_h8_final_write_processing (abfd, linker)
      bfd *abfd;
-     boolean linker ATTRIBUTE_UNUSED;
+     bfd_boolean linker ATTRIBUTE_UNUSED;
 {
   unsigned long val;
 
@@ -601,6 +610,18 @@ elf32_h8_final_write_processing (abfd, linker)
     case bfd_mach_h8300s:
       val = E_H8_MACH_H8300S;
       break;
+
+    case bfd_mach_h8300hn:
+      val = E_H8_MACH_H8300HN;
+      break;
+
+    case bfd_mach_h8300sn:
+      val = E_H8_MACH_H8300SN;
+      break;
+
+    case bfd_mach_h8300sx:
+      val = E_H8_MACH_H8300SX;
+      break;
     }
 
   elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
@@ -610,37 +631,37 @@ elf32_h8_final_write_processing (abfd, linker)
 /* Return nonzero if ABFD represents a valid H8 ELF object file; also
    record the encoded machine type found in the ELF flags.  */
 
-static boolean
+static bfd_boolean
 elf32_h8_object_p (abfd)
      bfd *abfd;
 {
   bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
                             elf32_h8_mach (elf_elfheader (abfd)->e_flags));
-  return true;
+  return TRUE;
 }
 
 /* Merge backend specific data from an object file to the output
    object file when linking.  The only data we need to copy at this
    time is the architecture/machine information.  */
 
-static boolean
+static bfd_boolean
 elf32_h8_merge_private_bfd_data (ibfd, obfd)
      bfd *ibfd;
      bfd *obfd;
 {
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return true;
+    return TRUE;
 
   if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
       && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
     {
       if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
                                bfd_get_mach (ibfd)))
-        return false;
+        return FALSE;
     }
 
-  return true;
+  return TRUE;
 }
 
 /* This function handles relaxing for the H8..
@@ -660,12 +681,12 @@ elf32_h8_merge_private_bfd_data (ibfd, obfd)
 
      mov.[bwl]:24/32 ->    mov.[bwl]:16           2 bytes */
 
-static boolean
+static bfd_boolean
 elf32_h8_relax_section (abfd, sec, link_info, again)
      bfd *abfd;
      asection *sec;
      struct bfd_link_info *link_info;
-     boolean *again;
+     bfd_boolean *again;
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs;
@@ -676,7 +697,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
   static Elf_Internal_Rela *last_reloc = NULL;
 
   /* Assume nothing changes.  */
-  *again = false;
+  *again = FALSE;
 
   /* We don't have to do anything for a relocateable link, if
      this section does not have relocs, or if this is not a
@@ -685,7 +706,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
-    return true;
+    return TRUE;
 
   /* If this is the first time we have been called for this section,
      initialize the cooked size.  */
@@ -695,7 +716,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
   /* Get a copy of the native relocations.  */
-  internal_relocs = (_bfd_elf32_link_read_relocs
+  internal_relocs = (_bfd_elf_link_read_relocs
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
                      link_info->keep_memory));
   if (internal_relocs == NULL)
@@ -764,9 +785,12 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
-         symval = (isym->st_value
-                   + sym_sec->output_section->vma
-                   + sym_sec->output_offset);
+         symval = isym->st_value;
+         /* If the reloc is absolute, it will not have
+            a symbol or section associated with it.  */
+         if (sym_sec)
+           symval += sym_sec->output_section->vma
+             + sym_sec->output_offset;
        }
       else
        {
@@ -827,14 +851,34 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                elf_section_data (sec)->this_hdr.contents = contents;
                symtab_hdr->contents = (unsigned char *) isymbuf;
 
+               /* Get the instruction code being relaxed.  */
+               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
                /* If the previous instruction conditionally jumped around
                   this instruction, we may be able to reverse the condition
                   and redirect the previous instruction to the target of
                   this instruction.
 
                   Such sequences are used by the compiler to deal with
-                  long conditional branches.  */
-               if ((int) gap <= 130
+                  long conditional branches.
+
+                  Only perform this optimisation for jumps (code 0x5a) not
+                  subroutine calls, as otherwise it could transform:
+
+                                    mov.w   r0,r0
+                                    beq     .L1
+                                    jsr     @_bar
+                             .L1:   rts
+                             _bar:  rts
+                  into:
+                                    mov.w   r0,r0
+                                    bne     _bar
+                                    rts
+                             _bar:  rts
+
+                  which changes the call (jsr) into a branch (bne).  */
+               if (code == 0x5a
+                   && (int) gap <= 130
                    && (int) gap >= -128
                    && last_reloc
                    && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
@@ -885,14 +929,11 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                                                          4))
                          goto error_return;
 
-                       *again = true;
+                       *again = TRUE;
                        break;
                      }
                  }
 
-               /* We could not eliminate this jump, so just shorten it.  */
-               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
-
                if (code == 0x5e)
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
                else if (code == 0x5a)
@@ -911,7 +952,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                /* That will change things, so, we should relax again.
                   Note that this is not required, and it may be slow.  */
-               *again = true;
+               *again = TRUE;
              }
            break;
          }
@@ -974,7 +1015,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                /* That will change things, so, we should relax again.
                   Note that this is not required, and it may be slow.  */
-               *again = true;
+               *again = TRUE;
              }
            break;
          }
@@ -989,7 +1030,10 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                 && value >= 0xff00
                 && value <= 0xffff)
                || ((bfd_get_mach (abfd) == bfd_mach_h8300h
-                    || bfd_get_mach (abfd) == bfd_mach_h8300s)
+                    /* FIXME: h8300hn? */
+                    || bfd_get_mach (abfd) == bfd_mach_h8300s
+                    /* FIXME: h8300sn? */
+                    || bfd_get_mach (abfd) == bfd_mach_h8300sx)
                    && value >= 0xffff00
                    && value <= 0xffffff))
              {
@@ -1032,7 +1076,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                /* That will change things, so, we should relax again.
                   Note that this is not required, and it may be slow.  */
-               *again = true;
+               *again = TRUE;
              }
            break;
          }
@@ -1047,10 +1091,14 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
                 && value >= 0xff00
                 && value <= 0xffff)
                || ((bfd_get_mach (abfd) == bfd_mach_h8300h
-                    || bfd_get_mach (abfd) == bfd_mach_h8300s)
+                    /* FIXME: h8300hn? */
+                    || bfd_get_mach (abfd) == bfd_mach_h8300s
+                    /* FIXME: h8300sn? */
+                    || bfd_get_mach (abfd) == bfd_mach_h8300sx)
                    && value >= 0xffff00
                    && value <= 0xffffff))
              {
+               bfd_boolean skip = FALSE;
                unsigned char code;
 
                /* Note that we've changed the relocs, section contents,
@@ -1068,16 +1116,27 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
 
-               if ((code & 0xf0) == 0x00)
-                 bfd_put_8 (abfd,
-                            (code & 0xf) | 0x20,
-                            contents + irel->r_offset - 2);
-               else if ((code & 0xf0) == 0x80)
-                 bfd_put_8 (abfd,
-                            (code & 0xf) | 0x30,
-                            contents + irel->r_offset - 2);
-               else
-                 abort ();
+               switch (code & 0xf0)
+                 {
+                 case 0x00:
+                   bfd_put_8 (abfd, (code & 0xf) | 0x20,
+                              contents + irel->r_offset - 2);
+                   break;
+                 case 0x80:
+                   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),
@@ -1089,7 +1148,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                /* That will change things, so, we should relax again.
                   Note that this is not required, and it may be slow.  */
-               *again = true;
+               *again = TRUE;
              }
          }
 
@@ -1130,7 +1189,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
 
                /* That will change things, so, we should relax again.
                   Note that this is not required, and it may be slow.  */
-               *again = true;
+               *again = TRUE;
              }
            break;
          }
@@ -1165,7 +1224,7 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
       && elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
-  return true;
+  return TRUE;
 
  error_return:
   if (isymbuf != NULL
@@ -1177,12 +1236,12 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
   if (internal_relocs != NULL
       && elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
-  return false;
+  return FALSE;
 }
 
 /* Delete some bytes from a section while relaxing.  */
 
-static boolean
+static bfd_boolean
 elf32_h8_relax_delete_bytes (abfd, sec, addr, count)
      bfd *abfd;
      asection *sec;
@@ -1258,12 +1317,12 @@ elf32_h8_relax_delete_bytes (abfd, sec, addr, count)
        }
     }
 
-  return true;
+  return TRUE;
 }
 
-/* Return true if a symbol exists at the given address, else return
-   false.  */
-static boolean
+/* Return TRUE if a symbol exists at the given address, else return
+   FALSE.  */
+static bfd_boolean
 elf32_h8_symbol_address_p (abfd, sec, addr)
      bfd *abfd;
      asection *sec;
@@ -1287,7 +1346,7 @@ elf32_h8_symbol_address_p (abfd, sec, addr)
     {
       if (isym->st_shndx == sec_shndx
          && isym->st_value == addr)
-       return true;
+       return TRUE;
     }
 
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
@@ -1301,10 +1360,10 @@ elf32_h8_symbol_address_p (abfd, sec, addr)
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
          && sym_hash->root.u.def.value == addr)
-       return true;
+       return TRUE;
     }
 
-  return false;
+  return FALSE;
 }
 
 /* This is a version of bfd_generic_get_relocated_section_contents
@@ -1317,7 +1376,7 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
      struct bfd_link_info *link_info;
      struct bfd_link_order *link_order;
      bfd_byte *data;
-     boolean relocateable;
+     bfd_boolean relocateable;
      asymbol **symbols;
 {
   Elf_Internal_Shdr *symtab_hdr;
@@ -1348,9 +1407,9 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
       Elf_Internal_Sym *isym, *isymend;
       bfd_size_type amt;
 
-      internal_relocs = (_bfd_elf32_link_read_relocs
+      internal_relocs = (_bfd_elf_link_read_relocs
                         (input_bfd, input_section, (PTR) NULL,
-                         (Elf_Internal_Rela *) NULL, false));
+                         (Elf_Internal_Rela *) NULL, FALSE));
       if (internal_relocs == NULL)
        goto error_return;