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

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

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


int score3 = 0;
int score7 = 1;

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

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

  /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section.  */
  bfd_boolean 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.  */
  bfd_boolean 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.  */
  bfd_boolean forced_local;
};

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

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

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

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

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

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

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

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

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

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

#define PDR_SIZE 32


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

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

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

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

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

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

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

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

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

static bfd_byte *hi16_rel_addr;

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

/* SCORE ELF uses two common sections.  One is the usual one, and the
   other is for small objects.  All the small objects are kept
   together, and then referenced via the gp pointer, which yields
   faster assembler code.  This is what we use for the small common
   section.  This approach is copied from ecoff.c.  */
static asection score_elf_scom_section;
static asymbol  score_elf_scom_symbol;
static asymbol  *score_elf_scom_symbol_ptr;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static bfd_boolean
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,
                    bfd_boolean 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,
                           asymbol *symbol,
                           arelent *reloc_entry,
                           asection *input_section,
                           bfd_boolean relocateable,
                           void * data,
                           bfd_vma gp ATTRIBUTE_UNUSED)
{
  bfd_vma relocation;
  unsigned long insn;

  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 > input_section->size)
    return bfd_reloc_outofrange;

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

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

  return bfd_reloc_ok;
}

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

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

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

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

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

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

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

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

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

  return bfd_reloc_ok;
}

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

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

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

  return score_elf_gprel15_with_gp (abfd, symbol, 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)
{
  bfd_boolean 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_get_section (symbol))
      || bfd_is_com_section (bfd_get_section (symbol)))
    /* The relocation is against a global symbol.  */
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
                                  input_section, output_bfd,
                                  error_message);

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

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

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

static reloc_howto_type elf32_score_howto_table[] =
{
  /* No relocation.  */
  HOWTO (R_SCORE_NONE,          /* type */
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         1,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         score_elf_lo16_reloc,  /* special_function */
         "R_SCORE_LO16",        /* name */
         TRUE,                  /* partial_inplace */
         0x37fff,               /* src_mask */
         0x37fff,               /* dst_mask */
         FALSE),                /* pcrel_offset */

  /*  R_SCORE_BCMP */
  HOWTO (R_SCORE_BCMP,          /* type */
         1,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         TRUE,                  /* pc_relative */
         1,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_SCORE_BCMP",        /* name */
         FALSE,                 /* partial_inplace */
         0x03e00381,            /* src_mask */
         0x03e00381,            /* dst_mask */
         FALSE),                /* pcrel_offset */

  /*R_SCORE_24 */
  HOWTO (R_SCORE_24,            /* type */
         1,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         9,                     /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_SCORE16_PC8",       /* name */
         FALSE,                 /* partial_inplace */
         0x000001ff,            /* src_mask */
         0x000001ff,            /* dst_mask */
         FALSE),                /* pcrel_offset */

  /* 32 bit absolute */
  HOWTO (R_SCORE_ABS32,         /* type  8 */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,    /* complain_on_overflow */
         bfd_elf_generic_reloc, /* 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 */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         NULL,                  /* special_function */
         "R_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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
         "R_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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_SCORE_CALL15",      /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */

  /* 32 bit GP relative reference.  */
  HOWTO (R_SCORE_GPREL32,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         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 */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         1,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         score_elf_hi16_reloc,  /* special_function */
         "R_SCORE_DUMMY_HI16",  /* name */
         TRUE,                  /* partial_inplace */
         0x37fff,               /* src_mask */
         0x37fff,               /* dst_mask */
         FALSE),                /* pcrel_offset */

  /* R_SCORE_IMM30 */
  HOWTO (R_SCORE_IMM30,         /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         30,                    /* bitsize */
         FALSE,                 /* pc_relative */
         7,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_SCORE_IMM30",       /* name */
         FALSE,                 /* partial_inplace */
         0x7f7fff7f80LL,        /* src_mask */
         0x7f7fff7f80LL,        /* dst_mask */
         FALSE),                /* pcrel_offset */

  /* R_SCORE_IMM32 */
  HOWTO (R_SCORE_IMM32,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
         FALSE,                 /* pc_relative */
         5,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_SCORE_IMM32",       /* name */
         FALSE,                 /* partial_inplace */
         0x7f7fff7fe0LL,        /* src_mask */
         0x7f7fff7fe0LL,        /* dst_mask */
         FALSE),                /* pcrel_offset */
};

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

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

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

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

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

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

/* If H needs a GOT entry, assign it the highest available dynamic
   index.  Otherwise, assign it the lowest available dynamic
   index.  */
static bfd_boolean
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, bfd_boolean maybe_excluded)
{
  asection *sgot = bfd_get_linker_section (abfd, ".got");

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

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

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

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

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

  dynobj = elf_hash_table (info)->dynobj;

  g = score_elf_got_info (dynobj, NULL);

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

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

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

  return TRUE;
}

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

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

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

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

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

  return (struct bfd_hash_entry *) ret;
}

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

      ++relocation;
    }

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

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

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

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

