/* 32-bit ELF support for S+core.
   Copyright (C) 2006-2022 Free Software Foundation, Inc.
   Contributed by
   Brain.lin (brain.lin@sunplusct.com)
   Mei Ligang (ligang@sunnorth.com.cn)
   Pei-Lin Tsai (pltsai@sunplus.com)

   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.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "libiberty.h"
#include "elf-bfd.h"
#include "elf/score.h"
#include "elf/common.h"
#include "elf/internal.h"
#include "hashtab.h"
#include "elf32-score.h"


int score3 = 0;
int score7 = 1;

/* The SCORE ELF linker needs additional information for each symbol in
   the global hash table.  */
struct score_elf_link_hash_entry
{
  struct elf_link_hash_entry root;

  /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol.  */
  unsigned int possibly_dynamic_relocs;

  /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section.  */
  bool readonly_reloc;

  /* We must not create a stub for a symbol that has relocations related to
     taking the function's address, i.e. any but R_SCORE_CALL15 ones.  */
  bool no_fn_stub;

  /* Are we forced local?  This will only be set if we have converted
     the initial global GOT entry to a local GOT entry.  */
  bool forced_local;
};

/* Traverse a score ELF linker hash table.  */
#define score_elf_link_hash_traverse(table, func, info) \
  (elf_link_hash_traverse					\
   ((table),							\
    (bool (*) (struct elf_link_hash_entry *, void *)) (func),	\
    (info)))

/* This structure is used to hold .got entries while estimating got sizes.  */
struct score_got_entry
{
  /* The input bfd in which the symbol is defined.  */
  bfd *abfd;
  /* The index of the symbol, as stored in the relocation r_info, if
     we have a local symbol; -1 otherwise.  */
  long symndx;
  union
  {
    /* If abfd == NULL, an address that must be stored in the got.  */
    bfd_vma address;
    /* If abfd != NULL && symndx != -1, the addend of the relocation
       that should be added to the symbol value.  */
    bfd_vma addend;
    /* If abfd != NULL && symndx == -1, the hash table entry
       corresponding to a global symbol in the got (or, local, if
       h->forced_local).  */
    struct score_elf_link_hash_entry *h;
  } d;

  /* The offset from the beginning of the .got section to the entry
     corresponding to this symbol+addend.  If it's a global symbol
     whose offset is yet to be decided, it's going to be -1.  */
  long gotidx;
};

/* This structure is passed to score_elf_sort_hash_table_f when sorting
   the dynamic symbols.  */

struct score_elf_hash_sort_data
{
  /* The symbol in the global GOT with the lowest dynamic symbol table index.  */
  struct elf_link_hash_entry *low;
  /* The least dynamic symbol table index corresponding to a symbol with a GOT entry.  */
  long min_got_dynindx;
  /* The greatest dynamic symbol table index corresponding to a symbol
     with a GOT entry that is not referenced (e.g., a dynamic symbol
     with dynamic relocations pointing to it from non-primary GOTs).  */
  long max_unref_got_dynindx;
  /* The greatest dynamic symbol table index not corresponding to a
     symbol without a GOT entry.  */
  long max_non_got_dynindx;
};

struct score_got_info
{
  /* The global symbol in the GOT with the lowest index in the dynamic
     symbol table.  */
  struct elf_link_hash_entry *global_gotsym;
  /* The number of global .got entries.  */
  unsigned int global_gotno;
  /* The number of local .got entries.  */
  unsigned int local_gotno;
  /* The number of local .got entries we have used.  */
  unsigned int assigned_gotno;
  /* A hash table holding members of the got.  */
  struct htab *got_entries;
  /* In multi-got links, a pointer to the next got (err, rather, most
     of the time, it points to the previous got).  */
  struct score_got_info *next;
};

/* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal.  */
struct _score_elf_section_data
{
  struct bfd_elf_section_data elf;
  union
  {
    struct score_got_info *got_info;
    bfd_byte *tdata;
  }
  u;
};

#define score_elf_section_data(sec) \
  ((struct _score_elf_section_data *) elf_section_data (sec))

/* The size of a symbol-table entry.  */
#define SCORE_ELF_SYM_SIZE(abfd)  \
  (get_elf_backend_data (abfd)->s->sizeof_sym)

/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
   from smaller values.  Start with zero, widen, *then* decrement.  */
#define MINUS_ONE (((bfd_vma)0) - 1)
#define MINUS_TWO (((bfd_vma)0) - 2)

#define PDR_SIZE 32


/* The number of local .got entries we reserve.  */
#define SCORE_RESERVED_GOTNO (2)
#define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"

/* The offset of $gp from the beginning of the .got section.  */
#define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
/* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp.  */
#define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)

#define SCORE_ELF_STUB_SECTION_NAME  (".SCORE.stub")
#define SCORE_FUNCTION_STUB_SIZE (16)

#define STUB_LW      0xc3bcc010     /* lw r29, [r28, -0x3ff0]  */
#define STUB_MOVE    0x8363bc56     /* mv r27, r3  */
#define STUB_LI16    0x87548000     /* ori r26, .dynsym_index  */
#define STUB_BRL     0x801dbc09     /* brl r29  */

#define SCORE_ELF_GOT_SIZE(abfd)   \
  (get_elf_backend_data (abfd)->s->arch_size / 8)

#define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
	(_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))

/* The size of an external dynamic table entry.  */
#define SCORE_ELF_DYN_SIZE(abfd) \
  (get_elf_backend_data (abfd)->s->sizeof_dyn)

/* The size of an external REL relocation.  */
#define SCORE_ELF_REL_SIZE(abfd) \
  (get_elf_backend_data (abfd)->s->sizeof_rel)

/* The default alignment for sections, as a power of two.  */
#define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
  (get_elf_backend_data (abfd)->s->log_file_align)

static bfd_byte *hi16_rel_addr;

/* This will be used when we sort the dynamic relocation records.  */
static bfd *reldyn_sorting_bfd;

/* SCORE ELF uses two common sections.  One is the usual one, and the
   other is for small objects.  All the small objects are kept
   together, and then referenced via the gp pointer, which yields
   faster assembler code.  This is what we use for the small common
   section.  This approach is copied from ecoff.c.  */
static asection score_elf_scom_section;
static const asymbol score_elf_scom_symbol =
  GLOBAL_SYM_INIT (".scommon", &score_elf_scom_section);
static asection score_elf_scom_section =
  BFD_FAKE_SECTION (score_elf_scom_section, &score_elf_scom_symbol,
		    ".scommon", 0, SEC_IS_COMMON | SEC_SMALL_DATA);

static bfd_vma
score_bfd_get_16 (bfd *abfd, const void *data)
{
  return bfd_get_16 (abfd, data);
}

static bfd_vma
score3_bfd_getl32 (const void *p)
{
  const bfd_byte *addr = p;
  unsigned long v;

  v = (unsigned long) addr[2];
  v |= (unsigned long) addr[3] << 8;
  v |= (unsigned long) addr[0] << 16;
  v |= (unsigned long) addr[1] << 24;
  return v;
}

static bfd_vma
score3_bfd_getl48 (const void *p)
{
  const bfd_byte *addr = p;
  uint64_t v;

  v = (uint64_t) addr[4];
  v |= (uint64_t) addr[5] << 8;
  v |= (uint64_t) addr[2] << 16;
  v |= (uint64_t) addr[3] << 24;
  v |= (uint64_t) addr[0] << 32;
  v |= (uint64_t) addr[1] << 40;
  return v;
}

static bfd_vma
score_bfd_get_32 (bfd *abfd, const void *data)
{
  if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    return score3_bfd_getl32 (data);
  else
    return bfd_get_32 (abfd, data);
}

static bfd_vma
score_bfd_get_48 (bfd *abfd, const void *p)
{
  if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    return score3_bfd_getl48 (p);
  else
    return bfd_get_bits (p, 48, 1);
}

static void
score_bfd_put_16 (bfd *abfd, bfd_vma addr, void *data)
{
  return bfd_put_16 (abfd, addr, data);
}

static void
score3_bfd_putl32 (bfd_vma data, void *p)
{
  bfd_byte *addr = p;
  addr[0] = (data >> 16) & 0xff;
  addr[1] = (data >> 24) & 0xff;
  addr[2] = data & 0xff;
  addr[3] = (data >>  8) & 0xff;
}

static void
score3_bfd_putl48 (bfd_vma data, void *p)
{
  bfd_byte *addr = p;
  addr[0] = (data >> 32) & 0xff;
  addr[1] = (data >> 40) & 0xff;
  addr[2] = (data >> 16) & 0xff;
  addr[3] = (data >> 24) & 0xff;
  addr[4] = data & 0xff;
  addr[5] = (data >>  8) & 0xff;
}

static void
score_bfd_put_32 (bfd *abfd, bfd_vma addr, void *data)
{
  if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    return score3_bfd_putl32 (addr, data);
  else
    return bfd_put_32 (abfd, addr, data);
}

static void
score_bfd_put_48 (bfd *abfd, bfd_vma val, void *p)
{
  if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    return score3_bfd_putl48 (val, p);
  else
    return bfd_put_bits (val, p, 48, 1);
}

static bfd_reloc_status_type
score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
		      arelent *reloc_entry,
		      asymbol *symbol ATTRIBUTE_UNUSED,
		      void * data,
		      asection *input_section ATTRIBUTE_UNUSED,
		      bfd *output_bfd ATTRIBUTE_UNUSED,
		      char **error_message ATTRIBUTE_UNUSED)
{
  hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
  return bfd_reloc_ok;
}

static bfd_reloc_status_type
score_elf_lo16_reloc (bfd *abfd,
		      arelent *reloc_entry,
		      asymbol *symbol ATTRIBUTE_UNUSED,
		      void * data,
		      asection *input_section,
		      bfd *output_bfd ATTRIBUTE_UNUSED,
		      char **error_message ATTRIBUTE_UNUSED)
{
  bfd_vma addend = 0, offset = 0;
  unsigned long val;
  unsigned long hi16_offset, hi16_value, uvalue;

  hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
  hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
  addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
  offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
  val = reloc_entry->addend;
  if (reloc_entry->address > input_section->size)
    return bfd_reloc_outofrange;
  uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
  hi16_offset = (uvalue >> 16) << 1;
  hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
  score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
  offset = (uvalue & 0xffff) << 1;
  addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
  score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
  return bfd_reloc_ok;
}

/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
   dangerous relocation.  */

static bool
score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
{
  unsigned int count;
  asymbol **sym;
  unsigned int i;

  /* If we've already figured out what GP will be, just return it.  */
  *pgp = _bfd_get_gp_value (output_bfd);
  if (*pgp)
    return true;

  count = bfd_get_symcount (output_bfd);
  sym = bfd_get_outsymbols (output_bfd);

  /* The linker script will have created a symbol named `_gp' with the
     appropriate value.  */
  if (sym == NULL)
    i = count;
  else
    {
      for (i = 0; i < count; i++, sym++)
	{
	  const char *name;

	  name = bfd_asymbol_name (*sym);
	  if (*name == '_' && strcmp (name, "_gp") == 0)
	    {
	      *pgp = bfd_asymbol_value (*sym);
	      _bfd_set_gp_value (output_bfd, *pgp);
	      break;
	    }
	}
    }

  if (i >= count)
    {
      /* Only get the error once.  */
      *pgp = 4;
      _bfd_set_gp_value (output_bfd, *pgp);
      return false;
    }

  return true;
}

/* We have to figure out the gp value, so that we can adjust the
   symbol value correctly.  We look up the symbol _gp in the output
   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
   target data.  We don't need to adjust the symbol value for an
   external symbol if we are producing relocatable output.  */
static bfd_reloc_status_type
score_elf_final_gp (bfd *output_bfd,
		    asymbol *symbol,
		    bool relocatable,
		     char **error_message,
		    bfd_vma *pgp)
{
  if (bfd_is_und_section (symbol->section)
      && ! relocatable)
    {
      *pgp = 0;
      return bfd_reloc_undefined;
    }

  *pgp = _bfd_get_gp_value (output_bfd);
  if (*pgp == 0
      && (! relocatable
	  || (symbol->flags & BSF_SECTION_SYM) != 0))
    {
      if (relocatable)
	{
	  /* Make up a value.  */
	  *pgp = symbol->section->output_section->vma + 0x4000;
	  _bfd_set_gp_value (output_bfd, *pgp);
	}
      else if (!score_elf_assign_gp (output_bfd, pgp))
	{
	    *error_message =
	      (char *) _("GP relative relocation when _gp not defined");
	    return bfd_reloc_dangerous;
	}
    }

  return bfd_reloc_ok;
}

static bfd_reloc_status_type
score_elf_gprel15_with_gp (bfd *abfd,
			   arelent *reloc_entry,
			   asection *input_section,
			   bool relocateable,
			   void * data,
			   bfd_vma gp ATTRIBUTE_UNUSED)
{
  unsigned long insn;

  if (reloc_entry->address > input_section->size)
    return bfd_reloc_outofrange;

  insn = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
  if (((reloc_entry->addend & 0xffffc000) != 0)
      && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
    return bfd_reloc_overflow;

  insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
  score_bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
  if (relocateable)
    reloc_entry->address += input_section->output_offset;

  return bfd_reloc_ok;
}

static bfd_reloc_status_type
gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
		 asection *input_section, bool relocatable,
		 void *data, bfd_vma gp)
{
  bfd_vma relocation;
  bfd_vma val;

  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  relocation += symbol->section->output_section->vma;
  relocation += symbol->section->output_offset;

  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  /* Set val to the offset into the section or symbol.  */
  val = reloc_entry->addend;

  if (reloc_entry->howto->partial_inplace)
    val += score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);

  /* Adjust val for the final section location and GP value.  If we
     are producing relocatable output, we don't want to do this for
     an external symbol.  */
  if (! relocatable
      || (symbol->flags & BSF_SECTION_SYM) != 0)
    val += relocation - gp;

  if (reloc_entry->howto->partial_inplace)
    score_bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
  else
    reloc_entry->addend = val;

  if (relocatable)
    reloc_entry->address += input_section->output_offset;

  return bfd_reloc_ok;
}

