/* 32-bit ELF support for S+core.
   Copyright (C) 2009-2025 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"


/* 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    0x8323bc56     /* mv r25, 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_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 = bfd_get_32 (abfd, hi16_rel_addr);
  hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
  addend = 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);
  bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
  offset = (uvalue & 0xffff) << 1;
  addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
  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 = 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);
  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 += 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)
    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;
      if (output_bfd == NULL)
	return bfd_reloc_undefined;
    }

  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 = bfd_get_32 (abfd, hi16_rel_addr);
  hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
  addend = 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);
  bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
  offset = (uvalue & 0xffff) << 1;
  addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
  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 */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 1,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc, /* special_function */
	 "R_SCORE_BCMP",	/* name */
	 true,			/* partial_inplace */
	 0x0000ffff,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  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 */
	 8,			/* 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 */
	 0x000000ff,		/* src_mask */
	 0x000000ff,		/* 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 */
	 0x00007fff,		/* src_mask */
	 0x00007fff,		/* 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 */
};

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

static inline hashval_t
score_elf_hash_bfd_vma (bfd_vma addr)
{
#ifdef BFD64
  return addr + (addr >> 32);
#else
  return addr;
#endif
}

/* 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 ? score_elf_hash_bfd_vma (entry->d.address)
       : entry->abfd->id
	 + (entry->symndx >= 0 ? score_elf_hash_bfd_vma (entry->d.addend)
	    : entry->d.h->root.root.root.hash));
}

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

/* 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;
  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.r_offset =
    _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset);

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

  if (outrel.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.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.  */

  /* Adjust the output offset of the relocation to reference the
     correct location in the output file.  */
  outrel.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,
     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;
    }

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

