Back to index

cell-binutils  2.17cvs20070401
coff-h8300.c
Go to the documentation of this file.
00001 /* BFD back-end for Renesas H8/300 COFF binaries.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005    Written by Steve Chamberlain, <sac@cygnus.com>.
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libbfd.h"
00026 #include "bfdlink.h"
00027 #include "genlink.h"
00028 #include "coff/h8300.h"
00029 #include "coff/internal.h"
00030 #include "libcoff.h"
00031 #include "libiberty.h"
00032 
00033 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
00034 
00035 /* We derive a hash table from the basic BFD hash table to
00036    hold entries in the function vector.  Aside from the
00037    info stored by the basic hash table, we need the offset
00038    of a particular entry within the hash table as well as
00039    the offset where we'll add the next entry.  */
00040 
00041 struct funcvec_hash_entry
00042   {
00043     /* The basic hash table entry.  */
00044     struct bfd_hash_entry root;
00045 
00046     /* The offset within the vectors section where
00047        this entry lives.  */
00048     bfd_vma offset;
00049   };
00050 
00051 struct funcvec_hash_table
00052   {
00053     /* The basic hash table.  */
00054     struct bfd_hash_table root;
00055 
00056     bfd *abfd;
00057 
00058     /* Offset at which we'll add the next entry.  */
00059     unsigned int offset;
00060   };
00061 
00062 static struct bfd_hash_entry *
00063 funcvec_hash_newfunc
00064   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
00065 
00066 static bfd_reloc_status_type special
00067   (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
00068 static int select_reloc
00069   (reloc_howto_type *);
00070 static void rtype2howto
00071   (arelent *, struct internal_reloc *);
00072 static void reloc_processing
00073   (arelent *, struct internal_reloc *, asymbol **, bfd *, asection *);
00074 static bfd_boolean h8300_symbol_address_p
00075   (bfd *, asection *, bfd_vma);
00076 static int h8300_reloc16_estimate
00077   (bfd *, asection *, arelent *, unsigned int,
00078    struct bfd_link_info *);
00079 static void h8300_reloc16_extra_cases
00080   (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
00081    bfd_byte *, unsigned int *, unsigned int *);
00082 static bfd_boolean h8300_bfd_link_add_symbols
00083   (bfd *, struct bfd_link_info *);
00084 
00085 /* To lookup a value in the function vector hash table.  */
00086 #define funcvec_hash_lookup(table, string, create, copy) \
00087   ((struct funcvec_hash_entry *) \
00088    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
00089 
00090 /* The derived h8300 COFF linker table.  Note it's derived from
00091    the generic linker hash table, not the COFF backend linker hash
00092    table!  We use this to attach additional data structures we
00093    need while linking on the h8300.  */
00094 struct h8300_coff_link_hash_table {
00095   /* The main hash table.  */
00096   struct generic_link_hash_table root;
00097 
00098   /* Section for the vectors table.  This gets attached to a
00099      random input bfd, we keep it here for easy access.  */
00100   asection *vectors_sec;
00101 
00102   /* Hash table of the functions we need to enter into the function
00103      vector.  */
00104   struct funcvec_hash_table *funcvec_hash_table;
00105 };
00106 
00107 static struct bfd_link_hash_table *h8300_coff_link_hash_table_create (bfd *);
00108 
00109 /* Get the H8/300 COFF linker hash table from a link_info structure.  */
00110 
00111 #define h8300_coff_hash_table(p) \
00112   ((struct h8300_coff_link_hash_table *) ((coff_hash_table (p))))
00113 
00114 /* Initialize fields within a funcvec hash table entry.  Called whenever
00115    a new entry is added to the funcvec hash table.  */
00116 
00117 static struct bfd_hash_entry *
00118 funcvec_hash_newfunc (struct bfd_hash_entry *entry,
00119                     struct bfd_hash_table *gen_table,
00120                     const char *string)
00121 {
00122   struct funcvec_hash_entry *ret;
00123   struct funcvec_hash_table *table;
00124 
00125   ret = (struct funcvec_hash_entry *) entry;
00126   table = (struct funcvec_hash_table *) gen_table;
00127 
00128   /* Allocate the structure if it has not already been allocated by a
00129      subclass.  */
00130   if (ret == NULL)
00131     ret = ((struct funcvec_hash_entry *)
00132           bfd_hash_allocate (gen_table,
00133                            sizeof (struct funcvec_hash_entry)));
00134   if (ret == NULL)
00135     return NULL;
00136 
00137   /* Call the allocation method of the superclass.  */
00138   ret = ((struct funcvec_hash_entry *)
00139         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string));
00140 
00141   if (ret == NULL)
00142     return NULL;
00143 
00144   /* Note where this entry will reside in the function vector table.  */
00145   ret->offset = table->offset;
00146 
00147   /* Bump the offset at which we store entries in the function
00148      vector.  We'd like to bump up the size of the vectors section,
00149      but it's not easily available here.  */
00150  switch (bfd_get_mach (table->abfd))
00151    {
00152    case bfd_mach_h8300:
00153    case bfd_mach_h8300hn:
00154    case bfd_mach_h8300sn:
00155      table->offset += 2;
00156      break;
00157    case bfd_mach_h8300h:
00158    case bfd_mach_h8300s:
00159      table->offset += 4;
00160      break;
00161    default:
00162      return NULL;
00163    }
00164 
00165   /* Everything went OK.  */
00166   return (struct bfd_hash_entry *) ret;
00167 }
00168 
00169 /* Initialize the function vector hash table.  */
00170 
00171 static bfd_boolean
00172 funcvec_hash_table_init (struct funcvec_hash_table *table,
00173                       bfd *abfd,
00174                       struct bfd_hash_entry *(*newfunc)
00175                         (struct bfd_hash_entry *,
00176                          struct bfd_hash_table *,
00177                          const char *),
00178                       unsigned int entsize)
00179 {
00180   /* Initialize our local fields, then call the generic initialization
00181      routine.  */
00182   table->offset = 0;
00183   table->abfd = abfd;
00184   return (bfd_hash_table_init (&table->root, newfunc, entsize));
00185 }
00186 
00187 /* Create the derived linker hash table.  We use a derived hash table
00188    basically to hold "static" information during an H8/300 coff link
00189    without using static variables.  */
00190 
00191 static struct bfd_link_hash_table *
00192 h8300_coff_link_hash_table_create (bfd *abfd)
00193 {
00194   struct h8300_coff_link_hash_table *ret;
00195   bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
00196 
00197   ret = (struct h8300_coff_link_hash_table *) bfd_malloc (amt);
00198   if (ret == NULL)
00199     return NULL;
00200   if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
00201                               _bfd_generic_link_hash_newfunc,
00202                               sizeof (struct generic_link_hash_entry)))
00203     {
00204       free (ret);
00205       return NULL;
00206     }
00207 
00208   /* Initialize our data.  */
00209   ret->vectors_sec = NULL;
00210   ret->funcvec_hash_table = NULL;
00211 
00212   /* OK.  Everything's initialized, return the base pointer.  */
00213   return &ret->root.root;
00214 }
00215 
00216 /* Special handling for H8/300 relocs.
00217    We only come here for pcrel stuff and return normally if not an -r link.
00218    When doing -r, we can't do any arithmetic for the pcrel stuff, because
00219    the code in reloc.c assumes that we can manipulate the targets of
00220    the pcrel branches.  This isn't so, since the H8/300 can do relaxing,
00221    which means that the gap after the instruction may not be enough to
00222    contain the offset required for the branch, so we have to use only
00223    the addend until the final link.  */
00224 
00225 static bfd_reloc_status_type
00226 special (bfd *abfd ATTRIBUTE_UNUSED,
00227         arelent *reloc_entry ATTRIBUTE_UNUSED,
00228         asymbol *symbol ATTRIBUTE_UNUSED,
00229         PTR data ATTRIBUTE_UNUSED,
00230         asection *input_section ATTRIBUTE_UNUSED,
00231         bfd *output_bfd,
00232         char **error_message ATTRIBUTE_UNUSED)
00233 {
00234   if (output_bfd == (bfd *) NULL)
00235     return bfd_reloc_continue;
00236 
00237   /* Adjust the reloc address to that in the output section.  */
00238   reloc_entry->address += input_section->output_offset;
00239   return bfd_reloc_ok;
00240 }
00241 
00242 static reloc_howto_type howto_table[] = {
00243   HOWTO (R_RELBYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8", FALSE, 0x000000ff, 0x000000ff, FALSE),
00244   HOWTO (R_RELWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
00245   HOWTO (R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "32", FALSE, 0xffffffff, 0xffffffff, FALSE),
00246   HOWTO (R_PCRBYTE, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8", FALSE, 0x000000ff, 0x000000ff, TRUE),
00247   HOWTO (R_PCRWORD, 0, 1, 16, TRUE, 0, complain_overflow_signed, special, "DISP16", FALSE, 0x0000ffff, 0x0000ffff, TRUE),
00248   HOWTO (R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, special, "DISP32", FALSE, 0xffffffff, 0xffffffff, TRUE),
00249   HOWTO (R_MOV16B1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
00250   HOWTO (R_MOV16B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", FALSE, 0x000000ff, 0x000000ff, FALSE),
00251   HOWTO (R_JMP1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16/pcrel", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
00252   HOWTO (R_JMP2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pcrecl/16", FALSE, 0x000000ff, 0x000000ff, FALSE),
00253   HOWTO (R_JMPL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "24/pcrell", FALSE, 0x00ffffff, 0x00ffffff, FALSE),
00254   HOWTO (R_JMPL2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pc8/24", FALSE, 0x000000ff, 0x000000ff, FALSE),
00255   HOWTO (R_MOV24B1, 0, 1, 32, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", FALSE, 0xffffffff, 0xffffffff, FALSE),
00256   HOWTO (R_MOV24B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
00257 
00258   /* An indirect reference to a function.  This causes the function's address
00259      to be added to the function vector in lo-mem and puts the address of
00260      the function vector's entry in the jsr instruction.  */
00261   HOWTO (R_MEM_INDIRECT, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8/indirect", FALSE, 0x000000ff, 0x000000ff, FALSE),
00262 
00263   /* Internal reloc for relaxing.  This is created when a 16-bit pc-relative
00264      branch is turned into an 8-bit pc-relative branch.  */
00265   HOWTO (R_PCRWORD_B, 0, 0, 8, TRUE, 0, complain_overflow_bitfield, special, "relaxed bCC:16", FALSE, 0x000000ff, 0x000000ff, FALSE),
00266 
00267   HOWTO (R_MOVL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,special, "32/24 relaxable move", FALSE, 0xffffffff, 0xffffffff, FALSE),
00268 
00269   HOWTO (R_MOVL2, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "32/24 relaxed move", FALSE, 0x0000ffff, 0x0000ffff, FALSE),
00270 
00271   HOWTO (R_BCC_INV, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8 inverted", FALSE, 0x000000ff, 0x000000ff, TRUE),
00272 
00273   HOWTO (R_JMP_DEL, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "Deleted jump", FALSE, 0x000000ff, 0x000000ff, TRUE),
00274 };
00275 
00276 /* Turn a howto into a reloc number.  */
00277 
00278 #define SELECT_RELOC(x,howto) \
00279   { x.r_type = select_reloc (howto); }
00280 
00281 #define BADMAG(x) (H8300BADMAG (x) && H8300HBADMAG (x) && H8300SBADMAG (x) \
00282                                && H8300HNBADMAG(x) && H8300SNBADMAG(x))
00283 #define H8300 1                    /* Customize coffcode.h  */
00284 #define __A_MAGIC_SET__
00285 
00286 /* Code to swap in the reloc.  */
00287 #define SWAP_IN_RELOC_OFFSET       H_GET_32
00288 #define SWAP_OUT_RELOC_OFFSET      H_PUT_32
00289 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
00290   dst->r_stuff[0] = 'S'; \
00291   dst->r_stuff[1] = 'C';
00292 
00293 static int
00294 select_reloc (reloc_howto_type *howto)
00295 {
00296   return howto->type;
00297 }
00298 
00299 /* Code to turn a r_type into a howto ptr, uses the above howto table.  */
00300 
00301 static void
00302 rtype2howto (arelent *internal, struct internal_reloc *dst)
00303 {
00304   switch (dst->r_type)
00305     {
00306     case R_RELBYTE:
00307       internal->howto = howto_table + 0;
00308       break;
00309     case R_RELWORD:
00310       internal->howto = howto_table + 1;
00311       break;
00312     case R_RELLONG:
00313       internal->howto = howto_table + 2;
00314       break;
00315     case R_PCRBYTE:
00316       internal->howto = howto_table + 3;
00317       break;
00318     case R_PCRWORD:
00319       internal->howto = howto_table + 4;
00320       break;
00321     case R_PCRLONG:
00322       internal->howto = howto_table + 5;
00323       break;
00324     case R_MOV16B1:
00325       internal->howto = howto_table + 6;
00326       break;
00327     case R_MOV16B2:
00328       internal->howto = howto_table + 7;
00329       break;
00330     case R_JMP1:
00331       internal->howto = howto_table + 8;
00332       break;
00333     case R_JMP2:
00334       internal->howto = howto_table + 9;
00335       break;
00336     case R_JMPL1:
00337       internal->howto = howto_table + 10;
00338       break;
00339     case R_JMPL2:
00340       internal->howto = howto_table + 11;
00341       break;
00342     case R_MOV24B1:
00343       internal->howto = howto_table + 12;
00344       break;
00345     case R_MOV24B2:
00346       internal->howto = howto_table + 13;
00347       break;
00348     case R_MEM_INDIRECT:
00349       internal->howto = howto_table + 14;
00350       break;
00351     case R_PCRWORD_B:
00352       internal->howto = howto_table + 15;
00353       break;
00354     case R_MOVL1:
00355       internal->howto = howto_table + 16;
00356       break;
00357     case R_MOVL2:
00358       internal->howto = howto_table + 17;
00359       break;
00360     case R_BCC_INV:
00361       internal->howto = howto_table + 18;
00362       break;
00363     case R_JMP_DEL:
00364       internal->howto = howto_table + 19;
00365       break;
00366     default:
00367       abort ();
00368       break;
00369     }
00370 }
00371 
00372 #define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
00373 
00374 /* Perform any necessary magic to the addend in a reloc entry.  */
00375 
00376 #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
00377  cache_ptr->addend = ext_reloc.r_offset;
00378 
00379 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
00380  reloc_processing (relent, reloc, symbols, abfd, section)
00381 
00382 static void
00383 reloc_processing (arelent *relent, struct internal_reloc *reloc,
00384                 asymbol **symbols, bfd *abfd, asection *section)
00385 {
00386   relent->address = reloc->r_vaddr;
00387   rtype2howto (relent, reloc);
00388 
00389   if (((int) reloc->r_symndx) > 0)
00390     relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
00391   else
00392     relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00393 
00394   relent->addend = reloc->r_offset;
00395   relent->address -= section->vma;
00396 }
00397 
00398 static bfd_boolean
00399 h8300_symbol_address_p (bfd *abfd, asection *input_section, bfd_vma address)
00400 {
00401   asymbol **s;
00402 
00403   s = _bfd_generic_link_get_symbols (abfd);
00404   BFD_ASSERT (s != (asymbol **) NULL);
00405 
00406   /* Search all the symbols for one in INPUT_SECTION with
00407      address ADDRESS.  */
00408   while (*s)
00409     {
00410       asymbol *p = *s;
00411 
00412       if (p->section == input_section
00413          && (input_section->output_section->vma
00414              + input_section->output_offset
00415              + p->value) == address)
00416        return TRUE;
00417       s++;
00418     }
00419   return FALSE;
00420 }
00421 
00422 /* If RELOC represents a relaxable instruction/reloc, change it into
00423    the relaxed reloc, notify the linker that symbol addresses
00424    have changed (bfd_perform_slip) and return how much the current
00425    section has shrunk by.
00426 
00427    FIXME: Much of this code has knowledge of the ordering of entries
00428    in the howto table.  This needs to be fixed.  */
00429 
00430 static int
00431 h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc,
00432                      unsigned int shrink, struct bfd_link_info *link_info)
00433 {
00434   bfd_vma value;
00435   bfd_vma dot;
00436   bfd_vma gap;
00437   static asection *last_input_section = NULL;
00438   static arelent *last_reloc = NULL;
00439 
00440   /* The address of the thing to be relocated will have moved back by
00441      the size of the shrink - but we don't change reloc->address here,
00442      since we need it to know where the relocation lives in the source
00443      uncooked section.  */
00444   bfd_vma address = reloc->address - shrink;
00445 
00446   if (input_section != last_input_section)
00447     last_reloc = NULL;
00448 
00449   /* Only examine the relocs which might be relaxable.  */
00450   switch (reloc->howto->type)
00451     {
00452       /* This is the 16-/24-bit absolute branch which could become an
00453         8-bit pc-relative branch.  */
00454     case R_JMP1:
00455     case R_JMPL1:
00456       /* Get the address of the target of this branch.  */
00457       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00458 
00459       /* Get the address of the next instruction (not the reloc).  */
00460       dot = (input_section->output_section->vma
00461             + input_section->output_offset + address);
00462 
00463       /* Adjust for R_JMP1 vs R_JMPL1.  */
00464       dot += (reloc->howto->type == R_JMP1 ? 1 : 2);
00465 
00466       /* Compute the distance from this insn to the branch target.  */
00467       gap = value - dot;
00468 
00469       /* If the distance is within -128..+128 inclusive, then we can relax
00470         this jump.  +128 is valid since the target will move two bytes
00471         closer if we do relax this branch.  */
00472       if ((int) gap >= -128 && (int) gap <= 128)
00473        {
00474          bfd_byte code;
00475 
00476          if (!bfd_get_section_contents (abfd, input_section, & code,
00477                                     reloc->address, 1))
00478            break;
00479          code = bfd_get_8 (abfd, & code);
00480 
00481          /* It's possible we may be able to eliminate this branch entirely;
00482             if the previous instruction is a branch around this instruction,
00483             and there's no label at this instruction, then we can reverse
00484             the condition on the previous branch and eliminate this jump.
00485 
00486               original:                   new:
00487                bCC lab1                   bCC' lab2
00488                jmp lab2
00489               lab1:                       lab1:
00490 
00491             This saves 4 bytes instead of two, and should be relatively
00492             common.
00493 
00494             Only perform this optimisation for jumps (code 0x5a) not
00495             subroutine calls, as otherwise it could transform:
00496 
00497                           mov.w   r0,r0
00498                           beq     .L1
00499                           jsr     @_bar
00500                     .L1:   rts
00501                     _bar:  rts
00502             into:
00503                           mov.w   r0,r0
00504                           bne     _bar
00505                           rts
00506                     _bar:  rts
00507 
00508             which changes the call (jsr) into a branch (bne).  */
00509          if (code == 0x5a
00510              && gap <= 126
00511              && last_reloc
00512              && last_reloc->howto->type == R_PCRBYTE)
00513            {
00514              bfd_vma last_value;
00515              last_value = bfd_coff_reloc16_get_value (last_reloc, link_info,
00516                                                  input_section) + 1;
00517 
00518              if (last_value == dot + 2
00519                 && last_reloc->address + 1 == reloc->address
00520                 && !h8300_symbol_address_p (abfd, input_section, dot - 2))
00521               {
00522                 reloc->howto = howto_table + 19;
00523                 last_reloc->howto = howto_table + 18;
00524                 last_reloc->sym_ptr_ptr = reloc->sym_ptr_ptr;
00525                 last_reloc->addend = reloc->addend;
00526                 shrink += 4;
00527                 bfd_perform_slip (abfd, 4, input_section, address);
00528                 break;
00529               }
00530            }
00531 
00532          /* Change the reloc type.  */
00533          reloc->howto = reloc->howto + 1;
00534 
00535          /* This shrinks this section by two bytes.  */
00536          shrink += 2;
00537          bfd_perform_slip (abfd, 2, input_section, address);
00538        }
00539       break;
00540 
00541     /* This is the 16-bit pc-relative branch which could become an 8-bit
00542        pc-relative branch.  */
00543     case R_PCRWORD:
00544       /* Get the address of the target of this branch, add one to the value
00545         because the addend field in PCrel jumps is off by -1.  */
00546       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section) + 1;
00547 
00548       /* Get the address of the next instruction if we were to relax.  */
00549       dot = input_section->output_section->vma +
00550        input_section->output_offset + address;
00551 
00552       /* Compute the distance from this insn to the branch target.  */
00553       gap = value - dot;
00554 
00555       /* If the distance is within -128..+128 inclusive, then we can relax
00556         this jump.  +128 is valid since the target will move two bytes
00557         closer if we do relax this branch.  */
00558       if ((int) gap >= -128 && (int) gap <= 128)
00559        {
00560          /* Change the reloc type.  */
00561          reloc->howto = howto_table + 15;
00562 
00563          /* This shrinks this section by two bytes.  */
00564          shrink += 2;
00565          bfd_perform_slip (abfd, 2, input_section, address);
00566        }
00567       break;
00568 
00569     /* This is a 16-bit absolute address in a mov.b insn, which can
00570        become an 8-bit absolute address if it's in the right range.  */
00571     case R_MOV16B1:
00572       /* Get the address of the data referenced by this mov.b insn.  */
00573       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00574       value = bfd_h8300_pad_address (abfd, value);
00575 
00576       /* If the address is in the top 256 bytes of the address space
00577         then we can relax this instruction.  */
00578       if (value >= 0xffffff00u)
00579        {
00580          /* Change the reloc type.  */
00581          reloc->howto = reloc->howto + 1;
00582 
00583          /* This shrinks this section by two bytes.  */
00584          shrink += 2;
00585          bfd_perform_slip (abfd, 2, input_section, address);
00586        }
00587       break;
00588 
00589     /* Similarly for a 24-bit absolute address in a mov.b.  Note that
00590        if we can't relax this into an 8-bit absolute, we'll fall through
00591        and try to relax it into a 16-bit absolute.  */
00592     case R_MOV24B1:
00593       /* Get the address of the data referenced by this mov.b insn.  */
00594       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00595       value = bfd_h8300_pad_address (abfd, value);
00596 
00597       if (value >= 0xffffff00u)
00598        {
00599          /* Change the reloc type.  */
00600          reloc->howto = reloc->howto + 1;
00601 
00602          /* This shrinks this section by four bytes.  */
00603          shrink += 4;
00604          bfd_perform_slip (abfd, 4, input_section, address);
00605 
00606          /* Done with this reloc.  */
00607          break;
00608        }
00609 
00610       /* FALLTHROUGH and try to turn the 24-/32-bit reloc into a 16-bit
00611         reloc.  */
00612 
00613     /* This is a 24-/32-bit absolute address in a mov insn, which can
00614        become an 16-bit absolute address if it's in the right range.  */
00615     case R_MOVL1:
00616       /* Get the address of the data referenced by this mov insn.  */
00617       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00618       value = bfd_h8300_pad_address (abfd, value);
00619 
00620       /* If the address is a sign-extended 16-bit value then we can
00621          relax this instruction.  */
00622       if (value <= 0x7fff || value >= 0xffff8000u)
00623        {
00624          /* Change the reloc type.  */
00625          reloc->howto = howto_table + 17;
00626 
00627          /* This shrinks this section by two bytes.  */
00628          shrink += 2;
00629          bfd_perform_slip (abfd, 2, input_section, address);
00630        }
00631       break;
00632 
00633       /* No other reloc types represent relaxing opportunities.  */
00634     default:
00635       break;
00636     }
00637 
00638   last_reloc = reloc;
00639   last_input_section = input_section;
00640   return shrink;
00641 }
00642 
00643 /* Handle relocations for the H8/300, including relocs for relaxed
00644    instructions.
00645 
00646    FIXME: Not all relocations check for overflow!  */
00647 
00648 static void
00649 h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info,
00650                         struct bfd_link_order *link_order, arelent *reloc,
00651                         bfd_byte *data, unsigned int *src_ptr,
00652                         unsigned int *dst_ptr)
00653 {
00654   unsigned int src_address = *src_ptr;
00655   unsigned int dst_address = *dst_ptr;
00656   asection *input_section = link_order->u.indirect.section;
00657   bfd_vma value;
00658   bfd_vma dot;
00659   int gap, tmp;
00660   unsigned char temp_code;
00661 
00662   switch (reloc->howto->type)
00663     {
00664     /* Generic 8-bit pc-relative relocation.  */
00665     case R_PCRBYTE:
00666       /* Get the address of the target of this branch.  */
00667       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00668 
00669       dot = (input_section->output_offset
00670             + dst_address
00671             + link_order->u.indirect.section->output_section->vma);
00672 
00673       gap = value - dot;
00674 
00675       /* Sanity check.  */
00676       if (gap < -128 || gap > 126)
00677        {
00678          if (! ((*link_info->callbacks->reloc_overflow)
00679                (link_info, NULL,
00680                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
00681                 reloc->howto->name, reloc->addend, input_section->owner,
00682                 input_section, reloc->address)))
00683            abort ();
00684        }
00685 
00686       /* Everything looks OK.  Apply the relocation and update the
00687         src/dst address appropriately.  */
00688       bfd_put_8 (abfd, gap, data + dst_address);
00689       dst_address++;
00690       src_address++;
00691 
00692       /* All done.  */
00693       break;
00694 
00695     /* Generic 16-bit pc-relative relocation.  */
00696     case R_PCRWORD:
00697       /* Get the address of the target of this branch.  */
00698       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00699 
00700       /* Get the address of the instruction (not the reloc).  */
00701       dot = (input_section->output_offset
00702             + dst_address
00703             + link_order->u.indirect.section->output_section->vma + 1);
00704 
00705       gap = value - dot;
00706 
00707       /* Sanity check.  */
00708       if (gap > 32766 || gap < -32768)
00709        {
00710          if (! ((*link_info->callbacks->reloc_overflow)
00711                (link_info, NULL,
00712                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
00713                 reloc->howto->name, reloc->addend, input_section->owner,
00714                 input_section, reloc->address)))
00715            abort ();
00716        }
00717 
00718       /* Everything looks OK.  Apply the relocation and update the
00719         src/dst address appropriately.  */
00720       bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address);
00721       dst_address += 2;
00722       src_address += 2;
00723 
00724       /* All done.  */
00725       break;
00726 
00727     /* Generic 8-bit absolute relocation.  */
00728     case R_RELBYTE:
00729       /* Get the address of the object referenced by this insn.  */
00730       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00731 
00732       bfd_put_8 (abfd, value & 0xff, data + dst_address);
00733       dst_address += 1;
00734       src_address += 1;
00735 
00736       /* All done.  */
00737       break;
00738 
00739     /* Various simple 16-bit absolute relocations.  */
00740     case R_MOV16B1:
00741     case R_JMP1:
00742     case R_RELWORD:
00743       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00744       bfd_put_16 (abfd, value, data + dst_address);
00745       dst_address += 2;
00746       src_address += 2;
00747       break;
00748 
00749     /* Various simple 24-/32-bit absolute relocations.  */
00750     case R_MOV24B1:
00751     case R_MOVL1:
00752     case R_RELLONG:
00753       /* Get the address of the target of this branch.  */
00754       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00755       bfd_put_32 (abfd, value, data + dst_address);
00756       dst_address += 4;
00757       src_address += 4;
00758       break;
00759 
00760     /* Another 24-/32-bit absolute relocation.  */
00761     case R_JMPL1:
00762       /* Get the address of the target of this branch.  */
00763       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00764 
00765       value = ((value & 0x00ffffff)
00766               | (bfd_get_32 (abfd, data + src_address) & 0xff000000));
00767       bfd_put_32 (abfd, value, data + dst_address);
00768       dst_address += 4;
00769       src_address += 4;
00770       break;
00771 
00772       /* This is a 24-/32-bit absolute address in one of the following
00773         instructions:
00774 
00775           "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
00776           "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", "ldc.w",
00777           "stc.w" and "mov.[bwl]"
00778 
00779         We may relax this into an 16-bit absolute address if it's in
00780         the right range.  */
00781     case R_MOVL2:
00782       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00783       value = bfd_h8300_pad_address (abfd, value);
00784 
00785       /* Sanity check.  */
00786       if (value <= 0x7fff || value >= 0xffff8000u)
00787        {
00788          /* Insert the 16-bit value into the proper location.  */
00789          bfd_put_16 (abfd, value, data + dst_address);
00790 
00791          /* Fix the opcode.  For all the instructions that belong to
00792             this relaxation, we simply need to turn off bit 0x20 in
00793             the previous byte.  */
00794          data[dst_address - 1] &= ~0x20;
00795          dst_address += 2;
00796          src_address += 4;
00797        }
00798       else
00799        {
00800          if (! ((*link_info->callbacks->reloc_overflow)
00801                (link_info, NULL,
00802                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
00803                 reloc->howto->name, reloc->addend, input_section->owner,
00804                 input_section, reloc->address)))
00805            abort ();
00806        }
00807       break;
00808 
00809     /* A 16-bit absolute branch that is now an 8-bit pc-relative branch.  */
00810     case R_JMP2:
00811       /* Get the address of the target of this branch.  */
00812       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00813 
00814       /* Get the address of the next instruction.  */
00815       dot = (input_section->output_offset
00816             + dst_address
00817             + link_order->u.indirect.section->output_section->vma + 1);
00818 
00819       gap = value - dot;
00820 
00821       /* Sanity check.  */
00822       if (gap < -128 || gap > 126)
00823        {
00824          if (! ((*link_info->callbacks->reloc_overflow)
00825                (link_info, NULL,
00826                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
00827                 reloc->howto->name, reloc->addend, input_section->owner,
00828                 input_section, reloc->address)))
00829            abort ();
00830        }
00831 
00832       /* Now fix the instruction itself.  */
00833       switch (data[dst_address - 1])
00834        {
00835        case 0x5e:
00836          /* jsr -> bsr */
00837          bfd_put_8 (abfd, 0x55, data + dst_address - 1);
00838          break;
00839        case 0x5a:
00840          /* jmp -> bra */
00841          bfd_put_8 (abfd, 0x40, data + dst_address - 1);
00842          break;
00843 
00844        default:
00845          abort ();
00846        }
00847 
00848       /* Write out the 8-bit value.  */
00849       bfd_put_8 (abfd, gap, data + dst_address);
00850 
00851       dst_address += 1;
00852       src_address += 3;
00853 
00854       break;
00855 
00856     /* A 16-bit pc-relative branch that is now an 8-bit pc-relative branch.  */
00857     case R_PCRWORD_B:
00858       /* Get the address of the target of this branch.  */
00859       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00860 
00861       /* Get the address of the instruction (not the reloc).  */
00862       dot = (input_section->output_offset
00863             + dst_address
00864             + link_order->u.indirect.section->output_section->vma - 1);
00865 
00866       gap = value - dot;
00867 
00868       /* Sanity check.  */
00869       if (gap < -128 || gap > 126)
00870        {
00871          if (! ((*link_info->callbacks->reloc_overflow)
00872                (link_info, NULL,
00873                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
00874                 reloc->howto->name, reloc->addend, input_section->owner,
00875                 input_section, reloc->address)))
00876            abort ();
00877        }
00878 
00879       /* Now fix the instruction.  */
00880       switch (data[dst_address - 2])
00881        {
00882        case 0x58:
00883          /* bCC:16 -> bCC:8 */
00884          /* Get the second byte of the original insn, which contains
00885             the condition code.  */
00886          tmp = data[dst_address - 1];
00887 
00888          /* Compute the fisrt byte of the relaxed instruction.  The
00889             original sequence 0x58 0xX0 is relaxed to 0x4X, where X
00890             represents the condition code.  */
00891          tmp &= 0xf0;
00892          tmp >>= 4;
00893          tmp |= 0x40;
00894 
00895          /* Write it.  */
00896          bfd_put_8 (abfd, tmp, data + dst_address - 2);
00897          break;
00898 
00899        case 0x5c:
00900          /* bsr:16 -> bsr:8 */
00901          bfd_put_8 (abfd, 0x55, data + dst_address - 2);
00902          break;
00903 
00904        default:
00905          abort ();
00906        }
00907 
00908       /* Output the target.  */
00909       bfd_put_8 (abfd, gap, data + dst_address - 1);
00910 
00911       /* We don't advance dst_address -- the 8-bit reloc is applied at
00912         dst_address - 1, so the next insn should begin at dst_address.  */
00913       src_address += 2;
00914 
00915       break;
00916 
00917     /* Similarly for a 24-bit absolute that is now 8 bits.  */
00918     case R_JMPL2:
00919       /* Get the address of the target of this branch.  */
00920       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00921 
00922       /* Get the address of the instruction (not the reloc).  */
00923       dot = (input_section->output_offset
00924             + dst_address
00925             + link_order->u.indirect.section->output_section->vma + 2);
00926 
00927       gap = value - dot;
00928 
00929       /* Fix the instruction.  */
00930       switch (data[src_address])
00931        {
00932        case 0x5e:
00933          /* jsr -> bsr */
00934          bfd_put_8 (abfd, 0x55, data + dst_address);
00935          break;
00936        case 0x5a:
00937          /* jmp ->bra */
00938          bfd_put_8 (abfd, 0x40, data + dst_address);
00939          break;
00940        default:
00941          abort ();
00942        }
00943 
00944       bfd_put_8 (abfd, gap, data + dst_address + 1);
00945       dst_address += 2;
00946       src_address += 4;
00947 
00948       break;
00949 
00950       /* This is a 16-bit absolute address in one of the following
00951         instructions:
00952 
00953           "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
00954           "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
00955           "mov.b"
00956 
00957         We may relax this into an 8-bit absolute address if it's in
00958         the right range.  */
00959     case R_MOV16B2:
00960       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
00961 
00962       /* All instructions with R_H8_DIR16B2 start with 0x6a.  */
00963       if (data[dst_address - 2] != 0x6a)
00964        abort ();
00965 
00966       temp_code = data[src_address - 1];
00967 
00968       /* If this is a mov.b instruction, clear the lower nibble, which
00969         contains the source/destination register number.  */
00970       if ((temp_code & 0x10) != 0x10)
00971        temp_code &= 0xf0;
00972 
00973       /* Fix up the opcode.  */
00974       switch (temp_code)
00975        {
00976        case 0x00:
00977          /* This is mov.b @aa:16,Rd.  */
00978          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
00979          break;
00980        case 0x80:
00981          /* This is mov.b Rs,@aa:16.  */
00982          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
00983          break;
00984        case 0x18:
00985          /* This is a bit-maniputation instruction that stores one
00986             bit into memory, one of "bclr", "bist", "bnot", "bset",
00987             and "bst".  */
00988          data[dst_address - 2] = 0x7f;
00989          break;
00990        case 0x10:
00991          /* This is a bit-maniputation instruction that loads one bit
00992             from memory, one of "band", "biand", "bild", "bior",
00993             "bixor", "bld", "bor", "btst", and "bxor".  */
00994          data[dst_address - 2] = 0x7e;
00995          break;
00996        default:
00997          abort ();
00998        }
00999 
01000       bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
01001       src_address += 2;
01002       break;
01003 
01004       /* This is a 24-bit absolute address in one of the following
01005         instructions:
01006 
01007           "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
01008           "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
01009           "mov.b"
01010 
01011         We may relax this into an 8-bit absolute address if it's in
01012         the right range.  */
01013     case R_MOV24B2:
01014       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
01015 
01016       /* All instructions with R_MOV24B2 start with 0x6a.  */
01017       if (data[dst_address - 2] != 0x6a)
01018        abort ();
01019 
01020       temp_code = data[src_address - 1];
01021 
01022       /* If this is a mov.b instruction, clear the lower nibble, which
01023         contains the source/destination register number.  */
01024       if ((temp_code & 0x30) != 0x30)
01025        temp_code &= 0xf0;
01026 
01027       /* Fix up the opcode.  */
01028       switch (temp_code)
01029        {
01030        case 0x20:
01031          /* This is mov.b @aa:24/32,Rd.  */
01032          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
01033          break;
01034        case 0xa0:
01035          /* This is mov.b Rs,@aa:24/32.  */
01036          data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
01037          break;
01038        case 0x38:
01039          /* This is a bit-maniputation instruction that stores one
01040             bit into memory, one of "bclr", "bist", "bnot", "bset",
01041             and "bst".  */
01042          data[dst_address - 2] = 0x7f;
01043          break;
01044        case 0x30:
01045          /* This is a bit-maniputation instruction that loads one bit
01046             from memory, one of "band", "biand", "bild", "bior",
01047             "bixor", "bld", "bor", "btst", and "bxor".  */
01048          data[dst_address - 2] = 0x7e;
01049          break;
01050        default:
01051          abort ();
01052        }
01053 
01054       bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
01055       src_address += 4;
01056       break;
01057 
01058     case R_BCC_INV:
01059       /* Get the address of the target of this branch.  */
01060       value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
01061 
01062       dot = (input_section->output_offset
01063             + dst_address
01064             + link_order->u.indirect.section->output_section->vma) + 1;
01065 
01066       gap = value - dot;
01067 
01068       /* Sanity check.  */
01069       if (gap < -128 || gap > 126)
01070        {
01071          if (! ((*link_info->callbacks->reloc_overflow)
01072                (link_info, NULL,
01073                 bfd_asymbol_name (*reloc->sym_ptr_ptr),
01074                 reloc->howto->name, reloc->addend, input_section->owner,
01075                 input_section, reloc->address)))
01076            abort ();
01077        }
01078 
01079       /* Everything looks OK.  Fix the condition in the instruction, apply
01080         the relocation, and update the src/dst address appropriately.  */
01081 
01082       bfd_put_8 (abfd, bfd_get_8 (abfd, data + dst_address - 1) ^ 1,
01083                data + dst_address - 1);
01084       bfd_put_8 (abfd, gap, data + dst_address);
01085       dst_address++;
01086       src_address++;
01087 
01088       /* All done.  */
01089       break;
01090 
01091     case R_JMP_DEL:
01092       src_address += 4;
01093       break;
01094 
01095     /* An 8-bit memory indirect instruction (jmp/jsr).
01096 
01097        There's several things that need to be done to handle
01098        this relocation.
01099 
01100        If this is a reloc against the absolute symbol, then
01101        we should handle it just R_RELBYTE.  Likewise if it's
01102        for a symbol with a value ge 0 and le 0xff.
01103 
01104        Otherwise it's a jump/call through the function vector,
01105        and the linker is expected to set up the function vector
01106        and put the right value into the jump/call instruction.  */
01107     case R_MEM_INDIRECT:
01108       {
01109        /* We need to find the symbol so we can determine it's
01110           address in the function vector table.  */
01111        asymbol *symbol;
01112        const char *name;
01113        struct funcvec_hash_table *ftab;
01114        struct funcvec_hash_entry *h;
01115        struct h8300_coff_link_hash_table *htab;
01116        asection *vectors_sec;
01117 
01118        if (link_info->hash->creator != abfd->xvec)
01119          {
01120            (*_bfd_error_handler)
01121              (_("cannot handle R_MEM_INDIRECT reloc when using %s output"),
01122               link_info->hash->creator->name);
01123 
01124            /* What else can we do?  This function doesn't allow return
01125               of an error, and we don't want to call abort as that
01126               indicates an internal error.  */
01127 #ifndef EXIT_FAILURE
01128 #define EXIT_FAILURE 1
01129 #endif
01130            xexit (EXIT_FAILURE);
01131          }
01132        htab = h8300_coff_hash_table (link_info);
01133        vectors_sec = htab->vectors_sec;
01134 
01135        /* First see if this is a reloc against the absolute symbol
01136           or against a symbol with a nonnegative value <= 0xff.  */
01137        symbol = *(reloc->sym_ptr_ptr);
01138        value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
01139        if (symbol == bfd_abs_section_ptr->symbol
01140            || value <= 0xff)
01141          {
01142            /* This should be handled in a manner very similar to
01143               R_RELBYTES.   If the value is in range, then just slam
01144               the value into the right location.  Else trigger a
01145               reloc overflow callback.  */
01146            if (value <= 0xff)
01147              {
01148               bfd_put_8 (abfd, value, data + dst_address);
01149               dst_address += 1;
01150               src_address += 1;
01151              }
01152            else
01153              {
01154               if (! ((*link_info->callbacks->reloc_overflow)
01155                      (link_info, NULL,
01156                      bfd_asymbol_name (*reloc->sym_ptr_ptr),
01157                      reloc->howto->name, reloc->addend, input_section->owner,
01158                      input_section, reloc->address)))
01159                 abort ();
01160              }
01161            break;
01162          }
01163 
01164        /* This is a jump/call through a function vector, and we're
01165           expected to create the function vector ourselves.
01166 
01167           First look up this symbol in the linker hash table -- we need
01168           the derived linker symbol which holds this symbol's index
01169           in the function vector.  */
01170        name = symbol->name;
01171        if (symbol->flags & BSF_LOCAL)
01172          {
01173            char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10);
01174 
01175            if (new_name == NULL)
01176              abort ();
01177 
01178            sprintf (new_name, "%s_%08x", name, symbol->section->id);
01179            name = new_name;
01180          }
01181 
01182        ftab = htab->funcvec_hash_table;
01183        h = funcvec_hash_lookup (ftab, name, FALSE, FALSE);
01184 
01185        /* This shouldn't ever happen.  If it does that means we've got
01186           data corruption of some kind.  Aborting seems like a reasonable
01187           thing to do here.  */
01188        if (h == NULL || vectors_sec == NULL)
01189          abort ();
01190 
01191        /* Place the address of the function vector entry into the
01192           reloc's address.  */
01193        bfd_put_8 (abfd,
01194                  vectors_sec->output_offset + h->offset,
01195                  data + dst_address);
01196 
01197        dst_address++;
01198        src_address++;
01199 
01200        /* Now create an entry in the function vector itself.  */
01201        switch (bfd_get_mach (input_section->owner))
01202          {
01203          case bfd_mach_h8300:
01204          case bfd_mach_h8300hn:
01205          case bfd_mach_h8300sn:
01206            bfd_put_16 (abfd,
01207                      bfd_coff_reloc16_get_value (reloc,
01208                                               link_info,
01209                                               input_section),
01210                      vectors_sec->contents + h->offset);
01211            break;
01212          case bfd_mach_h8300h:
01213          case bfd_mach_h8300s:
01214            bfd_put_32 (abfd,
01215                      bfd_coff_reloc16_get_value (reloc,
01216                                               link_info,
01217                                               input_section),
01218                      vectors_sec->contents + h->offset);
01219            break;
01220          default:
01221            abort ();
01222          }
01223 
01224        /* Gross.  We've already written the contents of the vector section
01225           before we get here...  So we write it again with the new data.  */
01226        bfd_set_section_contents (vectors_sec->output_section->owner,
01227                               vectors_sec->output_section,
01228                               vectors_sec->contents,
01229                               (file_ptr) vectors_sec->output_offset,
01230                               vectors_sec->size);
01231        break;
01232       }
01233 
01234     default:
01235       abort ();
01236       break;
01237 
01238     }
01239 
01240   *src_ptr = src_address;
01241   *dst_ptr = dst_address;
01242 }
01243 
01244 /* Routine for the h8300 linker.
01245 
01246    This routine is necessary to handle the special R_MEM_INDIRECT
01247    relocs on the h8300.  It's responsible for generating a vectors
01248    section and attaching it to an input bfd as well as sizing
01249    the vectors section.  It also creates our vectors hash table.
01250 
01251    It uses the generic linker routines to actually add the symbols.
01252    from this BFD to the bfd linker hash table.  It may add a few
01253    selected static symbols to the bfd linker hash table.  */
01254 
01255 static bfd_boolean
01256 h8300_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
01257 {
01258   asection *sec;
01259   struct funcvec_hash_table *funcvec_hash_table;
01260   bfd_size_type amt;
01261   struct h8300_coff_link_hash_table *htab;
01262 
01263   /* Add the symbols using the generic code.  */
01264   _bfd_generic_link_add_symbols (abfd, info);
01265 
01266   if (info->hash->creator != abfd->xvec)
01267     return TRUE;
01268 
01269   htab = h8300_coff_hash_table (info);
01270 
01271   /* If we haven't created a vectors section, do so now.  */
01272   if (!htab->vectors_sec)
01273     {
01274       flagword flags;
01275 
01276       /* Make sure the appropriate flags are set, including SEC_IN_MEMORY.  */
01277       flags = (SEC_ALLOC | SEC_LOAD
01278               | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
01279       htab->vectors_sec = bfd_make_section_with_flags (abfd, ".vectors",
01280                                                  flags);
01281 
01282       /* If the section wasn't created, or we couldn't set the flags,
01283         quit quickly now, rather than dying a painful death later.  */
01284       if (!htab->vectors_sec)
01285        return FALSE;
01286 
01287       /* Also create the vector hash table.  */
01288       amt = sizeof (struct funcvec_hash_table);
01289       funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt);
01290 
01291       if (!funcvec_hash_table)
01292        return FALSE;
01293 
01294       /* And initialize the funcvec hash table.  */
01295       if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
01296                                 funcvec_hash_newfunc,
01297                                 sizeof (struct funcvec_hash_entry)))
01298        {
01299          bfd_release (abfd, funcvec_hash_table);
01300          return FALSE;
01301        }
01302 
01303       /* Store away a pointer to the funcvec hash table.  */
01304       htab->funcvec_hash_table = funcvec_hash_table;
01305     }
01306 
01307   /* Load up the function vector hash table.  */
01308   funcvec_hash_table = htab->funcvec_hash_table;
01309 
01310   /* Now scan the relocs for all the sections in this bfd; create
01311      additional space in the .vectors section as needed.  */
01312   for (sec = abfd->sections; sec; sec = sec->next)
01313     {
01314       long reloc_size, reloc_count, i;
01315       asymbol **symbols;
01316       arelent **relocs;
01317 
01318       /* Suck in the relocs, symbols & canonicalize them.  */
01319       reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
01320       if (reloc_size <= 0)
01321        continue;
01322 
01323       relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
01324       if (!relocs)
01325        return FALSE;
01326 
01327       /* The symbols should have been read in by _bfd_generic link_add_symbols
01328         call abovec, so we can cheat and use the pointer to them that was
01329         saved in the above call.  */
01330       symbols = _bfd_generic_link_get_symbols(abfd);
01331       reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, symbols);
01332       if (reloc_count <= 0)
01333        {
01334          free (relocs);
01335          continue;
01336        }
01337 
01338       /* Now walk through all the relocations in this section.  */
01339       for (i = 0; i < reloc_count; i++)
01340        {
01341          arelent *reloc = relocs[i];
01342          asymbol *symbol = *(reloc->sym_ptr_ptr);
01343          const char *name;
01344 
01345          /* We've got an indirect reloc.  See if we need to add it
01346             to the function vector table.   At this point, we have
01347             to add a new entry for each unique symbol referenced
01348             by an R_MEM_INDIRECT relocation except for a reloc
01349             against the absolute section symbol.  */
01350          if (reloc->howto->type == R_MEM_INDIRECT
01351              && symbol != bfd_abs_section_ptr->symbol)
01352 
01353            {
01354              struct funcvec_hash_table *ftab;
01355              struct funcvec_hash_entry *h;
01356 
01357              name = symbol->name;
01358              if (symbol->flags & BSF_LOCAL)
01359               {
01360                 char *new_name;
01361 
01362                 new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10);
01363                 if (new_name == NULL)
01364                   abort ();
01365 
01366                 sprintf (new_name, "%s_%08x", name, symbol->section->id);
01367                 name = new_name;
01368               }
01369 
01370              /* Look this symbol up in the function vector hash table.  */
01371              ftab = htab->funcvec_hash_table;
01372              h = funcvec_hash_lookup (ftab, name, FALSE, FALSE);
01373 
01374              /* If this symbol isn't already in the hash table, add
01375                it and bump up the size of the hash table.  */
01376              if (h == NULL)
01377               {
01378                 h = funcvec_hash_lookup (ftab, name, TRUE, TRUE);
01379                 if (h == NULL)
01380                   {
01381                     free (relocs);
01382                     return FALSE;
01383                   }
01384 
01385                 /* Bump the size of the vectors section.  Each vector
01386                    takes 2 bytes on the h8300 and 4 bytes on the h8300h.  */
01387                 switch (bfd_get_mach (abfd))
01388                   {
01389                   case bfd_mach_h8300:
01390                   case bfd_mach_h8300hn:
01391                   case bfd_mach_h8300sn:
01392                     htab->vectors_sec->size += 2;
01393                     break;
01394                   case bfd_mach_h8300h:
01395                   case bfd_mach_h8300s:
01396                     htab->vectors_sec->size += 4;
01397                     break;
01398                   default:
01399                     abort ();
01400                   }
01401               }
01402            }
01403        }
01404 
01405       /* We're done with the relocations, release them.  */
01406       free (relocs);
01407     }
01408 
01409   /* Now actually allocate some space for the function vector.  It's
01410      wasteful to do this more than once, but this is easier.  */
01411   sec = htab->vectors_sec;
01412   if (sec->size != 0)
01413     {
01414       /* Free the old contents.  */
01415       if (sec->contents)
01416        free (sec->contents);
01417 
01418       /* Allocate new contents.  */
01419       sec->contents = bfd_malloc (sec->size);
01420     }
01421 
01422   return TRUE;
01423 }
01424 
01425 #define coff_reloc16_extra_cases h8300_reloc16_extra_cases
01426 #define coff_reloc16_estimate h8300_reloc16_estimate
01427 #define coff_bfd_link_add_symbols h8300_bfd_link_add_symbols
01428 #define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create
01429 
01430 #define COFF_LONG_FILENAMES
01431 #include "coffcode.h"
01432 
01433 #undef coff_bfd_get_relocated_section_contents
01434 #undef coff_bfd_relax_section
01435 #define coff_bfd_get_relocated_section_contents \
01436   bfd_coff_reloc16_get_relocated_section_contents
01437 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
01438 
01439 CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)