daily update
[deliverable/binutils-gdb.git] / bfd / elf32-xtensa.c
index 782baba652ea749f7ce45d606d8e12bb82996a61..cfdbd235fde78ccac7d83bb8b65fa4847d00f5c0 100644 (file)
@@ -497,13 +497,14 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
   int block_count;
   bfd_size_type num_records;
   Elf_Internal_Rela *internal_relocs;
+  bfd_vma section_addr;
 
   table_section_name = 
     xtensa_get_property_section_name (section, sec_name);
   table_section = bfd_get_section_by_name (abfd, table_section_name);
   free (table_section_name);
   if (table_section != NULL)
-    table_size = bfd_get_section_size_before_reloc (table_section);
+    table_size = table_section->size;
   
   if (table_size == 0) 
     {
@@ -517,10 +518,12 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
     bfd_malloc (num_records * sizeof (property_table_entry));
   block_count = 0;
   
+  section_addr = section->output_section->vma + section->output_offset;
+
   /* If the file has not yet been relocated, process the relocations
      and sort out the table entries that apply to the specified section.  */
   internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
-  if (internal_relocs)
+  if (internal_relocs && !table_section->reloc_done)
     {
       unsigned i;
 
@@ -539,7 +542,7 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
            {
              bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
              blocks[block_count].address =
-               (section->vma + sym_off + rel->r_addend
+               (section_addr + sym_off + rel->r_addend
                 + bfd_get_32 (abfd, table_data + rel->r_offset));
              blocks[block_count].size =
                bfd_get_32 (abfd, table_data + rel->r_offset + 4);
@@ -549,16 +552,16 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
     }
   else
     {
-      /* No relocations.  Presumably the file has been relocated
-        and the addresses are already in the table.  */
+      /* The file has already been relocated and the addresses are
+        already in the table.  */
       bfd_vma off;
 
       for (off = 0; off < table_size; off += 8) 
        {
          bfd_vma address = bfd_get_32 (abfd, table_data + off);
 
-         if (address >= section->vma
-             && address < ( section->vma + section->_raw_size))
+         if (address >= section_addr
+             && address < section_addr + section->size)
            {
              blocks[block_count].address = address;
              blocks[block_count].size =
@@ -619,8 +622,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
   struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
-  property_table_entry *lit_table;
-  int ltblsize;
 
   if (info->relocatable)
     return TRUE;
@@ -628,11 +629,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
-  ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
-                                       XTENSA_LIT_SEC_NAME);
-  if (ltblsize < 0)
-    return FALSE;
-
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
@@ -645,9 +641,8 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
-         (*_bfd_error_handler) (_("%s: bad symbol index: %d"),
-                                bfd_archive_filename (abfd),
-                                r_symndx);
+         (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+                                abfd, r_symndx);
          return FALSE;
        }
 
@@ -669,11 +664,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
 
          if ((sec->flags & SEC_ALLOC) != 0)
            {
-             if ((sec->flags & SEC_READONLY) != 0
-                 && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-                                                 sec->vma + rel->r_offset))
-               h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
              if (h->got.refcount <= 0)
                h->got.refcount = 1;
              else
@@ -689,11 +679,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
 
          if ((sec->flags & SEC_ALLOC) != 0)
            {
-             if ((sec->flags & SEC_READONLY) != 0
-                 && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-                                                 sec->vma + rel->r_offset))
-               h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
              if (h->plt.refcount <= 0)
                {
                  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
@@ -736,14 +721,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
                }
              local_got_refcounts[r_symndx] += 1;
-
-             /* If the relocation is not inside the GOT, the DF_TEXTREL
-                flag needs to be set.  */
-             if (info->shared
-                 && (sec->flags & SEC_READONLY) != 0
-                 && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-                                                 sec->vma + rel->r_offset))
-               info->flags |= DF_TEXTREL;
            }
          break;
 
@@ -758,14 +735,14 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
        case R_XTENSA_GNU_VTINHERIT:
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
-         if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
 
        case R_XTENSA_GNU_VTENTRY:
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
-         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
@@ -774,7 +751,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
        }
     }
 
-  free (lit_table);
   return TRUE;
 }
 
@@ -1044,7 +1020,6 @@ elf_xtensa_make_sym_local (info, h)
   else
     {
       /* Don't need any dynamic relocations at all.  */
-      h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
       h->plt.refcount = 0;
       h->got.refcount = 0;
     }
@@ -1064,11 +1039,6 @@ elf_xtensa_fix_refcounts (h, arg)
   if (! xtensa_elf_dynamic_symbol_p (h, info))
     elf_xtensa_make_sym_local (info, h);
 
