bfd/
[binutils-gdb.git] / bfd / elf32-xtensa.c
index 867832f08605536997c774e96fcb2dd80f137690..3322c9efd685178eb83d44e2f02adc71d49b2316 100644 (file)
@@ -102,6 +102,8 @@ static bfd_boolean elf_xtensa_new_section_hook
 
 /* Local helper functions.  */
 
+static bfd_boolean xtensa_elf_dynamic_symbol_p
+  PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
 static int property_table_compare
   PARAMS ((const PTR, const PTR));
 static bfd_boolean elf_xtensa_in_literal_pool
@@ -131,8 +133,6 @@ static void do_fix_for_relocatable_link
   PARAMS ((Elf_Internal_Rela *, bfd *, asection *));
 static void do_fix_for_final_link
   PARAMS ((Elf_Internal_Rela *, asection *, bfd_vma *));
-static bfd_boolean xtensa_elf_dynamic_symbol_p
-  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
 static bfd_vma elf_xtensa_create_plt_entry
   PARAMS ((bfd *, bfd *, unsigned));
 static int elf_xtensa_combine_prop_entries
@@ -233,7 +233,7 @@ typedef struct xtensa_relax_info_struct xtensa_relax_info;
    The actual PLT code must be split into multiple sections and all
    the sections have to be created before size_dynamic_sections,
    where we figure out the exact number of PLT entries that will be
-   needed.  It is OK is this count is an overestimate, e.g., some
+   needed.  It is OK if this count is an overestimate, e.g., some
    relocations may be removed by GC.  */
 
 static int plt_reloc_count = 0;
@@ -449,6 +449,21 @@ static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] =
   0                    /* unused */
 };
 
+
+static inline bfd_boolean
+xtensa_elf_dynamic_symbol_p (h, info)
+     struct elf_link_hash_entry *h;
+     struct bfd_link_info *info;
+{
+  /* Check if we should do dynamic things to this symbol.  The
+     "ignore_protected" argument need not be set, because Xtensa code
+     does not require special handling of STV_PROTECTED to make function
+     pointer comparisons work properly.  The PLT addresses are never
+     used for function pointers.  */
+
+  return _bfd_elf_dynamic_symbol_p (h, info, 0);
+}
+
 \f
 static int
 property_table_compare (ap, bp)
@@ -1063,7 +1078,7 @@ elf_xtensa_fix_refcounts (h, arg)
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
-  if (! xtensa_elf_dynamic_symbol_p (info, h))
+  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
@@ -1264,12 +1279,9 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
            continue;
          for (s = abfd->sections; s != NULL; s = s->next)
            {
-             /* Skip input sections that are being discarded.  */
-             if (!bfd_is_abs_section (s)
-                 && bfd_is_abs_section (s->output_section))
-               continue;
-
-             if (xtensa_is_littable_section (s) && s != spltlittbl)
+             if (! elf_discarded_section (s)
+                 && xtensa_is_littable_section (s)
+                 && s != spltlittbl)
                sgotloc->_raw_size += s->_raw_size;
            }
        }
@@ -1833,17 +1845,6 @@ elf_xtensa_create_plt_entry (dynobj, output_bfd, reloc_index)
 }
 
 
-static bfd_boolean
-xtensa_elf_dynamic_symbol_p (info, h)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
-{
-  /* ??? What, if anything, needs to happen wrt STV_PROTECTED and PLT
-     entries?  For now assume the worst.  */
-  return _bfd_elf_dynamic_symbol_p (h, info, 1);
-}
-
-
 /* Relocate an Xtensa ELF section.  This is invoked by the linker for
    both relocatable and final links.  */
 
