daily update
[deliverable/binutils-gdb.git] / bfd / elf64-s390.c
index 6af39db96aef9db1df909cb63e77228eb6e2c104..21a58649d9d996ba905eb666444537ec97eae0d6 100644 (file)
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed Martin Schwidefsky (schwidefsky@de.ibm.com).
 
@@ -629,11 +629,13 @@ struct elf_s390_link_hash_entry
 #define elf_s390_hash_entry(ent) \
   ((struct elf_s390_link_hash_entry *)(ent))
 
+/* NOTE: Keep this structure in sync with
+   the one declared in elf32-s390.c.  */
 struct elf_s390_obj_tdata
 {
   struct elf_obj_tdata root;
 
-  /* tls_type for each local got entry.  */
+  /* TLS type for each local got entry.  */
   char *local_got_tls_type;
 };
 
@@ -643,17 +645,16 @@ struct elf_s390_obj_tdata
 #define elf_s390_local_got_tls_type(abfd) \
   (elf_s390_tdata (abfd)->local_got_tls_type)
 
+#define is_s390_elf(bfd)                               \
+  (bfd_get_flavour (bfd) == bfd_target_elf_flavour     \
+   && elf_tdata (bfd) != NULL                          \
+   && elf_object_id (bfd) == S390_ELF_TDATA)
+
 static bfd_boolean
 elf_s390_mkobject (bfd *abfd)
 {
-  if (abfd->tdata.any == NULL)
-    {
-      bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
-      abfd->tdata.any = bfd_zalloc (abfd, amt);
-      if (abfd->tdata.any == NULL)
-       return FALSE;
-    }
-  return bfd_elf_mkobject (abfd);
+  return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata),
+                                 S390_ELF_TDATA);
 }
 
 static bfd_boolean
@@ -937,8 +938,10 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
   if (info->relocatable)
     return TRUE;
 
