gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-m68k.c
index f266d63a150d4f8e4327e00b15a6bd91e541ce5d..868435a444252e7826c139adb096160ec29a331b 100644 (file)
@@ -1,7 +1,5 @@
 /* Motorola 68k series support for 32-bit ELF
-   Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
-   Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #include "elf-bfd.h"
 #include "elf/m68k.h"
 #include "opcode/m68k.h"
+#include "cpu-m68k.h"
+#include "elf32-m68k.h"
 
 static bfd_boolean
 elf_m68k_discard_copies (struct elf_link_hash_entry *, void *);
 
 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),
+  HOWTO(R_68K_NONE,      0, 3, 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 */
@@ -343,18 +343,21 @@ static reloc_howto_type howto_table[] =
         FALSE),                /* pcrel_offset */
 };
 
-static void
+static bfd_boolean
 rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
   unsigned int indx = ELF32_R_TYPE (dst->r_info);
 
   if (indx >= (unsigned int) R_68K_max)
     {
-      (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
-                            abfd, (int) indx);
-      indx = R_68K_NONE;
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, indx);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
     }
   cache_ptr->howto = &howto_table[indx];
+  return TRUE;
 }
 
 #define elf_info_to_howto rtype_to_howto
@@ -509,7 +512,8 @@ static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
   0, 0, 0, 0             /* + .plt - . */
 };
 
