/* Motorola 68k series support for 32-bit ELF
   Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.

   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 "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/m68k.h"
#include "opcode/m68k.h"

static reloc_howto_type *reloc_type_lookup
  PARAMS ((bfd *, bfd_reloc_code_real_type));
static void rtype_to_howto
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
static struct bfd_hash_entry *elf_m68k_link_hash_newfunc
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
static struct bfd_link_hash_table *elf_m68k_link_hash_table_create
  PARAMS ((bfd *));
static bfd_boolean elf_m68k_check_relocs
  PARAMS ((bfd *, struct bfd_link_info *, asection *,
	   const Elf_Internal_Rela *));
static bfd_boolean elf_m68k_adjust_dynamic_symbol
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_boolean elf_m68k_size_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf_m68k_discard_copies
  PARAMS ((struct elf_link_hash_entry *, PTR));
static bfd_boolean elf_m68k_relocate_section
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static bfd_boolean elf_m68k_finish_dynamic_symbol
  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
	   Elf_Internal_Sym *));
static bfd_boolean elf_m68k_finish_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *));

static bfd_boolean elf32_m68k_set_private_flags
  PARAMS ((bfd *, flagword));
static bfd_boolean elf32_m68k_merge_private_bfd_data
  PARAMS ((bfd *, bfd *));
static bfd_boolean elf32_m68k_print_private_bfd_data
  PARAMS ((bfd *, PTR));
static enum elf_reloc_type_class elf32_m68k_reloc_type_class
  PARAMS ((const Elf_Internal_Rela *));

static reloc_howto_type howto_table[] = {
  HOWTO(R_68K_NONE,       0, 0, 0, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_NONE",      FALSE, 0, 0x00000000,FALSE),
  HOWTO(R_68K_32,         0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32",        FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_16,         0, 1,16, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16",        FALSE, 0, 0x0000ffff,FALSE),
  HOWTO(R_68K_8,          0, 0, 8, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8",         FALSE, 0, 0x000000ff,FALSE),
  HOWTO(R_68K_PC32,       0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32",      FALSE, 0, 0xffffffff,TRUE),
  HOWTO(R_68K_PC16,       0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PC16",      FALSE, 0, 0x0000ffff,TRUE),
  HOWTO(R_68K_PC8,        0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PC8",       FALSE, 0, 0x000000ff,TRUE),
  HOWTO(R_68K_GOT32,      0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32",     FALSE, 0, 0xffffffff,TRUE),
  HOWTO(R_68K_GOT16,      0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT16",     FALSE, 0, 0x0000ffff,TRUE),
  HOWTO(R_68K_GOT8,       0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT8",      FALSE, 0, 0x000000ff,TRUE),
  HOWTO(R_68K_GOT32O,     0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O",    FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_GOT16O,     0, 1,16, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT16O",    FALSE, 0, 0x0000ffff,FALSE),
  HOWTO(R_68K_GOT8O,      0, 0, 8, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT8O",     FALSE, 0, 0x000000ff,FALSE),
  HOWTO(R_68K_PLT32,      0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32",     FALSE, 0, 0xffffffff,TRUE),
  HOWTO(R_68K_PLT16,      0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT16",     FALSE, 0, 0x0000ffff,TRUE),
  HOWTO(R_68K_PLT8,       0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT8",      FALSE, 0, 0x000000ff,TRUE),
  HOWTO(R_68K_PLT32O,     0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O",    FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_PLT16O,     0, 1,16, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT16O",    FALSE, 0, 0x0000ffff,FALSE),
  HOWTO(R_68K_PLT8O,      0, 0, 8, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT8O",     FALSE, 0, 0x000000ff,FALSE),
  HOWTO(R_68K_COPY,       0, 0, 0, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_COPY",      FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_GLOB_DAT,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_GLOB_DAT",  FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_JMP_SLOT,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_JMP_SLOT",  FALSE, 0, 0xffffffff,FALSE),
  HOWTO(R_68K_RELATIVE,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_RELATIVE",  FALSE, 0, 0xffffffff,FALSE),
  /* GNU extension to record C++ vtable hierarchy.  */
  HOWTO (R_68K_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_68K_GNU_VTINHERIT",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),
  /* GNU extension to record C++ vtable member usage.  */
  HOWTO (R_68K_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_68K_GNU_VTENTRY",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),
};

static void
rtype_to_howto (abfd, cache_ptr, dst)
     bfd *abfd ATTRIBUTE_UNUSED;
     arelent *cache_ptr;
     Elf_Internal_Rela *dst;
{
  BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K_max);
  cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
}

#define elf_info_to_howto rtype_to_howto

static const struct
{
  bfd_reloc_code_real_type bfd_val;
  int elf_val;
} reloc_map[] = {
  { BFD_RELOC_NONE, R_68K_NONE },
  { BFD_RELOC_32, R_68K_32 },
  { BFD_RELOC_16, R_68K_16 },
  { BFD_RELOC_8, R_68K_8 },
  { BFD_RELOC_32_PCREL, R_68K_PC32 },
  { BFD_RELOC_16_PCREL, R_68K_PC16 },
  { BFD_RELOC_8_PCREL, R_68K_PC8 },
  { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 },
  { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 },
  { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 },
  { BFD_RELOC_32_GOTOFF, R_68K_GOT32O },
  { BFD_RELOC_16_GOTOFF, R_68K_GOT16O },
  { BFD_RELOC_8_GOTOFF, R_68K_GOT8O },
  { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 },
  { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 },
  { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 },
  { BFD_RELOC_32_PLTOFF, R_68K_PLT32O },
  { BFD_RELOC_16_PLTOFF, R_68K_PLT16O },
  { BFD_RELOC_8_PLTOFF, R_68K_PLT8O },
  { BFD_RELOC_NONE, R_68K_COPY },
  { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT },
  { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT },
  { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE },
  { BFD_RELOC_CTOR, R_68K_32 },
  { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },
  { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },
};

static reloc_howto_type *
reloc_type_lookup (abfd, code)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd_reloc_code_real_type code;
{
  unsigned int i;
  for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
    {
      if (reloc_map[i].bfd_val == code)
	return &howto_table[reloc_map[i].elf_val];
    }
  return 0;
}

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

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

  return NULL;
}

#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
#define ELF_ARCH bfd_arch_m68k

/* Functions for the m68k ELF linker.  */

/* The name of the dynamic interpreter.  This is put in the .interp
   section.  */

#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"

/* Describes one of the various PLT styles.  */

struct elf_m68k_plt_info
{
  /* The size of each PLT entry.  */
  bfd_vma size;

  /* The template for the first PLT entry.  */
  const bfd_byte *plt0_entry;

  /* Offsets of fields in PLT0_ENTRY that require R_68K_PC32 relocations.
     The comments by each member indicate the value that the relocation
     is against.  */
  struct {
    unsigned int got4; /* .got + 4 */
    unsigned int got8; /* .got + 8 */
  } plt0_relocs;

  /* The template for a symbol's PLT entry.  */
  const bfd_byte *symbol_entry;

  /* Offsets of fields in SYMBOL_ENTRY that require R_68K_PC32 relocations.
     The comments by each member indicate the value that the relocation
     is against.  */
  struct {
    unsigned int got; /* the symbol's .got.plt entry */
    unsigned int plt; /* .plt */
  } symbol_relocs;

  /* The offset of the resolver stub from the start of SYMBOL_ENTRY.
     The stub starts with "move.l #relocoffset,%d0".  */
  bfd_vma symbol_resolve_entry;
};

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

#define PLT_ENTRY_SIZE 20

/* The first entry in a procedure linkage table looks like this.  See
   the SVR4 ABI m68k supplement to see how this works.  */

static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
{
  0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
  0, 0, 0, 2,		  /* + (.got + 4) - . */
  0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
  0, 0, 0, 2,		  /* + (.got + 8) - . */
  0, 0, 0, 0		  /* pad out to 20 bytes.  */
};

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

static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
{
  0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
  0, 0, 0, 2,		  /* + (.got.plt entry) - . */
  0x2f, 0x3c,		  /* move.l #offset,-(%sp) */
  0, 0, 0, 0,		  /* + reloc index */
  0x60, 0xff,		  /* bra.l .plt */
  0, 0, 0, 0		  /* + .plt - . */
};

static const struct elf_m68k_plt_info elf_m68k_plt_info = {
  PLT_ENTRY_SIZE,
  elf_m68k_plt0_entry, { 4, 12 },
  elf_m68k_plt_entry, { 4, 16 }, 8
};

#define ISAB_PLT_ENTRY_SIZE 24

static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
{
  0x20, 0x3c,             /* move.l #offset,%d0 */
  0, 0, 0, 0,             /* + (.got + 4) - . */
  0x2f, 0x3b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),-(%sp) */
  0x20, 0x3c,             /* move.l #offset,%d0 */
  0, 0, 0, 0,             /* + (.got + 8) - . */
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
  0x4e, 0xd0,             /* jmp (%a0) */
  0x4e, 0x71		  /* nop */
};

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

static const bfd_byte elf_isab_plt_entry[ISAB_PLT_ENTRY_SIZE] =
{
  0x20, 0x3c,             /* move.l #offset,%d0 */
  0, 0, 0, 0,             /* + (.got.plt entry) - . */
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
  0x4e, 0xd0,             /* jmp (%a0) */
  0x2f, 0x3c,             /* move.l #offset,-(%sp) */
  0, 0, 0, 0,             /* + reloc index */
  0x60, 0xff,             /* bra.l .plt */
  0, 0, 0, 0              /* + .plt - . */
};

static const struct elf_m68k_plt_info elf_isab_plt_info = {
  ISAB_PLT_ENTRY_SIZE,
  elf_isab_plt0_entry, { 2, 12 },
  elf_isab_plt_entry, { 2, 20 }, 12
};

#define ISAC_PLT_ENTRY_SIZE 24

static const bfd_byte elf_isac_plt0_entry[ISAC_PLT_ENTRY_SIZE] =
{
  0x20, 0x3c,		  /* move.l #offset,%d0 */
  0, 0, 0, 0,		  /* replaced with .got + 4 - . */
  0x2e, 0xbb, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),(%sp) */
  0x20, 0x3c,		  /* move.l #offset,%d0 */
  0, 0, 0, 0,		  /* replaced with .got + 8 - . */
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
  0x4e, 0xd0,		  /* jmp (%a0) */
  0x4e, 0x71		  /* nop */
};

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

static const bfd_byte elf_isac_plt_entry[ISAC_PLT_ENTRY_SIZE] =
{
  0x20, 0x3c,		  /* move.l #offset,%d0 */
  0, 0, 0, 0,		  /* replaced with (.got entry) - . */
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
  0x4e, 0xd0,		  /* jmp (%a0) */
  0x2f, 0x3c,		  /* move.l #offset,-(%sp) */
  0, 0, 0, 0,		  /* replaced with offset into relocation table */
  0x61, 0xff,		  /* bsr.l .plt */
  0, 0, 0, 0 		  /* replaced with .plt - . */
};

static const struct elf_m68k_plt_info elf_isac_plt_info = {
  ISAC_PLT_ENTRY_SIZE,
  elf_isac_plt0_entry, { 2, 12},
  elf_isac_plt_entry, { 2, 20 }, 12
};

#define CPU32_PLT_ENTRY_SIZE 24
/* Procedure linkage table entries for the cpu32 */
static const bfd_byte elf_cpu32_plt0_entry[CPU32_PLT_ENTRY_SIZE] =
{
  0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
  0, 0, 0, 2,             /* + (.got + 4) - . */
  0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
  0, 0, 0, 2,             /* + (.got + 8) - . */
  0x4e, 0xd1,             /* jmp %a1@ */
  0, 0, 0, 0,             /* pad out to 24 bytes.  */
  0, 0
};

static const bfd_byte elf_cpu32_plt_entry[CPU32_PLT_ENTRY_SIZE] =
{
  0x22, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a1 */
  0, 0, 0, 2,              /* + (.got.plt entry) - . */
  0x4e, 0xd1,              /* jmp %a1@ */
  0x2f, 0x3c,              /* move.l #offset,-(%sp) */
  0, 0, 0, 0,              /* + reloc index */
  0x60, 0xff,              /* bra.l .plt */
  0, 0, 0, 0,              /* + .plt - . */
  0, 0
};

static const struct elf_m68k_plt_info elf_cpu32_plt_info = {
  CPU32_PLT_ENTRY_SIZE,
  elf_cpu32_plt0_entry, { 4, 12 },
  elf_cpu32_plt_entry, { 4, 18 }, 10
};

/* The m68k linker 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_m68k_pcrel_relocs_copied
{
  /* Next section.  */
  struct elf_m68k_pcrel_relocs_copied *next;
  /* A section in dynobj.  */
  asection *section;
  /* Number of relocs copied in this section.  */
  bfd_size_type count;
};