static bfd_reloc_status_type
score_elf_gprel15_reloc (bfd *abfd,
			 arelent *reloc_entry,
			 asymbol *symbol,
			 void * data,
			 asection *input_section,
			 bfd *output_bfd,
			 char **error_message)
{
  bool relocateable;
  bfd_reloc_status_type ret;
  bfd_vma gp;

  if (output_bfd != NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }
  if (output_bfd != NULL)
    relocateable = true;
  else
    {
      relocateable = false;
      output_bfd = symbol->section->output_section->owner;
    }

  ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
  if (ret != bfd_reloc_ok)
    return ret;

  return score_elf_gprel15_with_gp (abfd, reloc_entry,
				    input_section, relocateable, data, gp);
}

/* Do a R_SCORE_GPREL32 relocation.  This is a 32 bit value which must
   become the offset from the gp register.  */

static bfd_reloc_status_type
score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
			void *data, asection *input_section, bfd *output_bfd,
			char **error_message)
{
  bool relocatable;
  bfd_reloc_status_type ret;
  bfd_vma gp;

  /* R_SCORE_GPREL32 relocations are defined for local symbols only.  */
  if (output_bfd != NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (symbol->flags & BSF_LOCAL) != 0)
    {
      *error_message = (char *)
	_("32bits gp relative relocation occurs for an external symbol");
      return bfd_reloc_outofrange;
    }

  if (output_bfd != NULL)
    relocatable = true;
  else
    {
      relocatable = false;
      output_bfd = symbol->section->output_section->owner;
    }

  ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
  if (ret != bfd_reloc_ok)
    return ret;

  gp = 0;
  return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
			  relocatable, data, gp);
}

/* A howto special_function for R_SCORE_GOT15 relocations.  This is just
   like any other 16-bit relocation when applied to global symbols, but is
   treated in the same as R_SCORE_HI16 when applied to local symbols.  */
static bfd_reloc_status_type
score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
		       void *data, asection *input_section,
		       bfd *output_bfd, char **error_message)
{
  if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
      || bfd_is_und_section (bfd_asymbol_section (symbol))
      || bfd_is_com_section (bfd_asymbol_section (symbol)))
    /* The relocation is against a global symbol.  */
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
				  input_section, output_bfd,
				  error_message);

  return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
			       input_section, output_bfd, error_message);
}

static bfd_reloc_status_type
score_elf_got_lo16_reloc (bfd *abfd,
			  arelent *reloc_entry,
			  asymbol *symbol ATTRIBUTE_UNUSED,
			  void * data,
			  asection *input_section,
			  bfd *output_bfd ATTRIBUTE_UNUSED,
			  char **error_message ATTRIBUTE_UNUSED)
{
  bfd_vma addend = 0, offset = 0;
  signed long val;
  signed long hi16_offset, hi16_value, uvalue;

  hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
  hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
  addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
  offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
  val = reloc_entry->addend;
  if (reloc_entry->address > input_section->size)
    return bfd_reloc_outofrange;
  uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
  if ((uvalue > -0x8000) && (uvalue < 0x7fff))
    hi16_offset = 0;
  else
    hi16_offset = (uvalue >> 16) & 0x7fff;
  hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
  score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
  offset = (uvalue & 0xffff) << 1;
  addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
  score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
  return bfd_reloc_ok;
}

