/* CRIS-specific support for 32-bit ELF.
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
   2010, 2011, 2012 Free Software Foundation, Inc.
   Contributed by Axis Communications AB.
   Written by Hans-Peter Nilsson, based on elf32-fr30.c
   PIC and shlib bits based primarily on elf32-m68k.c and elf32-i386.c.

   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 "elf-bfd.h"
#include "elf/cris.h"
#include <limits.h>

bfd_reloc_status_type
cris_elf_pcrel_reloc (bfd *, arelent *, asymbol *, void *,
		      asection *, bfd *, char **);
static bfd_boolean
cris_elf_set_mach_from_flags (bfd *, unsigned long);

/* Forward declarations.  */
static reloc_howto_type cris_elf_howto_table [] =
{
  /* This reloc does nothing.  */
  HOWTO (R_CRIS_NONE,		/* type */
	 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_CRIS_NONE",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* An 8 bit absolute relocation.  */
  HOWTO (R_CRIS_8,		/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 8,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_CRIS_8",		/* name */
	 FALSE,			/* partial_inplace */
	 0x0000,		/* src_mask */
	 0x00ff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 16 bit absolute relocation.  */
  HOWTO (R_CRIS_16,		/* type */
	 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_CRIS_16",		/* name */
	 FALSE,			/* partial_inplace */
	 0x00000000,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 32 bit absolute relocation.  */
  HOWTO (R_CRIS_32,		/* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 32,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 /* We don't want overflow complaints for 64-bit vma builds
	    for e.g. sym+0x40000000 (or actually sym-0xc0000000 in
	    32-bit ELF) where sym=0xc0001234.
	    Don't do this for the PIC relocs, as we don't expect to
	    see them with large offsets.  */
	 complain_overflow_dont, /* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_CRIS_32",		/* name */
	 FALSE,			/* partial_inplace */
	 0x00000000,		/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* An 8 bit PC-relative relocation.  */
  HOWTO (R_CRIS_8_PCREL,	/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 8,			/* bitsize */
	 TRUE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 cris_elf_pcrel_reloc,	/* special_function */
	 "R_CRIS_8_PCREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0x0000,		/* src_mask */
	 0x00ff,		/* dst_mask */
	 TRUE),			/* pcrel_offset */

  /* A 16 bit PC-relative relocation.  */
  HOWTO (R_CRIS_16_PCREL,	/* type */
	 0,			/* rightshift */
	 1,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 TRUE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 cris_elf_pcrel_reloc,	/* special_function */
	 "R_CRIS_16_PCREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0x00000000,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 TRUE),			/* pcrel_offset */

  /* A 32 bit PC-relative relocation.  */
  HOWTO (R_CRIS_32_PCREL,	/* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 32,			/* bitsize */
	 TRUE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 cris_elf_pcrel_reloc,	/* special_function */
	 "R_CRIS_32_PCREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0x00000000,		/* src_mask */
	 0xffffffff,		/* dst_mask */
	 TRUE),			/* pcrel_offset */

  /* GNU extension to record C++ vtable hierarchy.  */
  HOWTO (R_CRIS_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_CRIS_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_CRIS_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_CRIS_GNU_VTENTRY",	 /* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* This is used only by the dynamic linker.  The symbol should exist
     both in the object being run and in some shared library.  The
     dynamic linker copies the data addressed by the symbol from the
     shared library into the object, because the object being
     run has to have the data at some particular address.  */
  HOWTO (R_CRIS_COPY,		/* type */
	 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_CRIS_COPY",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* Like R_CRIS_32, but used when setting global offset table entries.  */
  HOWTO (R_CRIS_GLOB_DAT,	/* type */
	 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_CRIS_GLOB_DAT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* Marks a procedure linkage table entry for a symbol.  */
  HOWTO (R_CRIS_JUMP_SLOT,	/* type */
	 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_CRIS_JUMP_SLOT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* Used only by the dynamic linker.  When the object is run, this
     longword is set to the load address of the object, plus the
     addend.  */
  HOWTO (R_CRIS_RELATIVE,	/* type */
	 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_CRIS_RELATIVE",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* Like R_CRIS_32, but referring to the GOT table entry for the symbol.  */
  HOWTO (R_CRIS_16_GOT,		/* type */
	 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_CRIS_16_GOT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_CRIS_32_GOT,		/* type */
	 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_CRIS_32_GOT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* Like R_CRIS_32_GOT, but referring to (and requesting a) PLT part of
     the GOT table for the symbol.  */
  HOWTO (R_CRIS_16_GOTPLT,	/* type */
	 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_CRIS_16_GOTPLT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_CRIS_32_GOTPLT,	/* type */
	 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_CRIS_32_GOTPLT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 32-bit offset from GOT to (local const) symbol: no GOT entry should
     be necessary.  */
  HOWTO (R_CRIS_32_GOTREL,	/* type */
	 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_CRIS_32_GOTREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 32-bit offset from GOT to entry for this symbol in PLT and request
     to create PLT entry for symbol.  */
  HOWTO (R_CRIS_32_PLT_GOTREL,	/* type */
	 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_CRIS_32_PLT_GOTREL", /* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  /* A 32-bit offset from PC (location after the relocation) + addend to
     entry for this symbol in PLT and request to create PLT entry for
     symbol.  */
  HOWTO (R_CRIS_32_PLT_PCREL,	/* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 32,			/* bitsize */
	 TRUE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 cris_elf_pcrel_reloc,	/* special_function */
	 "R_CRIS_32_PLT_PCREL",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 TRUE),			/* pcrel_offset */

  /* We don't handle these in any special manner and cross-format
     linking is not supported; just recognize them enough to pass them
     around.  FIXME: do the same for most PIC relocs and add sanity
     tests to actually refuse gracefully to handle these and PIC
     relocs for cross-format linking.  */
#define TLSHOWTO32(name) \
 HOWTO (name, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, \
        bfd_elf_generic_reloc, #name, FALSE, 0, 0xffffffff, FALSE)
#define TLSHOWTO16X(name, X)	     \
 HOWTO (name, 0, 1, 16, FALSE, 0, complain_overflow_ ## X, \
        bfd_elf_generic_reloc, #name, FALSE, 0, 0xffff, FALSE)
#define TLSHOWTO16(name) TLSHOWTO16X(name, unsigned)
#define TLSHOWTO16S(name) TLSHOWTO16X(name, signed)

  TLSHOWTO32 (R_CRIS_32_GOT_GD),
  TLSHOWTO16 (R_CRIS_16_GOT_GD),
  TLSHOWTO32 (R_CRIS_32_GD),
  TLSHOWTO32 (R_CRIS_DTP),
  TLSHOWTO32 (R_CRIS_32_DTPREL),
  TLSHOWTO16S (R_CRIS_16_DTPREL),
  TLSHOWTO32 (R_CRIS_32_GOT_TPREL),
  TLSHOWTO16S (R_CRIS_16_GOT_TPREL),
  TLSHOWTO32 (R_CRIS_32_TPREL),
  TLSHOWTO16S (R_CRIS_16_TPREL),
  TLSHOWTO32 (R_CRIS_DTPMOD),
  TLSHOWTO32 (R_CRIS_32_IE)
};

/* Map BFD reloc types to CRIS ELF reloc types.  */

struct cris_reloc_map
{
  bfd_reloc_code_real_type bfd_reloc_val;
  unsigned int cris_reloc_val;
};

static const struct cris_reloc_map cris_reloc_map [] =
{
  { BFD_RELOC_NONE,		R_CRIS_NONE },
  { BFD_RELOC_8,		R_CRIS_8 },
  { BFD_RELOC_16,		R_CRIS_16 },
  { BFD_RELOC_32,		R_CRIS_32 },
  { BFD_RELOC_8_PCREL,		R_CRIS_8_PCREL },
  { BFD_RELOC_16_PCREL,		R_CRIS_16_PCREL },
  { BFD_RELOC_32_PCREL,		R_CRIS_32_PCREL },
  { BFD_RELOC_VTABLE_INHERIT,	R_CRIS_GNU_VTINHERIT },
  { BFD_RELOC_VTABLE_ENTRY,	R_CRIS_GNU_VTENTRY },
  { BFD_RELOC_CRIS_COPY,	R_CRIS_COPY },
  { BFD_RELOC_CRIS_GLOB_DAT,	R_CRIS_GLOB_DAT },
  { BFD_RELOC_CRIS_JUMP_SLOT,	R_CRIS_JUMP_SLOT },
  { BFD_RELOC_CRIS_RELATIVE,	R_CRIS_RELATIVE },
  { BFD_RELOC_CRIS_16_GOT,	R_CRIS_16_GOT },
  { BFD_RELOC_CRIS_32_GOT,	R_CRIS_32_GOT },
  { BFD_RELOC_CRIS_16_GOTPLT,	R_CRIS_16_GOTPLT },
  { BFD_RELOC_CRIS_32_GOTPLT,	R_CRIS_32_GOTPLT },
  { BFD_RELOC_CRIS_32_GOTREL,	R_CRIS_32_GOTREL },
  { BFD_RELOC_CRIS_32_PLT_GOTREL, R_CRIS_32_PLT_GOTREL },
  { BFD_RELOC_CRIS_32_PLT_PCREL, R_CRIS_32_PLT_PCREL },
  { BFD_RELOC_CRIS_32_GOT_GD,	R_CRIS_32_GOT_GD },
  { BFD_RELOC_CRIS_16_GOT_GD,	R_CRIS_16_GOT_GD },
  { BFD_RELOC_CRIS_32_GD,	R_CRIS_32_GD },
  { BFD_RELOC_CRIS_DTP,	R_CRIS_DTP },
  { BFD_RELOC_CRIS_32_DTPREL,	R_CRIS_32_DTPREL },
  { BFD_RELOC_CRIS_16_DTPREL,	R_CRIS_16_DTPREL },
  { BFD_RELOC_CRIS_32_GOT_TPREL, R_CRIS_32_GOT_TPREL },
  { BFD_RELOC_CRIS_16_GOT_TPREL, R_CRIS_16_GOT_TPREL },
  { BFD_RELOC_CRIS_32_TPREL,	R_CRIS_32_TPREL },
  { BFD_RELOC_CRIS_16_TPREL,	R_CRIS_16_TPREL },
  { BFD_RELOC_CRIS_DTPMOD,	R_CRIS_DTPMOD },
  { BFD_RELOC_CRIS_32_IE,	R_CRIS_32_IE }
};

static reloc_howto_type *
cris_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
			bfd_reloc_code_real_type code)
{
  unsigned int i;

  for (i = 0; i < sizeof (cris_reloc_map) / sizeof (cris_reloc_map[0]); i++)
    if (cris_reloc_map [i].bfd_reloc_val == code)
      return & cris_elf_howto_table [cris_reloc_map[i].cris_reloc_val];

  return NULL;
}

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

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

  return NULL;
}

/* Set the howto pointer for an CRIS ELF reloc.  */

static void
cris_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
			 arelent * cache_ptr,
			 Elf_Internal_Rela * dst)
{
  enum elf_cris_reloc_type r_type;

  r_type = ELF32_R_TYPE (dst->r_info);
  BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);
  cache_ptr->howto = & cris_elf_howto_table [r_type];
}

bfd_reloc_status_type
cris_elf_pcrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
		      arelent *reloc_entry,
		      asymbol *symbol,
		      void * data ATTRIBUTE_UNUSED,
		      asection *input_section,
		      bfd *output_bfd,
		      char **error_message ATTRIBUTE_UNUSED)
{
  /* By default (using only bfd_elf_generic_reloc when linking to
     non-ELF formats) PC-relative relocs are relative to the beginning
     of the reloc.  CRIS PC-relative relocs are relative to the position
     *after* the reloc because that's what pre-CRISv32 PC points to
     after reading an insn field with that reloc.  (For CRISv32, PC is
     actually relative to the start of the insn, but we keep the old
     definition.)  Still, we use as much generic machinery as we can.

     Only adjust when doing a final link.  */
  if (output_bfd == (bfd *) NULL)
    reloc_entry->addend -= 1 << reloc_entry->howto->size;

  return
    bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
			   input_section, output_bfd, error_message);
}

/* Support for core dump NOTE sections.
   The slightly unintuitive code layout is an attempt to keep at least
   some similarities with other ports, hoping to simplify general
   changes, while still keeping Linux/CRIS and Linux/CRISv32 code apart.  */

static bfd_boolean
cris_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  int offset;
  size_t size;

  if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
    switch (note->descsz)
      {
      default:
	return FALSE;

      case 202:		/* Linux/CRISv32 */
	/* pr_cursig */
	elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);

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

	/* pr_reg */
	offset = 70;
	size = 128;

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

      case 214:		/* Linux/CRIS */
	/* pr_cursig */
	elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);

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

	/* pr_reg */
	offset = 70;
	size = 140;

	break;
      }

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

static bfd_boolean
cris_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
    switch (note->descsz)
      {
      default:
	return FALSE;

      case 124:		/* Linux/CRISv32 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);
      }
  else
    switch (note->descsz)
      {
      default:
	return FALSE;

      case 124:		/* Linux/CRIS 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;
}

/* The name of the dynamic interpreter.  This is put in the .interp
   section.  */

#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"

/* The size in bytes of an entry in the procedure linkage table.  */

#define PLT_ENTRY_SIZE 20
#define PLT_ENTRY_SIZE_V32 26

/* The first entry in an absolute procedure linkage table looks like this.  */

static const bfd_byte elf_cris_plt0_entry[PLT_ENTRY_SIZE] =
{
  0xfc, 0xe1,
  0x7e, 0x7e,	/* push mof.  */
  0x7f, 0x0d,   /*  (dip [pc+]) */
  0, 0, 0, 0,	/*  Replaced with address of .got + 4.  */
  0x30, 0x7a,	/* move [...],mof */
  0x7f, 0x0d,   /*  (dip [pc+]) */
  0, 0, 0, 0,	/*  Replaced with address of .got + 8.  */
  0x30, 0x09	/* jump [...] */
};

static const bfd_byte elf_cris_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
{
  0x84, 0xe2,	/* subq 4,$sp */
  0x6f, 0xfe,	/* move.d 0,$acr */
  0, 0, 0, 0,	/*  Replaced by address of .got + 4.  */
  0x7e, 0x7a,	/* move $mof,[$sp] */
  0x3f, 0x7a,	/* move [$acr],$mof */
  0x04, 0xf2,	/* addq 4,acr */
  0x6f, 0xfa,	/* move.d [$acr],$acr */
  0xbf, 0x09,	/* jump $acr */
  0xb0, 0x05,	/* nop */
  0, 0		/*  Pad out to 26 bytes.  */
};

/* Subsequent entries in an absolute procedure linkage table look like
   this.  */

static const bfd_byte elf_cris_plt_entry[PLT_ENTRY_SIZE] =
{
  0x7f, 0x0d,   /*  (dip [pc+]) */
  0, 0, 0, 0,	/*  Replaced with address of this symbol in .got.  */
  0x30, 0x09,	/* jump [...] */
  0x3f,	 0x7e,	/* move [pc+],mof */
  0, 0, 0, 0,	/*  Replaced with offset into relocation table.  */
  0x2f, 0xfe,	/* add.d [pc+],pc */
  0xec, 0xff,
  0xff, 0xff	/*  Replaced with offset to start of .plt.  */
};

static const bfd_byte elf_cris_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
{
  0x6f, 0xfe,	/* move.d 0,$acr */
  0, 0, 0, 0,	/*  Replaced with address of this symbol in .got.  */
  0x6f, 0xfa,   /* move.d [$acr],$acr */
  0xbf, 0x09,   /* jump $acr */
  0xb0, 0x05,	/* nop */
  0x3f, 0x7e,	/* move 0,mof */
  0, 0, 0, 0,	/*  Replaced with offset into relocation table. */
  0xbf, 0x0e,	/* ba start_of_plt0_entry */
  0, 0, 0, 0,	/*  Replaced with offset to plt0 entry.  */
  0xb0, 0x05	/* nop */
};

/* The first entry in a PIC procedure linkage table looks like this.  */

static const bfd_byte elf_cris_pic_plt0_entry[PLT_ENTRY_SIZE] =
{
  0xfc, 0xe1, 0x7e, 0x7e,	/* push mof */
  0x04, 0x01, 0x30, 0x7a,	/* move [r0+4],mof */
  0x08, 0x01, 0x30, 0x09,	/* jump [r0+8] */
  0, 0, 0, 0, 0, 0, 0, 0,	/*  Pad out to 20 bytes.  */
};

static const bfd_byte elf_cris_pic_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
{
  0x84, 0xe2,	/* subq 4,$sp */
  0x04, 0x01,	/* addoq 4,$r0,$acr */
  0x7e, 0x7a,	/* move $mof,[$sp] */
  0x3f, 0x7a,	/* move [$acr],$mof */
  0x04, 0xf2,	/* addq 4,$acr */
  0x6f, 0xfa,	/* move.d [$acr],$acr */
  0xbf, 0x09,	/* jump $acr */
  0xb0, 0x05,	/* nop */
  0, 0,		/*  Pad out to 26 bytes.  */
  0, 0, 0, 0,
  0, 0, 0, 0
};

/* Subsequent entries in a PIC procedure linkage table look like this.  */

static const bfd_byte elf_cris_pic_plt_entry[PLT_ENTRY_SIZE] =
{
  0x6f, 0x0d,   /*  (bdap [pc+].d,r0) */
  0, 0, 0, 0,	/*  Replaced with offset of this symbol in .got.  */
  0x30, 0x09,	/* jump [...] */
  0x3f, 0x7e,	/* move [pc+],mof */
  0, 0, 0, 0,	/*  Replaced with offset into relocation table.  */
  0x2f, 0xfe,	/* add.d [pc+],pc */
  0xec, 0xff,	/*  Replaced with offset to start of .plt.  */
  0xff, 0xff
};

static const bfd_byte elf_cris_pic_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
{
  0x6f, 0x0d,	/* addo.d 0,$r0,$acr */
  0, 0, 0, 0,	/*  Replaced with offset of this symbol in .got.  */
  0x6f, 0xfa,	/* move.d [$acr],$acr */
  0xbf, 0x09,	/* jump $acr */
  0xb0, 0x05,	/* nop */
  0x3f, 0x7e,	/* move relocoffs,$mof */
  0, 0, 0, 0,	/*  Replaced with offset into relocation table.  */
  0xbf, 0x0e,	/* ba start_of_plt */
  0, 0, 0, 0,	/*  Replaced with offset to start of .plt.  */
  0xb0, 0x05	/* nop */
};

/* We copy elf32-m68k.c and elf32-i386.c for the basic linker hash bits
   (and most other PIC/shlib stuff).  Check that we don't drift away
   without reason.

   The CRIS linker, like the m68k and i386 linkers (and probably the rest
   too) needs to keep track of the number of relocs that it decides to
   copy in check_relocs for each symbol.  This is so that it can discard
   PC relative relocs if it doesn't need them when linking with
   -Bsymbolic.  We store the information in a field extending the regular
   ELF linker hash table.  */

/* This structure keeps track of the number of PC relative relocs we have
   copied for a given symbol.  */

struct elf_cris_pcrel_relocs_copied
{
  /* Next section.  */
  struct elf_cris_pcrel_relocs_copied *next;

  /* A section in dynobj.  */
  asection *section;

  /* Number of relocs copied in this section.  */
  bfd_size_type count;

  /* Example of reloc being copied, for message.  */
  enum elf_cris_reloc_type r_type;
};

/* CRIS ELF linker hash entry.  */

struct elf_cris_link_hash_entry
{
  struct elf_link_hash_entry root;

  /* Number of PC relative relocs copied for this symbol.  */
  struct elf_cris_pcrel_relocs_copied *pcrel_relocs_copied;

  /* The GOTPLT references are CRIS-specific; the goal is to avoid having
     both a general GOT and a PLT-specific GOT entry for the same symbol,
     when it is referenced both as a function and as a function pointer.

     Number of GOTPLT references for a function.  */
  bfd_signed_vma gotplt_refcount;

  /* Actual GOTPLT index for this symbol, if applicable, or zero if not
     (zero is never used as an index).  FIXME: We should be able to fold
     this with gotplt_refcount in a union, like the got and plt unions in
     elf_link_hash_entry.  */
  bfd_size_type gotplt_offset;

  /* The root.got.refcount is the sum of the regular reference counts
     (this) and those members below.  We have to keep a separate count
     to track when we've found the first (or last) reference to a
     regular got entry.  The offset is in root.got.offset.  */
  bfd_signed_vma reg_got_refcount;

  /* Similar to the above, the number of reloc references to this
     symbols that need a R_CRIS_32_TPREL slot.  The offset is in
     root.got.offset, because this and .dtp_refcount can't validly
     happen when there's also a regular GOT entry; that's invalid
     input for which an error is emitted.  */
  bfd_signed_vma tprel_refcount;

  /* Similar to the above, the number of reloc references to this
     symbols that need a R_CRIS_DTP slot.  The offset is in
     root.got.offset; plus 4 if .tprel_refcount > 0.  */
  bfd_signed_vma dtp_refcount;
};

static bfd_boolean
elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *,
				      void * );
static bfd_boolean
elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *,
					  void *);

/* The local_got_refcounts and local_got_offsets are a multiple of
   LSNUM in size, namely LGOT_ALLOC_NELTS_FOR(LSNUM) (plus one for the
   refcount for GOT itself, see code), with the summary / group offset
   for local symbols located at offset N, reference counts for
   ordinary (address) relocs at offset N + LSNUM, for R_CRIS_DTP
   relocs at offset N + 2*LSNUM, and for R_CRIS_32_TPREL relocs at N +
   3*LSNUM.  */

#define LGOT_REG_NDX(x) ((x) + symtab_hdr->sh_info)
#define LGOT_DTP_NDX(x) ((x) + 2 * symtab_hdr->sh_info)
#define LGOT_TPREL_NDX(x) ((x) + 3 * symtab_hdr->sh_info)
#define LGOT_ALLOC_NELTS_FOR(x) ((x) * 4)

/* CRIS ELF linker hash table.  */

struct elf_cris_link_hash_table
{
  struct elf_link_hash_table root;

  /* We can't use the PLT offset and calculate to get the GOTPLT offset,
     since we try and avoid creating GOTPLT:s when there's already a GOT.
     Instead, we keep and update the next available index here.  */
  bfd_size_type next_gotplt_entry;

  /* The number of R_CRIS_32_DTPREL and R_CRIS_16_DTPREL that have
     been seen for any input; if != 0, then the constant-offset
     R_CRIS_DTPMOD is needed for this DSO/executable.  This turns
     negative at relocation, so that we don't need an extra flag for
     when the reloc is output.  */
  bfd_signed_vma dtpmod_refcount;
};

/* Traverse a CRIS ELF linker hash table.  */

#define elf_cris_link_hash_traverse(table, func, info)			\
  (elf_link_hash_traverse						\
   (&(table)->root,							\
    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),	\
    (info)))

/* Get the CRIS ELF linker hash table from a link_info structure.  */

#define elf_cris_hash_table(p) \
  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
  == CRIS_ELF_DATA ? ((struct elf_cris_link_hash_table *) ((p)->hash)) : NULL)

/* Get the CRIS ELF linker hash entry from a regular hash entry (the
   "parent class").  The .root reference is just a simple type
   check on the argument.  */

#define elf_cris_hash_entry(p) \
 ((struct elf_cris_link_hash_entry *) (&(p)->root))

/* Create an entry in a CRIS ELF linker hash table.  */

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

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

  /* Call the allocation method of the superclass.  */
  ret = ((struct elf_cris_link_hash_entry *)
	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
				     table, string));
  if (ret != (struct elf_cris_link_hash_entry *) NULL)
    {
      ret->pcrel_relocs_copied = NULL;
      ret->gotplt_refcount = 0;
      ret->gotplt_offset = 0;
      ret->dtp_refcount = 0;
      ret->tprel_refcount = 0;
      ret->reg_got_refcount = 0;
    }

  return (struct bfd_hash_entry *) ret;
}

/* Create a CRIS ELF linker hash table.  */

static struct bfd_link_hash_table *
elf_cris_link_hash_table_create (bfd *abfd)
{
  struct elf_cris_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct elf_cris_link_hash_table);

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

  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
				      elf_cris_link_hash_newfunc,
				      sizeof (struct elf_cris_link_hash_entry),
				      CRIS_ELF_DATA))
    {
      free (ret);
      return NULL;
    }

  /* Initialize to skip over the first three entries in the gotplt; they
     are used for run-time symbol evaluation.  */
  ret->next_gotplt_entry = 12;

  return &ret->root.root;
}

