/* Emulation code used by all ELF targets.
   Copyright (C) 1991-2025 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))
		    {
		      fatal (_("%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))
	    fatal (_("%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)
    fatal (_("%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))
	fatal (_("%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)
	fatal (_("%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)
	{
	  fatal (_("%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)
	fatal (_("%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
