daily update
[deliverable/binutils-gdb.git] / bfd / coff-h8300.c
index 5429076814338647605805faa11bef051261e824..e2a10a6c5cedae5f476d4b6c33be510484bdc561 100644 (file)
@@ -1,6 +1,6 @@
-/* BFD back-end for Hitachi H8/300 COFF binaries.
+/* BFD back-end for Renesas H8/300 COFF binaries.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Written by Steve Chamberlain, <sac@cygnus.com>.
 
    Free Software Foundation, Inc.
    Written by Steve Chamberlain, <sac@cygnus.com>.
 
@@ -8,7 +8,7 @@
 
    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
 
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    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.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "genlink.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "genlink.h"
@@ -61,33 +62,26 @@ struct funcvec_hash_table
 
 static struct bfd_hash_entry *
 funcvec_hash_newfunc
 
 static struct bfd_hash_entry *
 funcvec_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-
-static bfd_boolean
-funcvec_hash_table_init
-  PARAMS ((struct funcvec_hash_table *, bfd *,
-          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
-                                      struct bfd_hash_table *,
-                                      const char *)));
+  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 
 static bfd_reloc_status_type special
 
 static bfd_reloc_status_type special
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+  (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
 static int select_reloc
 static int select_reloc
-  PARAMS ((reloc_howto_type *));
+  (reloc_howto_type *);
 static void rtype2howto
 static void rtype2howto
-  PARAMS ((arelent *, struct internal_reloc *));
+  (arelent *, struct internal_reloc *);
 static void reloc_processing
 static void reloc_processing
-  PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
+  (arelent *, struct internal_reloc *, asymbol **, bfd *, asection *);
 static bfd_boolean h8300_symbol_address_p
 static bfd_boolean h8300_symbol_address_p
-  PARAMS ((bfd *, asection *, bfd_vma));
+  (bfd *, asection *, bfd_vma);
 static int h8300_reloc16_estimate
 static int h8300_reloc16_estimate
-  PARAMS ((bfd *, asection *, arelent *, unsigned int,
-    struct bfd_link_info *));
+  (bfd *, asection *, arelent *, unsigned int,
+   struct bfd_link_info *);
 static void h8300_reloc16_extra_cases
 static void h8300_reloc16_extra_cases
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
-    bfd_byte *, unsigned int *, unsigned int *));
+  (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+   bfd_byte *, unsigned int *, unsigned int *);
 static bfd_boolean h8300_bfd_link_add_symbols
 static bfd_boolean h8300_bfd_link_add_symbols
-  PARAMS ((bfd *, struct bfd_link_info *));
+  (bfd *, struct bfd_link_info *);
 
 /* To lookup a value in the function vector hash table.  */
 #define funcvec_hash_lookup(table, string, create, copy) \
 
 /* To lookup a value in the function vector hash table.  */
 #define funcvec_hash_lookup(table, string, create, copy) \
@@ -111,8 +105,7 @@ struct h8300_coff_link_hash_table {
   struct funcvec_hash_table *funcvec_hash_table;
 };
 
   struct funcvec_hash_table *funcvec_hash_table;
 };
 
-static struct bfd_link_hash_table *h8300_coff_link_hash_table_create
-  PARAMS ((bfd *));
+static struct bfd_link_hash_table *h8300_coff_link_hash_table_create (bfd *);
 
 /* Get the H8/300 COFF linker hash table from a link_info structure.  */
 
 
 /* Get the H8/300 COFF linker hash table from a link_info structure.  */
 
@@ -123,10 +116,9 @@ static struct bfd_link_hash_table *h8300_coff_link_hash_table_create
    a new entry is added to the funcvec hash table.  */
 
 static struct bfd_hash_entry *
    a new entry is added to the funcvec hash table.  */
 
 static struct bfd_hash_entry *
