aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog337
-rw-r--r--bfd/Makefile.am12
-rw-r--r--bfd/Makefile.in20
-rw-r--r--bfd/archures.c1
-rw-r--r--bfd/bfd-in2.h50
-rw-r--r--bfd/config.bfd9
-rwxr-xr-xbfd/configure43
-rw-r--r--bfd/configure.in11
-rw-r--r--bfd/cpu-sh.c17
-rw-r--r--bfd/doc/Makefile.in6
-rw-r--r--bfd/elf32-sh.c1410
-rw-r--r--bfd/elf32-sh64.c983
-rw-r--r--bfd/elf64-sh64.c4193
-rw-r--r--bfd/libbfd.h49
-rw-r--r--bfd/po/SRC-POTFILES.in3
-rw-r--r--bfd/po/bfd.pot342
-rw-r--r--bfd/reloc.c103
-rw-r--r--bfd/targets.c4
18 files changed, 7410 insertions, 183 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d734832..0d713d6 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 9f744c3..18438b3 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -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 \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 5ea4b0f..98c3435 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -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 \
diff --git a/bfd/archures.c b/bfd/archures.c
index 68057a4..1caac7f 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index b23955d..2692b00 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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 */
diff --git a/bfd/config.bfd b/bfd/config.bfd
index fc77461..253e2c4 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -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
diff --git a/bfd/configure b/bfd/configure
index 3a324d5..0dde688 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -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
diff --git a/bfd/configure.in b/bfd/configure.in
index a640718..c2dc8d5 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -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" ;;
diff --git a/bfd/cpu-sh.c b/bfd/cpu-sh.c
index 054eb16..30cd141 100644
--- a/bfd/cpu-sh.c
+++ b/bfd/cpu-sh.c
@@ -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 =
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index 698d76f..e0ce81f 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -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)
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 1a71191..150d912 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -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;
}
+#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
index 0000000..561c7af
--- /dev/null
+++ b/bfd/elf32-sh64.c
@@ -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
index 0000000..143a560
--- /dev/null
+++ b/bfd/elf64-sh64.c
@@ -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;
+}
+
+/* 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"
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index d055651..ad99a07 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
index 56501a1..f3f1d26 100644
--- a/bfd/po/SRC-POTFILES.in
+++ b/bfd/po/SRC-POTFILES.in
@@ -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
diff --git a/bfd/po/bfd.pot b/bfd/po/bfd.pot
index b21d3d2..8471c0c 100644
--- a/bfd/po/bfd.pot
+++ b/bfd/po/bfd.pot
@@ -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%"
diff --git a/bfd/reloc.c b/bfd/reloc.c
index db43bef..40e07a6 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -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.
diff --git a/bfd/targets.c b/bfd/targets.c
index b4fba96..78b4bbb 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -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