/* Perform a single relocation.  By default we use the standard BFD
   routines, with a few tweaks.  */

static bfd_reloc_status_type
cris_final_link_relocate (reloc_howto_type *  howto,
			  bfd *               input_bfd,
			  asection *          input_section,
			  bfd_byte *          contents,
			  Elf_Internal_Rela * rel,
			  bfd_vma             relocation)
{
  bfd_reloc_status_type r;
  enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);

  /* PC-relative relocations are relative to the position *after*
     the reloc.  Note that for R_CRIS_8_PCREL the adjustment is
     not a single byte, since PC must be 16-bit-aligned.  */
  switch (r_type)
    {
      /* Check that the 16-bit GOT relocs are positive.  */
    case R_CRIS_16_GOTPLT:
    case R_CRIS_16_GOT:
      if ((bfd_signed_vma) relocation < 0)
	return bfd_reloc_overflow;
      break;

    case R_CRIS_32_PLT_PCREL:
    case R_CRIS_32_PCREL:
      relocation -= 2;
      /* Fall through.  */
    case R_CRIS_8_PCREL:
    case R_CRIS_16_PCREL:
      relocation -= 2;
      break;

    default:
      break;
    }

  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
				contents, rel->r_offset,
				relocation, rel->r_addend);
  return r;
}


/* The number of errors left before we stop outputting reloc-specific
   explanatory messages.  By coincidence, this works nicely together
   with the default number of messages you'll get from LD about
   "relocation truncated to fit" messages before you get an
   "additional relocation overflows omitted from the output".  */
static int additional_relocation_error_msg_count = 10;

/* Relocate an CRIS ELF section.  See elf32-fr30.c, from where this was
   copied, for further comments.  */