/* Forward declaration.  */
struct elf_m68k_got_entry;

/* m68k ELF linker hash entry.  */

struct elf_m68k_link_hash_entry
{
  struct elf_link_hash_entry root;

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

  /* Key to got_entries.  */
  unsigned long got_entry_key;

  /* List of GOT entries for this symbol.  This list is build during
     offset finalization and is used within elf_m68k_finish_dynamic_symbol
     to traverse all GOT entries for a particular symbol.

     ??? We could've used root.got.glist field instead, but having
     a separate field is cleaner.  */
  struct elf_m68k_got_entry *glist;
};

#define elf_m68k_hash_entry(ent) ((struct elf_m68k_link_hash_entry *) (ent))

/* Key part of GOT entry in hashtable.  */
struct elf_m68k_got_entry_key
{
  /* BFD in which this symbol was defined.  NULL for global symbols.  */
  const bfd *bfd;

  /* Symbol index.  Either local symbol index or h->got_entry_key.  */
  unsigned long symndx;
};

/* Entry of the GOT.  */
struct elf_m68k_got_entry
{
  /* GOT entries are put into a got->entries hashtable.  This is the key.  */
  struct elf_m68k_got_entry_key key_;

  /* GOT entry data.  We need s1 before offset finalization and s2 after.  */
  union
  {
    struct
    {
      /* Number of times this entry is referenced.  It is used to
	 filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook.  */
      bfd_vma refcount;

      /* Type is one of R_68K_GOT8O, R_68K_GOT16O or R_68K_GOT32O.  */
      int type;
    } s1;

    struct
    {
      /* Offset from the start of .got section.  To calculate offset relative
	 to GOT pointer one should substract got->offset from this value.  */
      bfd_vma offset;

      /* Pointer to the next GOT entry for this global symbol.
	 Symbols have at most one entry in one GOT, but might
	 have entries in more than one GOT.
	 Root of this list is h->glist.
	 NULL for local symbols.  */
      struct elf_m68k_got_entry *next;
    } s2;
  } u;
};

/* Data structure representing a single GOT.  */
struct elf_m68k_got
{
  /* Hashtable of 'struct elf_m68k_got_entry's.
     Starting size of this table is the maximum number of
     R_68K_GOT8O entries.  */
  htab_t entries;

  /* Number of R_68K_GOT8O entries in this GOT.
     This is used to detect the overflow of number of such entries.  */
  bfd_vma rel_8o_n_entries;

  /* Cumulative count of R_68K_GOT8O and R_68K_GOT16O entries in this GOT.
     This is used to detect the overflow of number of such entries.  */
  bfd_vma rel_8o_16o_n_entries;

  /* Number of local (entry->key_.h == NULL) entries in this GOT.
     This is only used to properly calculate size of .rela.got section;
     see elf_m68k_partition_multi_got.  */
  bfd_vma local_n_entries;

  /* Offset of this GOT relative to beginning of .got section.  */
  bfd_vma offset;
};

/* BFD and its GOT.  This is an entry in multi_got->bfd2got hashtable.  */
struct elf_m68k_bfd2got_entry
{
  /* BFD.  */
  const bfd *bfd;

  /* Assigned GOT.  Before partitioning multi-GOT each BFD has its own
     GOT structure.  After partitioning several BFD's might [and often do]
     share a single GOT.  */
  struct elf_m68k_got *got;
};

/* The main data structure holding all the pieces.  */
struct elf_m68k_multi_got
{
  /* Hashtable mapping each BFD to its GOT.  If a BFD doesn't have an entry
     here, then it doesn't need a GOT (this includes the case of a BFD
     having an empty GOT).

     ??? This hashtable can be replaced by an array indexed by bfd->id.  */
  htab_t bfd2got;

  /* Next symndx to assign a global symbol.
     h->got_entry_key is initialized from this counter.  */
  unsigned long global_symndx;
};

/* m68k ELF linker hash table.  */

struct elf_m68k_link_hash_table
{
  struct elf_link_hash_table root;

  /* Small local sym to section mapping cache.  */
  struct sym_sec_cache sym_sec;

  /* The PLT format used by this link, or NULL if the format has not
     yet been chosen.  */
  const struct elf_m68k_plt_info *plt_info;

  /* True, if GP is loaded within each function which uses it.
     Set to TRUE when GOT negative offsets or multi-GOT is enabled.  */
  bfd_boolean local_gp_p;

  /* Switch controlling use of negative offsets to double the size of GOTs.  */
  bfd_boolean use_neg_got_offsets_p;

  /* Switch controlling generation of multiple GOTs.  */
  bfd_boolean allow_multigot_p;

  /* Multi-GOT data structure.  */
  struct elf_m68k_multi_got multi_got_;
};

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

#define elf_m68k_hash_table(p) \
  ((struct elf_m68k_link_hash_table *) (p)->hash)

/* Shortcut to multi-GOT data.  */
#define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)

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

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

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

  /* Call the allocation method of the superclass.  */
  ret = _bfd_elf_link_hash_newfunc (ret, table, string);
  if (ret != NULL)
    {
      elf_m68k_hash_entry (ret)->pcrel_relocs_copied = NULL;
      elf_m68k_hash_entry (ret)->got_entry_key = 0;
      elf_m68k_hash_entry (ret)->glist = NULL;
    }

  return ret;
}

/* Create an m68k ELF linker hash table.  */

static struct bfd_link_hash_table *
elf_m68k_link_hash_table_create (abfd)
     bfd *abfd;
{
  struct elf_m68k_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);

  ret = (struct elf_m68k_link_hash_table *) bfd_malloc (amt);
  if (ret == (struct elf_m68k_link_hash_table *) NULL)
    return NULL;

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

  ret->sym_sec.abfd = NULL;
  ret->plt_info = NULL;
  ret->local_gp_p = FALSE;
  ret->use_neg_got_offsets_p = FALSE;
  ret->allow_multigot_p = FALSE;
  ret->multi_got_.bfd2got = NULL;
  ret->multi_got_.global_symndx = 1;

  return &ret->root.root;
}

/* Destruct local data.  */

static void
elf_m68k_link_hash_table_free (struct bfd_link_hash_table *_htab)
{
  struct elf_m68k_link_hash_table *htab;

  htab = (struct elf_m68k_link_hash_table *) _htab;

  if (htab->multi_got_.bfd2got != NULL)
    {
      htab_delete (htab->multi_got_.bfd2got);
      htab->multi_got_.bfd2got = NULL;
    }
}

/* Set the right machine number.  */

static bfd_boolean
elf32_m68k_object_p (bfd *abfd)
{
  unsigned int mach = 0;
  unsigned features = 0;
  flagword eflags = elf_elfheader (abfd)->e_flags;

  if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
    features |= m68000;
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
    features |= cpu32;
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
    features |= fido_a;
  else
    {
      switch (eflags & EF_M68K_CF_ISA_MASK)
	{
	case EF_M68K_CF_ISA_A_NODIV:
	  features |= mcfisa_a;
	  break;
	case EF_M68K_CF_ISA_A:
	  features |= mcfisa_a|mcfhwdiv;
	  break;
	case EF_M68K_CF_ISA_A_PLUS:
	  features |= mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp;
	  break;
	case EF_M68K_CF_ISA_B_NOUSP:
	  features |= mcfisa_a|mcfisa_b|mcfhwdiv;
	  break;
	case EF_M68K_CF_ISA_B:
	  features |= mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp;
	  break;
	case EF_M68K_CF_ISA_C:
	  features |= mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp;
	  break;
	case EF_M68K_CF_ISA_C_NODIV:
	  features |= mcfisa_a|mcfisa_c|mcfusp;
	  break;
	}
      switch (eflags & EF_M68K_CF_MAC_MASK)
	{
	case EF_M68K_CF_MAC:
	  features |= mcfmac;
	  break;
	case EF_M68K_CF_EMAC:
	  features |= mcfemac;
	  break;
	}
      if (eflags & EF_M68K_CF_FLOAT)
	features |= cfloat;
    }

  mach = bfd_m68k_features_to_mach (features);
  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, mach);

  return TRUE;
}

/* Keep m68k-specific flags in the ELF header.  */
static bfd_boolean
elf32_m68k_set_private_flags (abfd, flags)
     bfd *abfd;
     flagword flags;
{
  elf_elfheader (abfd)->e_flags = flags;
  elf_flags_init (abfd) = TRUE;
  return TRUE;
}

/* Merge backend specific data from an object file to the output
   object file when linking.  */
static bfd_boolean
elf32_m68k_merge_private_bfd_data (ibfd, obfd)
     bfd *ibfd;
     bfd *obfd;
{
  flagword out_flags;
  flagword in_flags;
  flagword out_isa;
  flagword in_isa;
  const bfd_arch_info_type *arch_info;

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

  /* Get the merged machine.  This checks for incompatibility between
     Coldfire & non-Coldfire flags, incompability between different
     Coldfire ISAs, and incompability between different MAC types.  */
  arch_info = bfd_arch_get_compatible (ibfd, obfd, FALSE);
  if (!arch_info)
    return FALSE;

  bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);

  in_flags = elf_elfheader (ibfd)->e_flags;
  if (!elf_flags_init (obfd))
    {
      elf_flags_init (obfd) = TRUE;
      out_flags = in_flags;
    }
  else
    {
      out_flags = elf_elfheader (obfd)->e_flags;
      unsigned int variant_mask;

      if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
	variant_mask = 0;
      else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
	variant_mask = 0;
      else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
	variant_mask = 0;
      else
	variant_mask = EF_M68K_CF_ISA_MASK;

      in_isa = (in_flags & variant_mask);
      out_isa = (out_flags & variant_mask);
      if (in_isa > out_isa)
	out_flags ^= in_isa ^ out_isa;
      if (((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32
	   && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
	  || ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO
	      && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32))
	out_flags = EF_M68K_FIDO;
      else
      out_flags |= in_flags ^ in_isa;
    }
  elf_elfheader (obfd)->e_flags = out_flags;

  return TRUE;
}

/* Display the flags field.  */

static bfd_boolean
elf32_m68k_print_private_bfd_data (bfd *abfd, void * ptr)
{
  FILE *file = (FILE *) ptr;
  flagword eflags = elf_elfheader (abfd)->e_flags;

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

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

  /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */

  /* xgettext:c-format */
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);

  if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
    fprintf (file, " [m68000]");
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
    fprintf (file, " [cpu32]");
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
    fprintf (file, " [fido]");
  else
    {
      if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CFV4E)
	fprintf (file, " [cfv4e]");

      if (eflags & EF_M68K_CF_ISA_MASK)
	{
	  char const *isa = _("unknown");
	  char const *mac = _("unknown");
	  char const *additional = "";

	  switch (eflags & EF_M68K_CF_ISA_MASK)
	    {
	    case EF_M68K_CF_ISA_A_NODIV:
	      isa = "A";
	      additional = " [nodiv]";
	      break;
	    case EF_M68K_CF_ISA_A:
	      isa = "A";
	      break;
	    case EF_M68K_CF_ISA_A_PLUS:
	      isa = "A+";
	      break;
	    case EF_M68K_CF_ISA_B_NOUSP:
	      isa = "B";
	      additional = " [nousp]";
	      break;
	    case EF_M68K_CF_ISA_B:
	      isa = "B";
	      break;
	    case EF_M68K_CF_ISA_C:
	      isa = "C";
	      break;
	    case EF_M68K_CF_ISA_C_NODIV:
	      isa = "C";
	      additional = " [nodiv]";
	      break;
	    }
	  fprintf (file, " [isa %s]%s", isa, additional);

	  if (eflags & EF_M68K_CF_FLOAT)
	    fprintf (file, " [float]");

	  switch (eflags & EF_M68K_CF_MAC_MASK)
	    {
	    case 0:
	      mac = NULL;
	      break;
	    case EF_M68K_CF_MAC:
	      mac = "mac";
	      break;
	    case EF_M68K_CF_EMAC:
	      mac = "emac";
	      break;
	    }
	  if (mac)
	    fprintf (file, " [%s]", mac);
	}
    }

  fputc ('\n', file);

  return TRUE;
}

