PR 1147
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 35716796068032c038515300557d7ff57ad4ad3e..a9dff218cab13c3267b941173291721059c355d6 100644 (file)
@@ -95,7 +95,7 @@ static reloc_howto_type elf_howto_table[]=
   HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_386_16",
        TRUE, 0xffff, 0xffff, FALSE),
-  HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
+  HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_signed,
        bfd_elf_generic_reloc, "R_386_PC16",
        TRUE, 0xffff, 0xffff, TRUE),
   HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
@@ -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;
@@ -911,7 +911,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);
 
@@ -1431,7 +1436,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 +1455,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;
@@ -1463,8 +1472,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.  */
@@ -1914,7 +1921,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 +1948,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 +1959,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 +2278,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 +2394,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 +2449,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;
 
@@ -3155,7 +3167,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 +3454,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.025633 seconds and 4 git commands to generate.