/* Emulation code used by all ELF targets.
   Copyright (C) 1991-2024 Free Software Foundation, Inc.

   This file is part of the GNU Binutils.

   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.  */

#include "sysdep.h"
#include "libiberty.h"
#include "bfd.h"
#include "bfdlink.h"
#include "ctf-api.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldctor.h"
#include "elf-bfd.h"
#include "elf/internal.h"
#include "ldelfgen.h"

/* Info attached to an output_section_statement about input sections,
   used when sorting SHF_LINK_ORDER sections.  */

struct os_sections
{
  /* Size allocated for isec.  */
  unsigned int alloc;
  /* Used entries in isec.  */
  unsigned int count;
  /* How many are SHF_LINK_ORDER.  */
  unsigned int ordered;
  /* Input sections attached to this output section.  */
  struct os_sections_input {
    lang_input_section_type *is;
    unsigned int idx;
  } isec[1];
};

/* Add IS to data kept for OS.  */

static bool
add_link_order_input_section (lang_input_section_type *is,
			      lang_output_section_statement_type *os)
{
  struct os_sections *os_info = os->data;
  asection *s;

  if (os_info == NULL)
    {
      os_info = xmalloc (sizeof (*os_info) + 63 * sizeof (*os_info->isec));
      os_info->alloc = 64;
      os_info->count = 0;
      os_info->ordered = 0;
      os->data = os_info;
    }
  if (os_info->count == os_info->alloc)
    {
      size_t want;
      os_info->alloc *= 2;
      want = sizeof (*os_info) + (os_info->alloc - 1) * sizeof (*os_info->isec);
      os_info = xrealloc (os_info, want);
      os->data = os_info;
    }
  os_info->isec[os_info->count].is = is;
  os_info->isec[os_info->count].idx = os_info->count;
  os_info->count++;
  s = is->section;
  if (bfd_get_flavour (s->owner) == bfd_target_elf_flavour
      && (s->flags & SEC_LINKER_CREATED) == 0
      && elf_linked_to_section (s) != NULL)
    os_info->ordered++;
  return false;
}

/* Run over the linker's statement list, extracting info about input
   sections attached to each output section.  */

static bool
link_order_scan (lang_statement_union_type *u,
		 lang_output_section_statement_type *os)
{
  asection *s;
  bool ret = false;

  for (; u != NULL; u = u->header.next)
    {
      switch (u->header.type)
	{
	case lang_wild_statement_enum:
	  if (link_order_scan (u->wild_statement.children.head, os))
	    ret = true;
	  break;
	case lang_constructors_statement_enum:
	  if (link_order_scan (constructor_list.head, os))
	    ret = true;
	  break;
	case lang_output_section_statement_enum:
	  if (u->output_section_statement.constraint != -1
	      && link_order_scan (u->output_section_statement.children.head,
				  &u->output_section_statement))
	    ret = true;
	  break;
	case lang_group_statement_enum:
	  if (link_order_scan (u->group_statement.children.head, os))
	    ret = true;
	  break;
	case lang_input_section_enum:
	  s = u->input_section.section;
	  if (s->output_section != NULL
	      && s->output_section->owner == link_info.output_bfd
	      && (s->output_section->flags & SEC_EXCLUDE) == 0
	      && ((s->output_section->flags & SEC_HAS_CONTENTS) != 0
		  || ((s->output_section->flags & (SEC_LOAD | SEC_THREAD_LOCAL))
		      == (SEC_LOAD | SEC_THREAD_LOCAL))))
	    if (add_link_order_input_section (&u->input_section, os))
	      ret = true;
	  break;
	default:
	  break;
	}
    }
  return ret;
}

/* Compare two sections based on the locations of the sections they are
   linked to.  Used by fixup_link_order.  */

static int
compare_link_order (const void *a, const void *b)
{
  const struct os_sections_input *ai = a;
  const struct os_sections_input *bi = b;
  asection *asec = NULL;
  asection *bsec = NULL;
  bfd_vma apos, bpos;

  if (bfd_get_flavour (ai->is->section->owner) == bfd_target_elf_flavour)
    asec = elf_linked_to_section (ai->is->section);
  if (bfd_get_flavour (bi->is->section->owner) == bfd_target_elf_flavour)
    bsec = elf_linked_to_section (bi->is->section);

  /* Place unordered sections before ordered sections.  */
  if (asec == NULL || bsec == NULL)
    {
      if (bsec != NULL)
	return -1;
      else if (asec != NULL)
	return 1;
      return ai->idx - bi->idx;
    }

  apos = asec->output_section->lma + asec->output_offset;
  bpos = bsec->output_section->lma + bsec->output_offset;

  if (apos < bpos)
    return -1;
  else if (apos > bpos)
    return 1;

  if (! bfd_link_relocatable (&link_info))
    {
      /* The only way we should get matching LMAs is when the first of
	 the two sections has zero size, or asec and bsec are the
	 same section.  */
      if (asec->size < bsec->size)
	return -1;
      else if (asec->size > bsec->size)
	return 1;
    }

  /* If they are both zero size then they almost certainly have the same
     VMA and thus are not ordered with respect to each other.  Test VMA
     anyway, and fall back to idx to make the result reproducible across
     qsort implementations.  */
  apos = asec->output_section->vma + asec->output_offset;
  bpos = bsec->output_section->vma + bsec->output_offset;
  if (apos < bpos)
    return -1;
  else if (apos > bpos)
    return 1;
  else
    return ai->idx - bi->idx;
}