-static const struct elf_m68k_plt_info elf_m68k_plt_info = {
+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
@@ -519,13 +523,13 @@ static const struct elf_m68k_plt_info elf_m68k_plt_info = {
 
 static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
 {
-  0x20, 0x3c,             /* move.l #offset,%d0 */
-  0, 0, 0, 0,             /* + (.got + 4) - . */
+  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, 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, 0xd0,            /* jmp (%a0) */
   0x4e, 0x71             /* nop */
 };
 
@@ -533,17 +537,18 @@ static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
 
 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, 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 - . */
+  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 = {
+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
@@ -574,10 +579,11 @@ static const bfd_byte elf_isac_plt_entry[ISAC_PLT_ENTRY_SIZE] =
   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 - . */
+  0, 0, 0, 0             /* replaced with .plt - . */
 };
 
-static const struct elf_m68k_plt_info elf_isac_plt_info = {
+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
@@ -588,27 +594,28 @@ static const struct elf_m68k_plt_info elf_isac_plt_info = {
 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) - . */
+  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, 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, 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 = {
+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
@@ -692,15 +699,14 @@ struct elf_m68k_got_entry
   {
     struct
     {
-      /* Number of times this entry is referenced.  It is used to
-        filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook.  */
+      /* Number of times this entry is referenced.  */
       bfd_vma refcount;
     } s1;
 
     struct
     {
       /* Offset from the start of .got section.  To calculate offset relative
-        to GOT pointer one should substract got->offset from this value.  */
+        to GOT pointer one should subtract got->offset from this value.  */
       bfd_vma offset;
 
       /* Pointer to the next GOT entry for this global symbol.
@@ -942,13 +948,30 @@ elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry,
   return ret;
 }
 
+/* Destroy an m68k ELF linker hash table.  */
+
+static void
+elf_m68k_link_hash_table_free (bfd *obfd)
+{
+  struct elf_m68k_link_hash_table *htab;
+
+  htab = (struct elf_m68k_link_hash_table *) obfd->link.hash;
+
+  if (htab->multi_got_.bfd2got != NULL)
+    {
+      htab_delete (htab->multi_got_.bfd2got);
+      htab->multi_got_.bfd2got = NULL;
+    }
+  _bfd_elf_link_hash_table_free (obfd);
+}
+
 /* Create an m68k ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
 elf_m68k_link_hash_table_create (bfd *abfd)
 {
   struct elf_m68k_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
+  size_t amt = sizeof (struct elf_m68k_link_hash_table);
 
   ret = (struct elf_m68k_link_hash_table *) bfd_zmalloc (amt);
   if (ret == (struct elf_m68k_link_hash_table *) NULL)
@@ -962,29 +985,13 @@ elf_m68k_link_hash_table_create (bfd *abfd)
       free (ret);
       return NULL;
     }
+  ret->root.root.hash_table_free = elf_m68k_link_hash_table_free;
 
   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;
-    }
-  _bfd_elf_link_hash_table_free (_htab);
-}
-
 /* Set the right machine number.  */
 
 static bfd_boolean
@@ -1048,9 +1055,8 @@ elf32_m68k_object_p (bfd *abfd)
 /* Somewhat reverse of elf32_m68k_object_p, this sets the e_flag
    field based on the machine number.  */
 
-static void
-elf_m68k_final_write_processing (bfd *abfd,
-                                bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf_m68k_final_write_processing (bfd *abfd)
 {
   int mach = bfd_get_mach (abfd);
   unsigned long e_flags = elf_elfheader (abfd)->e_flags;
@@ -1103,6 +1109,7 @@ elf_m68k_final_write_processing (bfd *abfd,
        }
       elf_elfheader (abfd)->e_flags = e_flags;
     }
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Keep m68k-specific flags in the ELF header.  */
@@ -1118,17 +1125,20 @@ elf32_m68k_set_private_flags (bfd *abfd, flagword flags)
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 static bfd_boolean
-elf32_m68k_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_m68k_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   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
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return FALSE;
+    /* PR 24523: For non-ELF files do not try to merge any private
+       data, but also do not prevent the link from succeeding.  */
+    return TRUE;
 
   /* Get the merged machine.  This checks for incompatibility between
      Coldfire & non-Coldfire flags, incompability between different
@@ -1511,14 +1521,18 @@ elf_m68k_get_got_entry (struct elf_m68k_got *got,
     }
 
   entry_.key_ = *key;
-  ptr = htab_find_slot (got->entries, &entry_, (howto != SEARCH
-                                               ? INSERT : NO_INSERT));
+  ptr = htab_find_slot (got->entries, &entry_,
+                       (howto == SEARCH || howto == MUST_FIND ? NO_INSERT
+                        : INSERT));
   if (ptr == NULL)
     {
       if (howto == SEARCH)
        /* Entry not found.  */
        return NULL;
 
+      if (howto == MUST_FIND)
+       abort ();
+
       /* We're out of memory.  */
       bfd_set_error (bfd_error_no_memory);
       return NULL;
@@ -1527,7 +1541,10 @@ elf_m68k_get_got_entry (struct elf_m68k_got *got,
   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);
+      if (howto == MUST_FIND)
+       abort ();
+
+      BFD_ASSERT (howto != SEARCH);
 
       entry = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry));
       if (entry == NULL)
@@ -1601,27 +1618,6 @@ elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
   return was;
 }
 
-/* Update GOT counters when removing an entry of type TYPE.  */
-
-static void
-elf_m68k_remove_got_entry_type (struct elf_m68k_got *got,
-                               enum elf_m68k_reloc_type type)
-{
-  enum elf_m68k_got_offset_size os;
-  bfd_vma n_slots;
-
-  n_slots = elf_m68k_reloc_got_n_slots (type);
-
-  /* Decrese counter of slots with offset size corresponding to TYPE
-     and all greater offset sizes.  */
-  for (os = elf_m68k_reloc_got_offset_size (type); os <= R_32; ++os)
-    {
-      BFD_ASSERT (got->n_slots[os] >= n_slots);
-
-      got->n_slots[os] -= n_slots;
-    }
-}
-
 /* 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.  */
@@ -1671,17 +1667,19 @@ elf_m68k_add_entry_to_got (struct elf_m68k_got *got,
     /* This BFD has too many relocation.  */
     {
       if (got->n_slots[R_8] > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
-       (*_bfd_error_handler) (_("%B: GOT overflow: "
-                                "Number of relocations with 8-bit "
-                                "offset > %d"),
-                              abfd,
-                              ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info));
+       /* xgettext:c-format */
+       _bfd_error_handler (_("%pB: GOT overflow: "
+                             "number of relocations with 8-bit "
+                             "offset > %d"),
+                           abfd,
+                           ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info));
       else
-       (*_bfd_error_handler) (_("%B: GOT overflow: "
-                                "Number of relocations with 8- or 16-bit "
-                                "offset > %d"),
-                              abfd,
-                              ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info));
+       /* xgettext:c-format */
+       _bfd_error_handler (_("%pB: GOT overflow: "
+                             "number of relocations with 8- or 16-bit "
+                             "offset > %d"),
+                           abfd,
+                           ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info));
 
       return NULL;
     }
@@ -1761,14 +1759,18 @@ elf_m68k_get_bfd2got_entry (struct elf_m68k_multi_got *multi_got,
     }
 
   entry_.bfd = abfd;
-  ptr = htab_find_slot (multi_got->bfd2got, &entry_, (howto != SEARCH
-                                                     ? INSERT : NO_INSERT));
+  ptr = htab_find_slot (multi_got->bfd2got, &entry_,
+                       (howto == SEARCH || howto == MUST_FIND ? NO_INSERT
+                        : INSERT));
   if (ptr == NULL)
     {
       if (howto == SEARCH)
        /* Entry not found.  */
        return NULL;
 
+      if (howto == MUST_FIND)
+       abort ();
+
       /* We're out of memory.  */
       bfd_set_error (bfd_error_no_memory);
       return NULL;
@@ -1777,7 +1779,10 @@ elf_m68k_get_bfd2got_entry (struct elf_m68k_multi_got *multi_got,
   if (*ptr == NULL)
     /* Entry was not found.  Create new one.  */
     {
-      BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);
+      if (howto == MUST_FIND)
+       abort ();
+
+      BFD_ASSERT (howto != SEARCH);
 
       entry = ((struct elf_m68k_bfd2got_entry *)
               bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry)));
@@ -2233,7 +2238,7 @@ elf_m68k_partition_multi_got_2 (struct elf_m68k_partition_multi_got_arg *arg)
 
   arg->n_slots += arg->current_got->n_slots[R_32];
 
-  if (!arg->info->shared)
+  if (!bfd_link_pic (arg->info))
     /* 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
@@ -2346,7 +2351,7 @@ elf_m68k_partition_multi_got_1 (void **_entry, void *_arg)
   if (diff != NULL)
     elf_m68k_clear_got (diff);
 
-  return arg->error_p == FALSE ? 1 : 0;
+  return !arg->error_p;
 }
 
 /* Helper function to build symndx2h mapping.  */
@@ -2427,7 +2432,7 @@ elf_m68k_partition_multi_got (struct bfd_link_info *info)
     {
       asection *s;
 
-      s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".got");
+      s = elf_hash_table (info)->sgot;
       if (s != NULL)
        s->size = arg_.offset;
       else
@@ -2436,7 +2441,7 @@ elf_m68k_partition_multi_got (struct bfd_link_info *info)
       BFD_ASSERT (arg_.slots_relas_diff <= arg_.n_slots);
       arg_.n_slots -= arg_.slots_relas_diff;
 
-      s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".rela.got");
+      s = elf_hash_table (info)->srelgot;
       if (s != NULL)
        s->size = arg_.n_slots * sizeof (Elf32_External_Rela);
       else
@@ -2448,52 +2453,6 @@ elf_m68k_partition_multi_got (struct bfd_link_info *info)
   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->key_.type);