static bfd_boolean
cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
			   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)
{
  struct elf_cris_link_hash_table * htab;
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_vma *local_got_offsets;
  asection *sgot;
  asection *splt;
  asection *sreloc;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  asection *srelgot;

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

  dynobj = elf_hash_table (info)->dynobj;
  local_got_offsets = elf_local_got_offsets (input_bfd);
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);
  relend     = relocs + input_section->reloc_count;

  sgot = NULL;
  splt = NULL;
  sreloc = NULL;
  srelgot = NULL;

  if (dynobj != NULL)
    {
      splt = bfd_get_linker_section (dynobj, ".plt");
      sgot = bfd_get_linker_section (dynobj, ".got");
    }

  for (rel = relocs; rel < relend; rel ++)
    {
      reloc_howto_type *howto;
      unsigned long r_symndx;
      Elf_Internal_Sym *sym;
      asection *sec;
      struct elf_link_hash_entry *h;
      bfd_vma relocation;
      bfd_reloc_status_type r;
      const char *symname = NULL;
      enum elf_cris_reloc_type r_type;

      r_type = ELF32_R_TYPE (rel->r_info);

      if (   r_type == R_CRIS_GNU_VTINHERIT
	  || r_type == R_CRIS_GNU_VTENTRY)
	continue;

      r_symndx = ELF32_R_SYM (rel->r_info);
      howto  = cris_elf_howto_table + r_type;
      h      = NULL;
      sym    = NULL;
      sec    = NULL;

      if (r_symndx < symtab_hdr->sh_info)
	{
	  sym = local_syms + r_symndx;
	  sec = local_sections [r_symndx];
	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);

	  symname = (bfd_elf_string_from_elf_section
		     (input_bfd, symtab_hdr->sh_link, sym->st_name));
	  if (symname == NULL)
	    symname = bfd_section_name (input_bfd, sec);
	}
      else
	{
	  bfd_boolean warned;
	  bfd_boolean unresolved_reloc;

	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
				   r_symndx, symtab_hdr, sym_hashes,
				   h, sec, relocation,
				   unresolved_reloc, warned);

	  symname = h->root.root.string;

	  if (unresolved_reloc
	      /* Perhaps we should detect the cases that
		 sec->output_section is expected to be NULL like i386 and
		 m68k, but apparently (and according to elfxx-ia64.c) all
		 valid cases are where the symbol is defined in a shared
		 object which we link dynamically against.  This includes
		 PLT relocs for which we've created a PLT entry and other
		 relocs for which we're prepared to create dynamic
		 relocations.

		 For now, new situations cause us to just err when
		 sec->output_offset is NULL but the object with the symbol
		 is *not* dynamically linked against.  Thus this will
		 automatically remind us so we can see if there are other
		 valid cases we need to revisit.  */
	      && (sec->owner->flags & DYNAMIC) != 0)
	    relocation = 0;

	  else if (h->root.type == bfd_link_hash_defined
		   || h->root.type == bfd_link_hash_defweak)
	    {
	      /* Here follow the cases where the relocation value must
		 be zero (or when further handling is simplified when
		 zero).  I can't claim to understand the various
		 conditions and they weren't described in the files
		 where I copied them from (elf32-m68k.c and
		 elf32-i386.c), but let's mention examples of where
		 they happen.  FIXME: Perhaps define and use a
		 dynamic_symbol_p function like ia64.

		 - When creating a shared library, we can have an
		 ordinary relocation for a symbol defined in a shared
		 library (perhaps the one we create).  We then make
		 the relocation value zero, as the value seen now will
		 be added into the relocation addend in this shared
		 library, but must be handled only at dynamic-link
		 time.  FIXME: Not sure this example covers the
		 h->elf_link_hash_flags test, though it's there in
		 other targets.  */
	      if (info->shared
		  && ((! info->symbolic && h->dynindx != -1)
		      || !h->def_regular)
		  && (input_section->flags & SEC_ALLOC) != 0
		  && (r_type == R_CRIS_8
		      || r_type == R_CRIS_16
		      || r_type == R_CRIS_32
		      || r_type == R_CRIS_8_PCREL
		      || r_type == R_CRIS_16_PCREL
		      || r_type == R_CRIS_32_PCREL))
		relocation = 0;
	      else if (!info->relocatable && unresolved_reloc
		       && (_bfd_elf_section_offset (output_bfd, info,
						    input_section,
						    rel->r_offset)
			   != (bfd_vma) -1))
		{
		  _bfd_error_handler
		    (_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
		     input_bfd,
		     input_section,
		     cris_elf_howto_table[r_type].name,
		     symname);
		  bfd_set_error (bfd_error_bad_value);
		  return FALSE;
		}
	    }
	}

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

      if (info->relocatable)
	continue;

      switch (r_type)
	{
	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	  /* This is like the case for R_CRIS_32_GOT and R_CRIS_16_GOT,
	     but we require a PLT, and the PLT handling will take care of
	     filling in the PLT-specific GOT entry.  For the GOT offset,
	     calculate it as we do when filling it in for the .got.plt
	     section.  If we don't have a PLT, punt to GOT handling.  */
	  if (h != NULL
	      && ((struct elf_cris_link_hash_entry *) h)->gotplt_offset != 0)
	    {
	      asection *sgotplt
		= bfd_get_linker_section (dynobj, ".got.plt");
	      bfd_vma got_offset;

	      BFD_ASSERT (h->dynindx != -1);
	      BFD_ASSERT (sgotplt != NULL);

	      got_offset
		= ((struct elf_cris_link_hash_entry *) h)->gotplt_offset;

	      relocation = got_offset;
	      break;
	    }

	  /* We didn't make a PLT entry for this symbol.  Maybe everything is
	     folded into the GOT.  Other than folding, this happens when
	     statically linking PIC code, or when using -Bsymbolic.  Check
	     that we instead have a GOT entry as done for us by
	     elf_cris_adjust_dynamic_symbol, and drop through into the
	     ordinary GOT cases.  This must not happen for the
	     executable, because any reference it does to a function
	     that is satisfied by a DSO must generate a PLT.  We assume
	     these call-specific relocs don't address non-functions.  */
	  if (h != NULL
	      && (h->got.offset == (bfd_vma) -1
		  || (!info->shared
		      && !(h->def_regular
			   || (!h->def_dynamic
			       && h->root.type == bfd_link_hash_undefweak)))))
	    {
	      (*_bfd_error_handler)
		((h->got.offset == (bfd_vma) -1)
		 ? _("%B, section %A: No PLT nor GOT for relocation %s"
		     " against symbol `%s'")
		 : _("%B, section %A: No PLT for relocation %s"
		     " against symbol `%s'"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 (symname != NULL && symname[0] != '\0'
		  ? symname : _("[whose name is lost]")));

	      /* FIXME: Perhaps blaming input is not the right thing to
		 do; this is probably an internal error.  But it is true
		 that we didn't like that particular input.  */
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }
	  /* Fall through.  */

	  /* The size of the actual relocation is not used here; we only
	     fill in the GOT table here.  */
	case R_CRIS_16_GOT:
	case R_CRIS_32_GOT:
	  {
	    bfd_vma off;

	    /* Note that despite using RELA relocations, the .got contents
	       is always filled in with the link-relative relocation
	       value; the addend.  */

	    if (h != NULL)
	      {
		off = h->got.offset;
		BFD_ASSERT (off != (bfd_vma) -1);

		if (!elf_hash_table (info)->dynamic_sections_created
		    || (! info->shared
			&& (h->def_regular
			    || h->type == STT_FUNC
			    || h->needs_plt))
		    || (info->shared
			&& (info->symbolic || h->dynindx == -1)
			&& h->def_regular))
		  {
		    /* This wasn't checked above for ! info->shared, but
		       must hold there if we get here; the symbol must
		       be defined in the regular program or be undefweak
		       or be a function or otherwise need a PLT.  */
		    BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
				|| info->shared
				|| h->def_regular
				|| h->type == STT_FUNC
				|| h->needs_plt
				|| h->root.type == bfd_link_hash_undefweak);

		    /* This is actually a static link, or it is a
		       -Bsymbolic link and the symbol is defined locally,
		       or is undefweak, or the symbol was forced to be
		       local because of a version file, or we're not
		       creating a dynamic object.  We must initialize this
		       entry in the global offset table.  Since the offset
		       must always be a multiple of 4, we use the least
		       significant bit to record whether we have
		       initialized it already.

		       If this GOT entry should be runtime-initialized, we
		       will create a .rela.got relocation entry to
		       initialize the value.  This is done in the
		       finish_dynamic_symbol routine.  */
		    if ((off & 1) != 0)
		      off &= ~1;
		    else
		      {
			bfd_put_32 (output_bfd, relocation,
				    sgot->contents + off);
			h->got.offset |= 1;
		      }
		  }
	      }
	    else
	      {
		BFD_ASSERT (local_got_offsets != NULL
			    && local_got_offsets[r_symndx] != (bfd_vma) -1);

		off = local_got_offsets[r_symndx];

		/* The offset must always be a multiple of 4.  We use
		   the least significant bit to record whether we have
		   already generated the necessary reloc.  */
		if ((off & 1) != 0)
		  off &= ~1;
		else
		  {
		    bfd_put_32 (output_bfd, relocation, sgot->contents + off);

		    if (info->shared)
		      {
			Elf_Internal_Rela outrel;
			bfd_byte *loc;

			if (srelgot == NULL)
			  srelgot
			    = bfd_get_linker_section (dynobj, ".rela.got");
			BFD_ASSERT (srelgot != NULL);

			outrel.r_offset = (sgot->output_section->vma
					   + sgot->output_offset
					   + off);
			outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
			outrel.r_addend = relocation;
			loc = srelgot->contents;
			loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
			bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
		      }

		    local_got_offsets[r_symndx] |= 1;
		  }
	      }

	    relocation = sgot->output_offset + off;
	    if (rel->r_addend != 0)
	      {
		/* We can't do anything for a relocation which is against
		   a symbol *plus offset*.  GOT holds relocations for
		   symbols.  Make this an error; the compiler isn't
		   allowed to pass us these kinds of things.  */
		if (h == NULL)
		  (*_bfd_error_handler)
		    (_("%B, section %A: relocation %s with non-zero addend %d"
		       " against local symbol"),
		     input_bfd,
		     input_section,
		     cris_elf_howto_table[r_type].name,
		     rel->r_addend);
		else
		  (*_bfd_error_handler)
		    (_("%B, section %A: relocation %s with non-zero addend %d"
		       " against symbol `%s'"),
		     input_bfd,
		     input_section,
		     cris_elf_howto_table[r_type].name,
		     rel->r_addend,
		     symname[0] != '\0' ? symname : _("[whose name is lost]"));

		bfd_set_error (bfd_error_bad_value);
		return FALSE;
	      }
	  }
	  break;

	case R_CRIS_32_GOTREL:
	  /* This relocation must only be performed against local symbols.
	     It's also ok when we link a program and the symbol is either
	     defined in an ordinary (non-DSO) object or is undefined weak.  */
	  if (h != NULL
	      && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
	      && !(!info->shared
		   && (h->def_regular
		       || (!h->def_dynamic
			   && h->root.type == bfd_link_hash_undefweak))))
	    {
	      (*_bfd_error_handler)
		(_("%B, section %A: relocation %s is"
		   " not allowed for global symbol: `%s'"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 symname);
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  /* This can happen if we get a link error with the input ELF
	     variant mismatching the output variant.  Emit an error so
	     it's noticed if it happens elsewhere.  */
	  if (sgot == NULL)
	    {
	      (*_bfd_error_handler)
		(_("%B, section %A: relocation %s with no GOT created"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name);
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  /* This relocation is like a PC-relative one, except the
	     reference point is the location of GOT.  Note that
	     sgot->output_offset is not involved in this calculation.  We
	     always want the start of entire .got section, not the
	     position after the reserved header.  */
	  relocation -= sgot->output_section->vma;
	  break;

	case R_CRIS_32_PLT_PCREL:
	  /* Relocation is to the entry for this symbol in the
	     procedure linkage table.  */

	  /* Resolve a PLT_PCREL reloc against a local symbol directly,
	     without using the procedure linkage table.  */
	  if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
	    break;

	  if (h->plt.offset == (bfd_vma) -1
	      || splt == NULL)
	    {
	      /* We didn't make a PLT entry for this symbol.  This
		 happens when statically linking PIC code, or when
		 using -Bsymbolic.  */
	      break;
	    }

	  relocation = (splt->output_section->vma
			+ splt->output_offset
			+ h->plt.offset);
	  break;

	case R_CRIS_32_PLT_GOTREL:
	  /* Like R_CRIS_32_PLT_PCREL, but the reference point is the
	     start of the .got section.  See also comment at
	     R_CRIS_32_GOT.  */
	  relocation -= sgot->output_section->vma;

	  /* Resolve a PLT_GOTREL reloc against a local symbol directly,
	     without using the procedure linkage table.  */
	  if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
	    break;

	  if (h->plt.offset == (bfd_vma) -1
	      || splt == NULL)
	    {
	      /* We didn't make a PLT entry for this symbol.  This
		 happens when statically linking PIC code, or when
		 using -Bsymbolic.  */
	      break;
	    }

	  relocation = (splt->output_section->vma
			+ splt->output_offset
			+ h->plt.offset
			- sgot->output_section->vma);
	  break;

	case R_CRIS_8_PCREL:
	case R_CRIS_16_PCREL:
	case R_CRIS_32_PCREL:
	  /* If the symbol was local, we need no shlib-specific handling.  */
	  if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
	      || h->dynindx == -1)
	    break;

	  /* Fall through.  */
	case R_CRIS_8:
	case R_CRIS_16:
	case R_CRIS_32:
	  if (info->shared
	      && r_symndx != STN_UNDEF
	      && (input_section->flags & SEC_ALLOC) != 0
	      && ((r_type != R_CRIS_8_PCREL
		   && r_type != R_CRIS_16_PCREL
		   && r_type != R_CRIS_32_PCREL)
		  || (!info->symbolic
		      || (h != NULL && !h->def_regular))))
	    {
	      Elf_Internal_Rela outrel;
	      bfd_byte *loc;
	      bfd_boolean skip, relocate;

	      /* When generating a shared object, these relocations
		 are copied into the output file to be resolved at run
		 time.  */

	      if (sreloc == NULL)
		{
		  sreloc = _bfd_elf_get_dynamic_reloc_section
		    (dynobj, input_section, /*rela?*/ TRUE);
		  /* The section should have been created in cris_elf_check_relocs,
		     but that function will not be called for objects which fail in
		     cris_elf_merge_private_bfd_data.  */
		  if (sreloc == NULL)
		    {
		      bfd_set_error (bfd_error_bad_value);
		      return FALSE;
		    }
		}

	      skip = FALSE;
	      relocate = FALSE;

	      outrel.r_offset =
		_bfd_elf_section_offset (output_bfd, info, input_section,
					 rel->r_offset);
	      if (outrel.r_offset == (bfd_vma) -1)
		skip = TRUE;
	      else if (outrel.r_offset == (bfd_vma) -2
		       /* For now, undefined weak symbols with non-default
			  visibility (yielding 0), like exception info for
			  discarded sections, will get a R_CRIS_NONE
			  relocation rather than no relocation, because we
			  notice too late that the symbol doesn't need a
			  relocation.  */
		       || (h != NULL
			   && h->root.type == bfd_link_hash_undefweak
			   && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT))
		skip = TRUE, relocate = TRUE;
	      outrel.r_offset += (input_section->output_section->vma
				  + input_section->output_offset);

	      if (skip)
		memset (&outrel, 0, sizeof outrel);
	      /* h->dynindx may be -1 if the symbol was marked to
		 become local.  */
	      else if (h != NULL
		       && ((! info->symbolic && h->dynindx != -1)
			   || !h->def_regular))
		{
		  BFD_ASSERT (h->dynindx != -1);
		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
		  outrel.r_addend = relocation + rel->r_addend;
		}
	      else
		{
		  outrel.r_addend = relocation + rel->r_addend;

		  if (r_type == R_CRIS_32)
		    {
		      relocate = TRUE;
		      outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
		    }
		  else
		    {
		      long indx;

		      if (bfd_is_abs_section (sec))
			indx = 0;
		      else if (sec == NULL || sec->owner == NULL)
			{
			  bfd_set_error (bfd_error_bad_value);
			  return FALSE;
			}
		      else
			{
			  asection *osec;

			  /* We are turning this relocation into one
			     against a section symbol.  It would be
			     proper to subtract the symbol's value,
			     osec->vma, from the emitted reloc addend,
			     but ld.so expects buggy relocs.  */
			  osec = sec->output_section;
			  indx = elf_section_data (osec)->dynindx;
			  if (indx == 0)
			    {
			      osec = htab->root.text_index_section;
			      indx = elf_section_data (osec)->dynindx;
			    }
			  BFD_ASSERT (indx != 0);
			}

		      outrel.r_info = ELF32_R_INFO (indx, r_type);
		    }
		}

	      loc = sreloc->contents;
	      loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
	      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);

	      /* This reloc will be computed at runtime, so there's no
                 need to do anything now, except for R_CRIS_32 relocations
                 that have been turned into R_CRIS_RELATIVE.  */
	      if (!relocate)
		continue;
	    }

	  break;

	case R_CRIS_16_DTPREL:
	case R_CRIS_32_DTPREL:
	  /* This relocation must only be performed against local
	     symbols, or to sections that are not loadable.  It's also
	     ok when we link a program and the symbol is defined in an
	     ordinary (non-DSO) object (if it's undefined there, we've
	     already seen an error).  */
	  if (h != NULL
	      && (input_section->flags & SEC_ALLOC) != 0
	      && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
	      && (info->shared
		  || (!h->def_regular
		      && h->root.type != bfd_link_hash_undefined)))
	    {
	      (*_bfd_error_handler)
		((h->root.type == bfd_link_hash_undefined)
		 /* We shouldn't get here for GCC-emitted code.  */
		 ? _("%B, section %A: relocation %s has an undefined"
		     " reference to `%s', perhaps a declaration mixup?")
		 : ("%B, section %A: relocation %s is"
		     " not allowed for `%s', a global symbol with default"
		     " visibility, perhaps a declaration mixup?"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 symname != NULL && symname[0] != '\0'
		 ? symname : _("[whose name is lost]"));
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  BFD_ASSERT ((input_section->flags & SEC_ALLOC) == 0
		      || htab->dtpmod_refcount != 0);

	  /* Fill in a R_CRIS_DTPMOD reloc at offset 3 if we haven't
	     already done so.  Note that we do this in .got.plt, not
	     in .got, as .got.plt contains the first part, still the
	     reloc is against .got, because the linker script directs
	     (is required to direct) them both into .got.  */
	  if (htab->dtpmod_refcount > 0
	      && (input_section->flags & SEC_ALLOC) != 0)
	    {
	      asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
	      BFD_ASSERT (sgotplt != NULL);

	      if (info->shared)
		{
		  Elf_Internal_Rela outrel;
		  bfd_byte *loc;

		  if (srelgot == NULL)
		    srelgot = bfd_get_linker_section (dynobj, ".rela.got");
		  BFD_ASSERT (srelgot != NULL);
		  loc = srelgot->contents;
		  loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);

		  bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 12);
		  bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 16);
		  outrel.r_offset = (sgotplt->output_section->vma
				     + sgotplt->output_offset
				     + 12);
		  outrel.r_info = ELF32_R_INFO (0, R_CRIS_DTPMOD);
		  outrel.r_addend = 0;
		  bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
		}
	      else
		{
		  /* For an executable, the GOT entry contents is known.  */
		  bfd_put_32 (output_bfd, (bfd_vma) 1, sgotplt->contents + 12);
		  bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 16);
		}

	      /* Reverse the sign to mark that we've emitted the
		 required GOT entry.  */
	      htab->dtpmod_refcount = - htab->dtpmod_refcount;
	    }

	  /* The relocation is the offset from the start of the module
	     TLS block to the (local) symbol.  */
	  relocation -= elf_hash_table (info)->tls_sec == NULL
	    ? 0 : elf_hash_table (info)->tls_sec->vma;
	  break;

	case R_CRIS_32_GD:
	  if (info->shared)
	    {
	      bfd_set_error (bfd_error_invalid_operation);

	      /* We've already informed in cris_elf_check_relocs that
		 this is an error.  */
	      return FALSE;
	    }
	  /* Fall through.  */

	case R_CRIS_16_GOT_GD:
	case R_CRIS_32_GOT_GD:
	  if (rel->r_addend != 0)
	    {
	      /* We can't do anything for a relocation which is against a
		 symbol *plus offset*.  The GOT holds relocations for
		 symbols.  Make this an error; the compiler isn't allowed
		 to pass us these kinds of things.  */
	      (*_bfd_error_handler)
		(_("%B, section %A: relocation %s with non-zero addend %d"
		   " against symbol `%s'"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 rel->r_addend,
		 symname[0] != '\0' ? symname : _("[whose name is lost]"));

	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  if (!info->shared
	      && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
	    {
	      /* Known contents of the GOT.  */
	      bfd_vma off;

	      /* The symbol is defined in the program, so just write
		 (1, known_tpoffset) into the GOT.  */
	      relocation -= elf_hash_table (info)->tls_sec->vma;

	      if (h != NULL)
		{
		  off = elf_cris_hash_entry (h)->tprel_refcount > 0
		    ? h->got.offset + 4 : h->got.offset;
		}
	      else
		{
		  off = local_got_offsets[r_symndx];
		  if (local_got_offsets[LGOT_TPREL_NDX (r_symndx)])
		    off += 4;
		}

	      /* We use bit 1 of the offset as a flag for GOT entry with
		 the R_CRIS_DTP reloc, setting it when we've emitted the
		 GOT entry and reloc.  Bit 0 is used for R_CRIS_32_TPREL
		 relocs.  */
	      if ((off & 2) == 0)
		{
		  off &= ~3;

		  if (h != NULL)
		    h->got.offset |= 2;
		  else
		    local_got_offsets[r_symndx] |= 2;

		  bfd_put_32 (output_bfd, 1, sgot->contents + off);
		  bfd_put_32 (output_bfd, relocation, sgot->contents + off + 4);
		}
	      else
		off &= ~3;

	      relocation = sgot->output_offset + off
		+ (r_type == R_CRIS_32_GD ? sgot->output_section->vma : 0);
	    }
	  else
	    {
	      /* Not all parts of the GOT entry are known; emit a real
		 relocation.  */
	      bfd_vma off;

	      if (h != NULL)
		off = elf_cris_hash_entry (h)->tprel_refcount > 0
		  ? h->got.offset + 4 : h->got.offset;
	      else
		{
		  off = local_got_offsets[r_symndx];
		  if (local_got_offsets[LGOT_TPREL_NDX (r_symndx)])
		    off += 4;
		}

	      /* See above re bit 1 and bit 0 usage.  */
	      if ((off & 2) == 0)
		{
		  Elf_Internal_Rela outrel;
		  bfd_byte *loc;

		  off &= ~3;

		  if (h != NULL)
		    h->got.offset |= 2;
		  else
		    local_got_offsets[r_symndx] |= 2;

		  /* Clear the target contents of the GOT (just as a
		     gesture; it's already cleared on allocation): this
		     relocation is not like the other dynrelocs.  */
		  bfd_put_32 (output_bfd, 0, sgot->contents + off);
		  bfd_put_32 (output_bfd, 0, sgot->contents + off + 4);

		  if (srelgot == NULL)
		    srelgot = bfd_get_linker_section (dynobj, ".rela.got");
		  BFD_ASSERT (srelgot != NULL);

		  if (h != NULL && h->dynindx != -1)
		    {
		      outrel.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_DTP);
		      relocation = 0;
		    }
		  else
		    {
		      outrel.r_info = ELF32_R_INFO (0, R_CRIS_DTP);

		      /* NULL if we had an error.  */
		      relocation -= elf_hash_table (info)->tls_sec == NULL
			? 0 : elf_hash_table (info)->tls_sec->vma;
		    }

		  outrel.r_offset = (sgot->output_section->vma
				     + sgot->output_offset
				     + off);
		  outrel.r_addend = relocation;
		  loc = srelgot->contents;
		  loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);

		  /* NULL if we had an error.  */
		  if (srelgot->contents != NULL)
		    bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
		}
	      else
		off &= ~3;

	      relocation = sgot->output_offset + off
		+ (r_type == R_CRIS_32_GD ? sgot->output_section->vma : 0);
	    }

	  /* The GOT-relative offset to the GOT entry is the
	     relocation, or for R_CRIS_32_GD, the actual address of
	     the GOT entry.  */
	  break;

	case R_CRIS_32_IE:
	  if (info->shared)
	    {
	      bfd_set_error (bfd_error_invalid_operation);

	      /* We've already informed in cris_elf_check_relocs that
		 this is an error.  */
	      return FALSE;
	    }
	  /* Fall through.  */

	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_16_GOT_TPREL:
	  if (rel->r_addend != 0)
	    {
	      /* We can't do anything for a relocation which is
		 against a symbol *plus offset*.  GOT holds
		 relocations for symbols.  Make this an error; the
		 compiler isn't allowed to pass us these kinds of
		 things.  */
	      (*_bfd_error_handler)
		(_("%B, section %A: relocation %s with non-zero addend %d"
		   " against symbol `%s'"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 rel->r_addend,
		 symname[0] != '\0' ? symname : _("[whose name is lost]"));
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  if (!info->shared
	      && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
	    {
	      /* Known contents of the GOT.  */
	      bfd_vma off;

	      /* The symbol is defined in the program, so just write
		 the -prog_tls_size+known_tpoffset into the GOT.  */
	      relocation -= elf_hash_table (info)->tls_sec->vma;
	      relocation -= elf_hash_table (info)->tls_size;

	      if (h != NULL)
		off = h->got.offset;
	      else
		off = local_got_offsets[r_symndx];

	      /* Bit 0 is used to mark whether we've emitted the required
		 entry (and if needed R_CRIS_32_TPREL reloc).  Bit 1
		 is used similarly for R_CRIS_DTP, see above.  */
	      if ((off & 1) == 0)
		{
		  off &= ~3;

		  if (h != NULL)
		    h->got.offset |= 1;
		  else
		    local_got_offsets[r_symndx] |= 1;

		  bfd_put_32 (output_bfd, relocation, sgot->contents + off);
		}
	      else
		off &= ~3;

	      relocation = sgot->output_offset + off
		+ (r_type == R_CRIS_32_IE ? sgot->output_section->vma : 0);
	    }
	  else
	    {
	      /* Emit a real relocation.  */
	      bfd_vma off;

	      if (h != NULL)
		off = h->got.offset;
	      else
		off = local_got_offsets[r_symndx];

	      /* See above re usage of bit 0 and 1.  */
	      if ((off & 1) == 0)
		{
		  Elf_Internal_Rela outrel;
		  bfd_byte *loc;

		  off &= ~3;

		  if (h != NULL)
		    h->got.offset |= 1;
		  else
		    local_got_offsets[r_symndx] |= 1;

		  if (srelgot == NULL)
		    srelgot = bfd_get_linker_section (dynobj, ".rela.got");
		  BFD_ASSERT (srelgot != NULL);

		  if (h != NULL && h->dynindx != -1)
		    {
		      outrel.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_32_TPREL);
		      relocation = 0;
		    }
		  else
		    {
		      outrel.r_info = ELF32_R_INFO (0, R_CRIS_32_TPREL);

		      /* NULL if we had an error.  */
		      relocation -= elf_hash_table (info)->tls_sec == NULL
			? 0 : elf_hash_table (info)->tls_sec->vma;
		    }

		  /* Just "define" the initial contents in some
		     semi-logical way.  */
		  bfd_put_32 (output_bfd, relocation, sgot->contents + off);

		  outrel.r_offset = (sgot->output_section->vma
				     + sgot->output_offset
				     + off);
		  outrel.r_addend = relocation;
		  loc = srelgot->contents;
		  loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
		  /* NULL if we had an error.  */
		  if (srelgot->contents != NULL)
		    bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
		}
	      else
		off &= ~3;

	      relocation = sgot->output_offset + off
		+ (r_type == R_CRIS_32_IE ? sgot->output_section->vma : 0);
	    }

	  /* The GOT-relative offset to the GOT entry is the relocation,
	     or for R_CRIS_32_GD, the actual address of the GOT entry.  */
	  break;

	case R_CRIS_16_TPREL:
	case R_CRIS_32_TPREL:
	  /* This relocation must only be performed against symbols
	     defined in an ordinary (non-DSO) object.  */
	  if (info->shared)
	    {
	      bfd_set_error (bfd_error_invalid_operation);

	      /* We've already informed in cris_elf_check_relocs that
		 this is an error.  */
	      return FALSE;
	    }

	  if (h != NULL
	      && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
	      && !(h->def_regular || ELF_COMMON_DEF_P (h))
	      /* If it's undefined, then an error message has already
		 been emitted.  */
	      && h->root.type != bfd_link_hash_undefined)
	    {
	      (*_bfd_error_handler)
		(_("%B, section %A: relocation %s is"
		   " not allowed for symbol: `%s'"
		   " which is defined outside the program,"
		   " perhaps a declaration mixup?"),
		 input_bfd,
		 input_section,
		 cris_elf_howto_table[r_type].name,
		 symname);
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

	  /* NULL if we had an error.  */
	  relocation -= elf_hash_table (info)->tls_sec == NULL
	    ? 0
	    : (elf_hash_table (info)->tls_sec->vma
	       + elf_hash_table (info)->tls_size);

	  /* The TLS-relative offset is the relocation.  */
	  break;

	default:
	  BFD_FAIL ();
	  return FALSE;
	}

      r = cris_final_link_relocate (howto, input_bfd, input_section,
				     contents, rel, relocation);

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

	  switch (r)
	    {
	    case bfd_reloc_overflow:
	      r = info->callbacks->reloc_overflow
		(info, (h ? &h->root : NULL), symname, howto->name,
		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
	      if (additional_relocation_error_msg_count > 0)
		{
		  additional_relocation_error_msg_count--;
		  switch (r_type)
		    {
		    case R_CRIS_16_GOTPLT:
		    case R_CRIS_16_GOT:

		      /* Not just TLS is involved here, so we make
			 generation and message depend on -fPIC/-fpic
			 only.  */
		    case R_CRIS_16_GOT_TPREL:
		    case R_CRIS_16_GOT_GD:
		      (*_bfd_error_handler)
			(_("(too many global variables for -fpic:"
			   " recompile with -fPIC)"));
		      break;

		    case R_CRIS_16_TPREL:
		    case R_CRIS_16_DTPREL:
		      (*_bfd_error_handler)
			(_("(thread-local data too big for -fpic or"
			   " -msmall-tls: recompile with -fPIC or"
			   " -mno-small-tls)"));
		      break;

		      /* No known cause for overflow for other relocs.  */
		    default:
		      break;
		    }
		}
	      break;

	    case bfd_reloc_undefined:
	      r = info->callbacks->undefined_symbol
		(info, symname, input_bfd, input_section, rel->r_offset,
		 TRUE);
	      break;

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

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

	    case bfd_reloc_dangerous:
	      msg = _("internal error: dangerous relocation");
	      break;

	    default:
	      msg = _("internal error: unknown error");
	      break;
	    }

	  if (msg)
	    r = info->callbacks->warning
	      (info, msg, symname, input_bfd, input_section, rel->r_offset);

	  if (! r)
	    return FALSE;
	}
    }

  return TRUE;
}

/* Finish up dynamic symbol handling.  We set the contents of various
   dynamic sections here.  */

static bfd_boolean
elf_cris_finish_dynamic_symbol (bfd *output_bfd,
				struct bfd_link_info *info,
				struct elf_link_hash_entry *h,
				Elf_Internal_Sym *sym)
{
  struct elf_cris_link_hash_table * htab;
  bfd *dynobj;

  /* Where in the plt entry to put values.  */
  int plt_off1 = 2, plt_off2 = 10, plt_off3 = 16;

  /* What offset to add to the distance to the first PLT entry for the
     value at plt_off3.   */
  int plt_off3_value_bias = 4;

  /* Where in the PLT entry the call-dynlink-stub is (happens to be same
     for PIC and non-PIC for v32 and pre-v32).  */
  int plt_stub_offset = 8;
  int plt_entry_size = PLT_ENTRY_SIZE;
  const bfd_byte *plt_entry = elf_cris_plt_entry;
  const bfd_byte *plt_pic_entry = elf_cris_pic_plt_entry;

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

  /* Adjust the various PLT entry offsets.  */
  if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
    {
      plt_off2 = 14;
      plt_off3 = 20;
      plt_off3_value_bias = -2;
      plt_stub_offset = 12;
      plt_entry_size = PLT_ENTRY_SIZE_V32;
      plt_entry = elf_cris_plt_entry_v32;
      plt_pic_entry = elf_cris_pic_plt_entry_v32;
    }

  dynobj = elf_hash_table (info)->dynobj;

  if (h->plt.offset != (bfd_vma) -1)
    {
      asection *splt;
      asection *sgotplt;
      asection *srela;
      bfd_vma got_base;

      bfd_vma gotplt_offset
	= elf_cris_hash_entry (h)->gotplt_offset;
      Elf_Internal_Rela rela;
      bfd_byte *loc;
      bfd_boolean has_gotplt = gotplt_offset != 0;

      /* Get the index in the .rela.plt relocations for the .got.plt
	 entry that corresponds to this symbol.
	 We have to count backwards here, and the result is only valid
	 as an index into .rela.plt.  We also have to undo the effect
	 of the R_CRIS_DTPMOD entry at .got index 3 (offset 12 into
	 .got.plt) for which gotplt_offset is adjusted, because while
	 that entry goes into .got.plt, its relocation goes into
	 .rela.got, not .rela.plt.  (It's not PLT-specific; not to be
	 processed as part of the runtime lazy .rela.plt relocation).
	 FIXME: There be literal constants here...  */
      bfd_vma rela_plt_index
	= (htab->dtpmod_refcount != 0
	   ? gotplt_offset/4 - 2 - 3 : gotplt_offset/4 - 3);

      /* Get the offset into the .got table of the entry that corresponds
	 to this function.  Note that we embed knowledge that "incoming"
	 .got goes after .got.plt in the output without padding (pointer
	 aligned).  However, that knowledge is present in several other
	 places too.  */
      bfd_vma got_offset
	= (has_gotplt
	   ? gotplt_offset
	   : h->got.offset + htab->next_gotplt_entry);

      /* This symbol has an entry in the procedure linkage table.  Set it
	 up.  */

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

      splt = bfd_get_linker_section (dynobj, ".plt");
      sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
      srela = bfd_get_linker_section (dynobj, ".rela.plt");
      BFD_ASSERT (splt != NULL && sgotplt != NULL
		  && (! has_gotplt || srela != NULL));

      got_base = sgotplt->output_section->vma + sgotplt->output_offset;

      /* Fill in the entry in the procedure linkage table.  */
      if (! info->shared)
	{
	  memcpy (splt->contents + h->plt.offset, plt_entry,
		  plt_entry_size);

	  /* We need to enter the absolute address of the GOT entry here.  */
	  bfd_put_32 (output_bfd, got_base + got_offset,
		      splt->contents + h->plt.offset + plt_off1);
	}
      else
	{
	  memcpy (splt->contents + h->plt.offset, plt_pic_entry,
		  plt_entry_size);
	  bfd_put_32 (output_bfd, got_offset,
		      splt->contents + h->plt.offset + plt_off1);
	}

      /* Fill in the plt entry and make a relocation, if this is a "real"
	 PLT entry.  */
      if (has_gotplt)
	{
	  /* Fill in the offset to the reloc table.  */
	  bfd_put_32 (output_bfd,
		      rela_plt_index * sizeof (Elf32_External_Rela),
		      splt->contents + h->plt.offset + plt_off2);

	  /* Fill in the offset to the first PLT entry, where to "jump".  */
	  bfd_put_32 (output_bfd,
		      - (h->plt.offset + plt_off3 + plt_off3_value_bias),
		      splt->contents + h->plt.offset + plt_off3);

	  /* Fill in the entry in the global offset table with the address of
	     the relocating stub.  */
	  bfd_put_32 (output_bfd,
		      (splt->output_section->vma
		       + splt->output_offset
		       + h->plt.offset
		       + plt_stub_offset),
		      sgotplt->contents + got_offset);

	  /* Fill in the entry in the .rela.plt section.  */
	  rela.r_offset = (sgotplt->output_section->vma
			   + sgotplt->output_offset
			   + got_offset);
	  rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_JUMP_SLOT);
	  rela.r_addend = 0;
	  loc = srela->contents + rela_plt_index * sizeof (Elf32_External_Rela);
	  bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
	}

      if (!h->def_regular)
	{
	  /* Mark the symbol as undefined, rather than as defined in
	     the .plt section.  Leave the value alone.  */
	  sym->st_shndx = SHN_UNDEF;

	  /* FIXME: From elf32-sparc.c 2001-02-19 (1.18).  I still don't
	     know whether resetting the value is significant; if it really
	     is, rather than a quirk or bug in the sparc port, then I
	     believe we'd see this elsewhere.  */
	  /* If the symbol is weak, we do need to clear the value.
	     Otherwise, the PLT entry would provide a definition for
	     the symbol even if the symbol wasn't defined anywhere,
	     and so the symbol would never be NULL.  */
	  if (!h->ref_regular_nonweak)
	    sym->st_value = 0;
	}
    }

  /* For an ordinary program, we emit .got relocs only for symbols that
     are in the dynamic-symbols table and are either defined by the
     program or are undefined weak symbols, or are function symbols
     where we do not output a PLT: the PLT reloc was output above and all
     references to the function symbol are redirected to the PLT.  */
  if (h->got.offset != (bfd_vma) -1
      && (elf_cris_hash_entry (h)->reg_got_refcount > 0)
      && (info->shared
	  || (h->dynindx != -1
	      && h->plt.offset == (bfd_vma) -1
	      && !h->def_regular
	      && h->root.type != bfd_link_hash_undefweak)))
    {
      asection *sgot;
      asection *srela;
      Elf_Internal_Rela rela;
      bfd_byte *loc;
      bfd_byte *where;

      /* This symbol has an entry in the global offset table.  Set it up.  */

      sgot = bfd_get_linker_section (dynobj, ".got");
      srela = bfd_get_linker_section (dynobj, ".rela.got");
      BFD_ASSERT (sgot != NULL && srela != NULL);

      rela.r_offset = (sgot->output_section->vma
		       + sgot->output_offset
		       + (h->got.offset &~ (bfd_vma) 1));

      /* If this is a static link, or it is a -Bsymbolic link and the
	 symbol is defined locally or was forced to be local because
	 of a version file, we just want to emit a RELATIVE reloc.
	 The entry in the global offset table will already have been
	 initialized in the relocate_section function.  */
      where = sgot->contents + (h->got.offset &~ (bfd_vma) 1);
      if (! elf_hash_table (info)->dynamic_sections_created
	  || (info->shared
	      && (info->symbolic || h->dynindx == -1)
	      && h->def_regular))
	{
	  rela.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
	  rela.r_addend = bfd_get_signed_32 (output_bfd, where);
	}
      else
	{
	  bfd_put_32 (output_bfd, (bfd_vma) 0, where);
	  rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_GLOB_DAT);
	  rela.r_addend = 0;
	}

      loc = srela->contents;
      loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
    }

  if (h->needs_copy)
    {
      asection *s;
      Elf_Internal_Rela rela;
      bfd_byte *loc;

      /* This symbol needs a copy reloc.  Set it up.  */

      BFD_ASSERT (h->dynindx != -1
		  && (h->root.type == bfd_link_hash_defined
		      || h->root.type == bfd_link_hash_defweak));

      s = bfd_get_linker_section (dynobj, ".rela.bss");
      BFD_ASSERT (s != NULL);

      rela.r_offset = (h->root.u.def.value
		       + h->root.u.def.section->output_section->vma
		       + h->root.u.def.section->output_offset);
      rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_COPY);
      rela.r_addend = 0;
      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
    }

  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
  if (h == elf_hash_table (info)->hdynamic
      || h == elf_hash_table (info)->hgot)
    sym->st_shndx = SHN_ABS;

  return TRUE;
}

