/* SuperH SH64-specific support for 32-bit ELF
   Copyright (C) 2000-2017 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#define SH64_ELF

#include "sysdep.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "../opcodes/sh64-opc.h"
#include "elf32-sh64.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 bfd_boolean sh64_elf_new_section_hook
  (bfd *, asection *);
static bfd_boolean sh64_elf_copy_private_data
  (bfd *, bfd *);
static bfd_boolean sh64_elf_merge_private_data
  (bfd *, struct bfd_link_info *);
static bfd_boolean sh64_elf_fake_sections
  (bfd *, Elf_Internal_Shdr *, asection *);
static bfd_boolean sh64_elf_set_private_flags
  (bfd *, flagword);
static bfd_boolean sh64_elf_set_mach_from_flags
  (bfd *);
static bfd_boolean shmedia_prepare_reloc
  (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
   const Elf_Internal_Rela *, bfd_vma *);
static int sh64_elf_get_symbol_type
  (Elf_Internal_Sym *, int);
static bfd_boolean sh64_elf_add_symbol_hook
  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
   flagword *, asection **, bfd_vma *);
static int sh64_elf_link_output_symbol_hook
  (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
   struct elf_link_hash_entry *);
static bfd_boolean sh64_backend_section_from_shdr
  (bfd *, Elf_Internal_Shdr *, const char *, int);
static void sh64_elf_final_write_processing
  (bfd *, bfd_boolean);
static bfd_boolean sh64_bfd_elf_copy_private_section_data
  (bfd *, asection *, bfd *, asection *);
static void sh64_find_section_for_address
  (bfd *, asection *, void *);

/* 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_merge_symbol_attribute	sh64_elf_merge_symbol_attribute
#define elf_backend_final_write_processing 	sh64_elf_final_write_processing
#define elf_backend_section_from_shdr		sh64_backend_section_from_shdr
#define elf_backend_special_sections		sh64_elf_special_sections
#define elf_backend_section_flags		sh64_elf_section_flags

#define bfd_elf32_new_section_hook		sh64_elf_new_section_hook

/* 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) \
  ((void) f, (void) h, (void) i, TRUE)

#define GOT_BIAS (-((long)-32768))
#define INCLUDE_SHMEDIA
#define SH_TARGET_ALREADY_DEFINED
#include "elf32-sh.c"

/* Tack some extra info on struct bfd_elf_section_data.  */

static bfd_boolean
sh64_elf_new_section_hook (bfd *abfd, asection *sec)
{
  if (!sec->used_by_bfd)
    {
      struct _sh64_elf_section_data *sdata;
      bfd_size_type amt = sizeof (*sdata);

      sdata = bfd_zalloc (abfd, amt);
      if (sdata == NULL)
	return FALSE;
      sec->used_by_bfd = sdata;
    }

  return _bfd_elf_new_section_hook (abfd, sec);
}

/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
   through SHT_SH5_CR_SORTED on a sorted .cranges section.  */

bfd_boolean
sh64_elf_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
			Elf_Internal_Shdr *elf_section_hdr,
			asection *asect)
{
  if (sh64_elf_section_data (asect)->sh64_info != NULL)
    elf_section_hdr->sh_flags
      |= sh64_elf_section_data (asect)->sh64_info->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 bfd_boolean
sh64_elf_set_mach_from_flags (bfd *abfd)
{
  flagword flags = elf_elfheader (abfd)->e_flags;

  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;
    }

  return TRUE;
}

static bfd_boolean
sh64_elf_section_flags (flagword *flags,
			const Elf_Internal_Shdr *hdr)
{
  if (hdr->bfd_section == NULL)
    return FALSE;

  if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
    *flags |= SEC_DEBUGGING;

  return TRUE;
}

static bfd_boolean
sh64_elf_copy_private_data (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 _bfd_elf_copy_private_bfd_data (ibfd, obfd);
}

static bfd_boolean
sh64_elf_merge_private_data (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  flagword old_flags, new_flags;

  if (! _bfd_generic_verify_endian_match (ibfd, info))
    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)
	/* xgettext:c-format */
	msg = _("%B: compiled as 32-bit object and %B is 64-bit");
      else if (bfd_get_arch_size (ibfd) == 64
	       && bfd_get_arch_size (obfd) == 32)
	/* xgettext:c-format */
	msg = _("%B: compiled as 64-bit object and %B is 32-bit");
      else
	/* xgettext:c-format */
	msg = _("%B: object size does not match that of target %B");

      _bfd_error_handler (msg, ibfd, 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
	("%B: uses non-SH64 instructions while previous modules"
	 " use SH64 instructions",
	 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 bfd_section_from_shdr finds a section with an unknown
   type.

   We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */

bfd_boolean
sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
				const char *name, int shindex)
{
  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, shindex))
    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.  */

bfd_boolean
sh64_bfd_elf_copy_private_section_data (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)->sh64_info;
  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_info = sh64_sec_data;
    }

  return TRUE;
}

/* Function to keep SH64 specific file flags.  */