@@ -2070,7 +2071,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
       /* Generate dynamic relocations.  */
       if (elf_hash_table (info)->dynamic_sections_created)
        {
-         bfd_boolean dynamic_symbol = xtensa_elf_dynamic_symbol_p (info, h);
+         bfd_boolean dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);
 
          if (dynamic_symbol && (r_type == R_XTENSA_OP0
                                 || r_type == R_XTENSA_OP1
@@ -2259,7 +2260,11 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc)
   sgotloc_size = (sgotloc->_cooked_size != 0
                  ? sgotloc->_cooked_size : sgotloc->_raw_size);
   if (sgotloc_size != section_size)
-    return -1;
+    {
+      (*_bfd_error_handler)
+       ("internal inconsistency in size of .got.loc section");
+      return -1;
+    }
 
   contents = (bfd_byte *) bfd_malloc (section_size);
   table = (property_table_entry *)
@@ -2479,8 +2484,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info)
   BFD_ASSERT (! info->relocatable);
   sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
   sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
-  if (!sxtlit || !sgotloc)
-    return FALSE;
+  BFD_ASSERT (sxtlit && sgotloc);
   num_xtlit_entries =
     elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
   if (num_xtlit_entries < 0)
@@ -2578,7 +2582,7 @@ 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\n",
+       ("%s: incompatible machine type. Output is 0x%x. Input is 0x%x",
         bfd_archive_filename (ibfd), out_mach, in_mach);
       bfd_set_error (bfd_error_wrong_format);
       return FALSE;
@@ -2824,6 +2828,24 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec)
       sec->_cooked_size = section_size - removed_bytes;
       /* Also shrink _raw_size.  See comments in relax_property_section.  */
       sec->_raw_size = sec->_cooked_size;
+
+      if (xtensa_is_littable_section (sec))
+       {
+         bfd *dynobj = elf_hash_table (info)->dynobj;
+         if (dynobj)
+           {
+             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;
+               }
+           }
+       }
     }
   else
     {
@@ -3102,7 +3124,7 @@ elf_xtensa_do_asm_simplify (contents, address, content_length)
   if (content_length < address)
     {
       (*_bfd_error_handler)
-       ("Attempt to convert L32R/CALLX to CALL failed\n");
+       ("Attempt to convert L32R/CALLX to CALL failed");
       return bfd_reloc_other;
     }
 
@@ -3111,7 +3133,7 @@ elf_xtensa_do_asm_simplify (contents, address, content_length)
   if (direct_call_opcode == XTENSA_UNDEFINED)
     {
       (*_bfd_error_handler)
-       ("Attempt to convert L32R/CALLX to CALL failed\n");
+       ("Attempt to convert L32R/CALLX to CALL failed");
       return bfd_reloc_other;
     }
   
@@ -4945,7 +4967,7 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel)
   else
     h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
-  dynamic_symbol = xtensa_elf_dynamic_symbol_p (info, h);
+  dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);
 
   if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
       && (input_section->flags & SEC_ALLOC) != 0
@@ -5843,6 +5865,21 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure)
   return ok;
 }
 
+/* The default literal sections should always be marked as "code" (i.e.,
+   SHF_EXECINSTR).  This is particularly important for the Linux kernel
+   module loader so that the literals are not placed after the text.  */
+static struct bfd_elf_special_section const elf_xtensa_special_sections[]=
+{
+  { ".literal",                0,      NULL,   0,
+    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
+  { ".init.literal",   0,      NULL,   0,
+    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
+  { ".fini.literal",   0,      NULL,   0,
+    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
+  { NULL,              0,      NULL,   0,
+    0,                 0 }
+};
+
 \f
 #ifndef ELF_ARCH
 #define TARGET_LITTLE_SYM              bfd_elf32_xtensa_le_vec
@@ -5903,5 +5940,6 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure)
 #define elf_backend_reloc_type_class        elf_xtensa_reloc_type_class
 #define elf_backend_relocate_section        elf_xtensa_relocate_section
 #define elf_backend_size_dynamic_sections    elf_xtensa_size_dynamic_sections
+#define elf_backend_special_sections        elf_xtensa_special_sections
 
 #include "elf32-target.h"