-  /* If the symbol has a relocation outside the GOT, set the
-     DF_TEXTREL flag.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
-    info->flags |= DF_TEXTREL;
-
   return TRUE;
 }
 
@@ -1084,7 +1054,7 @@ elf_xtensa_allocate_plt_size (h, arg)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if (h->plt.refcount > 0)
-    srelplt->_raw_size += (h->plt.refcount * sizeof (Elf32_External_Rela));
+    srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
 
   return TRUE;
 }
@@ -1101,7 +1071,7 @@ elf_xtensa_allocate_got_size (h, arg)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if (h->got.refcount > 0)
-    srelgot->_raw_size += (h->got.refcount * sizeof (Elf32_External_Rela));
+    srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
 
   return TRUE;
 }
@@ -1130,8 +1100,8 @@ elf_xtensa_allocate_local_got_size (info, srelgot)
       for (j = 0; j < cnt; ++j)
        {
          if (local_got_refcounts[j] > 0)
-           srelgot->_raw_size += (local_got_refcounts[j]
-                                  * sizeof (Elf32_External_Rela));
+           srelgot->size += (local_got_refcounts[j]
+                             * sizeof (Elf32_External_Rela));
        }
     }
 }
@@ -1165,7 +1135,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
          s = bfd_get_section_by_name (dynobj, ".interp");
          if (s == NULL)
            abort ();
-         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
        }
 
@@ -1173,7 +1143,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
       s = bfd_get_section_by_name (dynobj, ".got");
       if (s == NULL)
        abort ();
-      s->_raw_size = 4;
+      s->size = 4;
 
       /* Adjust refcounts for symbols that we now know are not "dynamic".  */
       elf_link_hash_traverse (elf_hash_table (info),
@@ -1212,7 +1182,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
       if (spltlittbl == NULL)
        abort ();
 
-      plt_entries = srelplt->_raw_size / sizeof (Elf32_External_Rela);
+      plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
       plt_chunks =
        (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
 
@@ -1238,15 +1208,15 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
 
          if (chunk_entries != 0)
            {
-             sgotplt->_raw_size = 4 * (chunk_entries + 2);
-             splt->_raw_size = PLT_ENTRY_SIZE * chunk_entries;
-             srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
-             spltlittbl->_raw_size += 8;
+             sgotplt->size = 4 * (chunk_entries + 2);
+             splt->size = PLT_ENTRY_SIZE * chunk_entries;
+             srelgot->size += 2 * sizeof (Elf32_External_Rela);
+             spltlittbl->size += 8;
            }
          else
            {
-             sgotplt->_raw_size = 0;
-             splt->_raw_size = 0;
+             sgotplt->size = 0;
+             splt->size = 0;
            }
        }
 
@@ -1255,7 +1225,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
       sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
       if (sgotloc == NULL)
        abort ();
-      sgotloc->_raw_size = spltlittbl->_raw_size;
+      sgotloc->size = spltlittbl->size;
       for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
        {
          if (abfd->flags & DYNAMIC)
@@ -1265,7 +1235,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
              if (! elf_discarded_section (s)
                  && xtensa_is_littable_section (s)
                  && s != spltlittbl)
-               sgotloc->_raw_size += s->_raw_size;
+               sgotloc->size += s->size;
            }
        }
     }
@@ -1301,7 +1271,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
       else if (strncmp (name, ".plt.", 5) == 0
               || strncmp (name, ".got.plt.", 9) == 0)
        {
-         if (s->_raw_size == 0)
+         if (s->size == 0)
            {
              /* If we don't need this section, strip it from the output
                 file.  We must create the ".plt*" and ".got.plt*"
@@ -1330,8 +1300,8 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
       else
        {
          /* Allocate memory for the section contents.  */
-         s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
-         if (s->contents == NULL && s->_raw_size != 0)
+         s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+         if (s->contents == NULL && s->size != 0)
            return FALSE;
        }
     }
@@ -1366,7 +1336,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
 #define add_dynamic_entry(TAG, VAL) \
-  bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
       if (! info->shared)
        {
@@ -1391,12 +1361,6 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
            return FALSE;
        }
 
-      if ((info->flags & DF_TEXTREL) != 0)
-       {
-         if (!add_dynamic_entry (DT_TEXTREL, 0))
-           return FALSE;
-       }
-
       if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
          || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
        return FALSE;