/* Return whether a relocation is against a local symbol.  */
static bfd_boolean
score_elf_local_relocation_p (bfd *input_bfd,
                              const Elf_Internal_Rela *relocation,
                              asection **local_sections,
                              bfd_boolean 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, bfd_boolean 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 (dynobj, 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 bfd_boolean
score_elf_create_dynamic_relocation (bfd *output_bfd,
                                     struct bfd_link_info *info,
                                     const Elf_Internal_Rela *rel,
                                     struct score_elf_link_hash_entry *h,
                                     bfd_vma symbol,
                                     bfd_vma *addendp, asection *input_section)
{
  Elf_Internal_Rela outrel[3];
  asection *sreloc;
  bfd *dynobj;
  int r_type;
  long indx;
  bfd_boolean defined_p;

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

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

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

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

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

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

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

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

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

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

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

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

  return TRUE;
}

static bfd_boolean
score_elf_create_got_section (bfd *abfd,
                              struct bfd_link_info *info,
                              bfd_boolean maybe_exclude)
{
  flagword flags;
  asection *s;
  struct elf_link_hash_entry *h;
  struct bfd_link_hash_entry *bh;
  struct score_got_info *g;
  bfd_size_type 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);
   if (s == NULL
      || ! bfd_set_section_alignment (abfd, 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;

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

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

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

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

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

  return TRUE;
}

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

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

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

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

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

  *loc = bfd_alloc (abfd, sizeof entry);

  if (! *loc)
    return NULL;

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

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

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

  return *loc;
}

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

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

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

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

static void
s3_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
                              struct elf_link_hash_entry *entry,
                              bfd_boolean 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 bfd_boolean
score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
                                    bfd *abfd,
                                    struct bfd_link_info *info,
                                    struct score_got_info *g)
{
  struct score_got_entry entry, **loc;

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

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

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

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

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

  entry.gotidx = -1;

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

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

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

  return TRUE;
}

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

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

  if (*loc)
    return TRUE;

  entry.gotidx = g->local_gotno++;

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

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

  return TRUE;
}

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

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

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

  else
    return entry->gotidx;
}

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

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

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

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

  return got_index;
}

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

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

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

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

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

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

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

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

      entry->d.h = h;

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

  return 1;
}

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

  do
    {
      got_entries = g->got_entries;

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

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

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

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

    case R_SCORE16_11:

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

      break;
    case R_SCORE16_PC8:

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

      break;

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

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

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

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

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


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

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

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

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

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

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

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

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

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

    case R_SCORE_GP15:
      gp = _bfd_get_gp_value (output_bfd);

    default:
      break;
    }

  switch (r_type)
    {
    case R_SCORE_NONE:
      return bfd_reloc_ok;

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

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

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

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

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

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

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

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

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

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

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

    case R_SCORE_HI16:
      return bfd_reloc_ok;

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

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

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

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

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

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

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

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

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

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

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

    case R_SCORE_DUMMY_HI16:
      return bfd_reloc_ok;

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

    default:
      return bfd_reloc_notsupported;
    }
}

