/* .sframe section processing.
   Copyright (C) 2022-2024 Free Software Foundation, Inc.

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

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "sframe-api.h"

/* Return TRUE if the function has been marked for deletion during the linking
   process.  */

static bool
sframe_decoder_func_deleted_p (struct sframe_dec_info *sfd_info,
			       unsigned int func_idx)
{
  if (func_idx < sfd_info->sfd_fde_count)
    return sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p;

  return false;
}

/* Mark the function in the decoder info for deletion.  */

static void
sframe_decoder_mark_func_deleted (struct sframe_dec_info *sfd_info,
				  unsigned int func_idx)
{
  if (func_idx < sfd_info->sfd_fde_count)
    sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p = true;
}

/* Get the relocation offset from the decoder info for the given function.  */

static unsigned int
sframe_decoder_get_func_r_offset (struct sframe_dec_info *sfd_info,
				  unsigned int func_idx)
{
  BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
  unsigned int func_r_offset
    = sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset;
  /* There must have been a reloc.  */
  BFD_ASSERT (func_r_offset);
  return func_r_offset;
}

/* Bookkeep the function relocation offset in the decoder info.  */

static void
sframe_decoder_set_func_r_offset (struct sframe_dec_info *sfd_info,
				  unsigned int func_idx,
				  unsigned int r_offset)
{
  if (func_idx < sfd_info->sfd_fde_count)
    sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset = r_offset;
}

/* Get the relocation index in the elf_reloc_cookie for the function.  */

static unsigned int
sframe_decoder_get_func_reloc_index (struct sframe_dec_info *sfd_info,
				     unsigned int func_idx)
{
  BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
  return sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index;
}

/* Bookkeep the relocation index in the elf_reloc_cookie for the function.  */

static void
sframe_decoder_set_func_reloc_index (struct sframe_dec_info *sfd_info,
				     unsigned int func_idx,
				     unsigned int reloc_index)
{
  if (func_idx < sfd_info->sfd_fde_count)
    sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index = reloc_index;
}

/* Initialize the set of additional information in CFD_INFO,
   needed for linking SEC.  Returns TRUE if setup is done successfully.  */

static bool
sframe_decoder_init_func_bfdinfo (asection *sec,
				  struct sframe_dec_info *sfd_info,
				  struct elf_reloc_cookie *cookie)
{
  unsigned int fde_count;
  unsigned int func_bfdinfo_size, i;

  fde_count = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
  sfd_info->sfd_fde_count = fde_count;

  /* Allocate and clear the memory.  */
  func_bfdinfo_size = (sizeof (struct sframe_func_bfdinfo)) * fde_count;
  sfd_info->sfd_func_bfdinfo
    = (struct sframe_func_bfdinfo*) bfd_malloc (func_bfdinfo_size);
  if (sfd_info->sfd_func_bfdinfo == NULL)
    return false;
  memset (sfd_info->sfd_func_bfdinfo, 0, func_bfdinfo_size);

  /* For linker generated .sframe sections, we have no relocs.  Skip.  */
  if ((sec->flags & SEC_LINKER_CREATED) && cookie->rels == NULL)
    return true;

  for (i = 0; i < fde_count; i++)
    {
      cookie->rel = cookie->rels + i;
      BFD_ASSERT (cookie->rel < cookie->relend);
      /* Bookkeep the relocation offset and relocation index of each function
	 for later use.  */
      sframe_decoder_set_func_r_offset (sfd_info, i, cookie->rel->r_offset);
      sframe_decoder_set_func_reloc_index (sfd_info, i,
					   (cookie->rel - cookie->rels));

      cookie->rel++;
    }
  BFD_ASSERT (cookie->rel == cookie->relend);

  return true;
}

/* Read the value from CONTENTS at the specified OFFSET for the given ABFD.  */

static bfd_vma
sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
		   unsigned int width)
{
  BFD_ASSERT (contents && offset);
  /* Supporting the usecase of reading only the 4-byte relocated
     value (signed offset for func start addr) for now.  */
  BFD_ASSERT (width == 4);
  /* FIXME endianness ?? */
  unsigned char *buf = contents + offset;
  bfd_vma value = bfd_get_signed_32 (abfd, buf);
  return value;
}

/* Return true if there is at least one non-empty .sframe section in
   input files.  Can only be called after ld has mapped input to
   output sections, and before sections are stripped.  */