/* Multi-GOT support implementation design:

   Multi-GOT starts in check_relocs hook.  There we scan all
   relocations of a BFD and build a local GOT (struct elf_m68k_got)
   for it.  If a single BFD appears to require too many GOT slots with
   R_68K_GOT8O or R_68K_GOT16O relocations, we fail with notification
   to user.
   After check_relocs has been invoked for each input BFD, we have
   constructed a GOT for each input BFD.

   To minimize total number of GOTs required for a particular output BFD
   (as some environments support only 1 GOT per output object) we try
   to merge some of the GOTs to share an offset space.  Ideally [and in most
   cases] we end up with a single GOT.  In cases when there are too many
   restricted relocations (e.g., R_68K_GOT16O relocations) we end up with
   several GOTs, assuming the environment can handle them.

   Partitioning is done in elf_m68k_partition_multi_got.  We start with
   an empty GOT and traverse bfd2got hashtable putting got_entries from
   local GOTs to the new 'big' one.  We do that by constructing an
   intermediate GOT holding all the entries the local GOT has and the big
   GOT lacks.  Then we check if there is room in the big GOT to accomodate
   all the entries from diff.  On success we add those entries to the big
   GOT; on failure we start the new 'big' GOT and retry the adding of
   entries from the local GOT.  Note that this retry will always succeed as
   each local GOT doesn't overflow the limits.  After partitioning we
   end up with each bfd assigned one of the big GOTs.  GOT entries in the
   big GOTs are initialized with GOT offsets.  Note that big GOTs are
   positioned consequently in program space and represent a single huge GOT
   to the outside world.

   After that we get to elf_m68k_relocate_section.  There we
   adjust relocations of GOT pointer (_GLOBAL_OFFSET_TABLE_) and symbol
   relocations to refer to appropriate [assigned to current input_bfd]
   big GOT.

   Notes:

   GOT entry type: We have 3 types of GOT entries.
   * R_68K_GOT8O type is used in entries for symbols that have
   at least one R_68K_GOT8O relocation.  We can have at most 0x40
   such entries in one GOT.
   * R_68K_GOT16O type is used in entries for symbols that have
   at least one R_68K_GOT16O relocation and no R_68K_GOT8O relocations.
   We can have at most 0x4000 such entries in one GOT.
   * R_68K_GOT32O type is used in all other cases.  We can have as many
   such entries in one GOT as we like.
   When counting relocations we have to include the count of the smaller
   ranged relocations in the counts of the larger ranged ones in order
   to correctly detect overflow.

   Sorting the GOT: In each GOT starting offsets are assigned to
   R_68K_GOT8O entries, which are followed by R_68K_GOT16O entries, and
   R_68K_GOT32O entries go at the end.  See finalize_got_offsets for details.

   Negative GOT offsets: To double usable offset range of GOTs we use
   negative offsets.  As we assign entries with GOT offsets relative to
   start of .got section, the offset values are positive.  They become
   negative only in relocate_section where got->offset value is
   subtracted from them.

   3 special GOT entries: There are 3 special GOT entries used internally
   by loader.  These entries happen to be placed to .got.plt section,
   so we don't do anything about them in multi-GOT support.

   Memory management: All data except for hashtables
   multi_got->bfd2got and got->entries are allocated on
   elf_hash_table (info)->dynobj bfd (for this reason we pass 'info'
   to most functions), so we don't need to care to free them.  At the
   moment of allocation hashtables are being linked into main data
   structure (multi_got), all pieces of which are reachable from
   elf_m68k_multi_got (info).  We deallocate them in
   elf_m68k_link_hash_table_free.  */

/* Initialize GOT.  */

static void
elf_m68k_init_got (struct elf_m68k_got *got,
		   htab_t entries,
		   bfd_vma rel_8o_n_entries,
		   bfd_vma rel_8o_16o_n_entries,
		   bfd_vma local_n_entries,
		   bfd_vma offset)
{
  got->entries = entries;
  got->rel_8o_n_entries = rel_8o_n_entries;
  got->rel_8o_16o_n_entries = rel_8o_16o_n_entries;
  got->local_n_entries = local_n_entries;
  got->offset = offset;
}

/* Destruct GOT.  */

static void
elf_m68k_clear_got (struct elf_m68k_got *got)
{
  if (got->entries != NULL)
    {
      htab_delete (got->entries);
      got->entries = NULL;
    }
}

/* Create and empty GOT structure.  INFO is the context where memory
   should be allocated.  */

static struct elf_m68k_got *
elf_m68k_create_empty_got (struct bfd_link_info *info)
{
  struct elf_m68k_got *got;

  got = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*got));
  if (got == NULL)
    return NULL;

  elf_m68k_init_got (got, NULL, 0, 0, 0, (bfd_vma) -1);

  return got;
}

/* Initialize KEY.  */

static void
elf_m68k_init_got_entry_key (struct elf_m68k_got_entry_key *key,
			     struct elf_link_hash_entry *h,
			     const bfd *abfd, unsigned long symndx)
{
  if (h != NULL)
    {
      key->bfd = NULL;
      key->symndx = elf_m68k_hash_entry (h)->got_entry_key;
      BFD_ASSERT (key->symndx != 0);
    }
  else
    {
      key->bfd = abfd;
      key->symndx = symndx;
    }
}

/* Calculate hash of got_entry.
   ??? Is it good?  */

static hashval_t
elf_m68k_got_entry_hash (const void *_entry)
{
  const struct elf_m68k_got_entry_key *key;

  key = &((const struct elf_m68k_got_entry *) _entry)->key_;

  return key->symndx + (key->bfd != NULL
			? (int) key->bfd->id
			: -1);
}

/* Check if two got entries are equal.  */

static int
elf_m68k_got_entry_eq (const void *_entry1, const void *_entry2)
{
  const struct elf_m68k_got_entry_key *key1;
  const struct elf_m68k_got_entry_key *key2;

  key1 = &((const struct elf_m68k_got_entry *) _entry1)->key_;
  key2 = &((const struct elf_m68k_got_entry *) _entry2)->key_;

  return (key1->bfd == key2->bfd
	  && key1->symndx == key2->symndx);
}

/* Maximal number of R_68K_GOT8O entries in a single GOT.  */
#define ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT(INFO)		\
  (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p		\
   ? 0x40							\
   : 0x20)

/* Maximal number of R_68K_GOT8O and R_68K_GOT16O entries in a single GOT.  */
#define ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT(INFO)		\
  (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p		\
   ? 0x4000							\
   : 0x2000)

/* SEARCH - simply search the hashtable, don't insert new entries or fail when
   the entry cannot be found.
   FIND_OR_CREATE - search for an existing entry, but create new if there's
   no such.
   MUST_FIND - search for an existing entry and assert that it exist.
   MUST_CREATE - assert that there's no such entry and create new one.  */
enum elf_m68k_get_entry_howto
  {
    SEARCH,
    FIND_OR_CREATE,
    MUST_FIND,
    MUST_CREATE
  };

/* Get or create (depending on HOWTO) entry with KEY in GOT.
   INFO is context in which memory should be allocated (can be NULL if
   HOWTO is SEARCH or MUST_FIND).  */

static struct elf_m68k_got_entry *
elf_m68k_get_got_entry (struct elf_m68k_got *got,
			const struct elf_m68k_got_entry_key *key,
			enum elf_m68k_get_entry_howto howto,
			struct bfd_link_info *info)
{
  struct elf_m68k_got_entry entry_;
  struct elf_m68k_got_entry *entry;
  void **ptr;

  BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));

  if (got->entries == NULL)
    /* This is the first entry in ABFD.  Initialize hashtable.  */
    {
      if (howto == SEARCH)
	return NULL;

      got->entries = htab_try_create (ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT
				      (info),
				      elf_m68k_got_entry_hash,
				      elf_m68k_got_entry_eq, NULL);
      if (got->entries == NULL)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return NULL;
	}
    }

  entry_.key_ = *key;
  ptr = htab_find_slot (got->entries, &entry_, (howto != SEARCH
						? INSERT : NO_INSERT));
  if (ptr == NULL)
    {
      if (howto == SEARCH)
	/* Entry not found.  */
	return NULL;

      /* We're out of memory.  */
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  if (*ptr == NULL)
    /* We didn't find the entry and we're asked to create a new one.  */
    {
      BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);

      entry = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry));
      if (entry == NULL)
	return NULL;

      /* Initialize new entry.  */
      entry->key_ = *key;

      entry->u.s1.refcount = 0;
      entry->u.s1.type = R_68K_GOT32O;

      *ptr = entry;
    }
  else
    /* We found the entry.  */
    {
      BFD_ASSERT (howto != MUST_CREATE);

      entry = *ptr;
    }

  return entry;
}

/* Update GOT counters when merging entry of WAS type with entry of NEW type.
   Return the value to which ENTRY's type should be set.  */

static int
elf_m68k_update_got_entry_type (struct elf_m68k_got *got, int was, int new)
{
  if (new == R_68K_GOT8O && was != R_68K_GOT8O)
    /* NEW overrides WAS.  */
    {
      ++got->rel_8o_n_entries;

      if (was != R_68K_GOT16O)
	/* Update this counter too.  */
	++got->rel_8o_16o_n_entries;
    }
  else if (new == R_68K_GOT16O && was != R_68K_GOT8O && was != R_68K_GOT16O)
    /* NEW overrides WAS.  */
    ++got->rel_8o_16o_n_entries;
  else
    /* NEW doesn't override WAS.  */
    new = was;

  return new;
}

/* Update GOT counters when removing an entry of type TYPE.  */

static void
elf_m68k_remove_got_entry_type (struct elf_m68k_got *got, int type)
{
  switch (type)
    {
    case R_68K_GOT8O:
      BFD_ASSERT (got->rel_8o_n_entries > 0);

      --got->rel_8o_n_entries;
      /* FALLTHRU */

    case R_68K_GOT16O:
      BFD_ASSERT (got->rel_8o_16o_n_entries >= got->rel_8o_n_entries);

      --got->rel_8o_16o_n_entries;
      /* FALLTHRU */

    case R_68K_GOT32O:
      break;

    default:
      BFD_ASSERT (FALSE);
    }
}

/* Add new or update existing entry to GOT.
   H, ABFD, TYPE and SYMNDX is data for the entry.
   INFO is a context where memory should be allocated.  */

static struct elf_m68k_got_entry *
elf_m68k_add_entry_to_got (struct elf_m68k_got *got,
			   struct elf_link_hash_entry *h,
			   const bfd *abfd,
			   int type, unsigned long symndx,
			   struct bfd_link_info *info)
{
  struct elf_m68k_got_entry_key key_;
  struct elf_m68k_got_entry *entry;

  if (h != NULL && elf_m68k_hash_entry (h)->got_entry_key == 0)
    elf_m68k_hash_entry (h)->got_entry_key
      = elf_m68k_multi_got (info)->global_symndx++;

  elf_m68k_init_got_entry_key (&key_, h, abfd, symndx);

  entry = elf_m68k_get_got_entry (got, &key_, FIND_OR_CREATE, info);
  if (entry == NULL)
    return NULL;

  /* Update refcount.  */
  ++entry->u.s1.refcount;

  if (entry->u.s1.refcount == 1)
    /* We see this entry for the first time.  */
    {
      if (entry->key_.bfd != NULL)
	++got->local_n_entries;
    }

  /* Determine entry's type and update got->rel_*_n_entries counters.  */
  entry->u.s1.type = elf_m68k_update_got_entry_type (got, entry->u.s1.type,
						     type);

  if ((got->rel_8o_n_entries
       > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))
      || (got->rel_8o_16o_n_entries
	  > ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info)))
    /* This BFD has too many relocation.  */
    {
      if (got->rel_8o_n_entries
	  > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))
	(*_bfd_error_handler) (_("%B: GOT overflow: "
				 "Number of R_68K_GOT8O relocations > %d"),
			       abfd,
			       ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info));
      else
	(*_bfd_error_handler) (_("%B: GOT overflow: "
				 "Number of R_68K_GOT8O and R_68K_GOT16O "
				 "relocations > %d"),
			       abfd,
			       ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info));

      return NULL;
    }

  return entry;
}

/* Compute the hash value of the bfd in a bfd2got hash entry.  */

static hashval_t
elf_m68k_bfd2got_entry_hash (const void *entry)
{
  const struct elf_m68k_bfd2got_entry *e;

  e = (const struct elf_m68k_bfd2got_entry *) entry;

  return e->bfd->id;
}

/* Check whether two hash entries have the same bfd.  */

static int
elf_m68k_bfd2got_entry_eq (const void *entry1, const void *entry2)
{
  const struct elf_m68k_bfd2got_entry *e1;
  const struct elf_m68k_bfd2got_entry *e2;

  e1 = (const struct elf_m68k_bfd2got_entry *) entry1;
  e2 = (const struct elf_m68k_bfd2got_entry *) entry2;

  return e1->bfd == e2->bfd;
}

/* Destruct a bfd2got entry.  */

static void
elf_m68k_bfd2got_entry_del (void *_entry)
{
  struct elf_m68k_bfd2got_entry *entry;

  entry = (struct elf_m68k_bfd2got_entry *) _entry;

  BFD_ASSERT (entry->got != NULL);
  elf_m68k_clear_got (entry->got);
}

/* Find existing or create new (depending on HOWTO) bfd2got entry in
   MULTI_GOT.  ABFD is the bfd we need a GOT for.  INFO is a context where
   memory should be allocated.  */