/* Score backend functions.  */
static void
s3_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                            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))
    bfd_reloc->howto = NULL;
  else
    bfd_reloc->howto = &elf32_score_howto_table[r_type];
}

/* Relocate an score ELF section.  */
static bfd_boolean
s3_bfd_score_elf_relocate_section (bfd *output_bfd,
                                   struct bfd_link_info *info,
                                   bfd *input_bfd,
                                   asection *input_section,
                                   bfd_byte *contents,
                                   Elf_Internal_Rela *relocs,
                                   Elf_Internal_Sym *local_syms,
                                   asection **local_sections)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  const char *name;
  unsigned long offset;
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
  size_t extsymoff;
  bfd_boolean 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);

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

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

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

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

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

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

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

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

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

                    if (not_word_align_p)
                      return bfd_reloc_other;
                    else
                      break;
                  }

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

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

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

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

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

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

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

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

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

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

              gp_disp_p = TRUE;
            }

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

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

      if (bfd_link_relocatable (info))
        {
          /* This is a relocatable link.  We don't have to change
             anything, unless the reloc is against a section symbol,
             in which case we have to adjust according to where the
             section symbol winds up in the output section.  */
          if (r_symndx < symtab_hdr->sh_info)
            {
              sym = local_syms + r_symndx;
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
                {
                  sec = local_sections[r_symndx];
                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
                                    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
                }
            }
          continue;
        }

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

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

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

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

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

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

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

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

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

  return TRUE;
}

/* Look through the relocs for a section during the first phase, and
   allocate space in the global offset table.  */
static bfd_boolean
s3_bfd_score_elf_check_relocs (bfd *abfd,
                               struct bfd_link_info *info,
                               asection *sec,
                               const Elf_Internal_Rela *relocs)
{
  const char *name;
  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;
  const struct elf_backend_data *bed;

  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;

  name = bfd_get_section_name (abfd, sec);

  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;
  bed = get_elf_backend_data (abfd);
  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
  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) (_("%s: Malformed reloc detected for section %s"), abfd, name);
          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;

	      /* PR15323, ref flags aren't set for references in the
		 same object.  */
	      h->root.non_ir_ref = 1;
            }
        }

      /* 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)
                (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
                 abfd, (unsigned long) rel->r_offset);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
          else
            {
              /* This symbol requires a global offset table entry.  */
              if (! score_elf_record_global_got_symbol (h, abfd, info, g))
                return FALSE;

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

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

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

          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_SCORE_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;

          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_SCORE_GNU_VTENTRY:
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
        default:
          break;
        }

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

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

  return TRUE;
}

static bfd_boolean
s3_bfd_score_elf_add_symbol_hook (bfd *abfd,
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                  Elf_Internal_Sym *sym,
                                  const char **namep ATTRIBUTE_UNUSED,
                                  flagword *flagsp ATTRIBUTE_UNUSED,
                                  asection **secp,
                                  bfd_vma *valp)
{
  switch (sym->st_shndx)
    {
    case SHN_COMMON:
      if (sym->st_size > elf_gp_size (abfd))
        break;
      /* Fall through.  */
    case SHN_SCORE_SCOMMON:
      *secp = bfd_make_section_old_way (abfd, ".scommon");
      (*secp)->flags |= SEC_IS_COMMON;
      *valp = sym->st_size;
      break;
    }

  return TRUE;
}

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

  elfsym = (elf_symbol_type *) asym;
  switch (elfsym->internal_elf_sym.st_shndx)
    {
    case SHN_COMMON:
      if (asym->value > elf_gp_size (abfd))
        break;
      /* Fall through.  */
    case SHN_SCORE_SCOMMON:
      if (score_elf_scom_section.name == NULL)
        {
          /* Initialize the small common section.  */
          score_elf_scom_section.name = ".scommon";
          score_elf_scom_section.flags = SEC_IS_COMMON;
          score_elf_scom_section.output_section = &score_elf_scom_section;
          score_elf_scom_section.symbol = &score_elf_scom_symbol;
          score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
          score_elf_scom_symbol.name = ".scommon";
          score_elf_scom_symbol.flags = BSF_SECTION_SYM;
          score_elf_scom_symbol.section = &score_elf_scom_section;
          score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
        }
      asym->section = &score_elf_scom_section;
      asym->value = elfsym->internal_elf_sym.st_size;
      break;
    }
}