@@ -1473,7 +1437,7 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
          /* Check for windowed CALL across a 1GB boundary.  */
          xtensa_opcode opcode =
            get_expanded_call_opcode (contents + address,
-                                     input_section->_raw_size - address);
+                                     input_section->size - address);
          if (is_windowed_call_opcode (opcode))
            {
              self_address = (input_section->output_section->vma
@@ -1494,8 +1458,7 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
       { 
         /* Convert the L32R/CALLX to CALL.  */
        bfd_reloc_status_type retval = 
-         elf_xtensa_do_asm_simplify (contents, address,
-                                     input_section->_raw_size);
+         elf_xtensa_do_asm_simplify (contents, address, input_section->size);
        if (retval != bfd_reloc_ok)
          return retval;
 
@@ -1710,8 +1673,7 @@ bfd_elf_xtensa_reloc (abfd, reloc_entry, symbol, data, input_section,
     }
 
   /* Is the address of the relocation really within the section?  */
-  if (reloc_entry->address > (input_section->_cooked_size
-                             / bfd_octets_per_byte (abfd)))
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   /* Work out which section the relocation is targeted at and the
@@ -1851,6 +1813,8 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
   struct elf_link_hash_entry **sym_hashes;
   asection *srelgot, *srelplt;
   bfd *dynobj;
+  property_table_entry *lit_table = 0;
+  int ltblsize = 0;
   char *error_message = NULL;
 
   if (xtensa_default_isa == NULL)
@@ -1868,6 +1832,14 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
       srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
     }
 
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      ltblsize = xtensa_read_table_entries (input_bfd, input_section,
+                                           &lit_table, XTENSA_LIT_SEC_NAME);
+      if (ltblsize < 0)
+       return FALSE;
+    }
+
   rel = relocs;
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; rel++)
@@ -1919,7 +1891,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
            {
              /* Convert ASM_SIMPLIFY into the simpler relocation
                 so that they never escape a relaxing link.  */
-             contract_asm_expansion (contents, input_section->_raw_size, rel);
+             contract_asm_expansion (contents, input_section->size, rel);
              r_type = ELF32_R_TYPE (rel->r_info);
            }
 
@@ -2015,7 +1987,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
        }
 
       /* Sanity check the address.  */
-      if (rel->r_offset >= input_section->_raw_size
+      if (rel->r_offset >= bfd_get_section_limit (input_bfd, input_section)
          && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
        {
          bfd_set_error (bfd_error_bad_value);
@@ -2068,6 +2040,20 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
                  outrel.r_offset += (input_section->output_section->vma
                                      + input_section->output_offset);
 
+                 /* Complain if the relocation is in a read-only section
+                    and not in a literal pool.  */
+                 if ((input_section->flags & SEC_READONLY) != 0
+                     && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+                                                     outrel.r_offset))
+                   {
+                     error_message =
+                       _("dynamic relocation in read-only section");
+                     if (!((*info->callbacks->reloc_dangerous)
+                           (info, error_message, input_bfd, input_section,
+                            rel->r_offset)))
+                       return FALSE;
+                   }
+
                  if (dynamic_symbol)
                    {
                      outrel.r_addend = rel->r_addend;
@@ -2105,7 +2091,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
                     + srel->reloc_count++ * sizeof (Elf32_External_Rela));
              bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
              BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
-                         <= srel->_cooked_size);
+                         <= srel->size);
            }
        }
 
@@ -2116,9 +2102,9 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
          && !((input_section->flags & SEC_DEBUGGING) != 0
               && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
        (*_bfd_error_handler)
-         (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
-          bfd_archive_filename (input_bfd),
-          bfd_get_section_name (input_bfd, input_section),
+         (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+          input_bfd,
+          input_section,
           (long) rel->r_offset,
           h->root.root.string);
 
@@ -2155,6 +2141,11 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
        }
     }
 
+  if (lit_table)
+    free (lit_table);
+
+  input_section->reloc_done = TRUE;
+
   return TRUE;
 }
 
@@ -2206,13 +2197,11 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc)
   bfd_vma offset;
   int n, m, num;
 
-  section_size = (sxtlit->_cooked_size != 0
-                 ? sxtlit->_cooked_size : sxtlit->_raw_size);
+  section_size = sxtlit->size;
   BFD_ASSERT (section_size % 8 == 0);
   num = section_size / 8;
 
-  sgotloc_size = (sgotloc->_cooked_size != 0
-                 ? sgotloc->_cooked_size : sgotloc->_raw_size);
+  sgotloc_size = sgotloc->size;
   if (sgotloc_size != section_size)
     {
       (*_bfd_error_handler)
@@ -2220,20 +2209,22 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc)
       return -1;
     }
 