static struct elf_m68k_bfd2got_entry *
elf_m68k_get_bfd2got_entry (struct elf_m68k_multi_got *multi_got,
			    const bfd *abfd,
			    enum elf_m68k_get_entry_howto howto,
			    struct bfd_link_info *info)
{
  struct elf_m68k_bfd2got_entry entry_;
  void **ptr;
  struct elf_m68k_bfd2got_entry *entry;

  BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));

  if (multi_got->bfd2got == NULL)
    /* This is the first GOT.  Initialize bfd2got.  */
    {
      if (howto == SEARCH)
	return NULL;

      multi_got->bfd2got = htab_try_create (1, elf_m68k_bfd2got_entry_hash,
					    elf_m68k_bfd2got_entry_eq,
					    elf_m68k_bfd2got_entry_del);
      if (multi_got->bfd2got == NULL)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return NULL;
	}
    }

  entry_.bfd = abfd;
  ptr = htab_find_slot (multi_got->bfd2got, &entry_, (howto != SEARCH
						      ? INSERT : NO_INSERT));
  if (ptr == NULL)
    {
      if (howto == SEARCH)
	/* Entry not found.  */
	return NULL;

      /* We're out of memory.  */
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  if (*ptr == NULL)
    /* Entry was not found.  Create new one.  */
    {
      BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);

      entry = ((struct elf_m68k_bfd2got_entry *)
	       bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry)));
      if (entry == NULL)
	return NULL;

      entry->bfd = abfd;

      entry->got = elf_m68k_create_empty_got (info);
      if (entry->got == NULL)
	return NULL;

      *ptr = entry;
    }
  else
    {
      BFD_ASSERT (howto != MUST_CREATE);

      /* Return existing entry.  */
      entry = *ptr;
    }

  return entry;
}

struct elf_m68k_can_merge_gots_arg
{
  /* A current_got that we constructing a DIFF against.  */
  struct elf_m68k_got *big;

  /* GOT holding entries not present or that should be changed in
     BIG.  */
  struct elf_m68k_got *diff;

  /* Context where to allocate memory.  */
  struct bfd_link_info *info;

  /* Error flag.  */
  bfd_boolean error_p;
};

/* Process a single entry from the small GOT to see if it should be added
   or updated in the big GOT.  */

static int
elf_m68k_can_merge_gots_1 (void **_entry_ptr, void *_arg)
{
  const struct elf_m68k_got_entry *entry1;
  struct elf_m68k_can_merge_gots_arg *arg;
  const struct elf_m68k_got_entry *entry2;
  int type;

  entry1 = (const struct elf_m68k_got_entry *) *_entry_ptr;
  arg = (struct elf_m68k_can_merge_gots_arg *) _arg;

  entry2 = elf_m68k_get_got_entry (arg->big, &entry1->key_, SEARCH, NULL);

  if (entry2 != NULL)
    {
      type = elf_m68k_update_got_entry_type (arg->diff, entry2->u.s1.type,
					     entry1->u.s1.type);

      if (type == entry2->u.s1.type)
	/* ENTRY1 doesn't update data in ENTRY2.  Skip it.
	   To skip creation of difference entry we use the type,
	   which we won't see in GOT entries for sure.  */
	type = R_68K_32;
    }
  else
    {
      BFD_ASSERT (entry1->u.s1.type != R_68K_32);

      type = elf_m68k_update_got_entry_type (arg->diff, R_68K_GOT32O,
					     entry1->u.s1.type);

      /* Update local counter.  */
      if (entry1->key_.bfd != NULL)
	++arg->diff->local_n_entries;
    }

  if (type != R_68K_32)
    /* Create an entry in DIFF.  */
    {
      struct elf_m68k_got_entry *entry;

      entry = elf_m68k_get_got_entry (arg->diff, &entry1->key_, MUST_CREATE,
				      arg->info);
      if (entry == NULL)
	{
	  arg->error_p = TRUE;
	  return 0;
	}

      entry->u.s1.type = type;
    }

  return 1;
}

/* Return TRUE if SMALL GOT can be added to BIG GOT without overflowing it.
   Construct DIFF GOT holding the entries which should be added or updated
   in BIG GOT to accumulate information from SMALL.
   INFO is the context where memory should be allocated.  */

static bfd_boolean
elf_m68k_can_merge_gots (struct elf_m68k_got *big,
			 const struct elf_m68k_got *small,
			 struct bfd_link_info *info,
			 struct elf_m68k_got *diff)
{
  struct elf_m68k_can_merge_gots_arg arg_;

  BFD_ASSERT (small->offset == (bfd_vma) -1);

  arg_.big = big;
  arg_.diff = diff;
  arg_.info = info;
  arg_.error_p = FALSE;
  htab_traverse_noresize (small->entries, elf_m68k_can_merge_gots_1, &arg_);
  if (arg_.error_p)
    {
      diff->offset = 0;
      return FALSE;
    }

  /* Check for overflow.  */
  if ((big->rel_8o_n_entries + arg_.diff->rel_8o_n_entries
       > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))
      || (big->rel_8o_16o_n_entries + arg_.diff->rel_8o_16o_n_entries
	  > ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info)))
    return FALSE;

  return TRUE;
}

struct elf_m68k_merge_gots_arg
{
  /* The BIG got.  */
  struct elf_m68k_got *big;

  /* Context where memory should be allocated.  */
  struct bfd_link_info *info;

  /* Error flag.  */
  bfd_boolean error_p;
};

/* Process a single entry from DIFF got.  Add or update corresponding
   entry in the BIG got.  */

static int
elf_m68k_merge_gots_1 (void **entry_ptr, void *_arg)
{
  const struct elf_m68k_got_entry *from;
  struct elf_m68k_merge_gots_arg *arg;
  struct elf_m68k_got_entry *to;

  from = (const struct elf_m68k_got_entry *) *entry_ptr;
  arg = (struct elf_m68k_merge_gots_arg *) _arg;

  to = elf_m68k_get_got_entry (arg->big, &from->key_, FIND_OR_CREATE,
			       arg->info);
  if (to == NULL)
    {
      arg->error_p = TRUE;
      return 0;
    }

  BFD_ASSERT (to->u.s1.refcount == 0);
  /* All we need to merge is TYPE.  */
  to->u.s1.type = from->u.s1.type;

  return 1;
}

/* Merge data from DIFF to BIG.  INFO is context where memory should be
   allocated.  */

static bfd_boolean
elf_m68k_merge_gots (struct elf_m68k_got *big,
		     struct elf_m68k_got *diff,
		     struct bfd_link_info *info)
{
  if (diff->entries != NULL)
    /* DIFF is not empty.  Merge it into BIG GOT.  */
    {
      struct elf_m68k_merge_gots_arg arg_;

      /* Merge entries.  */
      arg_.big = big;
      arg_.info = info;
      arg_.error_p = FALSE;
      htab_traverse_noresize (diff->entries, elf_m68k_merge_gots_1, &arg_);
      if (arg_.error_p)
	return FALSE;

      /* Merge counters.  */
      big->rel_8o_n_entries += diff->rel_8o_n_entries;
      big->rel_8o_16o_n_entries += diff->rel_8o_16o_n_entries;
      big->local_n_entries += diff->local_n_entries;
    }
  else
    /* DIFF is empty.  */
    {
      BFD_ASSERT (diff->rel_8o_n_entries == 0);
      BFD_ASSERT (diff->rel_8o_16o_n_entries == 0);
      BFD_ASSERT (diff->local_n_entries == 0);
    }

  BFD_ASSERT (!elf_m68k_hash_table (info)->allow_multigot_p
	      || ((big->rel_8o_n_entries
		   <= ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))
		  && (big->rel_8o_16o_n_entries
		      <= ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info))));

  return TRUE;
}

struct elf_m68k_finalize_got_offsets_arg
{
  /* Offset for the next R_68K_GOT8O entry.  */
  bfd_vma rel_8o_offset;

  /* Offset for the next R_68K_GOT16O entry.  */
  bfd_vma rel_16o_offset;

  /* Offset for the next R_68K_GOT32O entry.  */
  bfd_vma rel_32o_offset;

  /* Should we use negative (relative to GP) offsets for GOT entries.  */
  bfd_boolean use_neg_got_offsets_p;

  /* Offset of this GOT relative to .got section.  */
  bfd_vma got_offset;

  /* Mapping from global symndx to global symbols.
     This is used to build lists of got entries for global symbols.  */
  struct elf_m68k_link_hash_entry **symndx2h;
};

/* Assign ENTRY an offset.  Build list of GOT entries for global symbols
   along the way.  */

static int
elf_m68k_finalize_got_offsets_1 (void **entry_ptr, void *_arg)
{
  struct elf_m68k_got_entry *entry;
  struct elf_m68k_finalize_got_offsets_arg *arg;

  entry = (struct elf_m68k_got_entry *) *entry_ptr;
  arg = (struct elf_m68k_finalize_got_offsets_arg *) _arg;

  /* This should be a fresh entry created in elf_m68k_can_merge_gots.  */
  BFD_ASSERT (entry->u.s1.refcount == 0);

  switch (entry->u.s1.type)
    {
    case R_68K_GOT8O:
      entry->u.s2.offset = arg->rel_8o_offset;

      if (arg->use_neg_got_offsets_p)
	{
	  if (arg->rel_8o_offset >= arg->got_offset)
	    /* We've assigned a positive offset to this entry,
	       next entry should get (-abs(offset) - 4).  */
	    arg->rel_8o_offset = (arg->got_offset
				  - (arg->rel_8o_offset - arg->got_offset)
				  - 4);
	  else
	    /* We've assigned a negative offset to this entry,
	       next entry should get (+abs(offset) + 0).  */
	    arg->rel_8o_offset = (arg->got_offset
				  + (arg->got_offset - arg->rel_8o_offset));
	}
      else
	/* Next entry will simply get next offset.  */
	arg->rel_8o_offset += 4;

      break;

    case R_68K_GOT16O:
      entry->u.s2.offset = arg->rel_16o_offset;

      if (arg->use_neg_got_offsets_p)
	{
	  if (arg->rel_16o_offset >= arg->got_offset)
	    /* We've assigned a positive offset to this entry,
	       next entry should get (-abs(offset) - 4).  */
	    arg->rel_16o_offset = (arg->got_offset
				   - (arg->rel_16o_offset - arg->got_offset)
				   - 4);
	  else
	    /* We've assigned a negative offset to this entry,
	       next entry should get (+abs(offset) + 0).  */
	    arg->rel_16o_offset = (arg->got_offset
				   + (arg->got_offset - arg->rel_16o_offset));
	}
      else
	/* Next entry will simply get next offset.  */
	arg->rel_16o_offset += 4;

      break;

    case R_68K_GOT32O:
      entry->u.s2.offset = arg->rel_32o_offset;

      if (arg->use_neg_got_offsets_p)
	{
	  if (arg->rel_32o_offset >= arg->got_offset)
	    /* We've assigned a positive offset to this entry,
	       next entry should get (-abs(offset) - 4).  */
	    arg->rel_32o_offset = (arg->got_offset
				   - (arg->rel_32o_offset - arg->got_offset)
				   - 4);
	  else
	    /* We've assigned a negative offset to this entry,
	       next entry should get (+abs(offset) + 0).  */
	    arg->rel_32o_offset = (arg->got_offset
				   + (arg->got_offset - arg->rel_32o_offset));
	}
      else
	/* Next entry will simply get next offset.  */
	arg->rel_32o_offset += 4;

      break;

    default:
      BFD_ASSERT (FALSE);
      break;
    }

  if (entry->key_.bfd == NULL)
    /* Hook up this entry into the list of got_entries of H.  */
    {
      struct elf_m68k_link_hash_entry *h;

      BFD_ASSERT (entry->key_.symndx != 0);
      h = arg->symndx2h[entry->key_.symndx];
      BFD_ASSERT (h != NULL);

      entry->u.s2.next = h->glist;
      h->glist = entry;
    }
  else
    /* This entry is for local symbol.  */
    entry->u.s2.next = NULL;

  return 1;
}

/* Assign offsets within GOT.  USE_NEG_GOT_OFFSETS_P indicates if we
   should use negative offsets.
   Build list of GOT entries for global symbols along the way.
   SYMNDX2H is mapping from global symbol indices to actual
   global symbols.  */

static void
elf_m68k_finalize_got_offsets (struct elf_m68k_got *got,
			       bfd_boolean use_neg_got_offsets_p,
			       struct elf_m68k_link_hash_entry **symndx2h)
{
  struct elf_m68k_finalize_got_offsets_arg arg_;

  BFD_ASSERT (got->offset != (bfd_vma) -1);

  /* We set entry offsets relative to the .got section (and not the
     start of a particular GOT), so that we can use them in
     finish_dynamic_symbol without needing to know the GOT they come
     from.  */

