Make bfd.link_next field a union
[deliverable/binutils-gdb.git] / bfd / elf32-xtensa.c
index 09e81ad82eeba1bead1d51cb23d043f7558b3cf3..09862e3c2ca876ca23ebcc3a405788819763f837 100644 (file)
@@ -1,5 +1,5 @@
 /* Xtensa-specific support for 32-bit ELF.
-   Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -154,6 +154,10 @@ static bfd_boolean relaxing_section = FALSE;
 
 int elf32xtensa_no_literal_movement = 1;
 
+/* Rename one of the generic section flags to better document how it
+   is used here.  */
+/* Whether relocations have been processed.  */
+#define reloc_done sec_flg0
 \f
 static reloc_howto_type elf_howto_table[] =
 {
@@ -218,11 +222,11 @@ static reloc_howto_type elf_howto_table[] =
         FALSE, 0, 0, FALSE),
 
   /* Relocations for supporting difference of symbols.  */
-  HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
+  HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
         bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE),
-  HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+  HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
         bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE),
-  HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+  HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
         bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE),
 
   /* General immediate operand relocations.  */
@@ -571,13 +575,13 @@ struct elf_xtensa_obj_tdata
 #define is_xtensa_elf(bfd) \
   (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
    && elf_tdata (bfd) != NULL \
-   && elf_object_id (bfd) == XTENSA_ELF_TDATA)
+   && elf_object_id (bfd) == XTENSA_ELF_DATA)
 
 static bfd_boolean
 elf_xtensa_mkobject (bfd *abfd)
 {
   return bfd_elf_allocate_object (abfd, sizeof (struct elf_xtensa_obj_tdata),
-                                 XTENSA_ELF_TDATA);
+                                 XTENSA_ELF_DATA);
 }
 
 /* Xtensa ELF linker hash table.  */
@@ -609,7 +613,8 @@ struct elf_xtensa_link_hash_table
 /* Get the Xtensa ELF linker hash table from a link_info structure.  */
 
 #define elf_xtensa_hash_table(p) \
-  ((struct elf_xtensa_link_hash_table *) ((p)->hash))
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == XTENSA_ELF_DATA ? ((struct elf_xtensa_link_hash_table *) ((p)->hash)) : NULL)
 
 /* Create an entry in an Xtensa ELF linker hash table.  */
 
@@ -649,28 +654,19 @@ elf_xtensa_link_hash_table_create (bfd *abfd)
   struct elf_xtensa_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf_xtensa_link_hash_table);
 
-  ret = bfd_malloc (amt);
+  ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
                                      elf_xtensa_link_hash_newfunc,
-                                     sizeof (struct elf_xtensa_link_hash_entry)))
+                                     sizeof (struct elf_xtensa_link_hash_entry),
+                                     XTENSA_ELF_DATA))
     {
       free (ret);
       return NULL;
     }
 
-  ret->sgot = NULL;
-  ret->sgotplt = NULL;
-  ret->srelgot = NULL;
-  ret->splt = NULL;
-  ret->srelplt = NULL;
-  ret->sgotloc = NULL;
-  ret->spltlittbl = NULL;
-
-  ret->plt_reloc_count = 0;
-
   /* Create a hash entry for "_TLS_MODULE_BASE_" to speed up checking
      for it later.  */
   tlsbase = elf_link_hash_lookup (&ret->elf, "_TLS_MODULE_BASE_",
@@ -745,7 +741,7 @@ property_table_compare (const void *ap, const void *bp)
              != GET_XTENSA_PROP_ALIGNMENT (b->flags)))
        return (GET_XTENSA_PROP_ALIGNMENT (a->flags)
                - GET_XTENSA_PROP_ALIGNMENT (b->flags));
