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

      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 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"