static reloc_howto_type elf32_score_howto_table[] =
{
  /* No relocation.  */
  HOWTO (R_SCORE_NONE,		/* type */
	 0,			/* rightshift */
	 0,			/* size */
	 0,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_NONE",	/* name */
	 false,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_HI16 */
  HOWTO (R_SCORE_HI16,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_hi16_reloc,	/* special_function */
	 "R_SCORE_HI16",	/* name */
	 true,			/* partial_inplace */
	 0x37fff,		/* src_mask */
	 0x37fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_LO16 */
  HOWTO (R_SCORE_LO16,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_lo16_reloc,	/* special_function */
	 "R_SCORE_LO16",	/* name */
	 true,			/* partial_inplace */
	 0x37fff,		/* src_mask */
	 0x37fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /*  R_SCORE_BCMP */
  HOWTO (R_SCORE_BCMP,		/* type */
	 1,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 true,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_BCMP",	/* name */
	 false,			/* partial_inplace */
	 0x03e00381,		/* src_mask */
	 0x03e00381,		/* dst_mask */
	 false),		/* pcrel_offset */

  /*R_SCORE_24 */
  HOWTO (R_SCORE_24,		/* type */
	 1,			/* rightshift */
	 4,			/* size */
	 24,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_24",		/* name */
	 false,			/* partial_inplace */
	 0x3ff7fff,		/* src_mask */
	 0x3ff7fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /*R_SCORE_PC19 */
  HOWTO (R_SCORE_PC19,		/* type */
	 1,			/* rightshift */
	 4,			/* size */
	 19,			/* bitsize */
	 true,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_PC19",	/* name */
	 false,			/* partial_inplace */
	 0x3ff03fe,		/* src_mask */
	 0x3ff03fe,		/* dst_mask */
	 false),		/* pcrel_offset */

  /*R_SCORE16_11 */
  HOWTO (R_SCORE16_11,		/* type */
	 1,			/* rightshift */
	 2,			/* size */
	 11,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE16_11",	/* name */
	 false,			/* partial_inplace */
	 0x000000ffe,		/* src_mask */
	 0x000000ffe,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE16_PC8 */
  HOWTO (R_SCORE16_PC8,		/* type */
	 1,			/* rightshift */
	 2,			/* size */
	 9,			/* bitsize */
	 true,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE16_PC8",	/* name */
	 false,			/* partial_inplace */
	 0x000001ff,		/* src_mask */
	 0x000001ff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* 32 bit absolute */
  HOWTO (R_SCORE_ABS32,		/* type	 8 */
	 0,			/* rightshift */
	 4,			/* size */
	 32,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield,	/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_ABS32",	/* name */
	 false,			/* partial_inplace */
	 0xffffffff,		/* src_mask */
	 0xffffffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* 16 bit absolute */
  HOWTO (R_SCORE_ABS16,		/* type 11 */
	 0,			/* rightshift */
	 2,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield,	/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_ABS16",	/* name */
	 false,			/* partial_inplace */
	 0x0000ffff,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_DUMMY2 */
  HOWTO (R_SCORE_DUMMY2,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_DUMMY2",	/* name */
	 true,			/* partial_inplace */
	 0x00007fff,		/* src_mask */
	 0x00007fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_GP15 */
  HOWTO (R_SCORE_GP15,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_gprel15_reloc,/* special_function */
	 "R_SCORE_GP15",	/* name */
	 true,			/* partial_inplace */
	 0x00007fff,		/* src_mask */
	 0x00007fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* GNU extension to record C++ vtable hierarchy.  */
  HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
	 0,			/* rightshift */
	 4,			/* size */
	 0,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 NULL,			/* special_function */
	 "R_SCORE_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_SCORE_GNU_VTENTRY,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 0,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 _bfd_elf_rel_vtable_reloc_fn,	/* special_function */
	 "R_SCORE_GNU_VTENTRY", /* name */
	 false,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 false),		/* pcrel_offset */

  /* Reference to global offset table.  */
  HOWTO (R_SCORE_GOT15,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_signed,	/* complain_on_overflow */
	 score_elf_got15_reloc, /* special_function */
	 "R_SCORE_GOT15",	/* name */
	 true,			/* partial_inplace */
	 0x00007fff,		/* src_mask */
	 0x00007fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* Low 16 bits of displacement in global offset table.  */
  HOWTO (R_SCORE_GOT_LO16,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_got_lo16_reloc, /* special_function */
	 "R_SCORE_GOT_LO16",	/* name */
	 true,			/* partial_inplace */
	 0x37ffe,		/* src_mask */
	 0x37ffe,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* 15 bit call through global offset table.  */
  HOWTO (R_SCORE_CALL15,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_signed, /* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_CALL15",	/* name */
	 true,			/* partial_inplace */
	 0x0000ffff,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* 32 bit GP relative reference.  */
  HOWTO (R_SCORE_GPREL32,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 32,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_gprel32_reloc, /* special_function */
	 "R_SCORE_GPREL32",	/* name */
	 true,			/* partial_inplace */
	 0xffffffff,		/* src_mask */
	 0xffffffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* 32 bit symbol relative relocation.  */
  HOWTO (R_SCORE_REL32,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 32,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_REL32",	/* name */
	 true,			/* partial_inplace */
	 0xffffffff,		/* src_mask */
	 0xffffffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_DUMMY_HI16 */
  HOWTO (R_SCORE_DUMMY_HI16,	/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 score_elf_hi16_reloc,	/* special_function */
	 "R_SCORE_DUMMY_HI16",	/* name */
	 true,			/* partial_inplace */
	 0x37fff,		/* src_mask */
	 0x37fff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_IMM30 */
  HOWTO (R_SCORE_IMM30,		/* type */
	 2,			/* rightshift */
	 4,			/* size */
	 30,			/* bitsize */
	 false,			/* pc_relative */
	 7,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_IMM30",	/* name */
	 false,			/* partial_inplace */
	 0x7f7fff7f80LL,	/* src_mask */
	 0x7f7fff7f80LL,	/* dst_mask */
	 false),		/* pcrel_offset */

  /* R_SCORE_IMM32 */
  HOWTO (R_SCORE_IMM32,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 32,			/* bitsize */
	 false,			/* pc_relative */
	 5,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_IMM32",	/* name */
	 false,			/* partial_inplace */
	 0x7f7fff7fe0LL,	/* src_mask */
	 0x7f7fff7fe0LL,	/* dst_mask */
	 false),		/* pcrel_offset */
};

struct score_reloc_map
{
  bfd_reloc_code_real_type bfd_reloc_val;
  unsigned char elf_reloc_val;
};

static const struct score_reloc_map elf32_score_reloc_map[] =
{
  {BFD_RELOC_NONE,		 R_SCORE_NONE},
  {BFD_RELOC_HI16_S,		 R_SCORE_HI16},
  {BFD_RELOC_LO16,		 R_SCORE_LO16},
  {BFD_RELOC_SCORE_BCMP,	 R_SCORE_BCMP},
  {BFD_RELOC_SCORE_JMP,		 R_SCORE_24},
  {BFD_RELOC_SCORE_BRANCH,	 R_SCORE_PC19},
  {BFD_RELOC_SCORE16_JMP,	 R_SCORE16_11},
  {BFD_RELOC_SCORE16_BRANCH,	 R_SCORE16_PC8},
  {BFD_RELOC_32,		 R_SCORE_ABS32},
  {BFD_RELOC_16,		 R_SCORE_ABS16},
  {BFD_RELOC_SCORE_DUMMY2,	 R_SCORE_DUMMY2},
  {BFD_RELOC_SCORE_GPREL15,	 R_SCORE_GP15},
  {BFD_RELOC_VTABLE_INHERIT,	 R_SCORE_GNU_VTINHERIT},
  {BFD_RELOC_VTABLE_ENTRY,	 R_SCORE_GNU_VTENTRY},
  {BFD_RELOC_SCORE_GOT15,	 R_SCORE_GOT15},
  {BFD_RELOC_SCORE_GOT_LO16,	 R_SCORE_GOT_LO16},
  {BFD_RELOC_SCORE_CALL15,	 R_SCORE_CALL15},
  {BFD_RELOC_GPREL32,		 R_SCORE_GPREL32},
  {BFD_RELOC_32_PCREL,		 R_SCORE_REL32},
  {BFD_RELOC_SCORE_DUMMY_HI16,	 R_SCORE_DUMMY_HI16},
  {BFD_RELOC_SCORE_IMM30,	 R_SCORE_IMM30},
  {BFD_RELOC_SCORE_IMM32,	 R_SCORE_IMM32},
};

/* got_entries only match if they're identical, except for gotidx, so
   use all fields to compute the hash, and compare the appropriate
   union members.  */
static hashval_t
score_elf_got_entry_hash (const void *entry_)
{
  const struct score_got_entry *entry = (struct score_got_entry *)entry_;

  return entry->symndx
    + (!entry->abfd ? entry->d.address : entry->abfd->id);
}

static int
score_elf_got_entry_eq (const void *entry1, const void *entry2)
{
  const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
  const struct score_got_entry *e2 = (struct score_got_entry *)entry2;

  return e1->abfd == e2->abfd && e1->symndx == e2->symndx
    && (! e1->abfd ? e1->d.address == e2->d.address
	: e1->symndx >= 0 ? e1->d.addend == e2->d.addend
	: e1->d.h == e2->d.h);
}

/* If H needs a GOT entry, assign it the highest available dynamic
   index.  Otherwise, assign it the lowest available dynamic
   index.  */
static bool
score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
{
  struct score_elf_hash_sort_data *hsd = data;

  /* Symbols without dynamic symbol table entries aren't interesting at all.  */
  if (h->root.dynindx == -1)
    return true;

  /* Global symbols that need GOT entries that are not explicitly
     referenced are marked with got offset 2.  Those that are
     referenced get a 1, and those that don't need GOT entries get
     -1.  */
  if (h->root.got.offset == 2)
    {
      if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
	hsd->low = (struct elf_link_hash_entry *) h;
      h->root.dynindx = hsd->max_unref_got_dynindx++;
    }
  else if (h->root.got.offset != 1)
    h->root.dynindx = hsd->max_non_got_dynindx++;
  else
    {
      h->root.dynindx = --hsd->min_got_dynindx;
      hsd->low = (struct elf_link_hash_entry *) h;
    }

  return true;
}

static asection *
score_elf_got_section (bfd *abfd, bool maybe_excluded)
{
  asection *sgot = bfd_get_linker_section (abfd, ".got");

  if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
    return NULL;
  return sgot;
}

/* Returns the GOT information associated with the link indicated by
   INFO.  If SGOTP is non-NULL, it is filled in with the GOT section.  */
static struct score_got_info *
score_elf_got_info (bfd *abfd, asection **sgotp)
{
  asection *sgot;
  struct score_got_info *g;

  sgot = score_elf_got_section (abfd, true);
  BFD_ASSERT (sgot != NULL);
  BFD_ASSERT (elf_section_data (sgot) != NULL);
  g = score_elf_section_data (sgot)->u.got_info;
  BFD_ASSERT (g != NULL);

  if (sgotp)
    *sgotp = sgot;
  return g;
}

/* Sort the dynamic symbol table so that symbols that need GOT entries
   appear towards the end.  This reduces the amount of GOT space
   required.  MAX_LOCAL is used to set the number of local symbols
   known to be in the dynamic symbol table.  During
   s3_bfd_score_elf_size_dynamic_sections, this value is 1.  Afterward, the
   section symbols are added and the count is higher.  */
static bool
score_elf_sort_hash_table (struct bfd_link_info *info,
			   unsigned long max_local)
{
  struct score_elf_hash_sort_data hsd;
  struct score_got_info *g;
  bfd *dynobj;

  dynobj = elf_hash_table (info)->dynobj;

  g = score_elf_got_info (dynobj, NULL);

  hsd.low = NULL;
  hsd.max_unref_got_dynindx =
    hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
    /* In the multi-got case, assigned_gotno of the master got_info
       indicate the number of entries that aren't referenced in the
       primary GOT, but that must have entries because there are
       dynamic relocations that reference it.  Since they aren't
       referenced, we move them to the end of the GOT, so that they
       don't prevent other entries that are referenced from getting
       too large offsets.  */
    - (g->next ? g->assigned_gotno : 0);
  hsd.max_non_got_dynindx = max_local;
  score_elf_link_hash_traverse (elf_hash_table (info),
				score_elf_sort_hash_table_f,
				&hsd);

  /* There should have been enough room in the symbol table to
     accommodate both the GOT and non-GOT symbols.  */
  BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
  BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
	      <= elf_hash_table (info)->dynsymcount);

  /* Now we know which dynamic symbol has the lowest dynamic symbol
     table index in the GOT.  */
  g->global_gotsym = hsd.low;

  return true;
}

/* Create an entry in an score ELF linker hash table.  */

static struct bfd_hash_entry *
score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
			     struct bfd_hash_table *table,
			     const char *string)
{
  struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry;

  /* Allocate the structure if it has not already been allocated by a subclass.  */
  if (ret == NULL)
    ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
  if (ret == NULL)
    return (struct bfd_hash_entry *) ret;

  /* Call the allocation method of the superclass.  */
  ret = ((struct score_elf_link_hash_entry *)
	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));

  if (ret != NULL)
    {
      ret->possibly_dynamic_relocs = 0;
      ret->readonly_reloc = false;
      ret->no_fn_stub = false;
      ret->forced_local = false;
    }

  return (struct bfd_hash_entry *) ret;
}

/* Returns the first relocation of type r_type found, beginning with
   RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
static const Elf_Internal_Rela *
score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
			    const Elf_Internal_Rela *relocation,
			   const Elf_Internal_Rela *relend)
{
  while (relocation < relend)
    {
      if (ELF32_R_TYPE (relocation->r_info) == r_type)
	return relocation;

      ++relocation;
    }

  /* We didn't find it.  */
  bfd_set_error (bfd_error_bad_value);
  return NULL;
}

/* This function is called via qsort() to sort the dynamic relocation
   entries by increasing r_symndx value.  */
static int
score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
{
  Elf_Internal_Rela int_reloc1;
  Elf_Internal_Rela int_reloc2;

  bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
  bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);

  return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
}

/* Return whether a relocation is against a local symbol.  */
static bool
score_elf_local_relocation_p (bfd *input_bfd,
			      const Elf_Internal_Rela *relocation,
			      asection **local_sections,
			      bool check_forced)
{
  unsigned long r_symndx;
  Elf_Internal_Shdr *symtab_hdr;
  struct score_elf_link_hash_entry *h;
  size_t extsymoff;

  r_symndx = ELF32_R_SYM (relocation->r_info);
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;

  if (r_symndx < extsymoff)
    return true;
  if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
    return true;

  if (check_forced)
    {
      /* Look up the hash table to check whether the symbol was forced local.  */
      h = (struct score_elf_link_hash_entry *)
	elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
      /* Find the real hash-table entry for this symbol.  */
      while (h->root.root.type == bfd_link_hash_indirect
	     || h->root.root.type == bfd_link_hash_warning)
	h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
      if (h->root.forced_local)
	return true;
    }

  return false;
}

/* Returns the dynamic relocation section for DYNOBJ.  */
static asection *
score_elf_rel_dyn_section (bfd *dynobj, bool create_p)
{
  static const char dname[] = ".rel.dyn";
  asection *sreloc;

  sreloc = bfd_get_linker_section (dynobj, dname);
  if (sreloc == NULL && create_p)
    {
      sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
						   (SEC_ALLOC
						    | SEC_LOAD
						    | SEC_HAS_CONTENTS
						    | SEC_IN_MEMORY
						    | SEC_LINKER_CREATED
						    | SEC_READONLY));
      if (sreloc == NULL
	  || !bfd_set_section_alignment (sreloc,
					 SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
	return NULL;
    }
  return sreloc;
}

static void
score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
{
  asection *s;

  s = score_elf_rel_dyn_section (abfd, false);
  BFD_ASSERT (s != NULL);

  if (s->size == 0)
    {
      /* Make room for a null element.  */
      s->size += SCORE_ELF_REL_SIZE (abfd);
      ++s->reloc_count;
    }
  s->size += n * SCORE_ELF_REL_SIZE (abfd);
}

/* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
   is the original relocation, which is now being transformed into a
   dynamic relocation.  The ADDENDP is adjusted if necessary; the
   caller should store the result in place of the original addend.  */
static bool
score_elf_create_dynamic_relocation (bfd *output_bfd,
				     struct bfd_link_info *info,
				     const Elf_Internal_Rela *rel,
				     struct score_elf_link_hash_entry *h,
				     bfd_vma symbol,
				     bfd_vma *addendp, asection *input_section)
{
  Elf_Internal_Rela outrel[3];
  asection *sreloc;
  bfd *dynobj;
  int r_type;
  long indx;
  bool defined_p;

  r_type = ELF32_R_TYPE (rel->r_info);
  dynobj = elf_hash_table (info)->dynobj;
  sreloc = score_elf_rel_dyn_section (dynobj, false);
  BFD_ASSERT (sreloc != NULL);
  BFD_ASSERT (sreloc->contents != NULL);
  BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);

  outrel[0].r_offset =
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
  outrel[1].r_offset =
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
  outrel[2].r_offset =
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);

  if (outrel[0].r_offset == MINUS_ONE)
    /* The relocation field has been deleted.  */
    return true;

  if (outrel[0].r_offset == MINUS_TWO)
    {
      /* The relocation field has been converted into a relative value of
	 some sort.  Functions like _bfd_elf_write_section_eh_frame expect
	 the field to be fully relocated, so add in the symbol's value.  */
      *addendp += symbol;
      return true;
    }

  /* We must now calculate the dynamic symbol table index to use
     in the relocation.  */
  if (h != NULL
      && (! info->symbolic || !h->root.def_regular)
      /* h->root.dynindx may be -1 if this symbol was marked to
	 become local.  */
      && h->root.dynindx != -1)
    {
      indx = h->root.dynindx;
	/* ??? glibc's ld.so just adds the final GOT entry to the
	   relocation field.  It therefore treats relocs against
	   defined symbols in the same way as relocs against
	   undefined symbols.  */
      defined_p = false;
    }
  else
    {
      indx = 0;
      defined_p = true;
    }

  /* If the relocation was previously an absolute relocation and
     this symbol will not be referred to by the relocation, we must
     adjust it by the value we give it in the dynamic symbol table.
     Otherwise leave the job up to the dynamic linker.  */
  if (defined_p && r_type != R_SCORE_REL32)
    *addendp += symbol;

  /* The relocation is always an REL32 relocation because we don't
     know where the shared library will wind up at load-time.  */
  outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);

  /* For strict adherence to the ABI specification, we should
     generate a R_SCORE_64 relocation record by itself before the
     _REL32/_64 record as well, such that the addend is read in as
     a 64-bit value (REL32 is a 32-bit relocation, after all).
     However, since none of the existing ELF64 SCORE dynamic
     loaders seems to care, we don't waste space with these
     artificial relocations.  If this turns out to not be true,
     score_elf_allocate_dynamic_relocations() should be tweaked so
     as to make room for a pair of dynamic relocations per
     invocation if ABI_64_P, and here we should generate an
     additional relocation record with R_SCORE_64 by itself for a
     NULL symbol before this relocation record.  */
  outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
  outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);

  /* Adjust the output offset of the relocation to reference the
     correct location in the output file.  */
  outrel[0].r_offset += (input_section->output_section->vma
			 + input_section->output_offset);
  outrel[1].r_offset += (input_section->output_section->vma
			 + input_section->output_offset);
  outrel[2].r_offset += (input_section->output_section->vma
			 + input_section->output_offset);

  /* Put the relocation back out.  We have to use the special
     relocation outputter in the 64-bit case since the 64-bit
     relocation format is non-standard.  */
  bfd_elf32_swap_reloc_out
      (output_bfd, &outrel[0],
       (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));

  /* We've now added another relocation.  */
  ++sreloc->reloc_count;

  /* Make sure the output section is writable.  The dynamic linker
     will be writing to it.  */
  elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;

  return true;
}

static bool
score_elf_create_got_section (bfd *abfd,
			      struct bfd_link_info *info,
			      bool maybe_exclude)
{
  flagword flags;
  asection *s;
  struct elf_link_hash_entry *h;
  struct bfd_link_hash_entry *bh;
  struct score_got_info *g;
  size_t amt;

  /* This function may be called more than once.  */
  s = score_elf_got_section (abfd, true);
  if (s)
    {
      if (! maybe_exclude)
	s->flags &= ~SEC_EXCLUDE;
      return true;
    }

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);

  if (maybe_exclude)
    flags |= SEC_EXCLUDE;

  /* We have to use an alignment of 2**4 here because this is hardcoded
     in the function stub generation and in the linker script.  */
  s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
  elf_hash_table (info)->sgot = s;
  if (s == NULL
      || !bfd_set_section_alignment (s, 4))
    return false;

  /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
     linker script because we don't want to define the symbol if we
     are not creating a global offset table.  */
  bh = NULL;
  if (! (_bfd_generic_link_add_one_symbol
	 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
	  0, NULL, false, get_elf_backend_data (abfd)->collect, &bh)))
    return false;

  h = (struct elf_link_hash_entry *) bh;
  h->non_elf = 0;
  h->def_regular = 1;
  h->type = STT_OBJECT;
  elf_hash_table (info)->hgot = h;

  if (bfd_link_pic (info) && ! bfd_elf_link_record_dynamic_symbol (info, h))
    return false;

  amt = sizeof (struct score_got_info);
  g = bfd_alloc (abfd, amt);
  if (g == NULL)
    return false;

  g->global_gotsym = NULL;
  g->global_gotno = 0;

  g->local_gotno = SCORE_RESERVED_GOTNO;
  g->assigned_gotno = SCORE_RESERVED_GOTNO;
  g->next = NULL;

  g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
				    score_elf_got_entry_eq, NULL);
  if (g->got_entries == NULL)
    return false;
  score_elf_section_data (s)->u.got_info = g;
  score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;

  return true;
}

/* Calculate the %high function.  */
static bfd_vma
score_elf_high (bfd_vma value)
{
  return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
}

/* Create a local GOT entry for VALUE.  Return the index of the entry,
   or -1 if it could not be created.  */
static struct score_got_entry *
score_elf_create_local_got_entry (bfd *abfd,
				  bfd *ibfd ATTRIBUTE_UNUSED,
				  struct score_got_info *gg,
				  asection *sgot, bfd_vma value,
				  unsigned long r_symndx ATTRIBUTE_UNUSED,
				  struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
				  int r_type ATTRIBUTE_UNUSED)
{
  struct score_got_entry entry, **loc;
  struct score_got_info *g;

  entry.abfd = NULL;
  entry.symndx = -1;
  entry.d.address = value;

  g = gg;
  loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
  if (*loc)
    return *loc;

  entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;

  *loc = bfd_alloc (abfd, sizeof entry);

  if (! *loc)
    return NULL;

  memcpy (*loc, &entry, sizeof entry);

  if (g->assigned_gotno >= g->local_gotno)
    {
      (*loc)->gotidx = -1;
      /* We didn't allocate enough space in the GOT.  */
      _bfd_error_handler
	(_("not enough GOT space for local GOT entries"));
      bfd_set_error (bfd_error_bad_value);
      return NULL;
    }

  score_bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));

  return *loc;
}

/* Find a GOT entry whose higher-order 16 bits are the same as those
   for value.  Return the index into the GOT for this entry.  */
static bfd_vma
score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
		       bfd_vma value, bool external)
{
  asection *sgot;
  struct score_got_info *g;
  struct score_got_entry *entry;

  if (!external)
    {
      /* Although the ABI says that it is "the high-order 16 bits" that we
	 want, it is really the %high value.  The complete value is
	 calculated with a `addiu' of a LO16 relocation, just as with a
	 HI16/LO16 pair.  */
      value = score_elf_high (value) << 16;
    }

  g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);

  entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
					    R_SCORE_GOT15);
  if (entry)
    return entry->gotidx;
  else
    return MINUS_ONE;
}