-      
+
       if ((a->flags & XTENSA_PROP_UNREACHABLE)
          != (b->flags & XTENSA_PROP_UNREACHABLE))
        return ((b->flags & XTENSA_PROP_UNREACHABLE)
@@ -807,7 +803,7 @@ xtensa_read_table_entries (bfd *abfd,
   if (table_section)
     table_size = table_section->size;
 
-  if (table_size == 0) 
+  if (table_size == 0)
     {
       *table_p = NULL;
       return 0;
@@ -842,7 +838,7 @@ xtensa_read_table_entries (bfd *abfd,
   section_limit = bfd_get_section_limit (abfd, section);
   rel_end = internal_relocs + table_section->reloc_count;
 
-  for (off = 0; off < table_size; off += table_entry_size) 
+  for (off = 0; off < table_size; off += table_entry_size)
     {
       bfd_vma address = bfd_get_32 (abfd, table_data + off);
 
@@ -976,6 +972,9 @@ elf_xtensa_check_relocs (bfd *abfd,
   BFD_ASSERT (is_xtensa_elf (abfd));
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -1007,6 +1006,10 @@ elf_xtensa_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;
        }
       eh = elf_xtensa_hash_entry (h);
 
@@ -1277,6 +1280,8 @@ elf_xtensa_gc_sweep_hook (bfd *abfd,
   struct elf_xtensa_link_hash_table *htab;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   if (info->relocatable)
     return TRUE;
@@ -1396,14 +1401,17 @@ elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   flagword flags, noalloc_flags;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   /* First do all the standard stuff.  */
   if (! _bfd_elf_create_dynamic_sections (dynobj, info))
     return FALSE;
-  htab->splt = bfd_get_section_by_name (dynobj, ".plt");
-  htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
-  htab->sgot = bfd_get_section_by_name (dynobj, ".got");
-  htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+  htab->splt = bfd_get_linker_section (dynobj, ".plt");
+  htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+  htab->sgot = bfd_get_linker_section (dynobj, ".got");
+  htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+  htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
 
   /* Create any extra PLT sections in case check_relocs has already
      been called on all the non-dynamic input files.  */
@@ -1419,21 +1427,16 @@ elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
       || ! bfd_set_section_flags (dynobj, htab->sgotplt, flags))
     return FALSE;
 
-  /* Create ".rela.got".  */
-  htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got", flags);
-  if (htab->srelgot == NULL
-      || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
-    return FALSE;
-
   /* Create ".got.loc" (literal tables for use by dynamic linker).  */
-  htab->sgotloc = bfd_make_section_with_flags (dynobj, ".got.loc", flags);
+  htab->sgotloc = bfd_make_section_anyway_with_flags (dynobj, ".got.loc",
+                                                     flags);
   if (htab->sgotloc == NULL
       || ! bfd_set_section_alignment (dynobj, htab->sgotloc, 2))
     return FALSE;
 
   /* Create ".xt.lit.plt" (literal table for ".got.plt*").  */
-  htab->spltlittbl = bfd_make_section_with_flags (dynobj, ".xt.lit.plt",
-                                                 noalloc_flags);
+  htab->spltlittbl = bfd_make_section_anyway_with_flags (dynobj, ".xt.lit.plt",
+                                                        noalloc_flags);
   if (htab->spltlittbl == NULL
       || ! bfd_set_section_alignment (dynobj, htab->spltlittbl, 2))
     return FALSE;
@@ -1465,14 +1468,14 @@ add_extra_plt_sections (struct bfd_link_info *info, int count)
 
       sname = (char *) bfd_malloc (10);
       sprintf (sname, ".plt.%u", chunk);
-      s = bfd_make_section_with_flags (dynobj, sname, flags | SEC_CODE);
+      s = bfd_make_section_anyway_with_flags (dynobj, sname, flags | SEC_CODE);
       if (s == NULL
          || ! bfd_set_section_alignment (dynobj, s, 2))
        return FALSE;
 
       sname = (char *) bfd_malloc (14);
       sprintf (sname, ".got.plt.%u", chunk);
-      s = bfd_make_section_with_flags (dynobj, sname, flags);
+      s = bfd_make_section_anyway_with_flags (dynobj, sname, flags);
       if (s == NULL
          || ! bfd_set_section_alignment (dynobj, s, 2))
        return FALSE;
@@ -1522,11 +1525,10 @@ elf_xtensa_allocate_dynrelocs (struct elf_link_hash_entry *h, void *arg)
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   info = (struct bfd_link_info *) arg;
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   /* If we saw any use of an IE model for this symbol, we can then optimize
      away GOT entries for any TLSDESC_FN relocs.  */
@@ -1556,8 +1558,10 @@ elf_xtensa_allocate_local_got_size (struct bfd_link_info *info)
   bfd *i;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return;
 
-  for (i = info->input_bfds; i; i = i->link_next)
+  for (i = info->input_bfds; i; i = i->link.next)
     {
       bfd_signed_vma *local_got_refcounts;
       bfd_size_type j, cnt;
@@ -1606,6 +1610,9 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   plt_chunks = 0;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = elf_hash_table (info)->dynobj;
   if (dynobj == NULL)
     abort ();
@@ -1623,7 +1630,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       /* Set the contents of the .interp section to the interpreter.  */
       if (info->executable)
        {
-         s = bfd_get_section_by_name (dynobj, ".interp");
+         s = bfd_get_linker_section (dynobj, ".interp");
          if (s == NULL)
            abort ();
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
@@ -1693,13 +1700,13 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         literal tables.  */
       sgotloc = htab->sgotloc;
       sgotloc->size = spltlittbl->size;
-      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
        {
          if (abfd->flags & DYNAMIC)
            continue;
          for (s = abfd->sections; s != NULL; s = s->next)
            {
-             if (! elf_discarded_section (s)
+             if (! discarded_section (s)
                  && xtensa_is_littable_section (s)
                  && s != spltlittbl)
                sgotloc->size += s->size;
@@ -1839,6 +1846,9 @@ elf_xtensa_always_size_sections (bfd *output_bfd,
   asection *tls_sec;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   tls_sec = htab->elf.tls_sec;
 
   if (tls_sec && (htab->tlsbase->tls_type & GOT_TLS_ANY) != 0)
@@ -1947,13 +1957,12 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
       if (!is_weak_undef)
        {
          /* Check for windowed CALL across a 1GB boundary.  */
-         xtensa_opcode opcode =
-           get_expanded_call_opcode (contents + address,
-                                     input_size - address, 0);
+         opcode = get_expanded_call_opcode (contents + address,
+                                            input_size - address, 0);
          if (is_windowed_call_opcode (opcode))
            {
              if ((self_address >> CALL_SEGMENT_BITS)
-                 != (relocation >> CALL_SEGMENT_BITS)) 
+                 != (relocation >> CALL_SEGMENT_BITS))
                {
                  *error_message = "windowed longcall crosses 1GB boundary; "
                    "return may fail";
@@ -2126,7 +2135,7 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
       && is_windowed_call_opcode (opcode))
     {
       if ((self_address >> CALL_SEGMENT_BITS)
-         != (relocation >> CALL_SEGMENT_BITS)) 
+         != (relocation >> CALL_SEGMENT_BITS))
        {
          *error_message =
            "windowed call crosses 1GB boundary; return may fail";
@@ -2151,11 +2160,11 @@ vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
   static char *message = NULL;
   bfd_size_type orig_len, len = 0;
   bfd_boolean is_append;
+  va_list ap;
 
-  VA_OPEN (ap, arglen);
-  VA_FIXEDARG (ap, const char *, origmsg);
-  
-  is_append = (origmsg == message);  
+  va_start (ap, arglen);
+
+  is_append = (origmsg == message);
 
   orig_len = strlen (origmsg);
   len = orig_len + strlen (fmt) + arglen + 20;
@@ -2170,7 +2179,7 @@ vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
        memcpy (message, origmsg, orig_len);
       vsprintf (message + orig_len, fmt, ap);
     }
-  VA_CLOSE (ap);
+  va_end (ap);
   return message;
 }
 
@@ -2551,6 +2560,9 @@ elf_xtensa_relocate_section (bfd *output_bfd,
   BFD_ASSERT (is_xtensa_elf (input_bfd));
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_tls_types = elf_xtensa_local_got_tls_type (input_bfd);
@@ -2625,10 +2637,12 @@ elf_xtensa_relocate_section (bfd *output_bfd,
        }
       else
        {
+         bfd_boolean 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 (relocation == 0
              && !unresolved_reloc
@@ -2638,19 +2652,15 @@ elf_xtensa_relocate_section (bfd *output_bfd,
          sym_type = h->type;
        }
 
-      if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
        {
+         bfd_vma dest_addr;
+         asection * sym_sec = get_elf_r_symndx_section (input_bfd, r_symndx);
+
          /* This is a relocatable link.
             1) If the reloc is against a section symbol, adjust
             according to the output section.
@@ -2667,9 +2677,12 @@ elf_xtensa_relocate_section (bfd *output_bfd,
                return FALSE;
            }
 
+         dest_addr = sym_sec->output_section->vma + sym_sec->output_offset
+           + get_elf_r_symndx_offset (input_bfd, r_symndx) + rel->r_addend;
+
          if (r_type == R_XTENSA_ASM_SIMPLIFY)
            {
-             char *error_message = NULL;
+             error_message = NULL;
              /* Convert ASM_SIMPLIFY into the simpler relocation
                 so that they never escape a relaxing link.  */
              r = contract_asm_expansion (contents, input_size, rel,
@@ -2703,25 +2716,41 @@ elf_xtensa_relocate_section (bfd *output_bfd,
             to work around problems with DWARF in relocatable links
             with some previous version of BFD.  Now we can't easily get
             rid of the hack without breaking backward compatibility.... */
-         if (rel->r_addend)
+         r = bfd_reloc_ok;
+         howto = &elf_howto_table[r_type];
+         if (howto->partial_inplace && rel->r_addend)
+           {
+             r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
+                                      rel->r_addend, contents,
+                                      rel->r_offset, FALSE,
+                                      &error_message);
+             rel->r_addend = 0;
+           }
+         else
            {
-             howto = &elf_howto_table[r_type];
-             if (howto->partial_inplace)
+             /* Put the correct bits in the target instruction, even
+                though the relocation will still be present in the output
+                file.  This makes disassembly clearer, as well as
+                allowing loadable kernel modules to work without needing
+                relocations on anything other than calls and l32r's.  */
+
+             /* If it is not in the same section, there is nothing we can do.  */
+             if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP &&
+                 sym_sec->output_section == input_section->output_section)
                {
                  r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
-                                          rel->r_addend, contents,
+                                          dest_addr, contents,
                                           rel->r_offset, FALSE,
                                           &error_message);
-                 if (r != bfd_reloc_ok)
-                   {
-                     if (!((*info->callbacks->reloc_dangerous)
-                           (info, error_message, input_bfd, input_section,
-                            rel->r_offset)))
-                       return FALSE;
-                   }
-                 rel->r_addend = 0;
                }
            }
+         if (r != bfd_reloc_ok)
+           {
+             if (!((*info->callbacks->reloc_dangerous)
+                   (info, error_message, input_bfd, input_section,
+                    rel->r_offset)))
+               return FALSE;
+           }
 
          /* Done with work for relocatable link; continue with next reloc.  */
          continue;
@@ -2757,7 +2786,7 @@ elf_xtensa_relocate_section (bfd *output_bfd,
            name = bfd_section_name (input_bfd, sec);
        }
 
-      if (r_symndx != 0
+      if (r_symndx != STN_UNDEF
          && r_type != R_XTENSA_NONE
          && (h == NULL
              || h->root.type == bfd_link_hash_defined
@@ -3025,7 +3054,9 @@ elf_xtensa_relocate_section (bfd *output_bfd,
         not process them.  */
       if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
-              && h->def_dynamic))
+              && h->def_dynamic)
+         && _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'"),
@@ -3099,7 +3130,7 @@ elf_xtensa_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
     }
 
   /* 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;
 
@@ -3170,18 +3201,18 @@ elf_xtensa_combine_prop_entries (bfd *output_bfd,
 
   for (n = 0; n < num; n++)
     {
-      bfd_boolean remove = FALSE;
+      bfd_boolean remove_entry = FALSE;
 
       if (table[n].size == 0)
-       remove = TRUE;
-      else if (n > 0 &&
-              (table[n-1].address + table[n-1].size == table[n].address))
+       remove_entry = TRUE;
+      else if (n > 0
+              && (table[n-1].address + table[n-1].size == table[n].address))
        {
          table[n-1].size += table[n].size;
-         remove = TRUE;
+         remove_entry = TRUE;
        }
 
-      if (remove)
+      if (remove_entry)
        {
          for (m = n; m < num - 1; m++)
            {
@@ -3236,8 +3267,11 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
     return TRUE;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = elf_hash_table (info)->dynobj;
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   BFD_ASSERT (sdyn != NULL);
 
   /* Set the first entry in the global offset table to the address of
@@ -3427,7 +3461,7 @@ elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   unsigned out_mach, in_mach;
   flagword out_flag, in_flag;
 
-  /* Check if we have the same endianess.  */
+  /* Check if we have the same endianness.  */
   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
     return FALSE;
 
@@ -3463,10 +3497,10 @@ elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       return TRUE;
     }
 
-  if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN)) 
+  if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN))
     elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_INSN);
 
-  if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT)) 
+  if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT))
     elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_LIT);
 
   return TRUE;
@@ -3556,7 +3590,9 @@ elf_xtensa_final_write_processing (bfd *abfd,
 
 
 static enum elf_reloc_type_class
-elf_xtensa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_xtensa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                            const asection *rel_sec ATTRIBUTE_UNUSED,
+                            const Elf_Internal_Rela *rela)
 {
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
@@ -3753,10 +3789,10 @@ elf_xtensa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
      based on the size.  Just assume this is GNU/Linux.  */
 
   /* 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_pid = bfd_get_32 (abfd, note->descdata + 24);
+  elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
 
   /* pr_reg */
   offset = 72;
@@ -3777,9 +3813,9 @@ elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
        return FALSE;
 
       case 128:                /* GNU/Linux elf_prpsinfo */
-       elf_tdata (abfd)->core_program
+       elf_tdata (abfd)->core->program
         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
-       elf_tdata (abfd)->core_command
+       elf_tdata (abfd)->core->command
         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
     }
 
@@ -3788,7 +3824,7 @@ elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *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] == ' ')
@@ -4057,7 +4093,7 @@ get_asm_simplify_size (bfd_byte *contents,
     return 0;
 
   size += insnlen;
-  
+
   insnlen = insn_decode_len (contents, content_len, offset + size);
   if (insnlen == 0)
     return 0;
@@ -4096,7 +4132,7 @@ is_operand_relocation (int r_type)
   return FALSE;
 }
 
-      
+
 #define MIN_INSN_LENGTH 2
 
 /* Return 0 if it fails to decode.  */
@@ -4197,7 +4233,7 @@ check_loop_aligned (bfd_byte *contents,
       BFD_ASSERT (FALSE);
       return FALSE;
     }
-  
+
   loop_len = insn_decode_len (contents, content_length, offset);
   insn_len = insn_decode_len (contents, content_length, offset + loop_len);
   if (loop_len == 0 || insn_len == 0)
@@ -4589,7 +4625,7 @@ can_widen_instruction (xtensa_insnbuf slotbuf,
   return 0;
 }
 
-                      
+
 /* Attempt to widen an instruction.  If the widening is valid, perform
    the action in-place directly into the contents and return TRUE.  Otherwise,
    the return value is FALSE and the contents are not modified.  */
@@ -4684,12 +4720,12 @@ elf_xtensa_do_asm_simplify (bfd_byte *contents,
       *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
       return bfd_reloc_other;
     }
-  
+
   /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset.  */
   core_format = xtensa_format_lookup (isa, "x24");
   opcode = xtensa_opcode_lookup (isa, "or");
   xtensa_opcode_encode (isa, core_format, 0, slotbuf, opcode);
-  for (opn = 0; opn < 3; opn++) 
+  for (opn = 0; opn < 3; opn++)
     {
       uint32 regno = 1;
       xtensa_operand_encode (isa, opcode, opn, &regno);
@@ -4757,7 +4793,7 @@ swap_callx_for_call_opcode (xtensa_opcode opcode)
 #define CONST16_TARGET_REG_OPERAND 0
 #define CALLN_SOURCE_OPERAND 0
 
-static xtensa_opcode 
+static xtensa_opcode
 get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r)
 {
   static xtensa_insnbuf insnbuf = NULL;
@@ -4833,7 +4869,7 @@ get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r)
       || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
     return XTENSA_UNDEFINED;
   opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
-  if (opcode == XTENSA_UNDEFINED 
+  if (opcode == XTENSA_UNDEFINED
       || !is_indirect_call_opcode (opcode))
     return XTENSA_UNDEFINED;
 
@@ -4864,7 +4900,7 @@ get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r)
    For efficiency, an r_reloc also contains a "target_offset" field to
    cache the target-section-relative offset value that is represented by
    the relocation.
-   
+
    The r_reloc also contains a virtual offset that allows multiple
    inserted literals to be placed at the same "address" with
    different offsets.  */
@@ -4991,7 +5027,7 @@ print_r_reloc (FILE *fp, const r_reloc *r_rel)
       fprintf (fp, " + ");
       fprintf_vma (fp, r_rel->virtual_offset);
     }
-    
+
   fprintf (fp, ")");
 }
 