/* Rearrange sections with SHF_LINK_ORDER into the same order as their
   linked sections.  */

static bool
fixup_link_order (lang_output_section_statement_type *os)
{
  struct os_sections *os_info = os->data;
  unsigned int i, j;
  lang_input_section_type **orig_is;
  asection **save_s;

  for (i = 0; i < os_info->count; i = j)
    {
      /* Normally a linker script will select SHF_LINK_ORDER sections
	 with an input section wildcard something like the following:
	 *(.IA_64.unwind* .gnu.linkonce.ia64unw.*)
	 However if some other random sections are smashed into an
	 output section, or if SHF_LINK_ORDER are split up by the
	 linker script, then we only want to sort sections matching a
	 given wildcard.  That's the purpose of the pattern test.  */
      for (j = i + 1; j < os_info->count; j++)
	if (os_info->isec[j].is->pattern != os_info->isec[i].is->pattern)
	  break;
      if (j - i > 1)
	qsort (&os_info->isec[i], j - i, sizeof (*os_info->isec),
	       compare_link_order);
    }
  for (i = 0; i < os_info->count; i++)
    if (os_info->isec[i].idx != i)
      break;
  if (i == os_info->count)
    return false;

  /* Now reorder the linker input section statements to reflect the
     proper sorting.  The is done by rewriting the existing statements
     rather than fiddling with lists, since the only thing we need to
     change is the bfd section pointer.  */
  orig_is = xmalloc (os_info->count * sizeof (*orig_is));
  save_s = xmalloc (os_info->count * sizeof (*save_s));
  for (i = 0; i < os_info->count; i++)
    {
      orig_is[os_info->isec[i].idx] = os_info->isec[i].is;
      save_s[i] = os_info->isec[i].is->section;
    }
  for (i = 0; i < os_info->count; i++)
    if (os_info->isec[i].idx != i)
      {
	orig_is[i]->section = save_s[i];
	/* Restore os_info to pristine state before the qsort, for the
	   next pass over sections.  */
	os_info->isec[i].is = orig_is[i];
	os_info->isec[i].idx = i;
      }
  free (save_s);
  free (orig_is);
  return true;
}

void
ldelf_map_segments (bool need_layout)
{
  int tries = 10;
  static bool done_link_order_scan = false;

  do
    {
      lang_relax_sections (need_layout);
      need_layout = false;

      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
	{
	  lang_output_section_statement_type *os;
	  if (!done_link_order_scan)
	    {
	      link_order_scan (statement_list.head, NULL);
	      done_link_order_scan = true;
	    }
	  for (os = (void *) lang_os_list.head; os != NULL; os = os->next)
	    {
	      struct os_sections *os_info = os->data;
	      if (os_info != NULL && os_info->ordered != 0)
		{
		  if (os_info->ordered != os_info->count
		      && bfd_link_relocatable (&link_info))
		    {
		      einfo (_("%F%P: "
			       "%pA has both ordered and unordered sections\n"),
			     os->bfd_section);
		      return;
		    }
		  if (os_info->count > 1
		      && fixup_link_order (os))
		    need_layout = true;
		}
	    }
	}

      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
	  && !bfd_link_relocatable (&link_info))
	{
	  bfd_size_type phdr_size;

	  phdr_size = elf_program_header_size (link_info.output_bfd);
	  /* If we don't have user supplied phdrs, throw away any
	     previous linker generated program headers.  */
	  if (lang_phdr_list == NULL)
	    elf_seg_map (link_info.output_bfd) = NULL;
	  if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
						  &link_info,
						  &need_layout))
	    einfo (_("%F%P: map sections to segments failed: %E\n"));

	  if (phdr_size != elf_program_header_size (link_info.output_bfd))
	    {
	      if (tries > 6)
		/* The first few times we allow any change to
		   phdr_size .  */
		need_layout = true;
	      else if (phdr_size
		       < elf_program_header_size (link_info.output_bfd))
		/* After that we only allow the size to grow.  */
		need_layout = true;
	      else
		elf_program_header_size (link_info.output_bfd) = phdr_size;
	    }
	}
    }
  while (need_layout && --tries);

  if (tries == 0)
    einfo (_("%F%P: looping in map_segments\n"));

  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
      && lang_phdr_list == NULL)
    {
      /* If we don't have user supplied phdrs, strip zero-sized dynamic
	 sections and regenerate program headers.  */
      const struct elf_backend_data *bed
	= get_elf_backend_data (link_info.output_bfd);
      if (bed->elf_backend_strip_zero_sized_dynamic_sections
	  && !bed->elf_backend_strip_zero_sized_dynamic_sections
		(&link_info))
	  einfo (_("%F%P: failed to strip zero-sized dynamic sections\n"));
    }
}