bool
_bfd_elf_sframe_present (struct bfd_link_info *info)
{
  asection *sframe = bfd_get_section_by_name (info->output_bfd, ".sframe");

  if (sframe == NULL)
    return false;

  /* Count only sections which have at least a single FDE.  */
  for (sframe = sframe->map_head.s; sframe != NULL; sframe = sframe->map_head.s)
    /* Note that this may become an approximate check in the future when
       some ABI/arch begin to use the sfh_auxhdr_len.  When sfh_auxhdr_len has
       non-zero value, it will need to be accounted for in the calculation of
       the SFrame header size.  */
    if (sframe->size > sizeof (sframe_header))
      return true;
  return false;
}

/* Try to parse .sframe section SEC, which belongs to ABFD.  Store the
   information in the section's sec_info field on success.  COOKIE
   describes the relocations in SEC.

   Returns TRUE if success, FALSE if any error or failure.  */

bool
_bfd_elf_parse_sframe (bfd *abfd,
		       struct bfd_link_info *info ATTRIBUTE_UNUSED,
		       asection *sec, struct elf_reloc_cookie *cookie)
{
  bfd_byte *sfbuf = NULL;
  struct sframe_dec_info *sfd_info;
  sframe_decoder_ctx *sfd_ctx;
  bfd_size_type sf_size;
  int decerr = 0;

  if (sec->size == 0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
      || sec->sec_info_type != SEC_INFO_TYPE_NONE)
    {
      /* This file does not contain .sframe information.  */
      return false;
    }

  if (bfd_is_abs_section (sec->output_section))
    {
      /* At least one of the sections is being discarded from the
	 link, so we should just ignore them.  */
      return false;
    }

  /* Read the SFrame stack trace information from abfd.  */
  if (!_bfd_elf_mmap_section_contents (abfd, sec, &sfbuf))
    goto fail_no_free;

  /* Decode the buffer and keep decoded contents for later use.
     Relocations are performed later, but are such that the section's
     size is unaffected.  */
  sfd_info = bfd_malloc (sizeof (struct sframe_dec_info));
  sf_size = sec->size;

  sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr);
  sfd_ctx = sfd_info->sfd_ctx;
  if (!sfd_ctx)
    /* Free'ing up any memory held by decoder context is done by
       sframe_decode in case of error.  */
    goto fail_no_free;

  if (!sframe_decoder_init_func_bfdinfo (sec, sfd_info, cookie))
    {
      sframe_decoder_free (&sfd_ctx);
      goto fail_no_free;
    }

  elf_section_data (sec)->sec_info = sfd_info;
  sec->sec_info_type = SEC_INFO_TYPE_SFRAME;

  goto success;

fail_no_free:
  _bfd_error_handler
   (_("error in %pB(%pA); no .sframe will be created"),
    abfd, sec);
  return false;
success:
  _bfd_elf_munmap_section_contents (sec, sfbuf);
  return true;
}

/* This function is called for each input file before the .sframe section
   is relocated.  It marks the SFrame FDE for the discarded functions for
   deletion.

   The function returns TRUE iff any entries have been deleted.  */

bool
_bfd_elf_discard_section_sframe
   (asection *sec,
    bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
    struct elf_reloc_cookie *cookie)
{
  bool changed;
  bool keep;
  unsigned int i;
  unsigned int func_desc_offset;
  unsigned int num_fidx;
  struct sframe_dec_info *sfd_info;

  changed = false;
  /* FIXME - if relocatable link and changed = true, how does the final
     .rela.sframe get updated ?.  */
  keep = false;

  sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;

  /* Skip checking for the linker created .sframe sections
     (for PLT sections).  */
  if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
    {
      num_fidx = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
      for (i = 0; i < num_fidx; i++)
	{
	  func_desc_offset = sframe_decoder_get_func_r_offset (sfd_info, i);

	  cookie->rel = cookie->rels
	    + sframe_decoder_get_func_reloc_index (sfd_info, i);
	  keep = !(*reloc_symbol_deleted_p) (func_desc_offset, cookie);

	  if (!keep)
	    {
	      sframe_decoder_mark_func_deleted (sfd_info, i);
	      changed = true;
	    }
	}
    }
  return changed;
}

/* Update the reference to the output .sframe section in the output ELF
   BFD ABFD.  Returns true if no error.  */

