Contribute sh64-elf.
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 8 Feb 2002 05:33:27 +0000 (05:33 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Fri, 8 Feb 2002 05:33:27 +0000 (05:33 +0000)
2002-01-23  Alexandre Oliva  <aoliva@redhat.com>
* reloc.c (R_SH_GOTPLT32, R_SH_GOT_LOW16, R_SH_GOT_MEDLOW16,
R_SH_GOT_MEDHI16, R_SH_GOT_HI16, R_SH_GOTPLT_LOW16,
R_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_HI16,
R_SH_PLT_LOW16, R_SH_PLT_MEDLOW16, R_SH_PLT_MEDHI16,
R_SH_PLT_HI16, R_SH_GOTOFF_LOW16, R_SH_GOTOFF_MEDLOW16,
R_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_HI16, R_SH_GOTPC_LOW16,
R_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDHI16, R_SH_GOTPC_HI16,
R_SH_GOT10BY4, R_SH_GOTPLT10BY4, R_SH_GOT10BY8, R_SH_GOTPLT10BY8,
R_SH_COPY64, R_SH_GLOB_DAT64, R_SH_JMP_SLOT64, R_SH_RELATIVE64):
New relocs.
* libbfd.h, bfd-in2.h: Rebuilt.
* elf32-sh.c (sh_elf_howto_table): Define new relocs.
(sh_reloc_map): Map them.
(PLT_ENTRY_SIZE, elf_sh_plt0_entry_be, elf_sh_plt0_entry_le,
elf_sh_plt_entry_be, elf_sh_plt_entry_le, elf_sh_pic_plt_entry_be,
elf_sh_pic_plt_entry_le, elf_sh_plt0_entry, elf_sh_plt_entry,
elf_sh_pic_plt_entry, elf_sh_sizeof_plt, elf_sh_plt_plt0_offset,
elf_sh_plt0_gotplt_offset, elf_sh_plt_temp_offset,
elf_sh_plt_symbol_offset, elf_sh_plt_reloc_offset,
movi_shori_putval) [INCLUDE_SHMEDIA]: New.
(elf_sh_link_hash_entry) [INCLUDE_SHMEDIA]: Add
datalabel_got_offset.
(sh_elf_link_hash_newfunc): Initialize it.
(sh_elf_relocate_section): Augment the scope of
seen_stt_datalabel.  Introduce GOTPLT support. Extend GOTPC, PLT,
GOT and GOTOFF handling to new SHmedia relocation types.  Support
GOT_BIAS.
(sh_elf_check_relocs): Likewise.
(sh_elf_finish_dynamic_symbol) [TARGET_SHMEDIA]: Set up values in
PLT entries using movi_shori_putval.  Support GOT_BIAS.
(sh_elf_finish_dynamic_sections): Likewise.
* elf32-sh64.c (shmedia_prepare_reloc): Do not add addend to
relocation, it's now done by the caller.
(GOT_BIAS): New.
* elf64-sh64.c (GOT_BIAS, PLT_ENTRY_SIZE, elf_sh64_sizeof_plt,
elf_sh64_plt_plt0_offset, elf_sh64_plt0_gotplt_offset,
elf_sh64_plt_temp_offset, elf_sh64_plt_symbol_offset,
elf_sh64_plt_reloc_offset, ELF_DYNAMIC_INTERPRETER,
elf_sh64_pcrel_relocs_copied, elf_sh64_link_hash_entry,
elf_sh64_link_hash_table, sh64_elf64_link_hash_traverse,
sh64_elf64_hash_table): New.
(sh_elf64_howto_table): Introduce new relocs.
(sh_elf64_info_to_howto): Accept new PIC relocs.
(sh_elf64_relocate_section): Augment the scope of
seen_stt_datalabel.  Support new PIC relocs.
(sh_elf64_check_relocs): Support new PIC relocs.
(elf_sh64_plt0_entry_be, elf_sh64_plt0_entry_le,
elf_sh64_plt_entry_be, elf_sh64_plt_entry_le,
elf_sh64_pic_plt_entry_be, elf_sh64_pic_plt_entry_le,
elf_sh64_plt0_entry, elf_sh64_plt_entry, elf_sh64_pic_plt_entry,
sh64_elf64_link_hash_newfunc, sh64_elf64_link_hash_table_create,
movi_shori_putval, movi_3shori_putval,
sh64_elf64_create_dynamic_sections,
sh64_elf64_adjust_dynamic_symbol, sh64_elf64_discard_copies,
sh64_elf64_size_dynamic_sections,
sh64_elf64_finish_dynamic_symbol,
sh64_elf64_finish_dynamic_sections): New.
(elf_backend_create_dynamic-sections,
bfd_elf64_bfd_link_hash_table_create,
elf_backend_adjust_dynamic_symbol,
elf_backend_size_dynamic_sections,
elf_backend_finish_dynamic_symbol,
elf_backend_finish_dynamic_sections, elf_backend_want_got_plt,
elf_backend_plt_readonly, elf_backend_want_plt_sym,
elf_backend_got_header_size, elf_backend_plt_header_size):
Define.
2001-05-16  Alexandre Oliva  <aoliva@redhat.com>
* elf32-sh.c: Renumbered and renamed some SH5 relocations to
match official numbers and names; moved unmaching ones to the
range 0xf2-0xff.
* elf32-sh64.c, elf64-sh64.c: Likewise.
2001-03-12  DJ Delorie <dj@redhat.com>
* elf32-sh.c (sh_elf_relax_section): Don't relax SHmedia
sections.
2001-03-12  DJ Delorie <dj@redhat.com>
* elf32-sh64.c (shmedia_prepare_reloc): Validate relocs that must
be aligned.
* elf64-sh64.c (sh_elf64_relocate_section): Ditto.
2001-01-14  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh64.c (bfd_elf32_bfd_copy_private_section_data): Define.
(sh64_elf_fake_sections): Set type to SHT_SH5_CR_SORTED for a
.cranges section with SEC_SORT_ENTRIES set.
(sh64_backend_section_from_shdr): Set SEC_SORT_ENTRIES on an
incoming sorted .cranges section.
(sh64_bfd_elf_copy_private_section_data): New.
(sh64_elf_final_write_processing): Only sort .cranges and modify
start address if called by linker.
2001-01-08  Ben Elliston  <bje@redhat.com>
* elf32-sh64.c (sh64_elf_final_write_processing): Activate
Hans-Peter Nilsson's set bit 0 patch from 2001-01-06.
* elf64-sh64.c (sh64_elf64_final_write_processing): Ditto.
2001-01-06  Hans-Peter Nilsson <hpn@cygnus.com>
* elf64-sh64.c (sh_elf64_howto_table): No open brace at start of
line.  Add comments before all entries.
<R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct and clarify describing
comment.
(sh_elf64_reloc): Correct head comment.
(sh_elf64_relocate_section): Correct spacing.
<relocating for a local symbol>: Do not honour STO_SH5_ISA32;
instead call reloc_dangerous callback.
<case R_SH_SHMEDIA_CODE>: New case.
(sh_elf64_gc_mark_hook): Correct spacing.
(sh_elf64_check_relocs): Ditto.
* elf32-sh64.c (shmedia_prepare_reloc) <case R_SH_SHMEDIA_CODE>:
New case.
* elf32-sh.c: Correct #endif comments for #ifndef-wrapped
functions.
(sh_elf_howto_table) <R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct,
clarify describing comment.  Add comments before all entries.
(sh_elf_relocate_section) <relocating for a local symbol>: Do not
honour STO_SH5_ISA32; instead call reloc_dangerous callback.
2001-01-06  Hans-Peter Nilsson <hpn@cygnus.com>
Sort .cranges section in final link.  Prepare to set bit 0 on
entry address.
* elf32-sh64.c (struct sh64_find_section_vma_data): New.
(sh64_elf_link_output_symbol_hook): Fix typo in prototype.
(sh64_elf_set_mach_from_flags): Set SEC_DEBUGGING on incoming
.cranges section.
(sh64_backend_section_from_shdr): New, to recognize
SHT_SH5_CR_SORTED on incoming .cranges section.
(elf_backend_section_from_shdr): Define.
(sh64_elf_final_write_processing): Sort outgoing .cranges
section.  (New, temporarily disabled:) Set bit 0 on entry address
according to ISA type.
(sh64_find_section_for_address): New.
(crange_qsort_cmpb, crange_qsort_cmpl, crange_bsearch_cmpb,
crange_bsearch_cmpl): Move here from opcodes/sh64-dis.c.
(sh64_address_in_cranges): Move here from opcodes/sh64-dis.c.  Use
bfd_malloc, not xmalloc.
(sh64_get_contents_type): Move here from opcodes/sh64-dis.c.  Make
global.
* elf32-sh64.c (sh64_elf64_final_write_processing): New, (but
temporarily disabled) setting bit 0 on entry address.
(elf_backend_final_write_processing): Define.
2001-01-05  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh.c (sh_elf_howto_table) <R_SH_PT_16>: Adjust fields to
be a proper relocation for PTA and PTB rather than a marker.
<R_SH_IMMU5, R_SH_IMMS6, R_SH_IMMU6, R_SH_IMMS10, R_SH_IMMS10BY2,
R_SH_IMMS10BY4, R_SH_IMMS10BY8, R_SH_IMMS16, R_SH_IMMU16,
R_SH_IMM_LOW16, R_SH_IMM_LOW16_PCREL, R_SH_IMM_MEDLOW16,
R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16_PCREL,
R_SH_IMM_HI16, R_SH_IMM_HI16_PCREL, R_SH_64, R_SH_64_PCREL>:
Zero src_mask.
* elf64-sh64.c: Ditto.
(sh_elf64_relocate_section) <case R_SH_PT_16>: New case.
* elf32-sh64.c: Include opcodes/sh64-opc.h
(shmedia_prepare_reloc): Take a bfd_link_info pointer as first
argument.  Drop const qualifiers from "bfd *" and "bfd_byte *"
parameters.  No unused parameters.  Caller changed.
<case R_SH_PT_16>: New case.
* Makefile.am (elf32-sh64.lo): Add dependency on sh64-opc.h.
* Makefile.in: Regenerate.
2000-12-30  Hans-Peter Nilsson <hpn@cygnus.com>
* elf64-sh64.c (sh64_elf64_fake_sections): Set SHF_SH5_ISA32 for
all code sections.
(sh_elf64_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
(sh64_elf_merge_private_data): Ditto.
* elf32-sh64.c (sh64_elf_fake_sections): Use sh64_elf_section_data
to access stored section flags.
(sh64_elf_final_write_processing): Return immediately unless
called by linker.  Use sh64_elf_section_data (cranges) to get size
of linker-generated cranges entries.
(sh64_elf_copy_private_data): Add missing "return true".
(sh64_elf_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
(sh_elf64_merge_private_data): Ditto.
2000-12-19  Hans-Peter Nilsson <hpn@cygnus.com>
* elf64-sh64.c (sh64_elf64_fake_sections): New, copy of
elf64-sh64.c:sh64_elf_fake_sections.
(elf_backend_fake_sections): Define as sh64_elf64_fake_sections.
2000-12-18  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh64.c (sh64_elf_copy_private_data_internal): Delete.
(sh64_elf_final_write_processing): New.
(elf_backend_final_write_processing): Define.
(sh64_elf_fake_sections): Get header flags from tdata field.
(sh64_elf_copy_private_data): Do not call
sh64_elf_copy_private_data_internal, just copy e_flags field.
(sh64_elf_merge_private_data): Do not call
sh64_elf_copy_private_data_internal.
2000-12-12  Hans-Peter Nilsson <hpn@cygnus.com>
Remove EF_SH64_ABI64, let ELF size make difference.
Remove SH64-specific BFD section flag.
* elf32-sh64.c (sh64_elf_fake_sections): Recognize section as
containing SHmedia through elf_section_data (asect)->tdata
non-zero, not using a BFD section flag.
(sh64_elf_set_mach_from_flags): Don't recognize EF_SH64_ABI64.
(sh64_elf_merge_private_data): Similar.
(elf_backend_section_flags): Don't define.
(sh64_elf_backend_section_flags): Delete.
* elf64-sh64.c (sh_elf64_set_mach_from_flags): Recognize EF_SH64,
not EF_SH64_ABI64.
(sh_elf64_merge_private_data): Similar.
* section.c (Section flags definitions): Don't define
SEC_SH_ISA_SHMEDIA.
(bfd-in2.h): Regenerate.
2000-12-09  Hans-Peter Nilsson <hpn@cygnus.com>
Make DataLabel references work with partial linking.
* elf32-sh64.c: Fix formatting.
(sh64_elf_link_output_symbol_hook): New.
(elf_backend_link_output_symbol_hook): Define to
sh64_elf_link_output_symbol_hook.
(sh64_elf_add_symbol_hook): Make DataLabel symbol just global
undefined if partial linking.  Adjust sanity check.
* elf64-sh64.c (sh64_elf64_link_output_symbol_hook): New.
(elf_backend_link_output_symbol_hook): Define to
sh64_elf64_link_output_symbol_hook.
(sh64_elf64_add_symbol_hook): Make DataLabel symbol just global
undefined if partial linking.  Adjust sanity check.
2000-12-07  Hans-Peter Nilsson <hpn@cygnus.com>
Implement semantics for inter-file DataLabel references.
* elf64-sh64.c (DATALABEL_SUFFIX): Define.
(sh64_elf64_add_symbol_hook): New.
(sh_elf64_relocate_section): If passing an indirect symbol with
st_type STT_DATALABEL on the way to a symbol with st_other
STO_SH5_ISA32, do not bitor 1 to the relocation.
(elf_backend_add_symbol_hook): Define to
sh64_elf64_add_symbol_hook.
* elf64-sh32.c: Tweak comments.
(DATALABEL_SUFFIX): Define.
(sh64_elf_add_symbol_hook): New.
(elf_backend_add_symbol_hook): Define to sh64_elf_add_symbol_hook.
* elf32-sh.c (sh_elf_relocate_section): If passing an indirect
symbol with st_type STT_DATALABEL on the way to a symbol with
st_other STO_SH5_ISA32, do not bitor 1 to the relocation.
2000-12-05  Hans-Peter Nilsson <hpn@cygnus.com>
Pass through STT_DATALABEL.
* elf32-sh64.c (sh64_elf_get_symbol_type): New.
(elf_backend_get_symbol_type): Define.
* elf64-sh64.c (sh64_elf64_get_symbol_type): New.
(elf_backend_get_symbol_type): Define.
2000-11-30  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh64.c: Tweak comments.
(sh64_elf_copy_private_data_internal): Add prototype.
(bfd_elf32_bfd_set_private_flags): Define.
(sh64_elf_copy_private_data_internal): Compare machine name, not
textual BFD target name, to check whether to copy section flag
SHF_SH5_ISA32.
(sh64_elf_merge_private_data): Validize bfd_get_arch_size.
Tweak section-contents-type-mismatch message.
(shmedia_prepare_reloc): Add ATTRIBUTE_UNUSED markers.
Validize reloc-types.
* elf64-sh64.c: New file.
* targets.c (bfd_elf64_sh64_vec, bfd_elf64_sh64l_vec): Declare.
* Makefile.am (BFD64_BACKENDS): Add elf64-sh64.lo.
(BFD64_BACKENDS_CFILES): Add elf64-sh64.c.
Regenerate dependencies.
* Makefile.in: Regenerate.
* config.bfd (sh64-*-elf*): Add bfd_elf64_sh64_vec and
bfd_elf64_sh64l_vec.
* configure.in: Handle bfd_elf64_sh64_vec and
bfd_elf64_sh64l_vec.
* configure: Regenerate.
* po/POTFILES.in: Regenerate.
* po/bfd.pot: Regenerate.
2000-11-29  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh64.c (sh64_elf_set_mach_from_flags): Do not recognize
anything else but EF_SH64 and EF_SH64_ABI64.
(sh64_elf_merge_private_data): Emit error for anything else but
EF_SH64 and EF_SH64_ABI64.
* config.bfd: Remove bfd_elf32_shblin_vec and bfd_elf32_shlin_vec
from targ_selvecs.
* configure.in: Add cofflink.lo to bfd_elf32_sh64_vec and
bfd_elf32_sh64l_vec as a temporary measure.
* configure: Regenerate.
2000-11-27  Hans-Peter Nilsson <hpn@cygnus.com>
* cpu-sh.c (arch_info_struct): Include sh5 item
unconditionalized.
* config.bfd (sh64-*-elf*): Do not set targ_cflags.
Add targ_selvecs bfd_elf32_sh_vec, bfd_elf32_shl_vec,
bfd_elf32_shblin_vec and bfd_elf32_shlin_vec.
* elf32-sh64.c: Tweak comments.
(sh64_elf_set_mach_from_flags): Recognize all machine flags that
are proper subsets of SH64 as bfd_mach_sh5.  Add EF_SH64_ABI64.
(sh64_elf_copy_private_data_internal): Wrap long line.
(sh64_elf_merge_private_data): Rewrite to allow objects from
SH64 subsets to be linked together.
(INCLUDE_SHMEDIA): Define.
* elf32-sh.c (sh_elf_relocate_section) <local symbol>:
Parenthesize plus-expression inside or-expression.
<global symbol>: Ditto.
(sh_elf_set_mach_from_flags): Remove code refusing
deleted EF_SH64_32BIT_ABI flag.
2000-11-26  Hans-Peter Nilsson <hpn@cygnus.com>
* elf32-sh.c (sh_elf_howto_table) <R_SH_IMM_LOW16_PCREL,
R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16_PCREL,
R_SH_IMM_HI16_PCREL, R_SH_64_PCREL>: Set pcrel_offset to true.
(sh_elf_relocate_section) <local symbol>: Or 1 in
calculation of relocation if sym->st_other & STO_SH5_ISA32.
<global symbol>: Ditto if h->other & STO_SH5_ISA32.
* elf32-sh64.c (shmedia_prepare_reloc): Add rel->r_addend to
relocation.
2000-11-24  Hans-Peter Nilsson <hpn@cygnus.com>
* Makefile.am (BFD32_BACKENDS): Add elf32-sh64.lo.
(BFD32_BACKENDS_CFILES): Add elf32-sh64.c.
Regenerate dependencies.
* Makefile.in: Regenerate.
* archures.c: Add bfd_mach_sh5.
* config.bfd: Map targ_cpu sh* to bfd_sh_arch.
Handle sh64-*-elf*.  Set targ_cflags to -DINCLUDE_SHMEDIA.
* configure.in: Handle bfd_elf32_sh64_vec and bfd_elf32_sh64l_vec.
* configure: Regenerate.
* reloc.c (BFD_RELOC_SH_SHMEDIA_CODE, BFD_RELOC_SH_IMMU5,
BFD_RELOC_SH_IMMS6, BFD_RELOC_SH_IMMS6BY32, BFD_RELOC_SH_IMMU6,
BFD_RELOC_SH_IMMS10, BFD_RELOC_SH_IMMS10BY2,
BFD_RELOC_SH_IMMS10BY4, BFD_RELOC_SH_IMMS10BY8,
BFD_RELOC_SH_IMMS16, BFD_RELOC_SH_IMMU16, BFD_RELOC_SH_IMM_LOW16,
BFD_RELOC_SH_IMM_LOW16_PCREL, BFD_RELOC_SH_IMM_MEDLOW16,
BFD_RELOC_SH_IMM_MEDLOW16_PCREL, BFD_RELOC_SH_IMM_MEDHI16,
BFD_RELOC_SH_IMM_MEDHI16_PCREL, BFD_RELOC_SH_IMM_HI16,
BFD_RELOC_SH_IMM_HI16_PCREL, BFD_RELOC_SH_PT_16): New relocations.
* cpu-sh.c [INCLUDE_SHMEDIA] (arch_info_struct): Define and link
in item for SH5.
* elf32-sh.c [INCLUDE_SHMEDIA] (sh_elf_howto_table): Add howto items
for SHmedia relocs.
[INCLUDE_SHMEDIA] (sh_rel): Add mappings for SHmedia relocs.
[INCLUDE_SHMEDIA] (sh_elf_relocate_section) [default]: Call
shmedia_prepare_reloc, goto final_link_relocate if it returns
non-zero, else fail as before.
(sh_elf_set_mach_from_flags): Provide function only if not defined
as macro.  Do not recognize objects with EF_SH64_32BIT_ABI set.
(sh_elf_set_private_flags): Provide function only if not defined
as a macro.
(sh_elf_copy_private_data): Similar.
(sh_elf_merge_private_data): Similar.
* section.c (SEC_SH_ISA_SHMEDIA): New.
* targets.c (bfd_elf32_sh64_vec, bfd_elf32_sh64l_vec): Declare.
* elf32-sh64.c: New file.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
* po/POTFILES.in: Regenerate.
* po/bfd.pot: Regenerate.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.

18 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/archures.c
bfd/bfd-in2.h
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/cpu-sh.c
bfd/doc/Makefile.in
bfd/elf32-sh.c
bfd/elf32-sh64.c [new file with mode: 0644]
bfd/elf64-sh64.c [new file with mode: 0644]
bfd/libbfd.h
bfd/po/SRC-POTFILES.in
bfd/po/bfd.pot
bfd/reloc.c
bfd/targets.c

index d73483232a7fe223d29e0b2deb9701013bd7c2a2..0d713d61c6a96f2a444a5745459efd4e4c20e3b3 100644 (file)
@@ -1,3 +1,340 @@
+2002-02-08  Alexandre Oliva  <aoliva@redhat.com>
+
+       Contribute sh64-elf.
+       2002-01-23  Alexandre Oliva  <aoliva@redhat.com>
+       * reloc.c (R_SH_GOTPLT32, R_SH_GOT_LOW16, R_SH_GOT_MEDLOW16,
+       R_SH_GOT_MEDHI16, R_SH_GOT_HI16, R_SH_GOTPLT_LOW16,
+       R_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_HI16,
+       R_SH_PLT_LOW16, R_SH_PLT_MEDLOW16, R_SH_PLT_MEDHI16,
+       R_SH_PLT_HI16, R_SH_GOTOFF_LOW16, R_SH_GOTOFF_MEDLOW16,
+       R_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_HI16, R_SH_GOTPC_LOW16,
+       R_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDHI16, R_SH_GOTPC_HI16,
+       R_SH_GOT10BY4, R_SH_GOTPLT10BY4, R_SH_GOT10BY8, R_SH_GOTPLT10BY8,
+       R_SH_COPY64, R_SH_GLOB_DAT64, R_SH_JMP_SLOT64, R_SH_RELATIVE64):
+       New relocs.
+       * libbfd.h, bfd-in2.h: Rebuilt.
+       * elf32-sh.c (sh_elf_howto_table): Define new relocs.
+       (sh_reloc_map): Map them.
+       (PLT_ENTRY_SIZE, elf_sh_plt0_entry_be, elf_sh_plt0_entry_le,
+       elf_sh_plt_entry_be, elf_sh_plt_entry_le, elf_sh_pic_plt_entry_be,
+       elf_sh_pic_plt_entry_le, elf_sh_plt0_entry, elf_sh_plt_entry,
+       elf_sh_pic_plt_entry, elf_sh_sizeof_plt, elf_sh_plt_plt0_offset,
+       elf_sh_plt0_gotplt_offset, elf_sh_plt_temp_offset,
+       elf_sh_plt_symbol_offset, elf_sh_plt_reloc_offset,
+       movi_shori_putval) [INCLUDE_SHMEDIA]: New.
+       (elf_sh_link_hash_entry) [INCLUDE_SHMEDIA]: Add
+       datalabel_got_offset.
+       (sh_elf_link_hash_newfunc): Initialize it.
+       (sh_elf_relocate_section): Augment the scope of
+       seen_stt_datalabel.  Introduce GOTPLT support.  Extend GOTPC, PLT,
+       GOT and GOTOFF handling to new SHmedia relocation types.  Support
+       GOT_BIAS.
+       (sh_elf_check_relocs): Likewise.
+       (sh_elf_finish_dynamic_symbol) [TARGET_SHMEDIA]: Set up values in
+       PLT entries using movi_shori_putval.  Support GOT_BIAS.
+       (sh_elf_finish_dynamic_sections): Likewise.
+       * elf32-sh64.c (shmedia_prepare_reloc): Do not add addend to
+       relocation, it's now done by the caller.
+       (GOT_BIAS): New.
+       * elf64-sh64.c (GOT_BIAS, PLT_ENTRY_SIZE, elf_sh64_sizeof_plt,
+       elf_sh64_plt_plt0_offset, elf_sh64_plt0_gotplt_offset,
+       elf_sh64_plt_temp_offset, elf_sh64_plt_symbol_offset,
+       elf_sh64_plt_reloc_offset, ELF_DYNAMIC_INTERPRETER,
+       elf_sh64_pcrel_relocs_copied, elf_sh64_link_hash_entry,
+       elf_sh64_link_hash_table, sh64_elf64_link_hash_traverse,
+       sh64_elf64_hash_table): New.
+       (sh_elf64_howto_table): Introduce new relocs.
+       (sh_elf64_info_to_howto): Accept new PIC relocs.
+       (sh_elf64_relocate_section): Augment the scope of
+       seen_stt_datalabel.  Support new PIC relocs.
+       (sh_elf64_check_relocs): Support new PIC relocs.
+       (elf_sh64_plt0_entry_be, elf_sh64_plt0_entry_le,
+       elf_sh64_plt_entry_be, elf_sh64_plt_entry_le,
+       elf_sh64_pic_plt_entry_be, elf_sh64_pic_plt_entry_le,
+       elf_sh64_plt0_entry, elf_sh64_plt_entry, elf_sh64_pic_plt_entry,
+       sh64_elf64_link_hash_newfunc, sh64_elf64_link_hash_table_create,
+       movi_shori_putval, movi_3shori_putval,
+       sh64_elf64_create_dynamic_sections,
+       sh64_elf64_adjust_dynamic_symbol, sh64_elf64_discard_copies,
+       sh64_elf64_size_dynamic_sections,
+       sh64_elf64_finish_dynamic_symbol,
+       sh64_elf64_finish_dynamic_sections): New.
+       (elf_backend_create_dynamic-sections,
+       bfd_elf64_bfd_link_hash_table_create,
+       elf_backend_adjust_dynamic_symbol,
+       elf_backend_size_dynamic_sections,
+       elf_backend_finish_dynamic_symbol,
+       elf_backend_finish_dynamic_sections, elf_backend_want_got_plt,
+       elf_backend_plt_readonly, elf_backend_want_plt_sym,
+       elf_backend_got_header_size, elf_backend_plt_header_size):
+       Define.
+       2001-05-16  Alexandre Oliva  <aoliva@redhat.com>
+       * elf32-sh.c: Renumbered and renamed some SH5 relocations to
+       match official numbers and names; moved unmaching ones to the
+       range 0xf2-0xff.
+       * elf32-sh64.c, elf64-sh64.c: Likewise.
+       2001-03-12  DJ Delorie  <dj@redhat.com>
+       * elf32-sh.c (sh_elf_relax_section): Don't relax SHmedia
+       sections.
+       2001-03-12  DJ Delorie  <dj@redhat.com>
+       * elf32-sh64.c (shmedia_prepare_reloc): Validate relocs that must
+       be aligned.
+       * elf64-sh64.c (sh_elf64_relocate_section): Ditto.
+       2001-01-14  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh64.c (bfd_elf32_bfd_copy_private_section_data): Define.
+       (sh64_elf_fake_sections): Set type to SHT_SH5_CR_SORTED for a
+       .cranges section with SEC_SORT_ENTRIES set.
+       (sh64_backend_section_from_shdr): Set SEC_SORT_ENTRIES on an
+       incoming sorted .cranges section.
+       (sh64_bfd_elf_copy_private_section_data): New.
+       (sh64_elf_final_write_processing): Only sort .cranges and modify
+       start address if called by linker.
+       2001-01-08  Ben Elliston  <bje@redhat.com>
+       * elf32-sh64.c (sh64_elf_final_write_processing): Activate
+       Hans-Peter Nilsson's set bit 0 patch from       2001-01-06.
+       * elf64-sh64.c (sh64_elf64_final_write_processing): Ditto.
+       2001-01-06  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf64-sh64.c (sh_elf64_howto_table): No open brace at start of
+       line.  Add comments before all entries.
+       <R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct and clarify describing
+       comment.
+       (sh_elf64_reloc): Correct head comment.
+       (sh_elf64_relocate_section): Correct spacing.
+       <relocating for a local symbol>: Do not honour STO_SH5_ISA32;
+       instead call reloc_dangerous callback.
+       <case R_SH_SHMEDIA_CODE>: New case.
+       (sh_elf64_gc_mark_hook): Correct spacing.
+       (sh_elf64_check_relocs): Ditto.
+       * elf32-sh64.c (shmedia_prepare_reloc) <case R_SH_SHMEDIA_CODE>:
+       New case.
+       * elf32-sh.c: Correct #endif comments for #ifndef-wrapped
+       functions.
+       (sh_elf_howto_table) <R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct,
+       clarify describing comment.  Add comments before all entries.
+       (sh_elf_relocate_section) <relocating for a local symbol>: Do not
+       honour STO_SH5_ISA32; instead call reloc_dangerous callback.
+       2001-01-06  Hans-Peter Nilsson  <hpn@cygnus.com>
+       Sort .cranges section in final link.  Prepare to set bit 0 on
+       entry address.
+       * elf32-sh64.c (struct sh64_find_section_vma_data): New.
+       (sh64_elf_link_output_symbol_hook): Fix typo in prototype.
+       (sh64_elf_set_mach_from_flags): Set SEC_DEBUGGING on incoming
+       .cranges section.
+       (sh64_backend_section_from_shdr): New, to recognize
+       SHT_SH5_CR_SORTED on incoming .cranges section.
+       (elf_backend_section_from_shdr): Define.
+       (sh64_elf_final_write_processing): Sort outgoing .cranges
+       section.  (New, temporarily disabled:) Set bit 0 on entry address
+       according to ISA type.
+       (sh64_find_section_for_address): New.
+       (crange_qsort_cmpb, crange_qsort_cmpl, crange_bsearch_cmpb,
+       crange_bsearch_cmpl): Move here from opcodes/sh64-dis.c.
+       (sh64_address_in_cranges): Move here from opcodes/sh64-dis.c.  Use
+       bfd_malloc, not xmalloc.
+       (sh64_get_contents_type): Move here from opcodes/sh64-dis.c.  Make
+       global.
+       * elf32-sh64.c (sh64_elf64_final_write_processing): New, (but
+       temporarily disabled) setting bit 0 on entry address.
+       (elf_backend_final_write_processing): Define.
+       2001-01-05  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh.c (sh_elf_howto_table) <R_SH_PT_16>: Adjust fields to
+       be a proper relocation for PTA and PTB rather than a marker.
+       <R_SH_IMMU5, R_SH_IMMS6, R_SH_IMMU6, R_SH_IMMS10, R_SH_IMMS10BY2,
+       R_SH_IMMS10BY4, R_SH_IMMS10BY8, R_SH_IMMS16, R_SH_IMMU16,
+       R_SH_IMM_LOW16, R_SH_IMM_LOW16_PCREL, R_SH_IMM_MEDLOW16,
+       R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16_PCREL,
+       R_SH_IMM_HI16, R_SH_IMM_HI16_PCREL, R_SH_64, R_SH_64_PCREL>:
+       Zero src_mask.
+       * elf64-sh64.c: Ditto.
+       (sh_elf64_relocate_section) <case R_SH_PT_16>: New case.
+       * elf32-sh64.c: Include opcodes/sh64-opc.h
+       (shmedia_prepare_reloc): Take a bfd_link_info pointer as first
+       argument.  Drop const qualifiers from "bfd *" and "bfd_byte *"
+       parameters.  No unused parameters.  Caller changed.
+       <case R_SH_PT_16>: New case.
+       * Makefile.am (elf32-sh64.lo): Add dependency on sh64-opc.h.
+       * Makefile.in: Regenerate.
+       2000-12-30  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf64-sh64.c (sh64_elf64_fake_sections): Set SHF_SH5_ISA32 for
+       all code sections.
+       (sh_elf64_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
+       (sh64_elf_merge_private_data): Ditto.
+       * elf32-sh64.c (sh64_elf_fake_sections): Use sh64_elf_section_data
+       to access stored section flags.
+       (sh64_elf_final_write_processing): Return immediately unless
+       called by linker.  Use sh64_elf_section_data (cranges) to get size
+       of linker-generated cranges entries.
+       (sh64_elf_copy_private_data): Add missing "return true".
+       (sh64_elf_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
+       (sh_elf64_merge_private_data): Ditto.
+       2000-12-19  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf64-sh64.c (sh64_elf64_fake_sections): New, copy of
+       elf64-sh64.c:sh64_elf_fake_sections.
+       (elf_backend_fake_sections): Define as sh64_elf64_fake_sections.
+       2000-12-18  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh64.c (sh64_elf_copy_private_data_internal): Delete.
+       (sh64_elf_final_write_processing): New.
+       (elf_backend_final_write_processing): Define.
+       (sh64_elf_fake_sections): Get header flags from tdata field.
+       (sh64_elf_copy_private_data): Do not call
+       sh64_elf_copy_private_data_internal, just copy e_flags field.
+       (sh64_elf_merge_private_data): Do not call
+       sh64_elf_copy_private_data_internal.
+       2000-12-12  Hans-Peter Nilsson  <hpn@cygnus.com>
+       Remove EF_SH64_ABI64, let ELF size make difference.
+       Remove SH64-specific BFD section flag.
+       * elf32-sh64.c (sh64_elf_fake_sections): Recognize section as
+       containing SHmedia through elf_section_data (asect)->tdata
+       non-zero, not using a BFD section flag.
+       (sh64_elf_set_mach_from_flags): Don't recognize EF_SH64_ABI64.
+       (sh64_elf_merge_private_data): Similar.
+       (elf_backend_section_flags): Don't define.
+       (sh64_elf_backend_section_flags): Delete.
+       * elf64-sh64.c (sh_elf64_set_mach_from_flags): Recognize EF_SH64,
+       not EF_SH64_ABI64.
+       (sh_elf64_merge_private_data): Similar.
+       * section.c (Section flags definitions): Don't define
+       SEC_SH_ISA_SHMEDIA.
+       (bfd-in2.h): Regenerate.
+       2000-12-09  Hans-Peter Nilsson  <hpn@cygnus.com>
+       Make DataLabel references work with partial linking.
+       * elf32-sh64.c: Fix formatting.
+       (sh64_elf_link_output_symbol_hook): New.
+       (elf_backend_link_output_symbol_hook): Define to
+       sh64_elf_link_output_symbol_hook.
+       (sh64_elf_add_symbol_hook): Make DataLabel symbol just global
+       undefined if partial linking.  Adjust sanity check.
+       * elf64-sh64.c (sh64_elf64_link_output_symbol_hook): New.
+       (elf_backend_link_output_symbol_hook): Define to
+       sh64_elf64_link_output_symbol_hook.
+       (sh64_elf64_add_symbol_hook): Make DataLabel symbol just global
+       undefined if partial linking.  Adjust sanity check.
+       2000-12-07  Hans-Peter Nilsson  <hpn@cygnus.com>
+       Implement semantics for inter-file DataLabel references.
+       * elf64-sh64.c (DATALABEL_SUFFIX): Define.
+       (sh64_elf64_add_symbol_hook): New.
+       (sh_elf64_relocate_section): If passing an indirect symbol with
+       st_type STT_DATALABEL on the way to a symbol with st_other
+       STO_SH5_ISA32, do not bitor 1 to the relocation.
+       (elf_backend_add_symbol_hook): Define to
+       sh64_elf64_add_symbol_hook.
+       * elf64-sh32.c: Tweak comments.
+       (DATALABEL_SUFFIX): Define.
+       (sh64_elf_add_symbol_hook): New.
+       (elf_backend_add_symbol_hook): Define to sh64_elf_add_symbol_hook.
+       * elf32-sh.c (sh_elf_relocate_section): If passing an indirect
+       symbol with st_type STT_DATALABEL on the way to a symbol with
+       st_other STO_SH5_ISA32, do not bitor 1 to the relocation.
+       2000-12-05  Hans-Peter Nilsson  <hpn@cygnus.com>
+       Pass through STT_DATALABEL.
+       * elf32-sh64.c (sh64_elf_get_symbol_type): New.
+       (elf_backend_get_symbol_type): Define.
+       * elf64-sh64.c (sh64_elf64_get_symbol_type): New.
+       (elf_backend_get_symbol_type): Define.
+       2000-11-30  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh64.c: Tweak comments.
+       (sh64_elf_copy_private_data_internal): Add prototype.
+       (bfd_elf32_bfd_set_private_flags): Define.
+       (sh64_elf_copy_private_data_internal): Compare machine name, not
+       textual BFD target name, to check whether to copy section flag
+       SHF_SH5_ISA32.
+       (sh64_elf_merge_private_data): Validize bfd_get_arch_size.
+       Tweak section-contents-type-mismatch message.
+       (shmedia_prepare_reloc): Add ATTRIBUTE_UNUSED markers.
+       Validize reloc-types.
+       * elf64-sh64.c: New file.
+       * targets.c (bfd_elf64_sh64_vec, bfd_elf64_sh64l_vec): Declare.
+       * Makefile.am (BFD64_BACKENDS): Add elf64-sh64.lo.
+       (BFD64_BACKENDS_CFILES): Add elf64-sh64.c.
+       Regenerate dependencies.
+       * Makefile.in: Regenerate.
+       * config.bfd (sh64-*-elf*): Add bfd_elf64_sh64_vec and
+       bfd_elf64_sh64l_vec.
+       * configure.in: Handle bfd_elf64_sh64_vec and
+       bfd_elf64_sh64l_vec.
+       * configure: Regenerate.
+       * po/POTFILES.in: Regenerate.
+       * po/bfd.pot: Regenerate.
+       2000-11-29  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh64.c (sh64_elf_set_mach_from_flags): Do not recognize
+       anything else but EF_SH64 and EF_SH64_ABI64.
+       (sh64_elf_merge_private_data): Emit error for anything else but
+       EF_SH64 and EF_SH64_ABI64.
+       * config.bfd: Remove bfd_elf32_shblin_vec and bfd_elf32_shlin_vec
+       from targ_selvecs.
+       * configure.in: Add cofflink.lo to bfd_elf32_sh64_vec and
+       bfd_elf32_sh64l_vec as a temporary measure.
+       * configure: Regenerate.
+       2000-11-27  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * cpu-sh.c (arch_info_struct): Include sh5 item
+       unconditionalized.
+       * config.bfd (sh64-*-elf*): Do not set targ_cflags.
+       Add targ_selvecs bfd_elf32_sh_vec, bfd_elf32_shl_vec,
+       bfd_elf32_shblin_vec and bfd_elf32_shlin_vec.
+       * elf32-sh64.c: Tweak comments.
+       (sh64_elf_set_mach_from_flags): Recognize all machine flags that
+       are proper subsets of SH64 as bfd_mach_sh5.  Add EF_SH64_ABI64.
+       (sh64_elf_copy_private_data_internal): Wrap long line.
+       (sh64_elf_merge_private_data): Rewrite to allow objects from
+       SH64 subsets to be linked together.
+       (INCLUDE_SHMEDIA): Define.
+       * elf32-sh.c (sh_elf_relocate_section) <local symbol>:
+       Parenthesize plus-expression inside or-expression.
+       <global symbol>: Ditto.
+       (sh_elf_set_mach_from_flags): Remove code refusing
+       deleted EF_SH64_32BIT_ABI flag.
+       2000-11-26  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * elf32-sh.c (sh_elf_howto_table) <R_SH_IMM_LOW16_PCREL,
+       R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16_PCREL,
+       R_SH_IMM_HI16_PCREL, R_SH_64_PCREL>: Set pcrel_offset to true.
+       (sh_elf_relocate_section) <local symbol>: Or 1 in
+       calculation of relocation if sym->st_other & STO_SH5_ISA32.
+       <global symbol>: Ditto if h->other & STO_SH5_ISA32.
+       * elf32-sh64.c (shmedia_prepare_reloc): Add rel->r_addend to
+       relocation.
+       2000-11-24  Hans-Peter Nilsson  <hpn@cygnus.com>
+       * Makefile.am (BFD32_BACKENDS): Add elf32-sh64.lo.
+       (BFD32_BACKENDS_CFILES): Add elf32-sh64.c.
+       Regenerate dependencies.
+       * Makefile.in: Regenerate.
+       * archures.c: Add bfd_mach_sh5.
+       * config.bfd: Map targ_cpu sh* to bfd_sh_arch.
+       Handle sh64-*-elf*.  Set targ_cflags to -DINCLUDE_SHMEDIA.
+       * configure.in: Handle bfd_elf32_sh64_vec and bfd_elf32_sh64l_vec.
+       * configure: Regenerate.
+       * reloc.c (BFD_RELOC_SH_SHMEDIA_CODE, BFD_RELOC_SH_IMMU5,
+       BFD_RELOC_SH_IMMS6, BFD_RELOC_SH_IMMS6BY32, BFD_RELOC_SH_IMMU6,
+       BFD_RELOC_SH_IMMS10, BFD_RELOC_SH_IMMS10BY2,
+       BFD_RELOC_SH_IMMS10BY4, BFD_RELOC_SH_IMMS10BY8,
+       BFD_RELOC_SH_IMMS16, BFD_RELOC_SH_IMMU16, BFD_RELOC_SH_IMM_LOW16,
+       BFD_RELOC_SH_IMM_LOW16_PCREL, BFD_RELOC_SH_IMM_MEDLOW16,
+       BFD_RELOC_SH_IMM_MEDLOW16_PCREL, BFD_RELOC_SH_IMM_MEDHI16,
+       BFD_RELOC_SH_IMM_MEDHI16_PCREL, BFD_RELOC_SH_IMM_HI16,
+       BFD_RELOC_SH_IMM_HI16_PCREL, BFD_RELOC_SH_PT_16): New relocations.
+       * cpu-sh.c [INCLUDE_SHMEDIA] (arch_info_struct): Define and link
+       in item for SH5.
+       * elf32-sh.c [INCLUDE_SHMEDIA] (sh_elf_howto_table): Add howto items
+       for SHmedia relocs.
+       [INCLUDE_SHMEDIA] (sh_rel): Add mappings for SHmedia relocs.
+       [INCLUDE_SHMEDIA] (sh_elf_relocate_section) [default]: Call
+       shmedia_prepare_reloc, goto final_link_relocate if it returns
+       non-zero, else fail as before.
+       (sh_elf_set_mach_from_flags): Provide function only if not defined
+       as macro.  Do not recognize objects with EF_SH64_32BIT_ABI set.
+       (sh_elf_set_private_flags): Provide function only if not defined
+       as a macro.
+       (sh_elf_copy_private_data): Similar.
+       (sh_elf_merge_private_data): Similar.
+       * section.c (SEC_SH_ISA_SHMEDIA): New.
+       * targets.c (bfd_elf32_sh64_vec, bfd_elf32_sh64l_vec): Declare.
+       * elf32-sh64.c: New file.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Regenerate.
+       * po/POTFILES.in: Regenerate.
+       * po/bfd.pot: Regenerate.
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+
 2002-02-07  Daniel Jacobowitz  <drow@mvista.com>
 
        * bfd-in.h: Update <stdbool.h> check to only see if <stdbool.h> has
index 9f744c321d2d183817f444abbe3e6258a84d6370..18438b3a841a243e0b80df8ffc450e7d7a0941f6 100644 (file)
@@ -221,6 +221,7 @@ BFD32_BACKENDS = \
        elf32-s390.lo \
        elf32-sh.lo \
        elf32-sh-lin.lo \
+       elf32-sh64.lo \
        elf32-sh-nbsd.lo \
        elf32-sparc.lo \
        elf32-v850.lo \
@@ -364,6 +365,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-or32.c \
        elf32-pj.c \
        elf32-ppc.c \
+       elf32-sh64.c \
        elf32-s390.c \
        elf32-sh.c \
        elf32-sh-lin.c \
@@ -451,6 +453,7 @@ BFD64_BACKENDS = \
        elf64-gen.lo \
        elf64-mips.lo \
        elf64-mmix.lo \
+       elf64-sh64.lo \
        elf64-ppc.lo \
        elf64-s390.lo \
        elf64-sparc.lo \
@@ -474,6 +477,7 @@ BFD64_BACKENDS_CFILES = \
        elf64-mmix.c \
        elf64-ppc.c \
        elf64-s390.c \
+       elf64-sh64.c \
        elf64-sparc.c \
        elf64.c \
        mmo.c \
@@ -1135,6 +1139,14 @@ elf32-ppc.lo: elf32-ppc.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
   elf32-target.h
+elf32-sh64.lo: elf32-sh64.c $(INCDIR)/filenames.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h elf32-sh.c $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h $(srcdir)/../opcodes/sh64-opc.h
+elf64-sh64.lo: elf64-sh64.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf64-target.h
 elf32-s390.lo: elf32-s390.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h \
index 5ea4b0f7b30e04ad24abc95287470a2e85955157..98c3435335c6c191e09f9b5ec68dffa9b943a934 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -349,6 +349,7 @@ BFD32_BACKENDS = \
        elf32-s390.lo \
        elf32-sh.lo \
        elf32-sh-lin.lo \
+       elf32-sh64.lo \
        elf32-sh-nbsd.lo \
        elf32-sparc.lo \
        elf32-v850.lo \
@@ -493,6 +494,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-or32.c \
        elf32-pj.c \
        elf32-ppc.c \
+       elf32-sh64.c \
        elf32-s390.c \
        elf32-sh.c \
        elf32-sh-lin.c \
@@ -581,6 +583,7 @@ BFD64_BACKENDS = \
        elf64-gen.lo \
        elf64-mips.lo \
        elf64-mmix.lo \
+       elf64-sh64.lo \
        elf64-ppc.lo \
        elf64-s390.lo \
        elf64-sparc.lo \
@@ -605,6 +608,7 @@ BFD64_BACKENDS_CFILES = \
        elf64-mmix.c \
        elf64-ppc.c \
        elf64-s390.c \
+       elf64-sh64.c \
        elf64-sparc.c \
        elf64.c \
        mmo.c \
@@ -746,7 +750,7 @@ configure.in
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = tar
+TAR = gtar
 GZIP_ENV = --best
 SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES)
 OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS)
@@ -913,7 +917,7 @@ maintainer-clean-recursive:
        dot_seen=no; \
        rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
          rev="$$subdir $$rev"; \
-         test "$$subdir" != "." || dot_seen=yes; \
+         test "$$subdir" = "." && dot_seen=yes; \
        done; \
        test "$$dot_seen" = "no" && rev=". $$rev"; \
        target=`echo $@ | sed s/-recursive//`; \
@@ -1679,6 +1683,14 @@ elf32-ppc.lo: elf32-ppc.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
   elf32-target.h
+elf32-sh64.lo: elf32-sh64.c $(INCDIR)/filenames.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h elf32-sh.c $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h $(srcdir)/../opcodes/sh64-opc.h
+elf64-sh64.lo: elf64-sh64.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf64-target.h
 elf32-s390.lo: elf32-s390.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h \
index 68057a497eeaa3955fa8ba59688ff87f9cb58edd..1caac7ff1490aeed71e868e8c6eda776e14a8658 100644 (file)
@@ -207,6 +207,7 @@ DESCRIPTION
 .#define bfd_mach_sh3_dsp    0x3d
 .#define bfd_mach_sh3e       0x3e
 .#define bfd_mach_sh4        0x40
+.#define bfd_mach_sh5        0x50
 .  bfd_arch_alpha,     {* Dec Alpha *}
 .#define bfd_mach_alpha_ev4  0x10
 .#define bfd_mach_alpha_ev5  0x20
index b23955dce3a382a91630f44f72504c66cf4c4bc7..2692b00d6b4d014d74cffdcf2bce15746b85d2ce 100644 (file)
@@ -1586,6 +1586,7 @@ enum bfd_architecture
 #define bfd_mach_sh3_dsp    0x3d
 #define bfd_mach_sh3e       0x3e
 #define bfd_mach_sh4        0x40
+#define bfd_mach_sh5        0x50
   bfd_arch_alpha,     /* Dec Alpha */
 #define bfd_mach_alpha_ev4  0x10
 #define bfd_mach_alpha_ev5  0x20
@@ -2188,6 +2189,55 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_MIPS_REL16,
   BFD_RELOC_MIPS_RELGOT,
   BFD_RELOC_MIPS_JALR,
+  BFD_RELOC_SH_GOT_LOW16,
+  BFD_RELOC_SH_GOT_MEDLOW16,
+  BFD_RELOC_SH_GOT_MEDHI16,
+  BFD_RELOC_SH_GOT_HI16,
+  BFD_RELOC_SH_GOTPLT_LOW16,
+  BFD_RELOC_SH_GOTPLT_MEDLOW16,
+  BFD_RELOC_SH_GOTPLT_MEDHI16,
+  BFD_RELOC_SH_GOTPLT_HI16,
+  BFD_RELOC_SH_PLT_LOW16,
+  BFD_RELOC_SH_PLT_MEDLOW16,
+  BFD_RELOC_SH_PLT_MEDHI16,
+  BFD_RELOC_SH_PLT_HI16,
+  BFD_RELOC_SH_GOTOFF_LOW16,
+  BFD_RELOC_SH_GOTOFF_MEDLOW16,
+  BFD_RELOC_SH_GOTOFF_MEDHI16,
+  BFD_RELOC_SH_GOTOFF_HI16,
+  BFD_RELOC_SH_GOTPC_LOW16,
+  BFD_RELOC_SH_GOTPC_MEDLOW16,
+  BFD_RELOC_SH_GOTPC_MEDHI16,
+  BFD_RELOC_SH_GOTPC_HI16,
+  BFD_RELOC_SH_COPY64,
+  BFD_RELOC_SH_GLOB_DAT64,
+  BFD_RELOC_SH_JMP_SLOT64,
+  BFD_RELOC_SH_RELATIVE64,
+  BFD_RELOC_SH_GOT10BY4,
+  BFD_RELOC_SH_GOT10BY8,
+  BFD_RELOC_SH_GOTPLT10BY4,
+  BFD_RELOC_SH_GOTPLT10BY8,
+  BFD_RELOC_SH_GOTPLT32,
+  BFD_RELOC_SH_SHMEDIA_CODE,
+  BFD_RELOC_SH_IMMU5,
+  BFD_RELOC_SH_IMMS6,
+  BFD_RELOC_SH_IMMS6BY32,
+  BFD_RELOC_SH_IMMU6,
+  BFD_RELOC_SH_IMMS10,
+  BFD_RELOC_SH_IMMS10BY2,
+  BFD_RELOC_SH_IMMS10BY4,
+  BFD_RELOC_SH_IMMS10BY8,
+  BFD_RELOC_SH_IMMS16,
+  BFD_RELOC_SH_IMMU16,
+  BFD_RELOC_SH_IMM_LOW16,
+  BFD_RELOC_SH_IMM_LOW16_PCREL,
+  BFD_RELOC_SH_IMM_MEDLOW16,
+  BFD_RELOC_SH_IMM_MEDLOW16_PCREL,
+  BFD_RELOC_SH_IMM_MEDHI16,
+  BFD_RELOC_SH_IMM_MEDHI16_PCREL,
+  BFD_RELOC_SH_IMM_HI16,
+  BFD_RELOC_SH_IMM_HI16_PCREL,
+  BFD_RELOC_SH_PT_16,
 
 
 /* i386/elf relocations  */
index fc77461981d651f2d6f723ca5dc6c0cbd4766721..253e2c42910fce0dd6173f8f35c5e6acf43ecf33 100644 (file)
@@ -57,6 +57,7 @@ v850*)                 targ_archs=bfd_v850_arch ;;
 x86_64)          targ_archs=bfd_i386_arch ;;
 xscale*)         targ_archs=bfd_arm_arch ;;
 z8k*)           targ_archs=bfd_z8k_arch ;;