static int
s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                          const char *name ATTRIBUTE_UNUSED,
                                          Elf_Internal_Sym *sym,
                                          asection *input_sec,
                                          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
{
  /* If we see a common symbol, which implies a relocatable link, then
     if a symbol was small common in an input file, mark it as small
     common in the output file.  */
  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
    sym->st_shndx = SHN_SCORE_SCOMMON;

  return 1;
}

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

  return FALSE;
}

/* Adjust a symbol defined by a dynamic object and referenced by a
   regular object.  The current definition is in some section of the
   dynamic object, but we're not including those sections.  We have to
   change the definition to something the rest of the link can understand.  */
static bfd_boolean
s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                                        struct elf_link_hash_entry *h)
{
  bfd *dynobj;
  struct score_elf_link_hash_entry *hscore;
  asection *s;

  dynobj = elf_hash_table (info)->dynobj;

  /* Make sure we know what is going on here.  */
  BFD_ASSERT (dynobj != NULL
              && (h->needs_plt
                  || h->u.weakdef != NULL
                  || (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->u.weakdef != NULL)
    {
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
      return TRUE;
    }

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

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

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

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

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

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

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

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

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

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

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

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

  score_elf_resolve_final_got_entries (g);

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

  return TRUE;
}

/* Set the sizes of the dynamic sections.  */
static bfd_boolean
s3_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *s;
  bfd_boolean reltext;

  dynobj = elf_hash_table (info)->dynobj;
  BFD_ASSERT (dynobj != NULL);

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Set the contents of the .interp section to the interpreter.  */
      if (!bfd_link_pic (info) && !info->nointerp)
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
          s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
        }
    }

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

      if ((s->flags & SEC_LINKER_CREATED) == 0)
        continue;

      /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
      name = bfd_get_section_name (dynobj, s);

      if (CONST_STRNEQ (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_get_section_name (s->output_section->owner,
                                                   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_get_section_name (output_bfd, 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 (CONST_STRNEQ (name, ".got"))
        {
          /* s3_bfd_score_elf_always_size_sections() has already done
             most of the work, but some symbols may have been mapped
             to versions that we must now resolve in the got_entries
             hash tables.  */
        }
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
        {
          /* IRIX rld assumes that the function stub isn't at the end
             of .text section. So put a dummy. XXX  */
          s->size += SCORE_FUNCTION_STUB_SIZE;
        }
      else if (! CONST_STRNEQ (name, ".init"))
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
        }

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

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
         values later, in s3_bfd_score_elf_finish_dynamic_sections, but we
         must add the entries now so that we get the correct size for
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */

      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
        return FALSE;

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

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

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

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

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

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

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

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

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

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

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

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

  return TRUE;
}

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

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

  /* ABI requests the .dynamic section to be read only.  */
  s = bfd_get_linker_section (abfd, ".dynamic");
  if (s != NULL)
    {
      if (!bfd_set_section_flags (abfd, 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 (abfd, s, 2))

        return FALSE;
    }

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

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

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

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

  return TRUE;
}


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

  dynobj = elf_hash_table (info)->dynobj;

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TRUE;
}

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

  dynobj = elf_hash_table (info)->dynobj;

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

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

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

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

      for (b = sdyn->contents;
           b < sdyn->contents + sdyn->size;
           b += SCORE_ELF_DYN_SIZE (dynobj))
        {
          Elf_Internal_Dyn dyn;
          const char *name;
          size_t elemsize;
          bfd_boolean 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:
              name = ".got";
              s = bfd_get_linker_section (dynobj, name);
              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, so we just fall through.  */

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

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

            default:
              swap_out_p = FALSE;
              break;
            }

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

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

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


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

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

  return TRUE;
}

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

  name = bfd_get_section_name (abfd, sec);

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

  return TRUE;
}

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

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

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

  return TRUE;
}

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

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

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

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

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

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

  return TRUE;
}

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

  _bfd_elf_link_hash_copy_indirect (info, dir, ind);

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

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

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

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

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

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

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

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

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

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

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

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

  return ret;
}

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