/* Finish up the dynamic sections.  Do *not* emit relocs here, as their
   offsets were changed, as part of -z combreloc handling, from those we
   computed.  */

static bfd_boolean
elf_cris_finish_dynamic_sections (bfd *output_bfd,
				  struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *sgot;
  asection *sdyn;

  dynobj = elf_hash_table (info)->dynobj;

  sgot = bfd_get_linker_section (dynobj, ".got.plt");
  BFD_ASSERT (sgot != NULL);
  sdyn = bfd_get_linker_section (dynobj, ".dynamic");

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      asection *splt;
      Elf32_External_Dyn *dyncon, *dynconend;

      splt = bfd_get_linker_section (dynobj, ".plt");
      BFD_ASSERT (splt != NULL && sdyn != NULL);

      dyncon = (Elf32_External_Dyn *) sdyn->contents;
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
      for (; dyncon < dynconend; dyncon++)
	{
	  Elf_Internal_Dyn dyn;
	  asection *s;

	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);

	  switch (dyn.d_tag)
	    {
	    default:
	      break;

	    case DT_PLTGOT:
	      s = bfd_get_section_by_name (output_bfd, ".got");
	      BFD_ASSERT (s != NULL);
	      dyn.d_un.d_ptr = s->vma;
	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
	      break;

	    case DT_JMPREL:
	      /* Yes, we *can* have a .plt and no .plt.rela, for instance
		 if all symbols are found in the .got (not .got.plt).  */
	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	      dyn.d_un.d_ptr = s != NULL ? s->vma : 0;
	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
	      break;

	    case DT_PLTRELSZ:
	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	      if (s == NULL)
		dyn.d_un.d_val = 0;
	      else
		dyn.d_un.d_val = s->size;
	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
	      break;

	    case DT_RELASZ:
	      /* The procedure linkage table relocs (DT_JMPREL) should
		 not be included in the overall relocs (DT_RELA).
		 Therefore, we override the DT_RELASZ entry here to
		 make it not include the JMPREL relocs.  Since the
		 linker script arranges for .rela.plt to follow all
		 other relocation sections, we don't have to worry
		 about changing the DT_RELA entry.  */
	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	      if (s != NULL)
		dyn.d_un.d_val -= s->size;
	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
	      break;
	    }
	}

      /* Fill in the first entry in the procedure linkage table.  */
      if (splt->size > 0)
	{
	  if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
	    {
	      if (info->shared)
		memcpy (splt->contents, elf_cris_pic_plt0_entry_v32,
			PLT_ENTRY_SIZE_V32);
	      else
		{
		  memcpy (splt->contents, elf_cris_plt0_entry_v32,
			  PLT_ENTRY_SIZE_V32);
		  bfd_put_32 (output_bfd,
			      sgot->output_section->vma
			      + sgot->output_offset + 4,
			      splt->contents + 4);

		  elf_section_data (splt->output_section)->this_hdr.sh_entsize
		    = PLT_ENTRY_SIZE_V32;
		}
	    }
	  else
	    {
	      if (info->shared)
		memcpy (splt->contents, elf_cris_pic_plt0_entry,
			PLT_ENTRY_SIZE);
	      else
		{
		  memcpy (splt->contents, elf_cris_plt0_entry,
			  PLT_ENTRY_SIZE);
		  bfd_put_32 (output_bfd,
			      sgot->output_section->vma
			      + sgot->output_offset + 4,
			      splt->contents + 6);
		  bfd_put_32 (output_bfd,
			      sgot->output_section->vma
			      + sgot->output_offset + 8,
			      splt->contents + 14);

		  elf_section_data (splt->output_section)->this_hdr.sh_entsize
		    = PLT_ENTRY_SIZE;
		}
            }
	}
    }

  /* Fill in the first three entries in the global offset table.  */
  if (sgot->size > 0)
    {
      if (sdyn == NULL)
	bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
      else
	bfd_put_32 (output_bfd,
		    sdyn->output_section->vma + sdyn->output_offset,
		    sgot->contents);
      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
    }

  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;

  return TRUE;
}

