[gdb/testsuite] Remove dependence on tcl_unknown
[deliverable/binutils-gdb.git] / bfd / elf-s390-common.c
index d8f568b6187368fa929444378e180335753f0b00..ebe881fcb6e587c299927aac741413272ea0225e 100644 (file)
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for ELF 32 and 64 bit functions
 /* IBM S/390-specific support for ELF 32 and 64 bit functions
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Contributed by Andreas Krebbel.
 
    This file is part of BFD, the Binary File Descriptor library.
    Contributed by Andreas Krebbel.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -30,6 +30,87 @@ s390_is_ifunc_symbol_p (struct elf_link_hash_entry *h)
   return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
 }
 
   return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
 }
 
+/* Return true if .got.plt is supposed to be emitted after .got.  */
+
+static inline bfd_boolean
+s390_gotplt_after_got_p (struct bfd_link_info *info)
+{
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+
+  if (!htab->elf.sgot || !htab->elf.sgotplt)
+    return TRUE;
+
+  if (htab->elf.sgot->output_section == htab->elf.sgotplt->output_section)
+    {
+      if (htab->elf.sgot->output_offset < htab->elf.sgotplt->output_offset)
+       return TRUE;
+    }
+  else
+    {
+      if (htab->elf.sgot->output_section->vma
+         <= htab->elf.sgotplt->output_section->vma)
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* Return the value of the _GLOBAL_OFFSET_TABLE_ symbol.  */
+
+static inline bfd_vma
+s390_got_pointer (struct bfd_link_info *info)
+{
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+  bfd_vma got_pointer;
+
+  BFD_ASSERT (htab && htab->elf.hgot);
+
+  got_pointer = (htab->elf.hgot->root.u.def.section->output_section->vma
+                + htab->elf.hgot->root.u.def.section->output_offset);
+  /* Our ABI requires the GOT pointer to point at the very beginning
+     of the global offset table.  */
+  BFD_ASSERT (got_pointer
+             <= (htab->elf.sgot->output_section->vma
+                 + htab->elf.sgot->output_offset));
+  BFD_ASSERT (got_pointer
+             <= (htab->elf.sgotplt->output_section->vma
+                 + htab->elf.sgotplt->output_offset));
+
+  return got_pointer;
+}
+
+
+/* Return the offset of the .got versus _GLOBAL_OFFSET_TABLE_.  */
+
+static inline bfd_vma
+s390_got_offset (struct bfd_link_info *info)
+{
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+
+  /* The absolute address of the .got in the target image.  */
+  bfd_vma got_address = (htab->elf.sgot->output_section->vma
+                        + htab->elf.sgot->output_offset);
+
+  /* GOT offset must not be negative.  */
+  BFD_ASSERT (s390_got_pointer (info) <= got_address);
+  return got_address - s390_got_pointer (info);
+}
+
+/* Return the offset of the .got.plt versus _GLOBAL_OFFSET_TABLE_.  */
+
+static inline bfd_vma
+s390_gotplt_offset (struct bfd_link_info *info)
+{
+  struct elf_s390_link_hash_table *htab = elf_s390_hash_table (info);
+
+  /* The absolute address of the .got.plt in the target image.  */
+  bfd_vma gotplt_address = (htab->elf.sgotplt->output_section->vma
+                           + htab->elf.sgotplt->output_offset);
+
+  /* GOT offset must not be negative.  */
+  BFD_ASSERT (s390_got_pointer (info) <= gotplt_address);
+  return gotplt_address - s390_got_pointer (info);
+}
+
 /* Create sections needed by STT_GNU_IFUNC symbol.  */
 
 static bfd_boolean
 /* Create sections needed by STT_GNU_IFUNC symbol.  */
 
 static bfd_boolean
@@ -50,8 +131,7 @@ s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
       s = bfd_make_section_with_flags (abfd, ".rela.ifunc",
                                       flags | SEC_READONLY);
       if (s == NULL
       s = bfd_make_section_with_flags (abfd, ".rela.ifunc",
                                       flags | SEC_READONLY);
       if (s == NULL
-         || ! bfd_set_section_alignment (abfd, s,
-                                         bed->s->log_file_align))
+         || !bfd_set_section_alignment (s, bed->s->log_file_align))
        return FALSE;
       htab->irelifunc = s;
     }
        return FALSE;
       htab->irelifunc = s;
     }