@@ -5111,7 +5147,7 @@ typedef struct value_map_hash_table_struct value_map_hash_table;
 
 struct literal_value_struct
 {
-  r_reloc r_rel; 
+  r_reloc r_rel;
   unsigned long value;
   bfd_boolean is_abs_literal;
 };
@@ -5152,7 +5188,7 @@ literal_value_equal (const literal_value *src1,
 {
   struct elf_link_hash_entry *h1, *h2;
 
-  if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) 
+  if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel))
     return FALSE;
 
   if (r_reloc_is_const (&src1->r_rel))
@@ -5164,13 +5200,13 @@ literal_value_equal (const literal_value *src1,
 
   if (src1->r_rel.target_offset != src2->r_rel.target_offset)
     return FALSE;
-   
+
   if (src1->r_rel.virtual_offset != src2->r_rel.virtual_offset)
     return FALSE;
 
   if (src1->value != src2->value)
     return FALSE;
-  
+
   /* Now check for the same section (if defined) or the same elf_hash
      (if undefined or weak).  */
   h1 = r_reloc_get_hash_entry (&src1->r_rel);
@@ -5212,7 +5248,7 @@ value_map_hash_table_init (void)
   values->count = 0;
   values->buckets = (value_map **)
     bfd_zmalloc (sizeof (value_map *) * values->bucket_count);
-  if (values->buckets == NULL) 
+  if (values->buckets == NULL)
     {
       free (values);
       return NULL;
@@ -5251,7 +5287,7 @@ literal_value_hash (const literal_value *src)
       hash_val += hash_bfd_vma (src->is_abs_literal * 1000);
       hash_val += hash_bfd_vma (src->r_rel.target_offset);
       hash_val += hash_bfd_vma (src->r_rel.virtual_offset);
-  
+
       /* Now check for the same section and the same elf_hash.  */
       if (r_reloc_is_defined (&src->r_rel))
        sec_or_hash = r_reloc_get_section (&src->r_rel);
@@ -5317,7 +5353,7 @@ add_value_map (value_map_hash_table *map,
   *bucket_p = val_e;
   map->count++;
   /* FIXME: Consider resizing the hash table if we get too many entries.  */
-  
+
   return val_e;
 }
 
@@ -5457,7 +5493,7 @@ adjust_fill_action (text_action *ta, int fill_diff)
    "unreachable_space" bytes can be freely contracted.  Note that a
    negative removed value is a fill.  */
 
-static void 
+static void
 text_action_add (text_action_list *l,
                 text_action_t action,
                 asection *sec,
@@ -5478,8 +5514,8 @@ text_action_add (text_action_list *l,
   for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next)
     {
       text_action *t = *m_p;
-      
-      if (action == ta_fill) 
+
+      if (action == ta_fill)
        {
          /* When the action is another fill at the same address,
             just increase the size.  */
@@ -5576,7 +5612,7 @@ removed_by_actions (text_action **p_start_action,
 }
 
 
-static bfd_vma 
+static bfd_vma
 offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
 {
   text_action *r = action_list->head;
@@ -5664,7 +5700,7 @@ print_action_list (FILE *fp, text_action_list *action_list)
 
       fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n",
               r->sec->owner->filename,
-              r->sec->name, r->offset, t, r->removed_bytes);
+              r->sec->name, (unsigned long) r->offset, t, r->removed_bytes);
     }
 }
 
@@ -5714,9 +5750,9 @@ add_removed_literal (removed_literal_list *removed_list,
   else
     new_r->to.abfd = NULL;
   new_r->next = NULL;
-  
+
   r = removed_list->head;
-  if (r == NULL) 
+  if (r == NULL)
     {
       removed_list->head = new_r;
       removed_list->tail = new_r;
@@ -5729,7 +5765,7 @@ add_removed_literal (removed_literal_list *removed_list,
     }
   else
     {
-      while (r->from.target_offset < from->target_offset && r->next) 
+      while (r->from.target_offset < from->target_offset && r->next)
        {
          r = r->next;
        }
@@ -5807,7 +5843,7 @@ struct xtensa_relax_info_struct
      reallocated, the newly allocated relocations will be referenced
      here along with the actual size allocated.  The relocation
      count will always be found in the section structure.  */
-  Elf_Internal_Rela *allocated_relocs; 
+  Elf_Internal_Rela *allocated_relocs;
   unsigned relocs_count;
   unsigned allocated_relocs_count;
 };
@@ -5873,7 +5909,7 @@ init_xtensa_relax_info (asection *sec)
   relax_info->fix_array = NULL;
   relax_info->fix_array_count = 0;
 
-  relax_info->allocated_relocs = NULL; 
+  relax_info->allocated_relocs = NULL;
   relax_info->relocs_count = 0;
   relax_info->allocated_relocs_count = 0;
 }
@@ -5893,11 +5929,11 @@ struct reloc_bfd_fix_struct
   asection *src_sec;
   bfd_vma src_offset;
   unsigned src_type;                   /* Relocation type.  */
-  
+
   asection *target_sec;
   bfd_vma target_offset;
   bfd_boolean translated;
-  
+
   reloc_bfd_fix *next;
 };
 
@@ -6028,7 +6064,7 @@ init_section_cache (section_cache_t *sec_cache)
 
 
 static void
-clear_section_cache (section_cache_t *sec_cache)
+free_section_cache (section_cache_t *sec_cache)
 {
   if (sec_cache->sec)
     {
@@ -6036,7 +6072,6 @@ clear_section_cache (section_cache_t *sec_cache)
       release_internal_relocs (sec_cache->sec, sec_cache->relocs);
       if (sec_cache->ptbl)
        free (sec_cache->ptbl);
-      memset (sec_cache, 0, sizeof (sec_cache));
     }
 }
 
@@ -6077,8 +6112,8 @@ section_cache_section (section_cache_t *sec_cache,
     goto err;
 
   /* Fill in the new section cache.  */
-  clear_section_cache (sec_cache);
-  memset (sec_cache, 0, sizeof (sec_cache));
+  free_section_cache (sec_cache);
+  init_section_cache (sec_cache);
 
   sec_cache->sec = sec;
   sec_cache->contents = contents;
@@ -6509,7 +6544,7 @@ retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory)
 
   sec_size = bfd_get_section_limit (abfd, sec);
   contents = elf_section_data (sec)->this_hdr.contents;
-  
+
   if (contents == NULL && sec_size != 0)
     {
       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
@@ -6518,7 +6553,7 @@ retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory)
            free (contents);
          return NULL;
        }
-      if (keep_memory) 
+      if (keep_memory)
        elf_section_data (sec)->this_hdr.contents = contents;
     }
   return contents;