static bfd_boolean
sh64_elf_set_private_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_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 bfd_boolean
sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
			  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
      && is_elf_hash_table (info->hash))
    {
      struct elf_link_hash_entry *h;

      /* For relocatable 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
	= bfd_link_relocatable (info) || 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.  */
	  struct bfd_link_hash_entry *bh = NULL;
	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

	  if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
						  flags, *secp, *valp,
						  *namep, FALSE,
						  bed->collect, &bh))
	    {
	      free (dl_name);
	      return FALSE;
	    }

	  h = (struct elf_link_hash_entry *) bh;
	  h->non_elf = 0;
	  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
	  || ((bfd_link_relocatable (info) || info->emitrelocations)
	      && h->root.type != bfd_link_hash_undefined)
	  || (! bfd_link_relocatable (info) && !info->emitrelocations
	      && h->root.type != bfd_link_hash_indirect))
	{
	  /* Make sure we don't get confused on invalid input.  */
	  _bfd_error_handler
	    (_("%B: encountered datalabel symbol in input"), 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.  */

static int
sh64_elf_link_output_symbol_hook (struct bfd_link_info *info,
				  const char *cname,
				  Elf_Internal_Sym *sym,
				  asection *input_sec ATTRIBUTE_UNUSED,
				  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
{
  char *name = (char *) cname;

  if (bfd_link_relocatable (info) || info->emitrelocations)
    {
      if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
	name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
    }

  return 1;
}

/* 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 bfd_boolean
shmedia_prepare_reloc (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);
	  }
	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
		  (_("%B: GAS error: unexpected PTB insn with R_SH_PT_16"),
		   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
	/* xgettext:c-format */
	(_("%B: error: unaligned relocation type %d at %#Lx reloc %#Lx"),
	 input_section->owner, (int) ELF32_R_TYPE (rel->r_info),
	 rel->r_offset, *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 (bfd *abfd ATTRIBUTE_UNUSED,
			       asection *section, void *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;

  size = section->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 (bfd *abfd,
				 bfd_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)->sh64_info->cranges_growth) != 0)
    {
      bfd_vma incoming_cranges_size
	= cranges->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
	    (_("%B: could not write out added .cranges entries"), 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,
			     &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->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)
		     ? _bfd_sh64_crange_qsort_cmpb
		     : _bfd_sh64_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
		(_("%B: could not write out sorted .cranges entries"), abfd);
	    }
	}
    }
}

/* Merge non visibility st_other attribute when the symbol comes from
   a dynamic object.  */
static void
sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
				 const Elf_Internal_Sym *isym,
				 bfd_boolean definition,
				 bfd_boolean dynamic ATTRIBUTE_UNUSED)
{
  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
    {
      unsigned char other;

      /* Take the balance of OTHER from the definition.  */
      other = (definition ? isym->st_other : h->other);
      other &= ~ ELF_ST_VISIBILITY (-1);
      h->other = other | ELF_ST_VISIBILITY (h->other);
    }

  return;
}

static const struct bfd_elf_special_section sh64_elf_special_sections[] =
{
  { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
  { NULL,                       0, 0, 0,            0 }
};

#undef	TARGET_BIG_SYM
#define	TARGET_BIG_SYM		sh64_elf32_vec
#undef	TARGET_BIG_NAME
#define	TARGET_BIG_NAME		"elf32-sh64"
#undef	TARGET_LITTLE_SYM
#define	TARGET_LITTLE_SYM	sh64_elf32_le_vec
#undef	TARGET_LITTLE_NAME
#define	TARGET_LITTLE_NAME	"elf32-sh64l"

#include "elf32-target.h"

/* NetBSD support.  */
#undef	TARGET_BIG_SYM
#define	TARGET_BIG_SYM		sh64_elf32_nbsd_vec
#undef	TARGET_BIG_NAME
#define	TARGET_BIG_NAME		"elf32-sh64-nbsd"
#undef	TARGET_LITTLE_SYM
#define	TARGET_LITTLE_SYM	sh64_elf32_nbsd_le_vec
#undef	TARGET_LITTLE_NAME
#define	TARGET_LITTLE_NAME	"elf32-sh64l-nbsd"
#undef	ELF_MAXPAGESIZE
#define	ELF_MAXPAGESIZE		0x10000
#undef	ELF_COMMONPAGESIZE
#undef	elf_symbol_leading_char
#define	elf_symbol_leading_char	0
#undef	elf32_bed
#define	elf32_bed		elf32_sh64_nbsd_bed

#include "elf32-target.h"

/* Linux support.  */
#undef	TARGET_BIG_SYM
#define	TARGET_BIG_SYM		sh64_elf32_linux_be_vec
#undef	TARGET_BIG_NAME
#define	TARGET_BIG_NAME		"elf32-sh64big-linux"
#undef	TARGET_LITTLE_SYM
#define	TARGET_LITTLE_SYM	sh64_elf32_linux_vec
#undef	TARGET_LITTLE_NAME
#define	TARGET_LITTLE_NAME	"elf32-sh64-linux"
#undef	elf32_bed
#define	elf32_bed		elf32_sh64_lin_bed
#undef	ELF_COMMONPAGESIZE
#define	ELF_COMMONPAGESIZE	0x1000

#include "elf32-target.h"