@@ -60,21 +140,19 @@ s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
   s = bfd_make_section_with_flags (abfd, ".iplt",
                                   flags | SEC_CODE | SEC_READONLY);
   if (s == NULL
   s = bfd_make_section_with_flags (abfd, ".iplt",
                                   flags | SEC_CODE | SEC_READONLY);
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+      || !bfd_set_section_alignment (s, bed->plt_alignment))
     return FALSE;
   htab->iplt = s;
 
   s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags | SEC_READONLY);
   if (s == NULL
     return FALSE;
   htab->iplt = s;
 
   s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags | SEC_READONLY);
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s,
-                                     bed->s->log_file_align))
+      || !bfd_set_section_alignment (s, bed->s->log_file_align))
     return FALSE;
   htab->irelplt = s;
 
   s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
   if (s == NULL
     return FALSE;
   htab->irelplt = s;
 
   s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s,
-                                    bed->s->log_file_align))
+      || !bfd_set_section_alignment (s, bed->s->log_file_align))
     return FALSE;
   htab->igotplt = s;
 
     return FALSE;
   htab->igotplt = s;
 
@@ -92,7 +170,7 @@ s390_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
   struct elf_dyn_relocs *p;
   struct elf_link_hash_table *htab;
   struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
   struct elf_dyn_relocs *p;
   struct elf_link_hash_table *htab;
   struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
-  struct elf_dyn_relocs **head = &eh->dyn_relocs;
+  struct elf_dyn_relocs **head = &h->dyn_relocs;
 
   htab = elf_hash_table (info);
   eh->ifunc_resolver_address = h->root.u.def.value;
 
   htab = elf_hash_table (info);
   eh->ifunc_resolver_address = h->root.u.def.value;
@@ -134,7 +212,7 @@ s390_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
       return TRUE;
     }
 
       return TRUE;
     }
 
-keep:
+ keep:
   /* Without checking h->plt.refcount here we allocate a PLT slot.
      When setting plt.refcount in check_relocs it might not have been
      known that this will be an IFUNC symol.  */
   /* Without checking h->plt.refcount here we allocate a PLT slot.
      When setting plt.refcount in check_relocs it might not have been
      known that this will be an IFUNC symol.  */
@@ -223,25 +301,6 @@ elf_s390_allocate_local_syminfo (bfd *abfd, Elf_Internal_Shdr *symtab_hdr)
   return TRUE;
 }
 
   return TRUE;
 }
 
-/* Pick ELFOSABI_GNU if IFUNC symbols are used.  */
-
-static bfd_boolean
-elf_s390_add_symbol_hook (bfd *abfd,
-                         struct bfd_link_info *info,
-                         Elf_Internal_Sym *sym,
-                         const char **namep ATTRIBUTE_UNUSED,
-                         flagword *flagsp ATTRIBUTE_UNUSED,
-                         asection **secp ATTRIBUTE_UNUSED,
-                         bfd_vma *valp ATTRIBUTE_UNUSED)
-{
-  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
-      && (abfd->flags & DYNAMIC) == 0
-      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
-    elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
-
-  return TRUE;
-}
-
 /* Whether to sort relocs output by ld -r or ld --emit-relocs, by
    r_offset.  Don't do so for code sections.  We want to keep ordering
    of GDCALL / PLT32DBL for TLS optimizations as is.  On the other
 /* Whether to sort relocs output by ld -r or ld --emit-relocs, by
    r_offset.  Don't do so for code sections.  We want to keep ordering
    of GDCALL / PLT32DBL for TLS optimizations as is.  On the other
@@ -286,12 +345,12 @@ elf_s390_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
   if (in_attr->i > 2)
     _bfd_error_handler
       /* xgettext:c-format */
   if (in_attr->i > 2)
     _bfd_error_handler
       /* xgettext:c-format */
-      (_("Warning: %B uses unknown vector ABI %d"), ibfd,
+      (_("warning: %pB uses unknown vector ABI %d"), ibfd,
        in_attr->i);
   else if (out_attr->i > 2)
     _bfd_error_handler
       /* xgettext:c-format */
        in_attr->i);
   else if (out_attr->i > 2)
     _bfd_error_handler
       /* xgettext:c-format */
-      (_("Warning: %B uses unknown vector ABI %d"), obfd,
+      (_("warning: %pB uses unknown vector ABI %d"), obfd,
        out_attr->i);
   else if (in_attr->i != out_attr->i)
     {
        out_attr->i);
   else if (in_attr->i != out_attr->i)
     {
@@ -303,7 +362,7 @@ elf_s390_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
 
          _bfd_error_handler
            /* xgettext:c-format */
 
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("Warning: %B uses vector %s ABI, %B uses %s ABI"),
+           (_("warning: %pB uses vector %s ABI, %pB uses %s ABI"),
             ibfd, abi_str[in_attr->i], obfd, abi_str[out_attr->i]);
        }
       if (in_attr->i > out_attr->i)
             ibfd, abi_str[in_attr->i], obfd, abi_str[out_attr->i]);
        }
       if (in_attr->i > out_attr->i)
This page took 0.027897 seconds and 4 git commands to generate.