PR ld/1540
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 35716796068032c038515300557d7ff57ad4ad3e..061a9cb32d88d6bf70bee1436a1f2ac0489dc67f 100644 (file)
@@ -602,7 +602,7 @@ struct elf_i386_link_hash_table
   asection *srelplt;
   asection *sdynbss;
   asection *srelbss;
-  
+
   /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
   asection *srelplt2;
 
@@ -614,7 +614,7 @@ struct elf_i386_link_hash_table
 
   /* Value used to fill the last word of the first plt entry.  */
   bfd_byte plt0_pad_byte;
-  
+
   union {
     bfd_signed_vma refcount;
     bfd_vma offset;
@@ -772,7 +772,7 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf_i386_copy_indirect_symbol (struct bfd_link_info *info,
                               struct elf_link_hash_entry *dir,
                               struct elf_link_hash_entry *ind)
 {
@@ -788,10 +788,7 @@ elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
          struct elf_i386_dyn_relocs **pp;
          struct elf_i386_dyn_relocs *p;
 
-         if (ind->root.type == bfd_link_hash_indirect)
-           abort ();
-
-         /* Add reloc counts against the weak sym to the strong sym
+         /* Add reloc counts against the indirect sym to the direct sym
             list.  Merge any entries against the same section.  */
          for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
            {
@@ -836,7 +833,7 @@ elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
       dir->pointer_equality_needed |= ind->pointer_equality_needed;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
@@ -911,7 +908,12 @@ elf_i386_check_relocs (bfd *abfd,
       if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
       else
-       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+       {
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+       }
 
       r_type = elf_i386_tls_transition (info, r_type, h == NULL);
 
@@ -1160,6 +1162,7 @@ elf_i386_check_relocs (bfd *abfd,
                }
              else
                {
+                 void **vpp;
                  /* Track dynamic relocs needed for local syms too.
                     We really need local syms available to do this
                     easily.  Oh well.  */
@@ -1170,8 +1173,8 @@ elf_i386_check_relocs (bfd *abfd,
                  if (s == NULL)
                    return FALSE;
 
-                 head = ((struct elf_i386_dyn_relocs **)
-                         &elf_section_data (s)->local_dynrel);
+                 vpp = &elf_section_data (s)->local_dynrel;
+                 head = (struct elf_i386_dyn_relocs **)vpp;
                }
 
              p = *head;
@@ -1431,7 +1434,13 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
-  if (ELIMINATE_COPY_RELOCS)
+  htab = elf_i386_hash_table (info);
+
+  /* If there aren't any dynamic relocs in read-only sections, then
+     we can keep the dynamic relocs and avoid the copy reloc.  This
+     doesn't work on VxWorks, where we can not have dynamic relocations
+     (other than copy and jump slot relocations) in an executable.  */
+  if (ELIMINATE_COPY_RELOCS && !htab->is_vxworks)
     {
       struct elf_i386_link_hash_entry * eh;
       struct elf_i386_dyn_relocs *p;
@@ -1444,8 +1453,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
            break;
        }
 
-      /* If we didn't find any dynamic relocs in read-only sections, then
-        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
       if (p == NULL)
        {
          h->non_got_ref = 0;
@@ -1453,6 +1460,13 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
        }
     }
 
+  if (h->size == 0)
+    {
+      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
+                            h->root.root.string);
+      return TRUE;
+    }
+
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -1463,8 +1477,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
-  htab = elf_i386_hash_table (info);
-
   /* We must generate a R_386_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
@@ -1809,8 +1821,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
          struct elf_i386_dyn_relocs *p;
 
-         for (p = *((struct elf_i386_dyn_relocs **)
-                    &elf_section_data (s)->local_dynrel);
+         for (p = ((struct elf_i386_dyn_relocs *)
+                    elf_section_data (s)->local_dynrel);
               p != NULL;
               p = p->next)
            {
@@ -1914,7 +1926,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       if (s == htab->splt
          || s == htab->sgot
-         || s == htab->sgotplt)
+         || s == htab->sgotplt
+         || s == htab->sdynbss)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -1940,7 +1953,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          continue;
        }
 
-      if (s->size == 0 && strip_section)
+      if (s->size == 0)
        {
          /* If we don't need this section, strip it from the
             output file.  This is mostly to handle .rel.bss and
@@ -1951,11 +1964,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
             adjust_dynamic_symbol is called, and it is that
             function which decides whether anything needs to go
             into these sections.  */
-
-         s->flags |= SEC_EXCLUDE;
+         if (strip_section)
+           s->flags |= SEC_EXCLUDE;
          continue;
        }
 
+      if ((s->flags & SEC_HAS_CONTENTS) == 0)
+       continue;
+
       /* Allocate memory for the section contents.  We use bfd_zalloc
         here in case unused entries are not reclaimed before the
         section's contents are written out.  This should not happen,
@@ -2267,6 +2283,21 @@ elf_i386_relocate_section (bfd *output_bfd,
                                   unresolved_reloc, warned);
        }
 
+      if (r_symndx == 0)
+       {
+       /* r_symndx will be zero only for relocs against symbols from
+          removed linkonce sections, or sections discarded by a linker
+          script.  For these relocs, we just want the section contents
+          zeroed.  Avoid any special processing in the switch below.  */
+         r_type = R_386_NONE;
+
+         relocation = 0;
+         if (howto->pc_relative)
+           relocation = (input_section->output_section->vma
+                         + input_section->output_offset
+                         + rel->r_offset);
+       }
+
       switch (r_type)
        {
        case R_386_GOT32:
@@ -2368,6 +2399,7 @@ elf_i386_relocate_section (bfd *output_bfd,
             for shared library since it may not be local when used
             as function address.  */
          if (info->shared
+             && !info->executable
              && h
              && h->def_regular
              && h->type == STT_FUNC
@@ -2422,21 +2454,6 @@ elf_i386_relocate_section (bfd *output_bfd,
 
        case R_386_32:
        case R_386_PC32:
-         /* r_symndx will be zero only for relocs against symbols
-            from removed linkonce sections, or sections discarded by
-            a linker script.  */
-         if (r_symndx == 0)
-           {
-             /* Zero the section contents.  eh_frame generated by old
-                versions of gcc isn't edited by elf-eh-frame.c, so
-                FDEs for discarded linkonce functions might remain.
-                Putting zeros here will zero such FDE's address range.
-                This is a hint to unwinders and other consumers of
-                exception handling info that the FDE is invalid.  */
-             bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
-             break;
-           }
-
          if ((input_section->flags & SEC_ALLOC) == 0)
            break;
 
@@ -3018,10 +3035,11 @@ elf_i386_relocate_section (bfd *output_bfd,
               && h->def_dynamic))
        {
          (*_bfd_error_handler)
-           (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+           (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
             input_bfd,
             input_section,
             (long) rel->r_offset,
+            howto->name,
             h->root.root.string);
          return FALSE;
        }
@@ -3155,7 +3173,6 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
              bfd_elf32_swap_reloc_out (output_bfd, &rel,
              loc + sizeof (Elf32_External_Rel));
            }
-
        }
       else
        {
@@ -3443,7 +3460,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
          if (htab->is_vxworks && !info->shared)
            {
              int num_plts = (htab->splt->size / PLT_ENTRY_SIZE) - 1;
-             char *p;
+             unsigned char *p;
 
              p = htab->srelplt2->contents;
              if (info->shared)
This page took 0.028654 seconds and 4 git commands to generate.