/* Return the section that should be marked against GC for a given
   relocation.  */
static asection *
s3_bfd_score_elf_gc_mark_hook (asection *sec,
                               struct bfd_link_info *info,
                               Elf_Internal_Rela *rel,
                               struct elf_link_hash_entry *h,
                               Elf_Internal_Sym *sym)
{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_SCORE_GNU_VTINHERIT:
      case R_SCORE_GNU_VTENTRY:
        return NULL;
      }

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

/* Support for core dump NOTE sections.  */

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

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

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

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

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

      break;
    }

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

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

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

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

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

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

  return TRUE;
}


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

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

  return NULL;
}

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

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

  return NULL;
}

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

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

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

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

  return TRUE;
}

static bfd_boolean
s3_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  flagword in_flags;
  flagword out_flags;

  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
    return FALSE;

  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) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
    }

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

  return TRUE;
}

static bfd_boolean
s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
{
  struct _score_elf_section_data *sdata;
  bfd_size_type amt = sizeof (*sdata);

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

  return _bfd_elf_new_section_hook (abfd, sec);
}

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

/* s3_s7: backend hooks.  */
static void
_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                          arelent *bfd_reloc,
                          Elf_Internal_Rela *elf_reloc)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
  else
    return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
}

static bfd_boolean
_bfd_score_elf_relocate_section (bfd *output_bfd,
                                 struct bfd_link_info *info,
                                 bfd *input_bfd,
                                 asection *input_section,
                                 bfd_byte *contents,
                                 Elf_Internal_Rela *relocs,
                                 Elf_Internal_Sym *local_syms,
                                 asection **local_sections)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_relocate_section (output_bfd,
             info, input_bfd, input_section, contents, relocs,
             local_syms, local_sections);
  else
    return s7_bfd_score_elf_relocate_section (output_bfd,
             info, input_bfd, input_section, contents, relocs,
             local_syms, local_sections);
}

static bfd_boolean
_bfd_score_elf_check_relocs (bfd *abfd,
                             struct bfd_link_info *info,
                             asection *sec,
                             const Elf_Internal_Rela *relocs)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
  else
    return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
}

static bfd_boolean
_bfd_score_elf_add_symbol_hook (bfd *abfd,
                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                Elf_Internal_Sym *sym,
                                const char **namep ATTRIBUTE_UNUSED,
                                flagword *flagsp ATTRIBUTE_UNUSED,
                                asection **secp,
                                bfd_vma *valp)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
                                             secp, valp);
  else
    return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
                                             secp, valp);
}

static void
_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_symbol_processing (abfd, asym);
  else
    return s7_bfd_score_elf_symbol_processing (abfd, asym);
}

static int
_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     const char *name ATTRIBUTE_UNUSED,
     Elf_Internal_Sym *sym,
     asection *input_sec,
     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
{
  /* If link a empty .o, then this filed is NULL.  */
  if (info->input_bfds == NULL)
    {
      /* If we see a common symbol, which implies a relocatable link, then
         if a symbol was small common in an input file, mark it as small
         common in the output file.  */
      if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
        sym->st_shndx = SHN_SCORE_SCOMMON;
      return 1;
    }

  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
    return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
  else
    return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
}

static bfd_boolean
_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
                                         asection *sec,
                                         int *retval)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
  else
    return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
}

static bfd_boolean
_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                                      struct elf_link_hash_entry *h)
{
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
    return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
  else
    return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
}

static bfd_boolean
_bfd_score_elf_always_size_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_always_size_sections (output_bfd, info);
  else
    return s7_bfd_score_elf_always_size_sections (output_bfd, info);
}

static bfd_boolean
_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_size_dynamic_sections (output_bfd, info);
  else
    return s7_bfd_score_elf_size_dynamic_sections (output_bfd, info);
}

static bfd_boolean
_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
  else
    return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
}