-  contents = (bfd_byte *) bfd_malloc (section_size);
-  table = (property_table_entry *)
-    bfd_malloc (num * sizeof (property_table_entry));
-  if (contents == 0 || table == 0)
+  table = bfd_malloc (num * sizeof (property_table_entry));
+  if (table == 0)
     return -1;
 
   /* The ".xt.lit.plt" section has the SEC_IN_MEMORY flag set and this
      propagates to the output section, where it doesn't really apply and
-     where it breaks the following call to bfd_get_section_contents.  */
+     where it breaks the following call to bfd_malloc_and_get_section.  */
   sxtlit->flags &= ~SEC_IN_MEMORY;
 
-  if (! bfd_get_section_contents (output_bfd, sxtlit, contents, 0,
-                                 section_size))
-    return -1;
+  if (!bfd_malloc_and_get_section (output_bfd, sxtlit, &contents))
+    {
+      if (contents != 0)
+       free (contents);
+      free (table);
+      return -1;
+    }
 
   /* There should never be any relocations left at this point, so this
      is quite a bit easier than what is done during relaxation.  */
@@ -2285,10 +2276,7 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc)
 
   /* Clear the removed bytes.  */
   if ((bfd_size_type) (num * 8) < section_size)
-    {
-      memset (&contents[num * 8], 0, section_size - num * 8);
-      sxtlit->_cooked_size = num * 8;
-    }
+    memset (&contents[num * 8], 0, section_size - num * 8);
 
   if (! bfd_set_section_contents (output_bfd, sxtlit, contents, 0,
                                  section_size))
@@ -2327,7 +2315,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
   sgot = bfd_get_section_by_name (dynobj, ".got");
   if (sgot)
     {
-      BFD_ASSERT (sgot->_raw_size == 4);
+      BFD_ASSERT (sgot->size == 4);
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
       else
@@ -2337,7 +2325,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
     }
 
   srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
-  if (srelplt != NULL && srelplt->_raw_size != 0)
+  if (srelplt != NULL && srelplt->size != 0)
     {
       asection *sgotplt, *srelgot, *spltlittbl;
       int chunk, plt_chunks, plt_entries;
@@ -2362,7 +2350,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
        }
       BFD_ASSERT (rtld_reloc < srelgot->reloc_count);
 
-      plt_entries = (srelplt->_raw_size / sizeof (Elf32_External_Rela));
+      plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
       plt_chunks =
        (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
 
@@ -2404,7 +2392,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
          else
            chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
 
-         BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->_cooked_size);
+         BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->size);
          bfd_put_32 (output_bfd,
                      sgotplt->output_section->vma + sgotplt->output_offset,
                      spltlittbl->contents + (chunk * 8) + 0);
@@ -2415,10 +2403,10 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
 
       /* All the dynamic relocations have been emitted at this point.
         Make sure the relocation sections are the correct size.  */
-      if (srelgot->_cooked_size != (sizeof (Elf32_External_Rela)
-                                   * srelgot->reloc_count)
-         || srelplt->_cooked_size != (sizeof (Elf32_External_Rela)
-                                      * srelplt->reloc_count))
+      if (srelgot->size != (sizeof (Elf32_External_Rela)
+                           * srelgot->reloc_count)
+         || srelplt->size != (sizeof (Elf32_External_Rela)
+                              * srelplt->reloc_count))
        abort ();
 
      /* The .xt.lit.plt section has just been modified.  This must
@@ -2429,7 +2417,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
                                      spltlittbl->output_section,
                                      spltlittbl->contents,
                                      spltlittbl->output_offset,
-                                     spltlittbl->_raw_size))
+                                     spltlittbl->size))
        return FALSE;
       /* Clear SEC_HAS_CONTENTS so the contents won't be output again.  */
       spltlittbl->flags &= ~SEC_HAS_CONTENTS;
@@ -2446,7 +2434,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
     return FALSE;
 
   dyncon = (Elf32_External_Dyn *) sdyn->contents;
-  dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+  dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   for (; dyncon < dynconend; dyncon++)
     {
       Elf_Internal_Dyn dyn;
@@ -2481,7 +2469,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
        case DT_PLTRELSZ:
          s = bfd_get_section_by_name (output_bfd, ".rela.plt");
          BFD_ASSERT (s);
-         dyn.d_un.d_val = (s->_cooked_size ? s->_cooked_size : s->_raw_size);
+         dyn.d_un.d_val = s->size;
          break;
 
        case DT_RELASZ:
@@ -2493,10 +2481,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
             don't have to worry about changing the DT_RELA entry.  */
          s = bfd_get_section_by_name (output_bfd, ".rela.plt");
          if (s)
-           {
-             dyn.d_un.d_val -=
-               (s->_cooked_size ? s->_cooked_size : s->_raw_size);
-           }
+           dyn.d_un.d_val -= s->size;
          break;
        }
 
