gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-cris.c
index f1f060b87b28446aa012ea62bceaa012290e765b..bee7108684924e98b2fc5e83896cd43c06259b60 100644 (file)
@@ -1,6 +1,5 @@
 /* CRIS-specific support for 32-bit ELF.
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Contributed by Axis Communications AB.
    Written by Hans-Peter Nilsson, based on elf32-fr30.c
    PIC and shlib bits based primarily on elf32-m68k.c and elf32-i386.c.
 #include "elf/cris.h"
 #include <limits.h>
 
-/* Forward declarations.  */
-static reloc_howto_type * cris_reloc_type_lookup
-  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-
-static void cris_info_to_howto_rela
-  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
-
-static bfd_reloc_status_type cris_elf_pcrel_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-
-static bfd_boolean cris_elf_grok_prstatus
-  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
-static bfd_boolean cris_elf_grok_psinfo
-  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
-static bfd_boolean cris_elf_relocate_section
-  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-
-static bfd_reloc_status_type cris_final_link_relocate
-  PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
-          Elf_Internal_Rela *, bfd_vma));
-
-static bfd_boolean cris_elf_object_p PARAMS ((bfd *));
-
-static void cris_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
-
-static bfd_boolean cris_elf_set_mach_from_flags
-  PARAMS ((bfd *, unsigned long int));
-
-static bfd_boolean cris_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
-
-static bfd_boolean cris_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
-static bfd_boolean cris_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
-
-struct elf_cris_link_hash_entry;
-static bfd_boolean elf_cris_discard_excess_dso_dynamics
-  PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_discard_excess_program_dynamics
-  PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_adjust_gotplt_to_got
-  PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_try_fold_plt_to_got
-  PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static struct bfd_hash_entry *elf_cris_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static struct bfd_link_hash_table *elf_cris_link_hash_table_create
-  PARAMS ((bfd *));
-static bfd_boolean elf_cris_adjust_dynamic_symbol
-  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static bfd_boolean cris_elf_check_relocs
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-
-static bfd_boolean elf_cris_size_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean elf_cris_finish_dynamic_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-          Elf_Internal_Sym *));
-static bfd_boolean elf_cris_finish_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static void elf_cris_hide_symbol
-  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
-static enum elf_reloc_type_class elf_cris_reloc_type_class
-  PARAMS ((const Elf_Internal_Rela *));
+bfd_reloc_status_type
+cris_elf_pcrel_reloc (bfd *, arelent *, asymbol *, void *,
+                     asection *, bfd *, char **);
+static bfd_boolean
+cris_elf_set_mach_from_flags (bfd *, unsigned long);
 
+/* Forward declarations.  */
 static reloc_howto_type cris_elf_howto_table [] =
 {
   /* This reloc does nothing.  */
   HOWTO (R_CRIS_NONE,          /* type */
         0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRIS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
@@ -419,10 +358,10 @@ static reloc_howto_type cris_elf_howto_table [] =
      relocs for cross-format linking.  */
 #define TLSHOWTO32(name) \
  HOWTO (name, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, \
-        bfd_elf_generic_reloc, #name, FALSE, 0, 0xffffffff, FALSE)
+       bfd_elf_generic_reloc, #name, FALSE, 0, 0xffffffff, FALSE)
 #define TLSHOWTO16X(name, X)        \
  HOWTO (name, 0, 1, 16, FALSE, 0, complain_overflow_ ## X, \
-        bfd_elf_generic_reloc, #name, FALSE, 0, 0xffff, FALSE)
+       bfd_elf_generic_reloc, #name, FALSE, 0, 0xffff, FALSE)
 #define TLSHOWTO16(name) TLSHOWTO16X(name, unsigned)
 #define TLSHOWTO16S(name) TLSHOWTO16X(name, signed)
 
@@ -485,9 +424,8 @@ static const struct cris_reloc_map cris_reloc_map [] =
 };
 
 static reloc_howto_type *
-cris_reloc_type_lookup (abfd, code)
-     bfd * abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+cris_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+                       bfd_reloc_code_real_type code)
 {
   unsigned int i;
 
@@ -515,29 +453,34 @@ cris_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
 
 /* Set the howto pointer for an CRIS ELF reloc.  */
 
-static void
-cris_info_to_howto_rela (abfd, cache_ptr, dst)
-     bfd * abfd ATTRIBUTE_UNUSED;
-     arelent * cache_ptr;
-     Elf_Internal_Rela * dst;
+static bfd_boolean
+cris_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+                        arelent * cache_ptr,
+                        Elf_Internal_Rela * dst)
 {
   enum elf_cris_reloc_type r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);
+  if (r_type >= R_CRIS_max)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
   cache_ptr->howto = & cris_elf_howto_table [r_type];
+  return TRUE;
 }
 
 bfd_reloc_status_type
-cris_elf_pcrel_reloc (abfd, reloc_entry, symbol, data, input_section,
-                     output_bfd, error_message)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *reloc_entry;
-     asymbol *symbol;
-     PTR data ATTRIBUTE_UNUSED;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+cris_elf_pcrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                     arelent *reloc_entry,
+                     asymbol *symbol,
+                     void * data ATTRIBUTE_UNUSED,
+                     asection *input_section,
+                     bfd *output_bfd,
+                     char **error_message ATTRIBUTE_UNUSED)
 {
   /* By default (using only bfd_elf_generic_reloc when linking to
      non-ELF formats) PC-relative relocs are relative to the beginning
@@ -562,9 +505,7 @@ cris_elf_pcrel_reloc (abfd, reloc_entry, symbol, data, input_section,
    changes, while still keeping Linux/CRIS and Linux/CRISv32 code apart.  */
 
 static bfd_boolean
-cris_elf_grok_prstatus (abfd, note)
-     bfd *abfd;
-     Elf_Internal_Note *note;
+cris_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
   int offset;
   size_t size;
@@ -577,10 +518,10 @@ cris_elf_grok_prstatus (abfd, note)
 
       case 202:                /* Linux/CRISv32 */
        /* pr_cursig */
-       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 22);
+       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
 
        /* pr_reg */
        offset = 70;
@@ -596,10 +537,10 @@ cris_elf_grok_prstatus (abfd, note)
 
       case 214:                /* Linux/CRIS */
        /* pr_cursig */
-       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 22);
+       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
 
        /* pr_reg */
        offset = 70;
@@ -614,9 +555,7 @@ cris_elf_grok_prstatus (abfd, note)
 }
 
 static bfd_boolean
-cris_elf_grok_psinfo (abfd, note)
-     bfd *abfd;
-     Elf_Internal_Note *note;
+cris_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
     switch (note->descsz)
@@ -625,9 +564,9 @@ cris_elf_grok_psinfo (abfd, note)
        return FALSE;
 
       case 124:                /* Linux/CRISv32 elf_prpsinfo */
-       elf_tdata (abfd)->core_program
+       elf_tdata (abfd)->core->program
          = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
-       elf_tdata (abfd)->core_command
+       elf_tdata (abfd)->core->command
          = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
       }
   else
@@ -637,9 +576,9 @@ cris_elf_grok_psinfo (abfd, note)
        return FALSE;
 
       case 124:                /* Linux/CRIS elf_prpsinfo */
-       elf_tdata (abfd)->core_program
+       elf_tdata (abfd)->core->program
          = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
-       elf_tdata (abfd)->core_command
+       elf_tdata (abfd)->core->command
          = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
       }
 
@@ -648,7 +587,7 @@ cris_elf_grok_psinfo (abfd, note)
      implementations, so strip it off if it exists.  */
 
   {
-    char *command = elf_tdata (abfd)->core_command;
+    char *command = elf_tdata (abfd)->core->command;
     int n = strlen (command);
 
     if (0 < n && command[n - 1] == ' ')
@@ -848,6 +787,13 @@ struct elf_cris_link_hash_entry
   bfd_signed_vma dtp_refcount;
 };
 