static void
s3_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
			      struct elf_link_hash_entry *entry,
			      bool force_local)
{
  bfd *dynobj;
  asection *got;
  struct score_got_info *g;
  struct score_elf_link_hash_entry *h;

  h = (struct score_elf_link_hash_entry *) entry;
  if (h->forced_local)
    return;
  h->forced_local = true;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj != NULL && force_local)
    {
      got = score_elf_got_section (dynobj, false);
      if (got == NULL)
	return;
      g = score_elf_section_data (got)->u.got_info;

      if (g->next)
	{
	  struct score_got_entry e;
	  struct score_got_info *gg = g;

	  /* Since we're turning what used to be a global symbol into a
	     local one, bump up the number of local entries of each GOT
	     that had an entry for it.  This will automatically decrease
	     the number of global entries, since global_gotno is actually
	     the upper limit of global entries.  */
	  e.abfd = dynobj;
	  e.symndx = -1;
	  e.d.h = h;

	  for (g = g->next; g != gg; g = g->next)
	    if (htab_find (g->got_entries, &e))
	      {
		BFD_ASSERT (g->global_gotno > 0);
		g->local_gotno++;
		g->global_gotno--;
	      }

	  /* If this was a global symbol forced into the primary GOT, we
	     no longer need an entry for it.  We can't release the entry
	     at this point, but we must at least stop counting it as one
	     of the symbols that required a forced got entry.  */
	  if (h->root.got.offset == 2)
	    {
	      BFD_ASSERT (gg->assigned_gotno > 0);
	      gg->assigned_gotno--;
	    }
	}
      else if (g->global_gotno == 0 && g->global_gotsym == NULL)
	/* If we haven't got through GOT allocation yet, just bump up the
	      number of local entries, as this symbol won't be counted as
	      global.  */
	g->local_gotno++;
      else if (h->root.got.offset == 1)
	{
	  /* If we're past non-multi-GOT allocation and this symbol had
		  been marked for a global got entry, give it a local entry
		  instead.  */
	  BFD_ASSERT (g->global_gotno > 0);
	  g->local_gotno++;
	  g->global_gotno--;
	}
    }

  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
}

/* If H is a symbol that needs a global GOT entry, but has a dynamic
   symbol table index lower than any we've seen to date, record it for
   posterity.  */
static bool
score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
				    bfd *abfd,
				    struct bfd_link_info *info,
				    struct score_got_info *g)
{
  struct score_got_entry entry, **loc;

  /* A global symbol in the GOT must also be in the dynamic symbol table.  */
  if (h->dynindx == -1)
    {
      switch (ELF_ST_VISIBILITY (h->other))
	{
	case STV_INTERNAL:
	case STV_HIDDEN:
	  s3_bfd_score_elf_hide_symbol (info, h, true);
	  break;
	}
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
	return false;
    }

  entry.abfd = abfd;
  entry.symndx = -1;
  entry.d.h = (struct score_elf_link_hash_entry *)h;

  loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);

  /* If we've already marked this entry as needing GOT space, we don't
     need to do it again.  */
  if (*loc)
    return true;

  *loc = bfd_alloc (abfd, sizeof entry);
  if (! *loc)
    return false;

  entry.gotidx = -1;

  memcpy (*loc, &entry, sizeof (entry));

  if (h->got.offset != MINUS_ONE)
    return true;

  /* By setting this to a value other than -1, we are indicating that
     there needs to be a GOT entry for H.  Avoid using zero, as the
     generic ELF copy_indirect_symbol tests for <= 0.  */
  h->got.offset = 1;

  return true;
}

/* Reserve space in G for a GOT entry containing the value of symbol
   SYMNDX in input bfd ABDF, plus ADDEND.  */
static bool
score_elf_record_local_got_symbol (bfd *abfd,
				   long symndx,
				   bfd_vma addend,
				   struct score_got_info *g)
{
  struct score_got_entry entry, **loc;

  entry.abfd = abfd;
  entry.symndx = symndx;
  entry.d.addend = addend;
  loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);

  if (*loc)
    return true;

  entry.gotidx = g->local_gotno++;

  *loc = bfd_alloc (abfd, sizeof(entry));
  if (! *loc)
    return false;

  memcpy (*loc, &entry, sizeof (entry));

  return true;
}

/* Returns the GOT offset at which the indicated address can be found.
   If there is not yet a GOT entry for this value, create one.
   Returns -1 if no satisfactory GOT offset can be found.  */
static bfd_vma
score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
			   bfd_vma value, unsigned long r_symndx,
			   struct score_elf_link_hash_entry *h, int r_type)
{
  asection *sgot;
  struct score_got_info *g;
  struct score_got_entry *entry;

  g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);

  entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
					     r_symndx, h, r_type);
  if (!entry)
    return MINUS_ONE;

  else
    return entry->gotidx;
}

/* Returns the GOT index for the global symbol indicated by H.  */

static bfd_vma
score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
{
  bfd_vma got_index;
  asection *sgot;
  struct score_got_info *g;
  long global_got_dynindx = 0;

  g = score_elf_got_info (abfd, &sgot);
  if (g->global_gotsym != NULL)
    global_got_dynindx = g->global_gotsym->dynindx;

  /* Once we determine the global GOT entry with the lowest dynamic
     symbol table index, we must put all dynamic symbols with greater
     indices into the GOT.  That makes it easy to calculate the GOT
     offset.  */
  BFD_ASSERT (h->dynindx >= global_got_dynindx);
  got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
  BFD_ASSERT (got_index < sgot->size);

  return got_index;
}

/* Returns the offset for the entry at the INDEXth position in the GOT.  */

static bfd_vma
score_elf_got_offset_from_index (bfd *dynobj,
				 bfd *output_bfd,
				 bfd *input_bfd ATTRIBUTE_UNUSED,
				 bfd_vma got_index)
{
  asection *sgot;
  bfd_vma gp;

  score_elf_got_info (dynobj, &sgot);
  gp = _bfd_get_gp_value (output_bfd);

  return sgot->output_section->vma + sgot->output_offset + got_index - gp;
}

/* Follow indirect and warning hash entries so that each got entry
   points to the final symbol definition.  P must point to a pointer
   to the hash table we're traversing.  Since this traversal may
   modify the hash table, we set this pointer to NULL to indicate
   we've made a potentially-destructive change to the hash table, so
   the traversal must be restarted.  */
static int
score_elf_resolve_final_got_entry (void **entryp, void *p)
{
  struct score_got_entry *entry = (struct score_got_entry *)*entryp;
  htab_t got_entries = *(htab_t *)p;

  if (entry->abfd != NULL && entry->symndx == -1)
    {
      struct score_elf_link_hash_entry *h = entry->d.h;

      while (h->root.root.type == bfd_link_hash_indirect
	     || h->root.root.type == bfd_link_hash_warning)
	h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;

      if (entry->d.h == h)
	return 1;

      entry->d.h = h;

      /* If we can't find this entry with the new bfd hash, re-insert
	 it, and get the traversal restarted.  */
      if (! htab_find (got_entries, entry))
	{
	  htab_clear_slot (got_entries, entryp);
	  entryp = htab_find_slot (got_entries, entry, INSERT);
	  if (! *entryp)
	    *entryp = entry;
	  /* Abort the traversal, since the whole table may have
	     moved, and leave it up to the parent to restart the
	     process.  */
	  *(htab_t *)p = NULL;
	  return 0;
	}
      /* We might want to decrement the global_gotno count, but it's
	 either too early or too late for that at this point.  */
    }

  return 1;
}

/* Turn indirect got entries in a got_entries table into their final locations.  */
static void
score_elf_resolve_final_got_entries (struct score_got_info *g)
{
  htab_t got_entries;

  do
    {
      got_entries = g->got_entries;

      htab_traverse (got_entries,
		     score_elf_resolve_final_got_entry,
		     &got_entries);
    }
  while (got_entries == NULL);
}