static bfd_boolean
_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
                                      struct bfd_link_info *info,
                                      struct elf_link_hash_entry *h,
                                      Elf_Internal_Sym *sym)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
  else
    return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
}

static bfd_boolean
_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
                                        struct bfd_link_info *info)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
  else
    return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
}

static bfd_boolean
_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
                              Elf_Internal_Shdr *hdr,
                              asection *sec)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
  else
    return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
}

static bfd_boolean
_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_section_processing (abfd, hdr);
  else
    return s7_bfd_score_elf_section_processing (abfd, hdr);
}

static bfd_boolean
_bfd_score_elf_write_section (bfd *output_bfd,
                              struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                              asection *sec, bfd_byte *contents)
{
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
    return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
  else
    return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
}

static void
_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
                                     struct elf_link_hash_entry *dir,
                                     struct elf_link_hash_entry *ind)
{
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
    return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
  else
    return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
}

static void
_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
                            struct elf_link_hash_entry *entry,
                            bfd_boolean force_local)
{
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
    return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
  else
    return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
}

static bfd_boolean
_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
                         struct bfd_link_info *info)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_discard_info (abfd, cookie, info);
  else
    return s7_bfd_score_elf_discard_info (abfd, cookie, info);
}

static bfd_boolean
_bfd_score_elf_ignore_discarded_relocs (asection *sec)
{
  if (bfd_get_mach (sec->owner) == bfd_mach_score3)
    return s3_bfd_score_elf_ignore_discarded_relocs (sec);
  else
    return s7_bfd_score_elf_ignore_discarded_relocs (sec);
}

static asection *
_bfd_score_elf_gc_mark_hook (asection *sec,
                             struct bfd_link_info *info,
                             Elf_Internal_Rela *rel,
                             struct elf_link_hash_entry *h,
                             Elf_Internal_Sym *sym)
{
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
    return s3_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
  else
    return s7_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
}

static bfd_boolean
_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_grok_prstatus (abfd, note);
  else
    return s7_bfd_score_elf_grok_prstatus (abfd, note);
}

static bfd_boolean
_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_bfd_score_elf_grok_psinfo (abfd, note);
  else
    return s7_bfd_score_elf_grok_psinfo (abfd, note);
}

static reloc_howto_type *
elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
{
  /* s3: NOTE!!!
     gas will call elf32_score_reloc_type_lookup, and don't write elf file.
     So just using score3, but we don't know ld will call this or not.
     If so, this way can't work.  */

  if (score3)
    return s3_elf32_score_reloc_type_lookup (abfd, code);
  else
    return s7_elf32_score_reloc_type_lookup (abfd, code);
}

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

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

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

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

  return &ret->root;
}

static bfd_boolean
elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_elf32_score_print_private_bfd_data (abfd, ptr);
  else
    return s7_elf32_score_print_private_bfd_data (abfd, ptr);
}

static bfd_boolean
elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  if (bfd_get_mach (obfd) == bfd_mach_score3)
    return s3_elf32_score_merge_private_bfd_data (ibfd, obfd);
  else
    return s7_elf32_score_merge_private_bfd_data (ibfd, obfd);
}

static bfd_boolean
elf32_score_new_section_hook (bfd *abfd, asection *sec)
{
  if (bfd_get_mach (abfd) == bfd_mach_score3)
    return s3_elf32_score_new_section_hook (abfd, sec);
  else
    return s7_elf32_score_new_section_hook (abfd, sec);
}


/* s3_s7: don't need to split.  */

/* Set the right machine number.  */
static bfd_boolean
_bfd_score_elf_score_object_p (bfd * abfd)
{
  int e_set = bfd_mach_score7;

  if (elf_elfheader (abfd)->e_machine == EM_SCORE)
    {
      int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
      switch (e_mach)
        {
        /* Set default target is score7.  */
        default:
        case E_SCORE_MACH_SCORE7:
          e_set = bfd_mach_score7;
          break;

        case E_SCORE_MACH_SCORE3:
          e_set = bfd_mach_score3;
          break;
        }
    }

  return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
}

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

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


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

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

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

#include "elf32-target.h"