-
-  if (entry->key_.bfd != NULL)
-    got->local_n_slots -= elf_m68k_reloc_got_n_slots (entry->key_.type);
-
-  BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
-
-  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
@@ -2550,20 +2509,16 @@ elf_m68k_check_relocs (bfd *abfd,
   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)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
-  sgot = NULL;
-  srelgot = NULL;
   sreloc = NULL;
 
   got = NULL;
@@ -2584,10 +2539,6 @@ elf_m68k_check_relocs (bfd *abfd,
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-         /* PR15323, ref flags aren't set for references in the same
-            object.  */
-         h->root.non_ir_ref = 1;
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
@@ -2621,7 +2572,7 @@ elf_m68k_check_relocs (bfd *abfd,
        case R_68K_TLS_DTPREL32:
 
          if (ELF32_R_TYPE (rel->r_info) == R_68K_TLS_TPREL32
-             && info->shared)
+             && bfd_link_pic (info))
            /* Do the special chorus for libraries with static TLS.  */
            info->flags |= DF_STATIC_TLS;
 
@@ -2635,30 +2586,6 @@ elf_m68k_check_relocs (bfd *abfd,
                return FALSE;
            }
 
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_linker_section (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
-
-         if (srelgot == NULL
-             && (h != NULL || info->shared))
-           {
-             srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-             if (srelgot == NULL)
-               {
-                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                   | SEC_READONLY);
-                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
-                                                               ".rela.got",
-                                                               flags);
-                 if (srelgot == NULL
-                     || !bfd_set_section_alignment (dynobj, srelgot, 2))
-                   return FALSE;
-               }
-           }
-
          if (got == NULL)
            {
              struct elf_m68k_bfd2got_entry *bfd2got_entry;
@@ -2703,10 +2630,10 @@ elf_m68k_check_relocs (bfd *abfd,
        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.  */
+            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.  */
@@ -2756,10 +2683,10 @@ elf_m68k_check_relocs (bfd *abfd,
             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
+         if (!(bfd_link_pic (info)
                && (sec->flags & SEC_ALLOC) != 0
                && h != NULL
-               && (!info->symbolic
+               && (!SYMBOLIC_BIND (info, h)
                    || h->root.type == bfd_link_hash_defweak
                    || !h->def_regular)))
            {
@@ -2787,14 +2714,16 @@ elf_m68k_check_relocs (bfd *abfd,
                 turns out to be a function defined by a dynamic object.  */
              h->plt.refcount++;
 
-             if (info->executable)
+             if (bfd_link_executable (info))
                /* This symbol needs a non-GOT reference.  */
                h->non_got_ref = 1;
            }
 
          /* If we are creating a shared library, we need to copy the
             reloc into the shared library.  */
-         if (info->shared)
+         if (bfd_link_pic (info)
+             && (h == NULL
+                 || !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))
            {
              /* When creating a shared object, we must copy these
                 reloc types into the output file.  We create a reloc
@@ -2890,9 +2819,7 @@ elf_m68k_check_relocs (bfd *abfd,
          /* 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))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
@@ -2924,131 +2851,6 @@ elf_m68k_gc_mark_hook (asection *sec,
 
   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;
-  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);
-  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:
-         /* Fall through.  */
-
-         /* TLS relocations.  */
-       case R_68K_TLS_GD8:
-       case R_68K_TLS_GD16:
-       case R_68K_TLS_GD32:
-       case R_68K_TLS_LDM8:
-       case R_68K_TLS_LDM16:
-       case R_68K_TLS_LDM32:
-       case R_68K_TLS_IE8:
-       case R_68K_TLS_IE16:
-       case R_68K_TLS_IE32:
-
-       case R_68K_TLS_TPREL32:
-       case R_68K_TLS_DTPREL32:
-
-         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,
-                                        ELF32_R_TYPE (rel->r_info));
-           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;
-}
 \f
 /* Return the type of PLT associated with OUTPUT_BFD.  */
 
@@ -3098,12 +2900,12 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
   asection *s;
 
   htab = elf_m68k_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
              && (h->needs_plt
-                 || h->u.weakdef != NULL
+                 || h->is_weakalias
                  || (h->def_dynamic
                      && h->ref_regular
                      && !h->def_regular)));
@@ -3115,8 +2917,9 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
       || h->needs_plt)
     {
       if ((h->plt.refcount <= 0
-           || SYMBOL_CALLS_LOCAL (info, h)
-          || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+          || SYMBOL_CALLS_LOCAL (info, h)
+          || ((ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+               || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
               && 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
@@ -3141,7 +2944,7 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
            return FALSE;
        }
 
-      s = bfd_get_linker_section (dynobj, ".plt");
+      s = htab->root.splt;
       BFD_ASSERT (s != NULL);
 
       /* If this is the first .plt entry, make room for the special
@@ -3154,7 +2957,7 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
         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
+      if (!bfd_link_pic (info)
          && !h->def_regular)
        {
          h->root.u.def.section = s;
@@ -3168,12 +2971,12 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
 
       /* 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_linker_section (dynobj, ".got.plt");
+      s = htab->root.sgotplt;
       BFD_ASSERT (s != NULL);
       s->size += 4;
 
       /* We also need to make an entry in the .rela.plt section.  */
-      s = bfd_get_linker_section (dynobj, ".rela.plt");
+      s = htab->root.srelplt;
       BFD_ASSERT (s != NULL);
       s->size += sizeof (Elf32_External_Rela);
 
@@ -3187,12 +2990,12 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* 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)
+  if (h->is_weakalias)
     {
-      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;
+      struct elf_link_hash_entry *def = weakdef (h);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      h->root.u.def.section = def->root.u.def.section;
+      h->root.u.def.value = def->root.u.def.value;
       return TRUE;
     }
 
@@ -3203,7 +3006,7 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
      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)
+  if (bfd_link_pic (info))
     return TRUE;
 
   /* If there are no references to this symbol that do not use the
@@ -3238,7 +3041,7 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Set the sizes of the dynamic sections.  */
@@ -3258,7 +3061,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -3273,7 +3076,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         not actually use these entries.  Reset the size of .rela.got,
         which will cause it to get stripped from the output file
         below.  */
-      s = bfd_get_linker_section (dynobj, ".rela.got");
+      s = elf_hash_table (info)->srelgot;
       if (s != NULL)
        s->size = 0;
     }
@@ -3284,7 +3087,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      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)
+  if (bfd_link_pic (info))
     elf_link_hash_traverse (elf_hash_table (info),
                            elf_m68k_discard_copies,
                            info);
@@ -3303,7 +3106,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       /* 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);
+      name = bfd_section_name (s);
 
       if (strcmp (name, ".plt") == 0)
        {
@@ -3367,7 +3170,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-      if (info->executable)
+      if (bfd_link_executable (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
@@ -3610,7 +3413,6 @@ elf_m68k_relocate_section (bfd *output_bfd,
                           Elf_Internal_Sym *local_syms,
                           asection **local_sections)
 {
-  bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   asection *sgot;
@@ -3621,7 +3423,6 @@ elf_m68k_relocate_section (bfd *output_bfd,
   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);
 
@@ -3645,6 +3446,7 @@ elf_m68k_relocate_section (bfd *output_bfd,
       bfd_vma relocation;
       bfd_boolean unresolved_reloc;
       bfd_reloc_status_type r;
+      bfd_boolean resolved_to_zero;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type < 0 || r_type >= (int) R_68K_max)
@@ -3669,21 +3471,24 @@ elf_m68k_relocate_section (bfd *output_bfd,
        }
       else
        {
-         bfd_boolean warned;
+         bfd_boolean warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
        }
 
       if (sec != NULL && discarded_section (sec))
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
                                         rel, 1, relend, howto, 0, contents);
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        continue;
 
+      resolved_to_zero = (h != NULL
+                         && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+
       switch (r_type)
        {
        case R_68K_GOT8:
@@ -3699,21 +3504,16 @@ elf_m68k_relocate_section (bfd *output_bfd,
                  bfd_vma sgot_output_offset;
                  bfd_vma got_offset;
 
-                 if (sgot == NULL)
-                   {
-                     sgot = bfd_get_linker_section (dynobj, ".got");
+                 sgot = elf_hash_table (info)->sgot;
 
-                     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
+                 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;
 
                  if (got == NULL)
                    {
@@ -3774,19 +3574,13 @@ elf_m68k_relocate_section (bfd *output_bfd,
            bfd_vma *off_ptr;
            bfd_vma off;
 
-           if (sgot == NULL)
-             {
-               sgot = bfd_get_linker_section (dynobj, ".got");
-               BFD_ASSERT (sgot != NULL);
-             }
+           sgot = elf_hash_table (info)->sgot;
+           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);
-             }
+             got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
+                                               input_bfd, MUST_FIND,
+                                               NULL)->got;
 
            /* Get GOT offset for this symbol.  */
            elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx,
@@ -3811,10 +3605,13 @@ elf_m68k_relocate_section (bfd *output_bfd,
                    bfd_boolean dyn;
 
                    dyn = elf_hash_table (info)->dynamic_sections_created;
-                   if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-                       || (info->shared
+                   if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+                                                         bfd_link_pic (info),
+                                                         h)
+                       || (bfd_link_pic (info)
                            && SYMBOL_REFERENCES_LOCAL (info, h))
-                       || (ELF_ST_VISIBILITY (h->other)
+                       || ((ELF_ST_VISIBILITY (h->other)
+                            || resolved_to_zero)
                            && h->root.type == bfd_link_hash_undefweak))
                      {
                        /* This is actually a static link, or it is a
@@ -3842,14 +3639,11 @@ elf_m68k_relocate_section (bfd *output_bfd,
                    else
                      unresolved_reloc = FALSE;
                  }
-               else if (info->shared) /* && h == NULL */
+               else if (bfd_link_pic (info)) /* && h == NULL */
                  /* Process local symbol during dynamic link.  */
                  {
-                   if (srela == NULL)
-                     {
-                       srela = bfd_get_linker_section (dynobj, ".rela.got");
-                       BFD_ASSERT (srela != NULL);
-                     }
+                   srela = elf_hash_table (info)->srelgot;
+                   BFD_ASSERT (srela != NULL);
 
                    elf_m68k_init_got_entry_local_shared (info,
                                                          output_bfd,
@@ -3861,7 +3655,7 @@ elf_m68k_relocate_section (bfd *output_bfd,
 
                    *off_ptr |= 1;
                  }
-               else /* h == NULL && !info->shared */
+               else /* h == NULL && !bfd_link_pic (info) */
                  {
                    elf_m68k_init_got_entry_static (info,
                                                    output_bfd,
@@ -3915,12 +3709,14 @@ elf_m68k_relocate_section (bfd *output_bfd,
        case R_68K_TLS_LE32:
        case R_68K_TLS_LE16:
        case R_68K_TLS_LE8:
-         if (info->shared && !info->pie)
+         if (bfd_link_dll (info))
            {
-             (*_bfd_error_handler)
-               (_("%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted "
-                  "in shared object"),
-                input_bfd, input_section, (long) rel->r_offset, howto->name);
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA+%#" PRIx64 "): "
+                  "%s relocation not permitted in shared object"),
+                input_bfd, input_section, (uint64_t) rel->r_offset,
+                howto->name);
 
              return FALSE;
            }
@@ -3949,11 +3745,8 @@ elf_m68k_relocate_section (bfd *output_bfd,
              break;
            }
 
-         if (splt == NULL)
-           {
-             splt = bfd_get_linker_section (dynobj, ".plt");
-             BFD_ASSERT (splt != NULL);
-           }
+         splt = elf_hash_table (info)->splt;
+         BFD_ASSERT (splt != NULL);
 
          relocation = (splt->output_section->vma
                        + splt->output_offset
@@ -3968,11 +3761,8 @@ elf_m68k_relocate_section (bfd *output_bfd,
             the procedure linkage table.  */
          BFD_ASSERT (h != NULL && h->plt.offset != (bfd_vma) -1);
 
-         if (splt == NULL)
-           {
-             splt = bfd_get_linker_section (dynobj, ".plt");
-             BFD_ASSERT (splt != NULL);
-           }
+         splt = elf_hash_table (info)->splt;
+         BFD_ASSERT (splt != NULL);
 
          relocation = h->plt.offset;
          unresolved_reloc = FALSE;
@@ -3988,11 +3778,12 @@ elf_m68k_relocate_section (bfd *output_bfd,
        case R_68K_PC8:
        case R_68K_PC16:
        case R_68K_PC32:
-         if (info->shared
+         if (bfd_link_pic (info)
              && r_symndx != STN_UNDEF
              && (input_section->flags & SEC_ALLOC) != 0
              && (h == NULL
-                 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                     && !resolved_to_zero)
                  || h->root.type != bfd_link_hash_undefweak)
              && ((r_type != R_68K_PC8
                   && r_type != R_68K_PC16
@@ -4027,8 +3818,8 @@ elf_m68k_relocate_section (bfd *output_bfd,
                       && (r_type == R_68K_PC8
                           || r_type == R_68K_PC16
                           || r_type == R_68K_PC32
-                          || !info->shared
-                          || !info->symbolic
+                          || !bfd_link_pic (info)
+                          || !SYMBOLIC_BIND (info, h)
                           || !h->def_regular))
                {
                  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
@@ -4089,9 +3880,9 @@ elf_m68k_relocate_section (bfd *output_bfd,
              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.  */
+                need to do anything now, except for R_68K_32
+                relocations that have been turned into
+                R_68K_RELATIVE.  */
              if (!relocate)
                continue;
            }
@@ -4116,11 +3907,13 @@ elf_m68k_relocate_section (bfd *output_bfd,
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
        {
-         (*_bfd_error_handler)
-           (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB(%pA+%#" PRIx64 "): "
+              "unresolvable %s relocation against symbol `%s'"),
             input_bfd,
             input_section,
-            (long) rel->r_offset,
+            (uint64_t) rel->r_offset,
             howto->name,
             h->root.root.string);
          return FALSE;
@@ -4147,16 +3940,18 @@ elf_m68k_relocate_section (bfd *output_bfd,
                  name = (bfd_elf_string_from_elf_section
                          (input_bfd, symtab_hdr->sh_link, sym->st_name));
                  if (name == NULL || *name == '\0')
-                   name = bfd_section_name (input_bfd, sec);
+                   name = bfd_section_name (sec);
                }
 
-             (*_bfd_error_handler)
+             _bfd_error_handler
                ((sym_type == STT_TLS
-                 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
-                 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+                 /* xgettext:c-format */
+                 ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
+                 /* xgettext:c-format */
+                 : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
                 input_bfd,
                 input_section,
-                (long) rel->r_offset,
+                (uint64_t) rel->r_offset,
                 howto->name,
                 name);
            }
@@ -4180,23 +3975,20 @@ elf_m68k_relocate_section (bfd *output_bfd,
              if (name == NULL)
                return FALSE;
              if (*name == '\0')
-               name = bfd_section_name (input_bfd, sec);
+               name = bfd_section_name (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;
-           }
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
          else
            {
-             (*_bfd_error_handler)
-               (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
                 input_bfd, input_section,
-                (long) rel->r_offset, name, (int) r);
+                (uint64_t) rel->r_offset, name, (int) r);
              return FALSE;
            }
        }
@@ -4250,9 +4042,9 @@ elf_m68k_finish_dynamic_symbol (bfd *output_bfd,
       BFD_ASSERT (h->dynindx != -1);
 
       plt_info = elf_m68k_hash_table (info)->plt_info;
-      splt = bfd_get_linker_section (dynobj, ".plt");
-      sgot = bfd_get_linker_section (dynobj, ".got.plt");
-      srela = bfd_get_linker_section (dynobj, ".rela.plt");
+      splt = elf_hash_table (info)->splt;
+      sgot = elf_hash_table (info)->sgotplt;
+      srela = elf_hash_table (info)->srelplt;
       BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
 
       /* Get the index in the procedure linkage table which
@@ -4317,8 +4109,8 @@ elf_m68k_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
 
-      sgot = bfd_get_linker_section (dynobj, ".got");
-      srela = bfd_get_linker_section (dynobj, ".rela.got");
+      sgot = elf_hash_table (info)->sgot;
+      srela = elf_hash_table (info)->srelgot;
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       got_entry = elf_m68k_hash_entry (h)->glist;
@@ -4336,7 +4128,7 @@ elf_m68k_finish_dynamic_symbol (bfd *output_bfd,
             the symbol was forced to be local because of a version file.
             The entry in the global offset table already have been
             initialized in the relocate_section function.  */
-         if (info->shared
+         if (bfd_link_pic (info)
              && SYMBOL_REFERENCES_LOCAL (info, h))
            {
              bfd_vma relocation;
@@ -4467,7 +4259,7 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  sgot = bfd_get_linker_section (dynobj, ".got.plt");
+  sgot = elf_hash_table (info)->sgotplt;
   BFD_ASSERT (sgot != NULL);
   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
@@ -4476,7 +4268,7 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       asection *splt;
       Elf32_External_Dyn *dyncon, *dynconend;
 
-      splt = bfd_get_linker_section (dynobj, ".plt");
+      splt = elf_hash_table (info)->splt;
       BFD_ASSERT (splt != NULL && sdyn != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
@@ -4484,7 +4276,6 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       for (; dyncon < dynconend; dyncon++)
        {
          Elf_Internal_Dyn dyn;
-         const char *name;
          asection *s;
 
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
@@ -4495,37 +4286,20 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
              break;
 
            case DT_PLTGOT:
-             name = ".got";
+             s = elf_hash_table (info)->sgotplt;
              goto get_vma;
            case DT_JMPREL:
-             name = ".rela.plt";
+             s = elf_hash_table (info)->srelplt;
            get_vma:
-             s = bfd_get_section_by_name (output_bfd, name);
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->vma;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              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);
+             s = elf_hash_table (info)->srelplt;
              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;
            }
        }
 
@@ -4578,12 +4352,9 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
    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;
+bfd_m68k_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info,
+                                      asection *datasec, asection *relsec,
+                                      char **errmsg)
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Sym *isymbuf = NULL;
@@ -4592,7 +4363,7 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
   bfd_byte *p;
   bfd_size_type amt;
 
-  BFD_ASSERT (! info->relocatable);
+  BFD_ASSERT (! bfd_link_relocatable (info));
 
   *errmsg = NULL;
 
@@ -4629,7 +4400,7 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
       /* 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");
+         *errmsg = _("unsupported relocation type");
          bfd_set_error (bfd_error_bad_value);
          goto error_return;
        }
@@ -4677,18 +4448,16 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
        strncpy ((char *) p + 4, targetsec->output_section->name, 8);
     }
 
-  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (internal_relocs != NULL
-      && elf_section_data (datasec)->relocs != internal_relocs)
+  if (elf_section_data (datasec)->relocs != internal_relocs)
     free (internal_relocs);
   return TRUE;
 
-error_return:
-  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ error_return:
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (internal_relocs != NULL
-      && elf_section_data (datasec)->relocs != internal_relocs)
+  if (elf_section_data (datasec)->relocs != internal_relocs)
     free (internal_relocs);
   return FALSE;
 }
@@ -4831,7 +4600,7 @@ elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#define TARGET_BIG_SYM                 bfd_elf32_m68k_vec
+#define TARGET_BIG_SYM                 m68k_elf32_vec
 #define TARGET_BIG_NAME                        "elf32-m68k"
 #define ELF_MACHINE_CODE               EM_68K
 #define ELF_MAXPAGESIZE                        0x2000
@@ -4839,9 +4608,6 @@ elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
                                        _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
@@ -4859,14 +4625,13 @@ elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #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
+                                       elf32_m68k_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags \
-                                        elf32_m68k_set_private_flags
+                                       elf32_m68k_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data \
-                                        elf32_m68k_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
@@ -4880,5 +4645,8 @@ elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #define elf_backend_want_plt_sym 0
 #define elf_backend_got_header_size    12
 #define elf_backend_rela_normal                1
+#define elf_backend_dtrel_excludes_plt 1
+
+#define elf_backend_linux_prpsinfo32_ugid16    TRUE
 
 #include "elf32-target.h"
This page took 0.046264 seconds and 4 git commands to generate.