/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
static void
score_elf_add_to_rel (bfd *abfd,
		      bfd_byte *address,
		      reloc_howto_type *howto,
		      bfd_signed_vma increment)
{
  bfd_signed_vma addend;
  bfd_vma contents;
  unsigned long offset;
  unsigned long r_type = howto->type;
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;

  contents = score_bfd_get_32 (abfd, address);
  /* Get the (signed) value from the instruction.  */
  addend = contents & howto->src_mask;
  if (addend & ((howto->src_mask + 1) >> 1))
    {
      bfd_signed_vma mask;

      mask = -1;
      mask &= ~howto->src_mask;
      addend |= mask;
    }
  /* Add in the increment, (which is a byte value).  */
  switch (r_type)
    {
    case R_SCORE_PC19:
      offset =
	(((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
      offset += increment;
      contents =
	(contents & ~howto->
	 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
      score_bfd_put_32 (abfd, contents, address);
      break;
    case R_SCORE_HI16:
      break;
    case R_SCORE_LO16:
      hi16_addend = score_bfd_get_32 (abfd, address - 4);
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
      offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
      offset = (hi16_offset << 16) | (offset & 0xffff);
      uvalue = increment + offset;
      hi16_offset = (uvalue >> 16) << 1;
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
	| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
      score_bfd_put_32 (abfd, hi16_value, address - 4);
      offset = (uvalue & 0xffff) << 1;
      contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
      score_bfd_put_32 (abfd, contents, address);
      break;
    case R_SCORE_24:
      offset =
	(((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
      offset += increment;
      contents =
	(contents & ~howto->
	 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
      score_bfd_put_32 (abfd, contents, address);
      break;

    case R_SCORE16_11:

      contents = score_bfd_get_16 (abfd, address);
      offset = contents & howto->src_mask;
      offset += increment;
      contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
      score_bfd_put_16 (abfd, contents, address);

      break;
    case R_SCORE16_PC8:

      contents = score_bfd_get_16 (abfd, address);
      offset = (contents & howto->src_mask) + ((increment >> 1) & 0x1ff);
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
      score_bfd_put_16 (abfd, contents, address);

      break;

    case R_SCORE_BCMP:
      contents = score_bfd_get_32 (abfd, address);
      offset = (contents & howto->src_mask);
      offset <<= howto->rightshift;
      offset += increment;
      offset >>= howto->rightshift;
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
      score_bfd_put_32 (abfd, contents, address);
      break;

    case R_SCORE_IMM30:
      contents = score_bfd_get_48 (abfd, address);
      offset = (contents & howto->src_mask);
      offset <<= howto->rightshift;
      offset += increment;
      offset >>= howto->rightshift;
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
      score_bfd_put_48 (abfd, contents, address);
      break;

    case R_SCORE_IMM32:
      contents = score_bfd_get_48 (abfd, address);
      offset = (contents & howto->src_mask);
      offset += increment;
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
      score_bfd_put_48 (abfd, contents, address);
      break;

    default:
      addend += increment;
      contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
      score_bfd_put_32 (abfd, contents, address);
      break;
    }
}

/* Perform a relocation as part of a final link.  */
static bfd_reloc_status_type
score_elf_final_link_relocate (reloc_howto_type *howto,
			       bfd *input_bfd,
			       bfd *output_bfd,
			       asection *input_section,
			       bfd_byte *contents,
			       Elf_Internal_Rela *rel,
			       Elf_Internal_Rela *relocs,
			       bfd_vma symbol,
			       struct bfd_link_info *info,
			       const char *sym_name ATTRIBUTE_UNUSED,
			       int sym_flags ATTRIBUTE_UNUSED,
			       struct score_elf_link_hash_entry *h,
			       asection **local_sections,
			       bool gp_disp_p)
{
  unsigned long r_type;
  unsigned long r_symndx;
  bfd_byte *hit_data = contents + rel->r_offset;
  bfd_vma addend;
  /* The final GP value to be used for the relocatable, executable, or
     shared object file being produced.  */
  bfd_vma gp = MINUS_ONE;
  /* The place (section offset or address) of the storage unit being relocated.  */
  bfd_vma rel_addr;
  /* The offset into the global offset table at which the address of the relocation entry
     symbol, adjusted by the addend, resides during execution.  */
  bfd_vma g = MINUS_ONE;
  /* TRUE if the symbol referred to by this relocation is a local symbol.  */
  bool local_p;
  /* The eventual value we will relocate.  */
  bfd_vma value = symbol;
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;


  if (elf_gp (output_bfd) == 0)
    {
      struct bfd_link_hash_entry *bh;
      asection *o;

      bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
      if (bh != NULL && bh->type == bfd_link_hash_defined)
	elf_gp (output_bfd) = (bh->u.def.value
			       + bh->u.def.section->output_section->vma
			       + bh->u.def.section->output_offset);
      else if (bfd_link_relocatable (info))
	{
	  bfd_vma lo = -1;

	  /* Find the GP-relative section with the lowest offset.  */
	  for (o = output_bfd->sections; o != NULL; o = o->next)
	    if (o->vma < lo)
	      lo = o->vma;
	  /* And calculate GP relative to that.  */
	  elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
	}
      else
	{
	  /* If the relocate_section function needs to do a reloc
	     involving the GP value, it should make a reloc_dangerous
	     callback to warn that GP is not defined.  */
	}
    }

  /* Parse the relocation.  */
  r_symndx = ELF32_R_SYM (rel->r_info);
  r_type = ELF32_R_TYPE (rel->r_info);
  rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, true);

  if (r_type == R_SCORE_GOT15)
    {
      const Elf_Internal_Rela *relend;
      const Elf_Internal_Rela *lo16_rel;
      bfd_vma lo_value = 0;

      relend = relocs + input_section->reloc_count;
      lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
      if ((local_p) && (lo16_rel != NULL))
	{
	  bfd_vma tmp = 0;
	  tmp = score_bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
	  lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
	}
      addend = lo_value;
    }
  /* For score3 R_SCORE_ABS32.  */
  else if (r_type == R_SCORE_ABS32 || r_type == R_SCORE_REL32)
    {
      addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
    }
  else
    {
      addend = (score_bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
    }

  /* If we haven't already determined the GOT offset, or the GP value,
     and we're going to need it, get it now.  */
  switch (r_type)
    {
    case R_SCORE_CALL15:
    case R_SCORE_GOT15:
      if (!local_p)
	{
	  g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
					  (struct elf_link_hash_entry *) h);
	  if ((! elf_hash_table (info)->dynamic_sections_created
	       || (bfd_link_pic (info)
		   && (info->symbolic || h->root.dynindx == -1)
		   && h->root.def_regular)))
	    {
	      /* This is a static link or a -Bsymbolic link.  The
		 symbol is defined locally, or was forced to be local.
		 We must initialize this entry in the GOT.  */
	      bfd *tmpbfd = elf_hash_table (info)->dynobj;
	      asection *sgot = score_elf_got_section (tmpbfd, false);
	      score_bfd_put_32 (tmpbfd, value, sgot->contents + g);
	    }
	}
      else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
	{
	  /* There's no need to create a local GOT entry here; the
	     calculation for a local GOT15 entry does not involve G.  */
	  ;
	}
      else
	{
	  g = score_elf_local_got_index (output_bfd, input_bfd, info,
					 symbol + addend, r_symndx, h, r_type);
	    if (g == MINUS_ONE)
	    return bfd_reloc_outofrange;
	}

      /* Convert GOT indices to actual offsets.  */
      g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
					   output_bfd, input_bfd, g);
      break;

    case R_SCORE_HI16:
    case R_SCORE_LO16:
    case R_SCORE_GPREL32:
      gp = _bfd_get_gp_value (output_bfd);
      break;

    case R_SCORE_GP15:
      gp = _bfd_get_gp_value (output_bfd);

    default:
      break;
    }

  switch (r_type)
    {
    case R_SCORE_NONE:
      return bfd_reloc_ok;

    case R_SCORE_ABS32:
    case R_SCORE_REL32:
      if ((bfd_link_pic (info)
	   || (elf_hash_table (info)->dynamic_sections_created
	       && h != NULL
	       && h->root.def_dynamic
	       && !h->root.def_regular))
	   && r_symndx != STN_UNDEF
	   && (input_section->flags & SEC_ALLOC) != 0)
	{
	  /* If we're creating a shared library, or this relocation is against a symbol
	     in a shared library, then we can't know where the symbol will end up.
	     So, we create a relocation record in the output, and leave the job up
	     to the dynamic linker.  */
	  value = addend;
	  if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
						    symbol, &value,
						    input_section))
	    return bfd_reloc_undefined;
	}
      else if (r_symndx == STN_UNDEF)
	/* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
	   from removed linkonce sections, or sections discarded by
	   a linker script.  */
	value = 0;
      else
	{
	  if (r_type != R_SCORE_REL32)
	    value = symbol + addend;
	  else
	    value = addend;
	}
      value &= howto->dst_mask;
      bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_ABS16:
      value += addend;
      if ((long)value > 0x7fff || (long)value < -0x8000)
	return bfd_reloc_overflow;
      score_bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_24:
      addend = score_bfd_get_32 (input_bfd, hit_data);
      offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
      if ((offset & 0x1000000) != 0)
	offset |= 0xfe000000;
      value += offset;
      abs_value = value - rel_addr;
      if ((abs_value & 0xfe000000) != 0)
	return bfd_reloc_overflow;
      addend = (addend & ~howto->src_mask)
		| (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
      score_bfd_put_32 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    /* signed imm32.  */
    case R_SCORE_IMM30:
      {
	int not_word_align_p = 0;
	bfd_vma imm_offset = 0;
	addend = score_bfd_get_48 (input_bfd, hit_data);
	imm_offset = ((addend >> 7) & 0xff)
		     | (((addend >> 16) & 0x7fff) << 8)
		     | (((addend >> 32) & 0x7f) << 23);
	imm_offset <<= howto->rightshift;
	value += imm_offset;
	value &= 0xffffffff;

	/* Check lw48/sw48 rd, value/label word align.  */
	if ((value & 0x3) != 0)
	  not_word_align_p = 1;

	value >>= howto->rightshift;
	addend = (addend & ~howto->src_mask)
		 | (((value & 0xff) >> 0) << 7)
		 | (((value & 0x7fff00) >> 8) << 16)
		 | (((value & 0x3f800000) >> 23) << 32);
	score_bfd_put_48 (input_bfd, addend, hit_data);
	if (not_word_align_p)
	  return bfd_reloc_other;
	else
	  return bfd_reloc_ok;
      }

    case R_SCORE_IMM32:
      {
	bfd_vma imm_offset = 0;
	addend = score_bfd_get_48 (input_bfd, hit_data);
	imm_offset = ((addend >> 5) & 0x3ff)
		     | (((addend >> 16) & 0x7fff) << 10)
		     | (((addend >> 32) & 0x7f) << 25);
	value += imm_offset;
	value &= 0xffffffff;
	addend = (addend & ~howto->src_mask)
		 | ((value & 0x3ff) << 5)
		 | (((value >> 10) & 0x7fff) << 16)
		 | (((value >> 25) & 0x7f) << 32);
	score_bfd_put_48 (input_bfd, addend, hit_data);
	return bfd_reloc_ok;
      }

    case R_SCORE_PC19:
      addend = score_bfd_get_32 (input_bfd, hit_data);
      offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
      if ((offset & 0x80000) != 0)
	offset |= 0xfff00000;
      abs_value = value = value - rel_addr + offset;
      /* exceed 20 bit : overflow.  */
      if ((abs_value & 0x80000000) == 0x80000000)
	abs_value = 0xffffffff - value + 1;
      if ((abs_value & 0xfff80000) != 0)
	return bfd_reloc_overflow;
      addend = (addend & ~howto->src_mask)
		| (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
      score_bfd_put_32 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE16_11:
      addend = score_bfd_get_16 (input_bfd, hit_data);
      offset = addend & howto->src_mask;
      if ((offset & 0x800) != 0)	/* Offset is negative.  */
	offset |= 0xfffff000;
      value += offset;
      abs_value = value - rel_addr;
      if ((abs_value & 0xfffff000) != 0)
	return bfd_reloc_overflow;
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
      score_bfd_put_16 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE16_PC8:
      addend = score_bfd_get_16 (input_bfd, hit_data);
      offset = (addend & howto->src_mask) << 1;
      if ((offset & 0x200) != 0)	/* Offset is negative.  */
	offset |= 0xfffffe00;
      abs_value = value = value - rel_addr + offset;
      /* Sign bit + exceed 9 bit.  */
      if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
	return bfd_reloc_overflow;
      value >>= 1;
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
      score_bfd_put_16 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_BCMP:
      addend = score_bfd_get_32 (input_bfd, hit_data);
      offset = (addend & howto->src_mask) << howto->rightshift;
      if ((offset & 0x200) != 0)	/* Offset is negative.  */
	offset |= 0xfffffe00;
      value = value - rel_addr + offset;
      /* Sign bit + exceed 9 bit.  */
      if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
	return bfd_reloc_overflow;
      value >>= howto->rightshift;
      addend = (addend & ~howto->src_mask)
	       | (value & 0x1)
	       | (((value >> 1) & 0x7) << 7)
	       | (((value >> 4) & 0x1f) << 21);
      score_bfd_put_32 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_HI16:
      return bfd_reloc_ok;

    case R_SCORE_LO16:
      hi16_addend = score_bfd_get_32 (input_bfd, hit_data - 4);
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
      addend = score_bfd_get_32 (input_bfd, hit_data);
      offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
      offset = (hi16_offset << 16) | (offset & 0xffff);

      if (!gp_disp_p)
	uvalue = value + offset;
      else
	uvalue = offset + gp - rel_addr + 4;

      hi16_offset = (uvalue >> 16) << 1;
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
			| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
      score_bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
      offset = (uvalue & 0xffff) << 1;
      value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
      score_bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_GP15:
      addend = score_bfd_get_32 (input_bfd, hit_data);
      offset = addend & 0x7fff;
      if ((offset & 0x4000) == 0x4000)
	offset |= 0xffffc000;
      value = value + offset - gp;
      if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
	return bfd_reloc_overflow;
      value = (addend & ~howto->src_mask) | (value & howto->src_mask);
      score_bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_GOT15:
    case R_SCORE_CALL15:
      if (local_p)
	{
	  bool forced;

	  /* The special case is when the symbol is forced to be local.  We need the
	     full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
	  forced = ! score_elf_local_relocation_p (input_bfd, rel,
						   local_sections, false);
	  value = score_elf_got16_entry (output_bfd, input_bfd, info,
					 symbol + addend, forced);
	  if (value == MINUS_ONE)
	    return bfd_reloc_outofrange;
	  value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
						   output_bfd, input_bfd, value);
	}
      else
	{
	  value = g;
	}

      if ((long) value > 0x3fff || (long) value < -0x4000)
	return bfd_reloc_overflow;

      addend = score_bfd_get_32 (input_bfd, hit_data);
      value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
      score_bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_GPREL32:
      value = (addend + symbol - gp);
      value &= howto->dst_mask;
      score_bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_GOT_LO16:
      addend = score_bfd_get_32 (input_bfd, hit_data);
      value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
      value += symbol;
      value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
	       | (((value >> 14) & 0x3) << 16);

      score_bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_DUMMY_HI16:
      return bfd_reloc_ok;

    case R_SCORE_GNU_VTINHERIT:
    case R_SCORE_GNU_VTENTRY:
      /* We don't do anything with these at present.  */
      return bfd_reloc_continue;

    default:
      return bfd_reloc_notsupported;
    }
}

/* Score backend functions.  */
static bool
s3_bfd_score_info_to_howto (bfd *abfd,
			    arelent *bfd_reloc,
			    Elf_Internal_Rela *elf_reloc)
{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (elf_reloc->r_info);
  if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
			  abfd, r_type);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  bfd_reloc->howto = &elf32_score_howto_table[r_type];
  return true;
}

/* Relocate an score ELF section.  */
static int
s3_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)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  const char *name;
  unsigned long offset;
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
  size_t extsymoff;
  bool gp_disp_p = false;

  /* Sort dynsym.  */
  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfd_size_type dynsecsymcount = 0;
      if (bfd_link_pic (info))
	{
	  asection * p;
	  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);

	  for (p = output_bfd->sections; p ; p = p->next)
	    if ((p->flags & SEC_EXCLUDE) == 0
		&& (p->flags & SEC_ALLOC) != 0
		&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
	      ++ dynsecsymcount;
	}

      if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
	return false;
    }

  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
  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 score_elf_link_hash_entry *h;
      bfd_vma relocation = 0;
      bfd_reloc_status_type r;
      arelent bfd_reloc;

      r_symndx = ELF32_R_SYM (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);

      if (! s3_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel))
	continue;
      howto = bfd_reloc.howto;

      h = NULL;
      sym = NULL;
      sec = NULL;

      if (r_symndx < extsymoff)
	{
	  sym = local_syms + r_symndx;
	  sec = local_sections[r_symndx];
	  relocation = (sec->output_section->vma
			+ sec->output_offset
			+ sym->st_value);
	  name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);

	  if (!bfd_link_relocatable (info)
	      && (sec->flags & SEC_MERGE)
	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
	    {
	      asection *msec;
	      bfd_vma addend, value;

	      switch (r_type)
		{
		case R_SCORE_HI16:
		  break;
		case R_SCORE_LO16:
		  hi16_addend = score_bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
		  hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
		  offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
		  addend = (hi16_offset << 16) | (offset & 0xffff);
		  msec = sec;
		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
		  addend -= relocation;
		  addend += msec->output_section->vma + msec->output_offset;
		  uvalue = addend;
		  hi16_offset = (uvalue >> 16) << 1;
		  hi16_value = (hi16_addend & (~(howto->dst_mask)))
		    | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
		  score_bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
		  offset = (uvalue & 0xffff) << 1;
		  value = (value & (~(howto->dst_mask)))
		    | (offset & 0x7fff) | ((offset << 1) & 0x30000);
		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		  break;

		case R_SCORE_IMM32:
		  {
		    value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
		    addend = ((value >> 5) & 0x3ff)
			      | (((value >> 16) & 0x7fff) << 10)
			      | (((value >> 32) & 0x7f) << 25);
		    msec = sec;
		    addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
		    addend -= relocation;
		    addend += msec->output_section->vma + msec->output_offset;
		    addend &= 0xffffffff;
		    value = (value & ~howto->src_mask)
			     | ((addend & 0x3ff) << 5)
			     | (((addend >> 10) & 0x7fff) << 16)
			     | (((addend >> 25) & 0x7f) << 32);
		    score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
		    break;
		  }

		case R_SCORE_IMM30:
		  {
		    int not_word_align_p = 0;
		    value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
		    addend = ((value >> 7) & 0xff)
			      | (((value >> 16) & 0x7fff) << 8)
			      | (((value >> 32) & 0x7f) << 23);
		    addend <<= howto->rightshift;
		    msec = sec;
		    addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
		    addend -= relocation;
		    addend += msec->output_section->vma + msec->output_offset;
		    addend &= 0xffffffff;

		    /* Check lw48/sw48 rd, value/label word align.  */
		    if ((addend & 0x3) != 0)
		      not_word_align_p = 1;

		    addend >>= howto->rightshift;
		    value = (value & ~howto->src_mask)
			     | (((addend & 0xff) >> 0) << 7)
			     | (((addend & 0x7fff00) >> 8) << 16)
			     | (((addend & 0x3f800000) >> 23) << 32);
		    score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);

		    if (not_word_align_p)
		      return bfd_reloc_other;
		    else
		      break;
		  }

		case R_SCORE_GOT_LO16:
		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
		  addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
		  msec = sec;
		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
		  addend += msec->output_section->vma + msec->output_offset;
		  value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
			   | (((addend >> 14) & 0x3) << 16);

		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		  break;

		case R_SCORE_ABS32:
		case R_SCORE_REL32:
		  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  /* Get the (signed) value from the instruction.  */
		  addend = value & howto->src_mask;
		  if (addend & ((howto->src_mask + 1) >> 1))
		    {
		      bfd_signed_vma mask;

		      mask = -1;
		      mask &= ~howto->src_mask;
		      addend |= mask;
		    }
		  msec = sec;
		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
		  addend += msec->output_section->vma + msec->output_offset;
		  value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
		  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		  break;

		default:
		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
		  /* Get the (signed) value from the instruction.  */
		  addend = value & howto->src_mask;
		  if (addend & ((howto->src_mask + 1) >> 1))
		    {
		      bfd_signed_vma mask;

		      mask = -1;
		      mask &= ~howto->src_mask;
		      addend |= mask;
		    }
		  msec = sec;
		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
		  addend += msec->output_section->vma + msec->output_offset;
		  value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		  break;
		}
	    }
	}
      else
	{
	  /* For global symbols we look up the symbol in the hash-table.  */
	  h = ((struct score_elf_link_hash_entry *)
	       elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);

	  if (info->wrap_hash != NULL
	      && (input_section->flags & SEC_DEBUGGING) != 0)
	    h = ((struct score_elf_link_hash_entry *)
		 unwrap_hash_lookup (info, input_bfd, &h->root.root));

	  /* Find the real hash-table entry for this symbol.  */
	  while (h->root.root.type == bfd_link_hash_indirect
		 || h->root.root.type == bfd_link_hash_warning)
	    h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;

	  /* Record the name of this symbol, for our caller.  */
	  name = h->root.root.root.string;

	  /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
	     symbol must always be a global symbol.  */
	  if (strcmp (name, GP_DISP_LABEL) == 0)
	    {
	      /* Relocations against GP_DISP_LABEL are permitted only with
		 R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
	      if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
		return bfd_reloc_notsupported;

	      gp_disp_p = true;
	    }

	  /* If this symbol is defined, calculate its address.  Note that
	      GP_DISP_LABEL is a magic symbol, always implicitly defined by the
	      linker, so it's inappropriate to check to see whether or not
	      its defined.  */
	  else if ((h->root.root.type == bfd_link_hash_defined
		    || h->root.root.type == bfd_link_hash_defweak)
		   && h->root.root.u.def.section)
	    {
	      sec = h->root.root.u.def.section;
	      if (sec->output_section)
		relocation = (h->root.root.u.def.value
			      + sec->output_section->vma
			      + sec->output_offset);
	      else
		{
		  relocation = h->root.root.u.def.value;
		}
	    }
	  else if (h->root.root.type == bfd_link_hash_undefweak)
	    /* We allow relocations against undefined weak symbols, giving
	       it the value zero, so that you can undefined weak functions
	       and check to see if they exist by looking at their addresses.  */
	    relocation = 0;
	  else if (info->unresolved_syms_in_objects == RM_IGNORE
		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
	    relocation = 0;
	  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
	    {
	      /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
		 in s3_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
		 the symbol with a value of 0.  */
	      BFD_ASSERT (! bfd_link_pic (info));
	      BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
	      relocation = 0;
	    }
	  else if (!bfd_link_relocatable (info))
	    {
              info->callbacks->undefined_symbol
		(info, h->root.root.root.string, input_bfd, input_section,
		 rel->r_offset,
		 (info->unresolved_syms_in_objects == RM_DIAGNOSE
		  && !info->warn_unresolved_syms)
		 || ELF_ST_VISIBILITY (h->root.other));
              relocation = 0;
            }
	}

      if (sec != NULL && discarded_section (sec))
	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
					 rel, 1, relend, howto, 0, contents);

      if (bfd_link_relocatable (info))
	{
	  /* This is a relocatable 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.  */
	  if (r_symndx < symtab_hdr->sh_info)
	    {
	      sym = local_syms + r_symndx;
	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
		{
		  sec = local_sections[r_symndx];
		  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
				    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
		}
	    }
	  continue;
	}

      /* This is a final link.  */
      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
					 input_section, contents, rel, relocs,
					 relocation, info, name,
					 (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
					 ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
					 gp_disp_p);

      if (r != bfd_reloc_ok)
	{
	  const char *msg = (const char *)0;

	  switch (r)
	    {
	    case bfd_reloc_overflow:
	      /* If the overflowing reloc was to an undefined symbol,
		 we have already printed one error message and there
		 is no point complaining again.  */
	      if (!h || h->root.root.type != bfd_link_hash_undefined)
		(*info->callbacks->reloc_overflow)
		  (info, NULL, name, howto->name, (bfd_vma) 0,
		   input_bfd, input_section, rel->r_offset);
	      break;
	    case bfd_reloc_undefined:
	      (*info->callbacks->undefined_symbol)
		(info, name, input_bfd, input_section, rel->r_offset, true);
	      break;

	    case bfd_reloc_outofrange:
	      msg = _("internal error: out of range error");
	      goto common_error;

	    case bfd_reloc_notsupported:
	      msg = _("internal error: unsupported relocation error");
	      goto common_error;

	    case bfd_reloc_dangerous:
	      msg = _("internal error: dangerous error");
	      goto common_error;

	    /* Use bfd_reloc_other to check lw48, sw48 word align.  */
	    case bfd_reloc_other:
	      msg = _("address not word aligned");
	      goto common_error;

	    default:
	      msg = _("internal error: unknown error");
	      /* Fall through.  */

	    common_error:
	      (*info->callbacks->warning) (info, msg, name, input_bfd,
					   input_section, rel->r_offset);
	      break;
	    }
	}
    }

  return true;
}

/* Look through the relocs for a section during the first phase, and
   allocate space in the global offset table.  */
static bool
s3_bfd_score_elf_check_relocs (bfd *abfd,
			       struct bfd_link_info *info,
			       asection *sec,
			       const Elf_Internal_Rela *relocs)
{
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  struct score_got_info *g;
  size_t extsymoff;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sgot;
  asection *sreloc;

  if (bfd_link_relocatable (info))
    return true;

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;

  if (dynobj == NULL)
    {
      sgot = NULL;
      g = NULL;
    }
  else
    {
      sgot = score_elf_got_section (dynobj, false);
      if (sgot == NULL)
	g = NULL;
      else
	{
	  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
	  g = score_elf_section_data (sgot)->u.got_info;
	  BFD_ASSERT (g != NULL);
	}
    }

  sreloc = NULL;
  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; ++rel)
    {
      unsigned long r_symndx;
      unsigned int r_type;
      struct elf_link_hash_entry *h;

      r_symndx = ELF32_R_SYM (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);

      if (r_symndx < extsymoff)
	{
	  h = NULL;
	}
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: malformed reloc detected for section %pA"), abfd, sec);
	  bfd_set_error (bfd_error_bad_value);
	  return false;
	}
      else
	{
	  h = sym_hashes[r_symndx - extsymoff];

	  /* This may be an indirect symbol created because of a version.  */
	  if (h != NULL)
	    {
	      while (h->root.type == bfd_link_hash_indirect)
		h = (struct elf_link_hash_entry *)h->root.u.i.link;
	    }
	}

      /* Some relocs require a global offset table.  */
      if (dynobj == NULL || sgot == NULL)
	{
	  switch (r_type)
	    {
	    case R_SCORE_GOT15:
	    case R_SCORE_CALL15:
	      if (dynobj == NULL)
		elf_hash_table (info)->dynobj = dynobj = abfd;
	      if (!score_elf_create_got_section (dynobj, info, false))
		return false;
	      g = score_elf_got_info (dynobj, &sgot);
	      break;
	    case R_SCORE_ABS32:
	    case R_SCORE_REL32:
	      if (dynobj == NULL
		  && (bfd_link_pic (info) || h != NULL)
		  && (sec->flags & SEC_ALLOC) != 0)
		elf_hash_table (info)->dynobj = dynobj = abfd;
	      break;
	    default:
	      break;
	    }
	}

      if (!h && (r_type == R_SCORE_GOT_LO16))
	{
	  if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
	    return false;
	}

      switch (r_type)
	{
	case R_SCORE_CALL15:
	  if (h == NULL)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: CALL15 reloc at %#" PRIx64 " not against global symbol"),
		 abfd, (uint64_t) rel->r_offset);
	      bfd_set_error (bfd_error_bad_value);
	      return false;
	    }
	  else
	    {
	      /* This symbol requires a global offset table entry.  */
	      if (! score_elf_record_global_got_symbol (h, abfd, info, g))
		return false;

	      /* We need a stub, not a plt entry for the undefined function.  But we record
		 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
	      h->needs_plt = 1;
	      h->type = STT_FUNC;
	    }
	  break;
	case R_SCORE_GOT15:
	  if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
	    return false;
	  break;
	case R_SCORE_ABS32:
	case R_SCORE_REL32:
	  if ((bfd_link_pic (info) || h != NULL)
	      && (sec->flags & SEC_ALLOC) != 0)
	    {
	      if (sreloc == NULL)
		{
		  sreloc = score_elf_rel_dyn_section (dynobj, true);
		  if (sreloc == NULL)
		    return false;
		}
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
	      if (bfd_link_pic (info))
		{
		  /* When creating a shared object, we must copy these reloc types into
		     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
		     in the .rel.dyn reloc section.  */
		  score_elf_allocate_dynamic_relocations (dynobj, 1);
		  if ((sec->flags & SCORE_READONLY_SECTION)
		      == SCORE_READONLY_SECTION)
		    /* We tell the dynamic linker that there are
		       relocations against the text segment.  */
		    info->flags |= DF_TEXTREL;
		}
	      else
		{
		  struct score_elf_link_hash_entry *hscore;

		  /* We only need to copy this reloc if the symbol is
		     defined in a dynamic object.  */
		  hscore = (struct score_elf_link_hash_entry *)h;
		  ++hscore->possibly_dynamic_relocs;
		  if ((sec->flags & SCORE_READONLY_SECTION)
		      == SCORE_READONLY_SECTION)
		    /* We need it to tell the dynamic linker if there
		       are relocations against the text segment.  */
		    hscore->readonly_reloc = true;
		}

	      /* Even though we don't directly need a GOT entry for this symbol,
		 a symbol must have a dynamic symbol table index greater that
		 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
	      if (h != NULL)
		{
		  if (dynobj == NULL)
		    elf_hash_table (info)->dynobj = dynobj = abfd;
		  if (! score_elf_create_got_section (dynobj, info, true))
		    return false;
		  g = score_elf_got_info (dynobj, &sgot);
		  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
		    return false;
		}
	    }
	  break;

	  /* This relocation describes the C++ object vtable hierarchy.
	     Reconstruct it for later use during GC.  */
	case R_SCORE_GNU_VTINHERIT:
	  if (!bfd_elf_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_SCORE_GNU_VTENTRY:
	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
	    return false;
	  break;
	default:
	  break;
	}

      /* We must not create a stub for a symbol that has relocations
	 related to taking the function's address.  */
      switch (r_type)
	{
	default:
	  if (h != NULL)
	    {
	      struct score_elf_link_hash_entry *sh;

	      sh = (struct score_elf_link_hash_entry *) h;
	      sh->no_fn_stub = true;
	    }
	  break;
	case R_SCORE_CALL15:
	  break;
	}
    }

  return true;
}