bool
_bfd_elf_set_section_sframe (bfd *abfd,
				struct bfd_link_info *info)
{
  asection *cfsec;

  cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
  if (!cfsec)
    return false;

  elf_sframe (abfd) = cfsec;

  return true;
}

/* Merge .sframe section SEC.  This is called with the relocated
   CONTENTS.  */

bool
_bfd_elf_merge_section_sframe (bfd *abfd,
			       struct bfd_link_info *info,
			       asection *sec,
			       bfd_byte *contents)
{
  struct sframe_dec_info *sfd_info;
  struct sframe_enc_info *sfe_info;
  sframe_decoder_ctx *sfd_ctx;
  sframe_encoder_ctx *sfe_ctx;
  uint8_t sfd_ctx_abi_arch;
  int8_t sfd_ctx_fixed_fp_offset;
  int8_t sfd_ctx_fixed_ra_offset;
  uint8_t dctx_version;
  uint8_t ectx_version;
  int encerr = 0;

  struct elf_link_hash_table *htab;
  asection *cfsec;

  /* Sanity check - handle SFrame sections only.  */
  if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
    return false;

  sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
  sfd_ctx = sfd_info->sfd_ctx;

  htab = elf_hash_table (info);
  sfe_info = &(htab->sfe_info);
  sfe_ctx = sfe_info->sfe_ctx;

  /* All input bfds are expected to have a valid SFrame section.  Even if
     the SFrame section is empty with only a header, there must be a valid
     SFrame decoder context by now.  The SFrame encoder context, however,
     will get set later here, if this is the first call to the function.  */
  if (sfd_ctx == NULL || sfe_info == NULL)
    return false;

  if (htab->sfe_info.sfe_ctx == NULL)
    {
      sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
      sfd_ctx_fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (sfd_ctx);
      sfd_ctx_fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (sfd_ctx);

      /* Valid values are non-zero.  */
      if (!sfd_ctx_abi_arch)
	return false;

      htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
					      0, /* SFrame flags.  */
					      sfd_ctx_abi_arch,
					      sfd_ctx_fixed_fp_offset,
					      sfd_ctx_fixed_ra_offset,
					      &encerr);
      /* Handle errors from sframe_encode.  */
      if (htab->sfe_info.sfe_ctx == NULL)
	return false;
    }
  sfe_ctx = sfe_info->sfe_ctx;

  if (sfe_info->sframe_section == NULL)
    {
      /* Make sure things are set for an eventual write.
	 Size of the output section is not known until
	 _bfd_elf_write_section_sframe is ready with the buffer
	 to write out.  */
      cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
      if (cfsec)
	{
	  sfe_info->sframe_section = cfsec;
	  // elf_sframe (abfd) = cfsec;
	}
      else
	return false;
    }

  /* Check that all .sframe sections being linked have the same
     ABI/arch.  */
  if (sframe_decoder_get_abi_arch (sfd_ctx)
      != sframe_encoder_get_abi_arch (sfe_ctx))
    {
      _bfd_error_handler
	(_("input SFrame sections with different abi prevent .sframe"
	  " generation"));
      return false;
    }

  /* Check that all .sframe sections being linked have the same version.  */
  dctx_version = sframe_decoder_get_version (sfd_ctx);
  ectx_version = sframe_encoder_get_version (sfe_ctx);
  if (dctx_version != SFRAME_VERSION_2 || dctx_version != ectx_version)
    {
      _bfd_error_handler
	(_("input SFrame sections with different format versions prevent"
	  " .sframe generation"));
      return false;
    }


  /* Iterate over the function descriptor entries and the FREs of the
     function from the decoder context.  Add each of them to the encoder
     context, if suitable.  */
  uint32_t i = 0, j = 0, cur_fidx = 0;

  uint32_t num_fidx = sframe_decoder_get_num_fidx (sfd_ctx);
  uint32_t num_enc_fidx = sframe_encoder_get_num_fidx (sfe_ctx);

  for (i = 0; i < num_fidx; i++)
    {
      unsigned int num_fres = 0;
      int32_t func_start_addr;
      bfd_vma address;
      uint32_t func_size = 0;
      unsigned char func_info = 0;
      unsigned int r_offset = 0;
      bool pltn_reloc_by_hand = false;
      unsigned int pltn_r_offset = 0;
      uint8_t rep_block_size = 0;

      if (!sframe_decoder_get_funcdesc_v2 (sfd_ctx, i, &num_fres, &func_size,
					   &func_start_addr, &func_info,
					   &rep_block_size))
	{
	  /* If function belongs to a deleted section, skip editing the
	     function descriptor entry.  */
	  if (sframe_decoder_func_deleted_p(sfd_info, i))
	    continue;

	  /* Don't edit function descriptor entries for relocatable link.  */
	  if (!bfd_link_relocatable (info))
	    {
	      if (!(sec->flags & SEC_LINKER_CREATED))
		{
		  /* Get relocated contents by reading the value of the
		     relocated function start address at the beginning of the
		     function descriptor entry.  */
		  r_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
		}
	      else
		{
		  /* Expected to land here when SFrame stack trace info is
		     created dynamically for the .plt* sections.  These
		     sections are expected to have upto two SFrame FDE entries.
		     Although the code should work for > 2,  leaving this
		     assert here for safety.  */
		  BFD_ASSERT (num_fidx <= 2);
		  /* For the first entry, we know the offset of the SFrame FDE's
		     sfde_func_start_address.  Side note: see how the value
		     of PLT_SFRAME_FDE_START_OFFSET is also set to the
		     same.  */
		  r_offset = sframe_decoder_get_hdr_size (sfd_ctx);
		  /* For any further SFrame FDEs, the generator has already put
		     in an offset in place of sfde_func_start_address of the
		     corresponding FDE.  We will use it by hand to relocate.  */
		  if (i > 0)
		    {
		      pltn_r_offset
			= r_offset + (i * sizeof (sframe_func_desc_entry));
		      pltn_reloc_by_hand = true;
		    }
		}

	      /* Get the SFrame FDE function start address after relocation.  */
	      address = sframe_read_value (abfd, contents, r_offset, 4);
	      if (pltn_reloc_by_hand)
		address += sframe_read_value (abfd, contents,
					      pltn_r_offset, 4);
	      address += (sec->output_offset + r_offset);

	      /* FIXME For testing only. Cleanup later.  */
	      // address += (sec->output_section->vma);

	      func_start_addr = address;
	    }

	  /* Update the encoder context with updated content.  */
	  int err = sframe_encoder_add_funcdesc_v2 (sfe_ctx, func_start_addr,
						    func_size, func_info,
						    rep_block_size, num_fres);
	  cur_fidx++;
	  BFD_ASSERT (!err);
	}

      for (j = 0; j < num_fres; j++)
	{
	  sframe_frame_row_entry fre;
	  if (!sframe_decoder_get_fre (sfd_ctx, i, j, &fre))
	    {
	      int err = sframe_encoder_add_fre (sfe_ctx,
						cur_fidx-1+num_enc_fidx,
						&fre);
	      BFD_ASSERT (!err);
	    }
	}
    }
  /* Free the SFrame decoder context.  */
  sframe_decoder_free (&sfd_ctx);

  return true;
}