-funcvec_hash_newfunc (entry, gen_table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *gen_table;
-     const char *string;
+funcvec_hash_newfunc (struct bfd_hash_entry *entry,
+                     struct bfd_hash_table *gen_table,
+                     const char *string)
 {
   struct funcvec_hash_entry *ret;
   struct funcvec_hash_table *table;
 {
   struct funcvec_hash_entry *ret;
   struct funcvec_hash_table *table;
@@ -156,13 +148,20 @@ funcvec_hash_newfunc (entry, gen_table, string)
   /* Bump the offset at which we store entries in the function
      vector.  We'd like to bump up the size of the vectors section,
      but it's not easily available here.  */
   /* Bump the offset at which we store entries in the function
      vector.  We'd like to bump up the size of the vectors section,
      but it's not easily available here.  */
-  if (bfd_get_mach (table->abfd) == bfd_mach_h8300)
-    table->offset += 2;
-  else if (bfd_get_mach (table->abfd) == bfd_mach_h8300h
-          || bfd_get_mach (table->abfd) == bfd_mach_h8300s)
-    table->offset += 4;
-  else
-    return NULL;
+ switch (bfd_get_mach (table->abfd))
+   {
+   case bfd_mach_h8300:
+   case bfd_mach_h8300hn:
+   case bfd_mach_h8300sn:
+     table->offset += 2;
+     break;
+   case bfd_mach_h8300h:
+   case bfd_mach_h8300s:
+     table->offset += 4;
+     break;
+   default:
+     return NULL;
+   }
 
   /* Everything went OK.  */
   return (struct bfd_hash_entry *) ret;
 
   /* Everything went OK.  */
   return (struct bfd_hash_entry *) ret;
@@ -171,27 +170,27 @@ funcvec_hash_newfunc (entry, gen_table, string)
 /* Initialize the function vector hash table.  */
 
 static bfd_boolean
 /* Initialize the function vector hash table.  */
 
 static bfd_boolean
-funcvec_hash_table_init (table, abfd, newfunc)
-     struct funcvec_hash_table *table;
-     bfd *abfd;
-     struct bfd_hash_entry *(*newfunc)
-       PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
-               const char *));
+funcvec_hash_table_init (struct funcvec_hash_table *table,
+                        bfd *abfd,
+                        struct bfd_hash_entry *(*newfunc)
+                          (struct bfd_hash_entry *,
+                           struct bfd_hash_table *,
+                           const char *),
+                        unsigned int entsize)
 {
   /* Initialize our local fields, then call the generic initialization
      routine.  */
   table->offset = 0;
   table->abfd = abfd;
 {
   /* Initialize our local fields, then call the generic initialization
      routine.  */
   table->offset = 0;
   table->abfd = abfd;
-  return (bfd_hash_table_init (&table->root, newfunc));
+  return (bfd_hash_table_init (&table->root, newfunc, entsize));
 }
 
 /* Create the derived linker hash table.  We use a derived hash table
 }
 
 /* Create the derived linker hash table.  We use a derived hash table
-   basically to hold "static" information during an h8/300 coff link
+   basically to hold "static" information during an H8/300 coff link
    without using static variables.  */
 
 static struct bfd_link_hash_table *
    without using static variables.  */
 
 static struct bfd_link_hash_table *
-h8300_coff_link_hash_table_create (abfd)
-     bfd *abfd;
+h8300_coff_link_hash_table_create (bfd *abfd)
 {
   struct h8300_coff_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
 {
   struct h8300_coff_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
@@ -200,7 +199,8 @@ h8300_coff_link_hash_table_create (abfd)
   if (ret == NULL)
     return NULL;
   if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
   if (ret == NULL)
     return NULL;
   if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
-                                 _bfd_generic_link_hash_newfunc))
+                                 _bfd_generic_link_hash_newfunc,
+                                 sizeof (struct generic_link_hash_entry)))
     {
       free (ret);
       return NULL;
     {
       free (ret);
       return NULL;
@@ -210,7 +210,7 @@ h8300_coff_link_hash_table_create (abfd)
   ret->vectors_sec = NULL;
   ret->funcvec_hash_table = NULL;
 
   ret->vectors_sec = NULL;
   ret->funcvec_hash_table = NULL;
 
-  /* OK.  Everything's intialized, return the base pointer.  */
+  /* OK.  Everything's initialized, return the base pointer.  */
   return &ret->root.root;
 }
 
   return &ret->root.root;
 }
 
@@ -224,15 +224,13 @@ h8300_coff_link_hash_table_create (abfd)
    the addend until the final link.  */
 
 static bfd_reloc_status_type
    the addend until the final link.  */
 
 static bfd_reloc_status_type
