Back to index

cell-binutils  2.17cvs20070401
elf32-sh64.c
Go to the documentation of this file.
00001 /* SuperH SH64-specific support for 32-bit ELF
00002    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #define SH64_ELF
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "elf-bfd.h"
00026 #include "../opcodes/sh64-opc.h"
00027 #include "elf32-sh64.h"
00028 
00029 /* Add a suffix for datalabel indirection symbols.  It must not match any
00030    other symbols; user symbols with or without version or other
00031    decoration.  It must only be used internally and not emitted by any
00032    means.  */
00033 #define DATALABEL_SUFFIX " DL"
00034 
00035 /* Used to hold data for function called through bfd_map_over_sections.  */
00036 struct sh64_find_section_vma_data
00037  {
00038    asection *section;
00039    bfd_vma addr;
00040  };
00041 
00042 static bfd_boolean sh64_elf_new_section_hook
00043   (bfd *, asection *);
00044 static bfd_boolean sh64_elf_copy_private_data
00045   (bfd *, bfd *);
00046 static bfd_boolean sh64_elf_merge_private_data
00047   (bfd *, bfd *);
00048 static bfd_boolean sh64_elf_fake_sections
00049   (bfd *, Elf_Internal_Shdr *, asection *);
00050 static bfd_boolean sh64_elf_set_private_flags
00051   (bfd *, flagword);
00052 static bfd_boolean sh64_elf_set_mach_from_flags
00053   (bfd *);
00054 static bfd_boolean shmedia_prepare_reloc
00055   (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00056    const Elf_Internal_Rela *, bfd_vma *);
00057 static int sh64_elf_get_symbol_type
00058   (Elf_Internal_Sym *, int);
00059 static bfd_boolean sh64_elf_add_symbol_hook
00060   (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
00061    flagword *, asection **, bfd_vma *);
00062 static bfd_boolean sh64_elf_link_output_symbol_hook
00063   (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
00064    struct elf_link_hash_entry *);
00065 static bfd_boolean sh64_backend_section_from_shdr
00066   (bfd *, Elf_Internal_Shdr *, const char *, int);
00067 static void sh64_elf_final_write_processing
00068   (bfd *, bfd_boolean);
00069 static bfd_boolean sh64_bfd_elf_copy_private_section_data
00070   (bfd *, asection *, bfd *, asection *);
00071 static void sh64_find_section_for_address
00072   (bfd *, asection *, void *);
00073 
00074 /* Let elf32-sh.c handle the "bfd_" definitions, so we only have to
00075    intrude with an #ifndef around the function definition.  */
00076 #define sh_elf_copy_private_data          sh64_elf_copy_private_data
00077 #define sh_elf_merge_private_data         sh64_elf_merge_private_data
00078 #define sh_elf_set_private_flags          sh64_elf_set_private_flags
00079 /* Typo in elf32-sh.c (and unlinear name).  */
00080 #define bfd_elf32_bfd_set_private_flags          sh64_elf_set_private_flags
00081 #define sh_elf_set_mach_from_flags        sh64_elf_set_mach_from_flags
00082 
00083 #define elf_backend_sign_extend_vma              1
00084 #define elf_backend_fake_sections         sh64_elf_fake_sections
00085 #define elf_backend_get_symbol_type              sh64_elf_get_symbol_type
00086 #define elf_backend_add_symbol_hook              sh64_elf_add_symbol_hook
00087 #define elf_backend_link_output_symbol_hook \
00088        sh64_elf_link_output_symbol_hook
00089 #define elf_backend_merge_symbol_attribute       sh64_elf_merge_symbol_attribute
00090 #define elf_backend_final_write_processing       sh64_elf_final_write_processing
00091 #define elf_backend_section_from_shdr            sh64_backend_section_from_shdr
00092 #define elf_backend_special_sections             sh64_elf_special_sections
00093 #define elf_backend_section_flags         sh64_elf_section_flags
00094 
00095 #define bfd_elf32_new_section_hook        sh64_elf_new_section_hook
00096 
00097 /* For objcopy, we need to set up sh64_elf_section_data (asection *) from
00098    incoming section flags.  This is otherwise done in sh64elf.em when
00099    linking or tc-sh64.c when assembling.  */
00100 #define bfd_elf32_bfd_copy_private_section_data \
00101        sh64_bfd_elf_copy_private_section_data
00102 
00103 /* This COFF-only function (only compiled with COFF support, making
00104    ELF-only chains problematic) returns TRUE early for SH4, so let's just
00105    define it TRUE here.  */
00106 #define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) TRUE
00107 
00108 #define GOT_BIAS (-((long)-32768))
00109 #define INCLUDE_SHMEDIA
00110 #define SH_TARGET_ALREADY_DEFINED
00111 #include "elf32-sh.c"
00112 
00113 /* Tack some extra info on struct bfd_elf_section_data.  */
00114 
00115 static bfd_boolean
00116 sh64_elf_new_section_hook (bfd *abfd, asection *sec)
00117 {
00118   if (!sec->used_by_bfd)
00119     {
00120       struct _sh64_elf_section_data *sdata;
00121       bfd_size_type amt = sizeof (*sdata);
00122 
00123       sdata = bfd_zalloc (abfd, amt);
00124       if (sdata == NULL)
00125        return FALSE;
00126       sec->used_by_bfd = sdata;
00127     }
00128 
00129   return _bfd_elf_new_section_hook (abfd, sec);
00130 }
00131 
00132 /* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
00133    through SHT_SH5_CR_SORTED on a sorted .cranges section.  */
00134 
00135 bfd_boolean
00136 sh64_elf_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
00137                      Elf_Internal_Shdr *elf_section_hdr,
00138                      asection *asect)
00139 {
00140   if (sh64_elf_section_data (asect)->sh64_info != NULL)
00141     elf_section_hdr->sh_flags
00142       |= sh64_elf_section_data (asect)->sh64_info->contents_flags;
00143 
00144   /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted
00145      .cranges section passing through objcopy.  */
00146   if ((bfd_get_section_flags (output_bfd, asect) & SEC_SORT_ENTRIES) != 0
00147       && strcmp (bfd_get_section_name (output_bfd, asect),
00148                SH64_CRANGES_SECTION_NAME) == 0)
00149     elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;
00150 
00151   return TRUE;
00152 }
00153 
00154 static bfd_boolean
00155 sh64_elf_set_mach_from_flags (bfd *abfd)
00156 {
00157   flagword flags = elf_elfheader (abfd)->e_flags;
00158 
00159   switch (flags & EF_SH_MACH_MASK)
00160     {
00161     case EF_SH5:
00162       /* These are fit to execute on SH5.  Just one but keep the switch
00163         construct to make additions easy.  */
00164       bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
00165       break;
00166 
00167     default:
00168       bfd_set_error (bfd_error_wrong_format);
00169       return FALSE;
00170     }
00171 
00172   return TRUE;
00173 }
00174 
00175 static bfd_boolean
00176 sh64_elf_section_flags (flagword *flags,
00177                      const Elf_Internal_Shdr *hdr)
00178 {
00179   if (hdr->bfd_section == NULL)
00180     return FALSE;
00181 
00182   if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
00183     *flags |= SEC_DEBUGGING;
00184 
00185   return TRUE;
00186 }
00187 
00188 static bfd_boolean
00189 sh64_elf_copy_private_data (bfd * ibfd, bfd * obfd)
00190 {
00191   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00192       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00193     return TRUE;
00194 
00195   BFD_ASSERT (!elf_flags_init (obfd)
00196              || (elf_elfheader (obfd)->e_flags
00197                 == elf_elfheader (ibfd)->e_flags));
00198 
00199   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
00200   return TRUE;
00201 }
00202 
00203 static bfd_boolean
00204 sh64_elf_merge_private_data (bfd *ibfd, bfd *obfd)
00205 {
00206   flagword old_flags, new_flags;
00207 
00208   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
00209     return FALSE;
00210 
00211   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00212       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00213     return TRUE;
00214 
00215   if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
00216     {
00217       const char *msg;
00218 
00219       if (bfd_get_arch_size (ibfd) == 32
00220          && bfd_get_arch_size (obfd) == 64)
00221        msg = _("%s: compiled as 32-bit object and %s is 64-bit");
00222       else if (bfd_get_arch_size (ibfd) == 64
00223               && bfd_get_arch_size (obfd) == 32)
00224        msg = _("%s: compiled as 64-bit object and %s is 32-bit");
00225       else
00226        msg = _("%s: object size does not match that of target %s");
00227 
00228       (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
00229                           bfd_get_filename (obfd));
00230       bfd_set_error (bfd_error_wrong_format);
00231       return FALSE;
00232     }
00233 
00234   old_flags = elf_elfheader (obfd)->e_flags;
00235   new_flags = elf_elfheader (ibfd)->e_flags;
00236   if (! elf_flags_init (obfd))
00237     {
00238       /* This happens when ld starts out with a 'blank' output file.  */
00239       elf_flags_init (obfd) = TRUE;
00240       elf_elfheader (obfd)->e_flags = old_flags = new_flags;
00241     }
00242   /* We don't allow linking in non-SH64 code.  */
00243   else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
00244     {
00245       (*_bfd_error_handler)
00246        ("%s: uses non-SH64 instructions while previous modules use SH64 instructions",
00247         bfd_get_filename (ibfd));
00248       bfd_set_error (bfd_error_bad_value);
00249       return FALSE;
00250     }
00251 
00252   /* I can't think of anything sane other than old_flags being EF_SH5 and
00253      that we need to preserve that.  */
00254   elf_elfheader (obfd)->e_flags = old_flags;
00255   return sh64_elf_set_mach_from_flags (obfd);
00256 }
00257 
00258 /* Handle a SH64-specific section when reading an object file.  This
00259    is called when bfd_section_from_shdr finds a section with an unknown
00260    type.
00261 
00262    We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */
00263 
00264 bfd_boolean
00265 sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
00266                             const char *name, int shindex)
00267 {
00268   flagword flags = 0;
00269 
00270   /* We do like MIPS with a bit switch for recognized types, and returning
00271      FALSE for a recognized section type with an unexpected name.  Right
00272      now we only have one recognized type, but that might change.  */
00273   switch (hdr->sh_type)
00274     {
00275     case SHT_SH5_CR_SORTED:
00276       if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)
00277        return FALSE;
00278 
00279       /* We set the SEC_SORT_ENTRIES flag so it can be passed on to
00280         sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object
00281         passes through objcopy.  Perhaps it is brittle; the flag can
00282         suddenly be used by other BFD parts, but it seems not really used
00283         anywhere at the moment.  */
00284       flags = SEC_DEBUGGING | SEC_SORT_ENTRIES;
00285       break;
00286 
00287     default:
00288       return FALSE;
00289     }
00290 
00291   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
00292     return FALSE;
00293 
00294   if (flags
00295       && ! bfd_set_section_flags (abfd, hdr->bfd_section,
00296                               bfd_get_section_flags (abfd,
00297                                                   hdr->bfd_section)
00298                               | flags))
00299     return FALSE;
00300 
00301   return TRUE;
00302 }
00303 
00304 /* In contrast to sh64_backend_section_from_shdr, this is called for all
00305    sections, but only when copying sections, not when linking or
00306    assembling.  We need to set up the sh64_elf_section_data (asection *)
00307    structure for the SH64 ELF section flags to be copied correctly.  */
00308 
00309 bfd_boolean
00310 sh64_bfd_elf_copy_private_section_data (bfd *ibfd, asection *isec,
00311                                    bfd *obfd, asection *osec)
00312 {
00313   struct sh64_section_data *sh64_sec_data;
00314 
00315   if (ibfd->xvec->flavour != bfd_target_elf_flavour
00316       || obfd->xvec->flavour != bfd_target_elf_flavour)
00317     return TRUE;
00318 
00319   if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
00320     return FALSE;
00321 
00322   sh64_sec_data = sh64_elf_section_data (isec)->sh64_info;
00323   if (sh64_sec_data == NULL)
00324     {
00325       sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));
00326 
00327       if (sh64_sec_data == NULL)
00328        return FALSE;
00329 
00330       sh64_sec_data->contents_flags
00331        = (elf_section_data (isec)->this_hdr.sh_flags
00332           & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));
00333 
00334       sh64_elf_section_data (osec)->sh64_info = sh64_sec_data;
00335     }
00336 
00337   return TRUE;
00338 }
00339 
00340 /* Function to keep SH64 specific file flags.  */
00341 
00342 static bfd_boolean
00343 sh64_elf_set_private_flags (bfd *abfd, flagword flags)
00344 {
00345   BFD_ASSERT (! elf_flags_init (abfd)
00346              || elf_elfheader (abfd)->e_flags == flags);
00347 
00348   elf_elfheader (abfd)->e_flags = flags;
00349   elf_flags_init (abfd) = TRUE;
00350   return sh64_elf_set_mach_from_flags (abfd);
00351 }
00352 
00353 /* Called when writing out an object file to decide the type of a symbol.  */
00354 
00355 static int
00356 sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
00357 {
00358   if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
00359     return STT_DATALABEL;
00360 
00361   return type;
00362 }
00363 
00364 /* Hook called by the linker routine which adds symbols from an object
00365    file.  We must make indirect symbols for undefined symbols marked with
00366    STT_DATALABEL, so relocations passing them will pick up that attribute
00367    and neutralize STO_SH5_ISA32 found on the symbol definition.
00368 
00369    There is a problem, though: We want to fill in the hash-table entry for
00370    this symbol and signal to the caller that no further processing is
00371    needed.  But we don't have the index for this hash-table entry.  We
00372    rely here on that the current entry is the first hash-entry with NULL,
00373    which seems brittle.  Also, iterating over the hash-table to find that
00374    entry is a linear operation on the number of symbols in this input
00375    file, and this function should take constant time, so that's not good
00376    too.  Only comfort is that DataLabel references should only be found in
00377    hand-written assembly code and thus be rare.  FIXME: Talk maintainers
00378    into adding an option to elf_add_symbol_hook (preferably) for the index
00379    or the hash entry, alternatively adding the index to Elf_Internal_Sym
00380    (not so good).  */
00381 
00382 static bfd_boolean
00383 sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
00384                        Elf_Internal_Sym *sym, const char **namep,
00385                        flagword *flagsp ATTRIBUTE_UNUSED,
00386                        asection **secp, bfd_vma *valp)
00387 {
00388   /* We want to do this for relocatable as well as final linking.  */
00389   if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
00390       && is_elf_hash_table (info->hash))
00391     {
00392       struct elf_link_hash_entry *h;
00393 
00394       /* For relocatable links, we register the DataLabel sym in its own
00395         right, and tweak the name when it's output.  Otherwise, we make
00396         an indirect symbol of it.  */
00397       flagword flags
00398        = info->relocatable || info->emitrelocations
00399        ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
00400 
00401       char *dl_name
00402        = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
00403       struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
00404 
00405       BFD_ASSERT (sym_hash != NULL);
00406 
00407       /* Allocation may fail.  */
00408       if (dl_name == NULL)
00409        return FALSE;
00410 
00411       strcpy (dl_name, *namep);
00412       strcat (dl_name, DATALABEL_SUFFIX);
00413 
00414       h = (struct elf_link_hash_entry *)
00415        bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
00416 
00417       if (h == NULL)
00418        {
00419          /* No previous datalabel symbol.  Make one.  */
00420          struct bfd_link_hash_entry *bh = NULL;
00421          const struct elf_backend_data *bed = get_elf_backend_data (abfd);
00422 
00423          if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
00424                                             flags, *secp, *valp,
00425                                             *namep, FALSE,
00426                                             bed->collect, &bh))
00427            {
00428              free (dl_name);
00429              return FALSE;
00430            }
00431 
00432          h = (struct elf_link_hash_entry *) bh;
00433          h->non_elf = 0;
00434          h->type = STT_DATALABEL;
00435        }
00436       else
00437        /* If a new symbol was created, it holds the allocated name.
00438           Otherwise, we don't need it anymore and should deallocate it.  */
00439        free (dl_name);
00440 
00441       if (h->type != STT_DATALABEL
00442          || ((info->relocatable || info->emitrelocations)
00443              && h->root.type != bfd_link_hash_undefined)
00444          || (! info->relocatable && !info->emitrelocations
00445              && h->root.type != bfd_link_hash_indirect))
00446        {
00447          /* Make sure we don't get confused on invalid input.  */
00448          (*_bfd_error_handler)
00449            (_("%s: encountered datalabel symbol in input"),
00450             bfd_get_filename (abfd));
00451          bfd_set_error (bfd_error_bad_value);
00452          return FALSE;
00453        }
00454 
00455       /* Now find the hash-table slot for this entry and fill it in.  */
00456       while (*sym_hash != NULL)
00457        sym_hash++;
00458       *sym_hash = h;
00459 
00460       /* Signal to caller to skip this symbol - we've handled it.  */
00461       *namep = NULL;
00462     }
00463 
00464   return TRUE;
00465 }
00466 
00467 /* This hook function is called before the linker writes out a global
00468    symbol.  For relocatable links, DataLabel symbols will be present in
00469    linker output.  We cut off the special suffix on those symbols, so the
00470    right name appears in the output.
00471 
00472    When linking and emitting relocations, there can appear global symbols
00473    that are not referenced by relocs, but rather only implicitly through
00474    DataLabel references, a relation that is not visible to the linker.
00475    Since no stripping of global symbols in done when doing such linking,
00476    we don't need to look up and make sure to emit the main symbol for each
00477    DataLabel symbol.  */
00478 
00479 bfd_boolean
00480 sh64_elf_link_output_symbol_hook (struct bfd_link_info *info,
00481                               const char *cname,
00482                               Elf_Internal_Sym *sym,
00483                               asection *input_sec ATTRIBUTE_UNUSED,
00484                               struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
00485 {
00486   char *name = (char *) cname;
00487 
00488   if (info->relocatable || info->emitrelocations)
00489     {
00490       if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
00491        name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
00492     }
00493 
00494   return TRUE;
00495 }
00496 
00497 /* Check a SH64-specific reloc and put the value to relocate to into
00498    RELOCATION, ready to pass to _bfd_final_link_relocate.  Return FALSE if
00499    bad value, TRUE if ok.  */
00500 
00501 static bfd_boolean
00502 shmedia_prepare_reloc (struct bfd_link_info *info, bfd *abfd,
00503                      asection *input_section, bfd_byte *contents,
00504                      const Elf_Internal_Rela *rel, bfd_vma *relocation)
00505 {
00506   bfd_vma disp, dropped;
00507 
00508   switch (ELF32_R_TYPE (rel->r_info))
00509     {
00510     case R_SH_PT_16:
00511       /* Check the lowest bit of the destination field.  If it is 1, we
00512         check the ISA type of the destination (i.e. the low bit of the
00513         "relocation" value, and emit an error if the instruction does not
00514         match).  If it is 0, we change a PTA to PTB.  There should never
00515         be a PTB that should change to a PTA; that indicates a toolchain
00516         error; a mismatch with GAS.  */
00517       {
00518        char *msg = NULL;
00519        bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
00520 
00521        if (insn & (1 << 10))
00522          {
00523            /* Check matching insn and ISA (address of target).  */
00524            if ((insn & SHMEDIA_PTB_BIT) != 0
00525               && ((*relocation + rel->r_addend) & 1) != 0)
00526              msg = _("PTB mismatch: a SHmedia address (bit 0 == 1)");
00527            else if ((insn & SHMEDIA_PTB_BIT) == 0
00528                    && ((*relocation + rel->r_addend) & 1) == 0)
00529              msg = _("PTA mismatch: a SHcompact address (bit 0 == 0)");
00530 
00531            if (msg != NULL
00532               && ! ((*info->callbacks->reloc_dangerous)
00533                     (info, msg, abfd, input_section,
00534                      rel->r_offset)))
00535              return FALSE;
00536          }
00537        else
00538          {
00539            /* We shouldn't get here with a PTB insn and a R_SH_PT_16.  It
00540               means GAS output does not match expectations; a PTA or PTB
00541               expressed as such (or a PT found at assembly to be PTB)
00542               would match the test above, and PT expansion with an
00543               unknown destination (or when relaxing) will get us here.  */
00544            if ((insn & SHMEDIA_PTB_BIT) != 0)
00545              {
00546               (*_bfd_error_handler)
00547                 (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),
00548                  bfd_get_filename (input_section->owner));
00549               return FALSE;
00550              }
00551 
00552            /* Change the PTA to a PTB, if destination indicates so.  */
00553            if (((*relocation + rel->r_addend) & 1) == 0)
00554              bfd_put_32 (abfd, insn | SHMEDIA_PTB_BIT,
00555                        contents + rel->r_offset);
00556          }
00557       }
00558 
00559     case R_SH_SHMEDIA_CODE:
00560     case R_SH_DIR5U:
00561     case R_SH_DIR6S:
00562     case R_SH_DIR6U:
00563     case R_SH_DIR10S:
00564     case R_SH_DIR10SW:
00565     case R_SH_DIR10SL:
00566     case R_SH_DIR10SQ:
00567     case R_SH_IMMS16:
00568     case R_SH_IMMU16:
00569     case R_SH_IMM_LOW16:
00570     case R_SH_IMM_LOW16_PCREL:
00571     case R_SH_IMM_MEDLOW16:
00572     case R_SH_IMM_MEDLOW16_PCREL:
00573     case R_SH_IMM_MEDHI16:
00574     case R_SH_IMM_MEDHI16_PCREL:
00575     case R_SH_IMM_HI16:
00576     case R_SH_IMM_HI16_PCREL:
00577     case R_SH_64:
00578     case R_SH_64_PCREL:
00579       break;
00580 
00581     default:
00582       return FALSE;
00583     }
00584 
00585   disp = (*relocation & 0xf);
00586   dropped = 0;
00587   switch (ELF32_R_TYPE (rel->r_info))
00588     {
00589     case R_SH_DIR10SW: dropped = disp & 1; break;
00590     case R_SH_DIR10SL: dropped = disp & 3; break;
00591     case R_SH_DIR10SQ: dropped = disp & 7; break;
00592     }
00593   if (dropped != 0)
00594     {
00595       (*_bfd_error_handler)
00596        (_("%B: error: unaligned relocation type %d at %08x reloc %p\n"),
00597         input_section->owner, ELF32_R_TYPE (rel->r_info),
00598         (unsigned) rel->r_offset, relocation);
00599       return FALSE;
00600     }
00601 
00602   return TRUE;
00603 }
00604 
00605 /* Helper function to locate the section holding a certain address.  This
00606    is called via bfd_map_over_sections.  */
00607 
00608 static void
00609 sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
00610                             asection *section, void *data)
00611 {
00612   bfd_vma vma;
00613   bfd_size_type size;
00614 
00615   struct sh64_find_section_vma_data *fsec_datap
00616     = (struct sh64_find_section_vma_data *) data;
00617 
00618   /* Return if already found.  */
00619   if (fsec_datap->section)
00620     return;
00621 
00622   /* If this section isn't part of the addressable contents, skip it.  */
00623   if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
00624     return;
00625 
00626   vma = bfd_get_section_vma (abfd, section);
00627   if (fsec_datap->addr < vma)
00628     return;
00629 
00630   size = section->size;
00631   if (fsec_datap->addr >= vma + size)
00632     return;
00633 
00634   fsec_datap->section = section;
00635 }
00636 
00637 /* Make sure to write out the generated entries in the .cranges section
00638    when doing partial linking, and set bit 0 on the entry address if it
00639    points to SHmedia code and write sorted .cranges entries when writing
00640    executables (final linking and objcopy).  */
00641 
00642 static void
00643 sh64_elf_final_write_processing (bfd *abfd,
00644                              bfd_boolean linker ATTRIBUTE_UNUSED)
00645 {
00646   bfd_vma ld_generated_cranges_size;
00647   asection *cranges
00648     = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
00649 
00650   /* If no new .cranges were added, the generic ELF linker parts will
00651      write it all out.  If not, we need to write them out when doing
00652      partial linking.  For a final link, we will sort them and write them
00653      all out further below.  */
00654   if (linker
00655       && cranges != NULL
00656       && elf_elfheader (abfd)->e_type != ET_EXEC
00657       && (ld_generated_cranges_size
00658          = sh64_elf_section_data (cranges)->sh64_info->cranges_growth) != 0)
00659     {
00660       bfd_vma incoming_cranges_size
00661        = cranges->size - ld_generated_cranges_size;
00662 
00663       if (! bfd_set_section_contents (abfd, cranges,
00664                                   cranges->contents
00665                                   + incoming_cranges_size,
00666                                   cranges->output_offset
00667                                   + incoming_cranges_size,
00668                                   ld_generated_cranges_size))
00669        {
00670          bfd_set_error (bfd_error_file_truncated);
00671          (*_bfd_error_handler)
00672            (_("%s: could not write out added .cranges entries"),
00673             bfd_get_filename (abfd));
00674        }
00675     }
00676 
00677   /* Only set entry address bit 0 and sort .cranges when linking to an
00678      executable; never with objcopy or strip.  */
00679   if (linker && elf_elfheader (abfd)->e_type == ET_EXEC)
00680     {
00681       struct sh64_find_section_vma_data fsec_data;
00682       sh64_elf_crange dummy;
00683 
00684       /* For a final link, set the low bit of the entry address to
00685         reflect whether or not it is a SHmedia address.
00686         FIXME: Perhaps we shouldn't do this if the entry address was
00687         supplied numerically, but we currently lack the infrastructure to
00688         recognize that: The entry symbol, and info whether it is numeric
00689         or a symbol name is kept private in the linker.  */
00690       fsec_data.addr = elf_elfheader (abfd)->e_entry;
00691       fsec_data.section = NULL;
00692 
00693       bfd_map_over_sections (abfd, sh64_find_section_for_address,
00694                           &fsec_data);
00695       if (fsec_data.section
00696          && (sh64_get_contents_type (fsec_data.section,
00697                                   elf_elfheader (abfd)->e_entry,
00698                                   &dummy) == CRT_SH5_ISA32))
00699        elf_elfheader (abfd)->e_entry |= 1;
00700 
00701       /* If we have a .cranges section, sort the entries.  */
00702       if (cranges != NULL)
00703        {
00704          bfd_size_type cranges_size = cranges->size;
00705 
00706          /* We know we always have these in memory at this time.  */
00707          BFD_ASSERT (cranges->contents != NULL);
00708 
00709          /* The .cranges may already have been sorted in the process of
00710             finding out the ISA-type of the entry address.  If not, we do
00711             it here.  */
00712          if (elf_section_data (cranges)->this_hdr.sh_type
00713              != SHT_SH5_CR_SORTED)
00714            {
00715              qsort (cranges->contents, cranges_size / SH64_CRANGE_SIZE,
00716                    SH64_CRANGE_SIZE,
00717                    bfd_big_endian (cranges->owner)
00718                    ? _bfd_sh64_crange_qsort_cmpb
00719                    : _bfd_sh64_crange_qsort_cmpl);
00720              elf_section_data (cranges)->this_hdr.sh_type
00721               = SHT_SH5_CR_SORTED;
00722            }
00723 
00724          /* We need to write it out in whole as sorted.  */
00725          if (! bfd_set_section_contents (abfd, cranges,
00726                                      cranges->contents,
00727                                      cranges->output_offset,
00728                                      cranges_size))
00729            {
00730              bfd_set_error (bfd_error_file_truncated);
00731              (*_bfd_error_handler)
00732               (_("%s: could not write out sorted .cranges entries"),
00733                bfd_get_filename (abfd));
00734            }
00735        }
00736     }
00737 }
00738 
00739 /* Merge non visibility st_other attribute when the symbol comes from
00740    a dynamic object.  */
00741 static void
00742 sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
00743                              const Elf_Internal_Sym *isym,
00744                              bfd_boolean definition,
00745                              bfd_boolean dynamic ATTRIBUTE_UNUSED)
00746 {
00747   if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
00748     {
00749       unsigned char other;
00750 
00751       /* Take the balance of OTHER from the definition.  */
00752       other = (definition ? isym->st_other : h->other);
00753       other &= ~ ELF_ST_VISIBILITY (-1);
00754       h->other = other | ELF_ST_VISIBILITY (h->other);
00755     }
00756 
00757   return;
00758 }
00759 
00760 static const struct bfd_elf_special_section sh64_elf_special_sections[] =
00761 {
00762   { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
00763   { NULL,                       0, 0, 0,            0 }
00764 };
00765 
00766 #undef TARGET_BIG_SYM
00767 #define       TARGET_BIG_SYM              bfd_elf32_sh64_vec
00768 #undef TARGET_BIG_NAME
00769 #define       TARGET_BIG_NAME             "elf32-sh64"
00770 #undef TARGET_LITTLE_SYM
00771 #define       TARGET_LITTLE_SYM    bfd_elf32_sh64l_vec
00772 #undef TARGET_LITTLE_NAME
00773 #define       TARGET_LITTLE_NAME   "elf32-sh64l"
00774 
00775 #include "elf32-target.h"
00776 
00777 /* NetBSD support.  */
00778 #undef TARGET_BIG_SYM
00779 #define       TARGET_BIG_SYM              bfd_elf32_sh64nbsd_vec
00780 #undef TARGET_BIG_NAME
00781 #define       TARGET_BIG_NAME             "elf32-sh64-nbsd"
00782 #undef TARGET_LITTLE_SYM
00783 #define       TARGET_LITTLE_SYM    bfd_elf32_sh64lnbsd_vec
00784 #undef TARGET_LITTLE_NAME
00785 #define       TARGET_LITTLE_NAME   "elf32-sh64l-nbsd"
00786 #undef ELF_MAXPAGESIZE
00787 #define       ELF_MAXPAGESIZE             0x10000
00788 #undef ELF_COMMONPAGESIZE
00789 #undef elf_symbol_leading_char
00790 #define       elf_symbol_leading_char     0
00791 #undef elf32_bed
00792 #define       elf32_bed            elf32_sh64_nbsd_bed
00793 
00794 #include "elf32-target.h"
00795 
00796 /* Linux support.  */
00797 #undef TARGET_BIG_SYM
00798 #define       TARGET_BIG_SYM              bfd_elf32_sh64blin_vec
00799 #undef TARGET_BIG_NAME
00800 #define       TARGET_BIG_NAME             "elf32-sh64big-linux"
00801 #undef TARGET_LITTLE_SYM
00802 #define       TARGET_LITTLE_SYM    bfd_elf32_sh64lin_vec
00803 #undef TARGET_LITTLE_NAME
00804 #define       TARGET_LITTLE_NAME   "elf32-sh64-linux"
00805 #undef elf32_bed
00806 #define       elf32_bed            elf32_sh64_lin_bed
00807 #undef ELF_COMMONPAGESIZE
00808 #define       ELF_COMMONPAGESIZE   0x1000
00809 
00810 #include "elf32-target.h"
00811