/* Return the section that should be marked against GC for a given
   relocation.  */

static asection *
cris_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)
{
  enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
  if (h != NULL)
    switch (r_type)
      {
      case R_CRIS_GNU_VTINHERIT:
      case R_CRIS_GNU_VTENTRY:
	return NULL;

      default:
	break;
      }

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

/* Update the got entry reference counts for the section being removed.  */

static bfd_boolean
cris_elf_gc_sweep_hook (bfd *abfd,
			struct bfd_link_info *info,
			asection *sec,
			const Elf_Internal_Rela *relocs)
{
  struct elf_cris_link_hash_table * htab;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel, *relend;
  bfd *dynobj;
  asection *sgot;
  asection *srelgot;

  if (info->relocatable)
    return TRUE;

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

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_refcounts = elf_local_got_refcounts (abfd);

  sgot = bfd_get_linker_section (dynobj, ".got");
  srelgot = bfd_get_linker_section (dynobj, ".rela.got");

  relend = relocs + sec->reloc_count;
  for (rel = relocs; rel < relend; rel++)
    {
      unsigned long r_symndx;
      struct elf_link_hash_entry *h = NULL;
      bfd_signed_vma got_element_size = 4;
      bfd_signed_vma *specific_refcount = NULL;
      enum elf_cris_reloc_type r_type;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx >= symtab_hdr->sh_info)
	{
	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
	  while (h->root.type == bfd_link_hash_indirect
		 || h->root.type == bfd_link_hash_warning)
	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
	}

      r_type = ELF32_R_TYPE (rel->r_info);
      switch (r_type)
	{
	case R_CRIS_32_GOT:
	case R_CRIS_16_GOT:
	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	  specific_refcount = h != NULL
	    ? &((struct elf_cris_link_hash_entry *) h)->reg_got_refcount
	    : &local_got_refcounts[LGOT_REG_NDX (r_symndx)];
	  break;

	case R_CRIS_32_GD:
	case R_CRIS_32_GOT_GD:
	case R_CRIS_16_GOT_GD:
	  got_element_size = 8;
	  specific_refcount = h != NULL
	    ? &((struct elf_cris_link_hash_entry *) h)->dtp_refcount
	    : &local_got_refcounts[LGOT_DTP_NDX (r_symndx)];
	  break;

	case R_CRIS_32_IE:
	case R_CRIS_16_GOT_TPREL:
	case R_CRIS_32_GOT_TPREL:
	  specific_refcount = h != NULL
	    ? &((struct elf_cris_link_hash_entry *) h)->tprel_refcount
	    : &local_got_refcounts[LGOT_TPREL_NDX (r_symndx)];
	  break;

	default:
	  break;
	}

      switch (r_type)
	{
	case R_CRIS_32_IE:
	case R_CRIS_32_GD:
	case R_CRIS_16_GOT_TPREL:
	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_32_GOT_GD:
	case R_CRIS_16_GOT_GD:
	case R_CRIS_16_GOT:
	case R_CRIS_32_GOT:
	  if (h != NULL)
	    {
	      /* If the counters are 0 when we got here, we've
		 miscounted somehow somewhere, an internal error.  */
	      BFD_ASSERT (h->got.refcount > 0);
	      --h->got.refcount;

	      BFD_ASSERT (*specific_refcount > 0);
	      --*specific_refcount;
	      if (*specific_refcount == 0)
		{
		  /* We don't need the .got entry any more.  */
		  sgot->size -= got_element_size;
		  srelgot->size -= sizeof (Elf32_External_Rela);
		}
	      break;
	    }

	local_got_reloc:
	  if (local_got_refcounts != NULL)
	    {
	      /* If the counters are 0 when we got here, we've
		 miscounted somehow somewhere, an internal error.  */
	      BFD_ASSERT (local_got_refcounts[r_symndx] > 0);
	      --local_got_refcounts[r_symndx];

	      BFD_ASSERT (*specific_refcount > 0);
	      --*specific_refcount;
	      if (*specific_refcount == 0)
		{
		  /* We don't need the .got entry any more.  */
		  sgot->size -= got_element_size;
		  if (info->shared)
		    srelgot->size -= sizeof (Elf32_External_Rela);
		}
	    }
	  break;

	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	  /* For local symbols, treat these like GOT relocs.  */
	  if (h == NULL)
	    goto local_got_reloc;
	  else
	    /* For global symbols, adjust the reloc-specific refcount.  */
	    elf_cris_hash_entry (h)->gotplt_refcount--;
	  /* Fall through.  */

	case R_CRIS_32_PLT_GOTREL:
	  /* FIXME: We don't garbage-collect away the .got section.  */
	  if (local_got_refcounts != NULL)
	    local_got_refcounts[-1]--;
	  /* Fall through.  */

	case R_CRIS_8:
	case R_CRIS_16:
	case R_CRIS_32:
	case R_CRIS_8_PCREL:
	case R_CRIS_16_PCREL:
	case R_CRIS_32_PCREL:
	case R_CRIS_32_PLT_PCREL:
	  /* Negate the increment we did in cris_elf_check_relocs.  */
	  if (h != NULL)
	    {
	      if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
		  && h->plt.refcount > 0)
		--h->plt.refcount;
	    }
	  break;

	case R_CRIS_32_DTPREL:
	  /* This'd be a .dtpreld entry in e.g. debug info.  */
	  if ((sec->flags & SEC_ALLOC) == 0)
	    break;
	  /* Fall through.  */
	case R_CRIS_16_DTPREL:
	  htab->dtpmod_refcount--;
	  if (htab->dtpmod_refcount == 0)
	    htab->next_gotplt_entry -= 8;
	  BFD_ASSERT (local_got_refcounts != NULL);
	  local_got_refcounts[-1]--;
	  break;

	default:
	  break;
	}
    }

  return TRUE;
}

/* The elf_backend_plt_sym_val hook function.  */

static bfd_vma
cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
		      const arelent *rel)
{
  bfd_size_type plt_entry_size;
  bfd_size_type pltoffs;
  bfd *abfd = plt->owner;

  /* Same for CRIS and CRIS v32; see elf_cris_(|pic_)plt_entry(|_v32)[].  */
  bfd_size_type plt_entry_got_offset = 2;
  bfd_size_type plt_sec_size;
  bfd_size_type got_vma_for_dyn;
  asection *got;

  /* FIXME: the .got section should be readily available also when
     we're not linking.  */
  if ((got = bfd_get_section_by_name (abfd, ".got")) == NULL)
    return (bfd_vma) -1;

  plt_sec_size =  bfd_section_size (plt->owner, plt);
  plt_entry_size
    = (bfd_get_mach (abfd) == bfd_mach_cris_v32
       ? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);

  /* Data in PLT is GOT-relative for DYN, but absolute for EXE.  */
  got_vma_for_dyn = (abfd->flags & EXEC_P) ? 0 : got->vma;

  /* Because we can have merged GOT entries; a single .got entry for
     both GOT and the PLT part of the GOT (.got.plt), the index of the
     reloc in .rela.plt is not the same as the index in the PLT.
     Instead, we have to hunt down the GOT offset in the PLT that
     corresponds to that of this reloc.  Unfortunately, we will only
     be called for the .rela.plt relocs, so we'll miss synthetic
     symbols for .plt entries with merged GOT entries.  (FIXME:
     fixable by providing our own bfd_elf32_get_synthetic_symtab.
     Doesn't seem worthwile at time of this writing.)  FIXME: we've
     gone from O(1) to O(N) (N number of PLT entries) for finding each
     PLT address.  Shouldn't matter in practice though.  */

  for (pltoffs = plt_entry_size;
       pltoffs < plt_sec_size;
       pltoffs += plt_entry_size)
    {
      bfd_size_type got_offset;
      bfd_byte gotoffs_raw[4];

      if (!bfd_get_section_contents (abfd, (asection *) plt, gotoffs_raw,
				     pltoffs + plt_entry_got_offset,
				     sizeof (gotoffs_raw)))
	return (bfd_vma) -1;

      got_offset = bfd_get_32 (abfd, gotoffs_raw);
      if (got_offset + got_vma_for_dyn == rel->address)
	return plt->vma + pltoffs;
    }

  /* While it's tempting to BFD_ASSERT that we shouldn't get here,
     that'd not be graceful behavior for invalid input.  */
  return (bfd_vma) -1;
}