+sh*)            targ_archs=bfd_sh_arch ;;
 *)              targ_archs=bfd_${targ_cpu}_arch ;;
 esac
 
@@ -845,6 +846,14 @@ case "${targ}" in
     ;;
 #endif
 
+#ifdef BFD64
+  sh64-*-elf*)
+    targ_defvec=bfd_elf32_sh64_vec
+    targ_selvecs="bfd_elf32_sh64l_vec bfd_elf64_sh64_vec bfd_elf64_sh64l_vec bfd_elf32_sh_vec bfd_elf32_shl_vec"
+    targ_underscore=yes
+    ;;
+#endif /* BFD64 */
+
   sh-*-linux*)
     targ_defvec=bfd_elf32_shblin_vec
     targ_selvecs=bfd_elf32_shlin_vec
index 3a324d5c93716cb5f9fb6405a813f38561ce8124..0dde6888d26d9f1e06be0f1b9de5e32bb9881fb5 100755 (executable)
@@ -1779,7 +1779,7 @@ else
   if { (eval echo configure:1780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.C | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -2388,7 +2388,7 @@ else
   if { (eval echo configure:2389: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.C | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -5958,6 +5958,17 @@ do
     # This list is alphabetized to make it easy to compare
     # with the two vector lists in targets.c.  For the same reason,
     # use one entry per line, even though this leads to long lines.
+    # FIXME: We include cofflink.lo not because it's needed for
+    # bfd_elf32_sh64[l]_vec, but because we include bfd_elf32_sh[l]_vec
+    # which needs it but does not list it.  Should be fixed in right place.
+    bfd_elf32_sh64_vec)                tb="$tb elf32-sh64.lo elf32.lo $elf cofflink.lo"
+                               target_size=64 ;;
+    bfd_elf32_sh64l_vec)       tb="$tb elf32-sh64.lo elf32.lo $elf cofflink.lo"
+                               target_size=64 ;;
+    bfd_elf64_sh64_vec)                tb="$tb elf64-sh64.lo elf64.lo $elf"
+                               target_size=64 ;;
+    bfd_elf64_sh64l_vec)       tb="$tb elf64-sh64.lo elf64.lo $elf"
+                               target_size=64 ;;
     a29kcoff_big_vec)          tb="$tb coff-a29k.lo cofflink.lo" ;;
     a_out_adobe_vec)           tb="$tb aout-adobe.lo aout32.lo" ;;
     aout0_big_vec)             tb="$tb aout0.lo aout32.lo" ;;
@@ -6223,10 +6234,10 @@ case ${host64}-${target64}-${want64} in
     if test -n "$GCC" ; then
        bad_64bit_gcc=no;
        echo $ac_n "checking for gcc version with buggy 64-bit support""... $ac_c" 1>&6
-echo "configure:6227: checking for gcc version with buggy 64-bit support" >&5
+echo "configure:6238: checking for gcc version with buggy 64-bit support" >&5
        # Add more tests for gcc versions with non-working 64-bit support here.
        cat > conftest.$ac_ext <<EOF
-#line 6230 "configure"
+#line 6241 "configure"
 #include "confdefs.h"
 :__GNUC__:__GNUC_MINOR__:__i386__:
 EOF
@@ -6271,17 +6282,17 @@ for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6275: checking for $ac_hdr" >&5
+echo "configure:6286: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6280 "configure"
+#line 6291 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6296: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6310,12 +6321,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6314: checking for $ac_func" >&5
+echo "configure:6325: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6319 "configure"
+#line 6330 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6338,7 +6349,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6363,7 +6374,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:6367: checking for working mmap" >&5
+echo "configure:6378: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6371,7 +6382,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 6375 "configure"
+#line 6386 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -6511,7 +6522,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:6515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -6536,12 +6547,12 @@ fi
 for ac_func in madvise mprotect
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6540: checking for $ac_func" >&5
+echo "configure:6551: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6545 "configure"
+#line 6556 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6564,7 +6575,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
index a6407186d269ec3776551a86bd57fd22ccbd2088..c2dc8d52336635b0774bae5a0bfa5fd53abc2d67 100644 (file)
@@ -515,6 +515,17 @@ do
     # This list is alphabetized to make it easy to compare
     # with the two vector lists in targets.c.  For the same reason,
     # use one entry per line, even though this leads to long lines.
+    # FIXME: We include cofflink.lo not because it's needed for
+    # bfd_elf32_sh64[l]_vec, but because we include bfd_elf32_sh[l]_vec
+    # which needs it but does not list it.  Should be fixed in right place.
+    bfd_elf32_sh64_vec)                tb="$tb elf32-sh64.lo elf32.lo $elf cofflink.lo"
+                               target_size=64 ;;
+    bfd_elf32_sh64l_vec)       tb="$tb elf32-sh64.lo elf32.lo $elf cofflink.lo"
+                               target_size=64 ;;
+    bfd_elf64_sh64_vec)                tb="$tb elf64-sh64.lo elf64.lo $elf"
+                               target_size=64 ;;
+    bfd_elf64_sh64l_vec)       tb="$tb elf64-sh64.lo elf64.lo $elf"
+                               target_size=64 ;;
     a29kcoff_big_vec)          tb="$tb coff-a29k.lo cofflink.lo" ;;
     a_out_adobe_vec)           tb="$tb aout-adobe.lo aout32.lo" ;;
     aout0_big_vec)             tb="$tb aout0.lo aout32.lo" ;;
index 054eb16449b5d7fbc67b86bf5b3e97607464afa5..30cd141ea9cfca2bb8b0b2b3ef5da727a9a5fd6e 100644 (file)
@@ -58,6 +58,9 @@ compatible (a,b)
 #define SH3_DSP_NEXT &arch_info_struct[4]
 #define SH3E_NEXT    &arch_info_struct[5]
 #define SH4_NEXT     NULL
+#undef  SH4_NEXT
+#define SH4_NEXT     &arch_info_struct[6]
+#define SH64_NEXT    NULL
 
 static const bfd_arch_info_type arch_info_struct[] =
 {
@@ -145,6 +148,20 @@ static const bfd_arch_info_type arch_info_struct[] =
     scan_mach,
     SH4_NEXT
   },
+  {
+    64,                                /* 64 bits in a word */
+    64,                                /* 64 bits in an address */
+    8,                         /* 8 bits in a byte */
+    bfd_arch_sh,
+    bfd_mach_sh5,
+    "sh",                      /* arch_name  */
+    "sh5",                     /* printable name */
+    1,
+    false,                     /* not the default */
+    bfd_default_compatible,
+    scan_mach,
+    SH64_NEXT
+  },
 };
 
 const bfd_arch_info_type bfd_sh_arch =
index 698d76f93c287d821bc578eab9d8e13b3f971ae2..e0ce81ffd7976269fd39bba7a47d1556ac4ede8e 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -328,7 +328,7 @@ uninstall-info:
        else ii=; fi; \
        list='$(INFO_DEPS)'; \
        for file in $$list; do \
-         test -z "$$ii" \
+         test -z "$ii" \
            || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
        done
        @$(NORMAL_UNINSTALL)