/* Write out the .sframe section.  This must be called after
   _bfd_elf_merge_section_sframe has been called on all input
   .sframe sections.  */

bool
_bfd_elf_write_section_sframe (bfd *abfd, struct bfd_link_info *info)
{
  bool retval = true;

  struct elf_link_hash_table *htab;
  struct sframe_enc_info *sfe_info;
  sframe_encoder_ctx *sfe_ctx;
  asection *sec;
  void *contents;
  size_t sec_size;
  int err = 0;

  htab = elf_hash_table (info);
  sfe_info = &htab->sfe_info;
  sec = sfe_info->sframe_section;
  sfe_ctx = sfe_info->sfe_ctx;

  if (sec == NULL)
    return true;

  contents = sframe_encoder_write (sfe_ctx, &sec_size, &err);
  sec->size = (bfd_size_type) sec_size;

  if (!bfd_set_section_contents (abfd, sec->output_section, contents,
				 (file_ptr) sec->output_offset,
				 sec->size))
    retval = false;
  else if (!bfd_link_relocatable (info))
    {
      Elf_Internal_Shdr *hdr = &elf_section_data (sec)->this_hdr;
      hdr->sh_size = sec->size;
    }
  /* For relocatable links, do not update the section size as the section
     contents have not been relocated.  */

  sframe_encoder_free (&sfe_ctx);

  return retval;
}