  if (use_neg_got_offsets_p)
    {
      size_t n;

      /* Put GOT pointer in the middle of GOT.  */
      n = htab_elements (got->entries);
      if ((n & 1) == 0)
	/* Even number of GOT entries.  */
	got->offset += 2 * n;
      else
	/* Odd number of GOT entries.  */
	got->offset += 2 * (n - 1);

      /* R_68K_GOT8O entries shall start at GOT offset.  */
      arg_.rel_8o_offset = got->offset;

      n = got->rel_8o_n_entries;
      if ((n & 1) == 0)
	/* Even number of R_68K_GOT8O entries.
	   The last R_68K_GOT8O entry will be at
	   (got->offset - 2 * n).  Hence the first R_68K_GOT16O
	   entry will be at offset ...  */
	arg_.rel_16o_offset = got->offset + 2 * n;
      else
	/* Odd number of R_68K_GOT8O entries.
	   The last R_68K_GOT8O entry will be at
	   (got->offset + 2 * (n - 1)).  Hence the first R_68K_GOT16O
	   entry will be at offset ...  */
	arg_.rel_16o_offset = got->offset - 2 * (n - 1) - 4;

      n = got->rel_8o_16o_n_entries;
      if ((n & 1) == 0)
	/* Even number of R_68K_GOT8O and R_68K_GOT16O entries.
	   The last R_68K_GOT8O entry will be at
	   (got->offset - 2 * n).  Hence the first R_68K_GOT32O
	   entry will be at offset ...  */
	arg_.rel_32o_offset = got->offset + 2 * n;
      else
	/* Odd number of R_68K_GOT8O and R_68K_GOT16O entries.
	   The last R_68K_GOT16O entry will be at
	   (got->offset + 2 * (n - 1)).  Hence the first R_68K_GOT32O
	   entry will be at offset ...  */
	arg_.rel_32o_offset = got->offset - 2 * (n - 1) - 4;

      arg_.use_neg_got_offsets_p = TRUE;

      arg_.got_offset = got->offset;
    }
  else
    {
      arg_.rel_8o_offset = got->offset;
      arg_.rel_16o_offset = 4 * got->rel_8o_n_entries + got->offset;
      arg_.rel_32o_offset = 4 * got->rel_8o_16o_n_entries + got->offset;

      arg_.use_neg_got_offsets_p = FALSE;

      /* This shouldn't be used.  */
      arg_.got_offset = (bfd_vma) -1;
    }

  arg_.symndx2h = symndx2h;

  htab_traverse (got->entries, elf_m68k_finalize_got_offsets_1, &arg_);

  /* Calculate offset ranges we have actually assigned.  */
  if (use_neg_got_offsets_p)
    {
      if (arg_.rel_8o_offset == (bfd_vma) -4
	  || arg_.rel_8o_offset < got->offset)
	arg_.rel_8o_offset = 2 * (got->offset - arg_.rel_8o_offset) - 4;
      else
	arg_.rel_8o_offset = 2 * (arg_.rel_8o_offset - got->offset);

      if (arg_.rel_16o_offset == (bfd_vma) -4
	  || arg_.rel_16o_offset < got->offset)
	arg_.rel_16o_offset = 2 * (got->offset - arg_.rel_16o_offset) - 4;
      else
	arg_.rel_16o_offset = 2 * (arg_.rel_16o_offset - got->offset);

      if (arg_.rel_32o_offset == (bfd_vma) -4
	  || arg_.rel_32o_offset < got->offset)
	arg_.rel_32o_offset = 2 * (got->offset - arg_.rel_32o_offset) - 4;
      else
	arg_.rel_32o_offset = 2 * (arg_.rel_32o_offset - got->offset);
    }
  else
    {
      arg_.rel_8o_offset -= got->offset;
      arg_.rel_16o_offset -= got->offset;
      arg_.rel_32o_offset -= got->offset;
    }

  /* These asserts check that we got counting of entries right.  */
  BFD_ASSERT (arg_.rel_8o_offset == 4 * got->rel_8o_n_entries);
  BFD_ASSERT (arg_.rel_16o_offset == 4 * got->rel_8o_16o_n_entries);
  BFD_ASSERT (arg_.rel_32o_offset == 4 * htab_elements (got->entries));
}

struct elf_m68k_partition_multi_got_arg
{
  /* The GOT we are adding entries to.  Aka big got.  */
  struct elf_m68k_got *current_got;

  /* Offset to assign the next CURRENT_GOT.  */
  bfd_vma offset;

  /* Context where memory should be allocated.  */
  struct bfd_link_info *info;

  /* Total number of entries in the .got section.
     This is used to calculate size of the .got and .rela.got sections.  */
  bfd_vma n_entries;

  /* Total number of local entries in the .got section.
     This is used to calculate size of the .rela.got section.  */
  bfd_vma local_n_entries;

  /* Error flag.  */
  bfd_boolean error_p;

  /* Mapping from global symndx to global symbols.
     This is used to build lists of got entries for global symbols.  */
  struct elf_m68k_link_hash_entry **symndx2h;
};

/* Process a single BFD2GOT entry and either merge GOT to CURRENT_GOT
   or start a new CURRENT_GOT.  */

static int
elf_m68k_partition_multi_got_1 (void **_entry, void *_arg)
{
  struct elf_m68k_bfd2got_entry *entry;
  struct elf_m68k_partition_multi_got_arg *arg;
  struct elf_m68k_got *got;
  struct elf_m68k_got *current_got;
  struct elf_m68k_got diff_;
  struct elf_m68k_got *diff;

  entry = (struct elf_m68k_bfd2got_entry *) *_entry;
  arg = (struct elf_m68k_partition_multi_got_arg *) _arg;

  got = entry->got;
  BFD_ASSERT (got != NULL);
  BFD_ASSERT (got->offset == (bfd_vma) -1);

  diff = NULL;

  if (arg->current_got != NULL)
    /* Construct diff.  */
    {
      diff = &diff_;
      elf_m68k_init_got (diff, NULL, 0, 0, 0, (bfd_vma) -1);

      if (!elf_m68k_can_merge_gots (arg->current_got, got, arg->info, diff))
	{
	  if (diff->offset == 0)
	    /* Offset set to 0 in the diff_ indicates an error.  */
	    {
	      arg->error_p = TRUE;
	      goto final_return;
	    }

	  if (elf_m68k_hash_table (arg->info)->allow_multigot_p)
	    {
	      elf_m68k_clear_got (diff);
	      /* Schedule to finish up CURRENT_GOT and start new one.  */
	      diff = NULL;
	    }
	  /* else
	     Merge GOTs no matter what.  If big GOT overflows,
	     we'll fail in relocate_section due to truncated relocations.

	     ??? May be fail earlier?  E.g., in can_merge_gots.  */
	}
    }
  else
    /* Diff of got against empty current_got is got itself.  */
    {
      /* Create empty CURRENT_GOT to subsequent GOTs to.  */
      arg->current_got = elf_m68k_create_empty_got (arg->info);
      if (arg->current_got == NULL)
	{
	  arg->error_p = TRUE;
	  goto final_return;
	}

      arg->current_got->offset = arg->offset;

      diff = got;
    }

  current_got = arg->current_got;

  if (diff != NULL)
    {
      if (!elf_m68k_merge_gots (current_got, diff, arg->info))
	{
	  arg->error_p = TRUE;
	  goto final_return;
	}

      /* Now we can free GOT.  */
      elf_m68k_clear_got (got);

      entry->got = current_got;
    }
  else
    {
      /* Schedule to start a new current_got.  */
      arg->current_got = NULL;
      arg->offset = (current_got->offset
		     + 4 * htab_elements (current_got->entries));

      /* Finish up current_got.  */
      {
	elf_m68k_finalize_got_offsets (current_got,
				       elf_m68k_hash_table (arg->info)
				       ->use_neg_got_offsets_p,
				       arg->symndx2h);

	arg->n_entries += htab_elements (current_got->entries);
	arg->local_n_entries += current_got->local_n_entries;

	BFD_ASSERT (arg->local_n_entries <= arg->n_entries);
      }

      /* Retry.  */
      if (!elf_m68k_partition_multi_got_1 (_entry, _arg))
	{
	  BFD_ASSERT (arg->error_p);
	  goto final_return;
	}
    }

 final_return:
  if (diff != NULL)
    elf_m68k_clear_got (diff);

  return arg->error_p == FALSE ? 1 : 0;
}

/* Helper function to build symndx2h mapping.  */

static bfd_boolean
elf_m68k_init_symndx2h_1 (struct elf_link_hash_entry *_h,
			  void *_arg)
{
  struct elf_m68k_link_hash_entry *h;

  h = elf_m68k_hash_entry (_h);

  if (h->got_entry_key != 0)
    /* H has at least one entry in the GOT.  */
    {
      struct elf_m68k_partition_multi_got_arg *arg;

      arg = (struct elf_m68k_partition_multi_got_arg *) _arg;

      BFD_ASSERT (arg->symndx2h[h->got_entry_key] == NULL);
      arg->symndx2h[h->got_entry_key] = h;
    }

  return TRUE;
}

/* Merge GOTs of some BFDs, assign offsets to GOT entries and build
   lists of GOT entries for global symbols.
   Calculate sizes of .got and .rela.got sections.  */

static bfd_boolean
elf_m68k_partition_multi_got (struct bfd_link_info *info)
{
  struct elf_m68k_multi_got *multi_got;
  struct elf_m68k_partition_multi_got_arg arg_;

  multi_got = elf_m68k_multi_got (info);

  arg_.current_got = NULL;
  arg_.offset = 0;
  arg_.info = info;
  arg_.n_entries = 0;
  arg_.local_n_entries = 0;
  arg_.error_p = FALSE;

  if (multi_got->bfd2got != NULL)
    {
      /* Initialize symndx2h mapping.  */
      {
	arg_.symndx2h = bfd_zmalloc (multi_got->global_symndx
				     * sizeof (*arg_.symndx2h));
	if (arg_.symndx2h == NULL)
	  return FALSE;

	elf_link_hash_traverse (elf_hash_table (info),
				elf_m68k_init_symndx2h_1, &arg_);
      }

      /* Partition.  */
      htab_traverse (multi_got->bfd2got, elf_m68k_partition_multi_got_1,
		     &arg_);
      if (arg_.error_p)
	{
	  free (arg_.symndx2h);
	  arg_.symndx2h = NULL;

	  return FALSE;
	}

      /* Finish up last current_got.  */
      {
	elf_m68k_finalize_got_offsets (arg_.current_got,
				       elf_m68k_hash_table (info)
				       ->use_neg_got_offsets_p, arg_.symndx2h);

	arg_.n_entries += htab_elements (arg_.current_got->entries);
	arg_.local_n_entries += arg_.current_got->local_n_entries;

	BFD_ASSERT (arg_.local_n_entries <= arg_.n_entries);
      }

      free (arg_.symndx2h);
    }

  if (elf_hash_table (info)->dynobj != NULL)
    /* Set sizes of .got and .rela.got sections.  */
    {
      asection *s;

      s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got");
      if (s != NULL)
	s->size = arg_.n_entries * 4;
      else
	BFD_ASSERT (arg_.n_entries == 0);

      /* If we are generating a shared object, we need to
	 output a R_68K_RELATIVE reloc so that the dynamic
	 linker can adjust this GOT entry.  Overwise we
	 don't need space in .rela.got for local symbols.  */
      if (!info->shared)
	{
	  BFD_ASSERT (arg_.local_n_entries <= arg_.n_entries);
	  arg_.n_entries -= arg_.local_n_entries;
	}

      s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".rela.got");
      if (s != NULL)
	s->size = arg_.n_entries * sizeof (Elf32_External_Rela);
      else
	BFD_ASSERT (arg_.n_entries == 0);
    }
  else
    BFD_ASSERT (multi_got->bfd2got == NULL);

  return TRUE;
}

/* Specialized version of elf_m68k_get_got_entry that returns pointer
   to hashtable slot, thus allowing removal of entry via
   elf_m68k_remove_got_entry.  */

static struct elf_m68k_got_entry **
elf_m68k_find_got_entry_ptr (struct elf_m68k_got *got,
			     struct elf_m68k_got_entry_key *key)
{
  void **ptr;
  struct elf_m68k_got_entry entry_;
  struct elf_m68k_got_entry **entry_ptr;

  entry_.key_ = *key;
  ptr = htab_find_slot (got->entries, &entry_, NO_INSERT);
  BFD_ASSERT (ptr != NULL);

  entry_ptr = (struct elf_m68k_got_entry **) ptr;

  return entry_ptr;
}

/* Remove entry pointed to by ENTRY_PTR from GOT.  */

static void
elf_m68k_remove_got_entry (struct elf_m68k_got *got,
			   struct elf_m68k_got_entry **entry_ptr)
{
  struct elf_m68k_got_entry *entry;

  entry = *entry_ptr;

  /* Check that offsets have not been finalized yet.  */
  BFD_ASSERT (got->offset == (bfd_vma) -1);
  /* Check that this entry is indeed unused.  */
  BFD_ASSERT (entry->u.s1.refcount == 0);

