* bfd-in.h (bfd_get_dynamic_symcount): Define.
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 1e886a593350b5f30640a752d0f8889d1ed89e3c..ef22e68e23568415cd052b636337f3ea142433c5 100644 (file)
@@ -45,7 +45,8 @@ static boolean create_got_section
 static boolean elf_i386_create_dynamic_sections
   PARAMS((bfd *, struct bfd_link_info *));
 static void elf_i386_copy_indirect_symbol
-  PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+  PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
+          struct elf_link_hash_entry *));
 static int elf_i386_tls_transition
   PARAMS ((struct bfd_link_info *, int, int));
 
@@ -697,6 +698,7 @@ elf_i386_link_hash_table_create (abfd)
   ret->srelplt = NULL;
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
+  ret->tls_ldm_got.refcount = 0;
   ret->sym_sec.abfd = NULL;
 
   return &ret->elf.root;
@@ -766,7 +768,8 @@ elf_i386_create_dynamic_sections (dynobj, info)
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf_i386_copy_indirect_symbol (dir, ind)
+elf_i386_copy_indirect_symbol (bed, dir, ind)
+     struct elf_backend_data *bed;
      struct elf_link_hash_entry *dir, *ind;
 {
   struct elf_i386_link_hash_entry *edir, *eind;
@@ -808,7 +811,13 @@ elf_i386_copy_indirect_symbol (dir, ind)
       eind->dyn_relocs = NULL;
     }
 
-  _bfd_elf_link_hash_copy_indirect (dir, ind);
+  if (ind->root.type == bfd_link_hash_indirect
+      && dir->got.refcount <= 0)
+    {
+      edir->tls_type = eind->tls_type;
+      eind->tls_type = GOT_UNKNOWN;
+    }
+  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
 static int
@@ -1953,7 +1962,9 @@ static bfd_vma
 dtpoff_base (info)
      struct bfd_link_info *info;
 {
-  BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
+  /* If tls_segment is NULL, we should have signalled an error already.  */
+  if (elf_hash_table (info)->tls_segment == NULL)
+    return 0;
   return elf_hash_table (info)->tls_segment->start;
 }
 
@@ -1968,7 +1979,9 @@ tpoff (info, address)
   struct elf_link_tls_segment *tls_segment
     = elf_hash_table (info)->tls_segment;
 
-  BFD_ASSERT (tls_segment != NULL);
+  /* If tls_segment is NULL, we should have signalled an error already.  */
+  if (tls_segment == NULL)
+    return 0;
   return (align_power (tls_segment->size, tls_segment->align)
          + tls_segment->start - address);
 }
@@ -2560,13 +2573,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
              outrel.r_offset = (htab->sgot->output_section->vma
                                 + htab->sgot->output_offset + off);
 
-             bfd_put_32 (output_bfd, 0,
-                         htab->sgot->contents + off);
              indx = h && h->dynindx != -1 ? h->dynindx : 0;
              if (r_type == R_386_TLS_GD)
                dr_type = R_386_TLS_DTPMOD32;
              else
                dr_type = R_386_TLS_TPOFF32;
+             if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
+               bfd_put_32 (output_bfd, dtpoff_base (info) - relocation,
+                           htab->sgot->contents + off);
+             else
+               bfd_put_32 (output_bfd, 0,
+                           htab->sgot->contents + off);
              outrel.r_info = ELF32_R_INFO (indx, dr_type);
              loc = (Elf32_External_Rel *) htab->srelgot->contents;
              loc += htab->srelgot->reloc_count++;
@@ -2737,21 +2754,21 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
        }
 
-      /* FIXME: Why do we allow debugging sections to escape this error?
-        More importantly, why do we not emit dynamic relocs for
-        R_386_32 above in debugging sections (which are ! SEC_ALLOC)?
-        If we had emitted the dynamic reloc, we could remove the
-        fudge here.  */
+      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+        because such sections are not SEC_ALLOC and thus ld.so will
+        not process them.  */
       if (unresolved_reloc
-         && !(info->shared
-              && (input_section->flags & SEC_DEBUGGING) != 0
+         && !((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),
-          (long) rel->r_offset,
-          h->root.root.string);
+       {
+         (*_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),
+            (long) rel->r_offset,
+            h->root.root.string);
+         return false;
+       }
 
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                    contents, rel->r_offset,
@@ -3105,11 +3122,13 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
   return true;
 }
 
+#ifndef ELF_ARCH
 #define TARGET_LITTLE_SYM              bfd_elf32_i386_vec
 #define TARGET_LITTLE_NAME             "elf32-i386"
 #define ELF_ARCH                       bfd_arch_i386
 #define ELF_MACHINE_CODE               EM_386
 #define ELF_MAXPAGESIZE                        0x1000
+#endif /* ELF_ARCH */
 
 #define elf_backend_can_gc_sections    1
 #define elf_backend_can_refcount       1
This page took 0.026833 seconds and 4 git commands to generate.