@@ -2537,8 +2522,8 @@ elf_xtensa_merge_private_bfd_data (ibfd, obfd)
   if (out_mach != in_mach) 
     {
       (*_bfd_error_handler)
-       ("%s: incompatible machine type. Output is 0x%x. Input is 0x%x",
-        bfd_archive_filename (ibfd), out_mach, in_mach);
+       ("%B: incompatible machine type. Output is 0x%x. Input is 0x%x",
+        ibfd, out_mach, in_mach);
       bfd_set_error (bfd_error_wrong_format);
       return FALSE;
     }
@@ -2692,7 +2677,7 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec)
   bfd_vma offset, actual_offset;
   size_t removed_bytes = 0;
 
-  section_size = (sec->_cooked_size ? sec->_cooked_size : sec->_raw_size);
+  section_size = sec->size;
   if (section_size == 0 || section_size % 8 != 0)
     return FALSE;
 
@@ -2730,7 +2715,7 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec)
       while (cookie->rel < cookie->relend
             && cookie->rel->r_offset == offset)
        {
-         if (_bfd_elf32_reloc_symbol_deleted_p (offset, cookie))
+         if (bfd_elf_reloc_symbol_deleted_p (offset, cookie))
            {
              /* Remove the table entry.  (If the reloc type is NONE, then
                 the entry has already been merged with another and deleted
@@ -2780,9 +2765,8 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec)
       pin_contents (sec, contents);
       pin_internal_relocs (sec, cookie->rels);
 
-      sec->_cooked_size = section_size - removed_bytes;
-      /* Also shrink _raw_size.  See comments in relax_property_section.  */
-      sec->_raw_size = sec->_cooked_size;
+      /* Shrink size.  */
+      sec->size = section_size - removed_bytes;
 
       if (xtensa_is_littable_section (sec))
        {
@@ -2792,13 +2776,7 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec)
              asection *sgotloc =
                bfd_get_section_by_name (dynobj, ".got.loc");
              if (sgotloc)
-               {
-                 bfd_size_type sgotloc_size =
-                   (sgotloc->_cooked_size ? sgotloc->_cooked_size
-                    : sgotloc->_raw_size);
-                 sgotloc->_cooked_size = sgotloc_size - removed_bytes;
-                 sgotloc->_raw_size = sgotloc_size - removed_bytes;
-               }
+               sgotloc->size -= removed_bytes;
            }
        }
     }
@@ -2850,7 +2828,7 @@ elf_xtensa_grok_prstatus (abfd, note)
      Elf_Internal_Note *note;
 {
   int offset;
-  unsigned int raw_size;
+  unsigned int size;
 
   /* The size for Xtensa is variable, so don't try to recognize the format
      based on the size.  Just assume this is GNU/Linux.  */
@@ -2863,11 +2841,11 @@ elf_xtensa_grok_prstatus (abfd, note)
 
   /* pr_reg */
   offset = 72;
-  raw_size = note->descsz - offset - 4;
+  size = note->descsz - offset - 4;
 
   /* Make a ".reg/999" section.  */
   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
-                                         raw_size, note->descpos + offset);
+                                         size, note->descpos + offset);
 }
 
 
@@ -3029,7 +3007,7 @@ get_relocation_opcode (sec, contents, irel)
   if (contents == NULL)
     return XTENSA_UNDEFINED;
 
-  if (sec->_raw_size <= irel->r_offset)
+  if (sec->size <= irel->r_offset)
     return XTENSA_UNDEFINED;
 
   if (ibuff == NULL)
@@ -3441,7 +3419,7 @@ struct value_map_hash_table_struct
 
 
 static bfd_boolean is_same_value
-  PARAMS ((const literal_value *, const literal_value *));
+  PARAMS ((const literal_value *, const literal_value *, bfd_boolean));
 static value_map_hash_table *value_map_hash_table_init
   PARAMS ((void));
 static unsigned hash_literal_value
@@ -3449,16 +3427,20 @@ static unsigned hash_literal_value
 static unsigned hash_bfd_vma
   PARAMS ((bfd_vma));
 static value_map *get_cached_value
-  PARAMS ((value_map_hash_table *, const literal_value *));
+  PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean));
 static value_map *add_value_map
-  PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *));
+  PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *,
+          bfd_boolean));
 
 
 static bfd_boolean