  elf_m68k_remove_got_entry_type (got, entry->u.s1.type);

  if (entry->key_.bfd != NULL)
    --got->local_n_entries;

  htab_clear_slot (got->entries, (void **) entry_ptr);
}

/* Copy any information related to dynamic linking from a pre-existing
   symbol to a newly created symbol.  Also called to copy flags and
   other back-end info to a weakdef, in which case the symbol is not
   newly created and plt/got refcounts and dynamic indices should not
   be copied.  */

static void
elf_m68k_copy_indirect_symbol (struct bfd_link_info *info,
			       struct elf_link_hash_entry *_dir,
			       struct elf_link_hash_entry *_ind)
{
  struct elf_m68k_link_hash_entry *dir;
  struct elf_m68k_link_hash_entry *ind;

  _bfd_elf_link_hash_copy_indirect (info, _dir, _ind);

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

  dir = elf_m68k_hash_entry (_dir);
  ind = elf_m68k_hash_entry (_ind);

  /* We might have a direct symbol already having entries in the GOTs.
     Update its key only in case indirect symbol has GOT entries and
     assert that both indirect and direct symbols don't have GOT entries
     at the same time.  */
  if (ind->got_entry_key != 0)
    {
      BFD_ASSERT (dir->got_entry_key == 0);
      /* Assert that GOTs aren't partioned yet.  */
      BFD_ASSERT (ind->glist == NULL);

      dir->got_entry_key = ind->got_entry_key;
      ind->got_entry_key = 0;
    }
}

/* Look through the relocs for a section during the first phase, and
   allocate space in the global offset table or procedure linkage
   table.  */

static bfd_boolean
elf_m68k_check_relocs (abfd, info, sec, relocs)
     bfd *abfd;
     struct bfd_link_info *info;
     asection *sec;
     const Elf_Internal_Rela *relocs;
{
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sgot;
  asection *srelgot;
  asection *sreloc;
  struct elf_m68k_got *got;

  if (info->relocatable)
    return TRUE;

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

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

  got = NULL;

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

      r_symndx = ELF32_R_SYM (rel->r_info);

      if (r_symndx < symtab_hdr->sh_info)
	h = NULL;
      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;
	}

      switch (ELF32_R_TYPE (rel->r_info))
	{
	case R_68K_GOT8:
	case R_68K_GOT16:
	case R_68K_GOT32:
	  if (h != NULL
	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
	    break;
	  /* Fall through.  */
	case R_68K_GOT8O:
	case R_68K_GOT16O:
	case R_68K_GOT32O:
	  /* This symbol requires a global offset table entry.  */

	  if (dynobj == NULL)
	    {
	      /* Create the .got section.  */
	      elf_hash_table (info)->dynobj = dynobj = abfd;
	      if (!_bfd_elf_create_got_section (dynobj, info))
		return FALSE;
	    }

	  if (sgot == NULL)
	    {
	      sgot = bfd_get_section_by_name (dynobj, ".got");
	      BFD_ASSERT (sgot != NULL);
	    }

	  if (srelgot == NULL
	      && (h != NULL || info->shared))
	    {
	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
	      if (srelgot == NULL)
		{
		  srelgot = bfd_make_section_with_flags (dynobj,
							 ".rela.got",
							 (SEC_ALLOC
							  | SEC_LOAD
							  | SEC_HAS_CONTENTS
							  | SEC_IN_MEMORY
							  | SEC_LINKER_CREATED
							  | SEC_READONLY));
		  if (srelgot == NULL
		      || !bfd_set_section_alignment (dynobj, srelgot, 2))
		    return FALSE;
		}
	    }

	  if (got == NULL)
	    {
	      struct elf_m68k_bfd2got_entry *bfd2got_entry;

	      bfd2got_entry
		= elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
					      abfd, FIND_OR_CREATE, info);
	      if (bfd2got_entry == NULL)
		return FALSE;

	      got = bfd2got_entry->got;
	      BFD_ASSERT (got != NULL);
	    }

	  {
	    struct elf_m68k_got_entry *got_entry;

	    /* Add entry to got.  */
	    got_entry = elf_m68k_add_entry_to_got (got, h, abfd,
						   ELF32_R_TYPE (rel->r_info),
						   r_symndx, info);
	    if (got_entry == NULL)
	      return FALSE;

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

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

		/* Allocate relocation space.  */
		if (h != NULL
		    || info->shared)
		  srelgot->size += sizeof (Elf32_External_Rela);
	      }
	  }

	  break;

	case R_68K_PLT8:
	case R_68K_PLT16:
	case R_68K_PLT32:
	  /* 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.  */

	  /* If this is a local symbol, we resolve it directly without
	     creating a procedure linkage table entry.  */
	  if (h == NULL)
	    continue;

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

	case R_68K_PLT8O:
	case R_68K_PLT16O:
	case R_68K_PLT32O:
	  /* This symbol requires a procedure linkage table entry.  */

	  if (h == NULL)
	    {
	      /* It does not make sense to have this relocation for a
		 local symbol.  FIXME: does it?  How to handle it if
		 it does make sense?  */
	      bfd_set_error (bfd_error_bad_value);
	      return FALSE;
	    }

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

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

	case R_68K_PC8:
	case R_68K_PC16:
	case R_68K_PC32:
	  /* 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).  We account for that
	     possibility below by storing information in the
	     pcrel_relocs_copied field of the hash table entry.  */
	  if (!(info->shared
		&& (sec->flags & SEC_ALLOC) != 0
		&& h != NULL
		&& (!info->symbolic
		    || h->root.type == bfd_link_hash_defweak
		    || !h->def_regular)))
	    {
	      if (h != NULL)
		{
		  /* Make sure a plt entry is created for this symbol if
		     it turns out to be a function defined by a dynamic
		     object.  */
		  h->plt.refcount++;
		}
	      break;
	    }
	  /* Fall through.  */
	case R_68K_8:
	case R_68K_16:
	case R_68K_32:
	  if (h != NULL)
	    {
	      /* Make sure a plt entry is created for this symbol if it
		 turns out to be a function defined by a dynamic object.  */
	      h->plt.refcount++;
	    }

	  /* If we are creating a shared library, we need to copy the
	     reloc into the shared library.  */
	  if (info->shared
	      && (sec->flags & SEC_ALLOC) != 0)
	    {
	      /* When creating a shared object, we must copy these
		 reloc types into the output file.  We create a reloc
		 section in dynobj and make room for this reloc.  */
	      if (sreloc == NULL)
		{
		  const char *name;

		  name = (bfd_elf_string_from_elf_section
			  (abfd,
			   elf_elfheader (abfd)->e_shstrndx,
			   elf_section_data (sec)->rel_hdr.sh_name));
		  if (name == NULL)
		    return FALSE;

		  BFD_ASSERT (CONST_STRNEQ (name, ".rela")
			      && strcmp (bfd_get_section_name (abfd, sec),
					 name + 5) == 0);

		  sreloc = bfd_get_section_by_name (dynobj, name);
		  if (sreloc == NULL)
		    {
		      sreloc = bfd_make_section_with_flags (dynobj,
							    name,
							    (SEC_ALLOC
							     | SEC_LOAD
							     | SEC_HAS_CONTENTS
							     | SEC_IN_MEMORY
							     | SEC_LINKER_CREATED
							     | SEC_READONLY));
		      if (sreloc == NULL
			  || !bfd_set_section_alignment (dynobj, sreloc, 2))
			return FALSE;
		    }
		  elf_section_data (sec)->sreloc = sreloc;
		}

	      if (sec->flags & SEC_READONLY
		  /* Don't set DF_TEXTREL yet for PC relative
		     relocations, they might be discarded later.  */
		  && !(ELF32_R_TYPE (rel->r_info) == R_68K_PC8
		       || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
		       || ELF32_R_TYPE (rel->r_info) == R_68K_PC32))
		    info->flags |= DF_TEXTREL;

	      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, in the -Bsymbolic case, the symbol is later
		 defined by a regular object, or, in the normal shared
		 case, the symbol is forced to be local.  Note that this
		 function is only called if we are using an m68kelf linker
		 hash table, which means that h is really a pointer to an
		 elf_m68k_link_hash_entry.  */
	      if (ELF32_R_TYPE (rel->r_info) == R_68K_PC8
		  || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
		  || ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
		{
		  struct elf_m68k_pcrel_relocs_copied *p;
		  struct elf_m68k_pcrel_relocs_copied **head;

		  if (h != NULL)
		    {
		      struct elf_m68k_link_hash_entry *eh
			= elf_m68k_hash_entry (h);
		      head = &eh->pcrel_relocs_copied;
		    }
		  else
		    {
		      asection *s;
		      void *vpp;

		      s = (bfd_section_from_r_symndx
			   (abfd, &elf_m68k_hash_table (info)->sym_sec,
			    sec, r_symndx));
		      if (s == NULL)
			return FALSE;

		      vpp = &elf_section_data (s)->local_dynrel;
		      head = (struct elf_m68k_pcrel_relocs_copied **) vpp;
		    }

		  for (p = *head; p != NULL; p = p->next)
		    if (p->section == sreloc)
		      break;

		  if (p == NULL)
		    {
		      p = ((struct elf_m68k_pcrel_relocs_copied *)
			   bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
		      if (p == NULL)
			return FALSE;
		      p->next = *head;
		      *head = p;
		      p->section = sreloc;
		      p->count = 0;
		    }

		  ++p->count;
		}
	    }

	  break;

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

	default:
	  break;
	}
    }

  return TRUE;
}

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

static asection *
elf_m68k_gc_mark_hook (asection *sec,
		       struct bfd_link_info *info,
		       Elf_Internal_Rela *rel,
		       struct elf_link_hash_entry *h,
		       Elf_Internal_Sym *sym)
{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_68K_GNU_VTINHERIT:
      case R_68K_GNU_VTENTRY:
	return NULL;
      }

  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
elf_m68k_gc_sweep_hook (bfd *abfd,
			struct bfd_link_info *info,
			asection *sec,
			const Elf_Internal_Rela *relocs)
{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  const Elf_Internal_Rela *rel, *relend;
  bfd *dynobj;
  asection *sgot;
  asection *srelgot;
  struct elf_m68k_got *got;

  if (info->relocatable)
    return TRUE;

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

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

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

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

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

      switch (ELF32_R_TYPE (rel->r_info))
	{
	case R_68K_GOT8:
	case R_68K_GOT16:
	case R_68K_GOT32:
	  if (h != NULL
	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
	    break;

	  /* FALLTHRU */
	case R_68K_GOT8O:
	case R_68K_GOT16O:
	case R_68K_GOT32O:
	  if (got == NULL)
	    {
	      got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
						abfd, MUST_FIND, NULL)->got;
	      BFD_ASSERT (got != NULL);
	    }

	  {
	    struct elf_m68k_got_entry_key key_;
	    struct elf_m68k_got_entry **got_entry_ptr;
	    struct elf_m68k_got_entry *got_entry;

	    elf_m68k_init_got_entry_key (&key_, h, abfd, r_symndx);
	    got_entry_ptr = elf_m68k_find_got_entry_ptr (got, &key_);

	    got_entry = *got_entry_ptr;

	    if (got_entry->u.s1.refcount > 0)
	      {
		--got_entry->u.s1.refcount;

		if (got_entry->u.s1.refcount == 0)
		  /* We don't need the .got entry any more.  */
		  elf_m68k_remove_got_entry (got, got_entry_ptr);
	      }
	  }
	  break;

	case R_68K_PLT8:
	case R_68K_PLT16:
	case R_68K_PLT32:
	case R_68K_PLT8O:
	case R_68K_PLT16O:
	case R_68K_PLT32O:
	case R_68K_PC8:
	case R_68K_PC16:
	case R_68K_PC32:
	case R_68K_8:
	case R_68K_16:
	case R_68K_32:
	  if (h != NULL)
	    {
	      if (h->plt.refcount > 0)
		--h->plt.refcount;
	    }
	  break;

	default:
	  break;
	}
    }

  return TRUE;
}

/* Return the type of PLT associated with OUTPUT_BFD.  */

static const struct elf_m68k_plt_info *
elf_m68k_get_plt_info (bfd *output_bfd)
{
  unsigned int features;

  features = bfd_m68k_mach_to_features (bfd_get_mach (output_bfd));
  if (features & cpu32)
    return &elf_cpu32_plt_info;
  if (features & mcfisa_b)
    return &elf_isab_plt_info;
  if (features & mcfisa_c)
    return &elf_isac_plt_info;
  return &elf_m68k_plt_info;
}

/* This function is called after all the input files have been read,
   and the input sections have been assigned to output sections.
   It's a convenient place to determine the PLT style.  */

