Warn relocation in readonly section in a shared object.
[binutils-gdb.git] / bfd / elf32-i386.c
index 3d8e2dfc7b8619d43117c1a266e2a2c373c75f8b..e32ec831c72b03bb5ca4221f282e155e823de244 100644 (file)
@@ -324,7 +324,7 @@ elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
     case BFD_RELOC_386_IRELATIVE:
       TRACE ("BFD_RELOC_386_IRELATIVE");
-      return &elf_howto_table[R_386_IRELATIVE];
+      return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset];
 
     case BFD_RELOC_VTABLE_INHERIT:
       TRACE ("BFD_RELOC_VTABLE_INHERIT");
@@ -2384,6 +2384,10 @@ elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
+  /* Skip local IFUNC symbols. */
+  if (h->forced_local && h->type == STT_GNU_IFUNC)
+    return TRUE;
+
   eh = (struct elf_i386_link_hash_entry *) h;
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
@@ -2395,6 +2399,11 @@ elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
          info->flags |= DF_TEXTREL;
 
+         if (info->warn_shared_textrel && info->shared)
+           info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
+                                   p->sec->owner, h->root.root.string,
+                                   p->sec);
+
          /* Not an error, just cut short the traversal.  */
          return FALSE;
        }
@@ -2478,7 +2487,13 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                  srel = elf_section_data (p->sec)->sreloc;
                  srel->size += p->count * sizeof (Elf32_External_Rel);
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
-                   info->flags |= DF_TEXTREL;
+                   {
+                     info->flags |= DF_TEXTREL;
+                     if (info->warn_shared_textrel && info->shared)
+                       info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
+                                               p->sec->owner, p->sec);
+                     break;
+                   }
                }
            }
        }
@@ -4189,7 +4204,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
          || plt == NULL
          || gotplt == NULL
          || relplt == NULL)
-       abort ();
+       return FALSE;
 
       /* Get the index in the procedure linkage table which
         corresponds to this symbol.  This is the index of this symbol
@@ -4705,8 +4720,9 @@ elf_i386_add_symbol_hook (bfd * abfd,
                          bfd_vma * valp ATTRIBUTE_UNUSED)
 {
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
   return TRUE;
 }