/* Emulation code used by all ELF targets.
   Copyright (C) 1991-2020 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 "elf-bfd.h"
#include "ldelfgen.h"

void
ldelf_map_segments (bfd_boolean need_layout)
{
  int tries = 10;

  do
    {
      lang_relax_sections (need_layout);
      need_layout = FALSE;

      if (link_info.output_bfd->xvec->flavour == 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))
	    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"));

  if (link_info.output_bfd->xvec->flavour == 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"));
    }
}

/* 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_strsym_iter_cb_arg
{
  struct elf_sym_strtab *syms;
  bfd_size_type symcount;
  struct elf_strtab_hash *symstrtab;
  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_strsym_iter_cb_arg *arg =
    (struct ctf_strsym_iter_cb_arg *) arg_;

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

  if (arg->next_i >= _bfd_elf_strtab_len (arg->symstrtab))
    {
      arg->next_i = 0;
      return NULL;
    }

  ret = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i++, &off);
  *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;
}

/* Return symbols from the symbol table to libctf, one by one.  We assume (and
   assert) that the symbols in the elf_link_hash_table are in strictly ascending
   order, and that none will be added in between existing ones.  Returns NULL
   when iteration is complete.  */

static struct ctf_link_sym *
ldelf_ctf_symbols_iter_cb (struct ctf_link_sym *dest,
					   void *arg_)
{
  struct ctf_strsym_iter_cb_arg *arg =
    (struct ctf_strsym_iter_cb_arg *) arg_;

  if (arg->next_i > arg->symcount)
    {
      arg->next_i = 0;
      arg->next_idx = 0;
      return NULL;
    }

  ASSERT (arg->syms[arg->next_i].dest_index == arg->next_idx);
  dest->st_name = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i, NULL);
  dest->st_shndx = arg->syms[arg->next_i].sym.st_shndx;
  dest->st_type = ELF_ST_TYPE (arg->syms[arg->next_i].sym.st_info);
  dest->st_value = arg->syms[arg->next_i].sym.st_value;
  arg->next_i++;
  return dest;
}

void
ldelf_examine_strtab_for_ctf
  (struct ctf_file *ctf_output, struct elf_sym_strtab *syms,
   bfd_size_type symcount, struct elf_strtab_hash *symstrtab)
{
  struct ctf_strsym_iter_cb_arg args = { syms, symcount, symstrtab,
					  0, 0 };
   if (!ctf_output)
     return;

   if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
       && !bfd_link_relocatable (&link_info))
    {
      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)));

      if (ctf_link_shuffle_syms (ctf_output, ldelf_ctf_symbols_iter_cb,
				 &args) < 0)
	einfo (_("%F%P: warning: CTF symbol shuffling failed; slight space "
		 "cost: %s\n"), ctf_errmsg (ctf_errno (ctf_output)));
    }
}