/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
   entry but we found we will not create any.  Called when we find we will
   not have any PLT for this symbol, by for example
   elf_cris_adjust_dynamic_symbol when we're doing a proper dynamic link,
   or elf_cris_size_dynamic_sections if no dynamic sections will be
   created (we're only linking static objects).  */

static bfd_boolean
elf_cris_adjust_gotplt_to_got (struct elf_cris_link_hash_entry *h, void * p)
{
  struct bfd_link_info *info = (struct bfd_link_info *) p;

  /* A GOTPLT reloc, when activated, is supposed to be included into
     the PLT refcount.  */
  BFD_ASSERT (h->gotplt_refcount == 0
	      || h->gotplt_refcount <= h->root.plt.refcount);

  /* If nobody wanted a GOTPLT with this symbol, we're done.  */
  if (h->gotplt_refcount <= 0)
    return TRUE;

  if (h->reg_got_refcount > 0)
    {
      /* There's a GOT entry for this symbol.  Just adjust the refcounts.
	 Probably not necessary at this stage, but keeping them accurate
	 helps avoiding surprises later.  */
      h->root.got.refcount += h->gotplt_refcount;
      h->reg_got_refcount += h->gotplt_refcount;
      h->gotplt_refcount = 0;
    }
  else
    {
      /* No GOT entry for this symbol.  We need to create one.  */
      bfd *dynobj = elf_hash_table (info)->dynobj;
      asection *sgot;
      asection *srelgot;

      BFD_ASSERT (dynobj != NULL);
      sgot = bfd_get_linker_section (dynobj, ".got");
      srelgot = bfd_get_linker_section (dynobj, ".rela.got");

      /* Put accurate refcounts there.  */
      h->root.got.refcount += h->gotplt_refcount;
      h->reg_got_refcount = h->gotplt_refcount;

      h->gotplt_refcount = 0;

      /* We always have a .got and a .rela.got section if there were
	 GOTPLT relocs in input.  */
      BFD_ASSERT (sgot != NULL && srelgot != NULL);

      /* Allocate space in the .got section.  */
      sgot->size += 4;

      /* Allocate relocation space.  */
      srelgot->size += sizeof (Elf32_External_Rela);
    }

  return TRUE;
}

/* Try to fold PLT entries with GOT entries.  There are two cases when we
   want to do this:

   - When all PLT references are GOTPLT references, and there are GOT
     references, and this is not the executable.  We don't have to
     generate a PLT at all.

   - When there are both (ordinary) PLT references and GOT references,
     and this isn't the executable.
     We want to make the PLT reference use the ordinary GOT entry rather
     than R_CRIS_JUMP_SLOT, a run-time dynamically resolved GOTPLT entry,
     since the GOT entry will have to be resolved at startup anyway.

   Though the latter case is handled when room for the PLT is allocated,
   not here.

   By folding into the GOT, we may need a round-trip to a PLT in the
   executable for calls, a loss in performance.  Still, losing a
   reloc is a win in size and at least in start-up time.

   Note that this function is called before symbols are forced local by
   version scripts.  The differing cases are handled by
   elf_cris_hide_symbol.  */

static bfd_boolean
elf_cris_try_fold_plt_to_got (struct elf_cris_link_hash_entry *h, void * p)
{
  struct bfd_link_info *info = (struct bfd_link_info *) p;

  /* If there are no GOT references for this symbol, we can't fold any
     other reference so there's nothing to do.  Likewise if there are no
     PLT references; GOTPLT references included.  */
  if (h->root.got.refcount <= 0 || h->root.plt.refcount <= 0)
    return TRUE;

  /* GOTPLT relocs are supposed to be included into the PLT refcount.  */
  BFD_ASSERT (h->gotplt_refcount <= h->root.plt.refcount);

  if (h->gotplt_refcount == h->root.plt.refcount)
    {
      /* The only PLT references are GOTPLT references, and there are GOT
	 references.  Convert PLT to GOT references.  */
      if (! elf_cris_adjust_gotplt_to_got (h, info))
	return FALSE;

      /* Clear the PLT references, so no PLT will be created.  */
      h->root.plt.offset = (bfd_vma) -1;
    }

  return TRUE;
}

/* Our own version of hide_symbol, so that we can adjust a GOTPLT reloc
   to use a GOT entry (and create one) rather than requiring a GOTPLT
   entry.  */

static void
elf_cris_hide_symbol (struct bfd_link_info *info,
		      struct elf_link_hash_entry *h,
		      bfd_boolean force_local)
{
  elf_cris_adjust_gotplt_to_got ((struct elf_cris_link_hash_entry *) h, info);

  _bfd_elf_link_hash_hide_symbol (info, h, force_local);
}

/* 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
elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
				struct elf_link_hash_entry *h)
{
  struct elf_cris_link_hash_table * htab;
  bfd *dynobj;
  asection *s;
  bfd_size_type plt_entry_size;

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

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

  plt_entry_size
    = (bfd_get_mach (dynobj) == bfd_mach_cris_v32
       ? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);

  /* If this is a function, put it in the procedure linkage table.  We
     will fill in the contents of the procedure linkage table later,
     when we know the address of the .got section.  */
  if (h->type == STT_FUNC
      || h->needs_plt)
    {
      /* If we link a program (not a DSO), we'll get rid of unnecessary
	 PLT entries; we point to the actual symbols -- even for pic
	 relocs, because a program built with -fpic should have the same
	 result as one built without -fpic, specifically considering weak
	 symbols.
	 FIXME: m68k and i386 differ here, for unclear reasons.  */
      if (! info->shared
	  && !h->def_dynamic)
	{
	  /* This case can occur if we saw a PLT reloc in an input file,
	     but the symbol was not defined by a dynamic object.  In such
	     a case, we don't actually need to build a procedure linkage
	     table, and we can just do an absolute or PC reloc instead, or
	     change a .got.plt index to a .got index for GOTPLT relocs.  */
	  BFD_ASSERT (h->needs_plt);
	  h->needs_plt = 0;
	  h->plt.offset = (bfd_vma) -1;
	  return
	    elf_cris_adjust_gotplt_to_got ((struct
					    elf_cris_link_hash_entry *) h,
					   info);
	}

      /* If we had a R_CRIS_GLOB_DAT that didn't have to point to a PLT;
	 where a pointer-equivalent symbol was unimportant (i.e. more
	 like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
	 of the PLT.  We can't for the executable, because the GOT
	 entries will point to the PLT there (and be constant).  */
      if (info->shared
	  && !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
					    h, info))
	return FALSE;

      /* GC or folding may have rendered this entry unused.  */
      if (h->plt.refcount <= 0)
	{
	  h->needs_plt = 0;
	  h->plt.offset = (bfd_vma) -1;
	  return TRUE;
	}

      /* Make sure this symbol is output as a dynamic symbol.  */
      if (h->dynindx == -1)
	{
	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
	    return FALSE;
	}

      s = bfd_get_linker_section (dynobj, ".plt");
      BFD_ASSERT (s != NULL);

      /* If this is the first .plt entry, make room for the special
	 first entry.  */
      if (s->size == 0)
	s->size += plt_entry_size;

      /* If this symbol is not defined in a regular file, and we are
	 not generating a shared library, then set the symbol to this
	 location in the .plt.  */
      if (!info->shared
	  && !h->def_regular)
	{
	  h->root.u.def.section = s;
	  h->root.u.def.value = s->size;
	}

      /* If there's already a GOT entry, use that, not a .got.plt.  A
	 GOT field still has a reference count when we get here; it's
	 not yet changed to an offset.  We can't do this for an
	 executable, because then the reloc associated with the PLT
	 would get a non-PLT reloc pointing to the PLT.  FIXME: Move
	 this to elf_cris_try_fold_plt_to_got.  */
      if (info->shared && h->got.refcount > 0)
	{
	  h->got.refcount += h->plt.refcount;

	  /* Mark the PLT offset to use the GOT entry by setting the low
	     bit in the plt offset; it is always a multiple of
	     plt_entry_size (which is at least a multiple of 2).  */
	  BFD_ASSERT ((s->size % plt_entry_size) == 0);

	  /* Change the PLT refcount to an offset.  */
	  h->plt.offset = s->size;

	  /* By not setting gotplt_offset (i.e. it remains at 0), we signal
	     that the got entry should be used instead.  */
	  BFD_ASSERT (((struct elf_cris_link_hash_entry *)
		       h)->gotplt_offset == 0);

	  /* Make room for this entry.  */
	  s->size += plt_entry_size;

	  return TRUE;
	}

      /* No GOT reference for this symbol; prepare for an ordinary PLT.  */
      h->plt.offset = s->size;

      /* Make room for this entry.  */
      s->size += plt_entry_size;

      /* We also need to make an entry in the .got.plt section, which
	 will be placed in the .got section by the linker script.  */
      ((struct elf_cris_link_hash_entry *) h)->gotplt_offset
	= htab->next_gotplt_entry;
      htab->next_gotplt_entry += 4;

      s = bfd_get_linker_section (dynobj, ".got.plt");
      BFD_ASSERT (s != NULL);
      s->size += 4;

      /* We also need to make an entry in the .rela.plt section.  */

      s = bfd_get_linker_section (dynobj, ".rela.plt");
      BFD_ASSERT (s != NULL);
      s->size += sizeof (Elf32_External_Rela);

      return TRUE;
    }

  /* Reinitialize the plt offset now that it is not used as a reference
     count any more.  */
  h->plt.offset = (bfd_vma) -1;

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

  /* If we are creating a shared library, we must presume that the
     only references to the symbol are via the global offset table.
     For such cases we need not do anything here; the relocations will
     be handled correctly by relocate_section.  */
  if (info->shared)
    return TRUE;

  /* If there are no references to this symbol that do not use the
     GOT, we don't need to generate a copy reloc.  */
  if (!h->non_got_ref)
    return TRUE;

  /* We must allocate the symbol in our .dynbss section, which will
     become part of the .bss section of the executable.  There will be
     an entry for this symbol in the .dynsym section.  The dynamic
     object will contain position independent code, so all references
     from the dynamic object to this symbol will go through the global
     offset table.  The dynamic linker will use the .dynsym entry to
     determine the address it must put in the global offset table, so
     both the dynamic object and the regular object will refer to the
     same memory location for the variable.  */

  s = bfd_get_linker_section (dynobj, ".dynbss");
  BFD_ASSERT (s != NULL);

  /* We must generate a R_CRIS_COPY reloc to tell the dynamic linker to
     copy the initial value out of the dynamic object and into the
     runtime process image.  We need to remember the offset into the
     .rela.bss section we are going to use.  */
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
    {
      asection *srel;

      srel = bfd_get_linker_section (dynobj, ".rela.bss");
      BFD_ASSERT (srel != NULL);
      srel->size += sizeof (Elf32_External_Rela);
      h->needs_copy = 1;
    }

  return _bfd_elf_adjust_dynamic_copy (h, s);
}

/* Adjust our "subclass" elements for an indirect symbol.  */

static void
elf_cris_copy_indirect_symbol (struct bfd_link_info *info,
			       struct elf_link_hash_entry *dir,
			       struct elf_link_hash_entry *ind)
{
  struct elf_cris_link_hash_entry *edir, *eind;

  edir = (struct elf_cris_link_hash_entry *) dir;
  eind = (struct elf_cris_link_hash_entry *) ind;

  /* Only indirect symbols are replaced; we're not interested in
     updating any of EIND's fields for other symbols.  */
  if (eind->root.root.type != bfd_link_hash_indirect)
    {
      /* Still, we need to copy flags for e.g. weak definitions.  */
      _bfd_elf_link_hash_copy_indirect (info, dir, ind);
      return;
    }

  BFD_ASSERT (edir->gotplt_offset == 0 || eind->gotplt_offset == 0);

#define XMOVOPZ(F, OP, Z) edir->F OP eind->F; eind->F = Z
#define XMOVE(F) XMOVOPZ (F, +=, 0)
  if (eind->pcrel_relocs_copied != NULL)
    {
      if (edir->pcrel_relocs_copied != NULL)
	{
	  struct elf_cris_pcrel_relocs_copied **pp;
	  struct elf_cris_pcrel_relocs_copied *p;

	  /* Add reloc counts against the indirect sym to the direct sym
	     list.  Merge any entries against the same section.  */
	  for (pp = &eind->pcrel_relocs_copied; *pp != NULL;)
	    {
	      struct elf_cris_pcrel_relocs_copied *q;
	      p = *pp;
	      for (q = edir->pcrel_relocs_copied; q != NULL; q = q->next)
		if (q->section == p->section)
		  {
		    q->count += p->count;
		    *pp = p->next;
		    break;
		  }
	      if (q == NULL)
		pp = &p->next;
	    }
	  *pp = edir->pcrel_relocs_copied;
	}
      XMOVOPZ (pcrel_relocs_copied, =, NULL);
    }
  XMOVE (gotplt_refcount);
  XMOVE (gotplt_offset);
  XMOVE (reg_got_refcount);
  XMOVE (tprel_refcount);
  XMOVE (dtp_refcount);
#undef XMOVE
#undef XMOVOPZ

  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}

/* Look through the relocs for a section during the first phase.  */