static bool
s3_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)
{
  switch (sym->st_shndx)
    {
    case SHN_COMMON:
      if (sym->st_size > elf_gp_size (abfd))
	break;
      /* Fall through.  */
    case SHN_SCORE_SCOMMON:
      *secp = bfd_make_section_old_way (abfd, ".scommon");
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
      *valp = sym->st_size;
      break;
    }

  return true;
}

static void
s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
{
  elf_symbol_type *elfsym;

  elfsym = (elf_symbol_type *) asym;
  switch (elfsym->internal_elf_sym.st_shndx)
    {
    case SHN_COMMON:
      if (asym->value > elf_gp_size (abfd))
	break;
      /* Fall through.  */
    case SHN_SCORE_SCOMMON:
      asym->section = &score_elf_scom_section;
      asym->value = elfsym->internal_elf_sym.st_size;
      break;
    }
}

static int
s3_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 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;
}

static bool
s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
					   asection *sec,
					   int *retval)
{
  if (strcmp (bfd_section_name (sec), ".scommon") == 0)
    {
      *retval = SHN_SCORE_SCOMMON;
      return true;
    }

  return false;
}

/* 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 bool
s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
					struct elf_link_hash_entry *h)
{
  bfd *dynobj;
  struct score_elf_link_hash_entry *hscore;
  asection *s;

  dynobj = elf_hash_table (info)->dynobj;

  /* Make sure we know what is going on here.  */
  BFD_ASSERT (dynobj != NULL
	      && (h->needs_plt
		  || h->is_weakalias
		  || (h->def_dynamic && h->ref_regular && !h->def_regular)));

  /* If this symbol is defined in a dynamic object, we need to copy
     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
     file.  */
  hscore = (struct score_elf_link_hash_entry *)h;
  if (!bfd_link_relocatable (info)
      && hscore->possibly_dynamic_relocs != 0
      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
    {
      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
      if (hscore->readonly_reloc)
	/* We tell the dynamic linker that there are relocations
	   against the text segment.  */
	info->flags |= DF_TEXTREL;
    }

  /* For a function, create a stub, if allowed.  */
  if (!hscore->no_fn_stub && h->needs_plt)
    {
      if (!elf_hash_table (info)->dynamic_sections_created)
	return true;

      /* If this symbol is not defined in a regular file, then set
	 the symbol to the stub location.  This is required to make
	 function pointers compare as equal between the normal
	 executable and the shared library.  */
      if (!h->def_regular)
	{
	  /* We need .stub section.  */
	  s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
	  BFD_ASSERT (s != NULL);

	  h->root.u.def.section = s;
	  h->root.u.def.value = s->size;

	  /* XXX Write this stub address somewhere.  */
	  h->plt.offset = s->size;

	  /* Make room for this stub code.  */
	  s->size += SCORE_FUNCTION_STUB_SIZE;

	  /* The last half word of the stub will be filled with the index
	     of this symbol in .dynsym section.  */
	  return true;
	}
    }
  else if ((h->type == STT_FUNC) && !h->needs_plt)
    {
      /* This will set the entry for this symbol in the GOT to 0, and
	 the dynamic linker will take care of this.  */
      h->root.u.def.value = 0;
      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->is_weakalias)
    {
      struct elf_link_hash_entry *def = weakdef (h);
      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
      h->root.u.def.section = def->root.u.def.section;
      h->root.u.def.value = def->root.u.def.value;
      return true;
    }

  /* This is a reference to a symbol defined by a dynamic object which
     is not a function.  */
  return true;
}