-special (abfd, reloc_entry, symbol, data, input_section, output_bfd,
-        error_message)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *reloc_entry ATTRIBUTE_UNUSED;
-     asymbol *symbol ATTRIBUTE_UNUSED;
-     PTR data ATTRIBUTE_UNUSED;
-     asection *input_section ATTRIBUTE_UNUSED;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+special (bfd *abfd ATTRIBUTE_UNUSED,
+        arelent *reloc_entry ATTRIBUTE_UNUSED,
+        asymbol *symbol ATTRIBUTE_UNUSED,
+        PTR data ATTRIBUTE_UNUSED,
+        asection *input_section ATTRIBUTE_UNUSED,
+        bfd *output_bfd,
+        char **error_message ATTRIBUTE_UNUSED)
 {
   if (output_bfd == (bfd *) NULL)
     return bfd_reloc_continue;
 {
   if (output_bfd == (bfd *) NULL)
     return bfd_reloc_continue;
@@ -263,8 +261,8 @@ static reloc_howto_type howto_table[] = {
      the function vector's entry in the jsr instruction.  */
   HOWTO (R_MEM_INDIRECT, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8/indirect", FALSE, 0x000000ff, 0x000000ff, FALSE),
 
      the function vector's entry in the jsr instruction.  */
   HOWTO (R_MEM_INDIRECT, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8/indirect", FALSE, 0x000000ff, 0x000000ff, FALSE),
 
-  /* Internal reloc for relaxing.  This is created when a 16bit pc-relative
-     branch is turned into an 8bit pc-relative branch.  */
+  /* Internal reloc for relaxing.  This is created when a 16-bit pc-relative
+     branch is turned into an 8-bit pc-relative branch.  */
   HOWTO (R_PCRWORD_B, 0, 0, 8, TRUE, 0, complain_overflow_bitfield, special, "relaxed bCC:16", FALSE, 0x000000ff, 0x000000ff, FALSE),
 
   HOWTO (R_MOVL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,special, "32/24 relaxable move", FALSE, 0xffffffff, 0xffffffff, FALSE),
   HOWTO (R_PCRWORD_B, 0, 0, 8, TRUE, 0, complain_overflow_bitfield, special, "relaxed bCC:16", FALSE, 0x000000ff, 0x000000ff, FALSE),
 
   HOWTO (R_MOVL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,special, "32/24 relaxable move", FALSE, 0xffffffff, 0xffffffff, FALSE),
@@ -281,8 +279,9 @@ static reloc_howto_type howto_table[] = {
 #define SELECT_RELOC(x,howto) \
   { x.r_type = select_reloc (howto); }
 
 #define SELECT_RELOC(x,howto) \
   { x.r_type = select_reloc (howto); }
 
-#define BADMAG(x) (H8300BADMAG (x) && H8300HBADMAG (x) && H8300SBADMAG (x))
-#define H8300 1                        /* Customize coffcode.h */
+#define BADMAG(x) (H8300BADMAG (x) && H8300HBADMAG (x) && H8300SBADMAG (x) \
+                                  && H8300HNBADMAG(x) && H8300SNBADMAG(x))
+#define H8300 1                        /* Customize coffcode.h  */
 #define __A_MAGIC_SET__
 
 /* Code to swap in the reloc.  */
 #define __A_MAGIC_SET__
 
 /* Code to swap in the reloc.  */
@@ -293,8 +292,7 @@ static reloc_howto_type howto_table[] = {
   dst->r_stuff[1] = 'C';
 
 static int
   dst->r_stuff[1] = 'C';
 
 static int
-select_reloc (howto)
-     reloc_howto_type *howto;
+select_reloc (reloc_howto_type *howto)
 {
   return howto->type;
 }
 {
   return howto->type;
 }
@@ -302,9 +300,7 @@ select_reloc (howto)
 /* Code to turn a r_type into a howto ptr, uses the above howto table.  */
 
 static void
 /* Code to turn a r_type into a howto ptr, uses the above howto table.  */
 
 static void
-rtype2howto (internal, dst)
-     arelent *internal;
-     struct internal_reloc *dst;
+rtype2howto (arelent *internal, struct internal_reloc *dst)
 {
   switch (dst->r_type)
     {
 {
   switch (dst->r_type)
     {
@@ -385,38 +381,23 @@ rtype2howto (internal, dst)
  reloc_processing (relent, reloc, symbols, abfd, section)
 
 static void
  reloc_processing (relent, reloc, symbols, abfd, section)
 
 static void
-reloc_processing (relent, reloc, symbols, abfd, section)
-     arelent *relent;
-     struct internal_reloc *reloc;
-     asymbol **symbols;
-     bfd *abfd;
-     asection *section;
+reloc_processing (arelent *relent, struct internal_reloc *reloc,
+                 asymbol **symbols, bfd *abfd, asection *section)
 {
   relent->address = reloc->r_vaddr;
   rtype2howto (relent, reloc);
 
   if (((int) reloc->r_symndx) > 0)
 {
   relent->address = reloc->r_vaddr;
   rtype2howto (relent, reloc);
 
   if (((int) reloc->r_symndx) > 0)
-    {
-      relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
-    }
+    relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
   else
   else
-    {
-      relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
-    }
+    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
 
   relent->addend = reloc->r_offset;
 
   relent->addend = reloc->r_offset;
-
   relent->address -= section->vma;
   relent->address -= section->vma;
-#if 0
-  relent->section = 0;
-#endif
 }
 
 static bfd_boolean
 }
 
 static bfd_boolean
-h8300_symbol_address_p (abfd, input_section, address)
-     bfd *abfd;
-     asection *input_section;
-     bfd_vma address;
+h8300_symbol_address_p (bfd *abfd, asection *input_section, bfd_vma address)
 {
   asymbol **s;
 
 {
   asymbol **s;
 
@@ -428,6 +409,7 @@ h8300_symbol_address_p (abfd, input_section, address)
   while (*s)
     {
       asymbol *p = *s;
   while (*s)
     {
       asymbol *p = *s;
+
       if (p->section == input_section
          && (input_section->output_section->vma
              + input_section->output_offset
       if (p->section == input_section
          && (input_section->output_section->vma
              + input_section->output_offset
@@ -447,12 +429,8 @@ h8300_symbol_address_p (abfd, input_section, address)
    in the howto table.  This needs to be fixed.  */
 
 static int
    in the howto table.  This needs to be fixed.  */
 
 static int
-h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
-     bfd *abfd;
-     asection *input_section;
-     arelent *reloc;
-     unsigned int shrink;
-     struct bfd_link_info *link_info;
+h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc,
+                       unsigned int shrink, struct bfd_link_info *link_info)
 {
   bfd_vma value;
   bfd_vma dot;
 {
   bfd_vma value;
   bfd_vma dot;
@@ -472,8 +450,8 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
   /* Only examine the relocs which might be relaxable.  */
   switch (reloc->howto->type)
     {
   /* Only examine the relocs which might be relaxable.  */
   switch (reloc->howto->type)
     {
-    /* This is the 16/24 bit absolute branch which could become an 8 bit
-       pc-relative branch.  */
+      /* This is the 16-/24-bit absolute branch which could become an
+        8-bit pc-relative branch.  */
     case R_JMP1:
     case R_JMPL1:
       /* Get the address of the target of this branch.  */
     case R_JMP1:
     case R_JMPL1:
       /* Get the address of the target of this branch.  */
@@ -561,7 +539,7 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
        }
       break;
 
        }
       break;
 
-    /* This is the 16 bit pc-relative branch which could become an 8 bit
+    /* This is the 16-bit pc-relative branch which could become an 8-bit
        pc-relative branch.  */
     case R_PCRWORD:
       /* Get the address of the target of this branch, add one to the value
        pc-relative branch.  */
     case R_PCRWORD:
       /* Get the address of the target of this branch, add one to the value
@@ -589,22 +567,16 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
        }
       break;
 
        }
       break;
 
-    /* This is a 16 bit absolute address in a mov.b insn, which can
-       become an 8 bit absolute address if it's in the right range.  */
+    /* This is a 16-bit absolute address in a mov.b insn, which can
+       become an 8-bit absolute address if it's in the right range.  */
     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);
     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;
        {
          /* Change the reloc type.  */
          reloc->howto = reloc->howto + 1;
@@ -615,19 +587,15 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
        }
       break;
 
        }
       break;
 
-    /* Similarly for a 24 bit absolute address in a mov.b.  Note that
-       if we can't relax this into an 8 bit absolute, we'll fall through
-       and try to relax it into a 16bit absolute.  */
+    /* Similarly for a 24-bit absolute address in a mov.b.  Note that
+       if we can't relax this into an 8-bit absolute, we'll fall through
+       and try to relax it into a 16-bit absolute.  */
     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);
     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;
        {
          /* Change the reloc type.  */
          reloc->howto = reloc->howto + 1;
@@ -640,18 +608,19 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
          break;
        }
 
          break;
        }
 
-      /* FALLTHROUGH and try to turn the 32/24 bit reloc into a 16 bit
+      /* FALLTHROUGH and try to turn the 24-/32-bit reloc into a 16-bit
         reloc.  */
 
         reloc.  */
 
-    /* This is a 24/32 bit absolute address in a mov insn, which can
-       become an 16 bit absolute address if it's in the right range.  */
+    /* This is a 24-/32-bit absolute address in a mov insn, which can
+       become an 16-bit absolute address if it's in the right range.  */
     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);
     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;
        {
          /* Change the reloc type.  */
          reloc->howto = howto_table + 17;
@@ -678,15 +647,10 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
    FIXME: Not all relocations check for overflow!  */
 
 static void
    FIXME: Not all relocations check for overflow!  */
 
 static void
-h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
-                          dst_ptr)
-     bfd *abfd;
-     struct bfd_link_info *link_info;
-     struct bfd_link_order *link_order;
-     arelent *reloc;
-     bfd_byte *data;
-     unsigned int *src_ptr;
-     unsigned int *dst_ptr;
+h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
+                          struct bfd_link_order *link_order, arelent *reloc,
+                          bfd_byte *data, unsigned int *src_ptr,
+                          unsigned int *dst_ptr)
 {
   unsigned int src_address = *src_ptr;
   unsigned int dst_address = *dst_ptr;
 {
   unsigned int src_address = *src_ptr;
   unsigned int dst_address = *dst_ptr;
@@ -694,15 +658,16 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
   bfd_vma value;
   bfd_vma dot;
   int gap, tmp;
   bfd_vma value;
   bfd_vma dot;
   int gap, tmp;
+  unsigned char temp_code;
 
   switch (reloc->howto->type)
     {
 
   switch (reloc->howto->type)
     {
-    /* Generic 8bit pc-relative relocation.  */
+    /* Generic 8-bit pc-relative relocation.  */
     case R_PCRBYTE:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
     case R_PCRBYTE:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma);
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma);
 
@@ -712,7 +677,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
@@ -720,7 +686,6 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
 
       /* Everything looks OK.  Apply the relocation and update the
         src/dst address appropriately.  */
 
       /* Everything looks OK.  Apply the relocation and update the
         src/dst address appropriately.  */
-
       bfd_put_8 (abfd, gap, data + dst_address);
       dst_address++;
       src_address++;
       bfd_put_8 (abfd, gap, data + dst_address);
       dst_address++;
       src_address++;
@@ -728,13 +693,13 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       /* All done.  */
       break;
 
       /* All done.  */
       break;
 
-    /* Generic 16bit pc-relative relocation.  */
+    /* Generic 16-bit pc-relative relocation.  */
     case R_PCRWORD:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
     case R_PCRWORD:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 1);
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 1);
 
@@ -744,7 +709,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       if (gap > 32766 || gap < -32768)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       if (gap > 32766 || gap < -32768)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
@@ -752,7 +718,6 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
 
       /* Everything looks OK.  Apply the relocation and update the
         src/dst address appropriately.  */
 
       /* Everything looks OK.  Apply the relocation and update the
         src/dst address appropriately.  */
-
       bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address);
       dst_address += 2;
       src_address += 2;
       bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address);
       dst_address += 2;
       src_address += 2;
@@ -760,37 +725,19 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       /* All done.  */
       break;
 
       /* All done.  */
       break;
 
-    /* Generic 8bit absolute relocation.  */
+    /* Generic 8-bit absolute relocation.  */
     case R_RELBYTE:
       /* Get the address of the object referenced by this insn.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
     case R_RELBYTE:
       /* 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;
 
 
       /* All done.  */
       break;
 
-    /* Various simple 16bit absolute relocations.  */
+    /* Various simple 16-bit absolute relocations.  */
     case R_MOV16B1:
     case R_JMP1:
     case R_RELWORD:
     case R_MOV16B1:
     case R_JMP1:
     case R_RELWORD:
@@ -800,7 +747,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       src_address += 2;
       break;
 
       src_address += 2;
       break;
 
-    /* Various simple 24/32bit absolute relocations.  */
+    /* Various simple 24-/32-bit absolute relocations.  */
     case R_MOV24B1:
     case R_MOVL1:
     case R_RELLONG:
     case R_MOV24B1:
     case R_MOVL1:
     case R_RELLONG:
@@ -811,7 +758,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       src_address += 4;
       break;
 
       src_address += 4;
       break;
 
-    /* Another 24/32bit absolute relocation.  */
+    /* Another 24-/32-bit absolute relocation.  */
     case R_JMPL1:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
     case R_JMPL1:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
@@ -823,19 +770,28 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       src_address += 4;
       break;
 
       src_address += 4;
       break;
 
-    /* A 16bit abolute relocation that was formerlly a 24/32bit
-       absolute relocation.  */
+      /* This is a 24-/32-bit absolute address in one of the following
+        instructions:
+
+          "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+          "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", "ldc.w",
+          "stc.w" and "mov.[bwl]"
+
+        We may relax this into an 16-bit absolute address if it's in
+        the right range.  */
     case R_MOVL2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
     case R_MOVL2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+      value = bfd_h8300_pad_address (abfd, value);
 
       /* Sanity check.  */
 
       /* Sanity check.  */
-      if (value <= 0x7fff || value >= 0xff8000)
+      if (value <= 0x7fff || value >= 0xffff8000u)
        {
        {
-         /* Insert the 16bit value into the proper location.  */
+         /* Insert the 16-bit value into the proper location.  */
          bfd_put_16 (abfd, value, data + dst_address);
 
          bfd_put_16 (abfd, value, data + dst_address);
 
-         /* Fix the opcode.  For all the move insns, we simply
-            need to turn off bit 0x20 in the previous byte.  */
+         /* Fix the opcode.  For all the instructions that belong to
+            this relaxation, we simply need to turn off bit 0x20 in
+            the previous byte.  */
          data[dst_address - 1] &= ~0x20;
          dst_address += 2;
          src_address += 4;
          data[dst_address - 1] &= ~0x20;
          dst_address += 2;
          src_address += 4;
@@ -843,20 +799,21 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       else
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       else
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
        }
       break;
 
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
        }
       break;
 
-    /* A 16bit absolute branch that is now an 8-bit pc-relative branch.  */
+    /* A 16-bit absolute branch that is now an 8-bit pc-relative branch.  */
     case R_JMP2:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the next instruction.  */
     case R_JMP2:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the next instruction.  */
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 1);
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 1);
 
@@ -866,7 +823,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
@@ -880,7 +838,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
          bfd_put_8 (abfd, 0x55, data + dst_address - 1);
          break;
        case 0x5a:
          bfd_put_8 (abfd, 0x55, data + dst_address - 1);
          break;
        case 0x5a:
-         /* jmp ->bra */
+         /* jmp -> bra */
          bfd_put_8 (abfd, 0x40, data + dst_address - 1);
          break;
 
          bfd_put_8 (abfd, 0x40, data + dst_address - 1);
          break;
 
@@ -888,7 +846,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
          abort ();
        }
 
          abort ();
        }
 
-      /* Write out the 8bit value.  */
+      /* Write out the 8-bit value.  */
       bfd_put_8 (abfd, gap, data + dst_address);
 
       dst_address += 1;
       bfd_put_8 (abfd, gap, data + dst_address);
 
       dst_address += 1;
@@ -896,13 +854,13 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
 
       break;
 
 
       break;
 
-    /* A 16bit pc-relative branch that is now an 8-bit pc-relative branch.  */
+    /* A 16-bit pc-relative branch that is now an 8-bit pc-relative branch.  */
     case R_PCRWORD_B:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
     case R_PCRWORD_B:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma - 1);
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma - 1);
 
@@ -912,7 +870,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
@@ -923,12 +882,15 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        {
        case 0x58:
          /* bCC:16 -> bCC:8 */
        {
        case 0x58:
          /* bCC:16 -> bCC:8 */
-         /* Get the condition code from the original insn.  */
+         /* Get the second byte of the original insn, which contains
+            the condition code.  */
          tmp = data[dst_address - 1];
          tmp = data[dst_address - 1];
+
+         /* Compute the fisrt byte of the relaxed instruction.  The
+            original sequence 0x58 0xX0 is relaxed to 0x4X, where X
+            represents the condition code.  */
          tmp &= 0xf0;
          tmp >>= 4;
          tmp &= 0xf0;
          tmp >>= 4;
-
-         /* Now or in the high nibble of the opcode.  */
          tmp |= 0x40;
 
          /* Write it.  */
          tmp |= 0x40;
 
          /* Write it.  */
@@ -947,19 +909,19 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       /* Output the target.  */
       bfd_put_8 (abfd, gap, data + dst_address - 1);
 
       /* Output the target.  */
       bfd_put_8 (abfd, gap, data + dst_address - 1);
 
-      /* We don't advance dst_address -- the 8bit reloc is applied at
+      /* We don't advance dst_address -- the 8-bit reloc is applied at
         dst_address - 1, so the next insn should begin at dst_address.  */
       src_address += 2;
 
       break;
 
         dst_address - 1, so the next insn should begin at dst_address.  */
       src_address += 2;
 
       break;
 
-    /* Similarly for a 24bit absolute that is now 8 bits.  */
+    /* Similarly for a 24-bit absolute that is now 8 bits.  */
     case R_JMPL2:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
     case R_JMPL2:
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 2);
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma + 2);
 
@@ -986,23 +948,52 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
 
       break;
 
 
       break;
 
-    /* A 16bit absolute mov.b that is now an 8bit absolute mov.b.  */
+      /* This is a 16-bit absolute address in one of the following
+        instructions:
+
+          "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+          "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+          "mov.b"
+
+        We may relax this into an 8-bit absolute address if it's in
+        the right range.  */
     case R_MOV16B2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
     case R_MOV16B2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
-      /* Sanity check.  */
+      /* All instructions with R_H8_DIR16B2 start with 0x6a.  */
       if (data[dst_address - 2] != 0x6a)
        abort ();
 
       if (data[dst_address - 2] != 0x6a)
        abort ();
 
+      temp_code = data[src_address - 1];
+
+      /* If this is a mov.b instruction, clear the lower nibble, which
+        contains the source/destination register number.  */
+      if ((temp_code & 0x10) != 0x10)
+       temp_code &= 0xf0;
+
       /* Fix up the opcode.  */
       /* Fix up the opcode.  */
-      switch (data[src_address - 1] & 0xf0)
+      switch (temp_code)
        {
        case 0x00:
        {
        case 0x00:
+         /* This is mov.b @aa:16,Rd.  */
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
          break;
        case 0x80:
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
          break;
        case 0x80:
+         /* This is mov.b Rs,@aa:16.  */
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
          break;
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
          break;
+       case 0x18:
+         /* This is a bit-maniputation instruction that stores one
+            bit into memory, one of "bclr", "bist", "bnot", "bset",
+            and "bst".  */
+         data[dst_address - 2] = 0x7f;
+         break;
+       case 0x10:
+         /* This is a bit-maniputation instruction that loads one bit
+            from memory, one of "band", "biand", "bild", "bior",
+            "bixor", "bld", "bor", "btst", and "bxor".  */
+         data[dst_address - 2] = 0x7e;
+         break;
        default:
          abort ();
        }
        default:
          abort ();
        }
@@ -1011,23 +1002,52 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       src_address += 2;
       break;
 
       src_address += 2;
       break;
 
-    /* Similarly for a 24bit mov.b  */
+      /* This is a 24-bit absolute address in one of the following
+        instructions:
+
+          "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+          "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+          "mov.b"
+
+        We may relax this into an 8-bit absolute address if it's in
+        the right range.  */
     case R_MOV24B2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
     case R_MOV24B2:
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
-      /* Sanity check.  */
+      /* All instructions with R_MOV24B2 start with 0x6a.  */
       if (data[dst_address - 2] != 0x6a)
        abort ();
 
       if (data[dst_address - 2] != 0x6a)
        abort ();
 
+      temp_code = data[src_address - 1];
+
+      /* If this is a mov.b instruction, clear the lower nibble, which
+        contains the source/destination register number.  */
+      if ((temp_code & 0x30) != 0x30)
+       temp_code &= 0xf0;
+
       /* Fix up the opcode.  */
       /* Fix up the opcode.  */
-      switch (data[src_address - 1] & 0xf0)
+      switch (temp_code)
        {
        case 0x20:
        {
        case 0x20:
+         /* This is mov.b @aa:24/32,Rd.  */
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
          break;
        case 0xa0:
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
          break;
        case 0xa0:
+         /* This is mov.b Rs,@aa:24/32.  */
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
          break;
          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
          break;
+       case 0x38:
+         /* This is a bit-maniputation instruction that stores one
+            bit into memory, one of "bclr", "bist", "bnot", "bset",
+            and "bst".  */
+         data[dst_address - 2] = 0x7f;
+         break;
+       case 0x30:
+         /* This is a bit-maniputation instruction that loads one bit
+            from memory, one of "band", "biand", "bild", "bior",
+            "bixor", "bld", "bor", "btst", and "bxor".  */
+         data[dst_address - 2] = 0x7e;
+         break;
        default:
          abort ();
        }
        default:
          abort ();
        }
@@ -1040,7 +1060,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the target of this branch.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
-      dot = (link_order->offset
+      dot = (input_section->output_offset
             + dst_address
             + link_order->u.indirect.section->output_section->vma) + 1;
 
             + dst_address
             + link_order->u.indirect.section->output_section->vma) + 1;
 
@@ -1050,7 +1070,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
       if (gap < -128 || gap > 126)
        {
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                (link_info, NULL,
+                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
                  reloc->howto->name, reloc->addend, input_section->owner,
                  input_section, reloc->address)))
            abort ();
@@ -1072,7 +1093,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       src_address += 4;
       break;
 
       src_address += 4;
       break;
 
-    /* An 8bit memory indirect instruction (jmp/jsr).
+    /* An 8-bit memory indirect instruction (jmp/jsr).
 
        There's several things that need to be done to handle
        this relocation.
 
        There's several things that need to be done to handle
        this relocation.
@@ -1095,11 +1116,11 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        struct h8300_coff_link_hash_table *htab;
        asection *vectors_sec;
 
        struct h8300_coff_link_hash_table *htab;
        asection *vectors_sec;
 
-       if (link_info->hash->creator != abfd->xvec)
+       if (link_info->output_bfd->xvec != abfd->xvec)
          {
            (*_bfd_error_handler)
              (_("cannot handle R_MEM_INDIRECT reloc when using %s output"),
          {
            (*_bfd_error_handler)
              (_("cannot handle R_MEM_INDIRECT reloc when using %s output"),
-              link_info->hash->creator->name);
+              link_info->output_bfd->xvec->name);
 
            /* What else can we do?  This function doesn't allow return
               of an error, and we don't want to call abort as that
 
            /* What else can we do?  This function doesn't allow return
               of an error, and we don't want to call abort as that
@@ -1132,7 +1153,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
            else
              {
                if (! ((*link_info->callbacks->reloc_overflow)
            else
              {
                if (! ((*link_info->callbacks->reloc_overflow)
-                      (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                      (link_info, NULL,
+                       bfd_asymbol_name (*reloc->sym_ptr_ptr),
                        reloc->howto->name, reloc->addend, input_section->owner,
                        input_section, reloc->address)))
                  abort ();
                        reloc->howto->name, reloc->addend, input_section->owner,
                        input_section, reloc->address)))
                  abort ();
@@ -1149,13 +1171,12 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        name = symbol->name;
        if (symbol->flags & BSF_LOCAL)
          {
        name = symbol->name;
        if (symbol->flags & BSF_LOCAL)
          {
-           char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
+           char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10);
+
            if (new_name == NULL)
              abort ();
 
            if (new_name == NULL)
              abort ();
 
-           strcpy (new_name, name);
-           sprintf (new_name + strlen (name), "_%08x",
-                    (int) symbol->section);
+           sprintf (new_name, "%s_%08x", name, symbol->section->id);
            name = new_name;
          }
 
            name = new_name;
          }
 
@@ -1178,21 +1199,28 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        src_address++;
 
        /* Now create an entry in the function vector itself.  */
        src_address++;
 
        /* Now create an entry in the function vector itself.  */
-       if (bfd_get_mach (input_section->owner) == bfd_mach_h8300)
-         bfd_put_16 (abfd,
-                     bfd_coff_reloc16_get_value (reloc,
-                                                 link_info,
-                                                 input_section),
-                     vectors_sec->contents + h->offset);
-       else if (bfd_get_mach (input_section->owner) == bfd_mach_h8300h
-                || bfd_get_mach (input_section->owner) == bfd_mach_h8300s)
-         bfd_put_32 (abfd,
-                     bfd_coff_reloc16_get_value (reloc,
-                                                 link_info,
-                                                 input_section),
-                     vectors_sec->contents + h->offset);
-       else
-         abort ();
+       switch (bfd_get_mach (input_section->owner))
+         {
+         case bfd_mach_h8300:
+         case bfd_mach_h8300hn:
+         case bfd_mach_h8300sn:
+           bfd_put_16 (abfd,
+                       bfd_coff_reloc16_get_value (reloc,
+                                                   link_info,
+                                                   input_section),
+                       vectors_sec->contents + h->offset);
+           break;
+         case bfd_mach_h8300h:
+         case bfd_mach_h8300s:
+           bfd_put_32 (abfd,
+                       bfd_coff_reloc16_get_value (reloc,
+                                                   link_info,
+                                                   input_section),
+                       vectors_sec->contents + h->offset);
+           break;
+         default:
+           abort ();
+         }
 
        /* Gross.  We've already written the contents of the vector section
           before we get here...  So we write it again with the new data.  */
 
        /* Gross.  We've already written the contents of the vector section
           before we get here...  So we write it again with the new data.  */
@@ -1200,7 +1228,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
                                  vectors_sec->output_section,
                                  vectors_sec->contents,
                                  (file_ptr) vectors_sec->output_offset,
                                  vectors_sec->output_section,
                                  vectors_sec->contents,
                                  (file_ptr) vectors_sec->output_offset,
-                                 vectors_sec->_raw_size);
+                                 vectors_sec->size);
        break;
       }
 
        break;
       }
 