index 1a711916bb07f9f8feb789894fb1bc9a24b91971..150d912b3ccb1b69870f154572477458b5b3b513 100644 (file)
@@ -1,5 +1,5 @@
 /* Hitachi SH specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
    Contributed by Ian Lance Taylor, Cygnus Support.
 
@@ -492,6 +492,114 @@ static reloc_howto_type sh_elf_howto_table[] =
   EMPTY_HOWTO (42),
   EMPTY_HOWTO (43),
   EMPTY_HOWTO (44),
+
+#ifdef INCLUDE_SHMEDIA
+  /* Used in SHLLI.L and SHLRI.L.  */
+  HOWTO (R_SH_DIR5U,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        5,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR5U",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in SHARI, SHLLI et al.  */
+  HOWTO (R_SH_DIR6U,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        6,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR6U",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in BxxI, LDHI.L et al.  */
+  HOWTO (R_SH_DIR6S,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        6,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR6S",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in ADDI, ANDI et al.  */
+  HOWTO (R_SH_DIR10S,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        10,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10S",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.UW, ST.W et al.  */
+  HOWTO (R_SH_DIR10SW, /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        11,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SW",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_DIR10SL, /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SL",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_DIR10SQ, /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SQ",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+#else
   EMPTY_HOWTO (45),
   EMPTY_HOWTO (46),
   EMPTY_HOWTO (47),
@@ -499,6 +607,8 @@ static reloc_howto_type sh_elf_howto_table[] =
   EMPTY_HOWTO (49),
   EMPTY_HOWTO (50),
   EMPTY_HOWTO (51),
+#endif
+
   EMPTY_HOWTO (52),
   EMPTY_HOWTO (53),
   EMPTY_HOWTO (54),
@@ -720,6 +830,704 @@ static reloc_howto_type sh_elf_howto_table[] =
         0xffffffff,            /* dst_mask */
         true),                 /* pcrel_offset */
 
+  HOWTO (R_SH_GOTPLT32,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* */
+        "R_SH_GOTPLT32",       /* name */
+        false,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+#ifdef INCLUDE_SHMEDIA
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOT_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOT_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOT_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOT_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTPLT_LOW16,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_LOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTPLT_MEDHI16,  /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_MEDHI16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTPLT_HI16,     /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_HI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_PLT_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_PLT_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_PLT_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_PLT_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTOFF_LOW16,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_LOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTOFF_MEDHI16,  /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_MEDHI16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTOFF_HI16,     /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_HI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTPC_LOW16,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_LOW16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTPC_MEDLOW16,  /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTPC_MEDHI16,   /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_MEDHI16",  /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTPC_HI16,      /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_HI16",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_GOT10BY4,                /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT10BY4",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_GOTPLT10BY4,     /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT10BY4",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_GOT10BY8,                /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT10BY8",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_GOTPLT10BY8,     /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT10BY8",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_COPY64,          /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_COPY64",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_GLOB_DAT64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GLOB_DAT64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_JMP_SLOT64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_JMP_SLOT64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_RELATIVE64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_RELATIVE64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  EMPTY_HOWTO (197),
+  EMPTY_HOWTO (198),
+  EMPTY_HOWTO (199),
+  EMPTY_HOWTO (200),
+  EMPTY_HOWTO (201),
+  EMPTY_HOWTO (202),
+  EMPTY_HOWTO (203),
+  EMPTY_HOWTO (204),
+  EMPTY_HOWTO (205),
+  EMPTY_HOWTO (206),
+  EMPTY_HOWTO (207),
+  EMPTY_HOWTO (208),
+  EMPTY_HOWTO (209),
+  EMPTY_HOWTO (210),
+  EMPTY_HOWTO (211),
+  EMPTY_HOWTO (212),
+  EMPTY_HOWTO (213),
+  EMPTY_HOWTO (214),
+  EMPTY_HOWTO (215),
+  EMPTY_HOWTO (216),
+  EMPTY_HOWTO (217),
+  EMPTY_HOWTO (218),
+  EMPTY_HOWTO (219),
+  EMPTY_HOWTO (220),
+  EMPTY_HOWTO (221),
+  EMPTY_HOWTO (222),
+  EMPTY_HOWTO (223),
+  EMPTY_HOWTO (224),
+  EMPTY_HOWTO (225),
+  EMPTY_HOWTO (226),
+  EMPTY_HOWTO (227),
+  EMPTY_HOWTO (228),
+  EMPTY_HOWTO (229),
+  EMPTY_HOWTO (230),
+  EMPTY_HOWTO (231),
+  EMPTY_HOWTO (232),
+  EMPTY_HOWTO (233),
+  EMPTY_HOWTO (234),
+  EMPTY_HOWTO (235),
+  EMPTY_HOWTO (236),
+  EMPTY_HOWTO (237),
+  EMPTY_HOWTO (238),
+  EMPTY_HOWTO (239),
+  EMPTY_HOWTO (240),
+  EMPTY_HOWTO (241),
+
+  /* Relocations for SHmedia code.  None of these are partial_inplace or
+     use the field being relocated (except R_SH_PT_16).  */
+
+  /* The assembler will generate this reloc before a block of SHmedia
+     instructions.  A section should be processed as assuming it contains
+     data, unless this reloc is seen.  Note that a block of SHcompact
+     instructions are instead preceded by R_SH_CODE.
+     This is currently not implemented, but should be used for SHmedia
+     linker relaxation.  */
+  HOWTO (R_SH_SHMEDIA_CODE,    /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        sh_elf_ignore_reloc,   /* special_function */
+        "R_SH_SHMEDIA_CODE",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* The assembler will generate this reloc at a PTA or PTB instruction,
+     and the linker checks the right type of target, or changes a PTA to a
+     PTB, if the original insn was PT.  */
+  HOWTO (R_SH_PT_16,           /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        18,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PT_16",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in unexpanded MOVI.  */
+  HOWTO (R_SH_IMMS16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMMS16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in SHORI.  */
+  HOWTO (R_SH_IMMU16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMMU16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_IMM_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x - $) & 65536).  */
+  HOWTO (R_SH_IMM_LOW16_PCREL, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_LOW16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_IMM_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 16) & 65536).  */
+  HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDLOW16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_IMM_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 32) & 65536).  */
+  HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDHI16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_IMM_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 48) & 65536).  */
+  HOWTO (R_SH_IMM_HI16_PCREL,  /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_HI16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* For the .uaquad pseudo.  */
+  HOWTO (R_SH_64,              /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_64",             /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* For the .uaquad pseudo, (x - $).  */
+  HOWTO (R_SH_64_PCREL,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_64_PCREL",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        true),                 /* pcrel_offset */
+
+#endif
 };
 
 static bfd_reloc_status_type
@@ -965,6 +1773,58 @@ static const struct elf_reloc_map sh_reloc_map[] =
   { BFD_RELOC_SH_RELATIVE, R_SH_RELATIVE },
   { BFD_RELOC_32_GOTOFF, R_SH_GOTOFF },
   { BFD_RELOC_SH_GOTPC, R_SH_GOTPC },
+  { BFD_RELOC_SH_GOTPLT32, R_SH_GOTPLT32 },
+#ifdef INCLUDE_SHMEDIA
+  { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
+  { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
+  { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
+  { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
+  { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
+  { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
+  { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
+  { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
+  { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
+  { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
+  { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
+  { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
+  { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
+  { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
+  { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
+  { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
+  { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
+  { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
+  { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
+  { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
+  { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
+  { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
+  { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
+  { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
+  { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
+  { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
+  { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
+  { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
+  { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
+  { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
+  { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
+  { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
+  { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
+  { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
+  { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
+  { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
+  { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
+  { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
+  { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
+  { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
+  { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
+  { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
+  { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
+  { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
+  { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
+  { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
+  { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
+  { BFD_RELOC_64, R_SH_64 },
+  { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
+#endif /* not INCLUDE_SHMEDIA */
 };
 
 /* Given a BFD reloc code, return the howto structure for the
@@ -1001,6 +1861,8 @@ sh_elf_info_to_howto (abfd, cache_ptr, dst)
   BFD_ASSERT (r < (unsigned int) R_SH_max);
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
 
   cache_ptr->howto = &sh_elf_howto_table[r];
 }
@@ -1041,6 +1903,14 @@ sh_elf_relax_section (abfd, sec, link_info, again)
       || sec->reloc_count == 0)
     return true;
 
+#ifdef INCLUDE_SHMEDIA
+  if (elf_section_data (sec)->this_hdr.sh_flags
+      & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED))
+    {
+      return true;
+    }
+#endif
+
   /* If this is the first time we have been called for this section,
      initialize the cooked size.  */
   if (sec->_cooked_size == 0)
@@ -2140,6 +3010,178 @@ sh_elf_swap_insns (abfd, sec, relocs, contents, addr)
   return true;
 }
 \f
+#ifdef INCLUDE_SHMEDIA
+
+/* The size in bytes of an entry in the procedure linkage table.  */
+
+#define PLT_ENTRY_SIZE 64
+
+/* First entry in an absolute procedure linkage table look like this.  */
+
+static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x10, /* movi  .got.plt >> 16, r17 */
+  0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */
+  0x89, 0x10, 0x09, 0x90, /* ld.l  r17, 8, r25 */
+  0x6b, 0xf1, 0x46, 0x00, /* ptabs r17, tr0 */
+  0x89, 0x10, 0x05, 0x10, /* ld.l  r17, 4, r17 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x10, 0x01, 0x00, 0xcc, /* movi  .got.plt >> 16, r17 */
+  0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */
+  0x90, 0x09, 0x10, 0x89, /* ld.l  r17, 8, r25 */
+  0x00, 0x46, 0xf1, 0x6b, /* ptabs r17, tr0 */
+  0x10, 0x05, 0x10, 0x89, /* ld.l  r17, 4, r17 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Sebsequent entries in an absolute procedure linkage table look like
+   this.  */
+
+static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x90, /* movi  nameN-in-GOT >> 16, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori nameN-in-GOT & 65535, r25 */
+  0x89, 0x90, 0x01, 0x90, /* ld.l  r25, 0, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0xcc, 0x00, 0x01, 0x90, /* movi  .PLT0 >> 16, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0xcc, 0x00, 0x01, 0x50, /* movi  reloc-offset >> 16, r21 */
+  0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x90, 0x01, 0x00, 0xcc, /* movi  nameN-in-GOT >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+  0x90, 0x01, 0x90, 0x89, /* ld.l  r25, 0, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0x90, 0x01, 0x00, 0xcc, /* movi  .PLT0 >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0x50, 0x01, 0x00, 0xcc, /* movi  reloc-offset >> 16, r21 */
+  0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Entries in a PIC procedure linkage table look like this.  */
+
+static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x90, /* movi  nameN@GOT >> 16, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori nameN@GOT & 65535, r25 */
+  0x40, 0xc2, 0x65, 0x90, /* ldx.l r12, r25, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0xce, 0x00, 0x01, 0x10, /* movi  -GOT_BIAS, r17 */
+  0x00, 0xca, 0x45, 0x10, /* sub.l r12, r17, r17 */
+  0x89, 0x10, 0x09, 0x90, /* ld.l  r17, 8, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x89, 0x10, 0x05, 0x10, /* ld.l  r17, 4, r17 */
+  0xcc, 0x00, 0x01, 0x50, /* movi  reloc-offset >> 16, r21 */
+  0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+};
+
+static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x90, 0x01, 0x00, 0xcc, /* movi  nameN@GOT >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN@GOT & 65535, r25 */
+  0x90, 0x65, 0xc2, 0x40, /* ldx.l r12, r25, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0x10, 0x01, 0x00, 0xce, /* movi  -GOT_BIAS, r17 */
+  0x10, 0x45, 0xca, 0x00, /* sub.l r12, r17, r17 */
+  0x90, 0x09, 0x10, 0x89, /* ld.l  r17, 8, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0x10, 0x05, 0x10, 0x89, /* ld.l  r17, 4, r17 */
+  0x50, 0x01, 0x00, 0xcc, /* movi  reloc-offset >> 16, r21 */
+  0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+};
+
+static const bfd_byte *elf_sh_plt0_entry;
+static const bfd_byte *elf_sh_plt_entry;
+static const bfd_byte *elf_sh_pic_plt_entry;
+
+/* Return size of a PLT entry.  */
+#define elf_sh_sizeof_plt(info) PLT_ENTRY_SIZE
+
+/* Return offset of the PLT0 address in an absolute PLT entry.  */
+#define elf_sh_plt_plt0_offset(info) 32
+
+/* Return offset of the linker in PLT0 entry.  */
+#define elf_sh_plt0_gotplt_offset(info) 0
+
+/* Return offset of the trampoline in PLT entry */
+#define elf_sh_plt_temp_offset(info) 33 /* Add one because it's SHmedia.  */
+
+/* Return offset of the symbol in PLT entry.  */
+#define elf_sh_plt_symbol_offset(info) 0
+
+/* Return offset of the relocation in PLT entry.  */
+#define elf_sh_plt_reloc_offset(info) (info->shared ? 52 : 44)
+
+inline static void
+movi_shori_putval (output_bfd, value, addr)
+     bfd *output_bfd;
+     unsigned long value;
+     char *addr;
+{
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr)
+             | ((value >> 6) & 0x3fffc00),
+             addr);
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr + 4)
+             | ((value << 10) & 0x3fffc00),
+             addr + 4);
+}
+
+#else
 /* The size in bytes of an entry in the procedure linkage table.  */
 
 #define PLT_ENTRY_SIZE 28
@@ -2379,6 +3421,7 @@ static const bfd_byte *elf_sh_pic_plt_entry;
 
 /* Return offset of the relocation in PLT entry.  */
 #define elf_sh_plt_reloc_offset(info) 24
+#endif
 
 /* The sh linker needs to keep track of the number of relocs that it
    decides to copy in check_relocs for each symbol.  This is so that
@@ -2405,6 +3448,10 @@ struct elf_sh_link_hash_entry
 {
   struct elf_link_hash_entry root;
 
+#ifdef INCLUDE_SHMEDIA
+  bfd_vma datalabel_got_offset;
+#endif
+
   /* Number of PC relative relocs copied for this symbol.  */
   struct elf_sh_pcrel_relocs_copied *pcrel_relocs_copied;
 };
@@ -2461,6 +3508,9 @@ sh_elf_link_hash_newfunc (entry, table, string)
   if (ret != (struct elf_sh_link_hash_entry *) NULL)
     {
       ret->pcrel_relocs_copied = NULL;
+#ifdef INCLUDE_SHMEDIA
+      ret->datalabel_got_offset = (bfd_vma) -1;
+#endif
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -3014,6 +4064,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   bfd *dynobj;
   bfd_vma *local_got_offsets;
   asection *sgot;
+  asection *sgotplt;
   asection *splt;
   asection *sreloc;
 
@@ -3023,6 +4074,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
   sgot = NULL;
+  sgotplt = NULL;
   splt = NULL;
   sreloc = NULL;
 
@@ -3039,6 +4091,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       bfd_vma relocation;
       bfd_vma addend = (bfd_vma) 0;
       bfd_reloc_status_type r;
+      int seen_stt_datalabel = 0;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
@@ -3056,6 +4109,10 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          || r_type >= R_SH_max
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
              && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+         || (   r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
+         || (   r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
              && r_type <= (int) R_SH_LAST_INVALID_RELOC_2))
        {
@@ -3080,6 +4137,14 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
+         /* A local symbol never has STO_SH5_ISA32, so we don't need
+            datalabel processing here.  Make sure this does not change
+            without notice.  */
+         if ((sym->st_other & STO_SH5_ISA32) != 0)
+           ((*info->callbacks->reloc_dangerous)
+            (info,
+             _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+             input_bfd, input_section, rel->r_offset));
          if (info->relocateable)
            {
              /* This is a relocateable link.  We don't have to change
@@ -3158,7 +4223,15 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+           {
+#ifdef INCLUDE_SHMEDIA
+             /* If the reference passes a symbol marked with
+                STT_DATALABEL, then any STO_SH5_ISA32 on the final value
+                doesn't count.  */
+             seen_stt_datalabel |= h->type == STT_DATALABEL;
+#endif
+             h = (struct elf_link_hash_entry *) h->root.u.i.link;
+           }
          if (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
            {
@@ -3167,9 +4240,21 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                 We check specially because in some obscure cases
                 sec->output_section will be NULL.  */
              if (r_type == R_SH_GOTPC
-                 || (r_type == R_SH_PLT32
+                 || r_type == R_SH_GOTPC_LOW16
+                 || r_type == R_SH_GOTPC_MEDLOW16
+                 || r_type == R_SH_GOTPC_MEDHI16
+                 || r_type == R_SH_GOTPC_HI16
+                 || ((r_type == R_SH_PLT32
+                      || r_type == R_SH_PLT_LOW16
+                      || r_type == R_SH_PLT_MEDLOW16
+                      || r_type == R_SH_PLT_MEDHI16
+                      || r_type == R_SH_PLT_HI16)
                      && h->plt.offset != (bfd_vma) -1)
-                 || (r_type == R_SH_GOT32
+                 || ((r_type == R_SH_GOT32
+                      || r_type == R_SH_GOT_LOW16
+                      || r_type == R_SH_GOT_MEDLOW16
+                      || r_type == R_SH_GOT_MEDHI16
+                      || r_type == R_SH_GOT_HI16)
                      && elf_hash_table (info)->dynamic_sections_created
                      && (! info->shared
                          || (! info->symbolic && h->dynindx != -1)
@@ -3204,9 +4289,14 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  relocation = 0;
                }
              else
-               relocation = (h->root.u.def.value
+               relocation = ((h->root.u.def.value
                              + sec->output_section->vma
-                             + sec->output_offset);
+                             + sec->output_offset)
+                             /* A STO_SH5_ISA32 causes a "bitor 1" to the
+                                symbol value, unless we've seen
+                                STT_DATALABEL on the way to it.  */
+                             | ((h->other & STO_SH5_ISA32) != 0
+                                && ! seen_stt_datalabel));
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
@@ -3277,6 +4367,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
 
        default:
+#ifdef INCLUDE_SHMEDIA
+         if (shmedia_prepare_reloc (info, input_bfd, input_section,
+                                    contents, rel, &relocation))
+           goto final_link_relocate;
+#endif
          bfd_set_error (bfd_error_bad_value);
          return false;
 
@@ -3383,7 +4478,56 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          goto final_link_relocate;
 
+       case R_SH_GOTPLT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOTPLT_LOW16:
+       case R_SH_GOTPLT_MEDLOW16:
+       case R_SH_GOTPLT_MEDHI16:
+       case R_SH_GOTPLT_HI16:
+       case R_SH_GOTPLT10BY4:
+       case R_SH_GOTPLT10BY8:
+#endif
+         /* Relocation is to the entry for this symbol in the
+            procedure linkage table.  */
+
+         if (h == NULL
+             || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+             || ! info->shared
+             || info->symbolic
+             || h->dynindx == -1
+             || h->plt.offset == (bfd_vma) -1
+             || h->got.offset != (bfd_vma) -1)
+           goto force_got;
+
+         /* Relocation is to the entry for this symbol in the global
+            offset table extension for the procedure linkage table.  */
+         if (sgotplt == NULL)
+           {
+             sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+             BFD_ASSERT (sgotplt != NULL);
+           }
+
+         relocation = (sgotplt->output_offset
+                       + ((h->plt.offset / elf_sh_sizeof_plt (info)
+                           - 1 + 3) * 4));
+
+#ifdef GOT_BIAS
+         relocation -= GOT_BIAS;
+#endif
+
+         goto final_link_relocate;
+
+       force_got:
        case R_SH_GOT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOT_LOW16:
+       case R_SH_GOT_MEDLOW16:
+       case R_SH_GOT_MEDHI16:
+       case R_SH_GOT_HI16:
+       case R_SH_GOT10BY4:
+       case R_SH_GOT10BY8:
+#endif
          /* Relocation is to the entry for this symbol in the global
             offset table.  */
          if (sgot == NULL)
@@ -3397,6 +4541,15 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              bfd_vma off;
 
              off = h->got.offset;
+#ifdef INCLUDE_SHMEDIA
+             if (seen_stt_datalabel)
+               {
+                 struct elf_sh_link_hash_entry *hsh;
+
+                 hsh = (struct elf_sh_link_hash_entry *)h;
+                 off = hsh->datalabel_got_offset;
+               }
+#endif
              BFD_ASSERT (off != (bfd_vma) -1);
 
              if (! elf_hash_table (info)->dynamic_sections_created
@@ -3424,7 +4577,17 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                    {
                      bfd_put_32 (output_bfd, relocation,
                                  sgot->contents + off);
-                     h->got.offset |= 1;
+#ifdef INCLUDE_SHMEDIA
+                     if (seen_stt_datalabel)
+                       {
+                         struct elf_sh_link_hash_entry *hsh;
+
+                         hsh = (struct elf_sh_link_hash_entry *)h;
+                         hsh->datalabel_got_offset |= 1;
+                       }
+                     else
+#endif
+                       h->got.offset |= 1;
                    }
                }
 
@@ -3434,10 +4597,27 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            {
              bfd_vma off;
 
+#ifdef INCLUDE_SHMEDIA
+             if (rel->r_addend)
+               {
+                 BFD_ASSERT (local_got_offsets != NULL
+                             && (local_got_offsets[symtab_hdr->sh_info
+                                                   + r_symndx]
+                                 != (bfd_vma) -1));
+
+                 off = local_got_offsets[symtab_hdr->sh_info
+                                         + r_symndx];
+               }
+             else
+               {
+#endif
              BFD_ASSERT (local_got_offsets != NULL
                          && local_got_offsets[r_symndx] != (bfd_vma) -1);
 
              off = local_got_offsets[r_symndx];
+#ifdef INCLUDE_SHMEDIA
+               }
+#endif
 
              /* The offset must always be a multiple of 4.  We use
                 the least significant bit to record whether we have
@@ -3468,15 +4648,30 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                      ++srelgot->reloc_count;
                    }
 
-                 local_got_offsets[r_symndx] |= 1;
+#ifdef INCLUDE_SHMEDIA
+                 if (rel->r_addend)
+                   local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
+                 else
+#endif
+                   local_got_offsets[r_symndx] |= 1;
                }
 
              relocation = sgot->output_offset + off;
            }
 
+#ifdef GOT_BIAS
+         relocation -= GOT_BIAS;
+#endif
+
          goto final_link_relocate;
 
        case R_SH_GOTOFF:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOTOFF_LOW16:
+       case R_SH_GOTOFF_MEDLOW16:
+       case R_SH_GOTOFF_MEDHI16:
+       case R_SH_GOTOFF_HI16:
+#endif
          /* Relocation is relative to the start of the global offset
             table.  */
 
@@ -3493,9 +4688,21 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
             calculation.  */
          relocation -= sgot->output_section->vma;
 
+#ifdef GOT_BIAS
+         relocation -= GOT_BIAS;
+#endif
+
+         addend = rel->r_addend;
+
          goto final_link_relocate;
 
        case R_SH_GOTPC:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOTPC_LOW16:
+       case R_SH_GOTPC_MEDLOW16:
+       case R_SH_GOTPC_MEDHI16:
+       case R_SH_GOTPC_HI16:
+#endif
          /* Use global offset table as symbol value.  */
 
          if (sgot == NULL)
@@ -3506,9 +4713,21 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
          relocation = sgot->output_section->vma;
 
+#ifdef GOT_BIAS
+         relocation += GOT_BIAS;
+#endif
+
+         addend = rel->r_addend;
+
          goto final_link_relocate;
 
        case R_SH_PLT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_PLT_LOW16:
+       case R_SH_PLT_MEDLOW16:
+       case R_SH_PLT_MEDHI16:
+       case R_SH_PLT_HI16:
+#endif
          /* Relocation is to the entry for this symbol in the
             procedure linkage table.  */
 
@@ -3539,6 +4758,12 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                        + splt->output_offset
                        + h->plt.offset);
 
+#ifdef INCLUDE_SHMEDIA
+         relocation++;
+#endif
+
+         addend = rel->r_addend;
+
          goto final_link_relocate;
 
        case R_SH_LOOP_START:
@@ -3851,9 +5076,32 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
        {
          switch (ELF32_R_TYPE (rel->r_info))
            {
+           case R_SH_GOTPLT32:
            case R_SH_GOT32:
            case R_SH_GOTOFF:
            case R_SH_GOTPC:
+#ifdef INCLUDE_SHMEDIA
+           case R_SH_GOTPLT_LOW16:
+           case R_SH_GOTPLT_MEDLOW16:
+           case R_SH_GOTPLT_MEDHI16:
+           case R_SH_GOTPLT_HI16:
+           case R_SH_GOTPLT10BY4:
+           case R_SH_GOTPLT10BY8:
+           case R_SH_GOT_LOW16:
+           case R_SH_GOT_MEDLOW16:
+           case R_SH_GOT_MEDHI16:
+           case R_SH_GOT_HI16:
+           case R_SH_GOT10BY4:
+           case R_SH_GOT10BY8:
+           case R_SH_GOTOFF_LOW16:
+           case R_SH_GOTOFF_MEDLOW16:
+           case R_SH_GOTOFF_MEDHI16:
+           case R_SH_GOTOFF_HI16:
+           case R_SH_GOTPC_LOW16:
+           case R_SH_GOTPC_MEDLOW16:
+           case R_SH_GOTPC_MEDHI16:
+           case R_SH_GOTPC_HI16:
+#endif
              elf_hash_table (info)->dynobj = dynobj = abfd;
              if (! _bfd_elf_create_got_section (dynobj, info))
                return false;
@@ -3880,7 +5128,16 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
            return false;
          break;
 
+       force_got:
        case R_SH_GOT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOT_LOW16:
+       case R_SH_GOT_MEDLOW16:
+       case R_SH_GOT_MEDHI16:
+       case R_SH_GOT_HI16:
+       case R_SH_GOT10BY4:
+       case R_SH_GOT10BY8:
+#endif
          /* This symbol requires a global offset table entry.  */
 
          if (sgot == NULL)
@@ -3911,12 +5168,30 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
+#ifdef INCLUDE_SHMEDIA
+             if (h->type == STT_DATALABEL)
+               {
+                 struct elf_sh_link_hash_entry *hsh;
+
+                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
+                 hsh = (struct elf_sh_link_hash_entry *)h;
+                 if (hsh->datalabel_got_offset != (bfd_vma) -1)
+                   break;
+
+                 hsh->datalabel_got_offset = sgot->_raw_size;
+               }
+             else
+               {
+#endif
              if (h->got.offset != (bfd_vma) -1)
                {
                  /* We have already allocated space in the .got.  */
                  break;
                }
              h->got.offset = sgot->_raw_size;
+#ifdef INCLUDE_SHMEDIA
+               }
+#endif
 
              /* Make sure this symbol is output as a dynamic symbol.  */
              if (h->dynindx == -1)
@@ -3938,19 +5213,46 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
 
                  size = symtab_hdr->sh_info;
                  size *= sizeof (bfd_vma);
+#ifdef INCLUDE_SHMEDIA
+                 /* Reserve space for both the datalabel and
+                    codelabel local GOT offsets.  */
+                 size *= 2;
+#endif
                  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
                  if (local_got_offsets == NULL)
                    return false;
                  elf_local_got_offsets (abfd) = local_got_offsets;
                  for (i = 0; i < symtab_hdr->sh_info; i++)
                    local_got_offsets[i] = (bfd_vma) -1;
+#ifdef INCLUDE_SHMEDIA
+                 for (; i < 2 * symtab_hdr->sh_info; i++)
+                   local_got_offsets[i] = (bfd_vma) -1;
+#endif
                }
+#ifdef INCLUDE_SHMEDIA
+             if ((rel->r_addend & 1) != 0)
+               {
+                 if (local_got_offsets[symtab_hdr->sh_info
+                                       + r_symndx] != (bfd_vma) -1)
+                   {
+                     /* We have already allocated space in the .got.  */
+                     break;
+                   }
+                 local_got_offsets[symtab_hdr->sh_info
+                                   + r_symndx] = sgot->_raw_size;
+               }
+             else
+               {
+#endif
              if (local_got_offsets[r_symndx] != (bfd_vma) -1)
                {
                  /* We have already allocated space in the .got.  */
                  break;
                }
              local_got_offsets[r_symndx] = sgot->_raw_size;
+#ifdef INCLUDE_SHMEDIA
+               }
+#endif
 
              if (info->shared)
                {
@@ -3965,7 +5267,45 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
 
          break;
 
+       case R_SH_GOTPLT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_GOTPLT_LOW16:
+       case R_SH_GOTPLT_MEDLOW16:
+       case R_SH_GOTPLT_MEDHI16:
+       case R_SH_GOTPLT_HI16:
+       case R_SH_GOTPLT10BY4:
+       case R_SH_GOTPLT10BY8:
+#endif
+         /* If this is a local symbol, we resolve it directly without
+            creating a procedure linkage table entry.  */
+
+         if (h == NULL
+             || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+             || ! info->shared
+             || info->symbolic
+             || h->dynindx == -1
+             || h->got.offset != (bfd_vma) -1)
+           goto force_got;
+
+         /* Make sure this symbol is output as a dynamic symbol.  */
+         if (h->dynindx == -1)
+           {
+             if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+               return false;
+           }
+
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+         break;
+
        case R_SH_PLT32:
+#ifdef INCLUDE_SHMEDIA
+       case R_SH_PLT_LOW16:
+       case R_SH_PLT_MEDLOW16:
+       case R_SH_PLT_MEDHI16:
+       case R_SH_PLT_HI16:
+#endif
          /* This symbol requires a procedure linkage table entry.  We
             actually build the entry in adjust_dynamic_symbol,
             because this might be a case of linking PIC code which is
@@ -4093,6 +5433,7 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
   return true;
 }
 
+#ifndef sh_elf_set_mach_from_flags
 static boolean
 sh_elf_set_mach_from_flags (abfd)
      bfd *abfd;
@@ -4128,7 +5469,9 @@ sh_elf_set_mach_from_flags (abfd)
     }
   return true;
 }
+#endif /* not sh_elf_set_mach_from_flags */
 
+#ifndef sh_elf_set_private_flags
 /* Function to keep SH specific file flags.  */
 
 static boolean
@@ -4143,7 +5486,9 @@ sh_elf_set_private_flags (abfd, flags)
   elf_flags_init (abfd) = true;
   return sh_elf_set_mach_from_flags (abfd);
 }
+#endif /* not sh_elf_set_private_flags */
 
+#ifndef sh_elf_copy_private_data
 /* Copy backend specific data from one object module to another */
 
 static boolean
@@ -4157,7 +5502,9 @@ sh_elf_copy_private_data (ibfd, obfd)
 
   return sh_elf_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
 }
+#endif /* not sh_elf_copy_private_data */
 
+#ifndef sh_elf_merge_private_data
 /* This routine checks for linking big and little endian objects
    together, and for linking sh-dsp with sh3e / sh4 objects.  */
 
@@ -4198,6 +5545,7 @@ sh_elf_merge_private_data (ibfd, obfd)
 
   return sh_elf_set_mach_from_flags (obfd);
 }
+#endif /* not sh_elf_merge_private_data */
 
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
@@ -4244,6 +5592,10 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
         The first three are reserved.  */
       got_offset = (plt_index + 3) * 4;
 
+#ifdef GOT_BIAS
+      got_offset -= GOT_BIAS;
+#endif
+
       /* Fill in the entry in the procedure linkage table.  */
       if (! info->shared)
        {
@@ -4254,6 +5606,19 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
            }
          memcpy (splt->contents + h->plt.offset, elf_sh_plt_entry,
                  elf_sh_sizeof_plt (info));
+#ifdef INCLUDE_SHMEDIA
+         movi_shori_putval (output_bfd,
+                            (sgot->output_section->vma
+                             + sgot->output_offset
+                             + got_offset),
+                            (splt->contents + h->plt.offset
+                             + elf_sh_plt_symbol_offset (info)));
+
+         movi_shori_putval (output_bfd,
+                            (splt->output_section->vma + splt->output_offset),
+                            (splt->contents + h->plt.offset
+                             + elf_sh_plt_plt0_offset (info)));
+#else
          bfd_put_32 (output_bfd,
                      (sgot->output_section->vma
                       + sgot->output_offset
@@ -4265,6 +5630,7 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
                      (splt->output_section->vma + splt->output_offset),
                      (splt->contents + h->plt.offset
                       + elf_sh_plt_plt0_offset (info)));
+#endif
        }
       else
        {
@@ -4276,14 +5642,31 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
            }
          memcpy (splt->contents + h->plt.offset, elf_sh_pic_plt_entry,
                  elf_sh_sizeof_plt (info));
+#ifdef INCLUDE_SHMEDIA
+         movi_shori_putval (output_bfd, got_offset,
+                            (splt->contents + h->plt.offset
+                             + elf_sh_plt_symbol_offset (info)));
+#else
          bfd_put_32 (output_bfd, got_offset,
                      (splt->contents + h->plt.offset
                       + elf_sh_plt_symbol_offset (info)));
+#endif
        }
 
+#ifdef GOT_BIAS
+      got_offset += GOT_BIAS;
+#endif
+
+#ifdef INCLUDE_SHMEDIA
+      movi_shori_putval (output_bfd,
+                        plt_index * sizeof (Elf32_External_Rela),
+                        (splt->contents + h->plt.offset
+                         + elf_sh_plt_reloc_offset (info)));
+#else
       bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
                  (splt->contents + h->plt.offset
                   + elf_sh_plt_reloc_offset (info)));
+#endif
 
       /* Fill in the entry in the global offset table.  */
       bfd_put_32 (output_bfd,
@@ -4299,6 +5682,9 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
                      + got_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_JMP_SLOT);
       rel.r_addend = 0;
+#ifdef GOT_BIAS
+      rel.r_addend = GOT_BIAS;
+#endif
       bfd_elf32_swap_reloca_out (output_bfd, &rel,
                                ((Elf32_External_Rela *) srel->contents
                                 + plt_index));
@@ -4498,12 +5884,20 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
                                       elf_sh_plt0_entry_le);
                }
              memcpy (splt->contents, elf_sh_plt0_entry, PLT_ENTRY_SIZE);
+#ifdef INCLUDE_SHMEDIA
+             movi_shori_putval (output_bfd,
+                                sgot->output_section->vma
+                                + sgot->output_offset,
+                                splt->contents
+                                + elf_sh_plt0_gotplt_offset (info));
+#else
              bfd_put_32 (output_bfd,
                          sgot->output_section->vma + sgot->output_offset + 4,
                          splt->contents + elf_sh_plt0_gotid_offset (info));
              bfd_put_32 (output_bfd,
                          sgot->output_section->vma + sgot->output_offset + 8,
                          splt->contents + elf_sh_plt0_linker_offset (info));
+#endif
            }
 
          /* UnixWare sets the entsize of .plt to 4, although that doesn't
diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c
new file mode 100644 (file)
index 0000000..561c7af
--- /dev/null
@@ -0,0 +1,983 @@
+/* Hitachi SH64-specific support for 32-bit ELF
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   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 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.  */
+
+#define SH64_ELF
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "elf-bfd.h"
+#include "../opcodes/sh64-opc.h"
+
+/* Add a suffix for datalabel indirection symbols.  It must not match any
+   other symbols; user symbols with or without version or other
+   decoration.  It must only be used internally and not emitted by any
+   means.  */
+#define DATALABEL_SUFFIX " DL"
+
+/* Used to hold data for function called through bfd_map_over_sections.  */
+struct sh64_find_section_vma_data
+ {
+   asection *section;
+   bfd_vma addr;
+ };
+
+static boolean sh64_elf_copy_private_data PARAMS ((bfd *, bfd *));
+static boolean sh64_elf_merge_private_data PARAMS ((bfd *, bfd *));
+static boolean sh64_elf_fake_sections PARAMS ((bfd *, Elf_Internal_Shdr *,
+                                             asection *));
+static boolean sh64_elf_set_private_flags PARAMS ((bfd *, flagword));
+static boolean sh64_elf_set_mach_from_flags PARAMS ((bfd *));
+static boolean shmedia_prepare_reloc
+  PARAMS ((struct bfd_link_info *, bfd *, asection *,
+          bfd_byte *, const Elf_Internal_Rela *, bfd_vma *));
+static int sh64_elf_get_symbol_type PARAMS ((Elf_Internal_Sym *, int));
+static boolean sh64_elf_add_symbol_hook
+  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+          const char **, flagword *, asection **, bfd_vma *));
+static boolean sh64_elf_link_output_symbol_hook
+  PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+          asection *));
+static boolean sh64_backend_section_from_shdr
+  PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
+static void sh64_elf_final_write_processing PARAMS ((bfd *, boolean));
+static boolean sh64_bfd_elf_copy_private_section_data
+  PARAMS ((bfd *, asection *, bfd *, asection *));
+
+/* Let elf32-sh.c handle the "bfd_" definitions, so we only have to
+   intrude with an #ifndef around the function definition.  */
+#define sh_elf_copy_private_data               sh64_elf_copy_private_data
+#define sh_elf_merge_private_data              sh64_elf_merge_private_data
+#define sh_elf_set_private_flags               sh64_elf_set_private_flags
+/* Typo in elf32-sh.c (and unlinear name).  */
+#define bfd_elf32_bfd_set_private_flags                sh64_elf_set_private_flags
+#define sh_elf_set_mach_from_flags             sh64_elf_set_mach_from_flags
+
+#define elf_backend_sign_extend_vma            1
+#define elf_backend_fake_sections              sh64_elf_fake_sections
+#define elf_backend_get_symbol_type            sh64_elf_get_symbol_type
+#define elf_backend_add_symbol_hook            sh64_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+       sh64_elf_link_output_symbol_hook
+#define elf_backend_final_write_processing     sh64_elf_final_write_processing
+#define elf_backend_section_from_shdr          sh64_backend_section_from_shdr
+
+/* For objcopy, we need to set up sh64_elf_section_data (asection *) from
+   incoming section flags.  This is otherwise done in sh64elf.em when
+   linking or tc-sh64.c when assembling.  */
+#define bfd_elf32_bfd_copy_private_section_data \
+       sh64_bfd_elf_copy_private_section_data
+
+/* This COFF-only function (only compiled with COFF support, making
+   ELF-only chains problematic) returns true early for SH4, so let's just
+   define it true here.  */
+#define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) true
+
+#ifndef ELF_ARCH
+#define TARGET_BIG_SYM         bfd_elf32_sh64_vec
+#define TARGET_BIG_NAME                "elf32-sh64"
+#define TARGET_LITTLE_SYM      bfd_elf32_sh64l_vec
+#define TARGET_LITTLE_NAME     "elf32-sh64l"
+#define ELF_ARCH               bfd_arch_sh
+#define ELF_MACHINE_CODE       EM_SH
+#define ELF_MAXPAGESIZE                128
+
+#define elf_symbol_leading_char '_'
+#endif /* ELF_ARCH */
+
+#define GOT_BIAS (-((long)-32768))
+#define INCLUDE_SHMEDIA
+#include "elf32-sh.c"
+
+/* The type sh64_elf_crange is defined in elf/sh.h which is included in
+   elf32-sh.c, hence these prototypes located after including it.  */
+static int crange_qsort_cmpb PARAMS ((const void *, const void *));
+static int crange_qsort_cmpl PARAMS ((const void *, const void *));
+static int crange_bsearch_cmpb PARAMS ((const void *, const void *));
+static int crange_bsearch_cmpl PARAMS ((const void *, const void *));
+static boolean sh64_address_in_cranges
+  PARAMS ((asection *cranges, bfd_vma, sh64_elf_crange *));
+
+/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
+   through SHT_SH5_CR_SORTED on a sorted .cranges section.  */
+
+boolean
+sh64_elf_fake_sections (output_bfd, elf_section_hdr, asect)
+     bfd *output_bfd ATTRIBUTE_UNUSED;
+     Elf_Internal_Shdr *elf_section_hdr;
+     asection *asect;
+{
+  if (sh64_elf_section_data (asect) != NULL)
+    elf_section_hdr->sh_flags
+      |= sh64_elf_section_data (asect)->contents_flags;
+
+  /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted
+     .cranges section passing through objcopy.  */
+  if ((bfd_get_section_flags (output_bfd, asect) & SEC_SORT_ENTRIES) != 0
+      && strcmp (bfd_get_section_name (output_bfd, asect),
+                SH64_CRANGES_SECTION_NAME) == 0)
+    elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;
+
+  return true;
+}
+
+static boolean
+sh64_elf_set_mach_from_flags (abfd)
+     bfd *abfd;
+{
+  flagword flags = elf_elfheader (abfd)->e_flags;
+  asection *cranges;
+
+  switch (flags & EF_SH_MACH_MASK)
+    {
+    case EF_SH5:
+      /* These are fit to execute on SH5.  Just one but keep the switch
+        construct to make additions easy.  */
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
+      break;
+
+    default:
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
+    }
+
+  /* We also need to set SEC_DEBUGGING on an incoming .cranges section.
+     We could have used elf_backend_section_flags if it had given us the
+     section name; the bfd_section member in the header argument is not
+     set at the point of the call.  FIXME: Find out whether that is by
+     undocumented design or a bug.  */
+  cranges = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
+  if (cranges != NULL
+      && ! bfd_set_section_flags (abfd, cranges,
+                                 bfd_get_section_flags (abfd, cranges)
+                                 | SEC_DEBUGGING))
+    return false;
+
+  return true;
+}
+
+static boolean
+sh64_elf_copy_private_data (ibfd, obfd)
+     bfd * ibfd;
+     bfd * obfd;
+{
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  BFD_ASSERT (!elf_flags_init (obfd)
+             || (elf_elfheader (obfd)->e_flags
+                 == elf_elfheader (ibfd)->e_flags));
+
+  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+  return true;
+}
+
+static boolean
+sh64_elf_merge_private_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword old_flags, new_flags;
+
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+    return false;
+
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
+    {
+      const char *msg;
+
+      if (bfd_get_arch_size (ibfd) == 32
+         && bfd_get_arch_size (obfd) == 64)
+       msg = _("%s: compiled as 32-bit object and %s is 64-bit");
+      else if (bfd_get_arch_size (ibfd) == 64
+              && bfd_get_arch_size (obfd) == 32)
+       msg = _("%s: compiled as 64-bit object and %s is 32-bit");
+      else
+       msg = _("%s: object size does not match that of target %s");
+
+      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
+                            bfd_get_filename (obfd));
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
+    }
+
+  old_flags = elf_elfheader (obfd)->e_flags;
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  if (! elf_flags_init (obfd))
+    {
+      /* This happens when ld starts out with a 'blank' output file.  */
+      elf_flags_init (obfd) = true;
+      elf_elfheader (obfd)->e_flags = old_flags = new_flags;
+    }
+  /* We don't allow linking in non-SH64 code.  */
+  else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
+    {
+      (*_bfd_error_handler)
+       ("%s: uses non-SH64 instructions while previous modules use SH64 instructions",
+        bfd_get_filename (ibfd));
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  /* I can't think of anything sane other than old_flags being EF_SH5 and
+     that we need to preserve that.  */
+  elf_elfheader (obfd)->e_flags = old_flags;
+  return sh64_elf_set_mach_from_flags (obfd);
+}
+
+/* Handle a SH64-specific section when reading an object file.  This
+   is called when elfcode.h finds a section with an unknown type.
+
+   We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */
+
+boolean
+sh64_backend_section_from_shdr (abfd, hdr, name)
+     bfd *abfd;
+     Elf_Internal_Shdr *hdr;
+     char *name;
+{
+  flagword flags = 0;
+
+  /* We do like MIPS with a bit switch for recognized types, and returning
+     false for a recognized section type with an unexpected name.  Right
+     now we only have one recognized type, but that might change.  */
+  switch (hdr->sh_type)
+    {
+    case SHT_SH5_CR_SORTED:
+      if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)
+       return false;
+
+      /* We set the SEC_SORT_ENTRIES flag so it can be passed on to
+        sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object
+        passes through objcopy.  Perhaps it is brittle; the flag can
+        suddenly be used by other BFD parts, but it seems not really used
+        anywhere at the moment.  */
+      flags = SEC_DEBUGGING | SEC_SORT_ENTRIES;
+      break;
+
+    default:
+      return false;
+    }
+
+  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+    return false;
+
+  if (flags
+      && ! bfd_set_section_flags (abfd, hdr->bfd_section,
+                                 bfd_get_section_flags (abfd,
+                                                        hdr->bfd_section)
+                                 | flags))
+    return false;
+
+  return true;
+}
+
+/* In contrast to sh64_backend_section_from_shdr, this is called for all
+   sections, but only when copying sections, not when linking or
+   assembling.  We need to set up the sh64_elf_section_data (asection *)
+   structure for the SH64 ELF section flags to be copied correctly.  */
+
+boolean
+sh64_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)
+     bfd *ibfd;
+     asection *isec;
+     bfd *obfd;
+     asection *osec;
+{
+  struct sh64_section_data *sh64_sec_data;
+
+  if (ibfd->xvec->flavour != bfd_target_elf_flavour
+      || obfd->xvec->flavour != bfd_target_elf_flavour)
+    return true;
+
+  if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
+    return false;
+
+  sh64_sec_data = sh64_elf_section_data (isec);
+  if (sh64_sec_data == NULL)
+    {
+      sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));
+
+      if (sh64_sec_data == NULL)
+       return false;
+
+      sh64_sec_data->contents_flags
+       = (elf_section_data (isec)->this_hdr.sh_flags
+          & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));
+
+      sh64_elf_section_data (osec) = sh64_sec_data;
+    }
+
+  return true;
+}
+
+/* Function to keep SH64 specific file flags.  */
+
+static boolean
+sh64_elf_set_private_flags (abfd, flags)
+     bfd *    abfd;
+     flagword flags;
+{
+  BFD_ASSERT (! elf_flags_init (abfd)
+             || elf_elfheader (abfd)->e_flags == flags);
+
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = true;
+  return sh64_elf_set_mach_from_flags (abfd);
+}
+
+/* Called when writing out an object file to decide the type of a symbol.  */
+
+static int
+sh64_elf_get_symbol_type (elf_sym, type)
+     Elf_Internal_Sym * elf_sym;
+     int type;
+{
+  if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
+    return STT_DATALABEL;
+
+  return type;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+   file.  We must make indirect symbols for undefined symbols marked with
+   STT_DATALABEL, so relocations passing them will pick up that attribute
+   and neutralize STO_SH5_ISA32 found on the symbol definition.
+
+   There is a problem, though: We want to fill in the hash-table entry for
+   this symbol and signal to the caller that no further processing is
+   needed.  But we don't have the index for this hash-table entry.  We
+   rely here on that the current entry is the first hash-entry with NULL,
+   which seems brittle.  Also, iterating over the hash-table to find that
+   entry is a linear operation on the number of symbols in this input
+   file, and this function should take constant time, so that's not good
+   too.  Only comfort is that DataLabel references should only be found in
+   hand-written assembly code and thus be rare.  FIXME: Talk maintainers
+   into adding an option to elf_add_symbol_hook (preferably) for the index
+   or the hash entry, alternatively adding the index to Elf_Internal_Sym
+   (not so good).  */
+
+static boolean
+sh64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     const Elf_Internal_Sym *sym;
+     const char **namep;
+     flagword *flagsp ATTRIBUTE_UNUSED;
+     asection **secp;
+     bfd_vma *valp;
+{
+  /* We want to do this for relocatable as well as final linking.  */
+  if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+    {
+      struct elf_link_hash_entry *h;
+
+      /* For relocateable links, we register the DataLabel sym in its own
+        right, and tweak the name when it's output.  Otherwise, we make
+        an indirect symbol of it.  */
+      flagword flags
+       = info->relocateable || info->emitrelocations
+       ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
+
+      char *dl_name
+       = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
+      struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
+
+      BFD_ASSERT (sym_hash != NULL);
+
+      /* Allocation may fail.  */
+      if (dl_name == NULL)
+       return false;
+
+      strcpy (dl_name, *namep);
+      strcat (dl_name, DATALABEL_SUFFIX);
+
+      h = (struct elf_link_hash_entry *)
+       bfd_link_hash_lookup (info->hash, dl_name, false, false, false);
+
+      if (h == NULL)
+       {
+         /* No previous datalabel symbol.  Make one.  */
+         if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
+                                                 flags, *secp, *valp,
+                                                 *namep, false,
+                                                 get_elf_backend_data (abfd)->collect,
+                                                 (struct bfd_link_hash_entry **) &h))
+           {
+             free (dl_name);
+             return false;
+           }
+
+         h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+         h->type = STT_DATALABEL;
+       }
+      else
+       /* If a new symbol was created, it holds the allocated name.
+          Otherwise, we don't need it anymore and should deallocate it.  */
+       free (dl_name);
+
+      if (h->type != STT_DATALABEL
+         || ((info->relocateable || info->emitrelocations)
+             && h->root.type != bfd_link_hash_undefined)
+         || (! info->relocateable && !info->emitrelocations
+             && h->root.type != bfd_link_hash_indirect))
+       {
+         /* Make sure we don't get confused on invalid input.  */
+         (*_bfd_error_handler)
+           (_("%s: encountered datalabel symbol in input"),
+            bfd_get_filename (abfd));
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+       }
+
+      /* Now find the hash-table slot for this entry and fill it in.  */
+      while (*sym_hash != NULL)
+       sym_hash++;
+      *sym_hash = h;
+
+      /* Signal to caller to skip this symbol - we've handled it.  */
+      *namep = NULL;
+    }
+
+  return true;
+}
+
+/* This hook function is called before the linker writes out a global
+   symbol.  For relocatable links, DataLabel symbols will be present in
+   linker output.  We cut off the special suffix on those symbols, so the
+   right name appears in the output.
+
+   When linking and emitting relocations, there can appear global symbols
+   that are not referenced by relocs, but rather only implicitly through
+   DataLabel references, a relation that is not visible to the linker.
+   Since no stripping of global symbols in done when doing such linking,
+   we don't need to look up and make sure to emit the main symbol for each
+   DataLabel symbol.  */
+
+boolean
+sh64_elf_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info;
+     const char *cname;
+     Elf_Internal_Sym *sym;
+     asection *input_sec ATTRIBUTE_UNUSED;
+{
+  char *name = (char *) cname;
+
+  if (info->relocateable || info->emitrelocations)
+    {
+      if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+       name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
+    }
+
+  return true;
+}
+
+/* Check a SH64-specific reloc and put the value to relocate to into
+   RELOCATION, ready to pass to _bfd_final_link_relocate.  Return FALSE if
+   bad value, TRUE if ok.  */
+
+static boolean
+shmedia_prepare_reloc (info, abfd, input_section,
+                      contents, rel, relocation)
+     struct bfd_link_info *info;
+     bfd *abfd;
+     asection *input_section;
+     bfd_byte *contents;
+     const Elf_Internal_Rela *rel;
+     bfd_vma *relocation;
+{
+  bfd_vma disp, dropped;
+
+  switch (ELF32_R_TYPE (rel->r_info))
+    {
+    case R_SH_PT_16:
+      /* Check the lowest bit of the destination field.  If it is 1, we
+        check the ISA type of the destination (i.e. the low bit of the
+        "relocation" value, and emit an error if the instruction does not
+        match).  If it is 0, we change a PTA to PTB.  There should never
+        be a PTB that should change to a PTA; that indicates a toolchain
+        error; a mismatch with GAS.  */
+      {
+       char *msg = NULL;
+       bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
+
+       if (insn & (1 << 10))
+         {
+           /* Check matching insn and ISA (address of target).  */
+           if ((insn & SHMEDIA_PTB_BIT) != 0
+               && ((*relocation + rel->r_addend) & 1) != 0)
+             msg = _("PTB mismatch: a SHmedia address (bit 0 == 1)");
+           else if ((insn & SHMEDIA_PTB_BIT) == 0
+                    && ((*relocation + rel->r_addend) & 1) == 0)
+             msg = _("PTA mismatch: a SHcompact address (bit 0 == 0)");
+
+           if (msg != NULL
+               && ! ((*info->callbacks->reloc_dangerous)
+                     (info, msg, abfd, input_section,
+                      rel->r_offset)))
+             return false;
+         }
+       else
+         {
+           /* We shouldn't get here with a PTB insn and a R_SH_PT_16.  It
+              means GAS output does not match expectations; a PTA or PTB
+              expressed as such (or a PT found at assembly to be PTB)
+              would match the test above, and PT expansion with an
+              unknown destination (or when relaxing) will get us here.  */
+           if ((insn & SHMEDIA_PTB_BIT) != 0)
+             {
+               (*_bfd_error_handler)
+                 (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),
+                  bfd_get_filename (input_section->owner));
+               return false;
+             }
+
+           /* Change the PTA to a PTB, if destination indicates so.  */
+           if (((*relocation + rel->r_addend) & 1) == 0)
+             bfd_put_32 (abfd, insn | SHMEDIA_PTB_BIT,
+                         contents + rel->r_offset);
+         }
+      }
+
+    case R_SH_SHMEDIA_CODE:
+    case R_SH_DIR5U:
+    case R_SH_DIR6S:
+    case R_SH_DIR6U:
+    case R_SH_DIR10S:
+    case R_SH_DIR10SW:
+    case R_SH_DIR10SL:
+    case R_SH_DIR10SQ:
+    case R_SH_IMMS16:
+    case R_SH_IMMU16:
+    case R_SH_IMM_LOW16:
+    case R_SH_IMM_LOW16_PCREL:
+    case R_SH_IMM_MEDLOW16:
+    case R_SH_IMM_MEDLOW16_PCREL:
+    case R_SH_IMM_MEDHI16:
+    case R_SH_IMM_MEDHI16_PCREL:
+    case R_SH_IMM_HI16:
+    case R_SH_IMM_HI16_PCREL:
+    case R_SH_64:
+    case R_SH_64_PCREL:
+      break;
+
+    default:
+      return false;
+    }
+
+  disp = (*relocation & 0xf);
+  dropped = 0;
+  switch (ELF32_R_TYPE (rel->r_info))
+    {
+    case R_SH_DIR10SW: dropped = disp & 1; break;
+    case R_SH_DIR10SL: dropped = disp & 3; break;
+    case R_SH_DIR10SQ: dropped = disp & 7; break;
+    }
+  if (dropped != 0)
+    {
+      (*_bfd_error_handler)
+       (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),
+        bfd_get_filename (input_section->owner), ELF32_R_TYPE (rel->r_info),
+        (unsigned)rel->r_offset, (unsigned)relocation);
+      return false;
+    }
+
+  return true;
+}
+
+/* Helper function to locate the section holding a certain address.  This
+   is called via bfd_map_over_sections.  */
+
+static void
+sh64_find_section_for_address (abfd, section, data)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section;
+     PTR data;
+{
+  bfd_vma vma;
+  bfd_size_type size;
+  struct sh64_find_section_vma_data *fsec_datap
+    = (struct sh64_find_section_vma_data *) data;
+
+  /* Return if already found.  */
+  if (fsec_datap->section)
+    return;
+
+  /* If this section isn't part of the addressable contents, skip it.  */
+  if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
+    return;
+
+  vma = bfd_get_section_vma (abfd, section);
+  if (fsec_datap->addr < vma)
+    return;
+
+  /* FIXME: section->reloc_done isn't set properly; a generic buglet
+     preventing us from using bfd_get_section_size_after_reloc.  */
+  size
+    = section->_cooked_size ? section->_cooked_size : section->_raw_size;
+
+  if (fsec_datap->addr >= vma + size)
+    return;
+
+  fsec_datap->section = section;
+}
+
+/* Make sure to write out the generated entries in the .cranges section
+   when doing partial linking, and set bit 0 on the entry address if it
+   points to SHmedia code and write sorted .cranges entries when writing
+   executables (final linking and objcopy).  */
+
+static void
+sh64_elf_final_write_processing (abfd, linker)
+     bfd *   abfd;
+     boolean linker ATTRIBUTE_UNUSED;
+{
+  bfd_vma ld_generated_cranges_size;
+  asection *cranges
+    = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
+
+  /* If no new .cranges were added, the generic ELF linker parts will
+     write it all out.  If not, we need to write them out when doing
+     partial linking.  For a final link, we will sort them and write them
+     all out further below.  */
+  if (linker
+      && cranges != NULL
+      && elf_elfheader (abfd)->e_type != ET_EXEC
+      && (ld_generated_cranges_size
+         = sh64_elf_section_data (cranges)->cranges_growth) != 0)
+    {
+      bfd_vma incoming_cranges_size
+       = ((cranges->_cooked_size != 0
+           ? cranges->_cooked_size : cranges->_raw_size)
+          - ld_generated_cranges_size);
+
+      if (! bfd_set_section_contents (abfd, cranges,
+                                     cranges->contents
+                                     + incoming_cranges_size,
+                                     cranges->output_offset
+                                     + incoming_cranges_size,
+                                     ld_generated_cranges_size))
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         (*_bfd_error_handler)
+           (_("%s: could not write out added .cranges entries"),
+            bfd_get_filename (abfd));
+       }
+    }
+
+  /* Only set entry address bit 0 and sort .cranges when linking to an
+     executable; never with objcopy or strip.  */
+  if (linker && elf_elfheader (abfd)->e_type == ET_EXEC)
+    {
+      struct sh64_find_section_vma_data fsec_data;
+      sh64_elf_crange dummy;
+
+      /* For a final link, set the low bit of the entry address to
+        reflect whether or not it is a SHmedia address.
+        FIXME: Perhaps we shouldn't do this if the entry address was
+        supplied numerically, but we currently lack the infrastructure to
+        recognize that: The entry symbol, and info whether it is numeric
+        or a symbol name is kept private in the linker.  */
+      fsec_data.addr = elf_elfheader (abfd)->e_entry;
+      fsec_data.section = NULL;
+
+      bfd_map_over_sections (abfd, sh64_find_section_for_address,
+                            (PTR) &fsec_data);
+      if (fsec_data.section
+         && (sh64_get_contents_type (fsec_data.section,
+                                     elf_elfheader (abfd)->e_entry,
+                                     &dummy) == CRT_SH5_ISA32))
+       elf_elfheader (abfd)->e_entry |= 1;
+
+      /* If we have a .cranges section, sort the entries.  */
+      if (cranges != NULL)
+       {
+         bfd_size_type cranges_size
+           = (cranges->_cooked_size != 0
+              ? cranges->_cooked_size : cranges->_raw_size);
+
+         /* We know we always have these in memory at this time.  */
+         BFD_ASSERT (cranges->contents != NULL);
+
+         /* The .cranges may already have been sorted in the process of
+            finding out the ISA-type of the entry address.  If not, we do
+            it here.  */
+         if (elf_section_data (cranges)->this_hdr.sh_type
+             != SHT_SH5_CR_SORTED)
+           {
+             qsort (cranges->contents, cranges_size / SH64_CRANGE_SIZE,
+                    SH64_CRANGE_SIZE,
+                    bfd_big_endian (cranges->owner)
+                    ? crange_qsort_cmpb : crange_qsort_cmpl);
+             elf_section_data (cranges)->this_hdr.sh_type
+               = SHT_SH5_CR_SORTED;
+           }
+
+         /* We need to write it out in whole as sorted.  */
+         if (! bfd_set_section_contents (abfd, cranges,
+                                         cranges->contents,
+                                         cranges->output_offset,
+                                         cranges_size))
+           {
+             bfd_set_error (bfd_error_file_truncated);
+             (*_bfd_error_handler)
+               (_("%s: could not write out sorted .cranges entries"),
+                bfd_get_filename (abfd));
+           }
+       }
+    }
+}
+
+/* Ordering functions of a crange, for the qsort and bsearch calls and for
+   different endianness.  */
+
+static int
+crange_qsort_cmpb (p1, p2)
+     const PTR p1;
+     const PTR p2;
+{
+  bfd_vma a1 = bfd_getb32 (p1);
+  bfd_vma a2 = bfd_getb32 (p2);
+
+  /* Preserve order if there's ambiguous contents.  */
+  if (a1 == a2)
+    return (char *) p1 - (char *) p2;
+
+  return a1 - a2;
+}
+
+static int
+crange_qsort_cmpl (p1, p2)
+     const PTR p1;
+     const PTR p2;
+{
+  bfd_vma a1 = (bfd_vma) bfd_getl32 (p1);
+  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
+
+  /* Preserve order if there's ambiguous contents.  */
+  if (a1 == a2)
+    return (char *) p1 - (char *) p2;
+
+  return a1 - a2;
+}
+
+static int
+crange_bsearch_cmpb (p1, p2)
+     const PTR p1;
+     const PTR p2;
+{
+  bfd_vma a1 = *(bfd_vma *) p1;
+  bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
+  bfd_size_type size
+    = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
+
+  if (a1 >= a2 + size)
+    return 1;
+  if (a1 < a2)
+    return -1;
+  return 0;
+}
+
+static int
+crange_bsearch_cmpl (p1, p2)
+     const PTR p1;
+     const PTR p2;
+{
+  bfd_vma a1 = *(bfd_vma *) p1;
+  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
+  bfd_size_type size
+    = (bfd_size_type) bfd_getl32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
+
+  if (a1 >= a2 + size)
+    return 1;
+  if (a1 < a2)
+    return -1;
+  return 0;
+}
+
+/* Check whether a specific address is specified within a .cranges
+   section.  Return FALSE if not found, and TRUE if found, and the region
+   filled into RANGEP if non-NULL.  */
+
+static boolean
+sh64_address_in_cranges (cranges, addr, rangep)
+     asection *cranges;
+     bfd_vma addr;
+     sh64_elf_crange *rangep;
+{
+  bfd_byte *cranges_contents;
+  bfd_byte *found_rangep;
+  bfd_size_type cranges_size = bfd_section_size (cranges->owner, cranges);
+
+  /* If the size is not a multiple of the cranges entry size, then
+     something is badly wrong.  */
+  if ((cranges_size % SH64_CRANGE_SIZE) != 0)
+    return false;
+
+  /* If this section has relocations, then we can't do anything sane.  */
+  if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
+    return false;
+
+  /* Has some kind soul (or previous call) left processed, sorted contents
+     for us?  */
+  if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
+      && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
+    cranges_contents = cranges->contents;
+  else
+    {
+      cranges_contents
+       = bfd_malloc (cranges->_cooked_size == 0
+                     ? cranges->_cooked_size : cranges->_raw_size);
+      if (cranges_contents == NULL)
+       return false;
+
+      if (! bfd_get_section_contents (cranges->owner, cranges,
+                                     cranges_contents, (file_ptr) 0,
+                                     cranges_size))
+       goto error_return;
+
+      /* Is it sorted?  */
+      if (elf_section_data (cranges)->this_hdr.sh_type
+         != SHT_SH5_CR_SORTED)
+       /* Nope.  Lets sort it.  */
+       qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
+              SH64_CRANGE_SIZE,
+              bfd_big_endian (cranges->owner)
+              ? crange_qsort_cmpb : crange_qsort_cmpl);
+
+      /* Let's keep it around.  */
+      cranges->contents = cranges_contents;
+      bfd_set_section_flags (cranges->owner, cranges,
+                            bfd_get_section_flags (cranges->owner, cranges)
+                            | SEC_IN_MEMORY);
+
+      /* It's sorted now.  */
+      elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
+    }
+
+  /* Try and find a matching range.  */
+  found_rangep
+    = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE, 
+              SH64_CRANGE_SIZE,
+              bfd_big_endian (cranges->owner)
+              ? crange_bsearch_cmpb : crange_bsearch_cmpl);
+
+  /* Fill in a few return values if we found a matching range.  */
+  if (found_rangep)
+    {
+      enum sh64_elf_cr_type cr_type
+       = bfd_get_16 (cranges->owner,
+                     SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
+      bfd_vma cr_addr
+       = bfd_get_32 (cranges->owner,
+                     SH64_CRANGE_CR_ADDR_OFFSET
+                     + (char *) found_rangep);
+      bfd_size_type cr_size
+       = bfd_get_32 (cranges->owner,
+                     SH64_CRANGE_CR_SIZE_OFFSET
+                     + (char *) found_rangep);
+
+      rangep->cr_addr = cr_addr;
+      rangep->cr_size = cr_size;
+      rangep->cr_type = cr_type;
+
+      return true;
+    }
+
+  /* There is a .cranges section, but it does not have a descriptor
+     matching this address.  */
+  return false;
+
+error_return:
+  free (cranges_contents);
+  return false;
+}
+
+/* Determine what ADDR points to in SEC, and fill in a range descriptor in
+   *RANGEP if it's non-NULL.  */
+
+enum sh64_elf_cr_type
+sh64_get_contents_type (sec, addr, rangep)
+     asection *sec;
+     bfd_vma addr;
+     sh64_elf_crange *rangep;
+{
+  asection *cranges;
+
+  /* Fill in the range with the boundaries of the section as a default.  */
+  if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
+      && elf_elfheader (sec->owner)->e_type == ET_EXEC)
+    {
+      rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
+      rangep->cr_size = bfd_section_size (sec->owner, sec);
+      rangep->cr_type = CRT_NONE;
+    }
+  else
+    return false;
+
+  /* If none of the pertinent bits are set, then it's a SHcompact (or at
+     least not SHmedia).  */
+  if ((elf_section_data (sec)->this_hdr.sh_flags
+       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
+    {
+      enum sh64_elf_cr_type cr_type
+       = ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
+          ? CRT_SH5_ISA16 : CRT_DATA);
+      rangep->cr_type = cr_type;
+      return cr_type;
+    }
+
+  /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia.  */
+  if ((elf_section_data (sec)->this_hdr.sh_flags
+       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
+    {
+      rangep->cr_type = CRT_SH5_ISA32;
+      return CRT_SH5_ISA32;
+    }
+
+  /* Otherwise, we have to look up the .cranges section.  */
+  cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);
+
+  if (cranges == NULL)
+    /* A mixed section but there's no .cranges section.  This is probably
+       bad input; it does not comply to specs.  */
+    return CRT_NONE;
+
+  /* If this call fails, we will still have CRT_NONE in rangep->cr_type
+     and that will be suitable to return.  */
+  sh64_address_in_cranges (cranges, addr, rangep);
+
+  return rangep->cr_type;
+}
+
+/* This is a simpler exported interface for the benefit of gdb et al.  */
+
+boolean
+sh64_address_is_shmedia (sec, addr)
+     asection *sec;
+     bfd_vma addr;
+{
+  sh64_elf_crange dummy;
+  return sh64_get_contents_type (sec, addr, &dummy) == CRT_SH5_ISA32;
+}
diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
new file mode 100644 (file)
index 0000000..143a560
--- /dev/null
@@ -0,0 +1,4193 @@
+/* Hitachi SH64-specific support for 64-bit ELF
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   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 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.  */
+
+#define SH64_ELF64
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sh.h"
+
+/* Add a suffix for datalabel indirection symbols.  It must not match any
+   other symbols; user symbols with or without version or other
+   decoration.  It must only be used internally and not emitted by any
+   means.  */
+#define DATALABEL_SUFFIX " DL"
+
+#define GOT_BIAS (-((long)-32768))
+
+#define PLT_ENTRY_SIZE 64
+
+/* Return size of a PLT entry.  */
+#define elf_sh64_sizeof_plt(info) PLT_ENTRY_SIZE
+
+/* Return offset of the PLT0 address in an absolute PLT entry.  */
+#define elf_sh64_plt_plt0_offset(info) 32
+
+/* Return offset of the linker in PLT0 entry.  */
+#define elf_sh64_plt0_gotplt_offset(info) 0
+
+/* Return offset of the trampoline in PLT entry */
+#define elf_sh64_plt_temp_offset(info) 33 /* Add one because it's SHmedia.  */
+
+/* Return offset of the symbol in PLT entry.  */
+#define elf_sh64_plt_symbol_offset(info) 0
+
+/* Return offset of the relocation in PLT entry.  */
+#define elf_sh64_plt_reloc_offset(info) (info->shared ? 52 : 44)
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* The sh linker needs to keep track of the number of relocs that it
+   decides to copy in check_relocs for each symbol.  This is so that
+   it can discard PC relative relocs if it doesn't need them when
+   linking with -Bsymbolic.  We store the information in a field
+   extending the regular ELF linker hash table.  */
+
+/* This structure keeps track of the number of PC relative relocs we
+   have copied for a given symbol.  */
+
+struct elf_sh64_pcrel_relocs_copied
+{
+  /* Next section.  */
+  struct elf_sh64_pcrel_relocs_copied *next;
+  /* A section in dynobj.  */
+  asection *section;
+  /* Number of relocs copied in this section.  */
+  bfd_size_type count;
+};
+
+/* sh ELF linker hash entry.  */
+
+struct elf_sh64_link_hash_entry
+{
+  struct elf_link_hash_entry root;
+
+  bfd_vma datalabel_got_offset;
+
+  /* Number of PC relative relocs copied for this symbol.  */
+  struct elf_sh_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* sh ELF linker hash table.  */
+
+struct elf_sh64_link_hash_table
+{
+  struct elf_link_hash_table root;
+};
+
+/* Traverse an sh ELF linker hash table.  */
+
+#define sh64_elf64_link_hash_traverse(table, func, info)               \
+  (elf_link_hash_traverse                                              \
+   (&(table)->root,                                                    \
+    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+    (info)))
+
+/* Get the sh ELF linker hash table from a link_info structure.  */
+
+#define sh64_elf64_hash_table(p) \
+  ((struct elf_sh64_link_hash_table *) ((p)->hash))
+
+static boolean sh_elf64_copy_private_data PARAMS ((bfd *, bfd *));
+static boolean sh_elf64_copy_private_data_internal PARAMS ((bfd *, bfd *));
+static boolean sh_elf64_merge_private_data PARAMS ((bfd *, bfd *));
+static bfd_reloc_status_type sh_elf64_ignore_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sh_elf64_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *sh_elf64_reloc_type_lookup
+  PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void sh_elf64_info_to_howto
+  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static boolean sh_elf64_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static bfd_byte *sh_elf64_get_relocated_section_contents
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+          bfd_byte *, boolean, asymbol **));
+static boolean sh_elf64_set_mach_from_flags PARAMS ((bfd *));
+static boolean sh_elf64_set_private_flags PARAMS ((bfd *, flagword));
+static asection *sh_elf64_gc_mark_hook
+  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+          struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean sh_elf64_gc_sweep_hook
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          const Elf_Internal_Rela *));
+static boolean sh_elf64_check_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          const Elf_Internal_Rela *));
+static int sh64_elf64_get_symbol_type PARAMS ((Elf_Internal_Sym *, int));
+static boolean sh64_elf64_add_symbol_hook
+  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+          const char **, flagword *, asection **, bfd_vma *));
+extern boolean sh64_elf64_link_output_symbol_hook
+  PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+          asection *));
+static boolean sh64_elf64_fake_sections
+  PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
+static void sh64_elf64_final_write_processing PARAMS ((bfd *, boolean));
+
+static reloc_howto_type sh_elf64_howto_table[] = {
+  /* No relocation.  */
+  HOWTO (R_SH_NONE,            /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_NONE",           /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 32 bit absolute relocation.  Setting partial_inplace to true and
+     src_mask to a non-zero value is similar to the COFF toolchain.  */
+  HOWTO (R_SH_DIR32,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        sh_elf64_reloc,                /* special_function */
+        "R_SH_DIR32",          /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 32 bit PC relative relocation.  */
+  HOWTO (R_SH_REL32,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_REL32",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* For 32-bit sh, this is R_SH_DIR8WPN.  */
+  EMPTY_HOWTO (3),
+
+  /* For 32-bit sh, this is R_SH_IND12W.  */
+  EMPTY_HOWTO (4),
+
+  /* For 32-bit sh, this is R_SH_DIR8WPL.  */
+  EMPTY_HOWTO (5),
+
+  /* For 32-bit sh, this is R_SH_DIR8WPZ.  */
+  EMPTY_HOWTO (6),
+
+  /* For 32-bit sh, this is R_SH_DIR8BP.  */
+  EMPTY_HOWTO (7),
+
+  /* For 32-bit sh, this is R_SH_DIR8W.  */
+  EMPTY_HOWTO (8),
+
+  /* For 32-bit sh, this is R_SH_DIR8L.  */
+  EMPTY_HOWTO (9),
+
+  EMPTY_HOWTO (10),
+  EMPTY_HOWTO (11),
+  EMPTY_HOWTO (12),
+  EMPTY_HOWTO (13),
+  EMPTY_HOWTO (14),
+  EMPTY_HOWTO (15),
+  EMPTY_HOWTO (16),
+  EMPTY_HOWTO (17),
+  EMPTY_HOWTO (18),
+  EMPTY_HOWTO (19),
+  EMPTY_HOWTO (20),
+  EMPTY_HOWTO (21),
+  EMPTY_HOWTO (22),
+  EMPTY_HOWTO (23),
+  EMPTY_HOWTO (24),
+
+  /* The remaining relocs are a GNU extension used for relaxing.  The
+     final pass of the linker never needs to do anything with any of
+     these relocs.  Any required operations are handled by the
+     relaxation code.  */
+
+  /* A 16 bit switch table entry.  This is generated for an expression
+     such as ``.word L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_SH_SWITCH16,                /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_SWITCH16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* A 32 bit switch table entry.  This is generated for an expression
+     such as ``.long L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_SH_SWITCH32,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_SWITCH32",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* For 32-bit sh, this is R_SH_USES.  */
+  EMPTY_HOWTO (27),
+
+  /* For 32-bit sh, this is R_SH_COUNT.  */
+  EMPTY_HOWTO (28),
+
+  /* For 32-bit sh, this is R_SH_ALIGN.  FIXME: For linker relaxation,
+     this might be emitted.  When linker relaxation is implemented, we
+     might want to use it.  */
+  EMPTY_HOWTO (29),
+
+  /* For 32-bit sh, this is R_SH_CODE.  FIXME: For linker relaxation,
+     this might be emitted.  When linker relaxation is implemented, we
+     might want to use it.  */
+  EMPTY_HOWTO (30),
+
+  /* For 32-bit sh, this is R_SH_DATA.  FIXME: For linker relaxation,
+     this might be emitted.  When linker relaxation is implemented, we
+     might want to use it.  */
+  EMPTY_HOWTO (31),
+
+  /* For 32-bit sh, this is R_SH_LABEL.  FIXME: For linker relaxation,
+     this might be emitted.  When linker relaxation is implemented, we
+     might want to use it.  */
+  EMPTY_HOWTO (32),
+
+  /* An 8 bit switch table entry.  This is generated for an expression
+     such as ``.word L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_SH_SWITCH8,         /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_SWITCH8",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* GNU extension to record C++ vtable hierarchy */
+  HOWTO (R_SH_GNU_VTINHERIT, /* type */
+         0,                     /* rightshift */
+         2,                     /* size (0 = byte, 1 = short, 2 = long) */
+         0,                     /* bitsize */
+         false,                 /* pc_relative */
+         0,                     /* bitpos */
+         complain_overflow_dont, /* complain_on_overflow */
+         NULL,                  /* special_function */
+         "R_SH_GNU_VTINHERIT", /* name */
+         false,                 /* partial_inplace */
+         0,                     /* src_mask */
+         0,                     /* dst_mask */
+         false),                /* pcrel_offset */
+
+  /* GNU extension to record C++ vtable member usage */
+  HOWTO (R_SH_GNU_VTENTRY,     /* type */
+         0,                     /* rightshift */
+         2,                     /* size (0 = byte, 1 = short, 2 = long) */
+         0,                     /* bitsize */
+         false,                 /* pc_relative */
+         0,                     /* bitpos */
+         complain_overflow_dont, /* complain_on_overflow */
+         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
+         "R_SH_GNU_VTENTRY",   /* name */
+         false,                 /* partial_inplace */
+         0,                     /* src_mask */
+         0,                     /* dst_mask */
+         false),                /* pcrel_offset */
+
+  /* For 32-bit sh, this is R_SH_LOOP_START.  */
+  EMPTY_HOWTO (36),
+
+  /* For 32-bit sh, this is R_SH_LOOP_END.  */
+  EMPTY_HOWTO (37),
+
+  EMPTY_HOWTO (38),
+  EMPTY_HOWTO (39),
+  EMPTY_HOWTO (40),
+  EMPTY_HOWTO (41),
+  EMPTY_HOWTO (42),
+  EMPTY_HOWTO (43),
+  EMPTY_HOWTO (44),
+
+  /* Used in SHLLI.L and SHLRI.L.  */
+  HOWTO (R_SH_DIR5U,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        5,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR5U",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in SHARI, SHLLI et al.  */
+  HOWTO (R_SH_DIR6U,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        6,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR6U",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in BxxI, LDHI.L et al.  */
+  HOWTO (R_SH_DIR6S,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        6,                     /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR6S",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xfc00,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in ADDI, ANDI et al.  */
+  HOWTO (R_SH_DIR10S,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        10,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10S",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.UW, ST.W et al.  */
+  HOWTO (R_SH_DIR10SW, /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        11,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SW",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_DIR10SL, /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SL",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_DIR10SQ, /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_DIR10SQ",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  EMPTY_HOWTO (52),
+  EMPTY_HOWTO (53),
+  EMPTY_HOWTO (54),
+  EMPTY_HOWTO (55),
+  EMPTY_HOWTO (56),
+  EMPTY_HOWTO (57),
+  EMPTY_HOWTO (58),
+  EMPTY_HOWTO (59),
+  EMPTY_HOWTO (60),
+  EMPTY_HOWTO (61),
+  EMPTY_HOWTO (62),
+  EMPTY_HOWTO (63),
+  EMPTY_HOWTO (64),
+  EMPTY_HOWTO (65),
+  EMPTY_HOWTO (66),
+  EMPTY_HOWTO (67),
+  EMPTY_HOWTO (68),
+  EMPTY_HOWTO (69),
+  EMPTY_HOWTO (70),
+  EMPTY_HOWTO (71),
+  EMPTY_HOWTO (72),
+  EMPTY_HOWTO (73),
+  EMPTY_HOWTO (74),
+  EMPTY_HOWTO (75),
+  EMPTY_HOWTO (76),
+  EMPTY_HOWTO (77),
+  EMPTY_HOWTO (78),
+  EMPTY_HOWTO (79),
+  EMPTY_HOWTO (80),
+  EMPTY_HOWTO (81),
+  EMPTY_HOWTO (82),
+  EMPTY_HOWTO (83),
+  EMPTY_HOWTO (84),
+  EMPTY_HOWTO (85),
+  EMPTY_HOWTO (86),
+  EMPTY_HOWTO (87),
+  EMPTY_HOWTO (88),
+  EMPTY_HOWTO (89),
+  EMPTY_HOWTO (90),
+  EMPTY_HOWTO (91),
+  EMPTY_HOWTO (92),
+  EMPTY_HOWTO (93),
+  EMPTY_HOWTO (94),
+  EMPTY_HOWTO (95),
+  EMPTY_HOWTO (96),
+  EMPTY_HOWTO (97),
+  EMPTY_HOWTO (98),
+  EMPTY_HOWTO (99),
+  EMPTY_HOWTO (100),
+  EMPTY_HOWTO (101),
+  EMPTY_HOWTO (102),
+  EMPTY_HOWTO (103),
+  EMPTY_HOWTO (104),
+  EMPTY_HOWTO (105),
+  EMPTY_HOWTO (106),
+  EMPTY_HOWTO (107),
+  EMPTY_HOWTO (108),
+  EMPTY_HOWTO (109),
+  EMPTY_HOWTO (110),
+  EMPTY_HOWTO (111),
+  EMPTY_HOWTO (112),
+  EMPTY_HOWTO (113),
+  EMPTY_HOWTO (114),
+  EMPTY_HOWTO (115),
+  EMPTY_HOWTO (116),
+  EMPTY_HOWTO (117),
+  EMPTY_HOWTO (118),
+  EMPTY_HOWTO (119),
+  EMPTY_HOWTO (120),
+  EMPTY_HOWTO (121),
+  EMPTY_HOWTO (122),
+  EMPTY_HOWTO (123),
+  EMPTY_HOWTO (124),
+  EMPTY_HOWTO (125),
+  EMPTY_HOWTO (126),
+  EMPTY_HOWTO (127),
+  EMPTY_HOWTO (128),
+  EMPTY_HOWTO (129),
+  EMPTY_HOWTO (130),
+  EMPTY_HOWTO (131),
+  EMPTY_HOWTO (132),
+  EMPTY_HOWTO (133),
+  EMPTY_HOWTO (134),
+  EMPTY_HOWTO (135),
+  EMPTY_HOWTO (136),
+  EMPTY_HOWTO (137),
+  EMPTY_HOWTO (138),
+  EMPTY_HOWTO (139),
+  EMPTY_HOWTO (140),
+  EMPTY_HOWTO (141),
+  EMPTY_HOWTO (142),
+  EMPTY_HOWTO (143),
+  EMPTY_HOWTO (144),
+  EMPTY_HOWTO (145),
+  EMPTY_HOWTO (146),
+  EMPTY_HOWTO (147),
+  EMPTY_HOWTO (148),
+  EMPTY_HOWTO (149),
+  EMPTY_HOWTO (150),
+  EMPTY_HOWTO (151),
+  EMPTY_HOWTO (152),
+  EMPTY_HOWTO (153),
+  EMPTY_HOWTO (154),
+  EMPTY_HOWTO (155),
+  EMPTY_HOWTO (156),
+  EMPTY_HOWTO (157),
+  EMPTY_HOWTO (158),
+  EMPTY_HOWTO (159),
+
+  /* Relocs for dynamic linking for 32-bit SH would follow.  We don't have
+     any dynamic linking support for 64-bit SH at present.  */
+
+  EMPTY_HOWTO (160),
+  EMPTY_HOWTO (161),
+  EMPTY_HOWTO (162),
+  EMPTY_HOWTO (163),
+  EMPTY_HOWTO (164),
+  EMPTY_HOWTO (165),
+  EMPTY_HOWTO (166),
+  EMPTY_HOWTO (167),
+  EMPTY_HOWTO (168),
+
+  /* Back to SH5 relocations.  */
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOT_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOT_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOT_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOT_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTPLT_LOW16,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_LOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTPLT_MEDHI16,  /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_MEDHI16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTPLT_HI16,     /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT_HI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_PLT_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_PLT_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_PLT_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_PLT_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PLT_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTOFF_LOW16,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_LOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTOFF_MEDHI16,  /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_MEDHI16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTOFF_HI16,     /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTOFF_HI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_GOTPC_LOW16,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_LOW16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_GOTPC_MEDLOW16,  /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_MEDLOW16", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_GOTPC_MEDHI16,   /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_MEDHI16",  /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_GOTPC_HI16,      /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPC_HI16",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_GOT10BY4,                /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT10BY4",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in LD.L, FLD.S et al.  */
+  HOWTO (R_SH_GOTPLT10BY4,     /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT10BY4",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_GOT10BY8,                /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOT10BY8",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in FLD.D, FST.P et al.  */
+  HOWTO (R_SH_GOTPLT10BY8,     /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        13,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GOTPLT10BY8",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffc00,               /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_COPY64,          /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_COPY64",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_GLOB_DAT64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_GLOB_DAT64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_JMP_SLOT64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_JMP_SLOT64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO (R_SH_RELATIVE64,      /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_RELATIVE64",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  EMPTY_HOWTO (197),
+  EMPTY_HOWTO (198),
+  EMPTY_HOWTO (199),
+  EMPTY_HOWTO (200),
+  EMPTY_HOWTO (201),
+  EMPTY_HOWTO (202),
+  EMPTY_HOWTO (203),
+  EMPTY_HOWTO (204),
+  EMPTY_HOWTO (205),
+  EMPTY_HOWTO (206),
+  EMPTY_HOWTO (207),
+  EMPTY_HOWTO (208),
+  EMPTY_HOWTO (209),
+  EMPTY_HOWTO (210),
+  EMPTY_HOWTO (211),
+  EMPTY_HOWTO (212),
+  EMPTY_HOWTO (213),
+  EMPTY_HOWTO (214),
+  EMPTY_HOWTO (215),
+  EMPTY_HOWTO (216),
+  EMPTY_HOWTO (217),
+  EMPTY_HOWTO (218),
+  EMPTY_HOWTO (219),
+  EMPTY_HOWTO (220),
+  EMPTY_HOWTO (221),
+  EMPTY_HOWTO (222),
+  EMPTY_HOWTO (223),
+  EMPTY_HOWTO (224),
+  EMPTY_HOWTO (225),
+  EMPTY_HOWTO (226),
+  EMPTY_HOWTO (227),
+  EMPTY_HOWTO (228),
+  EMPTY_HOWTO (229),
+  EMPTY_HOWTO (230),
+  EMPTY_HOWTO (231),
+  EMPTY_HOWTO (232),
+  EMPTY_HOWTO (233),
+  EMPTY_HOWTO (234),
+  EMPTY_HOWTO (235),
+  EMPTY_HOWTO (236),
+  EMPTY_HOWTO (237),
+  EMPTY_HOWTO (238),
+  EMPTY_HOWTO (239),
+  EMPTY_HOWTO (240),
+  EMPTY_HOWTO (241),
+
+  /* Relocations for SHmedia code.  None of these are partial_inplace or
+     use the field being relocated.  */
+
+  /* The assembler will generate this reloc before a block of SHmedia
+     instructions.  A section should be processed as assuming it contains
+     data, unless this reloc is seen.  Note that a block of SHcompact
+     instructions are instead preceded by R_SH_CODE.
+     This is currently not implemented, but should be used for SHmedia
+     linker relaxation.  */
+  HOWTO (R_SH_SHMEDIA_CODE,    /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        sh_elf64_ignore_reloc, /* special_function */
+        "R_SH_SHMEDIA_CODE",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* The assembler will generate this reloc at a PTA or PTB instruction,
+     and the linker checks the right type of target, or changes a PTA to a
+     PTB, if the original insn was PT.  */
+  HOWTO (R_SH_PT_16,           /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        18,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_PT_16",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in unexpanded MOVI.  */
+  HOWTO (R_SH_IMMS16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMMS16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in SHORI.  */
+  HOWTO (R_SH_IMMU16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMMU16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (x & 65536).  */
+  HOWTO (R_SH_IMM_LOW16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_LOW16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x - $) & 65536).  */
+  HOWTO (R_SH_IMM_LOW16_PCREL, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_LOW16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
+  HOWTO (R_SH_IMM_MEDLOW16,    /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDLOW16",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 16) & 65536).  */
+  HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDLOW16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
+  HOWTO (R_SH_IMM_MEDHI16,     /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDHI16",    /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 32) & 65536).  */
+  HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */
+        32,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_MEDHI16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
+  HOWTO (R_SH_IMM_HI16,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_HI16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used in MOVI and SHORI (((x - $) >> 48) & 65536).  */
+  HOWTO (R_SH_IMM_HI16_PCREL,  /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_IMM_HI16_PCREL", /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x3fffc00,             /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* For the .uaquad pseudo.  */
+  HOWTO (R_SH_64,              /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_64",             /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* For the .uaquad pseudo, (x - $).  */
+  HOWTO (R_SH_64_PCREL,                /* type */
+        48,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        true,                  /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_SH_64_PCREL",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ((bfd_vma) 0) - 1,     /* dst_mask */
+        true),                 /* pcrel_offset */
+
+};
+
+/* This function is used for relocs which are only used for relaxing,
+   which the linker should otherwise ignore.  */
+
+static bfd_reloc_status_type
+sh_elf64_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
+                    output_bfd, error_message)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     arelent *reloc_entry;
+     asymbol *symbol ATTRIBUTE_UNUSED;
+     PTR data ATTRIBUTE_UNUSED;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message ATTRIBUTE_UNUSED;
+{
+  if (output_bfd != NULL)
+    reloc_entry->address += input_section->output_offset;
+  return bfd_reloc_ok;
+}
+
+/* This function is used for normal relocs.  This used to be like the COFF
+   function, and is almost certainly incorrect for other ELF targets.
+
+   See sh_elf_reloc in elf32-sh.c for the original.  */
+
+static bfd_reloc_status_type
+sh_elf64_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+         error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol_in;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message ATTRIBUTE_UNUSED;
+{
+  unsigned long insn;
+  bfd_vma sym_value;
+  enum elf_sh_reloc_type r_type;
+  bfd_vma addr = reloc_entry->address;
+  bfd_byte *hit_data = addr + (bfd_byte *) data;
+
+  r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type;
+
+  if (output_bfd != NULL)
+    {
+      /* Partial linking--do nothing.  */
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  if (symbol_in != NULL
+      && bfd_is_und_section (symbol_in->section))
+    return bfd_reloc_undefined;
+
+  if (bfd_is_com_section (symbol_in->section))
+    sym_value = 0;                           
+  else 
+    sym_value = (symbol_in->value +
+                symbol_in->section->output_section->vma +
+                symbol_in->section->output_offset);
+
+  switch (r_type)
+    {
+    case R_SH_DIR32:
+      insn = bfd_get_32 (abfd, hit_data);
+      insn += sym_value + reloc_entry->addend;
+      bfd_put_32 (abfd, insn, hit_data);
+      break;
+
+    default:
+      abort ();
+      break;
+    }
+
+  return bfd_reloc_ok;
+}
+
+/* This structure is used to map BFD reloc codes to SH ELF relocs.  */
+
+struct elf_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned char elf_reloc_val;
+};
+
+/* An array mapping BFD reloc codes to SH ELF relocs.  */
+
+static const struct elf_reloc_map sh64_reloc_map[] =
+{
+  { BFD_RELOC_NONE, R_SH_NONE },
+  { BFD_RELOC_32, R_SH_DIR32 },
+  { BFD_RELOC_CTOR, R_SH_DIR32 },
+  { BFD_RELOC_32_PCREL, R_SH_REL32 },
+  { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
+  { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
+  { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
+  { BFD_RELOC_VTABLE_INHERIT, R_SH_GNU_VTINHERIT },
+  { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
+  { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
+  { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
+  { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
+  { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
+  { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
+  { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
+  { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
+  { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
+  { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
+  { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
+  { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
+  { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
+  { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
+  { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
+  { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
+  { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
+  { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
+  { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
+  { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
+  { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
+  { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
+  { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
+  { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
+  { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
+  { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
+  { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
+  { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
+  { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
+  { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
+  { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
+  { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
+  { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
+  { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
+  { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
+  { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
+  { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
+  { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
+  { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
+  { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
+  { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
+  { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
+  { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
+  { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
+  { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
+  { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
+  { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
+  { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
+  { BFD_RELOC_64, R_SH_64 },
+  { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
+};
+
+/* Given a BFD reloc code, return the howto structure for the
+   corresponding SH ELf reloc.  */
+
+static reloc_howto_type *
+sh_elf64_reloc_type_lookup (abfd, code)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     bfd_reloc_code_real_type code;
+{
+  unsigned int i;
+
+  for (i = 0; i < sizeof (sh64_reloc_map) / sizeof (struct elf_reloc_map); i++)
+    {
+      if (sh64_reloc_map[i].bfd_reloc_val == code)
+       return &sh_elf64_howto_table[(int) sh64_reloc_map[i].elf_reloc_val];
+    }
+
+  return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent.
+
+   See sh_elf_info_to_howto in elf32-sh.c for the original.  */
+
+static void
+sh_elf64_info_to_howto (abfd, cache_ptr, dst)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     arelent *cache_ptr;
+     Elf_Internal_Rela *dst;
+{
+  unsigned int r;
+
+  r = ELF64_R_TYPE (dst->r_info);
+
+  BFD_ASSERT (r <= (unsigned int) R_SH_64_PCREL);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
+  BFD_ASSERT (r < R_SH_DIR8WPN || r > R_SH_LAST_INVALID_RELOC_2);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_GOTPLT32);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+
+  cache_ptr->howto = &sh_elf64_howto_table[r];
+}
+
+/* Relocate an SH ELF section.
+
+   See sh_elf_info_to_howto in elf32-sh.c for the original.  */
+
+static boolean
+sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
+                          contents, relocs, local_syms, local_sections)
+     bfd *output_bfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     Elf_Internal_Rela *relocs;
+     Elf_Internal_Sym *local_syms;
+     asection **local_sections;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  Elf_Internal_Rela *rel, *relend;
+  bfd *dynobj;
+  bfd_vma *local_got_offsets;
+  asection *sgot;
+  asection *sgotplt;
+  asection *splt;
+  asection *sreloc;
+  bfd_vma disp, dropped;
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  dynobj = elf_hash_table (info)->dynobj;
+  local_got_offsets = elf_local_got_offsets (input_bfd);
+
+  sgot = NULL;
+  sgotplt = NULL;
+  splt = NULL;
+  sreloc = NULL;
+
+  rel = relocs;
+  relend = relocs + input_section->reloc_count;
+  for (; rel < relend; rel++)
+    {
+      int r_type;
+      reloc_howto_type *howto;
+      unsigned long r_symndx;
+      Elf_Internal_Sym *sym;
+      asection *sec;
+      struct elf_link_hash_entry *h;
+      bfd_vma relocation;
+      bfd_vma addend = (bfd_vma)0;
+      bfd_reloc_status_type r;
+      int seen_stt_datalabel = 0;
+
+      r_symndx = ELF64_R_SYM (rel->r_info);
+
+      r_type = ELF64_R_TYPE (rel->r_info);
+
+      if (r_type == (int) R_SH_NONE)
+       continue;
+
+      if (r_type < 0
+         || r_type > R_SH_64_PCREL
+         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+         || (r_type >= (int) R_SH_DIR8WPN
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC_2)
+         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
+             && r_type <= R_SH_GOTPLT32)
+         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC_4))
+       {
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+       }
+
+      howto = sh_elf64_howto_table + r_type;
+
+      /* This is a final link.  */
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      if (r_symndx < symtab_hdr->sh_info)
+       {
+         sym = local_syms + r_symndx;
+         sec = local_sections[r_symndx];
+         relocation = ((sec->output_section->vma
+                        + sec->output_offset
+                        + sym->st_value)
+                       | ((sym->st_other & STO_SH5_ISA32) != 0));
+
+         /* A local symbol never has STO_SH5_ISA32, so we don't need
+            datalabel processing here.  Make sure this does not change
+            without notice.  */
+         if ((sym->st_other & STO_SH5_ISA32) != 0)
+           ((*info->callbacks->reloc_dangerous)
+            (info,
+             _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+             input_bfd, input_section, rel->r_offset));
+
+         if (info->relocateable)
+           {
+             /* This is a relocateable link.  We don't have to change
+                anything, unless the reloc is against a section symbol,
+                in which case we have to adjust according to where the
+                section symbol winds up in the output section.  */
+             sym = local_syms + r_symndx;
+             if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+               goto final_link_relocate;
+
+             continue;
+           }
+       }
+      else
+       {
+         /* Section symbols are never (?) placed in the hash table, so
+            we can just ignore hash relocations when creating a
+            relocateable object file.  */
+         if (info->relocateable)
+           continue;
+
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           {
+             /* If the reference passes a symbol marked with
+                STT_DATALABEL, then any STO_SH5_ISA32 on the final value
+                doesn't count.  */
+             seen_stt_datalabel |= h->type == STT_DATALABEL;
+             h = (struct elf_link_hash_entry *) h->root.u.i.link;
+           }
+
+         if (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+           {
+             sec = h->root.u.def.section;
+             /* In these cases, we don't need the relocation value.
+                We check specially because in some obscure cases
+                sec->output_section will be NULL. */
+             if (r_type == R_SH_GOTPC_LOW16
+                 || r_type == R_SH_GOTPC_MEDLOW16
+                 || r_type == R_SH_GOTPC_MEDHI16
+                 || r_type == R_SH_GOTPC_HI16
+                 || ((r_type == R_SH_PLT_LOW16
+                      || r_type == R_SH_PLT_MEDLOW16
+                      || r_type == R_SH_PLT_MEDHI16
+                      || r_type == R_SH_PLT_HI16)
+                     && h->plt.offset != (bfd_vma) -1)
+                 || ((r_type == R_SH_GOT_LOW16
+                      || r_type == R_SH_GOT_MEDLOW16
+                      || r_type == R_SH_GOT_MEDHI16
+                      || r_type == R_SH_GOT_HI16)
+                     && elf_hash_table (info)->dynamic_sections_created
+                     && (! info->shared
+                         || (! info->symbolic && h->dynindx != -1)
+                         || (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) == 0))
+                 /* The cases above are those in which relocation is
+                    overwritten in the switch block below.  The cases
+                    below are those in which we must defer relocation
+                    to run-time, because we can't resolve absolute
+                    addresses when creating a shared library.  */
+                 || (info->shared
+                     && ((! info->symbolic && h->dynindx != -1)
+                         || (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) == 0)
+                     && ((r_type == R_SH_64
+                          && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+                               || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN))
+                         || r_type == R_SH_64_PCREL)
+                     && ((input_section->flags & SEC_ALLOC) != 0
+                         /* DWARF will emit R_SH_DIR32 relocations in its
+                            sections against symbols defined externally
+                            in shared libraries.  We can't do anything
+                            with them here.  */
+                         || (input_section->flags & SEC_DEBUGGING) != 0)))
+               relocation = 0;
+             else if (sec->output_section == NULL)
+               {
+                 (*_bfd_error_handler)
+                   (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+                    bfd_get_filename (input_bfd), h->root.root.string,
+                    bfd_get_section_name (input_bfd, input_section));
+                 relocation = 0;
+               }
+             else
+               relocation = ((h->root.u.def.value
+                              + sec->output_section->vma
+                              + sec->output_offset)
+                             /* A STO_SH5_ISA32 causes a "bitor 1" to the
+                                symbol value, unless we've seen
+                                STT_DATALABEL on the way to it.  */
+                             | ((h->other & STO_SH5_ISA32) != 0
+                                && ! seen_stt_datalabel));
+           }
+         else if (h->root.type == bfd_link_hash_undefweak)
+           relocation = 0;
+         else if (info->shared && !info->symbolic && !info->no_undefined)
+           relocation = 0;
+         else
+           {
+             if (! ((*info->callbacks->undefined_symbol)
+                    (info, h->root.root.string, input_bfd,
+                     input_section, rel->r_offset, true)))
+               return false;
+             relocation = 0;
+           }
+       }
+
+      disp = (relocation
+             - input_section->output_section->vma
+             - input_section->output_offset
+             - rel->r_offset);
+      dropped = 0;
+      switch ((int)r_type)
+       {
+       case R_SH_PT_16:     dropped = disp & 2; break;
+       case R_SH_DIR10SW: dropped = disp & 1; break;
+       case R_SH_DIR10SL: dropped = disp & 3; break;
+       case R_SH_DIR10SQ: dropped = disp & 7; break;
+       }
+      if (dropped != 0)
+       {
+         (*_bfd_error_handler)
+           (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),
+            bfd_get_filename (input_bfd), (int)r_type, (unsigned)rel->r_offset, (unsigned)relocation);
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+       }
+      switch ((int)r_type)
+       {
+       case R_SH_64:
+       case R_SH_64_PCREL:
+         if (info->shared
+             && (input_section->flags & SEC_ALLOC) != 0
+             && (r_type != R_SH_64_PCREL
+                 || (h != NULL
+                     && h->dynindx != -1
+                     && (! info->symbolic
+                         || (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+           {
+             Elf_Internal_Rela outrel;
+             boolean skip, relocate;
+
+             /* When generating a shared object, these relocations
+                are copied into the output file to be resolved at run
+                time.  */
+
+             if (sreloc == NULL)
+               {
+                 const char *name;
+
+                 name = (bfd_elf_string_from_elf_section
+                         (input_bfd,
+                          elf_elfheader (input_bfd)->e_shstrndx,
+                          elf_section_data (input_section)->rel_hdr.sh_name));
+                 if (name == NULL)
+                   return false;
+
+                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+                             && strcmp (bfd_get_section_name (input_bfd,
+                                                              input_section),
+                                        name + 5) == 0);
+
+                 sreloc = bfd_get_section_by_name (dynobj, name);
+                 BFD_ASSERT (sreloc != NULL);
+               }
+
+             skip = false;
+
+             outrel.r_offset
+               = _bfd_elf_section_offset (output_bfd,
+                                          &elf_hash_table (info)->stab_info,
+                                          input_section,
+                                          rel->r_offset);
+
+             if (outrel.r_offset == (bfd_vma) -1)
+               skip = true;
+             
+             outrel.r_offset += (input_section->output_section->vma
+                                 + input_section->output_offset);
+
+             if (skip)
+               {
+                 memset (&outrel, 0, sizeof outrel);
+                 relocate = false;
+               }
+             else if (r_type == R_SH_64_PCREL)
+               {
+                 BFD_ASSERT (h != NULL && h->dynindx != -1);
+                 relocate = false;
+                 outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL);
+                 outrel.r_addend = rel->r_addend;
+               }
+             else
+               {
+                 /* h->dynindx may be -1 if this symbol was marked to
+                    become local.  */
+                 if (h == NULL
+                     || ((info->symbolic || h->dynindx == -1)
+                         && (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) != 0))
+                   {
+                     relocate = true;
+                     outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+                     outrel.r_addend = relocation + rel->r_addend;
+                   }
+                 else
+                   {
+                     BFD_ASSERT (h->dynindx != -1);
+                     relocate = false;
+                     outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64);
+                     outrel.r_addend = relocation + rel->r_addend;
+                   }
+               }
+
+             bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+                                        (((Elf64_External_Rela *)
+                                          sreloc->contents)
+                                         + sreloc->reloc_count));
+             ++sreloc->reloc_count;
+
+             /* If this reloc is against an external symbol, we do
+                not want to fiddle with the addend.  Otherwise, we
+                need to include the symbol value so that it becomes
+                an addend for the dynamic reloc.  */
+             if (! relocate)
+               continue;
+           }
+         else if (r_type == R_SH_64)
+           addend = rel->r_addend;
+         goto final_link_relocate;
+
+       case R_SH_GOTPLT_LOW16:
+       case R_SH_GOTPLT_MEDLOW16:
+       case R_SH_GOTPLT_MEDHI16:
+       case R_SH_GOTPLT_HI16:
+       case R_SH_GOTPLT10BY4:
+       case R_SH_GOTPLT10BY8:
+         /* Relocation is to the entry for this symbol in the
+            procedure linkage table.  */
+
+         if (h == NULL
+             || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+             || ! info->shared
+             || info->symbolic
+             || h->dynindx == -1
+             || h->plt.offset == (bfd_vma) -1
+             || h->got.offset != (bfd_vma) -1)
+           goto force_got;
+
+         /* Relocation is to the entry for this symbol in the global
+            offset table extension for the procedure linkage table.  */
+         if (sgotplt == NULL)
+           {
+             sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+             BFD_ASSERT (sgotplt != NULL);
+           }
+
+         relocation = (sgotplt->output_offset
+                       + ((h->plt.offset / elf_sh64_sizeof_plt (info)
+                           - 1 + 3) * 8));
+
+         relocation -= GOT_BIAS;
+
+         goto final_link_relocate;
+
+       force_got:
+       case R_SH_GOT_LOW16:
+       case R_SH_GOT_MEDLOW16:
+       case R_SH_GOT_MEDHI16:
+       case R_SH_GOT_HI16:
+       case R_SH_GOT10BY4:
+       case R_SH_GOT10BY8:
+         /* Relocation is to the entry for this symbol in the global
+            offset table.  */
+         if (sgot == NULL)
+           {
+             sgot = bfd_get_section_by_name (dynobj, ".got");
+             BFD_ASSERT (sgot != NULL);
+           }
+
+         if (h != NULL)
+           {
+             bfd_vma off;
+
+             off = h->got.offset;
+             if (seen_stt_datalabel)
+               {
+                 struct elf_sh64_link_hash_entry *hsh;
+
+                 hsh = (struct elf_sh64_link_hash_entry *)h;
+                 off = hsh->datalabel_got_offset;
+               }
+             BFD_ASSERT (off != (bfd_vma) -1);
+
+             if (! elf_hash_table (info)->dynamic_sections_created
+                 || (info->shared
+                     && (info->symbolic || h->dynindx == -1
+                         || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+                         || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+                     && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+               {
+                 /* This is actually a static link, or it is a
+                    -Bsymbolic link and the symbol is defined
+                    locally, or the symbol was forced to be local
+                    because of a version file.  We must initialize
+                    this entry in the global offset table.  Since the
+                    offset must always be a multiple of 4, we use the
+                    least significant bit to record whether we have
+                    initialized it already.
+
+                    When doing a dynamic link, we create a .rela.got
+                    relocation entry to initialize the value.  This
+                    is done in the finish_dynamic_symbol routine.  */
+                 if ((off & 1) != 0)
+                   off &= ~1;
+                 else
+                   {
+                     bfd_put_64 (output_bfd, relocation,
+                                 sgot->contents + off);
+                     if (seen_stt_datalabel)
+                       {
+                         struct elf_sh64_link_hash_entry *hsh;
+
+                         hsh = (struct elf_sh64_link_hash_entry *)h;
+                         hsh->datalabel_got_offset |= 1;
+                       }
+                     else
+                       h->got.offset |= 1;
+                   }
+               }
+
+             relocation = sgot->output_offset + off;
+           }
+         else
+           {
+             bfd_vma off;
+
+             if (rel->r_addend)
+               {
+                 BFD_ASSERT (local_got_offsets != NULL
+                             && (local_got_offsets[symtab_hdr->sh_info
+                                                   + r_symndx]
+                                 != (bfd_vma) -1));
+
+                 off = local_got_offsets[symtab_hdr->sh_info
+                                         + r_symndx];
+               }
+             else
+               {
+                 BFD_ASSERT (local_got_offsets != NULL
+                             && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+                 off = local_got_offsets[r_symndx];
+               }
+
+             /* The offset must always be a multiple of 8.  We use
+                the least significant bit to record whether we have
+                already generated the necessary reloc.  */
+             if ((off & 1) != 0)
+               off &= ~1;
+             else
+               {
+                 bfd_put_64 (output_bfd, relocation, sgot->contents + off);
+
+                 if (info->shared)
+                   {
+                     asection *srelgot;
+                     Elf_Internal_Rela outrel;
+
+                     srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+                     BFD_ASSERT (srelgot != NULL);
+
+                     outrel.r_offset = (sgot->output_section->vma
+                                        + sgot->output_offset
+                                        + off);
+                     outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+                     outrel.r_addend = relocation;
+                     bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+                                               (((Elf64_External_Rela *)
+                                                 srelgot->contents)
+                                                + srelgot->reloc_count));
+                     ++srelgot->reloc_count;
+                   }
+
+                 if (rel->r_addend)
+                   local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
+                 else
+                   local_got_offsets[r_symndx] |= 1;
+               }
+
+             relocation = sgot->output_offset + off;
+           }
+
+         relocation -= GOT_BIAS;
+
+         goto final_link_relocate;
+
+       case R_SH_GOTOFF_LOW16:
+       case R_SH_GOTOFF_MEDLOW16:
+       case R_SH_GOTOFF_MEDHI16:
+       case R_SH_GOTOFF_HI16:
+         /* Relocation is relative to the start of the global offset
+            table.  */
+
+         if (sgot == NULL)
+           {
+             sgot = bfd_get_section_by_name (dynobj, ".got");
+             BFD_ASSERT (sgot != NULL);
+           }
+
+         /* Note that sgot->output_offset is not involved in this
+            calculation.  We always want the start of .got.  If we
+            defined _GLOBAL_OFFSET_TABLE in a different way, as is
+            permitted by the ABI, we might have to change this
+            calculation.  */
+         relocation -= sgot->output_section->vma;
+
+         relocation -= GOT_BIAS;
+
+         addend = rel->r_addend;
+
+         goto final_link_relocate;
+
+       case R_SH_GOTPC_LOW16:
+       case R_SH_GOTPC_MEDLOW16:
+       case R_SH_GOTPC_MEDHI16:
+       case R_SH_GOTPC_HI16:
+         /* Use global offset table as symbol value.  */
+
+         if (sgot == NULL)
+           {
+             sgot = bfd_get_section_by_name (dynobj, ".got");
+             BFD_ASSERT (sgot != NULL);
+           }
+
+         relocation = sgot->output_section->vma;
+
+         relocation += GOT_BIAS;
+
+         addend = rel->r_addend;
+
+         goto final_link_relocate;
+
+       case R_SH_PLT_LOW16:
+       case R_SH_PLT_MEDLOW16:
+       case R_SH_PLT_MEDHI16:
+       case R_SH_PLT_HI16:
+         /* Relocation is to the entry for this symbol in the
+            procedure linkage table.  */
+
+         /* Resolve a PLT reloc against a local symbol directly,
+            without using the procedure linkage table.  */
+         if (h == NULL)
+           goto final_link_relocate;
+
+         if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+           goto final_link_relocate;
+
+         if (h->plt.offset == (bfd_vma) -1)
+           {
+             /* We didn't make a PLT entry for this symbol.  This
+                happens when statically linking PIC code, or when
+                using -Bsymbolic.  */
+             goto final_link_relocate;
+           }
+
+         if (splt == NULL)
+           {
+             splt = bfd_get_section_by_name (dynobj, ".plt");
+             BFD_ASSERT (splt != NULL);
+           }
+
+         relocation = (splt->output_section->vma
+                       + splt->output_offset
+                       + h->plt.offset);
+         relocation++;
+
+         addend = rel->r_addend;
+
+         goto final_link_relocate;
+
+       case R_SH_DIR32:
+       case R_SH_SHMEDIA_CODE:
+       case R_SH_PT_16:
+       case R_SH_DIR5U:
+       case R_SH_DIR6S:
+       case R_SH_DIR6U:
+       case R_SH_DIR10S:
+       case R_SH_DIR10SW:
+       case R_SH_DIR10SL:
+       case R_SH_DIR10SQ:
+       case R_SH_IMMS16:
+       case R_SH_IMMU16:
+       case R_SH_IMM_LOW16:
+       case R_SH_IMM_LOW16_PCREL:
+       case R_SH_IMM_MEDLOW16:
+       case R_SH_IMM_MEDLOW16_PCREL:
+       case R_SH_IMM_MEDHI16:
+       case R_SH_IMM_MEDHI16_PCREL:
+       case R_SH_IMM_HI16:
+       case R_SH_IMM_HI16_PCREL:
+         addend = rel->r_addend;
+         /* Fall through.  */
+       case R_SH_REL32:
+       final_link_relocate:
+         r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                       contents, rel->r_offset,
+                                       relocation, addend);
+         break;
+
+       default:
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+
+       }
+
+      if (r != bfd_reloc_ok)
+       {
+         switch (r)
+           {
+           default:
+           case bfd_reloc_outofrange:
+             abort ();
+           case bfd_reloc_overflow:
+             {
+               const char *name;
+
+               if (h != NULL)
+                 name = h->root.root.string;
+               else
+                 {
+                   name = (bfd_elf_string_from_elf_section
+                           (input_bfd, symtab_hdr->sh_link, sym->st_name));
+                   if (name == NULL)
+                     return false;
+                   if (*name == '\0')
+                     name = bfd_section_name (input_bfd, sec);
+                 }
+               if (! ((*info->callbacks->reloc_overflow)
+                      (info, name, howto->name, (bfd_vma) 0,
+                       input_bfd, input_section, rel->r_offset)))
+                 return false;
+             }
+             break;
+           }
+       }
+    }
+
+  return true;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+   that uses sh_elf64_relocate_section.
+
+   See sh_elf_relocate_section in elf32-sh.c for the original.  */
+
+static bfd_byte *
+sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
+                                        data, relocateable, symbols)
+     bfd *output_bfd;
+     struct bfd_link_info *link_info;
+     struct bfd_link_order *link_order;
+     bfd_byte *data;
+     boolean relocateable;
+     asymbol **symbols;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Shdr *shndx_hdr;
+  asection *input_section = link_order->u.indirect.section;
+  bfd *input_bfd = input_section->owner;
+  asection **sections = NULL;
+  Elf_Internal_Rela *internal_relocs = NULL;
+  Elf64_External_Sym *external_syms = NULL;
+  Elf_External_Sym_Shndx *shndx_buf = NULL;
+  Elf_External_Sym_Shndx *shndx;
+  Elf_Internal_Sym *internal_syms = NULL;
+
+  /* We only need to handle the case of relaxing, or of having a
+     particular set of section contents, specially.  */
+  if (relocateable
+      || elf_section_data (input_section)->this_hdr.contents == NULL)
+    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+                                                      link_order, data,
+                                                      relocateable,
+                                                      symbols);
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  shndx_hdr  = &elf_tdata (input_bfd)->symtab_shndx_hdr;
+
+  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+         input_section->_raw_size);
+
+  if ((input_section->flags & SEC_RELOC) != 0
+      && input_section->reloc_count > 0)
+    {
+      Elf_Internal_Sym *isymp;
+      asection **secpp;
+      Elf64_External_Sym *esym, *esymend;
+      bfd_size_type amt;
+
+      if (symtab_hdr->contents != NULL)
+       external_syms = (Elf64_External_Sym *) symtab_hdr->contents;
+      else
+       {
+         amt = symtab_hdr->sh_info;
+         amt *= sizeof (Elf64_External_Sym);
+
+         external_syms = (Elf64_External_Sym *) bfd_malloc (amt);
+         if (external_syms == NULL && symtab_hdr->sh_info > 0)
+           goto error_return;
+
+         if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+             || (bfd_bread ((PTR) external_syms, amt, input_bfd) != amt))
+           goto error_return;
+       }
+
+      if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
+       {
+         amt = symtab_hdr->sh_info;
+         amt *= sizeof (Elf_External_Sym_Shndx);
+
+         shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+         if (shndx_buf == NULL)
+           goto error_return;
+
+         if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+             || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
+           goto error_return;
+       }
+
+      internal_relocs = (_bfd_elf64_link_read_relocs
+                        (input_bfd, input_section, (PTR) NULL,
+                         (Elf_Internal_Rela *) NULL, false));
+      if (internal_relocs == NULL)
+       goto error_return;
+
+      internal_syms = ((Elf_Internal_Sym *)
+                      bfd_malloc (symtab_hdr->sh_info
+                                  * sizeof (Elf_Internal_Sym)));
+      if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+       goto error_return;
+
+      sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+                                          * sizeof (asection *));
+      if (sections == NULL && symtab_hdr->sh_info > 0)
+       goto error_return;
+
+      isymp = internal_syms;
+      secpp = sections;
+      esym = external_syms;
+      esymend = esym + symtab_hdr->sh_info;
+      shndx = shndx_buf;
+      for (; esym < esymend;
+          ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
+       {
+         asection *isec;
+
+         bfd_elf64_swap_symbol_in (input_bfd, esym, shndx, isymp);
+
+         if (isymp->st_shndx == SHN_UNDEF)
+           isec = bfd_und_section_ptr;
+         else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
+           isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+         else if (isymp->st_shndx == SHN_ABS)
+           isec = bfd_abs_section_ptr;
+         else if (isymp->st_shndx == SHN_COMMON)
+           isec = bfd_com_section_ptr;
+         else
+           {
+             /* Who knows?  */
+             isec = NULL;
+           }
+
+         *secpp = isec;
+       }
+
+      if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd,
+                                      input_section, data, internal_relocs,
+                                      internal_syms, sections))
+       goto error_return;
+
+      if (sections != NULL)
+       free (sections);
+      sections = NULL;
+      if (internal_syms != NULL)
+       free (internal_syms);
+      internal_syms = NULL;
+      if (external_syms != NULL && symtab_hdr->contents == NULL)
+       free (external_syms);
+      external_syms = NULL;
+      if (internal_relocs != elf_section_data (input_section)->relocs)
+       free (internal_relocs);
+      internal_relocs = NULL;
+    }
+
+  return data;
+
+ error_return:
+  if (internal_relocs != NULL
+      && internal_relocs != elf_section_data (input_section)->relocs)
+    free (internal_relocs);
+  if (external_syms != NULL && symtab_hdr->contents == NULL)
+    free (external_syms);
+  if (internal_syms != NULL)
+    free (internal_syms);
+  if (sections != NULL)
+    free (sections);
+  return NULL;
+}
+
+/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections.  */
+
+boolean
+sh64_elf64_fake_sections (output_bfd, elf_section_hdr, asect)
+     bfd *output_bfd ATTRIBUTE_UNUSED;
+     Elf_Internal_Shdr *elf_section_hdr;
+     asection *asect;
+{
+  /* Code sections can only contain SH64 code, so mark them as such.  */
+  if (bfd_get_section_flags (output_bfd, asect) & SEC_CODE)
+    elf_section_hdr->sh_flags |= SHF_SH5_ISA32;
+
+  return true;
+}
+
+static boolean
+sh_elf64_set_mach_from_flags (abfd)
+     bfd *abfd;
+{
+  flagword flags = elf_elfheader (abfd)->e_flags;
+
+  switch (flags & EF_SH_MACH_MASK)
+    {
+    case EF_SH5:
+      /* Just one, but keep the switch construct to make additions easy.  */
+      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
+      break;
+
+    default:
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
+    }
+  return true;
+}
+
+/* Function to keep SH64 specific file flags.
+
+   See sh64_elf_set_private_flags in elf32-sh64.c for the original.  */
+
+static boolean
+sh_elf64_set_private_flags (abfd, flags)
+     bfd *    abfd;
+     flagword flags;
+{
+  BFD_ASSERT (! elf_flags_init (abfd)
+             || elf_elfheader (abfd)->e_flags == flags);
+
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = true;
+  return sh_elf64_set_mach_from_flags (abfd);
+}
+
+/* Copy the SHF_SH5_ISA32 attribute that we keep on all sections with
+   code, to keep attributes the same as for SHmedia in 32-bit ELF.  */
+
+static boolean
+sh_elf64_copy_private_data_internal (ibfd, obfd)
+     bfd * ibfd;
+     bfd * obfd;
+{
+  Elf_Internal_Shdr **o_shdrp;
+  asection *isec;
+  asection *osec;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  o_shdrp = elf_elfsections (obfd);
+  for (osec = obfd->sections; osec; osec = osec->next)
+    {
+      int oIndex = ((struct bfd_elf_section_data *) elf_section_data (osec))->this_idx;
+      for (isec = ibfd->sections; isec; isec = isec->next)
+       {
+         if (strcmp (osec->name, isec->name) == 0)
+           {
+             /* Note that we're not disallowing mixing data and code.  */
+             if ((elf_section_data (isec)->this_hdr.sh_flags
+                  & SHF_SH5_ISA32) != 0)
+               o_shdrp[oIndex]->sh_flags |= SHF_SH5_ISA32;
+             break;
+           }
+       }
+    }
+
+  return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
+}
+
+static boolean
+sh_elf64_copy_private_data (ibfd, obfd)
+     bfd * ibfd;
+     bfd * obfd;
+{
+  return sh_elf64_copy_private_data_internal (ibfd, obfd);
+}
+
+static boolean
+sh_elf64_merge_private_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword old_flags, new_flags;
+
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+    return false;
+
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
+    {
+      const char *msg;
+
+      if (bfd_get_arch_size (ibfd) == 32
+         && bfd_get_arch_size (obfd) == 64)
+       msg = _("%s: compiled as 32-bit object and %s is 64-bit");
+      else if (bfd_get_arch_size (ibfd) == 64
+              && bfd_get_arch_size (obfd) == 32)
+       msg = _("%s: compiled as 64-bit object and %s is 32-bit");
+      else
+       msg = _("%s: object size does not match that of target %s");
+
+      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
+                            bfd_get_filename (obfd));
+      bfd_set_error (bfd_error_wrong_format);
+      return false;
+    }
+
+  old_flags = elf_elfheader (obfd)->e_flags;
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  if (! elf_flags_init (obfd))
+    {
+      /* This happens when ld starts out with a 'blank' output file.  */
+      elf_flags_init (obfd) = true;
+      elf_elfheader (obfd)->e_flags = old_flags = new_flags;
+    }
+  /* We don't allow linking in anything else than SH64 code, and since
+     this is a 64-bit ELF, we assume the 64-bit ABI is used.  Add code
+     here as things change.  */
+  else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
+    {
+      (*_bfd_error_handler)
+       ("%s: does not use the SH64 64-bit ABI as previous modules do",
+        bfd_get_filename (ibfd));
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  sh_elf64_copy_private_data_internal (ibfd, obfd);
+
+  /* I can't think of anything sane other than old_flags being EF_SH5 and
+     that we need to preserve that.  */
+  elf_elfheader (obfd)->e_flags = old_flags;
+
+  return sh_elf64_set_mach_from_flags (obfd);
+}
+
+/* Return the section that should be marked against GC for a given
+   relocation.  */
+
+static asection *
+sh_elf64_gc_mark_hook (abfd, info, rel, h, sym)
+       bfd *abfd;
+       struct bfd_link_info *info ATTRIBUTE_UNUSED;
+       Elf_Internal_Rela *rel;
+       struct elf_link_hash_entry *h;
+       Elf_Internal_Sym *sym;
+{
+  if (h != NULL)
+    {
+      switch (ELF64_R_TYPE (rel->r_info))
+       {
+       case R_SH_GNU_VTINHERIT:
+       case R_SH_GNU_VTENTRY:
+         break;
+
+       default:
+         switch (h->root.type)
+           {
+           case bfd_link_hash_defined:
+           case bfd_link_hash_defweak:
+             return h->root.u.def.section;
+
+           case bfd_link_hash_common:
+             return h->root.u.c.p->section;
+
+           default:
+             break;
+           }
+       }
+    }
+  else
+    {
+      if (!(elf_bad_symtab (abfd)
+           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+               && sym->st_shndx != SHN_COMMON))
+       return bfd_section_from_elf_index (abfd, sym->st_shndx);
+    }
+
+  return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed.  */
+
+static boolean
+sh_elf64_gc_sweep_hook (abfd, info, sec, relocs)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+     asection *sec ATTRIBUTE_UNUSED;
+     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
+{
+  /* No got and plt entries for 64-bit SH at present.  */
+  return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+   Since we don't do .gots or .plts, we just need to consider the
+   virtual table relocs for gc.  */
+static boolean
+sh_elf64_check_relocs (abfd, info, sec, relocs)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     asection *sec;
+     const Elf_Internal_Rela *relocs;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  const Elf_Internal_Rela *rel;
+  const Elf_Internal_Rela *rel_end;
+  bfd *dynobj;
+  bfd_vma *local_got_offsets;
+  asection *sgot;
+  asection *srelgot;
+  asection *sreloc;
+
+  sgot = NULL;
+  srelgot = NULL;
+  sreloc = NULL;
+
+  if (info->relocateable)
+    return true;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);
+  if (!elf_bad_symtab (abfd))
+    sym_hashes_end -= symtab_hdr->sh_info;
+  dynobj = elf_hash_table (info)->dynobj;
+  local_got_offsets = elf_local_got_offsets (abfd);
+
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      struct elf_link_hash_entry *h;
+      unsigned long r_symndx;
+      r_symndx = ELF64_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+        h = NULL;
+      else
+        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+      /* Some relocs require a global offset table.  */
+      if (dynobj == NULL)
+       {
+         switch (ELF64_R_TYPE (rel->r_info))
+           {
+           case R_SH_GOTPLT_LOW16:
+           case R_SH_GOTPLT_MEDLOW16:
+           case R_SH_GOTPLT_MEDHI16:
+           case R_SH_GOTPLT_HI16:
+           case R_SH_GOTPLT10BY4:
+           case R_SH_GOTPLT10BY8:
+           case R_SH_GOT_LOW16:
+           case R_SH_GOT_MEDLOW16:
+           case R_SH_GOT_MEDHI16:
+           case R_SH_GOT_HI16:
+           case R_SH_GOT10BY4:
+           case R_SH_GOT10BY8:
+           case R_SH_GOTOFF_LOW16:
+           case R_SH_GOTOFF_MEDLOW16:
+           case R_SH_GOTOFF_MEDHI16:
+           case R_SH_GOTOFF_HI16:
+           case R_SH_GOTPC_LOW16:
+           case R_SH_GOTPC_MEDLOW16:
+           case R_SH_GOTPC_MEDHI16:
+           case R_SH_GOTPC_HI16:
+             elf_hash_table (info)->dynobj = dynobj = abfd;
+             if (! _bfd_elf_create_got_section (dynobj, info))
+               return false;
+             break;
+
+           default:
+             break;
+           }
+       }
+
+      switch (ELF64_R_TYPE (rel->r_info))
+        {
+         /* This relocation describes the C++ object vtable hierarchy.
+            Reconstruct it for later use during GC.  */
+        case R_SH_GNU_VTINHERIT:
+          if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+            return false;
+          break;
+         /* This relocation describes which C++ vtable entries are actually
+            used.  Record for later use during GC.  */
+        case R_SH_GNU_VTENTRY:
+          if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+            return false;
+          break;
+
+       force_got:
+       case R_SH_GOT_LOW16:
+       case R_SH_GOT_MEDLOW16:
+       case R_SH_GOT_MEDHI16:
+       case R_SH_GOT_HI16:
+       case R_SH_GOT10BY4:
+       case R_SH_GOT10BY8:
+         /* This symbol requires a global offset table entry.  */
+
+         if (sgot == NULL)
+           {
+             sgot = bfd_get_section_by_name (dynobj, ".got");
+             BFD_ASSERT (sgot != NULL);
+           }
+
+         if (srelgot == NULL
+             && (h != NULL || info->shared))
+           {
+             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+             if (srelgot == NULL)
+               {
+                 srelgot = bfd_make_section (dynobj, ".rela.got");
+                 if (srelgot == NULL
+                     || ! bfd_set_section_flags (dynobj, srelgot,
+                                                 (SEC_ALLOC
+                                                  | SEC_LOAD
+                                                  | SEC_HAS_CONTENTS
+                                                  | SEC_IN_MEMORY
+                                                  | SEC_LINKER_CREATED
+                                                  | SEC_READONLY))
+                     || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+                   return false;
+               }
+           }
+
+         if (h != NULL)
+           {
+             if (h->type == STT_DATALABEL)
+               {
+                 struct elf_sh64_link_hash_entry *hsh;
+
+                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
+                 hsh = (struct elf_sh64_link_hash_entry *)h;
+                 if (hsh->datalabel_got_offset != (bfd_vma) -1)
+                   break;
+
+                 hsh->datalabel_got_offset = sgot->_raw_size;
+               }
+             else
+               {
+                 if (h->got.offset != (bfd_vma) -1)
+                   {
+                     /* We have already allocated space in the .got.  */
+                     break;
+                   }
+                 h->got.offset = sgot->_raw_size;
+               }
+
+             /* Make sure this symbol is output as a dynamic symbol.  */
+             if (h->dynindx == -1)
+               {
+                 if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+                   return false;
+               }
+
+             srelgot->_raw_size += sizeof (Elf64_External_Rela);
+           }
+         else
+           {
+             /* This is a global offset table entry for a local
+                symbol.  */
+             if (local_got_offsets == NULL)
+               {
+                 size_t size;
+                 register unsigned int i;
+
+                 size = symtab_hdr->sh_info * sizeof (bfd_vma);
+                 /* Reserve space for both the datalabel and
+                    codelabel local GOT offsets.  */
+                 size *= 2;
+                 local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+                 if (local_got_offsets == NULL)
+                   return false;
+                 elf_local_got_offsets (abfd) = local_got_offsets;
+                 for (i = 0; i < symtab_hdr->sh_info; i++)
+                   local_got_offsets[i] = (bfd_vma) -1;
+                 for (; i < 2 * symtab_hdr->sh_info; i++)
+                   local_got_offsets[i] = (bfd_vma) -1;
+               }
+             if ((rel->r_addend & 1) != 0)
+               {
+                 if (local_got_offsets[symtab_hdr->sh_info
+                                       + r_symndx] != (bfd_vma) -1)
+                   {
+                     /* We have already allocated space in the .got.  */
+                     break;
+                   }
+                 local_got_offsets[symtab_hdr->sh_info
+                                   + r_symndx] = sgot->_raw_size;
+               }
+             else
+               {
+                 if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+                   {
+                     /* We have already allocated space in the .got.  */
+                     break;
+                   }
+                 local_got_offsets[r_symndx] = sgot->_raw_size;
+               }
+
+             if (info->shared)
+               {
+                 /* If we are generating a shared object, we need to
+                    output a R_SH_RELATIVE reloc so that the dynamic
+                    linker can adjust this GOT entry.  */
+                 srelgot->_raw_size += sizeof (Elf64_External_Rela);
+               }
+           }
+
+         sgot->_raw_size += 8;
+
+         break;
+
+       case R_SH_GOTPLT_LOW16:
+       case R_SH_GOTPLT_MEDLOW16:
+       case R_SH_GOTPLT_MEDHI16:
+       case R_SH_GOTPLT_HI16:
+       case R_SH_GOTPLT10BY4:
+       case R_SH_GOTPLT10BY8:
+         /* If this is a local symbol, we resolve it directly without
+            creating a procedure linkage table entry.  */
+
+         if (h == NULL
+             || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+             || ! info->shared
+             || info->symbolic
+             || h->dynindx == -1
+             || h->got.offset != (bfd_vma) -1)
+           goto force_got;
+
+         /* Make sure this symbol is output as a dynamic symbol.  */
+         if (h->dynindx == -1)
+           {
+             if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+               return false;
+           }
+
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+         break;
+
+       case R_SH_PLT_LOW16:
+       case R_SH_PLT_MEDLOW16:
+       case R_SH_PLT_MEDHI16:
+       case R_SH_PLT_HI16:
+         /* This symbol requires a procedure linkage table entry.  We
+            actually build the entry in adjust_dynamic_symbol,
+            because this might be a case of linking PIC code which is
+            never referenced by a dynamic object, in which case we
+            don't need to generate a procedure linkage table entry
+            after all.  */
+
+         /* If this is a local symbol, we resolve it directly without
+            creating a procedure linkage table entry.  */
+         if (h == NULL)
+           continue;
+
+         if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+             || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+           break;
+
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+         break;
+
+       case R_SH_64:
+       case R_SH_64_PCREL:
+         if (h != NULL)
+           h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+
+         /* If we are creating a shared library, and this is a reloc
+            against a global symbol, or a non PC relative reloc
+            against a local symbol, then we need to copy the reloc
+            into the shared library.  However, if we are linking with
+            -Bsymbolic, we do not need to copy a reloc against a
+            global symbol which is defined in an object we are
+            including in the link (i.e., DEF_REGULAR is set).  At
+            this point we have not seen all the input files, so it is
+            possible that DEF_REGULAR is not set now but will be set
+            later (it is never cleared).  We account for that
+            possibility below by storing information in the
+            pcrel_relocs_copied field of the hash table entry.  */
+         if (info->shared
+             && (sec->flags & SEC_ALLOC) != 0
+             && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL
+                 || (h != NULL
+                     && (! info->symbolic
+                         || (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+           {
+             /* When creating a shared object, we must copy these
+                reloc types into the output file.  We create a reloc
+                section in dynobj and make room for this reloc.  */
+             if (sreloc == NULL)
+               {
+                 const char *name;
+
+                 name = (bfd_elf_string_from_elf_section
+                         (abfd,
+                          elf_elfheader (abfd)->e_shstrndx,
+                          elf_section_data (sec)->rel_hdr.sh_name));
+                 if (name == NULL)
+                   return false;
+
+                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+                             && strcmp (bfd_get_section_name (abfd, sec),
+                                        name + 5) == 0);
+
+                 sreloc = bfd_get_section_by_name (dynobj, name);
+                 if (sreloc == NULL)
+                   {
+                     flagword flags;
+
+                     sreloc = bfd_make_section (dynobj, name);
+                     flags = (SEC_HAS_CONTENTS | SEC_READONLY
+                              | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+                     if ((sec->flags & SEC_ALLOC) != 0)
+                       flags |= SEC_ALLOC | SEC_LOAD;
+                     if (sreloc == NULL
+                         || ! bfd_set_section_flags (dynobj, sreloc, flags)
+                         || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+                       return false;
+                   }
+               }
+
+             sreloc->_raw_size += sizeof (Elf64_External_Rela);
+
+             /* If we are linking with -Bsymbolic, and this is a
+                global symbol, we count the number of PC relative
+                relocations we have entered for this symbol, so that
+                we can discard them again if the symbol is later
+                defined by a regular object.  Note that this function
+                is only called if we are using an elf_sh linker
+                hash table, which means that h is really a pointer to
+                an elf_sh_link_hash_entry.  */
+             if (h != NULL && info->symbolic
+                 && ELF64_R_TYPE (rel->r_info) == R_SH_64_PCREL)
+               {
+                 struct elf_sh64_link_hash_entry *eh;
+                 struct elf_sh64_pcrel_relocs_copied *p;
+
+                 eh = (struct elf_sh64_link_hash_entry *) h;
+
+                 for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+                   if (p->section == sreloc)
+                     break;
+
+                 if (p == NULL)
+                   {
+                     p = ((struct elf_sh64_pcrel_relocs_copied *)
+                          bfd_alloc (dynobj, sizeof *p));
+                     if (p == NULL)
+                       return false;
+                     p->next = eh->pcrel_relocs_copied;
+                     eh->pcrel_relocs_copied = p;
+                     p->section = sreloc;
+                     p->count = 0;
+                   }
+
+                 ++p->count;
+               }
+           }
+
+         break;
+        }
+    }
+  return true;
+}
+
+static int
+sh64_elf64_get_symbol_type (elf_sym, type)
+     Elf_Internal_Sym * elf_sym;
+     int type;
+{
+  if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
+    return STT_DATALABEL;
+
+  return type;
+}
+
+/* FIXME: This is a copy of sh64_elf_add_symbol_hook in elf32-sh64.c.
+   Either file can presumably exist without the other, but do not differ
+   in elf-size-ness.  How to share?
+
+   Hook called by the linker routine which adds symbols from an object
+   file.  We must make indirect symbols for undefined symbols marked with
+   STT_DATALABEL, so relocations passing them will pick up that attribute
+   and neutralize STO_SH5_ISA32 found on the symbol definition.
+
+   There is a problem, though: We want to fill in the hash-table entry for
+   this symbol and signal to the caller that no further processing is
+   needed.  But we don't have the index for this hash-table entry.  We
+   rely here on that the current entry is the first hash-entry with NULL,
+   which seems brittle.  Also, iterating over the hash-table to find that
+   entry is a linear operation on the number of symbols in this input
+   file, and this function should take constant time, so that's not good
+   too.  Only comfort is that DataLabel references should only be found in
+   hand-written assembly code and thus be rare.  FIXME: Talk maintainers
+   into adding an option to elf_add_symbol_hook (preferably) for the index
+   or the hash entry, alternatively adding the index to Elf_Internal_Sym
+   (not so good).  */
+
+static boolean
+sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     const Elf_Internal_Sym *sym;
+     const char **namep;
+     flagword *flagsp ATTRIBUTE_UNUSED;
+     asection **secp;
+     bfd_vma *valp;
+{
+  /* We want to do this for relocatable as well as final linking.  */
+  if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+    {
+      struct elf_link_hash_entry *h;
+
+      /* For relocateable links, we register the DataLabel sym in its own
+        right, and tweak the name when it's output.  Otherwise, we make
+        an indirect symbol of it.  */
+      flagword flags
+       = info->relocateable || info->emitrelocations
+       ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
+
+      char *dl_name
+       = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
+      struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
+
+      BFD_ASSERT (sym_hash != NULL);
+
+      /* Allocation may fail.  */
+      if (dl_name == NULL)
+       return false;
+
+      strcpy (dl_name, *namep);
+      strcat (dl_name, DATALABEL_SUFFIX);
+
+      h = (struct elf_link_hash_entry *)
+       bfd_link_hash_lookup (info->hash, dl_name, false, false, false);
+
+      if (h == NULL)
+       {
+         /* No previous datalabel symbol.  Make one.  */
+         if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
+                                                 flags, *secp, *valp,
+                                                 *namep, false,
+                                                 get_elf_backend_data (abfd)->collect,
+                                                 (struct bfd_link_hash_entry **) &h))
+           {
+             free (dl_name);
+             return false;
+           }
+
+         h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+         h->type = STT_DATALABEL;
+       }
+      else
+       /* If a new symbol was created, it holds the allocated name.
+          Otherwise, we don't need it anymore and should deallocate it.  */
+       free (dl_name);
+
+      if (h->type != STT_DATALABEL
+         || ((info->relocateable || info->emitrelocations)
+             && h->root.type != bfd_link_hash_undefined)
+         || (! info->relocateable && !info->emitrelocations
+             && h->root.type != bfd_link_hash_indirect))
+       {
+         /* Make sure we don't get confused on invalid input.  */
+         (*_bfd_error_handler)
+           (_("%s: encountered datalabel symbol in input"),
+            bfd_get_filename (abfd));
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+       }
+
+      /* Now find the hash-table slot for this entry and fill it in.  */
+      while (*sym_hash != NULL)
+       sym_hash++;
+      *sym_hash = h;
+
+      /* Signal to caller to skip this symbol - we've handled it.  */
+      *namep = NULL;
+    }
+
+  return true;
+}
+
+/* This hook function is called before the linker writes out a global
+   symbol.  For relocatable links, DataLabel symbols will be present in
+   linker output.  We cut off the special suffix on those symbols, so the
+   right name appears in the output.
+
+   When linking and emitting relocations, there can appear global symbols
+   that are not referenced by relocs, but rather only implicitly through
+   DataLabel references, a relation that is not visible to the linker.
+   Since no stripping of global symbols in done when doing such linking,
+   we don't need to look up and make sure to emit the main symbol for each
+   DataLabel symbol.  */
+
+boolean
+sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info;
+     const char *cname;
+     Elf_Internal_Sym *sym;
+     asection *input_sec ATTRIBUTE_UNUSED;
+{
+  char *name = (char *) cname;
+
+  if (info->relocateable || info->emitrelocations)
+    {
+      if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+       name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
+    }
+
+  return true;
+}
+
+/* Set bit 0 on the entry address; it always points to SHmedia code.  This
+   is mostly for symmetry with the 32-bit format, where code can be
+   SHcompact and we need to make a distinction to make sure execution
+   starts in the right ISA mode.  It is also convenient for a loader,
+   which would otherwise have to set this bit when loading a TR register
+   before jumping to the program entry.  */
+
+static void
+sh64_elf64_final_write_processing (abfd, linker)
+     bfd *abfd;
+     boolean linker ATTRIBUTE_UNUSED;
+{
+  /* FIXME: Perhaps we shouldn't do this if the entry address was supplied
+     numerically, but we currently lack the infrastructure to recognize
+     that: The entry symbol, and info whether it is numeric or a symbol
+     name is kept private in the linker.  */
+  if (elf_elfheader (abfd)->e_type == ET_EXEC)
+    elf_elfheader (abfd)->e_entry |= 1;
+}
+
+/* First entry in an absolute procedure linkage table look like this.  */
+
+static const bfd_byte elf_sh64_plt0_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x10, /* movi  .got.plt >> 48, r17 */
+  0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 32) & 65535, r17 */
+  0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 16) & 65535, r17 */
+  0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */
+  0x8d, 0x10, 0x09, 0x90, /* ld.q  r17, 16, r25 */
+  0x6b, 0xf1, 0x46, 0x00, /* ptabs r17, tr0 */
+  0x8d, 0x10, 0x05, 0x10, /* ld.q  r17, 8, r17 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh64_plt0_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x10, 0x01, 0x00, 0xcc, /* movi  .got.plt >> 16, r17 */
+  0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 32) & 65535, r17 */
+  0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 16) & 65535, r17 */
+  0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */
+  0x90, 0x09, 0x10, 0x8d, /* ld.q  r17, 16, r25 */
+  0x00, 0x46, 0xf1, 0x6b, /* ptabs r17, tr0 */
+  0x10, 0x05, 0x10, 0x8d, /* ld.q  r17, 8, r17 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Sebsequent entries in an absolute procedure linkage table look like
+   this.  */
+
+static const bfd_byte elf_sh64_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x90, /* movi  nameN-in-GOT >> 48, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori (nameN-in-GOT >> 32) & 65535, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori (nameN-in-GOT >> 16) & 65535, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori nameN-in-GOT & 65535, r25 */
+  0x8d, 0x90, 0x01, 0x90, /* ld.q  r25, 0, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0xcc, 0x00, 0x01, 0x90, /* movi  .PLT0 >> 16, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0xcc, 0x00, 0x01, 0x50, /* movi  reloc-offset >> 16, r21 */
+  0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh64_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x90, 0x01, 0x00, 0xcc, /* movi  nameN-in-GOT >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+  0x90, 0x01, 0x90, 0x8d, /* ld.q  r25, 0, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0x90, 0x01, 0x00, 0xcc, /* movi  .PLT0 >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0x50, 0x01, 0x00, 0xcc, /* movi  reloc-offset >> 16, r21 */
+  0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Entries in a PIC procedure linkage table look like this.  */
+
+static const bfd_byte elf_sh64_pic_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+  0xcc, 0x00, 0x01, 0x90, /* movi  nameN@GOT >> 16, r25 */
+  0xc8, 0x00, 0x01, 0x90, /* shori nameN@GOT & 65535, r25 */
+  0x40, 0xc3, 0x65, 0x90, /* ldx.q r12, r25, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0x6f, 0xf0, 0xff, 0xf0, /* nop */
+  0xce, 0x00, 0x01, 0x10, /* movi  -GOT_BIAS, r17 */
+  0x00, 0xcb, 0x45, 0x10, /* sub   r12, r17, r17 */
+  0x8d, 0x10, 0x09, 0x90, /* ld.q  r17, 16, r25 */
+  0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+  0x8d, 0x10, 0x05, 0x10, /* ld.q  r17, 8, r17 */
+  0xcc, 0x00, 0x01, 0x50, /* movi  reloc-offset >> 16, r21 */
+  0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+  0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+};
+
+static const bfd_byte elf_sh64_pic_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+  0x90, 0x01, 0x00, 0xcc, /* movi  nameN@GOT >> 16, r25 */
+  0x90, 0x01, 0x00, 0xc8, /* shori nameN@GOT & 65535, r25 */
+  0x90, 0x65, 0xc3, 0x40, /* ldx.q r12, r25, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0xf0, 0xff, 0xf0, 0x6f, /* nop */
+  0x10, 0x01, 0x00, 0xce, /* movi  -GOT_BIAS, r17 */
+  0x10, 0x45, 0xcb, 0x00, /* sub   r12, r17, r17 */
+  0x90, 0x09, 0x10, 0x8d, /* ld.q  r17, 16, r25 */
+  0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+  0x10, 0x05, 0x10, 0x8d, /* ld.q  r17, 8, r17 */
+  0x50, 0x01, 0x00, 0xcc, /* movi  reloc-offset >> 16, r21 */
+  0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+  0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+};
+
+static const bfd_byte *elf_sh64_plt0_entry;
+static const bfd_byte *elf_sh64_plt_entry;
+static const bfd_byte *elf_sh64_pic_plt_entry;
+
+/* Create an entry in an sh ELF linker hash table.  */
+
+static struct bfd_hash_entry *
+sh64_elf64_link_hash_newfunc (entry, table, string)
+     struct bfd_hash_entry *entry;
+     struct bfd_hash_table *table;
+     const char *string;
+{
+  struct elf_sh64_link_hash_entry *ret =
+    (struct elf_sh64_link_hash_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == (struct elf_sh64_link_hash_entry *) NULL)
+    ret = ((struct elf_sh64_link_hash_entry *)
+          bfd_hash_allocate (table,
+                             sizeof (struct elf_sh64_link_hash_entry)));
+  if (ret == (struct elf_sh64_link_hash_entry *) NULL)
+    return (struct bfd_hash_entry *) ret;
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct elf_sh64_link_hash_entry *)
+        _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+                                    table, string));
+  if (ret != (struct elf_sh64_link_hash_entry *) NULL)
+    {
+      ret->pcrel_relocs_copied = NULL;
+      ret->datalabel_got_offset = (bfd_vma) -1;
+    }
+
+  return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an sh64 ELF linker hash table.  */
+
+static struct bfd_link_hash_table *
+sh64_elf64_link_hash_table_create (abfd)
+     bfd *abfd;
+{
+  struct elf_sh64_link_hash_table *ret;
+
+  ret = ((struct elf_sh64_link_hash_table *)
+        bfd_alloc (abfd, sizeof (struct elf_sh64_link_hash_table)));
+  if (ret == (struct elf_sh64_link_hash_table *) NULL)
+    return NULL;
+
+  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+                                      sh64_elf64_link_hash_newfunc))
+    {
+      bfd_release (abfd, ret);
+      return NULL;
+    }
+
+  return &ret->root.root;
+}
+
+inline static void
+movi_shori_putval (output_bfd, value, addr)
+     bfd *output_bfd;
+     unsigned long value;
+     char *addr;
+{
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr)
+             | ((value >> 6) & 0x3fffc00),
+             addr);
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr + 4)
+             | ((value << 10) & 0x3fffc00),
+             addr + 4);
+}
+
+inline static void
+movi_3shori_putval (output_bfd, value, addr)
+     bfd *output_bfd;
+     bfd_vma value;
+     char *addr;
+{
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr)
+             | ((value >> 38) & 0x3fffc00),
+             addr);
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr + 4)
+             | ((value >> 22) & 0x3fffc00),
+             addr + 4);
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr + 8)
+             | ((value >> 6) & 0x3fffc00),
+             addr + 8);
+  bfd_put_32 (output_bfd,
+             bfd_get_32 (output_bfd, addr + 12)
+             | ((value << 10) & 0x3fffc00),
+             addr + 12);
+}
+
+/* Create dynamic sections when linking against a dynamic object.  */
+
+static boolean
+sh64_elf64_create_dynamic_sections (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  flagword flags, pltflags;
+  register asection *s;
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  int ptralign = 0;
+
+  switch (bed->s->arch_size)
+    {
+    case 32:
+      ptralign = 2;
+      break;
+
+    case 64:
+      ptralign = 3;
+      break;
+
+    default:
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+     .rel[a].bss sections.  */
+
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+          | SEC_LINKER_CREATED);
+
+  pltflags = flags;
+  pltflags |= SEC_CODE;
+  if (bed->plt_not_loaded)
+    pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
+  if (bed->plt_readonly)
+    pltflags |= SEC_READONLY;
+
+  s = bfd_make_section (abfd, ".plt");
+  if (s == NULL
+      || ! bfd_set_section_flags (abfd, s, pltflags)
+      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+    return false;
+
+  if (bed->want_plt_sym)
+    {
+      /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+        .plt section.  */
+      struct elf_link_hash_entry *h = NULL;
+      if (! (_bfd_generic_link_add_one_symbol
+            (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+             (bfd_vma) 0, (const char *) NULL, false,
+             get_elf_backend_data (abfd)->collect,
+             (struct bfd_link_hash_entry **) &h)))
+       return false;
+      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+      h->type = STT_OBJECT;
+
+      if (info->shared
+         && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+       return false;
+    }
+
+  s = bfd_make_section (abfd,
+                       bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
+  if (s == NULL
+      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+      || ! bfd_set_section_alignment (abfd, s, ptralign))
+    return false;
+
+  if (! _bfd_elf_create_got_section (abfd, info))
+    return false;
+
+  {
+    const char *secname;
+    char *relname;
+    flagword secflags;
+    asection *sec;
+
+    for (sec = abfd->sections; sec; sec = sec->next)
+      {
+       secflags = bfd_get_section_flags (abfd, sec);
+       if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
+           || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
+         continue;
+       secname = bfd_get_section_name (abfd, sec);
+       relname = (char *) bfd_malloc (strlen (secname) + 6);
+       strcpy (relname, ".rela");
+       strcat (relname, secname);
+       s = bfd_make_section (abfd, relname);
+       if (s == NULL
+           || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+           || ! bfd_set_section_alignment (abfd, s, ptralign))
+         return false;
+      }
+  }
+
+  if (bed->want_dynbss)
+    {
+      /* The .dynbss section is a place to put symbols which are defined
+        by dynamic objects, are referenced by regular objects, and are
+        not functions.  We must allocate space for them in the process
+        image and use a R_*_COPY reloc to tell the dynamic linker to
+        initialize them at run time.  The linker script puts the .dynbss
+        section into the .bss section of the final image.  */
+      s = bfd_make_section (abfd, ".dynbss");
+      if (s == NULL
+         || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+       return false;
+
+      /* The .rel[a].bss section holds copy relocs.  This section is not
+        normally needed.  We need to create it here, though, so that the
+        linker will map it to an output section.  We can't just create it
+        only if we need it, because we will not know whether we need it
+        until we have seen all the input files, and the first time the
+        main linker code calls BFD after examining all the input files
+        (size_dynamic_sections) the input sections have already been
+        mapped to the output sections.  If the section turns out not to
+        be needed, we can discard it later.  We will never need this
+        section when generating a shared object, since they do not use
+        copy relocs.  */
+      if (! info->shared)
+       {
+         s = bfd_make_section (abfd,
+                               (bed->default_use_rela_p
+                                ? ".rela.bss" : ".rel.bss"));
+         if (s == NULL
+             || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+             || ! bfd_set_section_alignment (abfd, s, ptralign))
+           return false;
+       }
+    }
+
+  return true;
+}
+\f
+/* Adjust a symbol defined by a dynamic object and referenced by a
+   regular object.  The current definition is in some section of the
+   dynamic object, but we're not including those sections.  We have to
+   change the definition to something the rest of the link can
+   understand.  */
+
+static boolean
+sh64_elf64_adjust_dynamic_symbol (info, h)
+     struct bfd_link_info *info;
+     struct elf_link_hash_entry *h;
+{
+  bfd *dynobj;
+  asection *s;
+  unsigned int power_of_two;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  /* Make sure we know what is going on here.  */
+  BFD_ASSERT (dynobj != NULL
+             && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+                 || h->weakdef != NULL
+                 || ((h->elf_link_hash_flags
+                      & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+                     && (h->elf_link_hash_flags
+                         & ELF_LINK_HASH_REF_REGULAR) != 0
+                     && (h->elf_link_hash_flags
+                         & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+  /* If this is a function, put it in the procedure linkage table.  We
+     will fill in the contents of the procedure linkage table later,
+     when we know the address of the .got section.  */
+  if (h->type == STT_FUNC
+      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+    {
+      if (! info->shared
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+       {
+         /* This case can occur if we saw a PLT reloc in an input
+            file, but the symbol was never referred to by a dynamic
+            object.  In such a case, we don't actually need to build
+            a procedure linkage table, and we can just do a REL64
+            reloc instead.  */
+         BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+         return true;
+       }
+
+      /* Make sure this symbol is output as a dynamic symbol.  */
+      if (h->dynindx == -1)
+       {
+         if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+           return false;
+       }
+
+      s = bfd_get_section_by_name (dynobj, ".plt");
+      BFD_ASSERT (s != NULL);
+
+      /* If this is the first .plt entry, make room for the special
+        first entry.  */
+      if (s->_raw_size == 0)
+       s->_raw_size += PLT_ENTRY_SIZE;
+
+      /* If this symbol is not defined in a regular file, and we are
+        not generating a shared library, then set the symbol to this
+        location in the .plt.  This is required to make function
+        pointers compare as equal between the normal executable and
+        the shared library.  */
+      if (! info->shared
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+       {
+         h->root.u.def.section = s;
+         h->root.u.def.value = s->_raw_size;
+       }
+
+      h->plt.offset = s->_raw_size;
+
+      /* Make room for this entry.  */
+      s->_raw_size += elf_sh64_sizeof_plt (info);
+
+      /* We also need to make an entry in the .got.plt section, which
+        will be placed in the .got section by the linker script.  */
+
+      s = bfd_get_section_by_name (dynobj, ".got.plt");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size += 8;
+
+      /* We also need to make an entry in the .rela.plt section.  */
+
+      s = bfd_get_section_by_name (dynobj, ".rela.plt");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size += sizeof (Elf64_External_Rela);
+
+      return true;
+    }
+
+  /* If this is a weak symbol, and there is a real definition, the
+     processor independent code will have arranged for us to see the
+     real definition first, and we can just use the same value.  */
+  if (h->weakdef != NULL)
+    {
+      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+                 || h->weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->weakdef->root.u.def.section;
+      h->root.u.def.value = h->weakdef->root.u.def.value;
+      return true;
+    }
+
+  /* This is a reference to a symbol defined by a dynamic object which
+     is not a function.  */
+
+  /* If we are creating a shared library, we must presume that the
+     only references to the symbol are via the global offset table.
+     For such cases we need not do anything here; the relocations will
+     be handled correctly by relocate_section.  */
+  if (info->shared)
+    return true;
+
+  /* If there are no references to this symbol that do not use the
+     GOT, we don't need to generate a copy reloc.  */
+  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
+    return true;
+
+  /* We must allocate the symbol in our .dynbss section, which will
+     become part of the .bss section of the executable.  There will be
+     an entry for this symbol in the .dynsym section.  The dynamic
+     object will contain position independent code, so all references
+     from the dynamic object to this symbol will go through the global
+     offset table.  The dynamic linker will use the .dynsym entry to
+     determine the address it must put in the global offset table, so
+     both the dynamic object and the regular object will refer to the
+     same memory location for the variable.  */
+
+  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  BFD_ASSERT (s != NULL);
+
+  /* We must generate a R_SH_COPY reloc to tell the dynamic linker to
+     copy the initial value out of the dynamic object and into the
+     runtime process image.  We need to remember the offset into the
+     .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+    {
+      asection *srel;
+
+      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      BFD_ASSERT (srel != NULL);
+      srel->_raw_size += sizeof (Elf64_External_Rela);
+      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+    }
+
+  /* We need to figure out the alignment required for this symbol.  I
+     have no idea how ELF linkers handle this.  */
+  power_of_two = bfd_log2 (h->size);
+  if (power_of_two > 3)
+    power_of_two = 3;
+
+  /* Apply the required alignment.  */
+  s->_raw_size = BFD_ALIGN (s->_raw_size,
+                           (bfd_size_type) (1 << power_of_two));
+  if (power_of_two > bfd_get_section_alignment (dynobj, s))
+    {
+      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+       return false;
+    }
+
+  /* Define the symbol as being at this point in the section.  */
+  h->root.u.def.section = s;
+  h->root.u.def.value = s->_raw_size;
+
+  /* Increment the section size to make room for the symbol.  */
+  s->_raw_size += h->size;
+
+  return true;
+}
+
+/* This function is called via sh_elf_link_hash_traverse if we are
+   creating a shared object with -Bsymbolic.  It discards the space
+   allocated to copy PC relative relocs against symbols which are
+   defined in regular objects.  We allocated space for them in the
+   check_relocs routine, but we won't fill them in in the
+   relocate_section routine.  */
+
+static boolean
+sh64_elf64_discard_copies (h, ignore)
+     struct elf_sh64_link_hash_entry *h;
+     PTR ignore ATTRIBUTE_UNUSED;
+{
+  struct elf_sh64_pcrel_relocs_copied *s;
+
+  /* We only discard relocs for symbols defined in a regular object.  */
+  if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+    return true;
+
+  for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+    s->section->_raw_size -= s->count * sizeof (Elf64_External_Rela);
+
+  return true;
+}
+
+/* Set the sizes of the dynamic sections.  */
+
+static boolean
+sh64_elf64_size_dynamic_sections (output_bfd, info)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+{
+  bfd *dynobj;
+  asection *s;
+  boolean plt;
+  boolean relocs;
+  boolean reltext;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  BFD_ASSERT (dynobj != NULL);
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Set the contents of the .interp section to the interpreter.  */
+      if (! info->shared)
+       {
+         s = bfd_get_section_by_name (dynobj, ".interp");
+         BFD_ASSERT (s != NULL);
+         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+       }
+    }
+  else
+    {
+      /* We may have created entries in the .rela.got section.
+        However, if we are not creating the dynamic sections, we will
+        not actually use these entries.  Reset the size of .rela.got,
+        which will cause it to get stripped from the output file
+        below.  */
+      s = bfd_get_section_by_name (dynobj, ".rela.got");
+      if (s != NULL)
+       s->_raw_size = 0;
+    }
+
+  /* If this is a -Bsymbolic shared link, then we need to discard all
+     PC relative relocs against symbols defined in a regular object.
+     We allocated space for them in the check_relocs routine, but we
+     will not fill them in in the relocate_section routine.  */
+  if (info->shared && info->symbolic)
+    sh64_elf64_link_hash_traverse (sh64_elf64_hash_table (info),
+                                  sh64_elf64_discard_copies,
+                                  (PTR) NULL);
+
+  /* The check_relocs and adjust_dynamic_symbol entry points have
+     determined the sizes of the various dynamic sections.  Allocate
+     memory for them.  */
+  plt = false;
+  relocs = false;
+  reltext = false;
+  for (s = dynobj->sections; s != NULL; s = s->next)
+    {
+      const char *name;
+      boolean strip;
+
+      if ((s->flags & SEC_LINKER_CREATED) == 0)
+       continue;
+
+      /* It's OK to base decisions on the section name, because none
+        of the dynobj section names depend upon the input files.  */
+      name = bfd_get_section_name (dynobj, s);
+
+      strip = false;
+
+      if (strcmp (name, ".plt") == 0)
+       {
+         if (s->_raw_size == 0)
+           {
+             /* Strip this section if we don't need it; see the
+                comment below.  */
+             strip = true;
+           }
+         else
+           {
+             /* Remember whether there is a PLT.  */
+             plt = true;
+           }
+       }
+      else if (strncmp (name, ".rela", 5) == 0)
+       {
+         if (s->_raw_size == 0)
+           {
+             /* If we don't need this section, strip it from the
+                output file.  This is mostly to handle .rela.bss and
+                .rela.plt.  We must create both sections in
+                create_dynamic_sections, because they must be created
+                before the linker maps input sections to output
+                sections.  The linker does that before
+                adjust_dynamic_symbol is called, and it is that
+                function which decides whether anything needs to go
+                into these sections.  */
+             strip = true;
+           }
+         else
+           {
+             asection *target;
+
+             /* Remember whether there are any reloc sections other
+                than .rela.plt.  */
+             if (strcmp (name, ".rela.plt") != 0)
+               {
+                 const char *outname;
+
+                 relocs = true;
+
+                 /* If this relocation section applies to a read only
+                    section, then we probably need a DT_TEXTREL
+                    entry.  The entries in the .rela.plt section
+                    really apply to the .got section, which we
+                    created ourselves and so know is not readonly.  */
+                 outname = bfd_get_section_name (output_bfd,
+                                                 s->output_section);
+                 target = bfd_get_section_by_name (output_bfd, outname + 5);
+                 if (target != NULL
+                     && (target->flags & SEC_READONLY) != 0
+                     && (target->flags & SEC_ALLOC) != 0)
+                   reltext = true;
+               }
+
+             /* We use the reloc_count field as a counter if we need
+                to copy relocs into the output file.  */
+             s->reloc_count = 0;
+           }
+       }
+      else if (strncmp (name, ".got", 4) != 0)
+       {
+         /* It's not one of our sections, so don't allocate space.  */
+         continue;
+       }
+
+      if (strip)
+       {
+         _bfd_strip_section_from_output (info, s);
+         continue;
+       }
+
+      /* Allocate memory for the section contents.  */
+      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+      if (s->contents == NULL && s->_raw_size != 0)
+       return false;
+    }
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Add some entries to the .dynamic section.  We fill in the
+        values later, in sh64_elf64_finish_dynamic_sections, but we
+        must add the entries now so that we get the correct size for
+        the .dynamic section.  The DT_DEBUG entry is filled in by the
+        dynamic linker and used by the debugger.  */
+      if (! info->shared)
+       {
+         if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+           return false;
+       }
+
+      if (plt)
+       {
+         if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+           return false;
+       }
+
+      if (relocs)
+       {
+         if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
+                                               sizeof (Elf64_External_Rela)))
+           return false;
+       }
+
+      if (reltext)
+       {
+         if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+           return false;
+       }
+    }
+
+  return true;
+}
+
+/* Finish up dynamic symbol handling.  We set the contents of various
+   dynamic sections here.  */
+
+static boolean
+sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+     struct elf_link_hash_entry *h;
+     Elf_Internal_Sym *sym;
+{
+  bfd *dynobj;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  if (h->plt.offset != (bfd_vma) -1)
+    {
+      asection *splt;
+      asection *sgot;
+      asection *srel;
+
+      bfd_vma plt_index;
+      bfd_vma got_offset;
+      Elf_Internal_Rela rel;
+
+      /* This symbol has an entry in the procedure linkage table.  Set
+        it up.  */
+
+      BFD_ASSERT (h->dynindx != -1);
+
+      splt = bfd_get_section_by_name (dynobj, ".plt");
+      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+      srel = bfd_get_section_by_name (dynobj, ".rela.plt");
+      BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+      /* Get the index in the procedure linkage table which
+        corresponds to this symbol.  This is the index of this symbol
+        in all the symbols for which we are making plt entries.  The
+        first entry in the procedure linkage table is reserved.  */
+      plt_index = h->plt.offset / elf_sh64_sizeof_plt (info) - 1;
+
+      /* Get the offset into the .got table of the entry that
+        corresponds to this function.  Each .got entry is 8 bytes.
+        The first three are reserved.  */
+      got_offset = (plt_index + 3) * 8;
+
+      got_offset -= GOT_BIAS;
+
+      /* Fill in the entry in the procedure linkage table.  */
+      if (! info->shared)
+       {
+         if (elf_sh64_plt_entry == NULL)
+           {
+             elf_sh64_plt_entry = (bfd_big_endian (output_bfd) ?
+                                 elf_sh64_plt_entry_be : elf_sh64_plt_entry_le);
+           }
+         memcpy (splt->contents + h->plt.offset, elf_sh64_plt_entry,
+                 elf_sh64_sizeof_plt (info));
+         movi_3shori_putval (output_bfd,
+                             (sgot->output_section->vma
+                              + sgot->output_offset
+                              + got_offset),
+                             (splt->contents + h->plt.offset
+                              + elf_sh64_plt_symbol_offset (info)));
+
+         movi_shori_putval (output_bfd,
+                            (splt->output_section->vma + splt->output_offset),
+                            (splt->contents + h->plt.offset
+                             + elf_sh64_plt_plt0_offset (info)));
+       }
+      else
+       {
+         if (elf_sh64_pic_plt_entry == NULL)
+           {
+             elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
+                                     elf_sh64_pic_plt_entry_be :
+                                     elf_sh64_pic_plt_entry_le);
+           }
+         memcpy (splt->contents + h->plt.offset, elf_sh64_pic_plt_entry,
+                 elf_sh64_sizeof_plt (info));
+         movi_shori_putval (output_bfd, got_offset,
+                            (splt->contents + h->plt.offset
+                             + elf_sh64_plt_symbol_offset (info)));
+       }
+
+      got_offset += GOT_BIAS;
+
+      movi_shori_putval (output_bfd,
+                        plt_index * sizeof (Elf64_External_Rela),
+                        (splt->contents + h->plt.offset
+                         + elf_sh64_plt_reloc_offset (info)));
+
+      /* Fill in the entry in the global offset table.  */
+      bfd_put_64 (output_bfd,
+                 (splt->output_section->vma
+                  + splt->output_offset
+                  + h->plt.offset
+                  + elf_sh64_plt_temp_offset (info)),
+                 sgot->contents + got_offset);
+
+      /* Fill in the entry in the .rela.plt section.  */
+      rel.r_offset = (sgot->output_section->vma
+                     + sgot->output_offset
+                     + got_offset);
+      rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_JMP_SLOT64);
+      rel.r_addend = 0;
+      rel.r_addend = GOT_BIAS;
+      bfd_elf64_swap_reloca_out (output_bfd, &rel,
+                               ((Elf64_External_Rela *) srel->contents
+                                + plt_index));
+
+      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+       {
+         /* Mark the symbol as undefined, rather than as defined in
+            the .plt section.  Leave the value alone.  */
+         sym->st_shndx = SHN_UNDEF;
+       }
+    }
+
+  if (h->got.offset != (bfd_vma) -1)
+    {
+      asection *sgot;
+      asection *srel;
+      Elf_Internal_Rela rel;
+
+      /* This symbol has an entry in the global offset table.  Set it
+        up.  */
+
+      sgot = bfd_get_section_by_name (dynobj, ".got");
+      srel = bfd_get_section_by_name (dynobj, ".rela.got");
+      BFD_ASSERT (sgot != NULL && srel != NULL);
+
+      rel.r_offset = (sgot->output_section->vma
+                     + sgot->output_offset
+                     + (h->got.offset &~ 1));
+
+      /* If this is a -Bsymbolic link, and the symbol is defined
+        locally, we just want to emit a RELATIVE reloc.  Likewise if
+        the symbol was forced to be local because of a version file.
+        The entry in the global offset table will already have been
+        initialized in the relocate_section function.  */
+      if (info->shared
+         && (info->symbolic || h->dynindx == -1)
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+       {
+         rel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+         rel.r_addend = (h->root.u.def.value
+                         + h->root.u.def.section->output_section->vma
+                         + h->root.u.def.section->output_offset);
+       }
+      else
+       {
+         bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+         rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_GLOB_DAT64);
+         rel.r_addend = 0;
+       }
+
+      bfd_elf64_swap_reloca_out (output_bfd, &rel,
+                                ((Elf64_External_Rela *) srel->contents
+                                 + srel->reloc_count));
+      ++srel->reloc_count;
+    }
+
+  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+    {
+      asection *s;
+      Elf_Internal_Rela rel;
+
+      /* This symbol needs a copy reloc.  Set it up.  */
+
+      BFD_ASSERT (h->dynindx != -1
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak));
+
+      s = bfd_get_section_by_name (h->root.u.def.section->owner,
+                                  ".rela.bss");
+      BFD_ASSERT (s != NULL);
+
+      rel.r_offset = (h->root.u.def.value
+                     + h->root.u.def.section->output_section->vma
+                     + h->root.u.def.section->output_offset);
+      rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_COPY64);
+      rel.r_addend = 0;
+      bfd_elf64_swap_reloca_out (output_bfd, &rel,
+                                ((Elf64_External_Rela *) s->contents
+                                 + s->reloc_count));
+      ++s->reloc_count;
+    }
+
+  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
+  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+    sym->st_shndx = SHN_ABS;
+
+  return true;
+}
+
+/* Finish up the dynamic sections.  */
+
+static boolean
+sh64_elf64_finish_dynamic_sections (output_bfd, info)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+{
+  bfd *dynobj;
+  asection *sgot;
+  asection *sdyn;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+  BFD_ASSERT (sgot != NULL);
+  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      asection *splt;
+      Elf64_External_Dyn *dyncon, *dynconend;
+
+      BFD_ASSERT (sdyn != NULL);
+
+      dyncon = (Elf64_External_Dyn *) sdyn->contents;
+      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+      for (; dyncon < dynconend; dyncon++)
+       {
+         Elf_Internal_Dyn dyn;
+         const char *name;
+         asection *s;
+
+         bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+         switch (dyn.d_tag)
+           {
+           default:
+             break;
+
+           case DT_PLTGOT:
+             name = ".got";
+             goto get_vma;
+
+           case DT_JMPREL:
+             name = ".rela.plt";
+           get_vma:
+             s = bfd_get_section_by_name (output_bfd, name);
+             BFD_ASSERT (s != NULL);
+             dyn.d_un.d_ptr = s->vma;
+             bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+             break;
+
+           case DT_PLTRELSZ:
+             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+             BFD_ASSERT (s != NULL);
+             if (s->_cooked_size != 0)
+               dyn.d_un.d_val = s->_cooked_size;
+             else
+               dyn.d_un.d_val = s->_raw_size;
+             bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+             break;
+
+           case DT_RELASZ:
+             /* My reading of the SVR4 ABI indicates that the
+                procedure linkage table relocs (DT_JMPREL) should be
+                included in the overall relocs (DT_RELA).  This is
+                what Solaris does.  However, UnixWare can not handle
+                that case.  Therefore, we override the DT_RELASZ entry
+                here to make it not include the JMPREL relocs.  Since
+                the linker script arranges for .rela.plt to follow all
+                other relocation sections, we don't have to worry
+                about changing the DT_RELA entry.  */
+             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+             if (s != NULL)
+               {
+                 if (s->_cooked_size != 0)
+                   dyn.d_un.d_val -= s->_cooked_size;
+                 else
+                   dyn.d_un.d_val -= s->_raw_size;
+               }
+             bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+             break;
+           }
+       }
+
+      /* Fill in the first entry in the procedure linkage table.  */
+      splt = bfd_get_section_by_name (dynobj, ".plt");
+      if (splt && splt->_raw_size > 0)
+       {
+         if (info->shared)
+           {
+             if (elf_sh64_pic_plt_entry == NULL)
+               {
+                 elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
+                                         elf_sh64_pic_plt_entry_be :
+                                         elf_sh64_pic_plt_entry_le);
+               }
+             memcpy (splt->contents, elf_sh64_pic_plt_entry,
+                     elf_sh64_sizeof_plt (info));
+           }
+         else
+           {
+             if (elf_sh64_plt0_entry == NULL)
+               {
+                 elf_sh64_plt0_entry = (bfd_big_endian (output_bfd) ?
+                                      elf_sh64_plt0_entry_be :
+                                      elf_sh64_plt0_entry_le);
+               }
+             memcpy (splt->contents, elf_sh64_plt0_entry, PLT_ENTRY_SIZE);
+             movi_3shori_putval (output_bfd,
+                                 sgot->output_section->vma
+                                 + sgot->output_offset,
+                                 splt->contents
+                                 + elf_sh64_plt0_gotplt_offset (info));
+           }
+
+         /* UnixWare sets the entsize of .plt to 8, although that doesn't
+            really seem like the right value.  */
+         elf_section_data (splt->output_section)->this_hdr.sh_entsize = 8;
+       }
+    }
+
+  /* Fill in the first three entries in the global offset table.  */
+  if (sgot->_raw_size > 0)
+    {
+      if (sdyn == NULL)
+       bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
+      else
+       bfd_put_64 (output_bfd,
+                   sdyn->output_section->vma + sdyn->output_offset,
+                   sgot->contents);
+      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 16);
+    }
+
+  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
+
+  return true;
+}
+
+
+#ifndef ELF_ARCH
+#define TARGET_BIG_SYM         bfd_elf64_sh64_vec
+#define TARGET_BIG_NAME                "elf64-sh64"
+#define TARGET_LITTLE_SYM      bfd_elf64_sh64l_vec
+#define TARGET_LITTLE_NAME     "elf64-sh64l"
+#define ELF_ARCH               bfd_arch_sh
+#define ELF_MACHINE_CODE       EM_SH
+#define ELF_MAXPAGESIZE                128
+
+#define elf_symbol_leading_char '_'
+#endif /* ELF_ARCH */
+
+#define bfd_elf64_bfd_reloc_type_lookup        sh_elf64_reloc_type_lookup
+#define elf_info_to_howto              sh_elf64_info_to_howto
+
+/* Note: there's no relaxation at present.  */
+
+#define elf_backend_relocate_section   sh_elf64_relocate_section
+#define bfd_elf64_bfd_get_relocated_section_contents \
+                                       sh_elf64_get_relocated_section_contents
+#define elf_backend_object_p           sh_elf64_set_mach_from_flags
+#define bfd_elf64_bfd_set_private_flags \
+                                       sh_elf64_set_private_flags
+#define bfd_elf64_bfd_copy_private_bfd_data \
+                                       sh_elf64_copy_private_data
+#define bfd_elf64_bfd_merge_private_bfd_data \
+                                       sh_elf64_merge_private_data
+#define elf_backend_fake_sections      sh64_elf64_fake_sections
+
+#define elf_backend_gc_mark_hook        sh_elf64_gc_mark_hook
+#define elf_backend_gc_sweep_hook       sh_elf64_gc_sweep_hook
+#define elf_backend_check_relocs        sh_elf64_check_relocs
+
+#define elf_backend_can_gc_sections    1
+
+#define elf_backend_get_symbol_type    sh64_elf64_get_symbol_type
+
+#define elf_backend_add_symbol_hook    sh64_elf64_add_symbol_hook
+
+#define elf_backend_link_output_symbol_hook \
+       sh64_elf64_link_output_symbol_hook
+
+#define elf_backend_final_write_processing \
+       sh64_elf64_final_write_processing
+
+#define elf_backend_create_dynamic_sections \
+                                       sh64_elf64_create_dynamic_sections
+#define bfd_elf64_bfd_link_hash_table_create \
+                                       sh64_elf64_link_hash_table_create
+#define elf_backend_adjust_dynamic_symbol \
+                                       sh64_elf64_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+                                       sh64_elf64_size_dynamic_sections
+#define elf_backend_finish_dynamic_symbol \
+                                       sh64_elf64_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+                                       sh64_elf64_finish_dynamic_sections
+
+#define elf_backend_want_got_plt       1
+#define elf_backend_plt_readonly       1
+#define elf_backend_want_plt_sym       0
+#define elf_backend_got_header_size    24
+#define elf_backend_plt_header_size    PLT_ENTRY_SIZE
+
+#include "elf64-target.h"
index d05565145c7584543c11546e3409b777f294c0d3..ad99a07fe1fc35d9f7881eb809a4a820dd590499 100644 (file)
@@ -751,6 +751,55 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MIPS_REL16",
   "BFD_RELOC_MIPS_RELGOT",
   "BFD_RELOC_MIPS_JALR",
+  "BFD_RELOC_SH_GOT_LOW16",
+  "BFD_RELOC_SH_GOT_MEDLOW16",
+  "BFD_RELOC_SH_GOT_MEDHI16",
+  "BFD_RELOC_SH_GOT_HI16",
+  "BFD_RELOC_SH_GOTPLT_LOW16",
+  "BFD_RELOC_SH_GOTPLT_MEDLOW16",
+  "BFD_RELOC_SH_GOTPLT_MEDHI16",
+  "BFD_RELOC_SH_GOTPLT_HI16",
+  "BFD_RELOC_SH_PLT_LOW16",
+  "BFD_RELOC_SH_PLT_MEDLOW16",
+  "BFD_RELOC_SH_PLT_MEDHI16",
+  "BFD_RELOC_SH_PLT_HI16",
+  "BFD_RELOC_SH_GOTOFF_LOW16",
+  "BFD_RELOC_SH_GOTOFF_MEDLOW16",
+  "BFD_RELOC_SH_GOTOFF_MEDHI16",
+  "BFD_RELOC_SH_GOTOFF_HI16",
+  "BFD_RELOC_SH_GOTPC_LOW16",
+  "BFD_RELOC_SH_GOTPC_MEDLOW16",
+  "BFD_RELOC_SH_GOTPC_MEDHI16",
+  "BFD_RELOC_SH_GOTPC_HI16",
+  "BFD_RELOC_SH_COPY64",
+  "BFD_RELOC_SH_GLOB_DAT64",
+  "BFD_RELOC_SH_JMP_SLOT64",
+  "BFD_RELOC_SH_RELATIVE64",
+  "BFD_RELOC_SH_GOT10BY4",
+  "BFD_RELOC_SH_GOT10BY8",
+  "BFD_RELOC_SH_GOTPLT10BY4",
+  "BFD_RELOC_SH_GOTPLT10BY8",
+  "BFD_RELOC_SH_GOTPLT32",
+  "BFD_RELOC_SH_SHMEDIA_CODE",
+  "BFD_RELOC_SH_IMMU5",
+  "BFD_RELOC_SH_IMMS6",
+  "BFD_RELOC_SH_IMMS6BY32",
+  "BFD_RELOC_SH_IMMU6",
+  "BFD_RELOC_SH_IMMS10",
+  "BFD_RELOC_SH_IMMS10BY2",
+  "BFD_RELOC_SH_IMMS10BY4",
+  "BFD_RELOC_SH_IMMS10BY8",
+  "BFD_RELOC_SH_IMMS16",
+  "BFD_RELOC_SH_IMMU16",
+  "BFD_RELOC_SH_IMM_LOW16",
+  "BFD_RELOC_SH_IMM_LOW16_PCREL",
+  "BFD_RELOC_SH_IMM_MEDLOW16",
+  "BFD_RELOC_SH_IMM_MEDLOW16_PCREL",
+  "BFD_RELOC_SH_IMM_MEDHI16",
+  "BFD_RELOC_SH_IMM_MEDHI16_PCREL",
+  "BFD_RELOC_SH_IMM_HI16",
+  "BFD_RELOC_SH_IMM_HI16_PCREL",
+  "BFD_RELOC_SH_PT_16",
 
   "BFD_RELOC_386_GOT32",
   "BFD_RELOC_386_PLT32",
index 56501a1357736fc7dec31af4b5c89d4a49bf294c..f3f1d265e385941e9049e712641f3a4dc39e9dd5 100644 (file)
@@ -140,12 +140,14 @@ elf32-m88k.c
 elf32-mcore.c
 elf32-mips.c
 elf32-openrisc.c
+elf32-or32.c
 elf32-pj.c
 elf32-ppc.c
 elf32-s390.c
 elf32-sh-lin.c
 elf32-sh-nbsd.c
 elf32-sh.c
+elf32-sh64.c
 elf32-sparc.c
 elf32-v850.c
 elf32-xstormy16.c
@@ -158,6 +160,7 @@ elf64-mips.c
 elf64-mmix.c
 elf64-ppc.c
 elf64-s390.c
+elf64-sh64.c
 elf64-sparc.c
 elf64-x86-64.c
 elf64.c
index b21d3d2cfdb90aafc973baacb39de2c1afc6de06..8471c0cda7e675fc6d4bb2736d111abb970c3d0f 100644 (file)
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2002-01-31 17:07+0000\n"
+"POT-Creation-Date: 2002-02-08 03:22-0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -240,45 +240,45 @@ msgstr ""
 
 #: coff-arm.c:2235
 #, c-format
-msgid "%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
 msgstr ""
 
-#: coff-arm.c:2250
+#: coff-arm.c:2250 elf32-arm.h:2287
 #, c-format
 msgid ""
-"%s: ERROR: passes floats in float registers whereas target %s uses integer "
-"registers"
+"ERROR: %s passes floats in float registers, whereas %s passes them in "
+"integer registers"
 msgstr ""
 
-#: coff-arm.c:2253
+#: coff-arm.c:2253 elf32-arm.h:2292
 #, c-format
 msgid ""
-"%s: ERROR: passes floats in integer registers whereas target %s uses float "
-"registers"
+"ERROR: %s passes floats in integer registers, whereas %s passes them in "
+"float registers"
 msgstr ""
 
 #: coff-arm.c:2268
 #, c-format
 msgid ""
-"%s: ERROR: compiled as position independent code, whereas target %s is "
+"ERROR: %s is compiled as position independent code, whereas target %s is "
 "absolute position"
 msgstr ""
 
 #: coff-arm.c:2271
 #, c-format
 msgid ""
-"%s: ERROR: compiled as absolute position code, whereas target %s is position "
-"independent"
+"ERROR: %s is compiled as absolute position code, whereas target %s is "
+"position independent"
 msgstr ""
 
-#: coff-arm.c:2300
+#: coff-arm.c:2300 elf32-arm.h:2348
 #, c-format
-msgid "Warning: %s supports interworking, whereas %s does not."
+msgid "Warning: %s supports interworking, whereas %s does not"
 msgstr ""
 
-#: coff-arm.c:2303
+#: coff-arm.c:2303 elf32-arm.h:2355
 #, c-format
-msgid "Warning: %s does not support interworking, whereas %s does."
+msgid "Warning: %s does not support interworking, whereas %s does"
 msgstr ""
 
 #: coff-arm.c:2330
@@ -330,7 +330,7 @@ msgstr ""
 msgid "uncertain calling convention for non-COFF symbol"
 msgstr ""
 
-#: coff-m68k.c:481 coff-mips.c:2431 elf32-m68k.c:2212 elf32-mips.c:9954
+#: coff-m68k.c:481 coff-mips.c:2431 elf32-m68k.c:2212 elf32-mips.c:9967
 msgid "unsupported reloc type"
 msgstr ""
 
@@ -368,7 +368,7 @@ msgstr ""
 msgid "Unrecognized reloc type 0x%x"
 msgstr ""
 
-#: coff-tic54x.c:390 coffcode.h:4868
+#: coff-tic54x.c:390 coffcode.h:4874
 #, c-format
 msgid "%s: warning: illegal symbol index %ld in relocs"
 msgstr ""
@@ -383,32 +383,32 @@ msgstr ""
 msgid "%s (%s): Section flag %s (0x%x) ignored"
 msgstr ""
 
-#: coffcode.h:2132
+#: coffcode.h:2137
 #, c-format
 msgid "Unrecognized TI COFF target id '0x%x'"
 msgstr ""
 
-#: coffcode.h:4257
+#: coffcode.h:4263
 #, c-format
 msgid "%s: warning: illegal symbol index %ld in line numbers"
 msgstr ""
 
-#: coffcode.h:4271
+#: coffcode.h:4277
 #, c-format
 msgid "%s: warning: duplicate line number information for `%s'"
 msgstr ""
 
-#: coffcode.h:4630
+#: coffcode.h:4636
 #, c-format
 msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
 msgstr ""
 
-#: coffcode.h:4761
+#: coffcode.h:4767
 #, c-format
 msgid "warning: %s: local symbol `%s' has no section"
 msgstr ""
 
-#: coffcode.h:4906
+#: coffcode.h:4912
 #, c-format
 msgid "%s: illegal relocation type %d at address 0x%lx"
 msgstr ""
@@ -568,8 +568,8 @@ msgid ""
 "      Type: %s"
 msgstr ""
 
-#: elf-hppa.h:1366 elf-hppa.h:1399 elf32-ppc.c:3062 elf32-sh.c:3201
-#: elf64-x86-64.c:1275
+#: elf-hppa.h:1366 elf-hppa.h:1399 elf32-ppc.c:3062 elf32-sh.c:4286
+#: elf64-sh64.c:1640 elf64-x86-64.c:1275
 #, c-format
 msgid ""
 "%s: warning: unresolvable relocation against symbol `%s' from %s section"
@@ -578,14 +578,14 @@ msgstr ""
 #: elf-m10200.c:463 elf-m10300.c:673 elf32-arm.h:2074 elf32-avr.c:835
 #: elf32-cris.c:1406 elf32-d10v.c:482 elf32-fr30.c:653 elf32-h8300.c:547
 #: elf32-i860.c:1048 elf32-m32r.c:1280 elf32-openrisc.c:455 elf32-v850.c:1691
-#: elf32-xstormy16.c:976 elf64-mmix.c:1164
+#: elf32-xstormy16.c:976 elf64-mmix.c:1302
 msgid "internal error: out of range error"
 msgstr ""
 
 #: elf-m10200.c:467 elf-m10300.c:677 elf32-arm.h:2078 elf32-avr.c:839
 #: elf32-cris.c:1410 elf32-d10v.c:486 elf32-fr30.c:657 elf32-h8300.c:551
-#: elf32-i860.c:1052 elf32-m32r.c:1284 elf32-mips.c:7587 elf32-openrisc.c:459
-#: elf32-v850.c:1695 elf32-xstormy16.c:980 elf64-mips.c:4464 elf64-mmix.c:1168
+#: elf32-i860.c:1052 elf32-m32r.c:1284 elf32-mips.c:7600 elf32-openrisc.c:459
+#: elf32-v850.c:1695 elf32-xstormy16.c:980 elf64-mips.c:4464 elf64-mmix.c:1306
 msgid "internal error: unsupported relocation error"
 msgstr ""
 
@@ -597,7 +597,7 @@ msgstr ""
 #: elf-m10200.c:475 elf-m10300.c:685 elf32-arm.h:2086 elf32-avr.c:847
 #: elf32-cris.c:1418 elf32-d10v.c:494 elf32-fr30.c:665 elf32-h8300.c:559
 #: elf32-i860.c:1060 elf32-m32r.c:1292 elf32-openrisc.c:467 elf32-v850.c:1715
-#: elf32-xstormy16.c:988 elf64-mmix.c:1176
+#: elf32-xstormy16.c:988 elf64-mmix.c:1314
 msgid "internal error: unknown error"
 msgstr ""
 
@@ -697,7 +697,7 @@ msgstr ""
 msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
 msgstr ""
 
-#: elf32-arm.h:1904 elf32-i386.c:1778 elf32-sh.c:3133
+#: elf32-arm.h:1904 elf32-i386.c:1782 elf32-sh.c:4198
 #, c-format
 msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
 msgstr ""
@@ -718,61 +718,38 @@ msgstr ""
 #: elf32-arm.h:2261
 #, c-format
 msgid ""
-"Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"
+"ERROR: %s is compiled for EABI version %d, whereas %s is compiled for "
+"version %d"
 msgstr ""
 
 #: elf32-arm.h:2275
 #, c-format
-msgid "Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"
-msgstr ""
-
-#: elf32-arm.h:2287
-#, c-format
-msgid ""
-"Error: %s passes floats in FP registers, whereas %s passes them in integer "
-"registers"
-msgstr ""
-
-#: elf32-arm.h:2292
-#, c-format
-msgid ""
-"Error: %s passes floats in integer registers, whereas %s passes them in FP "
-"registers"
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
 msgstr ""
 
 #: elf32-arm.h:2303
 #, c-format
-msgid "Error: %s uses VFP instructions, whereas %s uses FPA instructions"
+msgid "ERROR: %s uses VFP instructions, whereas %s uses FPA instructions"
 msgstr ""
 
 #: elf32-arm.h:2308
 #, c-format
-msgid "Error: %s uses FPA instructions, whereas %s uses VFP instructions"
+msgid "ERROR: %s uses FPA instructions, whereas %s uses VFP instructions"
 msgstr ""
 
 #: elf32-arm.h:2328
 #, c-format
-msgid "Error: %s uses software FP, whereas %s uses hardware FP"
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
 msgstr ""
 
 #: elf32-arm.h:2333
 #, c-format
-msgid "Error: %s uses hardware FP, whereas %s uses software FP"
-msgstr ""
-
-#: elf32-arm.h:2348
-#, c-format
-msgid "Warning: %s supports interworking, whereas %s does not"
-msgstr ""
-
-#: elf32-arm.h:2355
-#, c-format
-msgid "Warning: %s does not support interworking, whereas %s does"
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
 msgstr ""
 
 #. Ignore init flag - it may not be set, despite the flags field
 #. containing valid data.
-#: elf32-arm.h:2386 elf32-cris.c:2991 elf32-m68k.c:410 elf32-mips.c:3242
+#: elf32-arm.h:2386 elf32-cris.c:2991 elf32-m68k.c:410 elf32-mips.c:3255
 #, c-format
 msgid "private flags = %lx:"
 msgstr ""
@@ -781,14 +758,6 @@ msgstr ""
 msgid " [interworking enabled]"
 msgstr ""
 
-#: elf32-arm.h:2398
-msgid " [APCS-26]"
-msgstr ""
-
-#: elf32-arm.h:2400
-msgid " [APCS-32]"
-msgstr ""
-
 #: elf32-arm.h:2403
 msgid " [VFP float format]"
 msgstr ""
@@ -851,7 +820,7 @@ msgstr ""
 
 #: elf32-avr.c:843 elf32-cris.c:1414 elf32-fr30.c:661 elf32-i860.c:1056
 #: elf32-openrisc.c:463 elf32-v850.c:1699 elf32-xstormy16.c:984
-#: elf64-mmix.c:1172
+#: elf64-mmix.c:1310
 msgid "internal error: dangerous relocation"
 msgstr ""
 
@@ -930,7 +899,7 @@ msgstr ""
 msgid "%s: cannot create stub entry %s"
 msgstr ""
 
-#: elf32-hppa.c:937 elf32-hppa.c:3545
+#: elf32-hppa.c:937 elf32-hppa.c:3549
 #, c-format
 msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
 msgstr ""
@@ -954,22 +923,22 @@ msgstr ""
 msgid "Could not find relocation section for %s"
 msgstr ""
 
-#: elf32-hppa.c:2867
+#: elf32-hppa.c:2871
 #, c-format
 msgid "%s: duplicate export stub %s"
 msgstr ""
 
-#: elf32-hppa.c:3429
+#: elf32-hppa.c:3433
 #, c-format
 msgid "%s(%s+0x%lx): fixing %s"
 msgstr ""
 
-#: elf32-hppa.c:4069
+#: elf32-hppa.c:4073
 #, c-format
 msgid "%s(%s+0x%lx): cannot handle %s for %s"
 msgstr ""
 
-#: elf32-hppa.c:4408
+#: elf32-hppa.c:4412
 msgid ".got section not immediately after .plt section"
 msgstr ""
 
@@ -978,22 +947,22 @@ msgstr ""
 msgid "%s: invalid relocation type %d"
 msgstr ""
 
-#: elf32-i386.c:718 elf32-s390.c:636 elf64-s390.c:595
+#: elf32-i386.c:718 elf32-s390.c:637 elf64-s390.c:595
 #, c-format
 msgid "%s: bad symbol index: %d"
 msgstr ""
 
-#: elf32-i386.c:863 elf32-s390.c:790 elf64-ppc.c:2198 elf64-s390.c:759
+#: elf32-i386.c:863 elf32-s390.c:791 elf64-ppc.c:2198 elf64-s390.c:759
 #, c-format
 msgid "%s: bad relocation section name `%s'"
 msgstr ""
 
-#: elf32-i386.c:2069 elf32-s390.c:1951 elf64-ppc.c:4124 elf64-s390.c:1955
+#: elf32-i386.c:2073 elf32-s390.c:1956 elf64-ppc.c:4128 elf64-s390.c:1959
 #, c-format
 msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
 msgstr ""
 
-#: elf32-i386.c:2107 elf32-s390.c:1989 elf64-s390.c:1993
+#: elf32-i386.c:2111 elf32-s390.c:1994 elf64-s390.c:1997
 #, c-format
 msgid "%s(%s+0x%lx): reloc against `%s': error %d"
 msgstr ""
@@ -1068,117 +1037,117 @@ msgstr ""
 msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
 msgstr ""
 
-#: elf32-mips.c:3177
+#: elf32-mips.c:3190
 #, c-format
 msgid "%s: ISA mismatch (%d) with previous modules (%d)"
 msgstr ""
 
-#: elf32-mips.c:3200
+#: elf32-mips.c:3213
 #, c-format
 msgid "%s: ABI mismatch: linking %s module with previous %s modules"
 msgstr ""
 
-#: elf32-mips.c:3214 elf32-ppc.c:1470 elf64-ppc.c:1556 elf64-sparc.c:3027
+#: elf32-mips.c:3227 elf32-ppc.c:1470 elf64-ppc.c:1556 elf64-sparc.c:3027
 #, c-format
 msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
 msgstr ""
 
-#: elf32-mips.c:3245
+#: elf32-mips.c:3258
 msgid " [abi=O32]"
 msgstr ""
 
-#: elf32-mips.c:3247
+#: elf32-mips.c:3260
 msgid " [abi=O64]"
 msgstr ""
 
-#: elf32-mips.c:3249
+#: elf32-mips.c:3262
 msgid " [abi=EABI32]"
 msgstr ""
 
-#: elf32-mips.c:3251
+#: elf32-mips.c:3264
 msgid " [abi=EABI64]"
 msgstr ""
 
-#: elf32-mips.c:3253
+#: elf32-mips.c:3266
 msgid " [abi unknown]"
 msgstr ""
 
-#: elf32-mips.c:3255
+#: elf32-mips.c:3268
 msgid " [abi=N32]"
 msgstr ""
 
-#: elf32-mips.c:3257
+#: elf32-mips.c:3270
 msgid " [abi=64]"
 msgstr ""
 
-#: elf32-mips.c:3259
+#: elf32-mips.c:3272
 msgid " [no abi set]"
 msgstr ""
 
-#: elf32-mips.c:3262
+#: elf32-mips.c:3275
 msgid " [mips1]"
 msgstr ""
 
-#: elf32-mips.c:3264
+#: elf32-mips.c:3277
 msgid " [mips2]"
 msgstr ""
 
-#: elf32-mips.c:3266
+#: elf32-mips.c:3279
 msgid " [mips3]"
 msgstr ""
 
-#: elf32-mips.c:3268
+#: elf32-mips.c:3281
 msgid " [mips4]"
 msgstr ""
 
-#: elf32-mips.c:3270
+#: elf32-mips.c:3283
 msgid " [mips5]"
 msgstr ""
 
-#: elf32-mips.c:3272
+#: elf32-mips.c:3285
 msgid " [mips32]"
 msgstr ""
 
-#: elf32-mips.c:3274
+#: elf32-mips.c:3287
 msgid " [mips64]"
 msgstr ""
 
-#: elf32-mips.c:3276
+#: elf32-mips.c:3289
 msgid " [unknown ISA]"
 msgstr ""
 
-#: elf32-mips.c:3279
+#: elf32-mips.c:3292
 msgid " [32bitmode]"
 msgstr ""
 
-#: elf32-mips.c:3281
+#: elf32-mips.c:3294
 msgid " [not 32bitmode]"
 msgstr ""
 
-#: elf32-mips.c:4954
+#: elf32-mips.c:4967
 msgid "static procedure (no name)"
 msgstr ""
 
-#: elf32-mips.c:5572 elf64-mips.c:6694
+#: elf32-mips.c:5585 elf64-mips.c:6694
 #, c-format
 msgid "%s: illegal section name `%s'"
 msgstr ""
 
-#: elf32-mips.c:6139 elf64-mips.c:3150
+#: elf32-mips.c:6152 elf64-mips.c:3150
 msgid "not enough GOT space for local GOT entries"
 msgstr ""
 
-#: elf32-mips.c:7250 elf64-mips.c:4203
+#: elf32-mips.c:7263 elf64-mips.c:4203
 #, c-format
 msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
 msgstr ""
 
-#: elf32-mips.c:8259 elf64-mips.c:5891
+#: elf32-mips.c:8272 elf64-mips.c:5891
 #, c-format
 msgid "%s: Malformed reloc detected for section %s"
 msgstr ""
 
-#: elf32-mips.c:8337 elf64-mips.c:5969
+#: elf32-mips.c:8350 elf64-mips.c:5969
 #, c-format
 msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
 msgstr ""
@@ -1205,7 +1174,7 @@ msgstr ""
 msgid "%s: relocation %s cannot be used when making a shared object"
 msgstr ""
 
-#: elf32-ppc.c:3097 elf64-ppc.c:3716
+#: elf32-ppc.c:3097 elf64-ppc.c:3720
 #, c-format
 msgid "%s: unknown relocation type %d for symbol %s"
 msgstr ""
@@ -1221,51 +1190,103 @@ msgstr ""
 msgid "%s: Relocation %s is not yet supported for symbol %s."
 msgstr ""
 
-#: elf32-sh.c:1101
+#: elf32-sh.c:1971
 #, c-format
 msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
 msgstr ""
 
-#: elf32-sh.c:1113
+#: elf32-sh.c:1983
 #, c-format
 msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
 msgstr ""
 
-#: elf32-sh.c:1130
+#: elf32-sh.c:2000
 #, c-format
 msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
 msgstr ""
 
-#: elf32-sh.c:1145
+#: elf32-sh.c:2015
 #, c-format
 msgid "%s: 0x%lx: warning: could not find expected reloc"
 msgstr ""
 
-#: elf32-sh.c:1202
+#: elf32-sh.c:2072
 #, c-format
 msgid "%s: 0x%lx: warning: symbol in unexpected section"
 msgstr ""
 
-#: elf32-sh.c:1323
+#: elf32-sh.c:2193
 #, c-format
 msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
 msgstr ""
 
-#: elf32-sh.c:1332
+#: elf32-sh.c:2202
 #, c-format
 msgid "%s: 0x%lx: warning: bad count"
 msgstr ""
 
-#: elf32-sh.c:1741 elf32-sh.c:2132
+#: elf32-sh.c:2611 elf32-sh.c:3002
 #, c-format
 msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
 msgstr ""
 
-#: elf32-sh.c:3267
+#: elf32-sh.c:4146 elf64-sh64.c:1557
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr ""
+
+#: elf32-sh.c:4357
 #, c-format
 msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
 msgstr ""
 
+#: elf32-sh64.c:211 elf64-sh64.c:2391
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr ""
+
+#: elf32-sh64.c:214 elf64-sh64.c:2394
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr ""
+
+#: elf32-sh64.c:216 elf64-sh64.c:2396
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr ""
+
+#: elf32-sh64.c:447 elf64-sh64.c:2973
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr ""
+
+#: elf32-sh64.c:530
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr ""
+
+#: elf32-sh64.c:533
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr ""
+
+#: elf32-sh64.c:551
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr ""
+
+#: elf32-sh64.c:600 elf64-sh64.c:1684
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr ""
+
+#: elf32-sh64.c:684
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr ""
+
+#: elf32-sh64.c:745
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr ""
+
 #: elf32-sparc.c:1554 elf64-sparc.c:2280
 #, c-format
 msgid "%s: probably compiled without -fPIC?"
@@ -1371,36 +1392,55 @@ msgstr ""
 msgid "stub entry for %s cannot load .plt, dp offset = %ld"
 msgstr ""
 
-#: elf64-mmix.c:1271
+#: elf64-mmix.c:1002
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%"
+"08lx\n"
+msgstr ""
+
+#: elf64-mmix.c:1386
+#, c-format
+msgid ""
+"%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr ""
+
+#: elf64-mmix.c:1391
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr ""
+
+#: elf64-mmix.c:1435
 #, c-format
 msgid "%s: register relocation against non-register symbol: (unknown) in %s"
 msgstr ""
 
-#: elf64-mmix.c:1276
+#: elf64-mmix.c:1440
 #, c-format
 msgid "%s: register relocation against non-register symbol: %s in %s"
 msgstr ""
 
-#: elf64-mmix.c:1312
+#: elf64-mmix.c:1477
 #, c-format
 msgid "%s: directive LOCAL valid only with a register or absolute value"
 msgstr ""
 
-#: elf64-mmix.c:1340
+#: elf64-mmix.c:1505
 #, c-format
 msgid ""
 "%s: LOCAL directive: Register $%ld is not a local register.  First global "
 "register is $%ld."
 msgstr ""
 
-#: elf64-mmix.c:1615
+#: elf64-mmix.c:1967
 #, c-format
 msgid ""
 "%s: Error: multiple definition of `%s'; start of %s is set in a earlier "
 "linked file\n"
 msgstr ""
 
-#: elf64-mmix.c:1674
+#: elf64-mmix.c:2026
 msgid "Register section has contents\n"
 msgstr ""
 
@@ -1414,21 +1454,21 @@ msgstr ""
 msgid "%s: compiled for a little endian system and target is big endian"
 msgstr ""
 
-#: elf64-ppc.c:3350
+#: elf64-ppc.c:3354
 #, c-format
 msgid "linkage table error against `%s'"
 msgstr ""
 
-#: elf64-ppc.c:3432
+#: elf64-ppc.c:3436
 msgid "stub section size doesn't match calculated size"
 msgstr ""
 
-#: elf64-ppc.c:4061
+#: elf64-ppc.c:4065
 #, c-format
 msgid "%s: Relocation %s is not supported for symbol %s."
 msgstr ""
 
-#: elf64-ppc.c:4105
+#: elf64-ppc.c:4109
 #, c-format
 msgid "%s: error: relocation %s not a multiple of 4"
 msgstr ""
@@ -1658,142 +1698,142 @@ msgstr ""
 msgid "%s: access beyond end of merged section (%ld + %ld)"
 msgstr ""
 
-#: mmo.c:460
+#: mmo.c:459
 #, c-format
 msgid "%s: No core to allocate section name %s\n"
 msgstr ""
 
-#: mmo.c:537
+#: mmo.c:535
 #, c-format
 msgid "%s: No core to allocate a symbol %d bytes long\n"
 msgstr ""
 
-#: mmo.c:1190
+#: mmo.c:1188
 #, c-format
 msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
 msgstr ""
 
-#: mmo.c:1336
+#: mmo.c:1334
 #, c-format
 msgid ""
 "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name "
 "starting with `%s'\n"
 msgstr ""
 
-#: mmo.c:1571
+#: mmo.c:1569
 #, c-format
 msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
 msgstr ""
 
-#: mmo.c:1581
+#: mmo.c:1579
 #, c-format
 msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
 msgstr ""
 
-#: mmo.c:1617
+#: mmo.c:1615
 #, c-format
 msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
 msgstr ""
 
-#: mmo.c:1663
+#: mmo.c:1661
 #, c-format
 msgid ""
 "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
 msgstr ""
 
-#: mmo.c:1702
+#: mmo.c:1700
 #, c-format
 msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
 msgstr ""
 
-#: mmo.c:1711
+#: mmo.c:1709
 #, c-format
 msgid ""
 "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
 msgstr ""
 
-#: mmo.c:1734
+#: mmo.c:1732
 #, c-format
 msgid ""
 "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d "
 "for lop_fixrx\n"
 msgstr ""
 
-#: mmo.c:1757
+#: mmo.c:1755
 #, c-format
 msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
 msgstr ""
 
-#: mmo.c:1777
+#: mmo.c:1775
 #, c-format
 msgid ""
 "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
 msgstr ""
 
-#: mmo.c:1790
+#: mmo.c:1788
 #, c-format
 msgid ""
 "%s: invalid mmo file: file name for number %d was not specified before use\n"
 msgstr ""
 
-#: mmo.c:1896
+#: mmo.c:1894
 #, c-format
 msgid ""
 "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
 msgstr ""
 
-#: mmo.c:1932
+#: mmo.c:1930
 #, c-format
 msgid "%s: invalid mmo file: lop_end not last item in file\n"
 msgstr ""
 
-#: mmo.c:1945
+#: mmo.c:1943
 #, c-format
 msgid ""
 "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras "
 "to the preceding lop_stab (%ld)\n"
 msgstr ""
 
-#: mmo.c:2610
+#: mmo.c:2608
 #, c-format
 msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
 msgstr ""
 
-#: mmo.c:2898
+#: mmo.c:2896
 #, c-format
 msgid ""
 "%s: Bad symbol definition: `Main' set to %s rather than the start address %"
 "s\n"
 msgstr ""
 
-#: mmo.c:2932
+#: mmo.c:2930
 #, c-format
 msgid ""
 "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: "
 "%d.  Only `Main' will be emitted.\n"
 msgstr ""
 
-#: mmo.c:2977
+#: mmo.c:2975
 #, c-format
 msgid "%s: internal error, symbol table changed size from %d to %d words\n"
 msgstr ""
 
-#: mmo.c:3032
+#: mmo.c:3030
 #, c-format
 msgid "%s: internal error, internal register section %s had contents\n"
 msgstr ""
 
-#: mmo.c:3084
+#: mmo.c:3082
 #, c-format
 msgid "%s: no initialized registers; section length 0\n"
 msgstr ""
 
-#: mmo.c:3090
+#: mmo.c:3088
 #, c-format
 msgid "%s: too many initialized registers; section length %ld\n"
 msgstr ""
 
-#: mmo.c:3095
+#: mmo.c:3093
 #, c-format
 msgid ""
 "%s: invalid start address for initialized registers of length %ld: 0x%lx%"
index db43bef33b06204f1848dc9ffe6d7ef00ab71e2f..40e07a6a2d5b47ad6da7d92b1bc79de2ba5b11d3 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD support for handling relocation entries.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -2043,6 +2043,107 @@ ENUMX
 ENUMX
   BFD_RELOC_MIPS_JALR
 COMMENT
+COMMENT
+ENUMX
+  BFD_RELOC_SH_GOT_LOW16
+ENUMX
+  BFD_RELOC_SH_GOT_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_GOT_MEDHI16
+ENUMX
+  BFD_RELOC_SH_GOT_HI16
+ENUMX
+  BFD_RELOC_SH_GOTPLT_LOW16
+ENUMX
+  BFD_RELOC_SH_GOTPLT_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_GOTPLT_MEDHI16
+ENUMX
+  BFD_RELOC_SH_GOTPLT_HI16
+ENUMX
+  BFD_RELOC_SH_PLT_LOW16
+ENUMX
+  BFD_RELOC_SH_PLT_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_PLT_MEDHI16
+ENUMX
+  BFD_RELOC_SH_PLT_HI16
+ENUMX
+  BFD_RELOC_SH_GOTOFF_LOW16
+ENUMX
+  BFD_RELOC_SH_GOTOFF_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_GOTOFF_MEDHI16
+ENUMX
+  BFD_RELOC_SH_GOTOFF_HI16
+ENUMX
+  BFD_RELOC_SH_GOTPC_LOW16
+ENUMX
+  BFD_RELOC_SH_GOTPC_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_GOTPC_MEDHI16
+ENUMX
+  BFD_RELOC_SH_GOTPC_HI16
+ENUMX
+  BFD_RELOC_SH_COPY64
+ENUMX
+  BFD_RELOC_SH_GLOB_DAT64
+ENUMX
+  BFD_RELOC_SH_JMP_SLOT64
+ENUMX
+  BFD_RELOC_SH_RELATIVE64
+ENUMX
+  BFD_RELOC_SH_GOT10BY4
+ENUMX
+  BFD_RELOC_SH_GOT10BY8
+ENUMX
+  BFD_RELOC_SH_GOTPLT10BY4
+ENUMX
+  BFD_RELOC_SH_GOTPLT10BY8
+ENUMX
+  BFD_RELOC_SH_GOTPLT32
+COMMENT
+ENUMX
+  BFD_RELOC_SH_SHMEDIA_CODE
+ENUMX
+  BFD_RELOC_SH_IMMU5
+ENUMX
+  BFD_RELOC_SH_IMMS6
+ENUMX
+  BFD_RELOC_SH_IMMS6BY32
+ENUMX
+  BFD_RELOC_SH_IMMU6
+ENUMX
+  BFD_RELOC_SH_IMMS10
+ENUMX
+  BFD_RELOC_SH_IMMS10BY2
+ENUMX
+  BFD_RELOC_SH_IMMS10BY4
+ENUMX
+  BFD_RELOC_SH_IMMS10BY8
+ENUMX
+  BFD_RELOC_SH_IMMS16
+ENUMX
+  BFD_RELOC_SH_IMMU16
+ENUMX
+  BFD_RELOC_SH_IMM_LOW16
+ENUMX
+  BFD_RELOC_SH_IMM_LOW16_PCREL
+ENUMX
+  BFD_RELOC_SH_IMM_MEDLOW16
+ENUMX
+  BFD_RELOC_SH_IMM_MEDLOW16_PCREL
+ENUMX
+  BFD_RELOC_SH_IMM_MEDHI16
+ENUMX
+  BFD_RELOC_SH_IMM_MEDHI16_PCREL
+ENUMX
+  BFD_RELOC_SH_IMM_HI16
+ENUMX
+  BFD_RELOC_SH_IMM_HI16_PCREL
+ENUMX
+  BFD_RELOC_SH_PT_16
+COMMENT
 ENUMDOC
   MIPS ELF relocations.
 
index b4fba962395cb514f7a159a2e83c4f7cf3323e4a..78b4bbb107009f5b3e247a06544c40a40f7a17c3 100644 (file)
@@ -682,6 +682,10 @@ extern const bfd_target ptrace_core_vec;
 extern const bfd_target sco5_core_vec;
 extern const bfd_target trad_core_vec;
 
+extern const bfd_target bfd_elf32_sh64_vec;
+extern const bfd_target bfd_elf32_sh64l_vec;
+extern const bfd_target bfd_elf64_sh64_vec;
+extern const bfd_target bfd_elf64_sh64l_vec;
 static const bfd_target * const _bfd_target_vector[] = {
 
 #ifdef SELECT_VECS