static bfd_boolean
cris_elf_check_relocs (bfd *abfd,
		       struct bfd_link_info *info,
		       asection *sec,
		       const Elf_Internal_Rela *relocs)
{
  struct elf_cris_link_hash_table * htab;
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sgot;
  asection *srelgot;
  asection *sreloc;

  if (info->relocatable)
    return TRUE;

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_refcounts = elf_local_got_refcounts (abfd);

  sgot = NULL;
  srelgot = NULL;
  sreloc = NULL;

  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      struct elf_link_hash_entry *h;
      unsigned long r_symndx;
      enum elf_cris_reloc_type r_type;
      bfd_signed_vma got_element_size = 4;
      unsigned long r_symndx_lgot = INT_MAX;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx < symtab_hdr->sh_info)
	{
	  h = NULL;
	  r_symndx_lgot = LGOT_REG_NDX (r_symndx);
	}
      else
	{
	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
	  while (h->root.type == bfd_link_hash_indirect
		 || h->root.type == bfd_link_hash_warning)
	    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;
	}

      r_type = ELF32_R_TYPE (rel->r_info);

      /* Some relocs require linker-created sections; we need to hang them
	 on the first input bfd we found that contained dynamic relocs.  */
      switch (r_type)
	{
	case R_CRIS_32_DTPREL:
	  if ((sec->flags & SEC_ALLOC) == 0)
	    /* This'd be a .dtpreld entry in e.g. debug info.  We have
	       several different switch statements below, but none of
	       that is needed; we need no preparations for resolving
	       R_CRIS_32_DTPREL into a non-allocated section (debug
	       info), so let's just move on to the next
	       relocation.  */
	    continue;
	  /* Fall through.  */
	case R_CRIS_16_DTPREL:
	  /* The first .got.plt entry is right after the R_CRIS_DTPMOD
	     entry at index 3. */
	  if (htab->dtpmod_refcount == 0)
	    htab->next_gotplt_entry += 8;

	  htab->dtpmod_refcount++;
	  /* Fall through.  */

	case R_CRIS_32_IE:
	case R_CRIS_32_GD:
	case R_CRIS_16_GOT_GD:
	case R_CRIS_32_GOT_GD:
	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_16_GOT_TPREL:
	case R_CRIS_16_GOT:
	case R_CRIS_32_GOT:
	case R_CRIS_32_GOTREL:
	case R_CRIS_32_PLT_GOTREL:
	case R_CRIS_32_PLT_PCREL:
	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	  if (dynobj == NULL)
	    {
	      elf_hash_table (info)->dynobj = dynobj = abfd;

	      /* We could handle this if we can get a handle on the
		 output bfd in elf_cris_adjust_dynamic_symbol.  Failing
		 that, we must insist on dynobj being a specific mach.  */
	      if (bfd_get_mach (dynobj) == bfd_mach_cris_v10_v32)
		{
		  (*_bfd_error_handler)
		    (_("%B, section %A:\n  v10/v32 compatible object %s"
		       " must not contain a PIC relocation"),
		     abfd, sec);
		  return FALSE;
		}

	      /* Create the .got section, so we can assume it's always
		 present whenever there's a dynobj.  */
	      if (!_bfd_elf_create_got_section (dynobj, info))
		return FALSE;
	    }

	  if (sgot == NULL)
	    sgot = bfd_get_linker_section (dynobj, ".got");

	  if (local_got_refcounts == NULL)
	    {
	      bfd_size_type amt;

	      /* We use index local_got_refcounts[-1] to count all
		 GOT-relative relocations that do not have explicit
		 GOT entries.  */
	      amt = LGOT_ALLOC_NELTS_FOR (symtab_hdr->sh_info) + 1;
	      amt *= sizeof (bfd_signed_vma);
	      local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, amt));
	      if (local_got_refcounts == NULL)
		return FALSE;

	      local_got_refcounts++;
	      elf_local_got_refcounts (abfd) = local_got_refcounts;
	    }
	  break;

	default:
	  break;
	}

      /* Some relocs require a global offset table (but perhaps not a
	 specific GOT entry).  */
      switch (r_type)
	{
	case R_CRIS_16_DTPREL:
	case R_CRIS_32_DTPREL:
	  /* Not requesting .got.rela for an executable: the contents
	     of the first entry is constant there.  For a shared
	     library, we need .got.rela for the R_CRIS_DTPMOD
	     relocation at index 3.  */
	  if (!info->shared)
	    break;
	  /* Fall through.  */

	case R_CRIS_32_IE:
	case R_CRIS_32_GD:
	case R_CRIS_16_GOT_GD:
	case R_CRIS_32_GOT_GD:
	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_16_GOT_TPREL:
	  /* Fall through.  */

	  /* For R_CRIS_16_GOTPLT and R_CRIS_32_GOTPLT, we need a GOT
	     entry only for local symbols.  Unfortunately, we don't know
	     until later on if there's a version script that forces the
	     symbol local.  We must have the .rela.got section in place
	     before we know if the symbol looks global now, so we need
	     to treat the reloc just like for R_CRIS_16_GOT and
	     R_CRIS_32_GOT.  */
	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	case R_CRIS_16_GOT:
	case R_CRIS_32_GOT:
	  if (srelgot == NULL
	      && (h != NULL || info->shared))
	    {
	      srelgot = bfd_get_linker_section (dynobj, ".rela.got");
	      if (srelgot == NULL)
		{
		  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
				    | SEC_IN_MEMORY | SEC_LINKER_CREATED
				    | SEC_READONLY);
		  srelgot = bfd_make_section_anyway_with_flags (dynobj,
								".rela.got",
								flags);
		  if (srelgot == NULL
		      || !bfd_set_section_alignment (dynobj, srelgot, 2))
		    return FALSE;
		}
	    }
	  break;

	default:
	  break;
	}

      /* Warn and error for invalid input.  */
      switch (r_type)
	{
	case R_CRIS_32_IE:
	case R_CRIS_32_TPREL:
	case R_CRIS_16_TPREL:
	case R_CRIS_32_GD:
	  if (info->shared)
	    {
	      (*_bfd_error_handler)
		(_("%B, section %A:\n  relocation %s not valid"
		   " in a shared object;"
		   " typically an option mixup, recompile with -fPIC"),
		 abfd,
		 sec,
		 cris_elf_howto_table[r_type].name);
	      /* Don't return FALSE here; we want messages for all of
		 these and the error behavior is ungraceful
		 anyway.  */
	    }
	default:
	  break;
	}

      switch (r_type)
	{
	case R_CRIS_32_GD:
	case R_CRIS_16_GOT_GD:
	case R_CRIS_32_GOT_GD:
	  /* These are requests for tls_index entries, run-time R_CRIS_DTP.  */
	  got_element_size = 8;
	  r_symndx_lgot = LGOT_DTP_NDX (r_symndx);
	  break;

	case R_CRIS_16_DTPREL:
	case R_CRIS_32_DTPREL:
	  /* These two just request for the constant-index
	     module-local tls_index-sized GOT entry, which we add
	     elsewhere.  */
	  break;

	case R_CRIS_32_IE:
	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_16_GOT_TPREL:
	  r_symndx_lgot = LGOT_TPREL_NDX (r_symndx);

	  /* Those relocs also require that a DSO is of type
	     Initial Exec.  Like other targets, we don't reset this
	     flag even if the relocs are GC:ed away.  */
	  if (info->shared)
	    info->flags |= DF_STATIC_TLS;
	  break;

	  /* Let's list the other assembler-generated TLS-relocs too,
	     just to show that they're not forgotten. */
	case R_CRIS_16_TPREL:
	case R_CRIS_32_TPREL:
	default:
	  break;
	}

      switch (r_type)
        {
	case R_CRIS_16_GOTPLT:
	case R_CRIS_32_GOTPLT:
	  /* Mark that we need a GOT entry if the PLT entry (and its GOT
	     entry) is eliminated.  We can only do this for a non-local
	     symbol.  */
	  if (h != NULL)
	    {
	      elf_cris_hash_entry (h)->gotplt_refcount++;
	      goto handle_gotplt_reloc;
	    }
	  /* If h is NULL then this is a local symbol, and we must make a
	     GOT entry for it, so handle it like a GOT reloc.  */
	  /* Fall through.  */

	case R_CRIS_32_IE:
	case R_CRIS_32_GD:
	case R_CRIS_16_GOT_GD:
	case R_CRIS_32_GOT_GD:
	case R_CRIS_32_GOT_TPREL:
	case R_CRIS_16_GOT_TPREL:
	case R_CRIS_16_GOT:
	case R_CRIS_32_GOT:
	  /* This symbol requires a global offset table entry.  */
	  if (h != NULL)
	    {
	      if (h->got.refcount == 0)
		{
		  /* Make sure this symbol is output as a dynamic symbol.  */
		  if (h->dynindx == -1)
		    {
		      if (!bfd_elf_link_record_dynamic_symbol (info, h))
			return FALSE;
		    }
		}

	      /* Update the sum of reloc counts for this symbol.  */
	      h->got.refcount++;

	      switch (r_type)
		{
		case R_CRIS_16_GOT:
		case R_CRIS_32_GOT:
		  if (elf_cris_hash_entry (h)->reg_got_refcount == 0)
		    {
		      /* Allocate space in the .got section.  */
		      sgot->size += got_element_size;
		      /* Allocate relocation space.  */
		      srelgot->size += sizeof (Elf32_External_Rela);
		    }
		  elf_cris_hash_entry (h)->reg_got_refcount++;
		  break;

		case R_CRIS_32_GD:
		case R_CRIS_16_GOT_GD:
		case R_CRIS_32_GOT_GD:
		  if (elf_cris_hash_entry (h)->dtp_refcount == 0)
		    {
		      /* Allocate space in the .got section.  */
		      sgot->size += got_element_size;
		      /* Allocate relocation space.  */
		      srelgot->size += sizeof (Elf32_External_Rela);
		    }
		  elf_cris_hash_entry (h)->dtp_refcount++;
		  break;

		case R_CRIS_32_IE:
		case R_CRIS_32_GOT_TPREL:
		case R_CRIS_16_GOT_TPREL:
		  if (elf_cris_hash_entry (h)->tprel_refcount == 0)
		    {
		      /* Allocate space in the .got section.  */
		      sgot->size += got_element_size;
		      /* Allocate relocation space.  */
		      srelgot->size += sizeof (Elf32_External_Rela);
		    }
		  elf_cris_hash_entry (h)->tprel_refcount++;
		  break;

		default:
		  BFD_FAIL ();
		  break;
		}
	    }
	  else
	    {
	      /* This is a global offset table entry for a local symbol.  */
	      if (local_got_refcounts[r_symndx_lgot] == 0)
		{
		  sgot->size += got_element_size;
		  if (info->shared)
		    {
		      /* If we are generating a shared object, we need
			 to output a R_CRIS_RELATIVE reloc so that the
			 dynamic linker can adjust this GOT entry.
			 Similarly for non-regular got entries.  */
		      srelgot->size += sizeof (Elf32_External_Rela);
		    }
		}
	      /* Update the reloc-specific count.  */
	      local_got_refcounts[r_symndx_lgot]++;

	      /* This one is the sum of all the others.  */
	      local_got_refcounts[r_symndx]++;
	    }
	  break;

	case R_CRIS_16_DTPREL:
	case R_CRIS_32_DTPREL:
	case R_CRIS_32_GOTREL:
	  /* This reference requires a global offset table.
	     FIXME: The actual refcount isn't used currently; the .got
	     section can't be removed if there were any references in the
	     input.  */
	  local_got_refcounts[-1]++;
	  break;

	handle_gotplt_reloc:

	case R_CRIS_32_PLT_GOTREL:
	  /* This reference requires a global offset table.  */
	  local_got_refcounts[-1]++;
	  /* Fall through.  */

	case R_CRIS_32_PLT_PCREL:
	  /* This symbol requires a procedure linkage table entry.  We
	     actually build the entry in adjust_dynamic_symbol,
             because this might be a case of linking PIC code which is
             never referenced by a dynamic object, in which case we
             don't need to generate a procedure linkage table entry
             after all.  */

	  /* Beware: if we'd check for visibility of the symbol here
	     (and not marking the need for a PLT when non-visible), we'd
	     get into trouble with keeping handling consistent with
	     regards to relocs found before definition and GOTPLT
	     handling.  Eliminable PLT entries will be dealt with later
	     anyway.  */
	  if (h == NULL)
	    continue;

	  h->needs_plt = 1;
	  h->plt.refcount++;
	  break;

	case R_CRIS_8:
	case R_CRIS_16:
	case R_CRIS_32:
	  /* Let's help debug shared library creation.  Any of these
	     relocs *can* be used in shared libs, but pages containing
	     them cannot be shared, so they're not appropriate for
	     common use.  Don't warn for sections we don't care about,
	     such as debug sections or non-constant sections.  We
	     can't help tables of (global) function pointers, for
	     example, though they must be emitted in a (writable) data
	     section to avoid having impure text sections.  */
	  if (info->shared
	      && (sec->flags & SEC_ALLOC) != 0
	      && (sec->flags & SEC_READONLY) != 0)
	    {
	      /* FIXME: How do we make this optionally a warning only?  */
	      (*_bfd_error_handler)
		(_("%B, section %A:\n  relocation %s should not"
		   " be used in a shared object; recompile with -fPIC"),
		 abfd,
		 sec,
		 cris_elf_howto_table[r_type].name);
	    }

	  /* We don't need to handle relocs into sections not going into
	     the "real" output.  */
	  if ((sec->flags & SEC_ALLOC) == 0)
	    break;

	  if (h != NULL)
	    {
	      h->non_got_ref = 1;

	      /* Make sure a plt entry is created for this symbol if it
		 turns out to be a function defined by a dynamic object.  */
	      if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
		h->plt.refcount++;
	    }

	  /* If we are creating a shared library and this is not a local
	     symbol, we need to copy the reloc into the shared library.
	     However when linking with -Bsymbolic and this is a global
	     symbol which is defined in an object we are including in the
	     link (i.e., DEF_REGULAR is set), then we can resolve the
	     reloc directly.  At this point we have not seen all the input
	     files, so it is possible that DEF_REGULAR is not set now but
	     will be set later (it is never cleared).  In case of a weak
	     definition, DEF_REGULAR may be cleared later by a strong
	     definition in a shared library.  We account for that
	     possibility below by storing information in the relocs_copied
	     field of the hash table entry.  A similar situation occurs
	     when creating shared libraries and symbol visibility changes
	     render the symbol local.  */

	  /* No need to do anything if we're not creating a shared object.  */
	  if (! info->shared)
	    break;

	  /* We may need to create a reloc section in the dynobj and made room
	     for this reloc.  */
	  if (sreloc == NULL)
	    {
	      sreloc = _bfd_elf_make_dynamic_reloc_section
		(sec, dynobj, 2, abfd, /*rela?*/ TRUE);

	      if (sreloc == NULL)
		return FALSE;
	    }

	  if (sec->flags & SEC_READONLY)
	    info->flags |= DF_TEXTREL;

	  sreloc->size += sizeof (Elf32_External_Rela);
	  break;

	case R_CRIS_8_PCREL:
	case R_CRIS_16_PCREL:
	case R_CRIS_32_PCREL:
	  if (h != NULL)
	    {
	      h->non_got_ref = 1;

	      /* Make sure a plt entry is created for this symbol if it
		 turns out to be a function defined by a dynamic object.  */
	      if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
		h->plt.refcount++;
	    }

	  /* If we are creating a shared library and this is not a local
	     symbol, we need to copy the reloc into the shared library.
	     However when linking with -Bsymbolic and this is a global
	     symbol which is defined in an object we are including in the
	     link (i.e., DEF_REGULAR is set), then we can resolve the
	     reloc directly.  At this point we have not seen all the input
	     files, so it is possible that DEF_REGULAR is not set now but
	     will be set later (it is never cleared).  In case of a weak
	     definition, DEF_REGULAR may be cleared later by a strong
	     definition in a shared library.  We account for that
	     possibility below by storing information in the relocs_copied
	     field of the hash table entry.  A similar situation occurs
	     when creating shared libraries and symbol visibility changes
	     render the symbol local.  */

	  /* No need to do anything if we're not creating a shared object.  */
	  if (! info->shared)
	    break;

	  /* We don't need to handle relocs into sections not going into
	     the "real" output.  */
	  if ((sec->flags & SEC_ALLOC) == 0)
	    break;

	  /* If the symbol is local, then we know already we can
	     eliminate the reloc.  */
	  if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
	    break;

	  /* If this is with -Bsymbolic and the symbol isn't weak, and
	     is defined by an ordinary object (the ones we include in
	     this shared library) then we can also eliminate the
	     reloc.  See comment above for more eliminable cases which
	     we can't identify at this time.  */
	  if (info->symbolic
	      && h->root.type != bfd_link_hash_defweak
	      && h->def_regular)
	    break;

	  /* We may need to create a reloc section in the dynobj and made room
	     for this reloc.  */
	  if (sreloc == NULL)
	    {
	      sreloc = _bfd_elf_make_dynamic_reloc_section
		(sec, dynobj, 2, abfd, /*rela?*/ TRUE);

	      if (sreloc == NULL)
		return FALSE;
	    }

	  sreloc->size += sizeof (Elf32_External_Rela);

	  /* We count the number of PC relative relocations we have
	     entered for this symbol, so that we can discard them
	     again if the symbol is later defined by a regular object.
	     We know that h is really a pointer to an
	     elf_cris_link_hash_entry.  */
	  {
	    struct elf_cris_link_hash_entry *eh;
	    struct elf_cris_pcrel_relocs_copied *p;

	    eh = elf_cris_hash_entry (h);

	    for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
	      if (p->section == sec)
		break;

	    if (p == NULL)
	      {
		p = ((struct elf_cris_pcrel_relocs_copied *)
		     bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
		if (p == NULL)
		  return FALSE;
		p->next = eh->pcrel_relocs_copied;
		eh->pcrel_relocs_copied = p;
		p->section = sec;
		p->count = 0;
		p->r_type = r_type;
	      }

	    ++p->count;
	  }
	  break;

        /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_CRIS_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_CRIS_GNU_VTENTRY:
          BFD_ASSERT (h != NULL);
          if (h != NULL
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;

	case R_CRIS_16_TPREL:
	case R_CRIS_32_TPREL:
	  /* Already warned above, when necessary.  */
	  break;

	default:
	  /* Other relocs do not appear here.  */
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
        }
    }

  return TRUE;
}

/* Set the sizes of the dynamic sections.  */

static bfd_boolean
elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
				struct bfd_link_info *info)
{
  struct elf_cris_link_hash_table * htab;
  bfd *dynobj;
  asection *s;
  bfd_boolean plt;
  bfd_boolean relocs;

  htab = elf_cris_hash_table (info);
  if (htab == NULL)
    return FALSE;

  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 (info->executable)
	{
	  s = bfd_get_linker_section (dynobj, ".interp");
	  BFD_ASSERT (s != NULL);
	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
	}
    }
  else
    {
      /* Adjust all expected GOTPLT uses to use a GOT entry instead.  */
      elf_cris_link_hash_traverse (htab, elf_cris_adjust_gotplt_to_got,
				   info);

      /* We may have created entries in the .rela.got section.
	 However, if we are not creating the dynamic sections, we will
	 not actually use these entries.  Reset the size of .rela.got,
	 which will cause it to get stripped from the output file
	 below.  */
      s = bfd_get_linker_section (dynobj, ".rela.got");
      if (s != NULL)
	s->size = 0;
    }

  /* If this is a -Bsymbolic shared link, then we need to discard all PC
     relative relocs against symbols defined in a regular object.  We
     allocated space for them in the check_relocs routine, but we will not
     fill them in in the relocate_section routine.  We also discard space
     for relocs that have become for local symbols due to symbol
     visibility changes.  For programs, we discard space for relocs for
     symbols not referenced by any dynamic object.  */
  if (info->shared)
    elf_cris_link_hash_traverse (htab,
				 elf_cris_discard_excess_dso_dynamics,
				 info);
  else
    elf_cris_link_hash_traverse (htab,
				 elf_cris_discard_excess_program_dynamics,
				 info);

  /* The check_relocs and adjust_dynamic_symbol entry points have
     determined the sizes of the various dynamic sections.  Allocate
     memory for them.  */
  plt = FALSE;
  relocs = 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 (strcmp (name, ".plt") == 0)
	{
	  /* Remember whether there is a PLT.  */
	  plt = s->size != 0;
	}
      else if (strcmp (name, ".got.plt") == 0)
	{
	  /* The .got.plt contains the .got header as well as the
	     actual .got.plt contents.  The .got header may contain a
	     R_CRIS_DTPMOD entry at index 3.  */
	  s->size += htab->dtpmod_refcount != 0
	    ? 8 : 0;
	}
      else if (CONST_STRNEQ (name, ".rela"))
	{
	  if (strcmp (name, ".rela.got") == 0
	      && htab->dtpmod_refcount != 0
	      && info->shared)
	    s->size += sizeof (Elf32_External_Rela);

	  if (s->size != 0)
	    {
	      /* Remember whether there are any reloc sections other
                 than .rela.plt.  */
	      if (strcmp (name, ".rela.plt") != 0)
		  relocs = TRUE;

	      /* We use the reloc_count field as a counter if we need
		 to copy relocs into the output file.  */
	      s->reloc_count = 0;
	    }
	}
      else if (! CONST_STRNEQ (name, ".got")
	       && strcmp (name, ".dynbss") != 0)
	{
	  /* It's not one of our sections, so don't allocate space.  */
	  continue;
	}

      if (s->size == 0)
	{
	  /* If we don't need this section, strip it from the
	     output file.  This is mostly to handle .rela.bss and
	     .rela.plt.  We must create both sections in
	     create_dynamic_sections, because they must be created
	     before the linker maps input sections to output
	     sections.  The linker does that before
	     adjust_dynamic_symbol is called, and it is that
	     function which decides whether anything needs to go
	     into these sections.  */
	  s->flags |= SEC_EXCLUDE;
	  continue;
	}

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

      /* Allocate memory for the section contents. We use bfd_zalloc here
	 in case unused entries are not reclaimed before the section's
	 contents are written out.  This should not happen, but this way
	 if it does, we will not write out garbage.  For reloc sections,
	 this will make entries have the type R_CRIS_NONE.  */
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL)
	return FALSE;
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add some entries to the .dynamic section.  We fill in the
	 values later, in elf_cris_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.  */
