Replace xmalloc/xfree with vector in jit.c
[deliverable/binutils-gdb.git] / bfd / elf-s390-common.c
index b37cb254577a2904d20b1b43d96c9ffe4a7cd7f3..d7cd7e60e9e376599268daf1f1c0ff1dc53ac160 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-2018 Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 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;
 
This page took 0.024733 seconds and 4 git commands to generate.