Patch from David Mosberger.
[deliverable/binutils-gdb.git] / bfd / coff-h8300.c
index acde6300a9652bd97d393d7e3fbac3af1649b190..e21c5b5484227487c56d0cced49cc5dd53de36e9 100644 (file)
@@ -1,23 +1,24 @@
 /* BFD back-end for Hitachi H8/300 COFF binaries.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Steve Chamberlain, <sac@cygnus.com>.
 
-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"
@@ -27,46 +28,66 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "coff/h8300.h"
 #include "coff/internal.h"
 #include "libcoff.h"
+#include "libiberty.h"
 
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
 
 /* We derive a hash table from the basic BFD hash table to
-   hold entries in the function vector.  Aside from the 
+   hold entries in the function vector.  Aside from the
    info stored by the basic hash table, we need the offset
    of a particular entry within the hash table as well as
    the offset where we'll add the next entry.  */
 
 struct funcvec_hash_entry
-{
-  /* The basic hash table entry.  */
-  struct bfd_hash_entry root;
+  {
+    /* The basic hash table entry.  */
+    struct bfd_hash_entry root;
 
-  /* The offset within the vectors section where
-     this entry lives.  */
-  bfd_vma offset;
-};
+    /* The offset within the vectors section where
+       this entry lives.  */
+    bfd_vma offset;
+  };
 
 struct funcvec_hash_table
-{
-  /* The basic hash table.  */
-  struct bfd_hash_table root;
+  {
+    /* The basic hash table.  */
+    struct bfd_hash_table root;
 
-  bfd *abfd;
+    bfd *abfd;
 
-  /* Offset at which we'll add the next entry.  */
-  unsigned int offset;
-};
+    /* Offset at which we'll add the next entry.  */
+    unsigned int offset;
+  };
 
 static struct bfd_hash_entry *
 funcvec_hash_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
 
-static boolean
+static bfd_boolean
 funcvec_hash_table_init
   PARAMS ((struct funcvec_hash_table *, bfd *,
-           struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *,
-                                               struct bfd_hash_table *,
-                                               const char *))));
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+static bfd_reloc_status_type special
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static int select_reloc
+  PARAMS ((reloc_howto_type *));
+static void rtype2howto
+  PARAMS ((arelent *, struct internal_reloc *));
+static void reloc_processing
+  PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
+static bfd_boolean h8300_symbol_address_p
+  PARAMS ((bfd *, asection *, bfd_vma));
+static int h8300_reloc16_estimate
+  PARAMS ((bfd *, asection *, arelent *, unsigned int,
+    struct bfd_link_info *));
+static void h8300_reloc16_extra_cases
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+    bfd_byte *, unsigned int *, unsigned int *));
+static bfd_boolean h8300_bfd_link_add_symbols
+  PARAMS ((bfd *, struct bfd_link_info *));
 
 /* To lookup a value in the function vector hash table.  */
 #define funcvec_hash_lookup(table, string, create, copy) \
@@ -77,8 +98,7 @@ funcvec_hash_table_init
    the generic linker hash table, not the COFF backend linker hash
    table!  We use this to attach additional data structures we
    need while linking on the h8300.  */
-struct h8300_coff_link_hash_table
-{
+struct h8300_coff_link_hash_table {
   /* The main hash table.  */
   struct generic_link_hash_table root;
 
@@ -118,14 +138,14 @@ funcvec_hash_newfunc (entry, gen_table, string)
      subclass.  */
   if (ret == NULL)
     ret = ((struct funcvec_hash_entry *)
-           bfd_hash_allocate (gen_table,
-                              sizeof (struct funcvec_hash_entry)));
+          bfd_hash_allocate (gen_table,
+                             sizeof (struct funcvec_hash_entry)));
   if (ret == NULL)
     return NULL;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct funcvec_hash_entry *)
-         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string));
+        bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string));
 
   if (ret == NULL)
     return NULL;
@@ -150,13 +170,13 @@ funcvec_hash_newfunc (entry, gen_table, string)
 
 /* Initialize the function vector hash table.  */
 