static bfd_boolean
elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
{
  /* Bind input BFDs to GOTs and calculate sizes of .got and .rela.got
     sections.  */
  if (!elf_m68k_partition_multi_got (info))
    return FALSE;

  elf_m68k_hash_table (info)->plt_info = elf_m68k_get_plt_info (output_bfd);
  return TRUE;
}

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

  htab = elf_m68k_hash_table (info);
  dynobj = elf_hash_table (info)->dynobj;

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

  /* If this 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 ((h->plt.refcount <= 0
           || SYMBOL_CALLS_LOCAL (info, h)
	   || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
	       && h->root.type == bfd_link_hash_undefweak))
	  /* We must always create the plt entry if it was referenced
	     by a PLTxxO relocation.  In this case we already recorded
	     it as a dynamic symbol.  */
	  && h->dynindx == -1)
	{
	  /* This case can occur if we saw a PLTxx reloc in an input
	     file, but the symbol was never referred to by a dynamic
	     object, or if all references were garbage collected.  In
	     such a case, we don't actually need to build a procedure
	     linkage table, and we can just do a PCxx reloc instead.  */
	  h->plt.offset = (bfd_vma) -1;
	  h->needs_plt = 0;
	  return TRUE;
	}

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

      s = bfd_get_section_by_name (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 = htab->plt_info->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.  This is required to make function
	 pointers compare as equal between the normal executable and
	 the shared library.  */
      if (!info->shared
	  && !h->def_regular)
	{
	  h->root.u.def.section = s;
	  h->root.u.def.value = s->size;
	}

      h->plt.offset = s->size;

      /* Make room for this entry.  */
      s->size += htab->plt_info->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.  */
      s = bfd_get_section_by_name (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_section_by_name (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 (h->size == 0)
    {
      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
			     h->root.root.string);
      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_section_by_name (dynobj, ".dynbss");
  BFD_ASSERT (s != NULL);

  /* We must generate a R_68K_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)
    {
      asection *srel;

      srel = bfd_get_section_by_name (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);
}

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

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

  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_section_by_name (dynobj, ".interp");
	  BFD_ASSERT (s != NULL);
	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
	}
    }
  else
    {
      /* 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_section_by_name (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.
     For the normal shared case we discard the PC relative relocs
     against symbols that have become local due to visibility changes.
     We allocated space for them in the check_relocs routine, but we
     will not fill them in in the relocate_section routine.  */
  if (info->shared)
    elf_link_hash_traverse (elf_hash_table (info),
			    elf_m68k_discard_copies,
			    (PTR) 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 (CONST_STRNEQ (name, ".rela"))
	{
	  if (s->size != 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.  */
      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
	 Unused entries should be reclaimed before the section's contents
	 are written out, but at the moment this does not happen.  Thus in
	 order to prevent writing out garbage, we initialise the section's
	 contents to zero.  */
      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_m68k_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;
	}
    }
#undef add_dynamic_entry

  return TRUE;
}

/* This function is called via elf_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 shared case, it
   discards space for pc-relative 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.

   We also check whether any of the remaining relocations apply
   against a readonly section, and set the DF_TEXTREL flag in this
   case.  */

static bfd_boolean
elf_m68k_discard_copies (h, inf)
     struct elf_link_hash_entry *h;
     PTR inf;
{
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
  struct elf_m68k_pcrel_relocs_copied *s;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (!h->def_regular
      || (!info->symbolic
	  && !h->forced_local))
    {
      if ((info->flags & DF_TEXTREL) == 0)
	{
	  /* Look for relocations against read-only sections.  */
	  for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
	       s != NULL;
	       s = s->next)
	    if ((s->section->flags & SEC_READONLY) != 0)
	      {
		info->flags |= DF_TEXTREL;
		break;
	      }
	}

      return TRUE;
    }

  for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
       s != NULL;
       s = s->next)
    s->section->size -= s->count * sizeof (Elf32_External_Rela);

  return TRUE;
}

/* Relocate an M68K ELF section.  */

static bfd_boolean
elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
			   contents, relocs, local_syms, local_sections)
     bfd *output_bfd;
     struct bfd_link_info *info;
     bfd *input_bfd;
     asection *input_section;
     bfd_byte *contents;
     Elf_Internal_Rela *relocs;
     Elf_Internal_Sym *local_syms;
     asection **local_sections;
{
  bfd *dynobj;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  asection *sgot;
  asection *splt;
  asection *sreloc;
  struct elf_m68k_got *got;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);

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

  got = NULL;

  rel = relocs;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++)
    {
      int r_type;
      reloc_howto_type *howto;
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;
      Elf_Internal_Sym *sym;
      asection *sec;
      bfd_vma relocation;
      bfd_boolean unresolved_reloc;
      bfd_reloc_status_type r;

      r_type = ELF32_R_TYPE (rel->r_info);
      if (r_type < 0 || r_type >= (int) R_68K_max)
	{
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}
      howto = howto_table + r_type;

      r_symndx = ELF32_R_SYM (rel->r_info);

      h = NULL;
      sym = NULL;
      sec = NULL;
      unresolved_reloc = FALSE;

      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);
	}
      else
	{
	  bfd_boolean warned;

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

      if (sec != NULL && elf_discarded_section (sec))
	{
	  /* For relocs against symbols from removed linkonce sections,
	     or sections discarded by a linker script, we just want the
	     section contents zeroed.  Avoid any special processing.  */
	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
	  rel->r_info = 0;
	  rel->r_addend = 0;
	  continue;
	}

      if (info->relocatable)
	continue;

      switch (r_type)
	{
	case R_68K_GOT8:
	case R_68K_GOT16:
	case R_68K_GOT32:
	  /* Relocation is to the address of the entry for this symbol
	     in the global offset table.  */
	  if (h != NULL
	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
	    {
	      if (elf_m68k_hash_table (info)->local_gp_p)
		{
		  bfd_vma sgot_output_offset;
		  bfd_vma got_offset;

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

		      if (sgot != NULL)
			sgot_output_offset = sgot->output_offset;
		      else
			/* In this case we have a reference to
			   _GLOBAL_OFFSET_TABLE_, but the GOT itself is
			   empty.
			   ??? Issue a warning?  */
			sgot_output_offset = 0;
		    }
		  else
		    sgot_output_offset = sgot->output_offset;

		  if (got == NULL)
		    {
		      struct elf_m68k_bfd2got_entry *bfd2got_entry;

		      bfd2got_entry
			= elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
						      input_bfd, SEARCH, NULL);

		      if (bfd2got_entry != NULL)
			{
			  got = bfd2got_entry->got;
			  BFD_ASSERT (got != NULL);

			  got_offset = got->offset;
			}
		      else
			/* In this case we have a reference to
			   _GLOBAL_OFFSET_TABLE_, but no other references
			   accessing any GOT entries.
			   ??? Issue a warning?  */
			got_offset = 0;
		    }
		  else
		    got_offset = got->offset;

		  /* Adjust GOT pointer to point to the GOT
		     assigned to input_bfd.  */
		  rel->r_addend += sgot_output_offset + got_offset;
		}
	      else
		BFD_ASSERT (got == NULL || got->offset == 0);

	      break;
	    }
	  /* Fall through.  */
	case R_68K_GOT8O:
	case R_68K_GOT16O:
	case R_68K_GOT32O:
	  /* Relocation is the offset of the entry for this symbol in
	     the global offset table.  */

	  {
	    struct elf_m68k_got_entry_key key_;
	    bfd_vma *off_ptr;
	    bfd_vma off;

	    if (sgot == NULL)
	      {
		sgot = bfd_get_section_by_name (dynobj, ".got");
		BFD_ASSERT (sgot != NULL);
	      }

	    if (got == NULL)
	      {
		got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
						  input_bfd, MUST_FIND,
						  NULL)->got;
		BFD_ASSERT (got != NULL);
	      }

	    /* Get GOT offset for this symbol.  */
	    elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx);
	    off_ptr = &elf_m68k_get_got_entry (got, &key_, MUST_FIND,
					       NULL)->u.s2.offset;
	    off = *off_ptr;

	    if (h != NULL)
	      {
		bfd_boolean dyn;

		dyn = elf_hash_table (info)->dynamic_sections_created;
		if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
		    || (info->shared
			&& (info->symbolic
			    || h->dynindx == -1
			    || h->forced_local)
			&& h->def_regular))
		  {
		    /* This is actually a static link, or it is a
		       -Bsymbolic link and the symbol is defined
		       locally, or the symbol was forced to be local
		       because of a version file..  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.

		       When doing a dynamic link, we 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);
			*off_ptr |= 1;
		      }
		  }
		else
		  unresolved_reloc = FALSE;
	      }
	    else
	      {
		/* 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)
		      {
			asection *s;
			Elf_Internal_Rela outrel;
			bfd_byte *loc;

			s = bfd_get_section_by_name (dynobj, ".rela.got");
			BFD_ASSERT (s != NULL);

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

		    *off_ptr |= 1;
		  }
	      }

	    if (r_type == R_68K_GOT8O
		|| r_type == R_68K_GOT16O
		|| r_type == R_68K_GOT32O)
	      {
		/* GOT pointer is adjusted to point to the start/middle
		   of local GOT.  Adjust the offset accordingly.  */
		BFD_ASSERT (elf_m68k_hash_table (info)->use_neg_got_offsets_p
			    || off >= got->offset);

		if (elf_m68k_hash_table (info)->local_gp_p)
		  relocation = off - got->offset;
		else
		  {
		    BFD_ASSERT (got->offset == 0);
		    relocation = sgot->output_offset + off;
		  }

		/* This relocation does not use the addend.  */
		BFD_ASSERT (rel->r_addend == 0);
		rel->r_addend = 0;
	      }
	    else
	      relocation = (sgot->output_section->vma + sgot->output_offset
			    + off);
	  }
	  break;

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

	  /* Resolve a PLTxx reloc against a local symbol directly,
	     without using the procedure linkage table.  */
	  if (h == NULL)
	    break;

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

	  if (splt == NULL)
	    {
	      splt = bfd_get_section_by_name (dynobj, ".plt");
	      BFD_ASSERT (splt != NULL);
	    }

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

	case R_68K_PLT8O:
	case R_68K_PLT16O:
	case R_68K_PLT32O:
	  /* Relocation is the offset of the entry for this symbol in
	     the procedure linkage table.  */
	  BFD_ASSERT (h != NULL && h->plt.offset != (bfd_vma) -1);

	  if (splt == NULL)
	    {
	      splt = bfd_get_section_by_name (dynobj, ".plt");
	      BFD_ASSERT (splt != NULL);
	    }

	  relocation = h->plt.offset;
	  unresolved_reloc = FALSE;

	  /* This relocation does not use the addend.  */
	  rel->r_addend = 0;

	  break;

	case R_68K_PC8:
	case R_68K_PC16:
	case R_68K_PC32:
	  if (h == NULL
	      || (info->shared
		  && h->forced_local))
	    break;
	  /* Fall through.  */
	case R_68K_8:
	case R_68K_16:
	case R_68K_32:
	  if (info->shared
	      && r_symndx != 0
	      && (input_section->flags & SEC_ALLOC) != 0
	      && (h == NULL
		  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
		  || h->root.type != bfd_link_hash_undefweak)
	      && ((r_type != R_68K_PC8
		   && r_type != R_68K_PC16
		   && r_type != R_68K_PC32)
		  || (h != NULL
		      && h->dynindx != -1
		      && (!info->symbolic
			  || !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.  */

	      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)
		skip = TRUE, relocate = TRUE;
	      outrel.r_offset += (input_section->output_section->vma
				  + input_section->output_offset);

	      if (skip)
		memset (&outrel, 0, sizeof outrel);
	      else if (h != NULL
		       && h->dynindx != -1
		       && (r_type == R_68K_PC8
			   || r_type == R_68K_PC16
			   || r_type == R_68K_PC32
			   || !info->shared
			   || !info->symbolic
			   || !h->def_regular))
		{
		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
		  outrel.r_addend = rel->r_addend;
		}
	      else
		{
		  /* This symbol is local, or marked to become local.  */
		  outrel.r_addend = relocation + rel->r_addend;

		  if (r_type == R_68K_32)
		    {
		      relocate = TRUE;
		      outrel.r_info = ELF32_R_INFO (0, R_68K_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)
			    {
			      struct elf_link_hash_table *htab;
			      htab = elf_hash_table (info);
			      osec = htab->text_index_section;
			      indx = elf_section_data (osec)->dynindx;
			    }
			  BFD_ASSERT (indx != 0);
			}

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

	      sreloc = elf_section_data (input_section)->sreloc;
	      if (sreloc == NULL)
		abort ();

	      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_68K_32
                 relocations that have been turned into
                 R_68K_RELATIVE.  */
	      if (!relocate)
		continue;
	    }

	  break;

	case R_68K_GNU_VTINHERIT:
	case R_68K_GNU_VTENTRY:
	  /* These are no-ops in the end.  */
	  continue;

	default:
	  break;
	}

      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
	 because such sections are not SEC_ALLOC and thus ld.so will
	 not process them.  */
      if (unresolved_reloc
	  && !((input_section->flags & SEC_DEBUGGING) != 0
	       && h->def_dynamic))
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
	     input_bfd,
	     input_section,
	     (long) rel->r_offset,
	     howto->name,
	     h->root.root.string);
	  return FALSE;
	}

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

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

	  if (h != NULL)
	    name = h->root.root.string;
	  else
	    {
	      name = bfd_elf_string_from_elf_section (input_bfd,
						      symtab_hdr->sh_link,
						      sym->st_name);
	      if (name == NULL)
		return FALSE;
	      if (*name == '\0')
		name = bfd_section_name (input_bfd, sec);
	    }

	  if (r == bfd_reloc_overflow)
	    {
	      if (!(info->callbacks->reloc_overflow
		    (info, (h ? &h->root : NULL), name, howto->name,
		     (bfd_vma) 0, input_bfd, input_section,
		     rel->r_offset)))
		return FALSE;
	    }
	  else
	    {
	      (*_bfd_error_handler)
		(_("%B(%A+0x%lx): reloc against `%s': error %d"),
		 input_bfd, input_section,
		 (long) rel->r_offset, name, (int) r);
	      return FALSE;
	    }
	}
    }

  return TRUE;
}