+static bfd_boolean
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *,
+                                     void * );
+static bfd_boolean
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *,
+                                         void *);
+
 /* The local_got_refcounts and local_got_offsets are a multiple of
    LSNUM in size, namely LGOT_ALLOC_NELTS_FOR(LSNUM) (plus one for the
    refcount for GOT itself, see code), with the summary / group offset
@@ -943,9 +889,9 @@ static struct bfd_link_hash_table *
 elf_cris_link_hash_table_create (bfd *abfd)
 {
   struct elf_cris_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf_cris_link_hash_table);
+  size_t amt = sizeof (struct elf_cris_link_hash_table);
 
-  ret = ((struct elf_cris_link_hash_table *) bfd_malloc (amt));
+  ret = ((struct elf_cris_link_hash_table *) bfd_zmalloc (amt));
   if (ret == (struct elf_cris_link_hash_table *) NULL)
     return NULL;
 
@@ -962,9 +908,6 @@ elf_cris_link_hash_table_create (bfd *abfd)
      are used for run-time symbol evaluation.  */
   ret->next_gotplt_entry = 12;
 
-  /* We haven't seen any R_CRIS_nn_GOT_TPREL initially.  */
-  ret->dtpmod_refcount = 0;
-
   return &ret->root.root;
 }
 \f
@@ -972,14 +915,12 @@ elf_cris_link_hash_table_create (bfd *abfd)
    routines, with a few tweaks.  */
 
 static bfd_reloc_status_type
-cris_final_link_relocate (howto, input_bfd, input_section, contents, rel,
-                         relocation)
-     reloc_howto_type *  howto;
-     bfd *               input_bfd;
-     asection *          input_section;
-     bfd_byte *          contents;
-     Elf_Internal_Rela * rel;
-     bfd_vma             relocation;
+cris_final_link_relocate (reloc_howto_type *  howto,
+                         bfd *               input_bfd,
+                         asection *          input_section,
+                         bfd_byte *          contents,
+                         Elf_Internal_Rela * rel,
+                         bfd_vma             relocation)
 {
   bfd_reloc_status_type r;
   enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
@@ -1052,7 +993,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab == NULL)
     return FALSE;
 
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -1065,8 +1006,8 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   if (dynobj != NULL)
     {
-      splt = bfd_get_linker_section (dynobj, ".plt");
-      sgot = bfd_get_linker_section (dynobj, ".got");
+      splt = htab->root.splt;
+      sgot = htab->root.sgot;
     }
 
   for (rel = relocs; rel < relend; rel ++)
@@ -1080,6 +1021,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
       bfd_reloc_status_type r;
       const char *symname = NULL;
       enum elf_cris_reloc_type r_type;
+      bfd_boolean resolved_to_zero;
 
       r_type = ELF32_R_TYPE (rel->r_info);
 
@@ -1102,17 +1044,17 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          symname = (bfd_elf_string_from_elf_section
                     (input_bfd, symtab_hdr->sh_link, sym->st_name));
          if (symname == NULL)
