/* IBM S/390-specific support for ELF 32 and 64 bit functions
   Copyright (C) 2000-2021 Free Software Foundation, Inc.
   Contributed by Andreas Krebbel.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */


/* Return TRUE if H is an IFUNC symbol.  Simply checking for the
   symbol type might not be enough since it might get changed to
   STT_FUNC for pointer equality reasons.  */
static inline bool
s390_is_ifunc_symbol_p (struct elf_link_hash_entry *h)
{
  struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
  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 bool
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 bool
s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
  flagword flags;
  asection *s;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct elf_link_hash_table *htab = elf_hash_table (info);

  if (htab->iplt != NULL)
    return true;

  flags = bed->dynamic_sec_flags;

  if (bfd_link_pic (info))
    {
      s = bfd_make_section_with_flags (abfd, ".rela.ifunc",
				       flags | SEC_READONLY);
      if (s == NULL
	  || !bfd_set_section_alignment (s, bed->s->log_file_align))
	return false;
      htab->irelifunc = s;
    }

  /* Create .iplt, .rel[a].iplt, and .igot.plt.  */
  s = bfd_make_section_with_flags (abfd, ".iplt",
				   flags | SEC_CODE | SEC_READONLY);
  if (s == NULL
      || !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
      || !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
      || !bfd_set_section_alignment (s, bed->s->log_file_align))
    return false;
  htab->igotplt = s;

  return true;
}


/* Allocate space in .plt, .got and associated reloc sections for
   dynamic relocs against a STT_GNU_IFUNC symbol definition.  */

static bool
s390_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
				    struct elf_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 = &h->dyn_relocs;

  htab = elf_hash_table (info);
  eh->ifunc_resolver_address = h->root.u.def.value;
  eh->ifunc_resolver_section = h->root.u.def.section;

  /* Support garbage collection against STT_GNU_IFUNC symbols.  */
  if (h->plt.refcount <= 0 && h->got.refcount <= 0)
    {
      /* When building shared library, we need to handle the case
	 where it is marked with regular reference, but not non-GOT
	 reference.  It may happen if we didn't see STT_GNU_IFUNC
	 symbol at the time when checking relocations.  */
      if (bfd_link_pic (info)
	  && !h->non_got_ref
	  && h->ref_regular)
	for (p = *head; p != NULL; p = p->next)
	  if (p->count)
	    {
	      h->non_got_ref = 1;
	      goto keep;
	    }

      h->got = htab->init_got_offset;
      h->plt = htab->init_plt_offset;
      *head = NULL;
      return true;
    }

  /* Return and discard space for dynamic relocations against it if
     it is never referenced in a non-shared object.  */
  if (!h->ref_regular)
    {
      if (h->plt.refcount > 0
	  || h->got.refcount > 0)
	abort ();
      h->got = htab->init_got_offset;
      h->plt = htab->init_plt_offset;
      *head = NULL;
      return true;
    }

 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.  */
  h->plt.offset = htab->iplt->size;
  h->needs_plt = 1;
  htab->iplt->size += PLT_ENTRY_SIZE;
  htab->igotplt->size += GOT_ENTRY_SIZE;
  htab->irelplt->size += RELA_ENTRY_SIZE;
  htab->irelplt->reloc_count++;

  /* In order to make pointer equality work with IFUNC symbols defined
     in a non-PIE executable and referenced in a shared lib, we turn
     the symbol into a STT_FUNC symbol and make the symbol value to
     point to the IPLT slot.  That way the referencing shared lib will
     always get the PLT slot address when resolving the respective
     R_390_GLOB_DAT/R_390_64 relocs on that symbol.  */
  if (bfd_link_pde (info)
      && h->def_regular
      && h->ref_dynamic)
    {
      h->root.u.def.section = htab->iplt;
      h->root.u.def.value = h->plt.offset;
      h->size = PLT_ENTRY_SIZE;
      h->type = STT_FUNC;
    }

  if (!bfd_link_pic (info))
    *head = NULL;

  /* Finally, allocate space.  */
  p = *head;
  if (p != NULL)
    {
      bfd_size_type count = 0;
      do
	{
	  count += p->count;
	  p = p->next;
	}
      while (p != NULL);
      htab->irelifunc->size += count * RELA_ENTRY_SIZE;
    }

  /* Decide whether the got.iplt slot can be used.  This has to be
     avoided if the values in the GOT slots could differ for pointer
     equality reasons.  */
  if (h->got.refcount <= 0
      || (bfd_link_pic (info)
	  && (h->dynindx == -1 || h->forced_local))
      || bfd_link_pie (info)
      || htab->sgot == NULL)
    {
      /* Use .got.iplt.  */
      h->got.offset = (bfd_vma) -1;
    }
  else
    {
      h->got.offset = htab->sgot->size;
      htab->sgot->size += GOT_ENTRY_SIZE;
      if (bfd_link_pic (info))
	htab->srelgot->size += RELA_ENTRY_SIZE;
    }

  return true;
}