/* This function is called after all the input files have been read,
   and the input sections have been assigned to output sections.  */
static bool
s3_bfd_score_elf_always_size_sections (bfd *output_bfd,
				       struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *s;
  struct score_got_info *g;
  int i;
  bfd_size_type loadable_size = 0;
  bfd_size_type local_gotno;
  bfd *sub;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj == NULL)
    /* Relocatable links don't have it.  */
    return true;

  g = score_elf_got_info (dynobj, &s);
  if (s == NULL)
    return true;

  /* Calculate the total loadable size of the output.  That will give us the
     maximum number of GOT_PAGE entries required.  */
  for (sub = info->input_bfds; sub; sub = sub->link.next)
    {
      asection *subsection;

      for (subsection = sub->sections;
	   subsection;
	   subsection = subsection->next)
	{
	  if ((subsection->flags & SEC_ALLOC) == 0)
	    continue;
	  loadable_size += ((subsection->size + 0xf)
			    &~ (bfd_size_type) 0xf);
	}
    }

  /* There has to be a global GOT entry for every symbol with
     a dynamic symbol table index of DT_SCORE_GOTSYM or
     higher.  Therefore, it make sense to put those symbols
     that need GOT entries at the end of the symbol table.  We
     do that here.  */
  if (! score_elf_sort_hash_table (info, 1))
    return false;

  if (g->global_gotsym != NULL)
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
  else
    /* If there are no global symbols, or none requiring
       relocations, then GLOBAL_GOTSYM will be NULL.  */
    i = 0;

  /* In the worst case, we'll get one stub per dynamic symbol.  */
  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;

  /* Assume there are two loadable segments consisting of
     contiguous sections.  Is 5 enough?  */
  local_gotno = (loadable_size >> 16) + 5;

  g->local_gotno += local_gotno;
  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);

  g->global_gotno = i;
  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);

  score_elf_resolve_final_got_entries (g);

  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
    {
      /* Fixme. Error message or Warning message should be issued here.  */
    }

  return true;
}

/* Set the sizes of the dynamic sections.  */
static bool
s3_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *s;
  bool 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 (bfd_link_executable (info) && !info->nointerp)
	{
	  s = bfd_get_linker_section (dynobj, ".interp");
	  BFD_ASSERT (s != NULL);
	  s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
	  s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
	}
    }

  /* The check_relocs and adjust_dynamic_symbol entry points have
     determined the sizes of the various dynamic sections.  Allocate
     memory for them.  */
  reltext = false;
  for (s = dynobj->sections; s != NULL; s = s->next)
    {
      const char *name;

      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_section_name (s);

      if (startswith (name, ".rel"))
	{
	  if (s->size == 0)
	    {
	      /* We only strip the section if the output section name
		 has the same name.  Otherwise, there might be several
		 input sections for this output section.  FIXME: This
		 code is probably not needed these days anyhow, since
		 the linker now does not create empty output sections.  */
	      if (s->output_section != NULL
		  && strcmp (name,
			     bfd_section_name (s->output_section)) == 0)
		s->flags |= SEC_EXCLUDE;
	    }
	  else
	    {
	      const char *outname;
	      asection *target;

	      /* If this relocation section applies to a read only
		 section, then we probably need a DT_TEXTREL entry.
		 If the relocation section is .rel.dyn, we always
		 assert a DT_TEXTREL entry rather than testing whether
		 there exists a relocation to a read only section or
		 not.  */
	      outname = bfd_section_name (s->output_section);
	      target = bfd_get_section_by_name (output_bfd, outname + 4);
	      if ((target != NULL
		   && (target->flags & SEC_READONLY) != 0
		   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
		reltext = true;

	      /* We use the reloc_count field as a counter if we need
		 to copy relocs into the output file.  */
	      if (strcmp (name, ".rel.dyn") != 0)
		s->reloc_count = 0;
	    }
	}
      else if (startswith (name, ".got"))
	{
	  /* s3_bfd_score_elf_always_size_sections() has already done
	     most of the work, but some symbols may have been mapped
	     to versions that we must now resolve in the got_entries
	     hash tables.  */
	}
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
	{
	  /* IRIX rld assumes that the function stub isn't at the end
	     of .text section. So put a dummy. XXX  */
	  s->size += SCORE_FUNCTION_STUB_SIZE;
	}
      else if (! startswith (name, ".init"))
	{
	  /* It's not one of our sections, so don't allocate space.  */
	  continue;
	}

      /* Allocate memory for the section contents.  */
      s->contents = bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL && s->size != 0)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return false;
	}
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
	 values later, in s3_bfd_score_elf_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 (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
	return false;

      if (reltext)
	info->flags |= DF_TEXTREL;

      if ((info->flags & DF_TEXTREL) != 0)
	{
	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
	    return false;
	}

      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
	return false;

      if (score_elf_rel_dyn_section (dynobj, false))
	{
	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
	    return false;

	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
	    return false;

	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
	    return false;
	}

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
	return false;

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
	return false;

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
	return false;

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
	return false;

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
	return false;

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
	return false;
    }

  return true;
}

static bool
s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
  struct elf_link_hash_entry *h;
  struct bfd_link_hash_entry *bh;
  flagword flags;
  asection *s;

  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
	   | SEC_LINKER_CREATED | SEC_READONLY);

  /* ABI requests the .dynamic section to be read only.  */
  s = bfd_get_linker_section (abfd, ".dynamic");
  if (s != NULL)
    {
      if (!bfd_set_section_flags (s, flags))
	return false;
    }

  /* We need to create .got section.  */
  if (!score_elf_create_got_section (abfd, info, false))
    return false;

  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, true))
    return false;

  /* Create .stub section.  */
  if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
    {
      s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
					      flags | SEC_CODE);
      if (s == NULL
	  || !bfd_set_section_alignment (s, 2))

	return false;
    }

  if (!bfd_link_pic (info))
    {
      const char *name;

      name = "_DYNAMIC_LINK";
      bh = NULL;
      if (!(_bfd_generic_link_add_one_symbol
	    (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
	     (bfd_vma) 0, NULL, false, get_elf_backend_data (abfd)->collect, &bh)))
	return false;

      h = (struct elf_link_hash_entry *)bh;
      h->non_elf = 0;
      h->def_regular = 1;
      h->type = STT_SECTION;

      if (!bfd_elf_link_record_dynamic_symbol (info, h))
	return false;
    }

  return true;
}


/* Finish up dynamic symbol handling.  We set the contents of various
   dynamic sections here.  */
static bool
s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
					struct bfd_link_info *info,
					struct elf_link_hash_entry *h,
					Elf_Internal_Sym *sym)
{
  bfd *dynobj;
  asection *sgot;
  struct score_got_info *g;
  const char *name;

  dynobj = elf_hash_table (info)->dynobj;

  if (h->plt.offset != MINUS_ONE)
    {
      asection *s;
      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];

      /* This symbol has a stub.  Set it up.  */
      BFD_ASSERT (h->dynindx != -1);

      s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
      BFD_ASSERT (s != NULL);

      /* FIXME: Can h->dynindex be more than 64K?  */
      if (h->dynindx & 0xffff0000)
	return false;

      /* Fill the stub.  */
      score_bfd_put_32 (output_bfd, STUB_LW, stub);
      score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
      score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
      score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12);

      BFD_ASSERT (h->plt.offset <= s->size);
      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);

      /* Mark the symbol as undefined.  plt.offset != -1 occurs
	 only for the referenced symbol.  */
      sym->st_shndx = SHN_UNDEF;

      /* The run-time linker uses the st_value field of the symbol
	  to reset the global offset table entry for this external
	  to its stub address when unlinking a shared object.  */
      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
    }

  BFD_ASSERT (h->dynindx != -1 || h->forced_local);

  sgot = score_elf_got_section (dynobj, false);
  BFD_ASSERT (sgot != NULL);
  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
  g = score_elf_section_data (sgot)->u.got_info;
  BFD_ASSERT (g != NULL);

  /* Run through the global symbol table, creating GOT entries for all
     the symbols that need them.  */
  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
    {
      bfd_vma offset;
      bfd_vma value;

      value = sym->st_value;
      offset = score_elf_global_got_index (dynobj, h);
      score_bfd_put_32 (output_bfd, value, sgot->contents + offset);
    }

  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
  name = h->root.root.string;
  if (h == elf_hash_table (info)->hdynamic
      || h == elf_hash_table (info)->hgot)
    sym->st_shndx = SHN_ABS;
  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
    {
      sym->st_shndx = SHN_ABS;
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
      sym->st_value = 1;
    }
  else if (strcmp (name, GP_DISP_LABEL) == 0)
    {
      sym->st_shndx = SHN_ABS;
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
      sym->st_value = elf_gp (output_bfd);
    }

  return true;
}