-is_same_value (src1, src2)
+is_same_value (src1, src2, final_static_link)
      const literal_value *src1;
      const literal_value *src2;
+     bfd_boolean final_static_link;
 {
+  struct elf_link_hash_entry *h1, *h2;
+
   if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) 
     return FALSE;
 
@@ -3476,8 +3458,14 @@ is_same_value (src1, src2)
   if (src1->value != src2->value)
     return FALSE;
   
-  /* Now check for the same section and the same elf_hash.  */
-  if (r_reloc_is_defined (&src1->r_rel))
+  /* 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);
+  h2 = r_reloc_get_hash_entry (&src2->r_rel);
+  if (r_reloc_is_defined (&src1->r_rel)
+      && (final_static_link
+         || ((!h1 || h1->root.type != bfd_link_hash_defweak)
+             && (!h2 || h2->root.type != bfd_link_hash_defweak))))
     {
       if (r_reloc_get_section (&src1->r_rel)
          != r_reloc_get_section (&src2->r_rel))
@@ -3485,11 +3473,8 @@ is_same_value (src1, src2)
     }
   else
     {
-      if (r_reloc_get_hash_entry (&src1->r_rel)
-         != r_reloc_get_hash_entry (&src2->r_rel))
-       return FALSE;
-
-      if (r_reloc_get_hash_entry (&src1->r_rel) == 0)
+      /* Require that the hash entries (i.e., symbols) be identical.  */
+      if (h1 != h2 || h1 == 0)
        return FALSE;
     }
 
@@ -3550,9 +3535,10 @@ hash_literal_value (src)
 /* Check if the specified literal_value has been seen before.  */
 
 static value_map *
-get_cached_value (map, val)
+get_cached_value (map, val, final_static_link)
      value_map_hash_table *map;
      const literal_value *val;
+     bfd_boolean final_static_link;
 {
   value_map *map_e;
   value_map *bucket;
@@ -3563,7 +3549,7 @@ get_cached_value (map, val)
   bucket = map->buckets[idx];
   for (map_e = bucket; map_e; map_e = map_e->next)
     {
-      if (is_same_value (&map_e->val, val))
+      if (is_same_value (&map_e->val, val, final_static_link))
        return map_e;
     }
   return NULL;
@@ -3574,17 +3560,18 @@ get_cached_value (map, val)
    already has an entry here.  */
 
 static value_map *
-add_value_map (map, val, loc)
+add_value_map (map, val, loc, final_static_link)
      value_map_hash_table *map;
      const literal_value *val;
      const r_reloc *loc;
+     bfd_boolean final_static_link;
 {
   value_map **bucket_p;
   unsigned idx;
 
   value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
 
-  BFD_ASSERT (get_cached_value (map, val) == NULL);
+  BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL);
   val_e->val = *val;
   val_e->loc = *loc;
 
@@ -3954,20 +3941,16 @@ retrieve_contents (abfd, sec, keep_memory)
 
   contents = elf_section_data (sec)->this_hdr.contents;
   
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
-      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
-      if (contents != NULL)
+      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
        {
-         if (! bfd_get_section_contents (abfd, sec, contents,
-                                         (file_ptr) 0, sec->_raw_size))
-           {
-             free (contents);
-             return NULL;
-           }
-         if (keep_memory) 
-           elf_section_data (sec)->this_hdr.contents = contents;
+         if (contents != NULL)
+           free (contents);
+         return NULL;
        }
+      if (keep_memory) 
+       elf_section_data (sec)->this_hdr.contents = contents;
     }
   return contents;
 }
@@ -4193,7 +4176,7 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p)
     return ok;
 
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
@@ -4254,7 +4237,7 @@ collect_source_relocs (abfd, sec, link_info)
     return ok;
 
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
@@ -4402,7 +4385,7 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
     return FALSE;
   
   opcode = get_expanded_call_opcode (contents + irel->r_offset,
-                                    sec->_raw_size - irel->r_offset);
+                                    sec->size - irel->r_offset);
   
   direct_call_opcode = swap_callx_for_call_opcode (opcode);
   if (direct_call_opcode == XTENSA_UNDEFINED)
@@ -4490,6 +4473,7 @@ remove_literals (abfd, sec, link_info, values)
   bfd_byte *contents;
   Elf_Internal_Rela *internal_relocs;
   source_reloc *src_relocs;
+  bfd_boolean final_static_link;
   bfd_boolean ok = TRUE;
   int i;
 
@@ -4504,12 +4488,16 @@ remove_literals (abfd, sec, link_info, values)
                                              link_info->keep_memory);
 
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
     }
 