#ifdef ENABLE_LIBCTF
/* We want to emit CTF early if and only if we are not targetting ELF with this
   invocation.  */

int
ldelf_emit_ctf_early (void)
{
  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
    return 0;
  return 1;
}

/* Callbacks used to map from bfd types to libctf types, under libctf's
   control.  */

struct ctf_strtab_iter_cb_arg
{
  struct elf_strtab_hash *strtab;
  size_t next_i;
  size_t next_idx;
};

/* Return strings from the strtab to libctf, one by one.  Returns NULL when
   iteration is complete.  */

static const char *
ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
{
  bfd_size_type off;
  const char *ret;

  struct ctf_strtab_iter_cb_arg *arg =
    (struct ctf_strtab_iter_cb_arg *) arg_;

  /* There is no zeroth string.  */
  if (arg->next_i == 0)
    arg->next_i = 1;

  /* Hunt through strings until we fall off the end or find one with
     a nonzero refcount.  */
  do
    {
      if (arg->next_i >= _bfd_elf_strtab_len (arg->strtab))
	{
	  arg->next_i = 0;
	  return NULL;
	}

      ret = _bfd_elf_strtab_str (arg->strtab, arg->next_i++, &off);
    }
  while (ret == NULL);

  *offset = off;

  /* If we've overflowed, we cannot share any further strings: the CTF
     format cannot encode strings with such high offsets.  */
  if (*offset != off)
    return NULL;

  return ret;
}

void
ldelf_acquire_strings_for_ctf
  (struct ctf_dict *ctf_output, struct elf_strtab_hash *strtab)
{
  struct ctf_strtab_iter_cb_arg args = { strtab, 0, 0 };
  if (!ctf_output)
    return;

  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
    {
      if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
			       &args) < 0)
	einfo (_("%F%P: warning: CTF strtab association failed; strings will "
		 "not be shared: %s\n"),
	       ctf_errmsg (ctf_errno (ctf_output)));
    }
}

void
ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
			  struct elf_internal_sym *sym)
{
  ctf_link_sym_t lsym;

  if (!ctf_output)
     return;

  /* New symbol.  */
  if (sym != NULL)
    {
      lsym.st_name = NULL;
      lsym.st_nameidx = sym->st_name;
      lsym.st_nameidx_set = 1;
      lsym.st_symidx = symidx;
      lsym.st_shndx = sym->st_shndx;
      lsym.st_type = ELF_ST_TYPE (sym->st_info);
      lsym.st_value = sym->st_value;
      if (ctf_link_add_linker_symbol (ctf_output, &lsym) < 0)
	{
	  einfo (_("%F%P: warning: CTF symbol addition failed; CTF will "
		   "not be tied to symbols: %s\n"),
		 ctf_errmsg (ctf_errno (ctf_output)));
	}
    }
  else
    {
      /* Shuffle all the symbols.  */

      if (ctf_link_shuffle_syms (ctf_output) < 0)
	einfo (_("%F%P: warning: CTF symbol shuffling failed; CTF will "
		 "not be tied to symbols: %s\n"),
	       ctf_errmsg (ctf_errno (ctf_output)));
    }
}
#else
int
ldelf_emit_ctf_early (void)
{
  return 0;
}

void
ldelf_acquire_strings_for_ctf (struct ctf_dict *ctf_output ATTRIBUTE_UNUSED,
			       struct elf_strtab_hash *strtab ATTRIBUTE_UNUSED)
{}
void
ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output ATTRIBUTE_UNUSED,
			  int symidx ATTRIBUTE_UNUSED,
			  struct elf_internal_sym *sym ATTRIBUTE_UNUSED)
{}
#endif
