+/*****************************************************************************/
+
+/* s3_s7: backend hooks. */
+static void
+_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
+ else
+ return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
+}
+
+static bfd_boolean
+_bfd_score_elf_relocate_section (bfd *output_bfd,
+ 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)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_relocate_section (output_bfd,
+ info, input_bfd, input_section, contents, relocs,
+ local_syms, local_sections);
+ else
+ return s7_bfd_score_elf_relocate_section (output_bfd,
+ info, input_bfd, input_section, contents, relocs,
+ local_syms, local_sections);
+}
+
+static bfd_boolean
+_bfd_score_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
+ else
+ return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
+}
+
+static bfd_boolean
+_bfd_score_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
+ secp, valp);
+ else
+ return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
+ secp, valp);
+}
+
+static void
+_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_symbol_processing (abfd, asym);
+ else
+ return s7_bfd_score_elf_symbol_processing (abfd, asym);
+}
+
+static int
+_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* If link a empty .o, then this filed is NULL. */
+ if (info->input_bfds == NULL)
+ {
+ /* If we see a common symbol, which implies a relocatable link, then
+ if a symbol was small common in an input file, mark it as small
+ common in the output file. */
+ if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
+ sym->st_shndx = SHN_SCORE_SCOMMON;
+ return 1;
+ }
+
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
+ else
+ return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
+}
+
+static bfd_boolean
+_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
+ else
+ return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
+}
+
+static bfd_boolean
+_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
+ else
+ return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
+}
+
+static bfd_boolean
+_bfd_score_elf_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_always_size_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_always_size_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_size_dynamic_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_size_dynamic_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
+ else
+ return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
+ else
+ return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
+}
+
+static bfd_boolean
+_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
+ else
+ return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
+}
+
+static bfd_boolean
+_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_section_processing (abfd, hdr);
+ else
+ return s7_bfd_score_elf_section_processing (abfd, hdr);
+}
+
+static bfd_boolean
+_bfd_score_elf_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ asection *sec, bfd_byte *contents)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
+ else
+ return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
+}
+
+static void
+_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
+ else
+ return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
+}
+
+static void
+_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *entry,
+ bfd_boolean force_local)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
+ else
+ return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
+}
+
+static bfd_boolean
+_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_discard_info (abfd, cookie, info);
+ else
+ return s7_bfd_score_elf_discard_info (abfd, cookie, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_ignore_discarded_relocs (asection *sec)
+{
+ if (bfd_get_mach (sec->owner) == bfd_mach_score3)
+ return s3_bfd_score_elf_ignore_discarded_relocs (sec);
+ else
+ return s7_bfd_score_elf_ignore_discarded_relocs (sec);
+}
+
+static asection *
+_bfd_score_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
+ else
+ return s7_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_grok_prstatus (abfd, note);
+ else
+ return s7_bfd_score_elf_grok_prstatus (abfd, note);
+}
+
+static bfd_boolean
+_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_grok_psinfo (abfd, note);
+ else
+ return s7_bfd_score_elf_grok_psinfo (abfd, note);
+}
+
+static reloc_howto_type *
+elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ /* s3: NOTE!!!
+ gas will call elf32_score_reloc_type_lookup, and don't write elf file.
+ So just using score3, but we don't know ld will call this or not.
+ If so, this way can't work. */
+
+ if (score3)
+ return s3_elf32_score_reloc_type_lookup (abfd, code);
+ else
+ return s7_elf32_score_reloc_type_lookup (abfd, code);
+}
+
+static struct bfd_link_hash_table *
+elf32_score_link_hash_table_create (bfd *abfd)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_elf32_score_link_hash_table_create (abfd);
+ else
+ return s7_elf32_score_link_hash_table_create (abfd);
+}
+
+static bfd_boolean
+elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_elf32_score_print_private_bfd_data (abfd, ptr);
+ else
+ return s7_elf32_score_print_private_bfd_data (abfd, ptr);
+}
+
+static bfd_boolean
+elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ if (bfd_get_mach (obfd) == bfd_mach_score3)
+ return s3_elf32_score_merge_private_bfd_data (ibfd, obfd);
+ else
+ return s7_elf32_score_merge_private_bfd_data (ibfd, obfd);
+}
+
+static bfd_boolean
+elf32_score_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_elf32_score_new_section_hook (abfd, sec);
+ else
+ return s7_elf32_score_new_section_hook (abfd, sec);
+}
+
+
+/* s3_s7: don't need to split. */
+
+/* Set the right machine number. */
+static bfd_boolean
+_bfd_score_elf_score_object_p (bfd * abfd)
+{
+ int e_set = bfd_mach_score7;
+
+ if (elf_elfheader (abfd)->e_machine == EM_SCORE)
+ {
+ int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
+ switch (e_mach)
+ {
+ /* Set default target is score7. */
+ default:
+ case E_SCORE_MACH_SCORE7:
+ e_set = bfd_mach_score7;
+ break;
+
+ case E_SCORE_MACH_SCORE3:
+ e_set = bfd_mach_score3;
+ break;
+ }
+ }
+
+ return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
+}
+
+bfd_boolean
+_bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
+{
+ return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
+}
+
+/*****************************************************************************/
+