@@ -1226,9 +1254,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
    selected static symbols to the bfd linker hash table.  */
 
 static bfd_boolean
    selected static symbols to the bfd linker hash table.  */
 
 static bfd_boolean
-h8300_bfd_link_add_symbols (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+h8300_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 {
   asection *sec;
   struct funcvec_hash_table *funcvec_hash_table;
 {
   asection *sec;
   struct funcvec_hash_table *funcvec_hash_table;
@@ -1238,7 +1264,7 @@ h8300_bfd_link_add_symbols (abfd, info)
   /* Add the symbols using the generic code.  */
   _bfd_generic_link_add_symbols (abfd, info);
 
   /* Add the symbols using the generic code.  */
   _bfd_generic_link_add_symbols (abfd, info);
 
-  if (info->hash->creator != abfd->xvec)
+  if (info->output_bfd->xvec != abfd->xvec)
     return TRUE;
 
   htab = h8300_coff_hash_table (info);
     return TRUE;
 
   htab = h8300_coff_hash_table (info);
@@ -1251,12 +1277,12 @@ h8300_bfd_link_add_symbols (abfd, info)
       /* Make sure the appropriate flags are set, including SEC_IN_MEMORY.  */
       flags = (SEC_ALLOC | SEC_LOAD
               | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
       /* Make sure the appropriate flags are set, including SEC_IN_MEMORY.  */
       flags = (SEC_ALLOC | SEC_LOAD
               | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
-      htab->vectors_sec = bfd_make_section (abfd, ".vectors");
+      htab->vectors_sec = bfd_make_section_with_flags (abfd, ".vectors",
+                                                      flags);
 
       /* If the section wasn't created, or we couldn't set the flags,
         quit quickly now, rather than dying a painful death later.  */
 
       /* If the section wasn't created, or we couldn't set the flags,
         quit quickly now, rather than dying a painful death later.  */
-      if (!htab->vectors_sec
-         || !bfd_set_section_flags (abfd, htab->vectors_sec, flags))
+      if (!htab->vectors_sec)
        return FALSE;
 
       /* Also create the vector hash table.  */
        return FALSE;
 
       /* Also create the vector hash table.  */
@@ -1268,7 +1294,8 @@ h8300_bfd_link_add_symbols (abfd, info)
 
       /* And initialize the funcvec hash table.  */
       if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
 
       /* And initialize the funcvec hash table.  */
       if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
-                                   funcvec_hash_newfunc))
+                                   funcvec_hash_newfunc,
+                                   sizeof (struct funcvec_hash_entry)))
        {
          bfd_release (abfd, funcvec_hash_table);
          return FALSE;
        {
          bfd_release (abfd, funcvec_hash_table);
          return FALSE;
@@ -1333,13 +1360,11 @@ h8300_bfd_link_add_symbols (abfd, info)
                {
                  char *new_name;
 
                {
                  char *new_name;
 
-                 new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
+                 new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10);
                  if (new_name == NULL)
                    abort ();
 
                  if (new_name == NULL)
                    abort ();
 
-                 strcpy (new_name, name);
-                 sprintf (new_name + strlen (name), "_%08x",
-                          (int) symbol->section);
+                 sprintf (new_name, "%s_%08x", name, symbol->section->id);
                  name = new_name;
                }
 
                  name = new_name;
                }
 
@@ -1360,11 +1385,20 @@ h8300_bfd_link_add_symbols (abfd, info)
 
                  /* Bump the size of the vectors section.  Each vector
                     takes 2 bytes on the h8300 and 4 bytes on the h8300h.  */
 
                  /* Bump the size of the vectors section.  Each vector
                     takes 2 bytes on the h8300 and 4 bytes on the h8300h.  */
-                 if (bfd_get_mach (abfd) == bfd_mach_h8300)
-                   htab->vectors_sec->_raw_size += 2;
-                 else if (bfd_get_mach (abfd) == bfd_mach_h8300h
-                          || bfd_get_mach (abfd) == bfd_mach_h8300s)
-                   htab->vectors_sec->_raw_size += 4;
+                 switch (bfd_get_mach (abfd))
+                   {
+                   case bfd_mach_h8300:
+                   case bfd_mach_h8300hn:
+                   case bfd_mach_h8300sn:
+                     htab->vectors_sec->size += 2;
+                     break;
+                   case bfd_mach_h8300h:
+                   case bfd_mach_h8300s:
+                     htab->vectors_sec->size += 4;
+                     break;
+                   default:
+                     abort ();
+                   }
                }
            }
        }
                }
            }
        }