-           symname = bfd_section_name (input_bfd, sec);
+           symname = bfd_section_name (sec);
        }
       else
        {
-         bfd_boolean warned;
+         bfd_boolean warned, ignored;
          bfd_boolean unresolved_reloc;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
 
          symname = h->root.root.string;
 
@@ -1155,8 +1097,8 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                 time.  FIXME: Not sure this example covers the
                 h->elf_link_hash_flags test, though it's there in
                 other targets.  */
-             if (info->shared
-                 && ((! info->symbolic && h->dynindx != -1)
+             if (bfd_link_pic (info)
+                 && ((!SYMBOLIC_BIND (info, h) && h->dynindx != -1)
                      || !h->def_regular)
                  && (input_section->flags & SEC_ALLOC) != 0
                  && (r_type == R_CRIS_8
@@ -1166,14 +1108,15 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                      || r_type == R_CRIS_16_PCREL
                      || r_type == R_CRIS_32_PCREL))
                relocation = 0;
-             else if (!info->relocatable && unresolved_reloc
+             else if (!bfd_link_relocatable (info) && unresolved_reloc
                       && (_bfd_elf_section_offset (output_bfd, info,
                                                    input_section,
                                                    rel->r_offset)
                           != (bfd_vma) -1))
                {
                  _bfd_error_handler
-                   (_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
+                   /* xgettext:c-format */
+                   (_("%pB, section %pA: unresolvable relocation %s against symbol `%s'"),
                     input_bfd,
                     input_section,
                     cris_elf_howto_table[r_type].name,
@@ -1188,9 +1131,12 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        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_CRIS_16_GOTPLT:
@@ -1203,8 +1149,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          if (h != NULL
              && ((struct elf_cris_link_hash_entry *) h)->gotplt_offset != 0)
            {
-             asection *sgotplt
-               = bfd_get_linker_section (dynobj, ".got.plt");
+             asection *sgotplt = htab->root.sgotplt;
              bfd_vma got_offset;
 
              BFD_ASSERT (h->dynindx != -1);
@@ -1228,16 +1173,18 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
             these call-specific relocs don't address non-functions.  */
          if (h != NULL
              && (h->got.offset == (bfd_vma) -1
-                 || (!info->shared
+                 || (!bfd_link_pic (info)
                      && !(h->def_regular
                           || (!h->def_dynamic
                               && h->root.type == bfd_link_hash_undefweak)))))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
                ((h->got.offset == (bfd_vma) -1)
-                ? _("%B, section %A: No PLT nor GOT for relocation %s"
+                /* xgettext:c-format */
+                ? _("%pB, section %pA: no PLT nor GOT for relocation %s"
                     " against symbol `%s'")
-                : _("%B, section %A: No PLT for relocation %s"
+                /* xgettext:c-format */
+                : _("%pB, section %pA: no PLT for relocation %s"
                     " against symbol `%s'"),
                 input_bfd,
                 input_section,
@@ -1270,20 +1217,20 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                BFD_ASSERT (off != (bfd_vma) -1);
 
                if (!elf_hash_table (info)->dynamic_sections_created
-                   || (! info->shared
+                   || (! bfd_link_pic (info)
                        && (h->def_regular
                            || h->type == STT_FUNC
                            || h->needs_plt))
-                   || (info->shared
-                       && (info->symbolic || h->dynindx == -1)
+                   || (bfd_link_pic (info)
+                       && (SYMBOLIC_BIND (info, h) || h->dynindx == -1)
                        && h->def_regular))
                  {
-                   /* This wasn't checked above for ! info->shared, but
+                   /* This wasn't checked above for ! bfd_link_pic (info), but
                       must hold there if we get here; the symbol must
                       be defined in the regular program or be undefweak
                       or be a function or otherwise need a PLT.  */
                    BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
-                               || info->shared
+                               || bfd_link_pic (info)
                                || h->def_regular
                                || h->type == STT_FUNC
                                || h->needs_plt
@@ -1329,14 +1276,12 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                  {
                    bfd_put_32 (output_bfd, relocation, sgot->contents + off);
 
-                   if (info->shared)
+                   if (bfd_link_pic (info))
                      {
                        Elf_Internal_Rela outrel;
                        bfd_byte *loc;
 
-                       if (srelgot == NULL)
-                         srelgot
-                           = bfd_get_linker_section (dynobj, ".rela.got");
+                       srelgot = htab->root.srelgot;
                        BFD_ASSERT (srelgot != NULL);
 
                        outrel.r_offset = (sgot->output_section->vma
@@ -1361,21 +1306,23 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                   symbols.  Make this an error; the compiler isn't
                   allowed to pass us these kinds of things.  */
                if (h == NULL)
-                 (*_bfd_error_handler)
-                   (_("%B, section %A: relocation %s with non-zero addend %d"
-                      " against local symbol"),
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB, section %pA: relocation %s with non-zero addend"
+                      " %" PRId64 " against local symbol"),
                     input_bfd,
                     input_section,
                     cris_elf_howto_table[r_type].name,
-                    rel->r_addend);
+                    (int64_t) rel->r_addend);
                else
-                 (*_bfd_error_handler)
-                   (_("%B, section %A: relocation %s with non-zero addend %d"
-                      " against symbol `%s'"),
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB, section %pA: relocation %s with non-zero addend"
+                      " %" PRId64 " against symbol `%s'"),
                     input_bfd,
                     input_section,
                     cris_elf_howto_table[r_type].name,
-                    rel->r_addend,
+                    (int64_t) rel->r_addend,
                     symname[0] != '\0' ? symname : _("[whose name is lost]"));
 
                bfd_set_error (bfd_error_bad_value);
@@ -1390,13 +1337,14 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
             defined in an ordinary (non-DSO) object or is undefined weak.  */
          if (h != NULL
              && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-             && !(!info->shared
+             && !(!bfd_link_pic (info)
                   && (h->def_regular
                       || (!h->def_dynamic
                           && h->root.type == bfd_link_hash_undefweak))))
            {
-             (*_bfd_error_handler)
-               (_("%B, section %A: relocation %s is"
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s is"
                   " not allowed for global symbol: `%s'"),
                 input_bfd,
                 input_section,
@@ -1411,8 +1359,9 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
             it's noticed if it happens elsewhere.  */
          if (sgot == NULL)
            {
-             (*_bfd_error_handler)
-               (_("%B, section %A: relocation %s with no GOT created"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s with no GOT created"),
                 input_bfd,
                 input_section,
                 cris_elf_howto_table[r_type].name);
@@ -1489,13 +1438,14 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        case R_CRIS_8:
        case R_CRIS_16:
        case R_CRIS_32:
-         if (info->shared
+         if (bfd_link_pic (info)
+             && !resolved_to_zero
              && r_symndx != STN_UNDEF
              && (input_section->flags & SEC_ALLOC) != 0
              && ((r_type != R_CRIS_8_PCREL
                   && r_type != R_CRIS_16_PCREL
                   && r_type != R_CRIS_32_PCREL)
-                 || (!info->symbolic
+                 || (!SYMBOLIC_BIND (info, h)
                      || (h != NULL && !h->def_regular))))
            {
              Elf_Internal_Rela outrel;
@@ -1547,7 +1497,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              /* h->dynindx may be -1 if the symbol was marked to
                 become local.  */
              else if (h != NULL
-                      && ((! info->symbolic && h->dynindx != -1)
+                      && ((!SYMBOLIC_BIND (info, h) && h->dynindx != -1)
                           || !h->def_regular))
                {
                  BFD_ASSERT (h->dynindx != -1);
@@ -1602,8 +1552,8 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
 
              /* This reloc will be computed at runtime, so there's no
-                 need to do anything now, except for R_CRIS_32 relocations
-                 that have been turned into R_CRIS_RELATIVE.  */
+                need to do anything now, except for R_CRIS_32 relocations
+                that have been turned into R_CRIS_RELATIVE.  */
              if (!relocate)
                continue;
            }
@@ -1620,16 +1570,18 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          if (h != NULL
              && (input_section->flags & SEC_ALLOC) != 0
              && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-             && (info->shared
+             && (bfd_link_pic (info)
                  || (!h->def_regular
                      && h->root.type != bfd_link_hash_undefined)))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
                ((h->root.type == bfd_link_hash_undefined)
                 /* We shouldn't get here for GCC-emitted code.  */
-                ? _("%B, section %A: relocation %s has an undefined"
+                /* xgettext:c-format */
+                ? _("%pB, section %pA: relocation %s has an undefined"
                     " reference to `%s', perhaps a declaration mixup?")
-                : ("%B, section %A: relocation %s is"
+                /* xgettext:c-format */
+                : _("%pB, section %pA: relocation %s is"
                     " not allowed for `%s', a global symbol with default"
                     " visibility, perhaps a declaration mixup?"),
                 input_bfd,
@@ -1652,16 +1604,15 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          if (htab->dtpmod_refcount > 0
              && (input_section->flags & SEC_ALLOC) != 0)
            {
-             asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+             asection *sgotplt = htab->root.sgotplt;
              BFD_ASSERT (sgotplt != NULL);
 
-             if (info->shared)
+             if (bfd_link_pic (info))
                {
                  Elf_Internal_Rela outrel;
                  bfd_byte *loc;
 
-                 if (srelgot == NULL)
-                   srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+                 srelgot = htab->root.srelgot;
                  BFD_ASSERT (srelgot != NULL);
                  loc = srelgot->contents;
                  loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
@@ -1694,7 +1645,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          break;
 
        case R_CRIS_32_GD:
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              bfd_set_error (bfd_error_invalid_operation);
 
@@ -1712,20 +1663,21 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                 symbol *plus offset*.  The GOT holds relocations for
                 symbols.  Make this an error; the compiler isn't allowed
                 to pass us these kinds of things.  */
-             (*_bfd_error_handler)
-               (_("%B, section %A: relocation %s with non-zero addend %d"
-                  " against symbol `%s'"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s with non-zero addend"
+                  " %" PRId64 " against symbol `%s'"),
                 input_bfd,
                 input_section,
                 cris_elf_howto_table[r_type].name,
-                rel->r_addend,
+                (int64_t) rel->r_addend,
                 symname[0] != '\0' ? symname : _("[whose name is lost]"));
 
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
 
-         if (!info->shared
+         if (!bfd_link_pic (info)
              && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
            {
              /* Known contents of the GOT.  */
@@ -1804,8 +1756,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                  bfd_put_32 (output_bfd, 0, sgot->contents + off);
                  bfd_put_32 (output_bfd, 0, sgot->contents + off + 4);
 
-                 if (srelgot == NULL)
-                   srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+                 srelgot = htab->root.srelgot;
                  BFD_ASSERT (srelgot != NULL);
 
                  if (h != NULL && h->dynindx != -1)
@@ -1846,7 +1797,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          break;
 
        case R_CRIS_32_IE:
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              bfd_set_error (bfd_error_invalid_operation);
 
@@ -1865,19 +1816,20 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                 relocations for symbols.  Make this an error; the
                 compiler isn't allowed to pass us these kinds of
                 things.  */
-             (*_bfd_error_handler)
-               (_("%B, section %A: relocation %s with non-zero addend %d"
-                  " against symbol `%s'"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s with non-zero addend"
+                  " %" PRId64 " against symbol `%s'"),
                 input_bfd,
                 input_section,
                 cris_elf_howto_table[r_type].name,
-                rel->r_addend,
+                (int64_t) rel->r_addend,
                 symname[0] != '\0' ? symname : _("[whose name is lost]"));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
 
-         if (!info->shared
+         if (!bfd_link_pic (info)
              && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
            {
              /* Known contents of the GOT.  */
@@ -1936,8 +1888,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                  else
                    local_got_offsets[r_symndx] |= 1;
 
-                 if (srelgot == NULL)
-                   srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+                 srelgot = htab->root.srelgot;
                  BFD_ASSERT (srelgot != NULL);
 
                  if (h != NULL && h->dynindx != -1)
@@ -1983,7 +1934,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        case R_CRIS_32_TPREL:
          /* This relocation must only be performed against symbols
             defined in an ordinary (non-DSO) object.  */
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              bfd_set_error (bfd_error_invalid_operation);
 
@@ -1999,8 +1950,9 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                 been emitted.  */
              && h->root.type != bfd_link_hash_undefined)
            {
-             (*_bfd_error_handler)
-               (_("%B, section %A: relocation %s is"
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s is"
                   " not allowed for symbol: `%s'"
                   " which is defined outside the program,"
                   " perhaps a declaration mixup?"),
@@ -2036,7 +1988,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          switch (r)
            {
            case bfd_reloc_overflow:
-             r = info->callbacks->reloc_overflow
+             (*info->callbacks->reloc_overflow)
                (info, (h ? &h->root : NULL), symname, howto->name,
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              if (additional_relocation_error_msg_count > 0)
@@ -2052,14 +2004,14 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                         only.  */
                    case R_CRIS_16_GOT_TPREL:
                    case R_CRIS_16_GOT_GD:
-                     (*_bfd_error_handler)
+                     _bfd_error_handler
                        (_("(too many global variables for -fpic:"
                           " recompile with -fPIC)"));
                      break;
 
                    case R_CRIS_16_TPREL:
                    case R_CRIS_16_DTPREL:
-                     (*_bfd_error_handler)
+                     _bfd_error_handler
                        (_("(thread-local data too big for -fpic or"
                           " -msmall-tls: recompile with -fPIC or"
                           " -mno-small-tls)"));
@@ -2073,9 +2025,8 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              break;
 
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol
-               (info, symname, input_bfd, input_section, rel->r_offset,
-                TRUE);
+             (*info->callbacks->undefined_symbol)
+               (info, symname, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -2096,11 +2047,8 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
            }
 
          if (msg)
-           r = info->callbacks->warning
-             (info, msg, symname, input_bfd, input_section, rel->r_offset);
-
-         if (! r)
-           return FALSE;
+           (*info->callbacks->warning) (info, msg, symname, input_bfd,
+                                        input_section, rel->r_offset);
        }
     }
 
@@ -2117,7 +2065,6 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
                                Elf_Internal_Sym *sym)
 {
   struct elf_cris_link_hash_table * htab;
-  bfd *dynobj;
 
   /* Where in the plt entry to put values.  */
   int plt_off1 = 2, plt_off2 = 10, plt_off3 = 16;
@@ -2149,8 +2096,6 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
       plt_pic_entry = elf_cris_pic_plt_entry_v32;
     }
 
-  dynobj = elf_hash_table (info)->dynobj;
-
   if (h->plt.offset != (bfd_vma) -1)
     {
       asection *splt;
@@ -2193,16 +2138,16 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
 
       BFD_ASSERT (h->dynindx != -1);
 
-      splt = bfd_get_linker_section (dynobj, ".plt");
-      sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
-      srela = bfd_get_linker_section (dynobj, ".rela.plt");
+      splt = htab->root.splt;
+      sgotplt = htab->root.sgotplt;
+      srela = htab->root.srelplt;
       BFD_ASSERT (splt != NULL && sgotplt != NULL
                  && (! has_gotplt || srela != NULL));
 
       got_base = sgotplt->output_section->vma + sgotplt->output_offset;
 
       /* Fill in the entry in the procedure linkage table.  */
-      if (! info->shared)
+      if (! bfd_link_pic (info))
        {
          memcpy (splt->contents + h->plt.offset, plt_entry,
                  plt_entry_size);
@@ -2278,7 +2223,7 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
      references to the function symbol are redirected to the PLT.  */
   if (h->got.offset != (bfd_vma) -1
       && (elf_cris_hash_entry (h)->reg_got_refcount > 0)
-      && (info->shared
+      && (bfd_link_pic (info)
          || (h->dynindx != -1
              && h->plt.offset == (bfd_vma) -1
              && !h->def_regular
@@ -2292,8 +2237,8 @@ elf_cris_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 = htab->root.sgot;
+      srela = htab->root.srelgot;
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       rela.r_offset = (sgot->output_section->vma
@@ -2307,8 +2252,8 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
         initialized in the relocate_section function.  */
       where = sgot->contents + (h->got.offset &~ (bfd_vma) 1);
       if (! elf_hash_table (info)->dynamic_sections_created
-         || (info->shared
-             && (info->symbolic || h->dynindx == -1)
+         || (bfd_link_pic (info)
+             && (SYMBOLIC_BIND (info, h) || h->dynindx == -1)
              && h->def_regular))
        {
          rela.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
@@ -2338,8 +2283,10 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = bfd_get_linker_section (dynobj, ".rela.bss");
-      BFD_ASSERT (s != NULL);
+      if (h->root.u.def.section == htab->root.sdynrelro)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
 
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
@@ -2351,7 +2298,7 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+  if (h == elf_hash_table (info)->hdynamic
       || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
@@ -2363,9 +2310,8 @@ elf_cris_finish_dynamic_symbol (bfd *output_bfd,
    computed.  */
 
 static bfd_boolean
-elf_cris_finish_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+elf_cris_finish_dynamic_sections (bfd *output_bfd,
+                                 struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *sgot;
@@ -2373,7 +2319,7 @@ elf_cris_finish_dynamic_sections (output_bfd, 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");
 
@@ -2382,7 +2328,7 @@ elf_cris_finish_dynamic_sections (output_bfd, 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;
@@ -2400,42 +2346,27 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
              break;
 
            case DT_PLTGOT:
-             s = bfd_get_section_by_name (output_bfd, ".got");
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->vma;
+             dyn.d_un.d_ptr = sgot->output_section->vma + sgot->output_offset;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_JMPREL:
              /* Yes, we *can* have a .plt and no .plt.rela, for instance
                 if all symbols are found in the .got (not .got.plt).  */
-             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
-             dyn.d_un.d_ptr = s != NULL ? s->vma : 0;
+             s = elf_hash_table (info)->srelplt;
+             dyn.d_un.d_ptr = s != NULL ? (s->output_section->vma
+                                           + s->output_offset) : 0;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_PLTRELSZ:
-             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+             s = elf_hash_table (info)->srelplt;
              if (s == NULL)
                dyn.d_un.d_val = 0;
              else
                dyn.d_un.d_val = s->size;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
-
-           case DT_RELASZ:
-             /* The procedure linkage table relocs (DT_JMPREL) should
-                not be included in the overall relocs (DT_RELA).
-                Therefore, we override the DT_RELASZ entry here to
-                make it not include the JMPREL relocs.  Since the
-                linker script arranges for .rela.plt to follow all
-                other relocation sections, we don't have to worry
-                about changing the DT_RELA entry.  */
-             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
-             if (s != NULL)
-               dyn.d_un.d_val -= s->size;
-             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-             break;
            }
        }
 
@@ -2444,7 +2375,7 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
        {
          if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
            {
-             if (info->shared)
+             if (bfd_link_pic (info))
                memcpy (splt->contents, elf_cris_pic_plt0_entry_v32,
                        PLT_ENTRY_SIZE_V32);
              else
@@ -2462,7 +2393,7 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
            }
          else
            {
-             if (info->shared)
+             if (bfd_link_pic (info))
                memcpy (splt->contents, elf_cris_pic_plt0_entry,
                        PLT_ENTRY_SIZE);
              else
@@ -2481,7 +2412,7 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
                  elf_section_data (splt->output_section)->this_hdr.sh_entsize
                    = PLT_ENTRY_SIZE;
                }
-            }
+           }
        }
     }
 
@@ -2528,193 +2459,6 @@ cris_elf_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
-cris_elf_gc_sweep_hook (bfd *abfd,
-                       struct bfd_link_info *info,
-                       asection *sec,
-                       const Elf_Internal_Rela *relocs)
-{
-  struct elf_cris_link_hash_table * htab;
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  const Elf_Internal_Rela *rel, *relend;
-  bfd *dynobj;
-  asection *sgot;
-  asection *srelgot;
-
-  if (info->relocatable)
-    return TRUE;
-
-  dynobj = elf_hash_table (info)->dynobj;
-  if (dynobj == NULL)
-    return TRUE;
-
-  htab = elf_cris_hash_table (info);
-  if (htab == NULL)
-    return FALSE;
-
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
-
-  sgot = bfd_get_linker_section (dynobj, ".got");
-  srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
-    {
-      unsigned long r_symndx;
-      struct elf_link_hash_entry *h = NULL;
-      bfd_signed_vma got_element_size = 4;
-      bfd_signed_vma *specific_refcount = NULL;
-      enum elf_cris_reloc_type r_type;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-       }
-
-      r_type = ELF32_R_TYPE (rel->r_info);
-      switch (r_type)
-       {
-       case R_CRIS_32_GOT:
-       case R_CRIS_16_GOT:
-       case R_CRIS_16_GOTPLT:
-       case R_CRIS_32_GOTPLT:
-         specific_refcount = h != NULL
-           ? &((struct elf_cris_link_hash_entry *) h)->reg_got_refcount
-           : &local_got_refcounts[LGOT_REG_NDX (r_symndx)];
-         break;
-
-       case R_CRIS_32_GD:
-       case R_CRIS_32_GOT_GD:
-       case R_CRIS_16_GOT_GD:
-         got_element_size = 8;
-         specific_refcount = h != NULL
-           ? &((struct elf_cris_link_hash_entry *) h)->dtp_refcount
-           : &local_got_refcounts[LGOT_DTP_NDX (r_symndx)];
-         break;
-
-       case R_CRIS_32_IE:
-       case R_CRIS_16_GOT_TPREL:
-       case R_CRIS_32_GOT_TPREL:
-         specific_refcount = h != NULL
-           ? &((struct elf_cris_link_hash_entry *) h)->tprel_refcount
-           : &local_got_refcounts[LGOT_TPREL_NDX (r_symndx)];
-         break;
-
-       default:
-         break;
-       }
-
-      switch (r_type)
-       {
-       case R_CRIS_32_IE:
-       case R_CRIS_32_GD:
-       case R_CRIS_16_GOT_TPREL:
-       case R_CRIS_32_GOT_TPREL:
-       case R_CRIS_32_GOT_GD:
-       case R_CRIS_16_GOT_GD:
-       case R_CRIS_16_GOT:
-       case R_CRIS_32_GOT:
-         if (h != NULL)
-           {
-             /* If the counters are 0 when we got here, we've
-                miscounted somehow somewhere, an internal error.  */
-             BFD_ASSERT (h->got.refcount > 0);
-             --h->got.refcount;
-
-             BFD_ASSERT (*specific_refcount > 0);
-             --*specific_refcount;
-             if (*specific_refcount == 0)
-               {
-                 /* We don't need the .got entry any more.  */
-                 sgot->size -= got_element_size;
-                 srelgot->size -= sizeof (Elf32_External_Rela);
-               }
-             break;
-           }
-
-       local_got_reloc:
-         if (local_got_refcounts != NULL)
-           {
-             /* If the counters are 0 when we got here, we've
-                miscounted somehow somewhere, an internal error.  */
-             BFD_ASSERT (local_got_refcounts[r_symndx] > 0);
-             --local_got_refcounts[r_symndx];
-
-             BFD_ASSERT (*specific_refcount > 0);
-             --*specific_refcount;
-             if (*specific_refcount == 0)
-               {
-                 /* We don't need the .got entry any more.  */
-                 sgot->size -= got_element_size;
-                 if (info->shared)
-                   srelgot->size -= sizeof (Elf32_External_Rela);
-               }
-           }
-         break;
-
-       case R_CRIS_16_GOTPLT:
-       case R_CRIS_32_GOTPLT:
-         /* For local symbols, treat these like GOT relocs.  */
-         if (h == NULL)
-           goto local_got_reloc;
-         else
-           /* For global symbols, adjust the reloc-specific refcount.  */
-           elf_cris_hash_entry (h)->gotplt_refcount--;
-         /* Fall through.  */
-
-       case R_CRIS_32_PLT_GOTREL:
-         /* FIXME: We don't garbage-collect away the .got section.  */
-         if (local_got_refcounts != NULL)
-           local_got_refcounts[-1]--;
-         /* Fall through.  */
-
-       case R_CRIS_8:
-       case R_CRIS_16:
-       case R_CRIS_32:
-       case R_CRIS_8_PCREL:
-       case R_CRIS_16_PCREL:
-       case R_CRIS_32_PCREL:
-       case R_CRIS_32_PLT_PCREL:
-         /* Negate the increment we did in cris_elf_check_relocs.  */
-         if (h != NULL)
-           {
-             if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                 && h->plt.refcount > 0)
-               --h->plt.refcount;
-           }
-         break;
-
-       case R_CRIS_32_DTPREL:
-         /* This'd be a .dtpreld entry in e.g. debug info.  */
-         if ((sec->flags & SEC_ALLOC) == 0)
-           break;
-         /* Fall through.  */
-       case R_CRIS_16_DTPREL:
-         htab->dtpmod_refcount--;
-         if (htab->dtpmod_refcount == 0)
-           htab->next_gotplt_entry -= 8;
-         BFD_ASSERT (local_got_refcounts != NULL);
-         local_got_refcounts[-1]--;
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return TRUE;
-}
-
 /* The elf_backend_plt_sym_val hook function.  */
 
 static bfd_vma
@@ -2736,7 +2480,7 @@ cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
   if ((got = bfd_get_section_by_name (abfd, ".got")) == NULL)
     return (bfd_vma) -1;
 
-  plt_sec_size =  bfd_section_size (plt->owner, plt);
+  plt_sec_size =  bfd_section_size (plt);
   plt_entry_size
     = (bfd_get_mach (abfd) == bfd_mach_cris_v32
        ? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
@@ -2762,7 +2506,7 @@ cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
     {
       bfd_size_type got_offset;
       bfd_byte gotoffs_raw[4];
-      
+
       if (!bfd_get_section_contents (abfd, (asection *) plt, gotoffs_raw,
                                     pltoffs + plt_entry_got_offset,
                                     sizeof (gotoffs_raw)))
@@ -2786,15 +2530,14 @@ cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
    created (we're only linking static objects).  */
 
 static bfd_boolean
-elf_cris_adjust_gotplt_to_got (h, p)
-     struct elf_cris_link_hash_entry *h;
-     PTR p;
+elf_cris_adjust_gotplt_to_got (struct elf_cris_link_hash_entry *h, void * p)
 {
   struct bfd_link_info *info = (struct bfd_link_info *) p;
 
   /* A GOTPLT reloc, when activated, is supposed to be included into
-     the PLT refcount.  */
+     the PLT refcount, when the symbol isn't set-or-forced local.  */
   BFD_ASSERT (h->gotplt_refcount == 0
+             || h->root.plt.refcount == -1
              || h->gotplt_refcount <= h->root.plt.refcount);
 
   /* If nobody wanted a GOTPLT with this symbol, we're done.  */
@@ -2813,15 +2556,14 @@ elf_cris_adjust_gotplt_to_got (h, p)
   else
     {
       /* No GOT entry for this symbol.  We need to create one.  */
-      bfd *dynobj = elf_hash_table (info)->dynobj;
       asection *sgot;
       asection *srelgot;
 
-      BFD_ASSERT (dynobj != NULL);
-      sgot = bfd_get_linker_section (dynobj, ".got");
-      srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+      sgot = elf_hash_table (info)->sgot;
+      srelgot = elf_hash_table (info)->srelgot;
 
       /* Put accurate refcounts there.  */
+      BFD_ASSERT (h->root.got.refcount >= 0);
       h->root.got.refcount += h->gotplt_refcount;
       h->reg_got_refcount = h->gotplt_refcount;
 
@@ -2866,9 +2608,7 @@ elf_cris_adjust_gotplt_to_got (h, p)
    elf_cris_hide_symbol.  */
 
 static bfd_boolean
-elf_cris_try_fold_plt_to_got (h, p)
-     struct elf_cris_link_hash_entry *h;
-     PTR p;
+elf_cris_try_fold_plt_to_got (struct elf_cris_link_hash_entry *h, void * p)
 {
   struct bfd_link_info *info = (struct bfd_link_info *) p;
 
@@ -2900,10 +2640,9 @@ elf_cris_try_fold_plt_to_got (h, p)
    entry.  */
 
 static void
-elf_cris_hide_symbol (info, h, force_local)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
-     bfd_boolean force_local;
+elf_cris_hide_symbol (struct bfd_link_info *info,
+                     struct elf_link_hash_entry *h,
+                     bfd_boolean force_local)
 {
   elf_cris_adjust_gotplt_to_got ((struct elf_cris_link_hash_entry *) h, info);
 
@@ -2923,18 +2662,19 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct elf_cris_link_hash_table * htab;
   bfd *dynobj;
   asection *s;
+  asection *srel;
   bfd_size_type plt_entry_size;
 
   htab = elf_cris_hash_table (info);
   if (htab == NULL)
     return FALSE;
 
-  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)));
@@ -2955,7 +2695,7 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
         result as one built without -fpic, specifically considering weak
         symbols.
         FIXME: m68k and i386 differ here, for unclear reasons.  */
-      if (! info->shared
+      if (! bfd_link_pic (info)
          && !h->def_dynamic)
        {
          /* This case can occur if we saw a PLT reloc in an input file,
@@ -2977,7 +2717,7 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
         like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
         of the PLT.  We can't for the executable, because the GOT
         entries will point to the PLT there (and be constant).  */
-      if (info->shared
+      if (bfd_link_pic (info)
          && !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
                                            h, info))
        return FALSE;
@@ -2997,7 +2737,7 @@ elf_cris_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
@@ -3008,7 +2748,7 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
       /* If this symbol is not defined in a regular file, and we are
         not generating a shared library, then set the symbol to this
         location in the .plt.  */
-      if (!info->shared
+      if (!bfd_link_pic (info)
          && !h->def_regular)
        {
          h->root.u.def.section = s;
@@ -3021,7 +2761,7 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
         executable, because then the reloc associated with the PLT
         would get a non-PLT reloc pointing to the PLT.  FIXME: Move
         this to elf_cris_try_fold_plt_to_got.  */
-      if (info->shared && h->got.refcount > 0)
+      if (bfd_link_pic (info) && h->got.refcount > 0)
        {
          h->got.refcount += h->plt.refcount;
 
@@ -3056,13 +2796,13 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
        = htab->next_gotplt_entry;
       htab->next_gotplt_entry += 4;
 
-      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);
 
@@ -3076,12 +2816,12 @@ elf_cris_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;
     }
 
@@ -3092,7 +2832,7 @@ elf_cris_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
@@ -3110,24 +2850,31 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
-  s = bfd_get_linker_section (dynobj, ".dynbss");
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_CRIS_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
+
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      asection *srel;
-
-      srel = bfd_get_linker_section (dynobj, ".rela.bss");
       BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  BFD_ASSERT (s != NULL);
+
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Adjust our "subclass" elements for an indirect symbol.  */
@@ -3212,7 +2959,7 @@ cris_elf_check_relocs (bfd *abfd,
   asection *srelgot;
   asection *sreloc;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   htab = elf_cris_hash_table (info);
@@ -3298,21 +3045,28 @@ cris_elf_check_relocs (bfd *abfd,
                 that, we must insist on dynobj being a specific mach.  */
              if (bfd_get_mach (dynobj) == bfd_mach_cris_v10_v32)
                {
-                 (*_bfd_error_handler)
-                   (_("%B, section %A:\n  v10/v32 compatible object %s"
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB, section %pA: v10/v32 compatible object"
                       " must not contain a PIC relocation"),
                     abfd, sec);
                  return FALSE;
                }
+           }
 
-             /* Create the .got section, so we can assume it's always
-                present whenever there's a dynobj.  */
+         if (sgot == NULL)
+           {
+             /* We may have a dynobj but no .got section, if machine-
+                independent parts of the linker found a reason to create
+                a dynobj.  We want to create the .got section now, so we
+                can assume it's always present whenever there's a dynobj.
+                It's ok to call this function more than once.  */
              if (!_bfd_elf_create_got_section (dynobj, info))
                return FALSE;
-           }
 
-         if (sgot == NULL)
-           sgot = bfd_get_linker_section (dynobj, ".got");
+             sgot = elf_hash_table (info)->sgot;
+             srelgot = elf_hash_table (info)->srelgot;
+           }
 
          if (local_got_refcounts == NULL)
            {
@@ -3336,62 +3090,6 @@ cris_elf_check_relocs (bfd *abfd,
          break;
        }
 
-      /* Some relocs require a global offset table (but perhaps not a
-        specific GOT entry).  */
-      switch (r_type)
-       {
-       case R_CRIS_16_DTPREL:
-       case R_CRIS_32_DTPREL:
-         /* Not requesting .got.rela for an executable: the contents
-            of the first entry is constant there.  For a shared
-            library, we need .got.rela for the R_CRIS_DTPMOD
-            relocation at index 3.  */
-         if (!info->shared)
-           break;
-         /* Fall through.  */
-
-       case R_CRIS_32_IE:
-       case R_CRIS_32_GD:
-       case R_CRIS_16_GOT_GD:
-       case R_CRIS_32_GOT_GD:
-       case R_CRIS_32_GOT_TPREL:
-       case R_CRIS_16_GOT_TPREL:
-         /* Fall through.  */
-
-         /* For R_CRIS_16_GOTPLT and R_CRIS_32_GOTPLT, we need a GOT
-            entry only for local symbols.  Unfortunately, we don't know
-            until later on if there's a version script that forces the
-            symbol local.  We must have the .rela.got section in place
-            before we know if the symbol looks global now, so we need
-            to treat the reloc just like for R_CRIS_16_GOT and
-            R_CRIS_32_GOT.  */
-       case R_CRIS_16_GOTPLT:
-       case R_CRIS_32_GOTPLT:
-       case R_CRIS_16_GOT:
-       case R_CRIS_32_GOT:
-         if (srelgot == NULL
-             && (h != NULL || info->shared))
-           {
-             srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-             if (srelgot == NULL)
-               {
-                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                   | SEC_READONLY);
-                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
-                                                               ".rela.got",
-                                                               flags);
-                 if (srelgot == NULL
-                     || !bfd_set_section_alignment (dynobj, srelgot, 2))
-                   return FALSE;
-               }
-           }
-         break;
-
-       default:
-         break;
-       }
-
       /* Warn and error for invalid input.  */
       switch (r_type)
        {
@@ -3399,10 +3097,11 @@ cris_elf_check_relocs (bfd *abfd,
        case R_CRIS_32_TPREL:
        case R_CRIS_16_TPREL:
        case R_CRIS_32_GD:
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
-             (*_bfd_error_handler)
-               (_("%B, section %A:\n  relocation %s not valid"
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA:\n  relocation %s not valid"
                   " in a shared object;"
                   " typically an option mixup, recompile with -fPIC"),
                 abfd,
@@ -3441,7 +3140,7 @@ cris_elf_check_relocs (bfd *abfd,
          /* Those relocs also require that a DSO is of type
             Initial Exec.  Like other targets, we don't reset this
             flag even if the relocs are GC:ed away.  */
-         if (info->shared)
+         if (bfd_link_pic (info))
            info->flags |= DF_STATIC_TLS;
          break;
 
@@ -3454,7 +3153,7 @@ cris_elf_check_relocs (bfd *abfd,
        }
 
       switch (r_type)
-        {
+       {
        case R_CRIS_16_GOTPLT:
        case R_CRIS_32_GOTPLT:
          /* Mark that we need a GOT entry if the PLT entry (and its GOT
@@ -3544,7 +3243,7 @@ cris_elf_check_relocs (bfd *abfd,
              if (local_got_refcounts[r_symndx_lgot] == 0)
                {
                  sgot->size += got_element_size;
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    {
                      /* If we are generating a shared object, we need
                         to output a R_CRIS_RELATIVE reloc so that the
@@ -3581,10 +3280,10 @@ cris_elf_check_relocs (bfd *abfd,
        case R_CRIS_32_PLT_PCREL:
          /* This symbol requires a procedure linkage table entry.  We
             actually build the entry in adjust_dynamic_symbol,
-             because this might be a case of linking PIC code which is
-             never referenced by a dynamic object, in which case we
-             don't need to generate a procedure linkage table entry
-             after all.  */
+            because this might be a case of linking PIC code which is
+            never referenced by a dynamic object, in which case we
+            don't need to generate a procedure linkage table entry
+            after all.  */
 
          /* Beware: if we'd check for visibility of the symbol here
             (and not marking the need for a PLT when non-visible), we'd
@@ -3596,7 +3295,10 @@ cris_elf_check_relocs (bfd *abfd,
            continue;
 
          h->needs_plt = 1;
-         h->plt.refcount++;
+
+         /* If the symbol is forced local, the refcount is unavailable.  */
+         if (h->plt.refcount != -1)
+           h->plt.refcount++;
          break;
 
        case R_CRIS_8:
@@ -3610,13 +3312,14 @@ cris_elf_check_relocs (bfd *abfd,
             can't help tables of (global) function pointers, for
             example, though they must be emitted in a (writable) data
             section to avoid having impure text sections.  */
-         if (info->shared
+         if (bfd_link_pic (info)
              && (sec->flags & SEC_ALLOC) != 0
              && (sec->flags & SEC_READONLY) != 0)
            {
              /* FIXME: How do we make this optionally a warning only?  */
-             (*_bfd_error_handler)
-               (_("%B, section %A:\n  relocation %s should not"
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB, section %pA: relocation %s should not"
                   " be used in a shared object; recompile with -fPIC"),
                 abfd,
                 sec,
@@ -3654,7 +3357,8 @@ cris_elf_check_relocs (bfd *abfd,
             render the symbol local.  */
 
          /* No need to do anything if we're not creating a shared object.  */
-         if (! info->shared)
+         if (! bfd_link_pic (info)
+             || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
            break;
 
          /* We may need to create a reloc section in the dynobj and made room
@@ -3703,7 +3407,7 @@ cris_elf_check_relocs (bfd *abfd,
             render the symbol local.  */
 
          /* No need to do anything if we're not creating a shared object.  */
-         if (! info->shared)
+         if (! bfd_link_pic (info))
            break;
 
          /* We don't need to handle relocs into sections not going into
@@ -3721,7 +3425,7 @@ cris_elf_check_relocs (bfd *abfd,
             this shared library) then we can also eliminate the
             reloc.  See comment above for more eliminable cases which
             we can't identify at this time.  */
-         if (info->symbolic
+         if (SYMBOLIC_BIND (info, h)
              && h->root.type != bfd_link_hash_defweak
              && h->def_regular)
            break;
@@ -3771,21 +3475,19 @@ cris_elf_check_relocs (bfd *abfd,
          }
          break;
 
-        /* This relocation describes the C++ object vtable hierarchy.
-           Reconstruct it for later use during GC.  */
-        case R_CRIS_GNU_VTINHERIT:
-          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-            return FALSE;
-          break;
-
-        /* This relocation describes which C++ vtable entries are actually
-           used.  Record for later use during GC.  */
-        case R_CRIS_GNU_VTENTRY:
-          BFD_ASSERT (h != NULL);
-          if (h != NULL
-              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-            return FALSE;
-          break;
+       /* This relocation describes the C++ object vtable hierarchy.
+          Reconstruct it for later use during GC.  */
+       case R_CRIS_GNU_VTINHERIT:
+         if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+           return FALSE;
+         break;
+
+       /* This relocation describes which C++ vtable entries are actually
+          used.  Record for later use during GC.  */
+       case R_CRIS_GNU_VTENTRY:
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+           return FALSE;
+         break;
 
        case R_CRIS_16_TPREL:
        case R_CRIS_32_TPREL:
@@ -3796,7 +3498,7 @@ cris_elf_check_relocs (bfd *abfd,
          /* Other relocs do not appear here.  */
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
-        }
+       }
     }
 
   return TRUE;
@@ -3818,13 +3520,13 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab == NULL)
     return FALSE;
 
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.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);
@@ -3843,7 +3545,7 @@ elf_cris_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 = htab->root.srelgot;
       if (s != NULL)
        s->size = 0;
     }
@@ -3855,7 +3557,7 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      for relocs that have become for local symbols due to symbol
      visibility changes.  For programs, we discard space for relocs for
      symbols not referenced by any dynamic object.  */
-  if (info->shared)
+  if (bfd_link_pic (info))
     elf_cris_link_hash_traverse (htab,
                                 elf_cris_discard_excess_dso_dynamics,
                                 info);
@@ -3878,7 +3580,7 @@ elf_cris_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)
        {
@@ -3897,13 +3599,13 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
          if (strcmp (name, ".rela.got") == 0
              && htab->dtpmod_refcount != 0
-             && info->shared)
+             && bfd_link_pic (info))
            s->size += sizeof (Elf32_External_Rela);
 
          if (s->size != 0)
            {
              /* Remember whether there are any reloc sections other
-                 than .rela.plt.  */
+                than .rela.plt.  */
              if (strcmp (name, ".rela.plt") != 0)
                  relocs = TRUE;
 
@@ -3913,7 +3615,8 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            }
        }
       else if (! CONST_STRNEQ (name, ".got")
-              && strcmp (name, ".dynbss") != 0)
+              && strcmp (name, ".dynbss") != 0
+              && s != htab->root.sdynrelro)
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
@@ -3957,7 +3660,7 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-      if (!info->shared)
+      if (!bfd_link_pic (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
@@ -4002,9 +3705,8 @@ elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
    relocate_section routine.  */
 
 static bfd_boolean
-elf_cris_discard_excess_dso_dynamics (h, inf)
-     struct elf_cris_link_hash_entry *h;
-     PTR inf;
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *h,
+                                     void * inf)
 {
   struct elf_cris_pcrel_relocs_copied *s;
   struct bfd_link_info *info = (struct bfd_link_info *) inf;
@@ -4014,7 +3716,7 @@ elf_cris_discard_excess_dso_dynamics (h, inf)
      any relocs.  */
   if (h->root.def_regular
       && (h->root.forced_local
-         || info->symbolic))
+         || SYMBOLIC_BIND (info, &h->root)))
     {
       for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
        {
@@ -4038,9 +3740,10 @@ elf_cris_discard_excess_dso_dynamics (h, inf)
     if ((s->section->flags & SEC_READONLY) != 0)
       {
        /* FIXME: How do we make this optionally a warning only?  */
-       (*_bfd_error_handler)
-         (_("%B, section `%A', to symbol `%s':\n"
-            "  relocation %s should not be used"
+       _bfd_error_handler
+         /* xgettext:c-format */
+         (_("%pB, section `%pA', to symbol `%s':"
+            " relocation %s should not be used"
             " in a shared object; recompile with -fPIC"),
           s->section->owner,
           s->section,
@@ -4058,9 +3761,8 @@ elf_cris_discard_excess_dso_dynamics (h, inf)
    in the .got, but which we found we do not have to resolve at run-time.  */
 
 static bfd_boolean
-elf_cris_discard_excess_program_dynamics (h, inf)
-     struct elf_cris_link_hash_entry *h;
-     PTR inf;
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *h,
+                                         void * inf)
 {
   struct bfd_link_info *info = (struct bfd_link_info *) inf;
 
@@ -4079,12 +3781,9 @@ elf_cris_discard_excess_program_dynamics (h, inf)
          && elf_hash_table (info)->dynamic_sections_created)
        {
          bfd *dynobj = elf_hash_table (info)->dynobj;
-         asection *srelgot;
+         asection *srelgot = elf_hash_table (info)->srelgot;
 
          BFD_ASSERT (dynobj != NULL);
-
-         srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-
          BFD_ASSERT (srelgot != NULL);
 
          srelgot->size -= sizeof (Elf32_External_Rela);
@@ -4094,9 +3793,12 @@ elf_cris_discard_excess_program_dynamics (h, inf)
         have to export it as a dynamic symbol.  This was already done for
         functions; doing this for all symbols would presumably not
         introduce new problems.  Of course we don't do this if we're
-        exporting all dynamic symbols.  */
-      if (! info->export_dynamic
+        exporting all dynamic symbols, or all data symbols, regardless of
+        them being referenced or not.  */
+      if (! (info->export_dynamic
+            || (h->root.type != STT_FUNC && info->dynamic_data))
          && h->root.dynindx != -1
+         && !h->root.dynamic
          && !h->root.def_dynamic
          && !h->root.ref_dynamic)
        {
@@ -4113,8 +3815,7 @@ elf_cris_discard_excess_program_dynamics (h, inf)
    underscores on symbols.  */
 
 static bfd_boolean
-cris_elf_object_p (abfd)
-     bfd *abfd;
+cris_elf_object_p (bfd *abfd)
 {
   if (! cris_elf_set_mach_from_flags (abfd, elf_elfheader (abfd)->e_flags))
     return FALSE;
@@ -4128,10 +3829,8 @@ cris_elf_object_p (abfd)
 /* Mark presence or absence of leading underscore.  Set machine type
    flags from mach type.  */
 
-static void
-cris_elf_final_write_processing (abfd, linker)
-     bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
+static bfd_boolean
+cris_elf_final_write_processing (bfd *abfd)
 {
   unsigned long e_flags = elf_elfheader (abfd)->e_flags;
 
@@ -4155,18 +3854,18 @@ cris_elf_final_write_processing (abfd, linker)
 
     default:
       _bfd_abort (__FILE__, __LINE__,
-                 _("Unexpected machine number"));
+                 _("unexpected machine number"));
     }
 
   elf_elfheader (abfd)->e_flags = e_flags;
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Set the mach type from e_flags value.  */
 
 static bfd_boolean
-cris_elf_set_mach_from_flags (abfd, flags)
-     bfd *abfd;
-     unsigned long flags;
+cris_elf_set_mach_from_flags (bfd *abfd,
+                             unsigned long flags)
 {
   switch (flags & EF_CRIS_VARIANT_MASK)
     {
@@ -4196,9 +3895,7 @@ cris_elf_set_mach_from_flags (abfd, flags)
 /* Display the flags field.  */
 
 static bfd_boolean
-cris_elf_print_private_bfd_data (abfd, ptr)
-     bfd *abfd;
-     PTR ptr;
+cris_elf_print_private_bfd_data (bfd *abfd, void * ptr)
 {
   FILE *file = (FILE *) ptr;
 
@@ -4224,13 +3921,12 @@ cris_elf_print_private_bfd_data (abfd, ptr)
 /* Don't mix files with and without a leading underscore.  */
 
 static bfd_boolean
-cris_elf_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+cris_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   int imach, omach;
 
-  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+  if (! _bfd_generic_verify_endian_match (ibfd, info))
     return FALSE;
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
@@ -4258,10 +3954,10 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
   if (bfd_get_symbol_leading_char (ibfd)
       != bfd_get_symbol_leading_char (obfd))
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (bfd_get_symbol_leading_char (ibfd) == '_'
-        ? _("%B: uses _-prefixed symbols, but writing file with non-prefixed symbols")
-        : _("%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
+        ? _("%pB: uses _-prefixed symbols, but writing file with non-prefixed symbols")
+        : _("%pB: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
         ibfd);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
@@ -4278,11 +3974,11 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
          || (omach == bfd_mach_cris_v32
              && imach != bfd_mach_cris_v10_v32))
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
            ((imach == bfd_mach_cris_v32)
-            ? _("%B contains CRIS v32 code, incompatible"
+            ? _("%pB contains CRIS v32 code, incompatible"
                 " with previous objects")
-            : _("%B contains non-CRIS-v32 code, incompatible"
+            : _("%pB contains non-CRIS-v32 code, incompatible"
                 " with previous objects"),
             ibfd);
          bfd_set_error (bfd_error_bad_value);
@@ -4303,29 +3999,24 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
 /* Do side-effects of e_flags copying to obfd.  */
 
 static bfd_boolean
-cris_elf_copy_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+cris_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
-  /* Call the base function.  */
-  if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
-    return FALSE;
-
-  /* If output is big-endian for some obscure reason, stop here.  */
-  if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
-    return FALSE;
-
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
+  /* Call the base function.  */
+  if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
+    return FALSE;
+
   /* Do what we really came here for.  */
   return bfd_set_arch_mach (obfd, bfd_arch_cris, bfd_get_mach (ibfd));
 }
 
 static enum elf_reloc_type_class
-elf_cris_reloc_type_class (rela)
-     const Elf_Internal_Rela *rela;
+elf_cris_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                          const asection *rel_sec ATTRIBUTE_UNUSED,
+                          const Elf_Internal_Rela *rela)
 {
   enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rela->r_info);
   switch (r_type)
@@ -4408,7 +4099,7 @@ elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
 #define ELF_MACHINE_CODE       EM_CRIS
 #define ELF_MAXPAGESIZE                0x2000
 
-#define TARGET_LITTLE_SYM      bfd_elf32_cris_vec
+#define TARGET_LITTLE_SYM      cris_elf32_vec
 #define TARGET_LITTLE_NAME     "elf32-cris"
 #define elf_symbol_leading_char 0
 
@@ -4416,9 +4107,8 @@ elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_info_to_howto                      cris_info_to_howto_rela
 #define elf_backend_relocate_section           cris_elf_relocate_section
 #define elf_backend_gc_mark_hook               cris_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook              cris_elf_gc_sweep_hook
 #define elf_backend_plt_sym_val                        cris_elf_plt_sym_val
-#define elf_backend_check_relocs                cris_elf_check_relocs
+#define elf_backend_check_relocs               cris_elf_check_relocs
 #define elf_backend_grok_prstatus              cris_elf_grok_prstatus
 #define elf_backend_grok_psinfo                        cris_elf_grok_psinfo
 
@@ -4463,6 +4153,8 @@ elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
 #define elf_backend_got_elt_size elf_cris_got_elt_size
+#define elf_backend_dtrel_excludes_plt 1
+#define elf_backend_want_dynrelro      1
 
 /* Later, we my want to optimize RELA entries into REL entries for dynamic
    linking and libraries (if it's a win of any significance).  Until then,
@@ -4471,13 +4163,15 @@ elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_backend_may_use_rela_p 1
 #define elf_backend_rela_normal                1
 
+#define elf_backend_linux_prpsinfo32_ugid16    TRUE
+
 #include "elf32-target.h"
 
 #undef TARGET_LITTLE_SYM
 #undef TARGET_LITTLE_NAME
 #undef elf_symbol_leading_char
 
-#define TARGET_LITTLE_SYM bfd_elf32_us_cris_vec
+#define TARGET_LITTLE_SYM cris_elf32_us_vec
 #define TARGET_LITTLE_NAME "elf32-us-cris"
 #define elf_symbol_leading_char '_'
 #undef elf32_bed
This page took 0.072636 seconds and 4 git commands to generate.