#define add_dynamic_entry(TAG, VAL) \
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)

      if (!info->shared)
	{
	  if (!add_dynamic_entry (DT_DEBUG, 0))
	    return FALSE;
	}

      if (plt)
	{
	  if (!add_dynamic_entry (DT_PLTGOT, 0)
	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
	      || !add_dynamic_entry (DT_JMPREL, 0))
	    return FALSE;
	}

      if (relocs)
	{
	  if (!add_dynamic_entry (DT_RELA, 0)
	      || !add_dynamic_entry (DT_RELASZ, 0)
	      || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
	    return FALSE;
	}

      if ((info->flags & DF_TEXTREL) != 0)
	{
	  if (!add_dynamic_entry (DT_TEXTREL, 0))
	    return FALSE;
	  info->flags |= DF_TEXTREL;
	}
    }
#undef add_dynamic_entry

  return TRUE;
}

/* This function is called via elf_cris_link_hash_traverse if we are
   creating a shared object.  In the -Bsymbolic case, it discards the
   space allocated to copy PC relative relocs against symbols which
   are defined in regular objects.  For the normal non-symbolic case,
   we also discard space for relocs that have become local due to
   symbol visibility changes.  We allocated space for them in the
   check_relocs routine, but we won't fill them in in the
   relocate_section routine.  */

static bfd_boolean
elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *h,
				      void * inf)
{
  struct elf_cris_pcrel_relocs_copied *s;
  struct bfd_link_info *info = (struct bfd_link_info *) inf;

  /* If a symbol has been forced local or we have found a regular
     definition for the symbolic link case, then we won't be needing
     any relocs.  */
  if (h->root.def_regular
      && (h->root.forced_local
	  || info->symbolic))
    {
      for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
	{
	  asection *sreloc
	    = _bfd_elf_get_dynamic_reloc_section (elf_hash_table (info)
						  ->dynobj,
						  s->section,
						  /*rela?*/ TRUE);
	  sreloc->size -= s->count * sizeof (Elf32_External_Rela);
	}
      return TRUE;
    }

  /* If we have accounted for PC-relative relocs for read-only
     sections, now is the time to warn for them.  We can't do it in
     cris_elf_check_relocs, because we don't know the status of all
     symbols at that time (and it's common to force symbols local
     late).  */

  for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
    if ((s->section->flags & SEC_READONLY) != 0)
      {
	/* FIXME: How do we make this optionally a warning only?  */
	(*_bfd_error_handler)
	  (_("%B, section `%A', to symbol `%s':\n"
	     "  relocation %s should not be used"
	     " in a shared object; recompile with -fPIC"),
	   s->section->owner,
	   s->section,
	   h->root.root.root.string,
	   cris_elf_howto_table[s->r_type].name);

	info->flags |= DF_TEXTREL;
      }

  return TRUE;
}

/* This function is called via elf_cris_link_hash_traverse if we are *not*
   creating a shared object.  We discard space for relocs for symbols put
   in the .got, but which we found we do not have to resolve at run-time.  */

static bfd_boolean
elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *h,
					  void * inf)
{
  struct bfd_link_info *info = (struct bfd_link_info *) inf;

  /* If we're not creating a shared library and have a symbol which is
     referred to by .got references, but the symbol is defined locally,
     (or rather, not defined by a DSO) then lose the reloc for the .got
     (don't allocate room for it).  Likewise for relocs for something
     for which we create a PLT.  */
  if (!h->root.def_dynamic
      || h->root.plt.refcount > 0)
    {
      if (h->reg_got_refcount > 0
	  /* The size of this section is only valid and in sync with the
	     various reference counts if we do dynamic; don't decrement it
	     otherwise.  */
	  && elf_hash_table (info)->dynamic_sections_created)
	{
	  bfd *dynobj = elf_hash_table (info)->dynobj;
	  asection *srelgot;

	  BFD_ASSERT (dynobj != NULL);

	  srelgot = bfd_get_linker_section (dynobj, ".rela.got");

	  BFD_ASSERT (srelgot != NULL);

	  srelgot->size -= sizeof (Elf32_External_Rela);
	}

      /* If the locally-defined symbol isn't used by a DSO, then we don't
	 have to export it as a dynamic symbol.  This was already done for
	 functions; doing this for all symbols would presumably not
	 introduce new problems.  Of course we don't do this if we're
	 exporting all dynamic symbols.  */
      if (! info->export_dynamic
	  && h->root.dynindx != -1
	  && !h->root.def_dynamic
	  && !h->root.ref_dynamic)
	{
	  h->root.dynindx = -1;
	  _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
				  h->root.dynstr_index);
	}
    }

  return TRUE;
}

/* Reject a file depending on presence and expectation of prefixed
   underscores on symbols.  */

static bfd_boolean
cris_elf_object_p (bfd *abfd)
{
  if (! cris_elf_set_mach_from_flags (abfd, elf_elfheader (abfd)->e_flags))
    return FALSE;

  if ((elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE))
    return (bfd_get_symbol_leading_char (abfd) == '_');
  else
    return (bfd_get_symbol_leading_char (abfd) == 0);
}

/* Mark presence or absence of leading underscore.  Set machine type
   flags from mach type.  */

static void
cris_elf_final_write_processing (bfd *abfd,
				 bfd_boolean linker ATTRIBUTE_UNUSED)
{
  unsigned long e_flags = elf_elfheader (abfd)->e_flags;

  e_flags &= ~EF_CRIS_UNDERSCORE;
  if (bfd_get_symbol_leading_char (abfd) == '_')
    e_flags |= EF_CRIS_UNDERSCORE;

  switch (bfd_get_mach (abfd))
    {
    case bfd_mach_cris_v0_v10:
      e_flags |= EF_CRIS_VARIANT_ANY_V0_V10;
      break;

    case bfd_mach_cris_v10_v32:
      e_flags |= EF_CRIS_VARIANT_COMMON_V10_V32;
      break;

    case bfd_mach_cris_v32:
      e_flags |= EF_CRIS_VARIANT_V32;
      break;

    default:
      _bfd_abort (__FILE__, __LINE__,
		  _("Unexpected machine number"));
    }

  elf_elfheader (abfd)->e_flags = e_flags;
}

/* Set the mach type from e_flags value.  */

static bfd_boolean
cris_elf_set_mach_from_flags (bfd *abfd,
			      unsigned long flags)
{
  switch (flags & EF_CRIS_VARIANT_MASK)
    {
    case EF_CRIS_VARIANT_ANY_V0_V10:
      bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v0_v10);
      break;

    case EF_CRIS_VARIANT_V32:
      bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v32);
      break;

    case EF_CRIS_VARIANT_COMMON_V10_V32:
      bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v10_v32);
      break;

    default:
      /* Since we don't recognize them, we obviously can't support them
	 with this code; we'd have to require that all future handling
	 would be optional.  */
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  return TRUE;
}

/* Display the flags field.  */

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

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

  _bfd_elf_print_private_bfd_data (abfd, ptr);

  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);

  if (elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE)
    fprintf (file, _(" [symbols have a _ prefix]"));
  if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
      == EF_CRIS_VARIANT_COMMON_V10_V32)
    fprintf (file, _(" [v10 and v32]"));
  if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
      == EF_CRIS_VARIANT_V32)
    fprintf (file, _(" [v32]"));

  fputc ('\n', file);
  return TRUE;
}

/* Don't mix files with and without a leading underscore.  */

static bfd_boolean
cris_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  int imach, omach;

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

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

  imach = bfd_get_mach (ibfd);

  if (! elf_flags_init (obfd))
    {
      /* This happens when ld starts out with a 'blank' output file.  */
      elf_flags_init (obfd) = TRUE;

      /* We ignore the linker-set mach, and instead set it according to
	 the first input file.  This would also happen if we could
	 somehow filter out the OUTPUT_ARCH () setting from elf.sc.
	 This allows us to keep the same linker config across
	 cris(v0..v10) and crisv32.  The drawback is that we can't force
	 the output type, which might be a sane thing to do for a
	 v10+v32 compatibility object.  */
      if (! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
	return FALSE;
    }

  if (bfd_get_symbol_leading_char (ibfd)
      != bfd_get_symbol_leading_char (obfd))
    {
      (*_bfd_error_handler)
	(bfd_get_symbol_leading_char (ibfd) == '_'
	 ? _("%B: uses _-prefixed symbols, but writing file with non-prefixed symbols")
	 : _("%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
	 ibfd);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  omach = bfd_get_mach (obfd);

  if (imach != omach)
    {
      /* We can get an incompatible combination only if either is
	 bfd_mach_cris_v32, and the other one isn't compatible.  */
      if ((imach == bfd_mach_cris_v32
	   && omach != bfd_mach_cris_v10_v32)
	  || (omach == bfd_mach_cris_v32
	      && imach != bfd_mach_cris_v10_v32))
	{
	  (*_bfd_error_handler)
	    ((imach == bfd_mach_cris_v32)
	     ? _("%B contains CRIS v32 code, incompatible"
		 " with previous objects")
	     : _("%B contains non-CRIS-v32 code, incompatible"
		 " with previous objects"),
	     ibfd);
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}

      /* We don't have to check the case where the input is compatible
	 with v10 and v32, because the output is already known to be set
	 to the other (compatible) mach.  */
      if (omach == bfd_mach_cris_v10_v32
	  && ! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
	return FALSE;
    }

  return TRUE;
}

/* Do side-effects of e_flags copying to obfd.  */

static bfd_boolean
cris_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  /* Call the base function.  */
  if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
    return FALSE;

  /* If output is big-endian for some obscure reason, stop here.  */
  if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
    return FALSE;

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

  /* Do what we really came here for.  */
  return bfd_set_arch_mach (obfd, bfd_arch_cris, bfd_get_mach (ibfd));
}

static enum elf_reloc_type_class
elf_cris_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
			   const asection *rel_sec ATTRIBUTE_UNUSED,
			   const Elf_Internal_Rela *rela)
{
  enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rela->r_info);
  switch (r_type)
    {
    case R_CRIS_RELATIVE:
      return reloc_class_relative;
    case R_CRIS_JUMP_SLOT:
      return reloc_class_plt;
    case R_CRIS_COPY:
      return reloc_class_copy;
    default:
      return reloc_class_normal;
    }
}

/* The elf_backend_got_elt_size worker.  For one symbol, we can have up to
   two GOT entries from three types with two different sizes.  We handle
   it as a single entry, so we can use the regular offset-calculation
   machinery.  */

static bfd_vma
elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
		       struct bfd_link_info *info ATTRIBUTE_UNUSED,
		       struct elf_link_hash_entry *hr,
		       bfd *ibfd,
		       unsigned long symndx)
{
  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) hr;
  bfd_vma eltsiz = 0;

  /* We may have one regular GOT entry or up to two TLS GOT
     entries.  */
  if (h == NULL)
    {
      Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
      bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (ibfd);

      BFD_ASSERT (local_got_refcounts != NULL);

      if (local_got_refcounts[LGOT_REG_NDX (symndx)] > 0)
	{
	  /* We can't have a variable referred to both as a regular
	     variable and through TLS relocs.  */
	  BFD_ASSERT (local_got_refcounts[LGOT_DTP_NDX (symndx)] == 0
		      && local_got_refcounts[LGOT_TPREL_NDX (symndx)] == 0);
	  return 4;
	}

      if (local_got_refcounts[LGOT_DTP_NDX (symndx)] > 0)
	eltsiz += 8;

      if (local_got_refcounts[LGOT_TPREL_NDX (symndx)] > 0)
	eltsiz += 4;
    }
  else
    {
      struct elf_cris_link_hash_entry *hh = elf_cris_hash_entry (h);
      if (hh->reg_got_refcount > 0)
	{
	  /* The actual error-on-input is emitted elsewhere.  */
	  BFD_ASSERT (hh->dtp_refcount == 0 && hh->tprel_refcount == 0);
	  return 4;
	}

      if (hh->dtp_refcount > 0)
	eltsiz += 8;

      if (hh->tprel_refcount > 0)
	eltsiz += 4;
    }

  /* We're only called when h->got.refcount is non-zero, so we must
     have a non-zero size.  */
  BFD_ASSERT (eltsiz != 0);
  return eltsiz;
}

#define ELF_ARCH		bfd_arch_cris
#define ELF_TARGET_ID		CRIS_ELF_DATA
#define ELF_MACHINE_CODE	EM_CRIS
#define ELF_MAXPAGESIZE		0x2000

#define TARGET_LITTLE_SYM	bfd_elf32_cris_vec
#define TARGET_LITTLE_NAME	"elf32-cris"
#define elf_symbol_leading_char 0

#define elf_info_to_howto_rel			NULL
#define elf_info_to_howto			cris_info_to_howto_rela
#define elf_backend_relocate_section		cris_elf_relocate_section
#define elf_backend_gc_mark_hook		cris_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook		cris_elf_gc_sweep_hook
#define elf_backend_plt_sym_val			cris_elf_plt_sym_val
#define elf_backend_check_relocs                cris_elf_check_relocs
#define elf_backend_grok_prstatus		cris_elf_grok_prstatus
#define elf_backend_grok_psinfo			cris_elf_grok_psinfo

#define elf_backend_can_gc_sections		1
#define elf_backend_can_refcount		1

#define elf_backend_object_p			cris_elf_object_p
#define elf_backend_final_write_processing \
	cris_elf_final_write_processing
#define bfd_elf32_bfd_print_private_bfd_data \
	cris_elf_print_private_bfd_data
#define bfd_elf32_bfd_merge_private_bfd_data \
	cris_elf_merge_private_bfd_data
#define bfd_elf32_bfd_copy_private_bfd_data \
	cris_elf_copy_private_bfd_data

#define bfd_elf32_bfd_reloc_type_lookup		cris_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup	cris_reloc_name_lookup

#define bfd_elf32_bfd_link_hash_table_create \
	elf_cris_link_hash_table_create
#define elf_backend_adjust_dynamic_symbol \
	elf_cris_adjust_dynamic_symbol
#define elf_backend_copy_indirect_symbol \
	elf_cris_copy_indirect_symbol
#define elf_backend_size_dynamic_sections \
	elf_cris_size_dynamic_sections
#define elf_backend_init_index_section		_bfd_elf_init_1_index_section
#define elf_backend_finish_dynamic_symbol \
	elf_cris_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
	elf_cris_finish_dynamic_sections
#define elf_backend_create_dynamic_sections \
	_bfd_elf_create_dynamic_sections
#define bfd_elf32_bfd_final_link \
	bfd_elf_gc_common_final_link
#define elf_backend_hide_symbol			elf_cris_hide_symbol
#define elf_backend_reloc_type_class		elf_cris_reloc_type_class

#define elf_backend_want_got_plt	1
#define elf_backend_plt_readonly	1
#define elf_backend_want_plt_sym	0
#define elf_backend_got_header_size	12
#define elf_backend_got_elt_size elf_cris_got_elt_size

/* Later, we my want to optimize RELA entries into REL entries for dynamic
   linking and libraries (if it's a win of any significance).  Until then,
   take the easy route.  */
#define elf_backend_may_use_rel_p 0
#define elf_backend_may_use_rela_p 1
#define elf_backend_rela_normal		1

#include "elf32-target.h"

#undef TARGET_LITTLE_SYM
#undef TARGET_LITTLE_NAME
#undef elf_symbol_leading_char

#define TARGET_LITTLE_SYM bfd_elf32_us_cris_vec
#define TARGET_LITTLE_NAME "elf32-us-cris"
#define elf_symbol_leading_char '_'
#undef elf32_bed
#define elf32_bed elf32_us_cris_bed

#include "elf32-target.h"