+  final_static_link =
+    (!link_info->relocatable
+     && !elf_hash_table (link_info)->dynamic_sections_created);
+
   /* Sort the source_relocs by target offset.  */
   src_relocs = relax_info->src_relocs;
   qsort (src_relocs, relax_info->src_count,
@@ -4558,11 +4546,11 @@ remove_literals (abfd, sec, link_info, values)
 
       /* Find the literal value.  */
       r_reloc_init (&val.r_rel, abfd, irel);
-      BFD_ASSERT (rel->r_rel.target_offset < sec->_raw_size);
+      BFD_ASSERT (rel->r_rel.target_offset < sec->size);
       val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
           
       /* Check if we've seen another literal with the same value.  */
-      val_map = get_cached_value (values, &val);
+      val_map = get_cached_value (values, &val, final_static_link);
       if (val_map != NULL) 
        {
          /* First check that THIS and all the other relocs to this
@@ -4585,7 +4573,7 @@ remove_literals (abfd, sec, link_info, values)
        {
          /* This is the first time we've seen this literal value.  */
          BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel));
-         add_value_map (values, &val, &rel->r_rel);
+         add_value_map (values, &val, &rel->r_rel, final_static_link);
        }
     }
 
@@ -4714,7 +4702,7 @@ relax_section (abfd, sec, link_info)
   internal_relocs = retrieve_internal_relocs (abfd, sec, 
                                              link_info->keep_memory);
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
@@ -4793,13 +4781,13 @@ relax_section (abfd, sec, link_info)
       /* Walk through the contents and delete literals that are not needed 
          anymore.  */
 
-      unsigned long size = sec->_cooked_size;
+      unsigned long size = sec->size;
       unsigned long removed = 0;
 
       removed_literal *reloc = relax_info->removed_list.head;
       for (; reloc; reloc = reloc->next) 
        {
-         unsigned long upper = sec->_raw_size;
+         unsigned long upper = sec->size;
          bfd_vma start = reloc->from.target_offset + 4;
          if (reloc->next)
            upper = reloc->next->from.target_offset;
@@ -4816,13 +4804,7 @@ relax_section (abfd, sec, link_info)
        }
 
       /* Change the section size.  */
-      sec->_cooked_size = size;
-      /* Also shrink _raw_size.  (The code in relocate_section that
-        checks that relocations are within the section must use
-        _raw_size because of the way the stabs sections are relaxed;
-        shrinking _raw_size means that these checks will not be
-        unnecessarily lax.)  */
-      sec->_raw_size = size;
+      sec->size = size;
     }
   
  error_return:
@@ -4948,13 +4930,8 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel)
       /* Reduce size of the .rela.* section by one reloc.  */
       srel = bfd_get_section_by_name (dynobj, srel_name);
       BFD_ASSERT (srel != NULL);
-      BFD_ASSERT (srel->_cooked_size >= sizeof (Elf32_External_Rela));
-      srel->_cooked_size -= sizeof (Elf32_External_Rela);
-
-      /* Also shrink _raw_size.  (This seems wrong but other bfd code seems
-        to assume that linker-created sections will never be relaxed and
-        hence _raw_size must always equal _cooked_size.) */
-      srel->_raw_size = srel->_cooked_size;
+      BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
+      srel->size -= sizeof (Elf32_External_Rela);
 
       if (is_plt)
        {
@@ -4967,7 +4944,7 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel)
             = size - 1" since the index starts at zero, but in this
             context, the size has just been decremented so there's no
             need to subtract one.  */
-         reloc_index = srel->_cooked_size / sizeof (Elf32_External_Rela);
+         reloc_index = srel->size / sizeof (Elf32_External_Rela);
 
          chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
          splt = elf_xtensa_get_plt_section (dynobj, chunk);
@@ -4981,27 +4958,20 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel)
              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
              BFD_ASSERT (srelgot != NULL);
              srelgot->reloc_count -= 2;
-             srelgot->_cooked_size -= 2 * sizeof (Elf32_External_Rela);
-             /* Shrink _raw_size (see comment above).  */
-             srelgot->_raw_size = srelgot->_cooked_size;
-
-             sgotplt->_cooked_size -= 8;
+             srelgot->size -= 2 * sizeof (Elf32_External_Rela);
+             sgotplt->size -= 8;
 
              /* There should be only one entry left (and it will be
                 removed below).  */
-             BFD_ASSERT (sgotplt->_cooked_size == 4);
-             BFD_ASSERT (splt->_cooked_size == PLT_ENTRY_SIZE);
+             BFD_ASSERT (sgotplt->size == 4);
+             BFD_ASSERT (splt->size == PLT_ENTRY_SIZE);
            }
 