-static boolean
+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 *));
+     struct bfd_hash_entry *(*newfunc)
+       PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+               const char *));
 {
   /* Initialize our local fields, then call the generic initialization
      routine.  */
@@ -166,7 +186,7 @@ funcvec_hash_table_init (table, abfd, newfunc)
 }
 
 /* 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 *
@@ -174,13 +194,15 @@ h8300_coff_link_hash_table_create (abfd)
      bfd *abfd;
 {
   struct h8300_coff_link_hash_table *ret;
-  ret = ((struct h8300_coff_link_hash_table *)
-         bfd_alloc (abfd, sizeof (struct h8300_coff_link_hash_table)));
+  bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
+
+  ret = (struct h8300_coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
-  if (!_bfd_link_hash_table_init (&ret->root.root, abfd, _bfd_generic_link_hash_newfunc))
+  if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
+                                 _bfd_generic_link_hash_newfunc))
     {
-      bfd_release (abfd, ret);
+      free (ret);
       return NULL;
     }
 
@@ -196,7 +218,7 @@ h8300_coff_link_hash_table_create (abfd)
    We only come here for pcrel stuff and return normally if not an -r link.
    When doing -r, we can't do any arithmetic for the pcrel stuff, because
    the code in reloc.c assumes that we can manipulate the targets of
-   the pcrel branches.  This isn't so, since the H8/300 can do relaxing, 
+   the pcrel branches.  This isn't so, since the H8/300 can do relaxing,
    which means that the gap after the instruction may not be enough to
    contain the offset required for the branch, so we have to use only
    the addend until the final link.  */
@@ -220,53 +242,52 @@ special (abfd, reloc_entry, symbol, data, input_section, output_bfd,
   return bfd_reloc_ok;
 }
 