void
s7_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:
	  s7_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 = 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);
      bfd_put_32 (abfd, contents, address);
      break;
    case R_SCORE_HI16:
      break;
    case R_SCORE_LO16:
      hi16_addend = 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);
      bfd_put_32 (abfd, hi16_value, address - 4);
      offset = (uvalue & 0xffff) << 1;
      contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
      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);
      bfd_put_32 (abfd, contents, address);
      break;
    case R_SCORE16_11:

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

      break;
    case R_SCORE16_PC8:

      contents = bfd_get_16 (abfd, address);
      offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
      bfd_put_16 (abfd, contents, address);

      break;
    case R_SCORE_GOT15:
    case R_SCORE_GOT_LO16:
      break;

    default:
      addend += increment;
      contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
      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,
			       Elf_Internal_Sym *local_syms,
			       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 value of GP used to create the relocatable object.  */
  bfd_vma gp0 = MINUS_ONE;
  /* 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;

  Elf_Internal_Sym *sym = 0;
  asection *sec = NULL;
  bool merge_p = 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_offset);
	  if (bh->u.def.section->output_section)
	    elf_gp (output_bfd) += bh->u.def.section->output_section->vma;
	}
      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);

  /* For hidden symbol.  */
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, false);
  if (local_p)
    {
      sym = local_syms + r_symndx;
      sec = local_sections[r_symndx];

      symbol = sec->output_section->vma + sec->output_offset;
      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
	  || (sec->flags & SEC_MERGE))
	symbol += sym->st_value;
      if ((sec->flags & SEC_MERGE)
	  && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
	merge_p = 1;
    }

  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 = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
	  lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
	  if (merge_p)
	    {
	      asection *msec = sec;
	      lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
	      lo_value -= symbol;
	      lo_value += msec->output_section->vma + msec->output_offset;
	    }
	}
      addend = lo_value;
    }
  else
    {
      addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
    }

  /* Figure out the value of the symbol.  */
  if (local_p && !merge_p)
    {
      if (r_type == R_SCORE_GOT15)
	{
	  const Elf_Internal_Rela *relend;
	  const Elf_Internal_Rela *lo16_rel;
	  bfd_vma lo_value = 0;

	  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
	  addend = value & 0x7fff;
	  if ((addend & 0x4000) == 0x4000)
	    addend |= 0xffffc000;

	  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 = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
	      lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
	    }

	  addend <<= 16;
	  addend += lo_value;
	}
    }

  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, true);

  /* 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);
	      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:
      gp0 = _bfd_get_gp_value (input_bfd);
      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;
      bfd_put_16 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_24:
      addend = 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);
      bfd_put_32 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_PC19:
      addend = 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);
      bfd_put_32 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

    case R_SCORE16_11:
      addend = 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);
      bfd_put_16 (input_bfd, addend, hit_data);
      return bfd_reloc_ok;

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

    case R_SCORE_HI16:
      return bfd_reloc_ok;

    case R_SCORE_LO16:
      hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
      addend = 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);
      bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
      offset = (uvalue & 0xffff) << 1;
      value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
      bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

    case R_SCORE_GP15:
      addend = 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);
      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 = bfd_get_32 (input_bfd, hit_data);
      value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
      bfd_put_32 (input_bfd, value, hit_data);
      return bfd_reloc_ok;

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

    case R_SCORE_GOT_LO16:
      addend = 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);

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

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

int
s7_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 (! s7_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;
	  name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);

	  if (!bfd_link_relocatable (info))
	    {
	      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
		      || (sec->flags & SEC_MERGE))
		{
		      relocation += sym->st_value;
		    }

	      if ((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 = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
		      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
		      value = 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);
		      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);
		      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		      break;
		    case R_SCORE_GOT_LO16:
		      value = 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);

		      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		      break;
		    default:
		      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;
		    }
		}
	    }
	}
      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 s7_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, R_SCORE_NONE,
					 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 (r_type == R_SCORE_GOT15)
		{
		  const Elf_Internal_Rela *lo16_rel;
		  bfd_vma lo_addend = 0, lo_value = 0;
		  bfd_vma addend, value;

		  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  addend = value & 0x7fff;
		  if ((addend & 0x4000) == 0x4000)
		    addend |= 0xffffc000;

		  relend = relocs + input_section->reloc_count;
		  lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
		  if (lo16_rel != NULL)
		    {
		      lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
		      lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
		    }

		  addend <<= 16;
		  addend += lo_addend;

		  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
		    addend += local_sections[r_symndx]->output_offset;

		  lo_addend = addend & 0xffff;
		  lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
			      | (((lo_addend >> 14) & 0x3) << 16);
		  bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);

		  addend = addend >> 16;
		  value = (value & ~howto->src_mask) | (addend & howto->src_mask);
		  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
		}
	      else 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_syms,
					 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;

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

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

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

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

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

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

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

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

bool
s7_bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *s;
  bool reltext;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj == NULL)
    return true;

  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;
	  s->alloced = 1;
	}
    }

  /* 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"))
	{
	  /* s7_bfd_score_elf_early_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;
	}
      s->alloced = 1;
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
	 values later, in s7_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;
}

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

bool
s7_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)
	{
	  _bfd_error_handler
	    (_("%pB: cannot handle more than %d dynamic symbols"),
	     output_bfd, 0xffff);
	  bfd_set_error (bfd_error_bad_value);
	  return false;
	}

      /* Fill the stub.  */
      bfd_put_32 (output_bfd, STUB_LW, stub);
      bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
      bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
      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);
      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.  */

bool
s7_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)
    {
      bfd_put_32 (output_bfd, 0, sgot->contents);
      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.  */

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

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

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

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

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

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

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

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

  switch (note->descsz)
    {
    default:
      return false;
    case 272:		       /* Linux/Score elf_prstatus */

      /* pr_cursig */
      elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);

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

      /* pr_reg */
      offset = 72;

      /* sizeof(elf_gregset_t) */
      raw_size = 196;

      break;
    }

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

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

    case 128:		       /* Linux/Score elf_prpsinfo.  */
      /* pr_fname */
      elf_tdata (abfd)->core->program
	= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);

      /* pr_psargs */
      elf_tdata (abfd)->core->command
	= _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
      break;
    }

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

reloc_howto_type *
s7_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;
}

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

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

  /* Maybe dependency fix compatibility should be checked here.  */
  return true;
}

bool
s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
{
  struct _score_elf_section_data *sdata;

  sdata = bfd_zalloc (abfd, sizeof (*sdata));
  if (sdata == NULL)
    return false;
  sec->used_by_bfd = sdata;

  return _bfd_elf_new_section_hook (abfd, sec);
}

#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