@@ -1376,14 +1410,14 @@ h8300_bfd_link_add_symbols (abfd, info)
   /* Now actually allocate some space for the function vector.  It's
      wasteful to do this more than once, but this is easier.  */
   sec = htab->vectors_sec;
   /* Now actually allocate some space for the function vector.  It's
      wasteful to do this more than once, but this is easier.  */
   sec = htab->vectors_sec;
-  if (sec->_raw_size != 0)
+  if (sec->size != 0)
     {
       /* Free the old contents.  */
       if (sec->contents)
        free (sec->contents);
 
       /* Allocate new contents.  */
     {
       /* Free the old contents.  */
       if (sec->contents)
        free (sec->contents);
 
       /* Allocate new contents.  */
-      sec->contents = bfd_malloc (sec->_raw_size);
+      sec->contents = bfd_malloc (sec->size);
     }
 
   return TRUE;
     }
 
   return TRUE;
@@ -1395,6 +1429,11 @@ h8300_bfd_link_add_symbols (abfd, info)
 #define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create
 
 #define COFF_LONG_FILENAMES
 #define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create
 
 #define COFF_LONG_FILENAMES
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata     NULL
+#endif
+
 #include "coffcode.h"
 
 #undef coff_bfd_get_relocated_section_contents
 #include "coffcode.h"
 
 #undef coff_bfd_get_relocated_section_contents
@@ -1403,4 +1442,4 @@ h8300_bfd_link_add_symbols (abfd, info)
   bfd_coff_reloc16_get_relocated_section_contents
 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
 
   bfd_coff_reloc16_get_relocated_section_contents
 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
 
-CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL)
+CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
This page took 0.038016 seconds and 4 git commands to generate.