/* Install an M_68K_PC32 relocation against VALUE at offset OFFSET
   into section SEC.  */

static void
elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value)
{
  /* Make VALUE PC-relative.  */
  value -= sec->output_section->vma + offset;

  /* Apply any in-place addend.  */
  value += bfd_get_32 (sec->owner, sec->contents + offset);

  bfd_put_32 (sec->owner, value, sec->contents + offset);
}

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

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

  dynobj = elf_hash_table (info)->dynobj;

  if (h->plt.offset != (bfd_vma) -1)
    {
      const struct elf_m68k_plt_info *plt_info;
      asection *splt;
      asection *sgot;
      asection *srela;
      bfd_vma plt_index;
      bfd_vma got_offset;
      Elf_Internal_Rela rela;
      bfd_byte *loc;

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

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

      plt_info = elf_m68k_hash_table (info)->plt_info;
      splt = bfd_get_section_by_name (dynobj, ".plt");
      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
      srela = bfd_get_section_by_name (dynobj, ".rela.plt");
      BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);

      /* Get the index in the procedure linkage table which
	 corresponds to this symbol.  This is the index of this symbol
	 in all the symbols for which we are making plt entries.  The
	 first entry in the procedure linkage table is reserved.  */
      plt_index = (h->plt.offset / plt_info->size) - 1;

      /* Get the offset into the .got table of the entry that
	 corresponds to this function.  Each .got entry is 4 bytes.
	 The first three are reserved.  */
      got_offset = (plt_index + 3) * 4;

      memcpy (splt->contents + h->plt.offset,
	      plt_info->symbol_entry,
	      plt_info->size);

      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.got,
			     (sgot->output_section->vma
			      + sgot->output_offset
			      + got_offset));

      bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
		  splt->contents
		  + h->plt.offset
		  + plt_info->symbol_resolve_entry + 2);

      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.plt,
			     splt->output_section->vma);

      /* Fill in the entry in the global offset table.  */
      bfd_put_32 (output_bfd,
		  (splt->output_section->vma
		   + splt->output_offset
		   + h->plt.offset
		   + plt_info->symbol_resolve_entry),
		  sgot->contents + got_offset);

      /* Fill in the entry in the .rela.plt section.  */
      rela.r_offset = (sgot->output_section->vma
		       + sgot->output_offset
		       + got_offset);
      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT);
      rela.r_addend = 0;
      loc = srela->contents + 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;
	}
    }

  if (elf_m68k_hash_entry (h)->glist != NULL)
    {
      asection *sgot;
      asection *srela;
      struct elf_m68k_got_entry *got_entry;

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

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

      got_entry = elf_m68k_hash_entry (h)->glist;

      while (got_entry != NULL)
	{
	  Elf_Internal_Rela rela;
	  bfd_byte *loc;

	  rela.r_offset = (sgot->output_section->vma
			   + sgot->output_offset
			   + (got_entry->u.s2.offset &~ (bfd_vma) 1));

	  /* If this is a -Bsymbolic link, and the symbol is defined
	     locally, we just want to emit a RELATIVE reloc.  Likewise if
	     the symbol was forced to be local because of a version file.
	     The entry in the global offset table will already have been
	     initialized in the relocate_section function.  */
	  if (info->shared
	      && (info->symbolic
		  || h->dynindx == -1
		  || h->forced_local)
	      && h->def_regular)
	    {
	      rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
	      rela.r_addend = bfd_get_signed_32 (output_bfd,
						 (sgot->contents
						  + (got_entry->u.s2.offset
						     &~ (bfd_vma) 1)));
	    }
	  else
	    {
	      bfd_put_32 (output_bfd, (bfd_vma) 0,
			  sgot->contents + (got_entry->u.s2.offset
					    &~ (bfd_vma) 1));
	      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_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);

	  got_entry = got_entry->u.s2.next;
	}
    }

  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_section_by_name (h->root.u.def.section->owner,
				   ".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_68K_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 (strcmp (h->root.root.string, "_DYNAMIC") == 0
      || h == elf_hash_table (info)->hgot)
    sym->st_shndx = SHN_ABS;

  return TRUE;
}

/* Finish up the dynamic sections.  */

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

  dynobj = elf_hash_table (info)->dynobj;

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

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

      splt = bfd_get_section_by_name (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;
	  const char *name;
	  asection *s;

	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);

	  switch (dyn.d_tag)
	    {
	    default:
	      break;

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

	    case DT_PLTRELSZ:
	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	      BFD_ASSERT (s != NULL);
	      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)
	{
	  const struct elf_m68k_plt_info *plt_info;

	  plt_info = elf_m68k_hash_table (info)->plt_info;
	  memcpy (splt->contents, plt_info->plt0_entry, plt_info->size);

	  elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got4,
				 (sgot->output_section->vma
				  + sgot->output_offset
				  + 4));

	  elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got8,
				 (sgot->output_section->vma
				  + sgot->output_offset
				  + 8));

	  elf_section_data (splt->output_section)->this_hdr.sh_entsize
	    = plt_info->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;
}

/* Given a .data section and a .emreloc in-memory section, store
   relocation information into the .emreloc section which can be
   used at runtime to relocate the section.  This is called by the
   linker when the --embedded-relocs switch is used.  This is called
   after the add_symbols entry point has been called for all the
   objects, and before the final_link entry point is called.  */

bfd_boolean
bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
     bfd *abfd;
     struct bfd_link_info *info;
     asection *datasec;
     asection *relsec;
     char **errmsg;
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Sym *isymbuf = NULL;
  Elf_Internal_Rela *internal_relocs = NULL;
  Elf_Internal_Rela *irel, *irelend;
  bfd_byte *p;
  bfd_size_type amt;

  BFD_ASSERT (! info->relocatable);

  *errmsg = NULL;

  if (datasec->reloc_count == 0)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;

  /* Get a copy of the native relocations.  */
  internal_relocs = (_bfd_elf_link_read_relocs
		     (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
		      info->keep_memory));
  if (internal_relocs == NULL)
    goto error_return;

  amt = (bfd_size_type) datasec->reloc_count * 12;
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
  if (relsec->contents == NULL)
    goto error_return;

  p = relsec->contents;

  irelend = internal_relocs + datasec->reloc_count;
  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
    {
      asection *targetsec;

      /* We are going to write a four byte longword into the runtime
       reloc section.  The longword will be the address in the data
       section which must be relocated.  It is followed by the name
       of the target section NUL-padded or truncated to 8
       characters.  */

      /* We can only relocate absolute longword relocs at run time.  */
      if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
	{
	  *errmsg = _("unsupported reloc type");
	  bfd_set_error (bfd_error_bad_value);
	  goto error_return;
	}

      /* Get the target section referred to by the reloc.  */
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
	{
	  /* A local symbol.  */
	  Elf_Internal_Sym *isym;

	  /* Read this BFD's local symbols if we haven't done so already.  */
	  if (isymbuf == NULL)
	    {
	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
	      if (isymbuf == NULL)
		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
						symtab_hdr->sh_info, 0,
						NULL, NULL, NULL);
	      if (isymbuf == NULL)
		goto error_return;
	    }

	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
	  targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
	}
      else
	{
	  unsigned long indx;
	  struct elf_link_hash_entry *h;

	  /* An external symbol.  */
	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
	  h = elf_sym_hashes (abfd)[indx];
	  BFD_ASSERT (h != NULL);
	  if (h->root.type == bfd_link_hash_defined
	      || h->root.type == bfd_link_hash_defweak)
	    targetsec = h->root.u.def.section;
	  else
	    targetsec = NULL;
	}

      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
      memset (p + 4, 0, 8);
      if (targetsec != NULL)
	strncpy ((char *) p + 4, targetsec->output_section->name, 8);
    }

  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
    free (isymbuf);
  if (internal_relocs != NULL
      && elf_section_data (datasec)->relocs != internal_relocs)
    free (internal_relocs);
  return TRUE;

error_return:
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
    free (isymbuf);
  if (internal_relocs != NULL
      && elf_section_data (datasec)->relocs != internal_relocs)
    free (internal_relocs);
  return FALSE;
}

/* Set target options.  */

void
bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling)
{
  struct elf_m68k_link_hash_table *htab;

  htab = elf_m68k_hash_table (info);

  switch (got_handling)
    {
    case 0:
      /* --got=single.  */
      htab->local_gp_p = FALSE;
      htab->use_neg_got_offsets_p = FALSE;
      htab->allow_multigot_p = FALSE;
      break;

    case 1:
      /* --got=negative.  */
      htab->local_gp_p = TRUE;
      htab->use_neg_got_offsets_p = TRUE;
      htab->allow_multigot_p = FALSE;
      break;

    case 2:
      /* --got=multigot.  */
      htab->local_gp_p = TRUE;
      htab->use_neg_got_offsets_p = TRUE;
      htab->allow_multigot_p = TRUE;
      break;

    default:
      BFD_ASSERT (FALSE);
    }
}

static enum elf_reloc_type_class
elf32_m68k_reloc_type_class (rela)
     const Elf_Internal_Rela *rela;
{
  switch ((int) ELF32_R_TYPE (rela->r_info))
    {
    case R_68K_RELATIVE:
      return reloc_class_relative;
    case R_68K_JMP_SLOT:
      return reloc_class_plt;
    case R_68K_COPY:
      return reloc_class_copy;
    default:
      return reloc_class_normal;
    }
}

/* Return address for Ith PLT stub in section PLT, for relocation REL
   or (bfd_vma) -1 if it should not be included.  */

static bfd_vma
elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
		      const arelent *rel ATTRIBUTE_UNUSED)
{
  return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size;
}

#define TARGET_BIG_SYM			bfd_elf32_m68k_vec
#define TARGET_BIG_NAME			"elf32-m68k"
#define ELF_MACHINE_CODE		EM_68K
#define ELF_MAXPAGESIZE			0x2000
#define elf_backend_create_dynamic_sections \
					_bfd_elf_create_dynamic_sections
#define bfd_elf32_bfd_link_hash_table_create \
					elf_m68k_link_hash_table_create
/* ??? Should it be this macro or bfd_elfNN_bfd_link_hash_table_create?  */
#define bfd_elf32_bfd_link_hash_table_free \
					elf_m68k_link_hash_table_free
#define bfd_elf32_bfd_final_link	bfd_elf_final_link

#define elf_backend_check_relocs	elf_m68k_check_relocs
#define elf_backend_always_size_sections \
					elf_m68k_always_size_sections
#define elf_backend_adjust_dynamic_symbol \
					elf_m68k_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections \
					elf_m68k_size_dynamic_sections
#define elf_backend_init_index_section	_bfd_elf_init_1_index_section
#define elf_backend_relocate_section	elf_m68k_relocate_section
#define elf_backend_finish_dynamic_symbol \
					elf_m68k_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
					elf_m68k_finish_dynamic_sections
#define elf_backend_gc_mark_hook	elf_m68k_gc_mark_hook
#define elf_backend_gc_sweep_hook	elf_m68k_gc_sweep_hook
#define elf_backend_copy_indirect_symbol elf_m68k_copy_indirect_symbol
#define bfd_elf32_bfd_merge_private_bfd_data \
                                        elf32_m68k_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags \
                                        elf32_m68k_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data \
                                        elf32_m68k_print_private_bfd_data
#define elf_backend_reloc_type_class	elf32_m68k_reloc_type_class
#define elf_backend_plt_sym_val		elf_m68k_plt_sym_val
#define elf_backend_object_p		elf32_m68k_object_p

#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
#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_rela_normal		1

#include "elf32-target.h"
