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