-         BFD_ASSERT (sgotplt->_cooked_size >= 4);
-         BFD_ASSERT (splt->_cooked_size >= PLT_ENTRY_SIZE);
+         BFD_ASSERT (sgotplt->size >= 4);
+         BFD_ASSERT (splt->size >= PLT_ENTRY_SIZE);
 
-         sgotplt->_cooked_size -= 4;
-         splt->_cooked_size -= PLT_ENTRY_SIZE;
-
-         /* Shrink _raw_sizes (see comment above).  */
-         sgotplt->_raw_size = sgotplt->_cooked_size;
-         splt->_raw_size = splt->_cooked_size;
+         sgotplt->size -= 4;
+         splt->size -= PLT_ENTRY_SIZE;
        }
     }
 }
@@ -5026,7 +4996,7 @@ relax_property_section (abfd, sec, link_info)
   internal_relocs = retrieve_internal_relocs (abfd, sec, 
                                              link_info->keep_memory);
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
@@ -5117,7 +5087,7 @@ relax_property_section (abfd, sec, link_info)
       pin_contents (sec, contents);
 
       last_irel_offset = (bfd_vma) -1;
-      section_size = (sec->_cooked_size ? sec->_cooked_size : sec->_raw_size);
+      section_size = sec->size;
       BFD_ASSERT (section_size % 8 == 0);
 
       for (offset = 0; offset < section_size; offset += 8)
@@ -5249,13 +5219,7 @@ relax_property_section (abfd, sec, link_info)
          /* Clear the removed bytes.  */
          memset (&contents[section_size - removed_bytes], 0, removed_bytes);
 
-         sec->_cooked_size = section_size - removed_bytes;
-         /* Also shrink _raw_size.  (The code in relocate_section that
-            checks that relocations are within the section must use
-            _raw_size because of the way the stabs sections are
-            relaxed; shrinking _raw_size means that these checks will
-            not be unnecessarily lax.)  */
-         sec->_raw_size = sec->_cooked_size;
+         sec->size = section_size - removed_bytes;
 
          if (xtensa_is_littable_section (sec))
            {
@@ -5265,13 +5229,7 @@ relax_property_section (abfd, sec, link_info)
                  asection *sgotloc =
                    bfd_get_section_by_name (dynobj, ".got.loc");
                  if (sgotloc)
-                   {
-                     bfd_size_type sgotloc_size =
-                       (sgotloc->_cooked_size ? sgotloc->_cooked_size
-                        : sgotloc->_raw_size);
-                     sgotloc->_cooked_size = sgotloc_size - removed_bytes;
-                     sgotloc->_raw_size = sgotloc_size - removed_bytes;
-                   }
+                   sgotloc->size -= removed_bytes;
                }
            }
        }
@@ -5676,12 +5634,10 @@ xtensa_get_property_section_name (sec, base_name)
       prop_sec_name[linkonce_len + 1] = '.';
 
       suffix = sec->name + linkonce_len;
-      while (*suffix)
-       {
-         suffix += 1;
-         if (suffix[-1] == '.')
-           break;
-       }
+      /* For backward compatibility, replace "t." instead of inserting
+        the new linkonce_kind.  */
+      if (strncmp (suffix, "t.", 2) == 0)
+       suffix += 2;
       strcpy (prop_sec_name + linkonce_len + 2, suffix);
 
       return prop_sec_name;
@@ -5732,7 +5688,7 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure)
       /* Assume worst-case offsets: L32R at the very end of the ".plt"
         section referencing a literal at the very beginning of
         ".got.plt".  This is very close to the real dependence, anyway.  */
-      (*callback) (sec, sec->_raw_size, sgotplt, 0, closure);
+      (*callback) (sec, sec->size, sgotplt, 0, closure);
     }
 
   internal_relocs = retrieve_internal_relocs (abfd, sec, 
@@ -5743,7 +5699,7 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure)
 
   /* Cache the contents for the duration of this scan.  */
   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->_raw_size != 0)
+  if (contents == NULL && sec->size != 0)
     {
       ok = FALSE;
       goto error_return;
@@ -5825,7 +5781,6 @@ static struct bfd_elf_special_section const elf_xtensa_special_sections[]=
 
 #define elf_info_to_howto                   elf_xtensa_info_to_howto_rela
 
-#define bfd_elf32_bfd_final_link            bfd_elf32_bfd_final_link
 #define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
 #define bfd_elf32_new_section_hook          elf_xtensa_new_section_hook
 #define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data
This page took 0.038236 seconds and 4 git commands to generate.