static bool
elf_s390_allocate_local_syminfo (bfd *abfd, Elf_Internal_Shdr *symtab_hdr)
{
  bfd_size_type size;

  size = symtab_hdr->sh_info;
  size *= (sizeof (bfd_signed_vma)	 /* local got */
	   + sizeof (struct plt_entry)	 /* local plt */
	   + sizeof(char));		 /* local tls type */
  elf_local_got_refcounts (abfd) = ((bfd_signed_vma *)
				    bfd_zalloc (abfd, size));
  if (elf_local_got_refcounts (abfd) == NULL)
    return false;
  elf_s390_local_plt (abfd)
    = (struct plt_entry*)(elf_local_got_refcounts (abfd)
			  + symtab_hdr->sh_info);
  elf_s390_local_got_tls_type (abfd)
    = (char *) (elf_s390_local_plt (abfd) + symtab_hdr->sh_info);

  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
   hand, elf-eh-frame.c processing requires .eh_frame relocs to be
   sorted.  */

static bool
elf_s390_elf_sort_relocs_p (asection *sec)
{
  return (sec->flags & SEC_CODE) == 0;
}

/* Merge object attributes from IBFD into OBFD.  Raise an error if
   there are conflicting attributes.  */
static bool
elf_s390_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  obj_attribute *in_attr, *in_attrs;
  obj_attribute *out_attr, *out_attrs;

  if (!elf_known_obj_attributes_proc (obfd)[0].i)
    {
      /* This is the first object.  Copy the attributes.  */
      _bfd_elf_copy_obj_attributes (ibfd, obfd);

      /* Use the Tag_null value to indicate the attributes have been
	 initialized.  */
      elf_known_obj_attributes_proc (obfd)[0].i = 1;

      return true;
    }

  in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
  out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];

  /* Check for conflicting Tag_GNU_S390_ABI_Vector attributes and
     merge non-conflicting ones.  */
  in_attr = &in_attrs[Tag_GNU_S390_ABI_Vector];
  out_attr = &out_attrs[Tag_GNU_S390_ABI_Vector];

  if (in_attr->i > 2)
    _bfd_error_handler
      /* xgettext:c-format */
      (_("warning: %pB uses unknown vector ABI %d"), ibfd,
       in_attr->i);
  else if (out_attr->i > 2)
    _bfd_error_handler
      /* xgettext:c-format */
      (_("warning: %pB uses unknown vector ABI %d"), obfd,
       out_attr->i);
  else if (in_attr->i != out_attr->i)
    {
      out_attr->type = ATTR_TYPE_FLAG_INT_VAL;

      if (in_attr->i && out_attr->i)
	{
	  const char abi_str[3][9] = { "none", "software", "hardware" };

	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("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)
	out_attr->i = in_attr->i;
    }

  /* Merge Tag_compatibility attributes and any common GNU ones.  */
  _bfd_elf_merge_object_attributes (ibfd, info);

  return true;
}
