/* IBM S/390-specific support for ELF 32 and 64 bit functions
   Copyright (C) 2000-2026 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;
  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;
}