@@ -6593,12 +6628,12 @@ static bfd_boolean compute_removed_literals
   (bfd *, asection *, struct bfd_link_info *, value_map_hash_table *);
 static Elf_Internal_Rela *get_irel_at_offset
   (asection *, Elf_Internal_Rela *, bfd_vma);
-static bfd_boolean is_removable_literal 
+static bfd_boolean is_removable_literal
   (const source_reloc *, int, const source_reloc *, int, asection *,
    property_table_entry *, int);
 static bfd_boolean remove_dead_literal
   (bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-   Elf_Internal_Rela *, source_reloc *, property_table_entry *, int); 
+   Elf_Internal_Rela *, source_reloc *, property_table_entry *, int);
 static bfd_boolean identify_literal_placement
   (bfd *, asection *, bfd_byte *, struct bfd_link_info *,
    value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int,
@@ -6628,7 +6663,7 @@ static bfd_boolean relax_property_section
 static bfd_boolean relax_section_symbols (bfd *, asection *);
 
 
-static bfd_boolean 
+static bfd_boolean
 elf_xtensa_relax_section (bfd *abfd,
                          asection *sec,
                          struct bfd_link_info *link_info,
@@ -6638,10 +6673,6 @@ elf_xtensa_relax_section (bfd *abfd,
   static bfd_boolean relocations_analyzed = FALSE;
   xtensa_relax_info *relax_info;
 
-  if (link_info->relocatable)
-    (*link_info->callbacks->einfo)
-      (_("%P%F: --relax and -r may not be used together\n"));
-
   if (!relocations_analyzed)
     {
       /* Do some overall initialization for relaxation.  */
@@ -6715,14 +6746,14 @@ analyze_relocations (struct bfd_link_info *link_info)
   bfd_boolean is_relaxable = FALSE;
 
   /* Initialize the per-section relaxation info.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
        init_xtensa_relax_info (sec);
       }
 
   /* Mark relaxable sections (and count relocations against each one).  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
        if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
@@ -6734,7 +6765,7 @@ analyze_relocations (struct bfd_link_info *link_info)
     return TRUE;
 
   /* Allocate space for source_relocs.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
        xtensa_relax_info *relax_info;
@@ -6751,7 +6782,7 @@ analyze_relocations (struct bfd_link_info *link_info)
       }
 
   /* Collect info on relocations against each relaxable section.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
        if (!collect_source_relocs (abfd, sec, link_info))
@@ -6759,7 +6790,7 @@ analyze_relocations (struct bfd_link_info *link_info)
       }
 
   /* Compute the text actions.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
        if (!compute_text_actions (abfd, sec, link_info))
@@ -6795,7 +6826,7 @@ find_relaxable_sections (bfd *abfd,
 
   internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
-  if (internal_relocs == NULL) 
+  if (internal_relocs == NULL)
     return ok;
 
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
@@ -6806,7 +6837,7 @@ find_relaxable_sections (bfd *abfd,
     }
 
   source_relax_info = get_xtensa_relax_info (sec);
-  for (i = 0; i < sec->reloc_count; i++) 
+  for (i = 0; i < sec->reloc_count; i++)
     {
       Elf_Internal_Rela *irel = &internal_relocs[i];
       r_reloc r_rel;
@@ -6886,9 +6917,9 @@ collect_source_relocs (bfd *abfd,
   unsigned i;
   bfd_size_type sec_size;
 
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
+  internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
-  if (internal_relocs == NULL) 
+  if (internal_relocs == NULL)
     return ok;
 
   sec_size = bfd_get_section_limit (abfd, sec);
@@ -6900,7 +6931,7 @@ collect_source_relocs (bfd *abfd,
     }
 
   /* Record relocations against relaxable literal sections.  */
-  for (i = 0; i < sec->reloc_count; i++) 
+  for (i = 0; i < sec->reloc_count; i++)
     {
       Elf_Internal_Rela *irel = &internal_relocs[i];
       r_reloc r_rel;
@@ -6958,7 +6989,7 @@ collect_source_relocs (bfd *abfd,
      relocations associated with ASM_EXPANDs because they were just
      added in the preceding loop over the relocations.  */
 
-  for (i = 0; i < sec->reloc_count; i++) 
+  for (i = 0; i < sec->reloc_count; i++)
     {
       Elf_Internal_Rela *irel = &internal_relocs[i];
       bfd_boolean is_reachable;
@@ -6997,7 +7028,7 @@ collect_source_relocs (bfd *abfd,
                 the l32r_irel.  Note: The src_relocs array is not yet
                 sorted, but it wouldn't matter anyway because we're
                 searching by source offset instead of target offset.  */
-             s_reloc = find_source_reloc (target_relax_info->src_relocs, 
+             s_reloc = find_source_reloc (target_relax_info->src_relocs,
                                           target_relax_info->src_next,
                                           sec, l32r_irel);
              BFD_ASSERT (s_reloc);
@@ -7056,7 +7087,7 @@ is_resolvable_asm_expansion (bfd *abfd,
   if (contents == NULL)
     return FALSE;
 
-  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND) 
+  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND)
     return FALSE;
 
   sec_size = bfd_get_section_limit (abfd, sec);
@@ -7065,7 +7096,7 @@ is_resolvable_asm_expansion (bfd *abfd,
   /* Optimization of longcalls that use CONST16 is not yet implemented.  */
   if (!uses_l32r)
     return FALSE;
-  
+
   direct_call_opcode = swap_callx_for_call_opcode (opcode);
   if (direct_call_opcode == XTENSA_UNDEFINED)
     return FALSE;
@@ -7084,7 +7115,7 @@ is_resolvable_asm_expansion (bfd *abfd,
      shouldn't crash regardless.  */
   if (!target_sec->output_section)
     return FALSE;
-      
+
   /* For relocatable sections, we can only simplify when the output
      section of the target is the same as the output section of the
      source.  */
@@ -7097,7 +7128,7 @@ is_resolvable_asm_expansion (bfd *abfd,
                  + sec->output_offset + irel->r_offset + 3);
   dest_address = (target_sec->output_section->vma
                  + target_sec->output_offset + target_offset);
-      
+
   *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
                                      self_address, dest_address);
 
@@ -7118,7 +7149,7 @@ find_associated_l32r_irel (bfd *abfd,
 {
   unsigned i;
 
-  for (i = 0; i < sec->reloc_count; i++) 
+  for (i = 0; i < sec->reloc_count; i++)
     {
       Elf_Internal_Rela *irel = &internal_relocs[i];
 
@@ -7335,7 +7366,7 @@ prev_instr_is_a_loop (bfd_byte *contents,
     return FALSE;
   prev_opcode = insn_decode_opcode (contents, content_length, offset-3, 0);
   return (xtensa_opcode_is_loop (xtensa_default_isa, prev_opcode) == 1);
-} 
+}
 
 
 /* Find all of the possible actions for an extended basic block.  */
@@ -7385,7 +7416,7 @@ compute_ebb_proposed_actions (ebb_constraint *ebb_table)
 
          insn_len = insn_decode_len (ebb->contents, ebb->content_length,
                                      offset);
-         if (insn_len == 0) 
+         if (insn_len == 0)
            goto decode_error;
 
          if (check_branch_target_aligned_address (offset, insn_len))
@@ -7414,7 +7445,7 @@ compute_ebb_proposed_actions (ebb_constraint *ebb_table)
            {
              bfd_size_type simplify_size;
 
-             simplify_size = get_asm_simplify_size (ebb->contents, 
+             simplify_size = get_asm_simplify_size (ebb->contents,
                                                     ebb->content_length,
                                                     irel->r_offset);
              if (simplify_size == 0)
@@ -7422,7 +7453,7 @@ compute_ebb_proposed_actions (ebb_constraint *ebb_table)
 
              ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
                                  ta_convert_longcall, offset, 0, TRUE);
-             
+
              offset += simplify_size;
              continue;
            }
@@ -7769,7 +7800,7 @@ struct xlate_map
 };
 
 
-static int 
+static int
 xlate_compare (const void *a_v, const void *b_v)
 {
   const xlate_map_entry_t *a = (const xlate_map_entry_t *) a_v;
@@ -7787,7 +7818,6 @@ xlate_offset_with_removed_text (const xlate_map_t *map,
                                text_action_list *action_list,
                                bfd_vma offset)
 {
-  xlate_map_entry_t tmp;
   void *r;
   xlate_map_entry_t *e;
 
@@ -7797,14 +7827,10 @@ xlate_offset_with_removed_text (const xlate_map_t *map,
   if (map->entry_count == 0)
     return offset;
 
-  tmp.orig_address = offset;
-  tmp.new_address = offset;
-  tmp.size = 1;
-
   r = bsearch (&offset, map->entry, map->entry_count,
               sizeof (xlate_map_entry_t), &xlate_compare);
   e = (xlate_map_entry_t *) r;
-  
+
   BFD_ASSERT (e != NULL);
   if (e == NULL)
     return offset;
@@ -7829,7 +7855,7 @@ build_xlate_map (asection *sec, xtensa_relax_info *relax_info)
     return NULL;
 
   num_actions = action_list_count (action_list);
-  map->entry = (xlate_map_entry_t *) 
+  map->entry = (xlate_map_entry_t *)
     bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1));
   if (map->entry == NULL)
     {
@@ -7837,7 +7863,7 @@ build_xlate_map (asection *sec, xtensa_relax_info *relax_info)
       return NULL;
     }
   map->entry_count = 0;
-  
+
   removed = 0;
   current_entry = &map->entry[0];
 
@@ -7892,7 +7918,7 @@ build_xlate_map (asection *sec, xtensa_relax_info *relax_info)
 
 /* Free an offset translation map.  */
 
-static void 
+static void
 free_xlate_map (xlate_map_t *map)
 {
   if (map && map->entry)
@@ -8124,7 +8150,7 @@ compute_fill_extra_space (property_table_entry *entry)
    add an entry to the per-section list of removed literals.  The
    actual changes are deferred until the next pass.  */
 
-static bfd_boolean 
+static bfd_boolean
 compute_removed_literals (bfd *abfd,
                          asection *sec,
                          struct bfd_link_info *link_info,
@@ -8151,7 +8177,7 @@ compute_removed_literals (bfd *abfd,
   if (!relax_info->is_relaxable_literal_section)
     return ok;
 
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
+  internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
 
   sec_size = bfd_get_section_limit (abfd, sec);
@@ -8203,14 +8229,14 @@ compute_removed_literals (bfd *abfd,
        continue;
       prev_i = i;
 
-      if (last_loc_is_prev && 
+      if (last_loc_is_prev &&
          last_target_offset + 4 != rel->r_rel.target_offset)
        last_loc_is_prev = FALSE;
 
       /* Check if the relocation was from an L32R that is being removed
         because a CALLX was converted to a direct CALL, and check if
         there are no other relocations to the literal.  */
-      if (is_removable_literal (rel, i, src_relocs, relax_info->src_count, 
+      if (is_removable_literal (rel, i, src_relocs, relax_info->src_count,
                                sec, prop_table, ptblsize))
        {
          if (!remove_dead_literal (abfd, sec, link_info, internal_relocs,
@@ -8224,8 +8250,8 @@ compute_removed_literals (bfd *abfd,
        }
 
       if (!identify_literal_placement (abfd, sec, contents, link_info,
-                                      values, 
-                                      &last_loc_is_prev, irel, 
+                                      values,
+                                      &last_loc_is_prev, irel,
                                       relax_info->src_count - i, rel,
                                       prop_table, ptblsize,
                                       &target_sec_cache, rel->is_abs_literal))
@@ -8242,8 +8268,9 @@ compute_removed_literals (bfd *abfd,
 #endif /* DEBUG */
 
 error_return:
-  if (prop_table) free (prop_table);
-  clear_section_cache (&target_sec_cache);
+  if (prop_table)
+    free (prop_table);
+  free_section_cache (&target_sec_cache);
 
   release_contents (sec, contents);
   release_internal_relocs (sec, internal_relocs);
@@ -8261,7 +8288,7 @@ get_irel_at_offset (asection *sec,
   unsigned r_type;
   Elf_Internal_Rela key;
 
-  if (!internal_relocs) 
+  if (!internal_relocs)
     return NULL;
 
   key.r_offset = offset;
@@ -8305,8 +8332,8 @@ is_removable_literal (const source_reloc *rel,
 
   if (!rel->is_null)
     return FALSE;
-  
-  entry = elf_xtensa_find_property_entry (prop_table, ptblsize, 
+
+  entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
                                          sec->vma + rel->r_rel.target_offset);
   if (entry && (entry->flags & XTENSA_PROP_NO_TRANSFORM))
     return FALSE;
@@ -8327,7 +8354,7 @@ is_removable_literal (const source_reloc *rel,
 }
 
 
-bfd_boolean 
+bfd_boolean
 remove_dead_literal (bfd *abfd,
                     asection *sec,
                     struct bfd_link_info *link_info,
@@ -8354,7 +8381,7 @@ remove_dead_literal (bfd *abfd,
                   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
 
   /* If the section is 4-byte aligned, do not add fill.  */
-  if (sec->alignment_power > 2) 
+  if (sec->alignment_power > 2)
     {
       int fill_extra_space;
       bfd_vma entry_sec_offset;
@@ -8398,7 +8425,7 @@ remove_dead_literal (bfd *abfd,
 }
 
 
-bfd_boolean 
+bfd_boolean
 identify_literal_placement (bfd *abfd,
                            asection *sec,
                            bfd_byte *contents,
@@ -8468,7 +8495,7 @@ identify_literal_placement (bfd *abfd,
   /* For relocatable links, do not try to move literals.  To do it
      correctly might increase the number of relocations in an input
      section making the default relocatable linking fail.  */
-  if (!link_info->relocatable && !literal_placed 
+  if (!link_info->relocatable && !literal_placed
       && values->has_last_loc && !(*last_loc_is_prev_p))
     {
       asection *target_sec = r_reloc_get_section (&values->last_loc);
@@ -8481,7 +8508,7 @@ identify_literal_placement (bfd *abfd,
          /* There is a last loc that was in the same output section.  */
          if (relocations_reach (rel, remaining_src_rels, &try_loc)
              && move_shared_literal (sec, link_info, rel,
-                                     prop_table, ptblsize, 
+                                     prop_table, ptblsize,
                                      &try_loc, &val, target_sec_cache))
            {
              values->last_loc.virtual_offset += 4;
@@ -8581,7 +8608,7 @@ relocations_reach (source_reloc *reloc,
 /* Move a literal to another literal location because it is
    the same as the other literal value.  */
 
-static bfd_boolean 
+static bfd_boolean
 coalesce_shared_literal (asection *sec,
                         source_reloc *rel,
                         property_table_entry *prop_table,
@@ -8610,7 +8637,7 @@ coalesce_shared_literal (asection *sec,
                   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
 
   /* If the section is 4-byte aligned, do not add fill.  */
-  if (sec->alignment_power > 2) 
+  if (sec->alignment_power > 2)
     {
       int fill_extra_space;
       bfd_vma entry_sec_offset;
@@ -8646,7 +8673,7 @@ coalesce_shared_literal (asection *sec,
    total amount of space used because of alignments so we need to do
    this carefully.  Also, it may make a branch go out of range.  */
 
-static bfd_boolean 
+static bfd_boolean
 move_shared_literal (asection *sec,
                     struct bfd_link_info *link_info,
                     source_reloc *rel,
@@ -8689,7 +8716,7 @@ move_shared_literal (asection *sec,
     return FALSE;
 
   target_entry = elf_xtensa_find_property_entry
-    (target_sec_cache->ptbl, target_sec_cache->pte_count, 
+    (target_sec_cache->ptbl, target_sec_cache->pte_count,
      target_sec->vma + target_loc->target_offset);
 
   if (!target_entry)
@@ -8700,7 +8727,7 @@ move_shared_literal (asection *sec,
 
   init_ebb_constraint (&ebb_table);
   ebb = &ebb_table.ebb;
-  init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents, 
+  init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents,
            target_sec_cache->content_length,
            target_sec_cache->ptbl, target_sec_cache->pte_count,
            target_sec_cache->relocs, target_sec_cache->reloc_count);
@@ -8712,24 +8739,24 @@ move_shared_literal (asection *sec,
                      -4 - (1 << target_sec->alignment_power), TRUE);
 
   /* Check all of the PC-relative relocations to make sure they still fit.  */
-  relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, 
+  relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec,
                                             target_sec_cache->contents,
                                             target_sec_cache->relocs,
                                             &ebb_table, NULL);
 
-  if (!relocs_fit) 
+  if (!relocs_fit)
     return FALSE;
 
   text_action_add_literal (&target_relax_info->action_list,
                           ta_add_literal, target_loc, lit_value, -4);
 
-  if (target_sec->alignment_power > 2 && target_entry != src_entry) 
+  if (target_sec->alignment_power > 2 && target_entry != src_entry)
     {
       /* May need to add or remove some fill to maintain alignment.  */
       int fill_extra_space;
       bfd_vma entry_sec_offset;
 
-      entry_sec_offset = 
+      entry_sec_offset =
        target_entry->address - target_sec->vma + target_entry->size;
 
       /* If the literal range is at the end of the section,
@@ -8762,7 +8789,7 @@ move_shared_literal (asection *sec,
                   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
 
   /* If the section is 4-byte aligned, do not add fill.  */
-  if (sec->alignment_power > 2 && target_entry != src_entry) 
+  if (sec->alignment_power > 2 && target_entry != src_entry)
     {
       int fill_extra_space;
       bfd_vma entry_sec_offset;
@@ -8826,8 +8853,11 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
       return relax_property_section (abfd, sec, link_info);
     }
 
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
+  internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
+  if (!internal_relocs && !relax_info->action_list.head)
+    return TRUE;
+
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   if (contents == NULL && sec_size != 0)
     {
@@ -8930,9 +8960,9 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
             that here and adjust things accordingly.  */
          if (! elf_xtensa_ignore_discarded_relocs (sec)
              && elf_xtensa_action_discarded (sec) == PRETEND
-             && sec->sec_info_type != ELF_INFO_TYPE_STABS
+             && sec->sec_info_type != SEC_INFO_TYPE_STABS
              && target_sec != NULL
-             && elf_discarded_section (target_sec))
+             && discarded_section (target_sec))
            {
              /* It would be natural to call _bfd_elf_check_kept_section
                 here, but it's not exported from elflink.c.  It's also a
@@ -8983,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
                  || r_type == R_XTENSA_DIFF16
                  || r_type == R_XTENSA_DIFF32)
                {
-                 bfd_vma diff_value = 0, new_end_offset, diff_mask = 0;
+                 bfd_signed_vma diff_value = 0;
+                 bfd_vma new_end_offset, diff_mask = 0;
 
                  if (bfd_get_section_limit (abfd, sec) < old_source_offset)
                    {
@@ -8997,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
                    {
                    case R_XTENSA_DIFF8:
                      diff_value =
-                       bfd_get_8 (abfd, &contents[old_source_offset]);
+                       bfd_get_signed_8 (abfd, &contents[old_source_offset]);
                      break;
                    case R_XTENSA_DIFF16:
                      diff_value =
-                       bfd_get_16 (abfd, &contents[old_source_offset]);
+                       bfd_get_signed_16 (abfd, &contents[old_source_offset]);
                      break;
                    case R_XTENSA_DIFF32:
                      diff_value =
-                       bfd_get_32 (abfd, &contents[old_source_offset]);
+                       bfd_get_signed_32 (abfd, &contents[old_source_offset]);
                      break;
                    }
 
@@ -9017,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
                  switch (r_type)
                    {
                    case R_XTENSA_DIFF8:
-                     diff_mask = 0xff;
-                     bfd_put_8 (abfd, diff_value,
+                     diff_mask = 0x7f;
+                     bfd_put_signed_8 (abfd, diff_value,
                                 &contents[old_source_offset]);
                      break;
                    case R_XTENSA_DIFF16:
-                     diff_mask = 0xffff;
-                     bfd_put_16 (abfd, diff_value,
+                     diff_mask = 0x7fff;
+                     bfd_put_signed_16 (abfd, diff_value,
                                  &contents[old_source_offset]);
                      break;
                    case R_XTENSA_DIFF32:
-                     diff_mask = 0xffffffff;
-                     bfd_put_32 (abfd, diff_value,
+                     diff_mask = 0x7fffffff;
+                     bfd_put_signed_32 (abfd, diff_value,
                                  &contents[old_source_offset]);
                      break;
                    }
 
-                 /* Check for overflow.  */
-                 if ((diff_value & ~diff_mask) != 0)
+                 /* Check for overflow. Sign bits must be all zeroes or all ones */
+                 if ((diff_value & ~diff_mask) != 0 &&
+                     (diff_value & ~diff_mask) != (-1 & ~diff_mask))
                    {
                      (*link_info->callbacks->reloc_dangerous)
                        (link_info, _("overflow after relaxation"),
@@ -9153,7 +9185,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
                      dup_dot += copy_size;
                    }
                  virtual_action = TRUE;
-               } 
+               }
              else
                BFD_ASSERT (action->virtual_offset <= orig_dot_vo);
            }
@@ -9224,7 +9256,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
                                 relax_info, &internal_relocs, &action->value))
                goto error_return;
 
-             if (virtual_action) 
+             if (virtual_action)
                orig_dot_vo += copy_size;
 
              orig_dot += orig_insn_size;
@@ -9289,7 +9321,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
 }
 
 
-static bfd_boolean 
+static bfd_boolean
 translate_section_fixes (asection *sec)
 {
   xtensa_relax_info *relax_info;
@@ -9310,7 +9342,7 @@ translate_section_fixes (asection *sec)
 /* Translate a fix given the mapping in the relax info for the target
    section.  If it has already been translated, no work is required.  */
 
-static bfd_boolean 
+static bfd_boolean
 translate_reloc_bfd_fix (reloc_bfd_fix *fix)
 {
   reloc_bfd_fix new_fix;
@@ -9356,7 +9388,7 @@ translate_reloc_bfd_fix (reloc_bfd_fix *fix)
                                      target_offset);
     }
 
-  if (removed) 
+  if (removed)
     {
       asection *new_sec;
 
@@ -9366,11 +9398,11 @@ translate_reloc_bfd_fix (reloc_bfd_fix *fix)
 
       /* This was moved to some other address (possibly another section).  */
       new_sec = r_reloc_get_section (&removed->to);
-      if (new_sec != sec) 
+      if (new_sec != sec)
        {
          sec = new_sec;
          relax_info = get_xtensa_relax_info (sec);
-         if (!relax_info || 
+         if (!relax_info ||
              (!relax_info->is_relaxable_literal_section
               && !relax_info->is_relaxable_asm_section))
            {
@@ -9504,6 +9536,9 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info,
   bfd_boolean dynamic_symbol;
 
   htab = elf_xtensa_hash_table (info);
+  if (htab == NULL)
+    return;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -9612,12 +9647,10 @@ move_literal (bfd *abfd,
     {
       int r_type;
       unsigned i;
-      asection *target_sec;
       reloc_bfd_fix *fix;
       unsigned insert_at;
 
       r_type = ELF32_R_TYPE (r_rel->rela.r_info);
-      target_sec = r_reloc_get_section (r_rel);
 
       /* This is the difficult case.  We have to create a fix up.  */
       this_rela.r_offset = offset;
@@ -9658,7 +9691,7 @@ move_literal (bfd *abfd,
          BFD_ASSERT (relax_info->allocated_relocs == NULL
                      || sec->reloc_count == relax_info->relocs_count);
 
-         if (relax_info->allocated_relocs_count == 0) 
+         if (relax_info->allocated_relocs_count == 0)
            new_relocs_count = (sec->reloc_count + 2) * 2;
          else
            new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2;
@@ -9678,7 +9711,7 @@ move_literal (bfd *abfd,
          if (insert_at != sec->reloc_count)
            memcpy (new_relocs + insert_at + 1,
                    (*internal_relocs_p) + insert_at,
-                   (sec->reloc_count - insert_at) 
+                   (sec->reloc_count - insert_at)
                    * sizeof (Elf_Internal_Rela));
 
          if (*internal_relocs_p != relax_info->allocated_relocs)
@@ -9737,7 +9770,7 @@ relax_property_section (bfd *abfd,
   bfd_size_type entry_size;
 
   sec_size = bfd_get_section_limit (abfd, sec);
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
+  internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   if (contents == NULL && sec_size != 0)
@@ -9962,7 +9995,7 @@ relax_property_section (bfd *abfd,
          actual_offset = offset - removed_bytes;
          size = bfd_get_32 (abfd, &contents[actual_offset + 4]);
 
-         if (is_full_prop_section) 
+         if (is_full_prop_section)
            flags = bfd_get_32 (abfd, &contents[actual_offset + 8]);
          else
            flags = predef_flags;
@@ -9990,7 +10023,7 @@ relax_property_section (bfd *abfd,
                  bfd_vma new_address =
                    (offset_rel->r_addend
                     + bfd_get_32 (abfd, &contents[actual_offset]));
-                 if (is_full_prop_section) 
+                 if (is_full_prop_section)
                    old_flags = bfd_get_32
                      (abfd, &contents[last_irel->r_offset + 8]);
                  else
@@ -10234,12 +10267,15 @@ elf_xtensa_get_plt_section (struct bfd_link_info *info, int chunk)
   if (chunk == 0)
     {
       htab = elf_xtensa_hash_table (info);
+      if (htab == NULL)
+       return NULL;
+
       return htab->splt;
     }
 
   dynobj = elf_hash_table (info)->dynobj;
   sprintf (plt_name, ".plt.%u", chunk);
-  return bfd_get_section_by_name (dynobj, plt_name);
+  return bfd_get_linker_section (dynobj, plt_name);
 }
 
 
@@ -10253,12 +10289,14 @@ elf_xtensa_get_gotplt_section (struct bfd_link_info *info, int chunk)
   if (chunk == 0)
     {
       htab = elf_xtensa_hash_table (info);
+      if (htab == NULL)
+       return NULL;
       return htab->sgotplt;
     }
 
   dynobj = elf_hash_table (info)->dynobj;
   sprintf (got_name, ".got.plt.%u", chunk);
-  return bfd_get_section_by_name (dynobj, got_name);
+  return bfd_get_linker_section (dynobj, got_name);
 }
 
 
@@ -10401,7 +10439,7 @@ pcrel_reloc_fits (xtensa_opcode opc,
 }
 
 
-static bfd_boolean 
+static bfd_boolean
 xtensa_is_property_section (asection *sec)
 {
   if (xtensa_is_insntable_section (sec)
@@ -10413,7 +10451,7 @@ xtensa_is_property_section (asection *sec)
 }
 
 
-static bfd_boolean 
+static bfd_boolean
 xtensa_is_insntable_section (asection *sec)
 {
   if (CONST_STRNEQ (sec->name, XTENSA_INSN_SEC_NAME)
@@ -10424,7 +10462,7 @@ xtensa_is_insntable_section (asection *sec)
 }
 
 
-static bfd_boolean 
+static bfd_boolean
 xtensa_is_littable_section (asection *sec)
 {
   if (CONST_STRNEQ (sec->name, XTENSA_LIT_SEC_NAME)
@@ -10435,7 +10473,7 @@ xtensa_is_littable_section (asection *sec)
 }
 
 
-static bfd_boolean 
+static bfd_boolean
 xtensa_is_proptable_section (asection *sec)
 {
   if (CONST_STRNEQ (sec->name, XTENSA_PROP_SEC_NAME)
@@ -10488,7 +10526,7 @@ match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 {
   const char *gname = inf;
   const char *group_name = elf_group_name (sec);
-  
+
   return (group_name == gname
          || (group_name != NULL
              && gname != NULL
@@ -10520,9 +10558,9 @@ xtensa_property_section_name (asection *sec, const char *base_name)
     {
       char *linkonce_kind = 0;
 
-      if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0) 
+      if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0)
        linkonce_kind = "x.";
-      else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0) 
+      else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0)
        linkonce_kind = "p.";
       else if (strcmp (base_name, XTENSA_PROP_SEC_NAME) == 0)
        linkonce_kind = "prop.";
@@ -10637,7 +10675,7 @@ xtensa_callback_required_dependence (bfd *abfd,
 
       /* Find the corresponding ".got.plt*" section.  */
       if (sec->name[4] == '\0')
-       sgotplt = bfd_get_section_by_name (sec->owner, ".got.plt");
+       sgotplt = bfd_get_linker_section (sec->owner, ".got.plt");
       else
        {
          char got_name[14];
@@ -10647,7 +10685,7 @@ xtensa_callback_required_dependence (bfd *abfd,
          chunk = strtol (&sec->name[5], NULL, 10);
 
          sprintf (got_name, ".got.plt.%u", chunk);
-         sgotplt = bfd_get_section_by_name (sec->owner, got_name);
+         sgotplt = bfd_get_linker_section (sec->owner, got_name);
        }
       BFD_ASSERT (sgotplt);
 
@@ -10662,7 +10700,7 @@ xtensa_callback_required_dependence (bfd *abfd,
   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
     return ok;
 
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
+  internal_relocs = retrieve_internal_relocs (abfd, sec,
                                              link_info->keep_memory);
   if (internal_relocs == NULL
       || sec->reloc_count == 0)
@@ -10720,10 +10758,11 @@ static const struct bfd_elf_special_section elf_xtensa_special_sections[] =
   { NULL,                       0,      0, 0,            0 }
 };
 \f
+#define ELF_TARGET_ID                  XTENSA_ELF_DATA
 #ifndef ELF_ARCH
-#define TARGET_LITTLE_SYM              bfd_elf32_xtensa_le_vec
+#define TARGET_LITTLE_SYM              xtensa_elf32_le_vec
 #define TARGET_LITTLE_NAME             "elf32-xtensa-le"
-#define TARGET_BIG_SYM                 bfd_elf32_xtensa_be_vec
+#define TARGET_BIG_SYM                 xtensa_elf32_be_vec
 #define TARGET_BIG_NAME                        "elf32-xtensa-be"
 #define ELF_ARCH                       bfd_arch_xtensa
 
This page took 0.048389 seconds and 4 git commands to generate.