-static reloc_howto_type howto_table[] =
-{
-  HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false),
-  HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false),
-  HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false),
-  HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true),
-  HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true),
-  HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true),
-  HOWTO (R_MOV16B1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", false, 0x0000ffff, 0x0000ffff, false),
-  HOWTO (R_MOV16B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", false, 0x000000ff, 0x000000ff, false),
-  HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false),
-  HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false),
-  HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false),
-  HOWTO (R_JMPL2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false),
-  HOWTO (R_MOV24B1, 0, 1, 32, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", false, 0xffffffff, 0xffffffff, false),
-  HOWTO (R_MOV24B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", false, 0x0000ffff, 0x0000ffff, false),
+static reloc_howto_type howto_table[] = {
+  HOWTO (R_RELBYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8", FALSE, 0x000000ff, 0x000000ff, FALSE),
+  HOWTO (R_RELWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
+  HOWTO (R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "32", FALSE, 0xffffffff, 0xffffffff, FALSE),
+  HOWTO (R_PCRBYTE, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8", FALSE, 0x000000ff, 0x000000ff, TRUE),
+  HOWTO (R_PCRWORD, 0, 1, 16, TRUE, 0, complain_overflow_signed, special, "DISP16", FALSE, 0x0000ffff, 0x0000ffff, TRUE),
+  HOWTO (R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, special, "DISP32", FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO (R_MOV16B1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
+  HOWTO (R_MOV16B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", FALSE, 0x000000ff, 0x000000ff, FALSE),
+  HOWTO (R_JMP1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16/pcrel", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
+  HOWTO (R_JMP2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pcrecl/16", FALSE, 0x000000ff, 0x000000ff, FALSE),
+  HOWTO (R_JMPL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "24/pcrell", FALSE, 0x00ffffff, 0x00ffffff, FALSE),
+  HOWTO (R_JMPL2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pc8/24", FALSE, 0x000000ff, 0x000000ff, FALSE),
+  HOWTO (R_MOV24B1, 0, 1, 32, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", FALSE, 0xffffffff, 0xffffffff, FALSE),
+  HOWTO (R_MOV24B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
 
   /* An indirect reference to a function.  This causes the function's address
      to be added to the function vector in lo-mem and puts the address of
      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),
+  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.  */
-  HOWTO (R_PCRWORD_B, 0, 0, 8, true, 0, complain_overflow_bitfield, special, "relaxed bCC:16", false, 0x000000ff, 0x000000ff, 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),
+  HOWTO (R_MOVL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,special, "32/24 relaxable move", FALSE, 0xffffffff, 0xffffffff, FALSE),
 
-  HOWTO (R_MOVL2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "32/24 relaxed move", false, 0x0000ffff, 0x0000ffff, false),
+  HOWTO (R_MOVL2, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "32/24 relaxed move", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
 
-  HOWTO (R_BCC_INV, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8 inverted", false, 0x000000ff, 0x000000ff, true),
+  HOWTO (R_BCC_INV, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8 inverted", FALSE, 0x000000ff, 0x000000ff, TRUE),
 
-  HOWTO (R_JMP_DEL, 0, 0, 8, true, 0, complain_overflow_signed, special, "Deleted jump", false, 0x000000ff, 0x000000ff, true),
+  HOWTO (R_JMP_DEL, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "Deleted jump", FALSE, 0x000000ff, 0x000000ff, TRUE),
 };
 
 /* Turn a howto into a reloc number.  */
 
 #define SELECT_RELOC(x,howto) \
-  { x.r_type = select_reloc(howto); }
+  { x.r_type = select_reloc (howto); }
 
-#define BADMAG(x) (H8300BADMAG(x) && H8300HBADMAG(x) && H8300SBADMAG(x))
+#define BADMAG(x) (H8300BADMAG (x) && H8300HBADMAG (x) && H8300SBADMAG (x))
 #define H8300 1                        /* Customize coffcode.h */
 #define __A_MAGIC_SET__
 
 /* Code to swap in the reloc.  */
-#define SWAP_IN_RELOC_OFFSET   bfd_h_get_32
-#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_IN_RELOC_OFFSET   H_GET_32
+#define SWAP_OUT_RELOC_OFFSET  H_PUT_32
 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
   dst->r_stuff[0] = 'S'; \
   dst->r_stuff[1] = 'C';
@@ -353,15 +374,15 @@ rtype2howto (internal, dst)
     }
 }
 
-#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
 
 /* Perform any necessary magic to the addend in a reloc entry.  */
 
 #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
- cache_ptr->addend =  ext_reloc.r_offset;
+ cache_ptr->addend = ext_reloc.r_offset;
 
 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
- reloc_processing(relent, reloc, symbols, abfd, section)
+ reloc_processing (relent, reloc, symbols, abfd, section)
 
 static void
 reloc_processing (relent, reloc, symbols, abfd, section)
@@ -391,7 +412,7 @@ reloc_processing (relent, reloc, symbols, abfd, section)
 #endif
 }
 
-static boolean
+static bfd_boolean
 h8300_symbol_address_p (abfd, input_section, address)
      bfd *abfd;
      asection *input_section;
@@ -411,10 +432,10 @@ h8300_symbol_address_p (abfd, input_section, address)
          && (input_section->output_section->vma
              + input_section->output_offset
              + p->value) == address)
-       return true;
+       return TRUE;
       s++;
     }
-  return false;
+  return FALSE;
 }
 
 /* If RELOC represents a relaxable instruction/reloc, change it into
@@ -439,7 +460,7 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
   static asection *last_input_section = NULL;
   static arelent *last_reloc = NULL;
 
-  /* The address of the thing to be relocated will have moved back by 
+  /* The address of the thing to be relocated will have moved back by
      the size of the shrink - but we don't change reloc->address here,
      since we need it to know where the relocation lives in the source
      uncooked section.  */
@@ -450,7 +471,7 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
 
   /* 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.  */
     case R_JMP1:
@@ -471,8 +492,15 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
       /* If the distance is within -128..+128 inclusive, then we can relax
         this jump.  +128 is valid since the target will move two bytes
         closer if we do relax this branch.  */
-      if ((int)gap >= -128 && (int)gap <= 128 )
-       { 
+      if ((int) gap >= -128 && (int) gap <= 128)
+       {
+         bfd_byte code;
+
+         if (!bfd_get_section_contents (abfd, input_section, & code,
+                                        reloc->address, 1))
+           break;
+         code = bfd_get_8 (abfd, & code);
+
          /* It's possible we may be able to eliminate this branch entirely;
             if the previous instruction is a branch around this instruction,
             and there's no label at this instruction, then we can reverse
@@ -482,11 +510,27 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
                 bCC lab1                       bCC' lab2
                 jmp lab2
                lab1:                           lab1:
-       
-            This saves 4 bytes instead of two, and should be relatively
-            common.  */
 
-         if (gap <= 126
+            This saves 4 bytes instead of two, and should be relatively
+            common.
+
+            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
+             && gap <= 126
              && last_reloc
              && last_reloc->howto->type == R_PCRBYTE)
            {
@@ -521,7 +565,7 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
        pc-relative branch.  */
     case R_PCRWORD:
       /* Get the address of the target of this branch, add one to the value
-         because the addend field in PCrel jumps is off by -1.  */
+        because the addend field in PCrel jumps is off by -1.  */
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section) + 1;
 
       /* Get the address of the next instruction if we were to relax.  */
@@ -534,8 +578,8 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
       /* If the distance is within -128..+128 inclusive, then we can relax
         this jump.  +128 is valid since the target will move two bytes
         closer if we do relax this branch.  */
-      if ((int)gap >= -128 && (int)gap <= 128 )
-       { 
+      if ((int) gap >= -128 && (int) gap <= 128)
+       {
          /* Change the reloc type.  */
          reloc->howto = howto_table + 15;
 
@@ -606,7 +650,7 @@ h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* If this address is in 0x0000..0x7fff inclusive or
-         0xff8000..0xffffff inclusive, then it can be relaxed.  */
+        0xff8000..0xffffff inclusive, then it can be relaxed.  */
       if (value <= 0x7fff || value >= 0xff8000)
        {
          /* Change the reloc type.  */
@@ -690,8 +734,8 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
 
       /* Get the address of the instruction (not the reloc).  */
-      dot = (link_order->offset 
-            + dst_address 
+      dot = (link_order->offset
+            + dst_address
             + link_order->u.indirect.section->output_section->vma + 1);
 
       gap = value - dot;
@@ -709,7 +753,7 @@ 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.  */
 
-      bfd_put_16 (abfd, gap, data + dst_address);
+      bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address);
       dst_address += 2;
       src_address += 2;
 
@@ -724,7 +768,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
       /* Sanity check.  */
       if (value <= 0xff
          || (value >= 0x0000ff00 && value <= 0x0000ffff)
-         || (value >= 0x00ffff00 && value <= 0x00ffffff)
+         || (value >= 0x00ffff00 && value <= 0x00ffffff)
          || (value >= 0xffffff00 && value <= 0xffffffff))
        {
          /* Everything looks OK.  Apply the relocation and update the
@@ -792,7 +836,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
 
          /* Fix the opcode.  For all the move insns, we simply
             need to turn off bit 0x20 in the previous byte.  */
-          data[dst_address - 1] &= ~0x20;
+         data[dst_address - 1] &= ~0x20;
          dst_address += 2;
          src_address += 4;
        }
@@ -803,7 +847,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
                  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.  */
@@ -900,15 +944,15 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
          abort ();
        }
 
-       /* 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
-          dst_address - 1, so the next insn should begin at dst_address.  */
-       src_address += 2;
+      /* We don't advance dst_address -- the 8bit reloc is applied at
+        dst_address - 1, so the next insn should begin at dst_address.  */
+      src_address += 2;
+
+      break;
 
-       break;
-      
     /* Similarly for a 24bit absolute that is now 8 bits.  */
     case R_JMPL2:
       /* Get the address of the target of this branch.  */
@@ -1045,10 +1089,28 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        /* We need to find the symbol so we can determine it's
           address in the function vector table.  */
        asymbol *symbol;
-       bfd_vma value;
        const char *name;
+       struct funcvec_hash_table *ftab;
        struct funcvec_hash_entry *h;
-       asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec;
+       struct h8300_coff_link_hash_table *htab;
+       asection *vectors_sec;
+
+       if (link_info->hash->creator != abfd->xvec)
+         {
+           (*_bfd_error_handler)
+             (_("cannot handle R_MEM_INDIRECT reloc when using %s output"),
+              link_info->hash->creator->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
+              indicates an internal error.  */
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+           xexit (EXIT_FAILURE);
+         }
+       htab = h8300_coff_hash_table (link_info);
+       vectors_sec = htab->vectors_sec;
 
        /* First see if this is a reloc against the absolute symbol
           or against a symbol with a nonnegative value <= 0xff.  */
@@ -1079,7 +1141,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
          }
 
        /* This is a jump/call through a function vector, and we're
-          expected to create the function vector ourselves. 
+          expected to create the function vector ourselves.
 
           First look up this symbol in the linker hash table -- we need
           the derived linker symbol which holds this symbol's index
@@ -1087,7 +1149,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        name = symbol->name;
        if (symbol->flags & BSF_LOCAL)
          {
-           char *new_name = bfd_malloc (strlen (name) + 9);
+           char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
            if (new_name == NULL)
              abort ();
 
@@ -1097,12 +1159,12 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
            name = new_name;
          }
 
-       h = funcvec_hash_lookup (h8300_coff_hash_table (link_info)->funcvec_hash_table,
-                                name, false, false);
+       ftab = htab->funcvec_hash_table;
+       h = funcvec_hash_lookup (ftab, name, FALSE, FALSE);
 
        /* This shouldn't ever happen.  If it does that means we've got
           data corruption of some kind.  Aborting seems like a reasonable
-          think to do here.  */
+          thing to do here.  */
        if (h == NULL || vectors_sec == NULL)
          abort ();
 
@@ -1137,7 +1199,7 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
        bfd_set_section_contents (vectors_sec->output_section->owner,
                                  vectors_sec->output_section,
                                  vectors_sec->contents,
-                                 vectors_sec->output_offset,
+                                 (file_ptr) vectors_sec->output_offset,
                                  vectors_sec->_raw_size);
        break;
       }
@@ -1163,57 +1225,61 @@ h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
    from this BFD to the bfd linker hash table.  It may add a few
    selected static symbols to the bfd linker hash table.  */
 
-static boolean
+static bfd_boolean
 h8300_bfd_link_add_symbols (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
 {
   asection *sec;
   struct funcvec_hash_table *funcvec_hash_table;
+  bfd_size_type amt;
+  struct h8300_coff_link_hash_table *htab;
+
+  /* Add the symbols using the generic code.  */
+  _bfd_generic_link_add_symbols (abfd, info);
+
+  if (info->hash->creator != abfd->xvec)
+    return TRUE;
+
+  htab = h8300_coff_hash_table (info);
 
   /* If we haven't created a vectors section, do so now.  */
-  if (!h8300_coff_hash_table (info)->vectors_sec)
+  if (!htab->vectors_sec)
     {
       flagword flags;
 
       /* Make sure the appropriate flags are set, including SEC_IN_MEMORY.  */
       flags = (SEC_ALLOC | SEC_LOAD
               | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
-      h8300_coff_hash_table (info)->vectors_sec = bfd_make_section (abfd,
-                                                                   ".vectors");
+      htab->vectors_sec = bfd_make_section (abfd, ".vectors");
 
       /* If the section wasn't created, or we couldn't set the flags,
-        quit quickly now, rather than dieing a painful death later.  */
-      if (! h8300_coff_hash_table (info)->vectors_sec
-         || ! bfd_set_section_flags (abfd,
-                                     h8300_coff_hash_table(info)->vectors_sec,
-                                     flags))
-       return false;
+        quit quickly now, rather than dying a painful death later.  */
+      if (!htab->vectors_sec
+         || !bfd_set_section_flags (abfd, htab->vectors_sec, flags))
+       return FALSE;
 
       /* Also create the vector hash table.  */
-      funcvec_hash_table = ((struct funcvec_hash_table *)
-       bfd_alloc (abfd, sizeof (struct funcvec_hash_table)));
+      amt = sizeof (struct funcvec_hash_table);
+      funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt);
 
       if (!funcvec_hash_table)
-       return false;
+       return FALSE;
 
       /* And initialize the funcvec hash table.  */
       if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
                                    funcvec_hash_newfunc))
        {
          bfd_release (abfd, funcvec_hash_table);
-         return false;
+         return FALSE;
        }
 
       /* Store away a pointer to the funcvec hash table.  */
-      h8300_coff_hash_table (info)->funcvec_hash_table = funcvec_hash_table;
+      htab->funcvec_hash_table = funcvec_hash_table;
     }
 
   /* Load up the function vector hash table.  */
-  funcvec_hash_table = h8300_coff_hash_table (info)->funcvec_hash_table;
-
-  /* Add the symbols using the generic code.  */
-  _bfd_generic_link_add_symbols (abfd, info);
+  funcvec_hash_table = htab->funcvec_hash_table;
 
   /* Now scan the relocs for all the sections in this bfd; create
      additional space in the .vectors section as needed.  */
@@ -1228,9 +1294,9 @@ h8300_bfd_link_add_symbols (abfd, info)
       if (reloc_size <= 0)
        continue;
 
-      relocs = (arelent **) bfd_malloc ((size_t) reloc_size);
+      relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
       if (!relocs)
-       return false;
+       return FALSE;
 
       /* The symbols should have been read in by _bfd_generic link_add_symbols
         call abovec, so we can cheat and use the pointer to them that was
@@ -1259,13 +1325,15 @@ h8300_bfd_link_add_symbols (abfd, info)
              && symbol != bfd_abs_section_ptr->symbol)
 
            {
+             struct funcvec_hash_table *ftab;
              struct funcvec_hash_entry *h;
 
              name = symbol->name;
              if (symbol->flags & BSF_LOCAL)
                {
-                 char *new_name = bfd_malloc (strlen (name) + 9);
+                 char *new_name;
 
+                 new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
                  if (new_name == NULL)
                    abort ();
 
@@ -1276,29 +1344,27 @@ h8300_bfd_link_add_symbols (abfd, info)
                }
 
              /* Look this symbol up in the function vector hash table.  */
-             h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
-                                      name, false, false);
-
+             ftab = htab->funcvec_hash_table;
+             h = funcvec_hash_lookup (ftab, name, FALSE, FALSE);
 
              /* If this symbol isn't already in the hash table, add
                 it and bump up the size of the hash table.  */
              if (h == NULL)
                {
-                 h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
-                                          name, true, true);
+                 h = funcvec_hash_lookup (ftab, name, TRUE, TRUE);
                  if (h == NULL)
                    {
                      free (relocs);
-                     return false;
+                     return FALSE;
                    }
 
                  /* 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)
-                   h8300_coff_hash_table (info)->vectors_sec->_raw_size += 2;
+                   htab->vectors_sec->_raw_size += 2;
                  else if (bfd_get_mach (abfd) == bfd_mach_h8300h
                           || bfd_get_mach (abfd) == bfd_mach_h8300s)
-                   h8300_coff_hash_table (info)->vectors_sec->_raw_size += 4;
+                   htab->vectors_sec->_raw_size += 4;
                }
            }
        }
@@ -1309,18 +1375,18 @@ 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.  */
-  if (h8300_coff_hash_table (info)->vectors_sec->_raw_size != 0)
+  sec = htab->vectors_sec;
+  if (sec->_raw_size != 0)
     {
       /* Free the old contents.  */
-      if (h8300_coff_hash_table (info)->vectors_sec->contents)
-       free (h8300_coff_hash_table (info)->vectors_sec->contents);
+      if (sec->contents)
+       free (sec->contents);
 
       /* Allocate new contents.  */
-      h8300_coff_hash_table (info)->vectors_sec->contents
-       = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size);
+      sec->contents = bfd_malloc (sec->_raw_size);
     }
 
-  return true;
+  return TRUE;
 }
 
 #define coff_reloc16_extra_cases h8300_reloc16_extra_cases
This page took 0.045035 seconds and 4 git commands to generate.