+  BFD_ASSERT (is_s390_elf (abfd));
+
   htab = elf_s390_hash_table (info);
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
@@ -1225,7 +1228,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                    && ELF64_R_TYPE (rel->r_info) != R_390_PC32DBL
                    && ELF64_R_TYPE (rel->r_info) != R_390_PC64)
                   || (h != NULL
-                      && (! info->symbolic
+                      && (! SYMBOLIC_BIND (info, h)
                           || h->root.type == bfd_link_hash_defweak
                           || !h->def_regular))))
              || (ELIMINATE_COPY_RELOCS
@@ -1243,46 +1246,14 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                 this reloc.  */
              if (sreloc == NULL)
                {
-                 const char *name;
-                 bfd *dynobj;
-
-                 name = (bfd_elf_string_from_elf_section
-                         (abfd,
-                          elf_elfheader (abfd)->e_shstrndx,
-                          elf_section_data (sec)->rel_hdr.sh_name));
-                 if (name == NULL)
-                   return FALSE;
-
-                 if (! CONST_STRNEQ (name, ".rela")
-                     || strcmp (bfd_get_section_name (abfd, sec),
-                                name + 5) != 0)
-                   {
-                     (*_bfd_error_handler)
-                       (_("%B: bad relocation section name `%s\'"),
-                        abfd, name);
-                   }
-
                  if (htab->elf.dynobj == NULL)
                    htab->elf.dynobj = abfd;
 
-                 dynobj = htab->elf.dynobj;
-                 sreloc = bfd_get_section_by_name (dynobj, name);
+                 sreloc = _bfd_elf_make_dynamic_reloc_section
+                   (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
+
                  if (sreloc == NULL)
-                   {
-                     flagword flags;
-
-                     flags = (SEC_HAS_CONTENTS | SEC_READONLY
-                              | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-                     if ((sec->flags & SEC_ALLOC) != 0)
-                       flags |= SEC_ALLOC | SEC_LOAD;
-                     sreloc = bfd_make_section_with_flags (dynobj,
-                                                           name,
-                                                           flags);
-                     if (sreloc == NULL
-                         || ! bfd_set_section_alignment (dynobj, sreloc, 3))
-                       return FALSE;
-                   }
-                 elf_section_data (sec)->sreloc = sreloc;
+                   return FALSE;
                }
 
              /* If this is a global symbol, we count the number of
@@ -1392,9 +1363,12 @@ elf_s390_gc_sweep_hook (bfd *abfd,
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
 
+  if (info->relocatable)
+    return TRUE;
+
   elf_section_data (sec)->local_dynrel = NULL;
 
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
@@ -1567,11 +1541,9 @@ elf_s390_adjust_dynamic_symbol (info, h)
       || h->needs_plt)
     {
       if (h->plt.refcount <= 0
-         || (! info->shared
-             && !h->def_dynamic
-             && !h->ref_dynamic
-             && h->root.type != bfd_link_hash_undefweak
-             && h->root.type != bfd_link_hash_undefined))
+         || SYMBOL_CALLS_LOCAL (info, h)
+         || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+             && h->root.type == bfd_link_hash_undefweak))
        {
          /* This case can occur if we saw a PLT32 reloc in an input
             file, but the symbol was never referred to by a dynamic
@@ -1710,9 +1682,7 @@ allocate_dynrelocs (h, inf)
   htab = elf_s390_hash_table (info);
 
   if (htab->elf.dynamic_sections_created
-      && h->plt.refcount > 0
-      && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-         || h->root.type != bfd_link_hash_undefweak))
+      && h->plt.refcount > 0)
     {
       /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
@@ -1841,7 +1811,7 @@ allocate_dynrelocs (h, inf)
 
   if (info->shared)
     {
-      if (SYMBOL_REFERENCES_LOCAL (info, h))
+      if (SYMBOL_CALLS_LOCAL (info, h))
        {
          struct elf_s390_dyn_relocs **pp;
 
@@ -1990,7 +1960,7 @@ elf_s390_size_dynamic_sections (output_bfd, info)
       Elf_Internal_Shdr *symtab_hdr;
       asection *srela;
 
-      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+      if (! is_s390_elf (ibfd))
        continue;
 
       for (s = ibfd->sections; s != NULL; s = s->next)
@@ -2021,7 +1991,7 @@ elf_s390_size_dynamic_sections (output_bfd, info)
       if (!local_got)
        continue;
 
-      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+      symtab_hdr = &elf_symtab_hdr (ibfd);
       locsymcount = symtab_hdr->sh_info;
       end_local_got = local_got + locsymcount;
       local_tls_type = elf_s390_local_got_tls_type (ibfd);
@@ -2240,8 +2210,10 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
+  BFD_ASSERT (is_s390_elf (input_bfd));
+
   htab = elf_s390_hash_table (info);
-  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  symtab_hdr = &elf_symtab_hdr (input_bfd);
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
@@ -2364,10 +2336,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
              dyn = htab->elf.dynamic_sections_created;
              if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
                  || (info->shared
-                     && (info->symbolic
-                         || h->dynindx == -1
-                         || h->forced_local)
-                     && h->def_regular)
+                     && SYMBOL_REFERENCES_LOCAL (info, h))
                  || (ELF_ST_VISIBILITY (h->other)
                      && h->root.type == bfd_link_hash_undefweak))
                {
@@ -2543,8 +2512,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
                    && r_type != R_390_PC32
                    && r_type != R_390_PC32DBL
                    && r_type != R_390_PC64)
-                  || (h != NULL
-                      && !SYMBOL_REFERENCES_LOCAL (info, h))))
+                  || !SYMBOL_CALLS_LOCAL (info, h)))
              || (ELIMINATE_COPY_RELOCS
                  && !info->shared
                  && h != NULL
@@ -2587,7 +2555,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
                           || r_type == R_390_PC32DBL
                           || r_type == R_390_PC64
                           || !info->shared
-                          || !info->symbolic
+                          || !SYMBOLIC_BIND (info, h)
                           || !h->def_regular))
                {
                  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
@@ -3192,11 +3160,10 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
         The entry in the global offset table will already have been
         initialized in the relocate_section function.  */
       if (info->shared
-         && (info->symbolic
-             || h->dynindx == -1
-             || h->forced_local)
-         && h->def_regular)
+         && SYMBOL_REFERENCES_LOCAL (info, h))
        {
+         if (!h->def_regular)
+           return FALSE;
          BFD_ASSERT((h->got.offset & 1) != 0);
          rela.r_info = ELF64_R_INFO (0, R_390_RELATIVE);
          rela.r_addend = (h->root.u.def.value
This page took 0.026618 seconds and 4 git commands to generate.