/* Finish up the dynamic sections.  */
static bool
s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
					  struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *sdyn;
  asection *sgot;
  asection *s;
  struct score_got_info *g;

  dynobj = elf_hash_table (info)->dynobj;

  sdyn = bfd_get_linker_section (dynobj, ".dynamic");

  sgot = score_elf_got_section (dynobj, false);
  if (sgot == NULL)
    g = NULL;
  else
    {
      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
      g = score_elf_section_data (sgot)->u.got_info;
      BFD_ASSERT (g != NULL);
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      bfd_byte *b;

      BFD_ASSERT (sdyn != NULL);
      BFD_ASSERT (g != NULL);

      for (b = sdyn->contents;
	   b < sdyn->contents + sdyn->size;
	   b += SCORE_ELF_DYN_SIZE (dynobj))
	{
	  Elf_Internal_Dyn dyn;
	  const char *name;
	  size_t elemsize;
	  bool swap_out_p;

	  /* Read in the current dynamic entry.  */
	  (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);

	  /* Assume that we're going to modify it and write it out.  */
	  swap_out_p = true;

	  switch (dyn.d_tag)
	    {
	    case DT_RELENT:
	      dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
	      break;

	    case DT_STRSZ:
	      /* Rewrite DT_STRSZ.  */
	      dyn.d_un.d_val
		= _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
	      break;

	    case DT_PLTGOT:
	      s = elf_hash_table (info)->sgot;
	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
	      break;

	    case DT_SCORE_BASE_ADDRESS:
	      s = output_bfd->sections;
	      BFD_ASSERT (s != NULL);
	      dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
	      break;

	    case DT_SCORE_LOCAL_GOTNO:
	      dyn.d_un.d_val = g->local_gotno;
	      break;

	    case DT_SCORE_UNREFEXTNO:
	      /* The index into the dynamic symbol table which is the
		 entry of the first external symbol that is not
		 referenced within the same object.  */
	      dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
	      break;

	    case DT_SCORE_GOTSYM:
	      if (g->global_gotsym)
		{
		  dyn.d_un.d_val = g->global_gotsym->dynindx;
		  break;
		}
	      /* In case if we don't have global got symbols we default
		  to setting DT_SCORE_GOTSYM to the same value as
		  DT_SCORE_SYMTABNO.  */
	      /* Fall through.  */

	    case DT_SCORE_SYMTABNO:
	      name = ".dynsym";
	      elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
	      s = bfd_get_linker_section (dynobj, name);
	      dyn.d_un.d_val = s->size / elemsize;
	      break;

	    case DT_SCORE_HIPAGENO:
	      dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
	      break;

	    default:
	      swap_out_p = false;
	      break;
	    }

	  if (swap_out_p)
	    (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
	}
    }

  /* The first entry of the global offset table will be filled at
     runtime. The second entry will be used by some runtime loaders.
     This isn't the case of IRIX rld.  */
  if (sgot != NULL && sgot->size > 0)
    {
      score_bfd_put_32 (output_bfd, 0, sgot->contents);
      score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
    }

  if (sgot != NULL)
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
      = SCORE_ELF_GOT_SIZE (output_bfd);


  /* We need to sort the entries of the dynamic relocation section.  */
  s = score_elf_rel_dyn_section (dynobj, false);

  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
    {
      reldyn_sorting_bfd = output_bfd;
      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
	     sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
    }

  return true;
}

/* This function set up the ELF section header for a BFD section in preparation for writing
   it out.  This is where the flags and type fields are set for unusual sections.  */
static bool
s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
				Elf_Internal_Shdr *hdr,
				asection *sec)
{
  const char *name;

  name = bfd_section_name (sec);

  if (strcmp (name, ".got") == 0
      || strcmp (name, ".srdata") == 0
      || strcmp (name, ".sdata") == 0
      || strcmp (name, ".sbss") == 0)
    hdr->sh_flags |= SHF_SCORE_GPREL;

  return true;
}

/* This function do additional processing on the ELF section header before writing
   it out.  This is used to set the flags and type fields for some sections.  */

/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
   warning message will be issued.  backend_fake_section is called before
   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
   modify section flag there, but not backend_fake_section.  */
static bool
s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
{
  if (hdr->bfd_section != NULL)
    {
      const char *name = bfd_section_name (hdr->bfd_section);

      if (strcmp (name, ".sdata") == 0)
	{
	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
	  hdr->sh_type = SHT_PROGBITS;
	}
      else if (strcmp (name, ".sbss") == 0)
	{
	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
	  hdr->sh_type = SHT_NOBITS;
	}
      else if (strcmp (name, ".srdata") == 0)
	{
	  hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
	  hdr->sh_type = SHT_PROGBITS;
	}
    }

  return true;
}

static bool
s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
{
  bfd_byte *to, *from, *end;
  int i;

  if (strcmp (sec->name, ".pdr") != 0)
    return false;

  if (score_elf_section_data (sec)->u.tdata == NULL)
    return false;

  to = contents;
  end = contents + sec->size;
  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
    {
      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
	continue;

      if (to != from)
	memcpy (to, from, PDR_SIZE);

      to += PDR_SIZE;
    }
  bfd_set_section_contents (output_bfd, sec->output_section, contents,
			    (file_ptr) sec->output_offset, sec->size);

  return true;
}

/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
   indirect symbol.  Process additional relocation information.  */
static void
s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
				       struct elf_link_hash_entry *dir,
				       struct elf_link_hash_entry *ind)
{
  struct score_elf_link_hash_entry *dirscore, *indscore;

  _bfd_elf_link_hash_copy_indirect (info, dir, ind);

  if (ind->root.type != bfd_link_hash_indirect)
    return;

  dirscore = (struct score_elf_link_hash_entry *) dir;
  indscore = (struct score_elf_link_hash_entry *) ind;
  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;

  if (indscore->readonly_reloc)
    dirscore->readonly_reloc = true;

  if (indscore->no_fn_stub)
    dirscore->no_fn_stub = true;
}

/* Remove information about discarded functions from other sections which mention them.  */
static bool
s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
			       struct bfd_link_info *info)
{
  asection *o;
  bool ret = false;
  unsigned char *tdata;
  size_t i, skip;

  o = bfd_get_section_by_name (abfd, ".pdr");
  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
    return false;

  tdata = bfd_zmalloc (o->size / PDR_SIZE);
  if (!tdata)
    return false;

  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
  if (!cookie->rels)
    {
      free (tdata);
      return false;
    }

  cookie->rel = cookie->rels;
  cookie->relend = cookie->rels + o->reloc_count;

  for (i = 0, skip = 0; i < o->size; i++)
    {
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
	{
	  tdata[i] = 1;
	  skip++;
	}
    }

  if (skip != 0)
    {
      score_elf_section_data (o)->u.tdata = tdata;
      o->size -= skip * PDR_SIZE;
      ret = true;
    }
  else
    free (tdata);

  if (!info->keep_memory)
    free (cookie->rels);

  return ret;
}

/* Signal that discard_info() has removed the discarded relocations for this section.  */
static bool
s3_bfd_score_elf_ignore_discarded_relocs (asection *sec)
{
  if (strcmp (sec->name, ".pdr") == 0)
    return true;
  return false;
}

/* Return the section that should be marked against GC for a given
   relocation.  */
static asection *
s3_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 (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_SCORE_GNU_VTINHERIT:
      case R_SCORE_GNU_VTENTRY:
	return NULL;
      }

  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}

/* Support for core dump NOTE sections.  */

static bool
s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  int offset;
  unsigned int raw_size;

  switch (note->descsz)
    {
    default:
      return false;

    case 148:		       /* Linux/Score 32-bit.  */
      /* pr_cursig */
      elf_tdata (abfd)->core->signal
	= score_bfd_get_16 (abfd, note->descdata + 12);

      /* pr_pid */
      elf_tdata (abfd)->core->lwpid
	= score_bfd_get_32 (abfd, note->descdata + 24);

      /* pr_reg */
      offset = 72;
      raw_size = 72;

      break;
    }

  /* Make a ".reg/999" section.  */
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
					  note->descpos + offset);
}

static bool
s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  switch (note->descsz)
    {
    default:
      return false;

    case 124:		       /* Linux/Score elf_prpsinfo.  */
      elf_tdata (abfd)->core->program
	= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
      elf_tdata (abfd)->core->command
	= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
    }

  /* Note that for some reason, a spurious space is tacked
     onto the end of the args in some (at least one anyway)
     implementations, so strip it off if it exists.  */

  {
    char *command = elf_tdata (abfd)->core->command;
    int n = strlen (command);

    if (0 < n && command[n - 1] == ' ')
      command[n - 1] = '\0';
  }

  return true;
}


/* Score BFD functions.  */
static reloc_howto_type *
s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];

  return NULL;
}

static reloc_howto_type *
elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
			       const char *r_name)
{
  unsigned int i;

  for (i = 0;
       i < (sizeof (elf32_score_howto_table)
	    / sizeof (elf32_score_howto_table[0]));
       i++)
    if (elf32_score_howto_table[i].name != NULL
	&& strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
      return &elf32_score_howto_table[i];

  return NULL;
}

static bool
s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
{
  FILE *file = (FILE *) ptr;

  BFD_ASSERT (abfd != NULL && ptr != NULL);

  /* Print normal ELF private data.  */
  _bfd_elf_print_private_bfd_data (abfd, ptr);

  /* xgettext:c-format */
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
    {
      fprintf (file, _(" [pic]"));
    }
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
    {
      fprintf (file, _(" [fix dep]"));
    }
  fputc ('\n', file);

  return true;
}

static bool
s3_elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  flagword in_flags;
  flagword out_flags;

  if (!_bfd_generic_verify_endian_match (ibfd, info))
    return false;

  /* FIXME: What should be checked when linking shared libraries?  */
  if ((ibfd->flags & DYNAMIC) != 0)
    return true;

  in_flags  = elf_elfheader (ibfd)->e_flags;
  out_flags = elf_elfheader (obfd)->e_flags;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return true;

  in_flags = elf_elfheader (ibfd)->e_flags;
  out_flags = elf_elfheader (obfd)->e_flags;

  if (! elf_flags_init (obfd))
    {
      elf_flags_init (obfd) = true;
      elf_elfheader (obfd)->e_flags = in_flags;

      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
	  && bfd_get_arch_info (obfd)->the_default)
	{
	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
	}

      return true;
    }

  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
    _bfd_error_handler
      (_("%pB: warning: linking PIC files with non-PIC files"), ibfd);

  /* FIXME: Maybe dependency fix compatibility should be checked here.  */

  return true;
}

static bool
s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
{
  struct _score_elf_section_data *sdata;
  size_t 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);
}

/*****************************************************************************/

/* s3_s7: backend hooks.  */
static bool
_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 int
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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 bool
_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,
			    bool 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 bool
_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 bool
_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 bool
_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 bool
_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);
}

/* Create a score elf linker hash table.
   This is a copy of _bfd_elf_link_hash_table_create() except with a
   different hash table entry creation function.  */

static struct bfd_link_hash_table *
elf32_score_link_hash_table_create (bfd *abfd)
{
  struct elf_link_hash_table *ret;
  size_t amt = sizeof (struct elf_link_hash_table);

  ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
  if (ret == NULL)
    return NULL;

  if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
				      sizeof (struct score_elf_link_hash_entry),
				      GENERIC_ELF_DATA))
    {
      free (ret);
      return NULL;
    }

  return &ret->root;
}

static bool
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 bool
elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
  if (bfd_get_mach (info->output_bfd) == bfd_mach_score3)
    return s3_elf32_score_merge_private_bfd_data (ibfd, info);
  else
    return s7_elf32_score_merge_private_bfd_data (ibfd, info);
}

static bool
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 bool
_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);
}

bool
_bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
{
  return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
}

/*****************************************************************************/


#define USE_REL				1
#define TARGET_LITTLE_SYM		score_elf32_le_vec
#define TARGET_LITTLE_NAME		"elf32-littlescore"
#define TARGET_BIG_SYM			score_elf32_be_vec
#define TARGET_BIG_NAME			"elf32-bigscore"
#define ELF_ARCH			bfd_arch_score
#define ELF_MACHINE_CODE		EM_SCORE
#define ELF_MACHINE_ALT1		EM_SCORE_OLD
#define ELF_MAXPAGESIZE			0x8000

#define elf_info_to_howto		NULL
#define elf_info_to_howto_rel		_bfd_score_info_to_howto
#define elf_backend_relocate_section	_bfd_score_elf_relocate_section
#define elf_backend_check_relocs	_bfd_score_elf_check_relocs
#define elf_backend_add_symbol_hook	_bfd_score_elf_add_symbol_hook
#define elf_backend_symbol_processing	_bfd_score_elf_symbol_processing
#define elf_backend_link_output_symbol_hook \
  _bfd_score_elf_link_output_symbol_hook
#define elf_backend_section_from_bfd_section \
  _bfd_score_elf_section_from_bfd_section
#define elf_backend_adjust_dynamic_symbol \
  _bfd_score_elf_adjust_dynamic_symbol
#define elf_backend_always_size_sections \
  _bfd_score_elf_always_size_sections
#define elf_backend_size_dynamic_sections \
  _bfd_score_elf_size_dynamic_sections
#define elf_backend_omit_section_dynsym   _bfd_elf_omit_section_dynsym_all
#define elf_backend_create_dynamic_sections \
  _bfd_score_elf_create_dynamic_sections
#define elf_backend_finish_dynamic_symbol \
  _bfd_score_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
  _bfd_score_elf_finish_dynamic_sections
#define elf_backend_fake_sections	  _bfd_score_elf_fake_sections
#define elf_backend_section_processing	  _bfd_score_elf_section_processing
#define elf_backend_write_section	  _bfd_score_elf_write_section
#define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
#define elf_backend_hide_symbol		  _bfd_score_elf_hide_symbol
#define elf_backend_discard_info	  _bfd_score_elf_discard_info
#define elf_backend_ignore_discarded_relocs \
  _bfd_score_elf_ignore_discarded_relocs
#define elf_backend_gc_mark_hook	  _bfd_score_elf_gc_mark_hook
#define elf_backend_grok_prstatus	  _bfd_score_elf_grok_prstatus
#define elf_backend_grok_psinfo		  _bfd_score_elf_grok_psinfo
#define elf_backend_can_gc_sections	  1
#define elf_backend_want_plt_sym	  0
#define elf_backend_got_header_size	  (4 * SCORE_RESERVED_GOTNO)
#define elf_backend_plt_header_size	  0
#define elf_backend_collect		  true
#define elf_backend_type_change_ok	  true
#define elf_backend_object_p		      _bfd_score_elf_score_object_p

#define bfd_elf32_bfd_reloc_type_lookup	     elf32_score_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup \
  elf32_score_reloc_name_lookup
#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
#define bfd_elf32_new_section_hook	     elf32_score_new_section_hook

#include "elf32-target.h"
