/* sframe.c - SFrame decoder/encoder.

   Copyright (C) 2022-2025 Free Software Foundation, Inc.

   This file is part of libsframe.

   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, see <http://www.gnu.org/licenses/>.  */

#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stddef.h>
#include "sframe-impl.h"
#include "swap.h"

struct sf_fde_tbl
{
  unsigned int count;
  unsigned int alloced;
  sframe_func_desc_entry entry[1];
};

struct sf_fre_tbl
{
  unsigned int count;
  unsigned int alloced;
  sframe_frame_row_entry entry[1];
};

#define _sf_printflike_(string_index,first_to_check) \
    __attribute__ ((__format__ (__printf__, (string_index), (first_to_check))))

static void debug_printf (const char *, ...);

static int _sframe_debug;	/* Control for printing out debug info.  */
static int number_of_entries = 64;

static void
sframe_init_debug (void)
{
  static int inited;

  if (!inited)
    {
      _sframe_debug = getenv ("SFRAME_DEBUG") != NULL;
      inited = 1;
    }
}

_sf_printflike_ (1, 2)
static void debug_printf (const char *format, ...)
{
  if (_sframe_debug)
    {
      va_list args;

      va_start (args, format);
      vfprintf (stderr, format, args);
      va_end (args);
    }
}

/* Generate bitmask of given size in bytes.  This is used for
   some checks on the FRE start address.
   SFRAME_FRE_TYPE_ADDR1 => 1 byte => [ bitmask = 0xff ]
   SFRAME_FRE_TYPE_ADDR2 => 2 byte => [ bitmask = 0xffff ]
   SFRAME_FRE_TYPE_ADDR4 => 4 byte => [ bitmask = 0xffffffff ].  */
#define SFRAME_BITMASK_OF_SIZE(size_in_bytes) \
  (((uint64_t)1 << (size_in_bytes*8)) - 1)

/* Store the specified error code into errp if it is non-NULL.
   Return SFRAME_ERR.  */

static int
sframe_set_errno (int *errp, int error)
{
  if (errp != NULL)
    *errp = error;
  return SFRAME_ERR;
}

/* Store the specified error code into errp if it is non-NULL.
   Return NULL.  */

static void *
sframe_ret_set_errno (int *errp, int error)
{
  if (errp != NULL)
    *errp = error;
  return NULL;
}

/* Get the SFrame header size.  */

static uint32_t
sframe_get_hdr_size (sframe_header *sfh)
{
  return SFRAME_V1_HDR_SIZE (*sfh);
}

/* Access functions for frame row entry data.  */

static uint8_t
sframe_fre_get_offset_count (uint8_t fre_info)
{
  return SFRAME_V1_FRE_OFFSET_COUNT (fre_info);
}

static uint8_t
sframe_fre_get_offset_size (uint8_t fre_info)
{
  return SFRAME_V1_FRE_OFFSET_SIZE (fre_info);
}

static bool
sframe_get_fre_ra_mangled_p (uint8_t fre_info)
{
  return SFRAME_V1_FRE_MANGLED_RA_P (fre_info);
}

/* Access functions for info from function descriptor entry.  */

static uint32_t
sframe_get_fre_type (sframe_func_desc_entry *fdep)
{
  uint32_t fre_type = 0;
  if (fdep)
    fre_type = SFRAME_V1_FUNC_FRE_TYPE (fdep->sfde_func_info);
  return fre_type;
}

static uint32_t
sframe_get_fde_type (sframe_func_desc_entry *fdep)
{
  uint32_t fde_type = 0;
  if (fdep)
    fde_type = SFRAME_V1_FUNC_FDE_TYPE (fdep->sfde_func_info);
  return fde_type;
}

/* Check if flipping is needed, based on ENDIAN.  */

static int
need_swapping (int endian)
{
  unsigned int ui = 1;
  char *c = (char *)&ui;
  int is_little = (int)*c;

  switch (endian)
    {
      case SFRAME_ABI_AARCH64_ENDIAN_LITTLE:
      case SFRAME_ABI_AMD64_ENDIAN_LITTLE:
	return !is_little;
      case SFRAME_ABI_AARCH64_ENDIAN_BIG:
      case SFRAME_ABI_S390X_ENDIAN_BIG:
	return is_little;
      default:
	break;
    }

  return 0;
}

/* Flip the endianness of the SFrame header.  */

static void
flip_header (sframe_header *sfheader)
{
  swap_thing (sfheader->sfh_preamble.sfp_magic);
  swap_thing (sfheader->sfh_preamble.sfp_version);
  swap_thing (sfheader->sfh_preamble.sfp_flags);
  swap_thing (sfheader->sfh_cfa_fixed_fp_offset);
  swap_thing (sfheader->sfh_cfa_fixed_ra_offset);
  swap_thing (sfheader->sfh_num_fdes);
  swap_thing (sfheader->sfh_num_fres);
  swap_thing (sfheader->sfh_fre_len);
  swap_thing (sfheader->sfh_fdeoff);
  swap_thing (sfheader->sfh_freoff);
}

static void
flip_fde (sframe_func_desc_entry *fdep)
{
  swap_thing (fdep->sfde_func_start_address);
  swap_thing (fdep->sfde_func_size);
  swap_thing (fdep->sfde_func_start_fre_off);
  swap_thing (fdep->sfde_func_num_fres);
}

/* Check if SFrame header has valid data.  */

static bool
sframe_header_sanity_check_p (sframe_header *hp)
{
  /* Check preamble is valid.  */
  if (hp->sfh_preamble.sfp_magic != SFRAME_MAGIC
      || (hp->sfh_preamble.sfp_version != SFRAME_VERSION_1
	  && hp->sfh_preamble.sfp_version != SFRAME_VERSION_2)
      || (hp->sfh_preamble.sfp_flags & ~SFRAME_V2_F_ALL_FLAGS))
    return false;

  /* Check offsets are valid.  */
  if (hp->sfh_fdeoff > hp->sfh_freoff)
    return false;

  return true;
}

/* Flip the start address pointed to by FP.  */

static void
flip_fre_start_address (char *addr, uint32_t fre_type)
{
  if (fre_type == SFRAME_FRE_TYPE_ADDR2)
    {
      uint16_t *start_addr = (uint16_t *)addr;
      swap_thing (*start_addr);
    }
  else if (fre_type == SFRAME_FRE_TYPE_ADDR4)
    {
      uint32_t *start_addr = (uint32_t *)addr;
      swap_thing (*start_addr);
    }
}

static void
flip_fre_stack_offsets (char *offsets, uint8_t offset_size, uint8_t offset_cnt)
{
  int j;

  if (offset_size == SFRAME_FRE_OFFSET_2B)
    {
      uint16_t *ust = (uint16_t *)offsets;
      for (j = offset_cnt; j > 0; ust++, j--)
	swap_thing (*ust);
    }
  else if (offset_size == SFRAME_FRE_OFFSET_4B)
    {
      uint32_t *uit = (uint32_t *)offsets;
      for (j = offset_cnt; j > 0; uit++, j--)
	swap_thing (*uit);
    }
}

/* Get the FRE start address size, given the FRE_TYPE.  */

static size_t
sframe_fre_start_addr_size (uint32_t fre_type)
{
  size_t addr_size = 0;
  switch (fre_type)
    {
    case SFRAME_FRE_TYPE_ADDR1:
      addr_size = 1;
      break;
    case SFRAME_FRE_TYPE_ADDR2:
      addr_size = 2;
      break;
    case SFRAME_FRE_TYPE_ADDR4:
      addr_size = 4;
      break;
    default:
      /* No other value is expected.  */
      sframe_assert (0);
      break;
    }
  return addr_size;
}

/* Check if the FREP has valid data.  */

static bool
sframe_fre_sanity_check_p (sframe_frame_row_entry *frep)
{
  uint8_t offset_size, offset_cnt;
  uint8_t fre_info;

  if (frep == NULL)
    return false;

  fre_info = frep->fre_info;
  offset_size = sframe_fre_get_offset_size (fre_info);

  if (offset_size != SFRAME_FRE_OFFSET_1B
      && offset_size != SFRAME_FRE_OFFSET_2B
      && offset_size != SFRAME_FRE_OFFSET_4B)
    return false;

  offset_cnt = sframe_fre_get_offset_count (fre_info);
  if (offset_cnt > MAX_NUM_STACK_OFFSETS)
    return false;

  return true;
}

/* Get FRE_INFO's offset size in bytes.  */

static size_t
sframe_fre_offset_bytes_size (uint8_t fre_info)
{
  uint8_t offset_size, offset_cnt;

  offset_size = sframe_fre_get_offset_size (fre_info);

  debug_printf ("offset_size =  %u\n", offset_size);

  offset_cnt = sframe_fre_get_offset_count (fre_info);

  if (offset_size == SFRAME_FRE_OFFSET_2B
      || offset_size == SFRAME_FRE_OFFSET_4B)	/* 2 or 4 bytes.  */
    return (offset_cnt * (offset_size * 2));

  return (offset_cnt);
}

/* Get total size in bytes to represent FREP in the binary format.  This
   includes the starting address, FRE info, and all the offsets.  */

static size_t
sframe_fre_entry_size (sframe_frame_row_entry *frep, uint32_t fre_type)
{
  if (frep == NULL)
    return 0;

  uint8_t fre_info = frep->fre_info;
  size_t addr_size = sframe_fre_start_addr_size (fre_type);

  return (addr_size + sizeof (frep->fre_info)
	  + sframe_fre_offset_bytes_size (fre_info));
}

/* Get the function descriptor entry at index FUNC_IDX in the decoder
   context CTX.  */

static sframe_func_desc_entry *
sframe_decoder_get_funcdesc_at_index (sframe_decoder_ctx *ctx,
				      uint32_t func_idx)
{
  sframe_func_desc_entry *fdep;
  uint32_t num_fdes;
  int err;

  num_fdes = sframe_decoder_get_num_fidx (ctx);
  if (num_fdes == 0
      || func_idx >= num_fdes
      || ctx->sfd_funcdesc == NULL)
    return sframe_ret_set_errno (&err, SFRAME_ERR_DCTX_INVAL);

  fdep = &ctx->sfd_funcdesc[func_idx];
  return fdep;
}

/* Get the offset of the start PC of the SFrame FDE at FUNC_IDX from the start
   of the SFrame section.  This section-relative offset is used within
   libsframe for sorting the SFrame FDEs, and also information lookup routines
   like sframe_find_fre.

   If FUNC_IDX is not a valid index in the given decoder object, returns 0.  */

static int32_t
sframe_decoder_get_secrel_func_start_addr (sframe_decoder_ctx *dctx,
					   uint32_t func_idx)
{
  int err = 0;
  int32_t offsetof_fde_in_sec
    = sframe_decoder_get_offsetof_fde_start_addr (dctx, func_idx, &err);
  /* If func_idx is not a valid index, return 0.  */
  if (err)
    return 0;

  int32_t func_start_addr = dctx->sfd_funcdesc[func_idx].sfde_func_start_address;

  return func_start_addr + offsetof_fde_in_sec;
}

/* Check whether for the given FDEP, the SFrame Frame Row Entry identified via
   the START_IP_OFFSET and the END_IP_OFFSET, provides the stack trace
   information for the PC.  */

static bool
sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx,
			  uint32_t start_ip_offset, uint32_t end_ip_offset,
			  int32_t pc)
{
  sframe_func_desc_entry *fdep;
  int32_t func_start_addr;
  uint8_t rep_block_size;
  uint32_t fde_type;
  uint32_t pc_offset;
  bool mask_p;

  fdep = &dctx->sfd_funcdesc[func_idx];
  func_start_addr = sframe_decoder_get_secrel_func_start_addr (dctx, func_idx);
  fde_type = sframe_get_fde_type (fdep);
  mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK);
  rep_block_size = fdep->sfde_func_rep_size;

  if (func_start_addr > pc)
    return false;

  /* Given func_start_addr <= pc, pc - func_start_addr must be positive.  */
  pc_offset = pc - func_start_addr;
  /* For SFrame FDEs encoding information for repetitive pattern of insns,
     masking with the rep_block_size is necessary to find the matching FRE.  */
  if (mask_p)
    pc_offset = pc_offset % rep_block_size;

  return (start_ip_offset <= pc_offset) && (end_ip_offset >= pc_offset);
}

static int
flip_fre (char *fp, uint32_t fre_type, size_t *fre_size)
{
  uint8_t fre_info;
  uint8_t offset_size, offset_cnt;
  size_t addr_size, fre_info_size = 0;
  int err = 0;

  if (fre_size == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  flip_fre_start_address (fp, fre_type);

  /* Advance the buffer pointer to where the FRE info is.  */
  addr_size = sframe_fre_start_addr_size (fre_type);
  fp += addr_size;

  /* FRE info is uint8_t.  No need to flip.  */
  fre_info = *(uint8_t*)fp;
  offset_size = sframe_fre_get_offset_size (fre_info);
  offset_cnt = sframe_fre_get_offset_count (fre_info);

  /* Advance the buffer pointer to where the stack offsets are.  */
  fre_info_size = sizeof (uint8_t);
  fp += fre_info_size;
  flip_fre_stack_offsets (fp, offset_size, offset_cnt);

  *fre_size
    = addr_size + fre_info_size + sframe_fre_offset_bytes_size (fre_info);

  return 0;
}

/* Endian flip the contents of FRAME_BUF of size BUF_SIZE.
   The SFrame header in the FRAME_BUF must be endian flipped prior to
   calling flip_sframe.

   Endian flipping at decode time vs encode time have different needs.  At
   encode time, the frame_buf is in host endianness, and hence, values should
   be read up before the buffer is changed to foreign endianness.  This change
   of behaviour is specified via TO_FOREIGN arg.

   If an error code is returned, the buffer should not be used.  */

static int
flip_sframe (char *frame_buf, size_t buf_size, uint32_t to_foreign)
{
  unsigned int i, j, prev_frep_index;
  sframe_header *ihp;
  char *fdes;
  char *fp = NULL;
  sframe_func_desc_entry *fdep;
  unsigned int num_fdes = 0;
  unsigned int num_fres = 0;
  uint32_t fre_type = 0;
  uint32_t fre_offset = 0;
  size_t esz = 0;
  size_t hdrsz = 0;
  int err = 0;
  /* For error checking.  */
  size_t bytes_flipped = 0;

  /* Header must be in host endianness at this time.  */
  ihp = (sframe_header *)frame_buf;

  if (!sframe_header_sanity_check_p (ihp))
    return sframe_set_errno (&err, SFRAME_ERR_BUF_INVAL);

  /* The contents of the SFrame header are safe to read.  Get the number of
     FDEs and the first FDE in the buffer.  */
  hdrsz = sframe_get_hdr_size (ihp);
  num_fdes = ihp->sfh_num_fdes;
  fdes = frame_buf + hdrsz + ihp->sfh_fdeoff;
  fdep = (sframe_func_desc_entry *)fdes;

  j = 0;
  prev_frep_index = 0;
  for (i = 0; i < num_fdes; fdep++, i++)
    {
      if ((char*)fdep >= (frame_buf + buf_size))
	goto bad;

      if (to_foreign)
	{
	  num_fres = fdep->sfde_func_num_fres;
	  fre_type = sframe_get_fre_type (fdep);
	  fre_offset = fdep->sfde_func_start_fre_off;
	}

      flip_fde (fdep);
      bytes_flipped += sizeof (sframe_func_desc_entry);

      if (!to_foreign)
	{
	  num_fres = fdep->sfde_func_num_fres;
	  fre_type = sframe_get_fre_type (fdep);
	  fre_offset = fdep->sfde_func_start_fre_off;
	}

      fp = frame_buf + hdrsz + ihp->sfh_freoff;
      fp += fre_offset;
      for (; j < prev_frep_index + num_fres; j++)
	{
	  if (flip_fre (fp, fre_type, &esz))
	    goto bad;
	  bytes_flipped += esz;

	  if (esz == 0 || esz > buf_size)
	    goto bad;
	  fp += esz;
	}
      prev_frep_index = j;
    }
  /* All FDEs and FREs must have been endian flipped by now.  */
  if ((j != ihp->sfh_num_fres) || (bytes_flipped > (buf_size - hdrsz)))
    goto bad;
  /* Optional trailing section padding.  */
  for (fp = frame_buf + hdrsz + bytes_flipped; fp < frame_buf + buf_size; fp++)
    if (*fp != '\0')
      goto bad;

  /* Success.  */
  return 0;
bad:
  return SFRAME_ERR;
}

/* The SFrame Decoder.  */

/* Get SFrame header from the given decoder context DCTX.  */

static sframe_header *
sframe_decoder_get_header (sframe_decoder_ctx *dctx)
{
  sframe_header *hp = NULL;
  if (dctx != NULL)
    hp = &dctx->sfd_header;
  return hp;
}

/* Compare function for qsort'ing the FDE table.  */

static int
fde_func (const void *p1, const void *p2)
{
  const sframe_func_desc_entry *aa = p1;
  const sframe_func_desc_entry *bb = p2;

  if (aa->sfde_func_start_address < bb->sfde_func_start_address)
    return -1;
  else if (aa->sfde_func_start_address > bb->sfde_func_start_address)
    return 1;
  return 0;
}

/* Get IDX'th offset from FRE.  Set errp as applicable.  */

static int32_t
sframe_get_fre_offset (sframe_frame_row_entry *fre, int idx, int *errp)
{
  uint8_t offset_cnt, offset_size;

  if (fre == NULL || !sframe_fre_sanity_check_p (fre))
    return sframe_set_errno (errp, SFRAME_ERR_FRE_INVAL);

  offset_cnt = sframe_fre_get_offset_count (fre->fre_info);
  offset_size = sframe_fre_get_offset_size (fre->fre_info);

  if (offset_cnt < idx + 1)
    return sframe_set_errno (errp, SFRAME_ERR_FREOFFSET_NOPRESENT);

  if (errp)
    *errp = 0; /* Offset Valid.  */

  if (offset_size == SFRAME_FRE_OFFSET_1B)
    {
      int8_t *sp = (int8_t *)fre->fre_offsets;
      return sp[idx];
    }
  else if (offset_size == SFRAME_FRE_OFFSET_2B)
    {
      int16_t *sp = (int16_t *)fre->fre_offsets;
      return sp[idx];
    }
  else
    {
      int32_t *ip = (int32_t *)fre->fre_offsets;
      return ip[idx];
    }
}

/* Free the decoder context.  */

void
sframe_decoder_free (sframe_decoder_ctx **dctxp)
{
  if (dctxp != NULL)
    {
      sframe_decoder_ctx *dctx = *dctxp;
      if (dctx == NULL)
	return;

      if (dctx->sfd_funcdesc != NULL)
	{
	  free (dctx->sfd_funcdesc);
	  dctx->sfd_funcdesc = NULL;
	}
      if (dctx->sfd_fres != NULL)
	{
	  free (dctx->sfd_fres);
	  dctx->sfd_fres = NULL;
	}
      if (dctx->sfd_buf != NULL)
	{
	  free (dctx->sfd_buf);
	  dctx->sfd_buf = NULL;
	}

      free (*dctxp);
      *dctxp = NULL;
    }
}

/* Create an FDE function info byte given an FRE_TYPE and an FDE_TYPE.  */
/* FIXME API for linker.  Revisit if its better placed somewhere else?  */

unsigned char
sframe_fde_create_func_info (uint32_t fre_type,
			     uint32_t fde_type)
{
  unsigned char func_info;
  sframe_assert (fre_type == SFRAME_FRE_TYPE_ADDR1
		   || fre_type == SFRAME_FRE_TYPE_ADDR2
		   || fre_type == SFRAME_FRE_TYPE_ADDR4);
  sframe_assert (fde_type == SFRAME_FDE_TYPE_PCINC
		    || fde_type == SFRAME_FDE_TYPE_PCMASK);
  func_info = SFRAME_V1_FUNC_INFO (fde_type, fre_type);
  return func_info;
}

/* Get the FRE type given the function size.  */
/* FIXME API for linker.  Revisit if its better placed somewhere else?  */

uint32_t
sframe_calc_fre_type (size_t func_size)
{
  uint32_t fre_type = 0;
  if (func_size < SFRAME_FRE_TYPE_ADDR1_LIMIT)
    fre_type = SFRAME_FRE_TYPE_ADDR1;
  else if (func_size < SFRAME_FRE_TYPE_ADDR2_LIMIT)
    fre_type = SFRAME_FRE_TYPE_ADDR2;
  /* Adjust the check a bit so that it remains warning-free but meaningful
     on 32-bit systems.  */
  else if (func_size <= (size_t) (SFRAME_FRE_TYPE_ADDR4_LIMIT - 1))
    fre_type = SFRAME_FRE_TYPE_ADDR4;
  return fre_type;
}

/* Get the base reg id from the FRE info.  Set errp if failure.  */

uint8_t
sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp)
{
  if (fre == NULL)
    return sframe_set_errno (errp, SFRAME_ERR_FRE_INVAL);

  uint8_t fre_info = fre->fre_info;
  return SFRAME_V1_FRE_CFA_BASE_REG_ID (fre_info);
}

/* Get the CFA offset from the FRE.  If the offset is invalid, sets errp.  */

int32_t
sframe_fre_get_cfa_offset (sframe_decoder_ctx *dctx,
			   sframe_frame_row_entry *fre, int *errp)
{
  int32_t offset = sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, errp);

  /* For s390x undo adjustment of CFA offset (to enable 8-bit offsets).  */
  if (sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
    offset = SFRAME_V2_S390X_CFA_OFFSET_DECODE (offset);

  return offset;
}

/* Get the FP offset from the FRE.  If the offset is invalid, sets errp.

   For s390x the offset may be an encoded register number, indicated by
   LSB set to one, which is only valid in the topmost frame.  */

int32_t
sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
			  sframe_frame_row_entry *fre, int *errp)
{
  uint32_t fp_offset_idx = 0;
  int8_t fp_offset = sframe_decoder_get_fixed_fp_offset (dctx);
  /* If the FP offset is not being tracked, return the fixed FP offset
     from the SFrame header.  */
  if (fp_offset != SFRAME_CFA_FIXED_FP_INVALID)
    {
      if (errp)
	*errp = 0;
      return fp_offset;
    }

  /* In some ABIs, the stack offset to recover RA (using the CFA) from is
     fixed (like AMD64).  In such cases, the stack offset to recover FP will
     appear at the second index.  */
  fp_offset_idx = ((sframe_decoder_get_fixed_ra_offset (dctx)
		    != SFRAME_CFA_FIXED_RA_INVALID)
		   ? SFRAME_FRE_RA_OFFSET_IDX
		   : SFRAME_FRE_FP_OFFSET_IDX);
  return sframe_get_fre_offset (fre, fp_offset_idx, errp);
}

/* Get the RA offset from the FRE.  If the offset is invalid, sets errp.

   For s390x an RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
   that the RA is not saved, which is only valid in the topmost frame.
   For s390x the offset may be an encoded register number, indicated by
   LSB set to one, which is only valid in the topmost frame.  */

int32_t
sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,
			  sframe_frame_row_entry *fre, int *errp)
{
  int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
  /* If the RA offset was not being tracked, return the fixed RA offset
     from the SFrame header.  */
  if (ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
    {
      if (errp)
	*errp = 0;
      return ra_offset;
    }

  /* Otherwise, get the RA offset from the FRE.  */
  return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp);
}

/* Get whether the RA is mangled.  */

bool
sframe_fre_get_ra_mangled_p (sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED,
			     sframe_frame_row_entry *fre, int *errp)
{
  if (fre == NULL || !sframe_fre_sanity_check_p (fre))
    return sframe_set_errno (errp, SFRAME_ERR_FRE_INVAL);

  return sframe_get_fre_ra_mangled_p (fre->fre_info);
}

static int
sframe_frame_row_entry_copy (sframe_frame_row_entry *dst,
			     sframe_frame_row_entry *src)
{
  int err = 0;

  if (dst == NULL || src == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  memcpy (dst, src, sizeof (sframe_frame_row_entry));
  return 0;
}

/* Decode the SFrame FRE start address offset value from FRE_BUF in on-disk
   binary format, given the FRE_TYPE.  Updates the FRE_START_ADDR.

   Returns 0 on success, SFRAME_ERR otherwise.  */

static int
sframe_decode_fre_start_address (const char *fre_buf,
				 uint32_t *fre_start_addr,
				 uint32_t fre_type)
{
  uint32_t saddr = 0;
  int err = 0;
  size_t addr_size = 0;

  addr_size = sframe_fre_start_addr_size (fre_type);

  if (fre_type == SFRAME_FRE_TYPE_ADDR1)
    {
      uint8_t *uc = (uint8_t *)fre_buf;
      saddr = (uint32_t)*uc;
    }
  else if (fre_type == SFRAME_FRE_TYPE_ADDR2)
    {
      uint16_t *ust = (uint16_t *)fre_buf;
      /* SFrame is an unaligned on-disk format.  Using memcpy helps avoid the
	 use of undesirable unaligned loads.  See PR libsframe/29856.  */
      uint16_t tmp = 0;
      memcpy (&tmp, ust, addr_size);
      saddr = (uint32_t)tmp;
    }
  else if (fre_type == SFRAME_FRE_TYPE_ADDR4)
    {
      uint32_t *uit = (uint32_t *)fre_buf;
      uint32_t tmp = 0;
      memcpy (&tmp, uit, addr_size);
      saddr = (uint32_t)tmp;
    }
  else
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  *fre_start_addr = saddr;
  return 0;
}

/* Decode a frame row entry FRE which starts at location FRE_BUF.  The function
   updates ESZ to the size of the FRE as stored in the binary format.

   This function works closely with the SFrame binary format.

   Returns SFRAME_ERR if failure.  */

static int
sframe_decode_fre (const char *fre_buf, sframe_frame_row_entry *fre,
		   uint32_t fre_type, size_t *esz)
{
  int err = 0;
  const char *stack_offsets = NULL;
  size_t stack_offsets_sz;
  size_t addr_size;
  size_t fre_size;

  if (fre_buf == NULL || fre == NULL || esz == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  /* Copy over the FRE start address.  */
  sframe_decode_fre_start_address (fre_buf, &fre->fre_start_addr, fre_type);

  addr_size = sframe_fre_start_addr_size (fre_type);
  fre->fre_info = *(uint8_t *)(fre_buf + addr_size);
  /* Sanity check as the API works closely with the binary format.  */
  sframe_assert (sizeof (fre->fre_info) == sizeof (uint8_t));

  /* Cleanup the space for fre_offsets first, then copy over the valid
     bytes.  */
  memset (fre->fre_offsets, 0, MAX_OFFSET_BYTES);
  /* Get offsets size.  */
  stack_offsets_sz = sframe_fre_offset_bytes_size (fre->fre_info);
  stack_offsets = fre_buf + addr_size + sizeof (fre->fre_info);
  memcpy (fre->fre_offsets, stack_offsets, stack_offsets_sz);

  /* The FRE has been decoded.  Use it to perform one last sanity check.  */
  fre_size = sframe_fre_entry_size (fre, fre_type);
  sframe_assert (fre_size == (addr_size + sizeof (fre->fre_info)
			      + stack_offsets_sz));
  *esz = fre_size;

  return 0;
}

/* Decode the specified SFrame buffer SF_BUF of size SF_SIZE and return the
   new SFrame decoder context.

   Sets ERRP for the caller if any error.  Frees up the allocated memory in
   case of error.  */

sframe_decoder_ctx *
sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
{
  const sframe_preamble *sfp;
  size_t hdrsz;
  sframe_header *sfheaderp;
  sframe_decoder_ctx *dctx;
  char *frame_buf;
  char *tempbuf = NULL;

  int fidx_size;
  uint32_t fre_bytes;
  int foreign_endian = 0;

  sframe_init_debug ();

  if ((sf_buf == NULL) || (!sf_size))
    return sframe_ret_set_errno (errp, SFRAME_ERR_INVAL);
  else if (sf_size < sizeof (sframe_header))
    return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);

  sfp = (const sframe_preamble *) sf_buf;

  debug_printf ("sframe_decode: magic=0x%x version=%u flags=%u\n",
		sfp->sfp_magic, sfp->sfp_version, sfp->sfp_flags);

  /* Check for foreign endianness.  */
  if (sfp->sfp_magic != SFRAME_MAGIC)
    {
      if (sfp->sfp_magic == bswap_16 (SFRAME_MAGIC))
	foreign_endian = 1;
      else
	return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
    }

  /* Initialize a new decoder context.  */
  if ((dctx = malloc (sizeof (sframe_decoder_ctx))) == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
  memset (dctx, 0, sizeof (sframe_decoder_ctx));

  if (foreign_endian)
    {
      /* Allocate a new buffer and initialize it.  */
      tempbuf = (char *) malloc (sf_size * sizeof (char));
      if (tempbuf == NULL)
	return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
      memcpy (tempbuf, sf_buf, sf_size);

      /* Flip the header.  */
      sframe_header *ihp = (sframe_header *) tempbuf;
      flip_header (ihp);
      /* Flip the rest of the SFrame section data buffer.  */
      if (flip_sframe (tempbuf, sf_size, 0))
	{
	  free (tempbuf);
	  return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
	}
      frame_buf = tempbuf;
      /* This buffer is malloc'd when endian flipping the contents of the input
	 buffer are needed.  Keep a reference to it so it can be free'd up
	 later in sframe_decoder_free ().  */
      dctx->sfd_buf = tempbuf;
    }
  else
    frame_buf = (char *)sf_buf;

  /* Handle the SFrame header.  */
  dctx->sfd_header = *(sframe_header *) frame_buf;
  /* Validate the contents of SFrame header.  */
  sfheaderp = &dctx->sfd_header;
  if (!sframe_header_sanity_check_p (sfheaderp))
    {
      sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
      goto decode_fail_free;
    }
  hdrsz = sframe_get_hdr_size (sfheaderp);
  frame_buf += hdrsz;

  /* Handle the SFrame Function Descriptor Entry section.  */
  fidx_size
    = sfheaderp->sfh_num_fdes * sizeof (sframe_func_desc_entry);
  dctx->sfd_funcdesc = malloc (fidx_size);
  if (dctx->sfd_funcdesc == NULL)
    {
      sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
      goto decode_fail_free;
    }
  /* SFrame FDEs are at an offset of sfh_fdeoff from SFrame header end.  */
  memcpy (dctx->sfd_funcdesc, frame_buf + sfheaderp->sfh_fdeoff, fidx_size);

  debug_printf ("%u total fidx size\n", fidx_size);

  /* Handle the SFrame Frame Row Entry section.  */
  dctx->sfd_fres = (char *) malloc (sfheaderp->sfh_fre_len);
  if (dctx->sfd_fres == NULL)
    {
      sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
      goto decode_fail_free;
    }
  /* SFrame FREs are at an offset of sfh_freoff from SFrame header end.  */
  memcpy (dctx->sfd_fres,
	  frame_buf + sfheaderp->sfh_freoff,
	  sfheaderp->sfh_fre_len);

  fre_bytes = sfheaderp->sfh_fre_len;
  dctx->sfd_fre_nbytes = fre_bytes;

  debug_printf ("%u total fre bytes\n", fre_bytes);

  return dctx;

decode_fail_free:
  if (foreign_endian && tempbuf != NULL)
    free (tempbuf);
  sframe_decoder_free (&dctx);
  dctx = NULL;
  return dctx;
}

/* Get the size of the SFrame header from the decoder context CTX.  */

unsigned int
sframe_decoder_get_hdr_size (sframe_decoder_ctx *ctx)
{
  sframe_header *dhp;
  dhp = sframe_decoder_get_header (ctx);
  return sframe_get_hdr_size (dhp);
}

/* Get the SFrame's abi/arch info given the decoder context DCTX.  */

uint8_t
sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx)
{
  sframe_header *sframe_header;
  sframe_header = sframe_decoder_get_header (dctx);
  return sframe_header->sfh_abi_arch;
}

/* Get the format version from the SFrame decoder context DCTX.  */

uint8_t
sframe_decoder_get_version (sframe_decoder_ctx *dctx)
{
  sframe_header *dhp;
  dhp = sframe_decoder_get_header (dctx);
  return dhp->sfh_preamble.sfp_version;
}

/* Get the section flags from the SFrame decoder context DCTX.  */

uint8_t
sframe_decoder_get_flags (sframe_decoder_ctx *dctx)
{
  const sframe_header *dhp = sframe_decoder_get_header (dctx);
  return dhp->sfh_preamble.sfp_flags;
}

/* Get the SFrame's fixed FP offset given the decoder context CTX.  */
int8_t
sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *ctx)
{
  sframe_header *dhp;
  dhp = sframe_decoder_get_header (ctx);
  return dhp->sfh_cfa_fixed_fp_offset;
}

/* Get the SFrame's fixed RA offset given the decoder context CTX.  */
int8_t
sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *ctx)
{
  sframe_header *dhp;
  dhp = sframe_decoder_get_header (ctx);
  return dhp->sfh_cfa_fixed_ra_offset;
}

/* Get the offset of the sfde_func_start_address field (from the start of the
   on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the decoder
   context DCTX.

   If FUNC_IDX is more than the number of SFrame FDEs in the section, sets
   error code in ERRP, but returns the (hypothetical) offset.  This is useful
   for the linker when arranging input FDEs into the output section to be
   emitted.  */

uint32_t
sframe_decoder_get_offsetof_fde_start_addr (sframe_decoder_ctx *dctx,
					    uint32_t func_idx, int *errp)
{
  if (func_idx >= sframe_decoder_get_num_fidx (dctx))
    sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTFOUND);
  else if (errp)
    *errp = 0;

  return (sframe_decoder_get_hdr_size (dctx)
	  + func_idx * sizeof (sframe_func_desc_entry)
	  + offsetof (sframe_func_desc_entry, sfde_func_start_address));
}

/* Find the function descriptor entry starting which contains the specified
   address ADDR.  */

static sframe_func_desc_entry *
sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
					int *errp, uint32_t *func_idx)
{
  sframe_header *dhp;
  sframe_func_desc_entry *fdp;
  int low, high;

  if (ctx == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_INVAL);

  dhp = sframe_decoder_get_header (ctx);

  if (dhp == NULL || dhp->sfh_num_fdes == 0 || ctx->sfd_funcdesc == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_DCTX_INVAL);
  /* If the FDE sub-section is not sorted on PCs, skip the lookup because
     binary search cannot be used.  */
  if ((sframe_decoder_get_flags (ctx) & SFRAME_F_FDE_SORTED) == 0)
    return sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTSORTED);

  /* Do the binary search.  */
  fdp = (sframe_func_desc_entry *) ctx->sfd_funcdesc;
  low = 0;
  high = dhp->sfh_num_fdes - 1;
  while (low <= high)
    {
      int mid = low + (high - low) / 2;

      /* Given sfde_func_start_address <= addr,
	 addr - sfde_func_start_address must be positive.  */
      if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) <= addr
	  && ((uint32_t)(addr - sframe_decoder_get_secrel_func_start_addr (ctx,
									   mid))
	      < fdp[mid].sfde_func_size))
	{
	  *func_idx = mid;
	  return fdp + mid;
	}

      if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) < addr)
	low = mid + 1;
      else
	high = mid - 1;
    }

  return sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTFOUND);
}

/* Get the end IP offset for the FRE at index i in the FDEP.  The buffer FRES
   is the starting location for the FRE.  */

static uint32_t
sframe_fre_get_end_ip_offset (sframe_func_desc_entry *fdep, unsigned int i,
			      const char *fres)
{
  uint32_t end_ip_offset;
  uint32_t fre_type;

  fre_type = sframe_get_fre_type (fdep);

  /* Get the start address of the next FRE in sequence.  */
  if (i < fdep->sfde_func_num_fres - 1)
    {
      sframe_decode_fre_start_address (fres, &end_ip_offset, fre_type);
      end_ip_offset -= 1;
    }
  else
    /* The end IP offset for the FRE needs to be deduced from the function
       size.  */
    end_ip_offset = fdep->sfde_func_size - 1;

  return end_ip_offset;
}

/* Find the SFrame Row Entry which contains the PC.  Returns
   SFRAME_ERR if failure.  */

int
sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
		 sframe_frame_row_entry *frep)
{
  sframe_frame_row_entry cur_fre;
  sframe_func_desc_entry *fdep;
  uint32_t func_idx;
  uint32_t fre_type, i;
  int32_t func_start_addr;
  uint32_t start_ip_offset, end_ip_offset;
  const char *fres;
  size_t size = 0;
  int err = 0;

  if ((ctx == NULL) || (frep == NULL))
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  /* Find the FDE which contains the PC, then scan its fre entries.  */
  fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err, &func_idx);
  if (fdep == NULL || ctx->sfd_fres == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_DCTX_INVAL);

  fre_type = sframe_get_fre_type (fdep);

  fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off;
  func_start_addr = sframe_decoder_get_secrel_func_start_addr (ctx, func_idx);

  for (i = 0; i < fdep->sfde_func_num_fres; i++)
   {
     err = sframe_decode_fre (fres, &cur_fre, fre_type, &size);
     if (err)
       return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

     start_ip_offset = cur_fre.fre_start_addr;
     end_ip_offset = sframe_fre_get_end_ip_offset (fdep, i, fres + size);

     /* Stop search if FRE's start_ip is greater than pc.  Given
	func_start_addr <= pc, pc - func_start_addr must be positive.  */
     if (start_ip_offset > (uint32_t)(pc - func_start_addr))
       return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

     if (sframe_fre_check_range_p (ctx, func_idx, start_ip_offset,
				   end_ip_offset, pc))
       {
	 sframe_frame_row_entry_copy (frep, &cur_fre);
	 return 0;
       }
     fres += size;
   }
  return sframe_set_errno (&err, SFRAME_ERR_FDE_INVAL);
}

/* Return the number of function descriptor entries in the SFrame decoder
   DCTX.  */

uint32_t
sframe_decoder_get_num_fidx (sframe_decoder_ctx *ctx)
{
  uint32_t num_fdes = 0;
  sframe_header *dhp = NULL;
  dhp = sframe_decoder_get_header (ctx);
  if (dhp)
    num_fdes = dhp->sfh_num_fdes;
  return num_fdes;
}

/* Get the data (NUM_FRES, FUNC_START_ADDRESS) from the function
   descriptor entry at index I'th in the decoder CTX.  If failed,
   return error code.  */
/* FIXME - consolidate the args and return a
   sframe_func_desc_index_elem rather?  */

int
sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx,
			     unsigned int i,
			     uint32_t *num_fres,
			     uint32_t *func_size,
			     int32_t *func_start_address,
			     unsigned char *func_info)
{
  sframe_func_desc_entry *fdp;
  int err = 0;

  if (ctx == NULL || func_start_address == NULL || num_fres == NULL
      || func_size == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  fdp = sframe_decoder_get_funcdesc_at_index (ctx, i);

  if (fdp == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);

  *num_fres = fdp->sfde_func_num_fres;
  *func_start_address = fdp->sfde_func_start_address;
  *func_size = fdp->sfde_func_size;
  *func_info = fdp->sfde_func_info;

  return 0;
}

int
sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *dctx,
				unsigned int i,
				uint32_t *num_fres,
				uint32_t *func_size,
				int32_t *func_start_address,
				unsigned char *func_info,
				uint8_t *rep_block_size)
{
  sframe_func_desc_entry *fdp;
  int err = 0;

  if (dctx == NULL || func_start_address == NULL
      || num_fres == NULL || func_size == NULL
      || sframe_decoder_get_version (dctx) == SFRAME_VERSION_1)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  fdp = sframe_decoder_get_funcdesc_at_index (dctx, i);

  if (fdp == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);

  *num_fres = fdp->sfde_func_num_fres;
  *func_start_address = fdp->sfde_func_start_address;
  *func_size = fdp->sfde_func_size;
  *func_info = fdp->sfde_func_info;
  *rep_block_size = fdp->sfde_func_rep_size;

  return 0;
}
/* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function
   descriptor entry in the SFrame decoder CTX.  Returns error code as
   applicable.  */

int
sframe_decoder_get_fre (sframe_decoder_ctx *ctx,
			unsigned int func_idx,
			unsigned int fre_idx,
			sframe_frame_row_entry *fre)
{
  sframe_func_desc_entry *fdep;
  sframe_frame_row_entry ifre;
  const char *fres;
  uint32_t i;
  uint32_t fre_type;
  size_t esz = 0;
  int err = 0;

  if (ctx == NULL || fre == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  /* Get function descriptor entry at index func_idx.  */
  fdep = sframe_decoder_get_funcdesc_at_index (ctx, func_idx);

  if (fdep == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);

  fre_type = sframe_get_fre_type (fdep);
  /* Now scan the FRE entries.  */
  fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off;
  for (i = 0; i < fdep->sfde_func_num_fres; i++)
   {
     /* Decode the FRE at the current position.  Return it if valid.  */
     err = sframe_decode_fre (fres, &ifre, fre_type, &esz);
     if (i == fre_idx)
       {
	 if (!sframe_fre_sanity_check_p (&ifre))
	   return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

	  /* Although a stricter sanity check on fre_start_addr like:
	       if (fdep->sfde_func_size)
		 sframe_assert (frep->fre_start_addr < fdep->sfde_func_size);
	     is more suitable, some code has been seen to not abide by it.  See
	     PR libsframe/33131.  */
	  sframe_assert (ifre.fre_start_addr <= fdep->sfde_func_size);

	 sframe_frame_row_entry_copy (fre, &ifre);

	 return 0;
       }
     /* Next FRE.  */
     fres += esz;
   }

  return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);
}


/* SFrame Encoder.  */

/* Get a reference to the ENCODER's SFrame header.  */

static sframe_header *
sframe_encoder_get_header (sframe_encoder_ctx *encoder)
{
  sframe_header *hp = NULL;
  if (encoder)
    hp = &encoder->sfe_header;
  return hp;
}

static sframe_func_desc_entry *
sframe_encoder_get_funcdesc_at_index (sframe_encoder_ctx *encoder,
				      uint32_t func_idx)
{
  sframe_func_desc_entry *fde = NULL;
  if (func_idx < sframe_encoder_get_num_fidx (encoder))
    {
      sf_fde_tbl *func_tbl = encoder->sfe_funcdesc;
      fde = func_tbl->entry + func_idx;
    }
  return fde;
}

/* Create an encoder context with the given SFrame format version VER, FLAGS
   and ABI information.  Uses the ABI specific FIXED_FP_OFFSET and
   FIXED_RA_OFFSET values as provided.  Sets errp if failure.  */

sframe_encoder_ctx *
sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch,
	       int8_t fixed_fp_offset, int8_t fixed_ra_offset, int *errp)
{
  sframe_header *hp;
  sframe_encoder_ctx *encoder;

  if (ver != SFRAME_VERSION)
    return sframe_ret_set_errno (errp, SFRAME_ERR_VERSION_INVAL);

  if ((encoder = malloc (sizeof (sframe_encoder_ctx))) == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);

  memset (encoder, 0, sizeof (sframe_encoder_ctx));

  /* Get the SFrame header and update it.  */
  hp = sframe_encoder_get_header (encoder);
  hp->sfh_preamble.sfp_version = ver;
  hp->sfh_preamble.sfp_magic = SFRAME_MAGIC;
  hp->sfh_preamble.sfp_flags = flags;

  /* Implementation in the SFrame encoder APIs, e.g.,
     sframe_encoder_write_sframe assume flag SFRAME_F_FDE_FUNC_START_PCREL
     set.  */
  if (!(flags & SFRAME_F_FDE_FUNC_START_PCREL))
   return sframe_ret_set_errno (errp, SFRAME_ERR_ECTX_INVAL);

  hp->sfh_abi_arch = abi_arch;
  hp->sfh_cfa_fixed_fp_offset = fixed_fp_offset;
  hp->sfh_cfa_fixed_ra_offset = fixed_ra_offset;

  return encoder;
}

/* Free the encoder context.  */

void
sframe_encoder_free (sframe_encoder_ctx **encoder)
{
  if (encoder != NULL)
    {
      sframe_encoder_ctx *ectx = *encoder;
      if (ectx == NULL)
	return;

      if (ectx->sfe_funcdesc != NULL)
	{
	  free (ectx->sfe_funcdesc);
	  ectx->sfe_funcdesc = NULL;
	}
      if (ectx->sfe_fres != NULL)
	{
	  free (ectx->sfe_fres);
	  ectx->sfe_fres = NULL;
	}
      if (ectx->sfe_data != NULL)
	{
	  free (ectx->sfe_data);
	  ectx->sfe_data = NULL;
	}

      free (*encoder);
      *encoder = NULL;
    }
}

/* Get the size of the SFrame header from the encoder ctx ENCODER.  */

unsigned int
sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder)
{
  sframe_header *ehp;
  ehp = sframe_encoder_get_header (encoder);
  return sframe_get_hdr_size (ehp);
}

/* Get the abi/arch info from the SFrame encoder context ENCODER.  */

uint8_t
sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder)
{
  uint8_t abi_arch = 0;
  sframe_header *ehp;
  ehp = sframe_encoder_get_header (encoder);
  if (ehp)
    abi_arch = ehp->sfh_abi_arch;
  return abi_arch;
}

/* Get the format version from the SFrame encoder context ENCODER.  */

uint8_t
sframe_encoder_get_version (sframe_encoder_ctx *encoder)
{
  sframe_header *ehp;
  ehp = sframe_encoder_get_header (encoder);
  return ehp->sfh_preamble.sfp_version;
}

/* Get the section flags from the SFrame encoder context ENCODER.  */

uint8_t
sframe_encoder_get_flags (sframe_encoder_ctx *encoder)
{
  const sframe_header *ehp = sframe_encoder_get_header (encoder);
  return ehp->sfh_preamble.sfp_flags;
}

/* Return the number of function descriptor entries in the SFrame encoder
   ENCODER.  */

uint32_t
sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder)
{
  uint32_t num_fdes = 0;
  sframe_header *ehp = NULL;
  ehp = sframe_encoder_get_header (encoder);
  if (ehp)
    num_fdes = ehp->sfh_num_fdes;
  return num_fdes;
}

/* Get the offset of the sfde_func_start_address field (from the start of the
   on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the encoder
   context ENCODER.

   If FUNC_IDX is more than the number of SFrame FDEs in the section, sets
   error code in ERRP, but returns the (hypothetical) offset.  This is useful
   for the linker when arranging input FDEs into the output section to be
   emitted.  */

uint32_t
sframe_encoder_get_offsetof_fde_start_addr (sframe_encoder_ctx *encoder,
					    uint32_t func_idx, int *errp)
{
  if (func_idx >= sframe_encoder_get_num_fidx (encoder))
    sframe_ret_set_errno (errp, SFRAME_ERR_FDE_INVAL);
  else if (errp)
    *errp = 0;

  return (sframe_encoder_get_hdr_size (encoder)
	  + func_idx * sizeof (sframe_func_desc_entry)
	  + offsetof (sframe_func_desc_entry, sfde_func_start_address));
}

/* Add an FRE to function at FUNC_IDX'th function descriptor entry in
   the encoder context.  */

int
sframe_encoder_add_fre (sframe_encoder_ctx *encoder,
			unsigned int func_idx,
			sframe_frame_row_entry *frep)
{
  sframe_header *ehp;
  sframe_func_desc_entry *fdep;
  sframe_frame_row_entry *ectx_frep;
  size_t offsets_sz, esz;
  uint32_t fre_type;
  size_t fre_tbl_sz;
  int err = 0;

  if (encoder == NULL || frep == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);
  if (!sframe_fre_sanity_check_p (frep))
    return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

  /* Use func_idx to gather the function descriptor entry.  */
  fdep = sframe_encoder_get_funcdesc_at_index (encoder, func_idx);

  if (fdep == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);

  fre_type = sframe_get_fre_type (fdep);
  sf_fre_tbl *fre_tbl = encoder->sfe_fres;

  if (fre_tbl == NULL)
    {
      fre_tbl_sz = (sizeof (sf_fre_tbl)
		    + (number_of_entries * sizeof (sframe_frame_row_entry)));
      fre_tbl = malloc (fre_tbl_sz);

      if (fre_tbl == NULL)
	{
	  sframe_set_errno (&err, SFRAME_ERR_NOMEM);
	  goto bad;		/* OOM.  */
	}
      memset (fre_tbl, 0, fre_tbl_sz);
      fre_tbl->alloced = number_of_entries;
    }
  else if (fre_tbl->count == fre_tbl->alloced)
    {
      fre_tbl_sz = (sizeof (sf_fre_tbl)
		    + ((fre_tbl->alloced + number_of_entries)
		       * sizeof (sframe_frame_row_entry)));
      fre_tbl = realloc (fre_tbl, fre_tbl_sz);
      if (fre_tbl == NULL)
	{
	  sframe_set_errno (&err, SFRAME_ERR_NOMEM);
	  goto bad;		/* OOM.  */
	}

      memset (&fre_tbl->entry[fre_tbl->alloced], 0,
	      number_of_entries * sizeof (sframe_frame_row_entry));
      fre_tbl->alloced += number_of_entries;
    }

  ectx_frep = &fre_tbl->entry[fre_tbl->count];
  ectx_frep->fre_start_addr
    = frep->fre_start_addr;
  ectx_frep->fre_info = frep->fre_info;

  /* Although a stricter sanity check on fre_start_addr like:
       if (fdep->sfde_func_size)
	 sframe_assert (frep->fre_start_addr < fdep->sfde_func_size);
     is more suitable, some code has been seen to not abide by it.  See PR
     libsframe/33131.  */
  sframe_assert (frep->fre_start_addr <= fdep->sfde_func_size);

  /* frep has already been sanity check'd.  Get offsets size.  */
  offsets_sz = sframe_fre_offset_bytes_size (frep->fre_info);
  memcpy (&ectx_frep->fre_offsets, &frep->fre_offsets, offsets_sz);

  esz = sframe_fre_entry_size (frep, fre_type);
  fre_tbl->count++;

  encoder->sfe_fres = fre_tbl;
  encoder->sfe_fre_nbytes += esz;

  ehp = sframe_encoder_get_header (encoder);
  ehp->sfh_num_fres = fre_tbl->count;

  /* Update the value of the number of FREs for the function.  */
  fdep->sfde_func_num_fres++;

  return 0;

bad:
  if (fre_tbl != NULL)
    free (fre_tbl);
  encoder->sfe_fres = NULL;
  encoder->sfe_fre_nbytes = 0;
  return -1;
}

/* Add a new function descriptor entry with START_ADDR, FUNC_SIZE and NUM_FRES
   to the encoder.  */

int
sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder,
			     int32_t start_addr,
			     uint32_t func_size,
			     unsigned char func_info,
			     uint32_t num_fres ATTRIBUTE_UNUSED)
{
  sframe_header *ehp;
  sf_fde_tbl *fd_info;
  size_t fd_tbl_sz;
  int err = 0;

  /* FIXME book-keep num_fres for error checking.  */
  if (encoder == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  fd_info = encoder->sfe_funcdesc;
  ehp = sframe_encoder_get_header (encoder);

  if (fd_info == NULL)
    {
      fd_tbl_sz = (sizeof (sf_fde_tbl)
		   + (number_of_entries * sizeof (sframe_func_desc_entry)));
      fd_info = malloc (fd_tbl_sz);
      if (fd_info == NULL)
	{
	  sframe_set_errno (&err, SFRAME_ERR_NOMEM);
	  goto bad;		/* OOM.  */
	}
      memset (fd_info, 0, fd_tbl_sz);
      fd_info->alloced = number_of_entries;
    }
  else if (fd_info->count == fd_info->alloced)
    {
      fd_tbl_sz = (sizeof (sf_fde_tbl)
		   + ((fd_info->alloced + number_of_entries)
		      * sizeof (sframe_func_desc_entry)));
      fd_info = realloc (fd_info, fd_tbl_sz);
      if (fd_info == NULL)
	{
	  sframe_set_errno (&err, SFRAME_ERR_NOMEM);
	  goto bad;		/* OOM.  */
	}

      memset (&fd_info->entry[fd_info->alloced], 0,
	      number_of_entries * sizeof (sframe_func_desc_entry));
      fd_info->alloced += number_of_entries;
    }

  fd_info->entry[fd_info->count].sfde_func_start_address = start_addr;
  /* Num FREs is updated as FREs are added for the function later via
     sframe_encoder_add_fre.  */
  fd_info->entry[fd_info->count].sfde_func_size = func_size;
  fd_info->entry[fd_info->count].sfde_func_start_fre_off
    = encoder->sfe_fre_nbytes;
#if 0
  // Linker optimization test code cleanup later ibhagat TODO FIXME
  uint32_t fre_type = sframe_calc_fre_type (func_size);

  fd_info->entry[fd_info->count].sfde_func_info
    = sframe_fde_func_info (fre_type);
#endif
  fd_info->entry[fd_info->count].sfde_func_info = func_info;
  fd_info->count++;
  encoder->sfe_funcdesc = fd_info;
  ehp->sfh_num_fdes++;
  return 0;

bad:
  if (fd_info != NULL)
    free (fd_info);
  encoder->sfe_funcdesc = NULL;
  ehp->sfh_num_fdes = 0;
  return -1;
}

/* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO
   and REP_BLOCK_SIZE to the encoder.

   This API is valid only for SFrame format version 2.  */

int
sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder,
				int32_t start_addr,
				uint32_t func_size,
				unsigned char func_info,
				uint8_t rep_block_size,
				uint32_t num_fres ATTRIBUTE_UNUSED)
{
  sf_fde_tbl *fd_info;
  int err;

  if (encoder == NULL
      || sframe_encoder_get_version (encoder) == SFRAME_VERSION_1)
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  err = sframe_encoder_add_funcdesc (encoder, start_addr, func_size, func_info,
				     num_fres);
  if (err)
    return SFRAME_ERR;

  fd_info = encoder->sfe_funcdesc;
  fd_info->entry[fd_info->count-1].sfde_func_rep_size = rep_block_size;

  return 0;
}

static int
sframe_sort_funcdesc (sframe_encoder_ctx *encoder)
{
  sframe_header *ehp = sframe_encoder_get_header (encoder);

  /* Sort and write out the FDE table.  */
  sf_fde_tbl *fd_info = encoder->sfe_funcdesc;
  if (fd_info)
    {
      /* The new encoding of sfde_func_start_address means the distances are
	 not from the same anchor, so cannot be sorted directly.  At the moment
	 we adress this by manual value adjustments before and after sorting.
	 FIXME - qsort_r may be more optimal.  */

      for (unsigned int i = 0; i < fd_info->count; i++)
	fd_info->entry[i].sfde_func_start_address
	  += sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL);

      qsort (fd_info->entry, fd_info->count,
	     sizeof (sframe_func_desc_entry), fde_func);

      for (unsigned int i = 0; i < fd_info->count; i++)
	fd_info->entry[i].sfde_func_start_address
	  -= sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL);

      /* Update preamble's flags.  */
      ehp->sfh_preamble.sfp_flags |= SFRAME_F_FDE_SORTED;
    }
  return 0;
}

/* Write the SFrame FRE start address from the in-memory FRE_START_ADDR
   to the buffer CONTENTS (on-disk format), given the FRE_TYPE and
   FRE_START_ADDR_SZ.  */

static int
sframe_encoder_write_fre_start_addr (char *contents,
				     uint32_t fre_start_addr,
				     uint32_t fre_type,
				     size_t fre_start_addr_sz)
{
  int err = 0;

  if (fre_type == SFRAME_FRE_TYPE_ADDR1)
    {
      uint8_t uc = fre_start_addr;
      memcpy (contents, &uc, fre_start_addr_sz);
    }
  else if (fre_type == SFRAME_FRE_TYPE_ADDR2)
    {
      uint16_t ust = fre_start_addr;
      memcpy (contents, &ust, fre_start_addr_sz);
    }
  else if (fre_type == SFRAME_FRE_TYPE_ADDR4)
    {
      uint32_t uit = fre_start_addr;
      memcpy (contents, &uit, fre_start_addr_sz);
    }
  else
    return sframe_set_errno (&err, SFRAME_ERR_INVAL);

  return 0;
}

/* Write a frame row entry pointed to by FREP into the buffer CONTENTS.  The
   size in bytes written out are updated in ESZ.

   This function works closely with the SFrame binary format.

   Returns SFRAME_ERR if failure.  */

static int
sframe_encoder_write_fre (char *contents, sframe_frame_row_entry *frep,
			  uint32_t fre_type, size_t *esz)
{
  size_t fre_sz;
  size_t fre_start_addr_sz;
  size_t fre_stack_offsets_sz;
  int err = 0;

  if (!sframe_fre_sanity_check_p (frep))
    return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

  fre_start_addr_sz = sframe_fre_start_addr_size (fre_type);
  fre_stack_offsets_sz = sframe_fre_offset_bytes_size (frep->fre_info);

  /* The FRE start address must be encodable in the available number of
     bytes.  */
  uint64_t bitmask = SFRAME_BITMASK_OF_SIZE (fre_start_addr_sz);
  sframe_assert ((uint64_t)frep->fre_start_addr <= bitmask);

  sframe_encoder_write_fre_start_addr (contents, frep->fre_start_addr,
				       fre_type, fre_start_addr_sz);
  contents += fre_start_addr_sz;

  memcpy (contents, &frep->fre_info, sizeof (frep->fre_info));
  contents += sizeof (frep->fre_info);

  memcpy (contents, frep->fre_offsets, fre_stack_offsets_sz);
  contents+= fre_stack_offsets_sz;

  fre_sz = sframe_fre_entry_size (frep, fre_type);
  /* Sanity checking.  */
  sframe_assert ((fre_start_addr_sz
		  + sizeof (frep->fre_info)
		  + fre_stack_offsets_sz) == fre_sz);

  *esz = fre_sz;

  return 0;
}

/* Serialize the core contents of the SFrame section and write out to the
   output buffer held in the ENCODER.  Return SFRAME_ERR if failure.  */

static int
sframe_encoder_write_sframe (sframe_encoder_ctx *encoder)
{
  char *contents;
  size_t buf_size;
  size_t hdr_size;
  size_t all_fdes_size;
  size_t fre_size;
  size_t esz = 0;
  sframe_header *ehp;
  sf_fde_tbl *fd_info;
  sf_fre_tbl *fr_info;
  uint32_t i, num_fdes;
  uint32_t j, num_fres;
  sframe_func_desc_entry *fdep;
  sframe_frame_row_entry *frep;

  uint32_t fre_type;
  int err = 0;

  contents = encoder->sfe_data;
  buf_size = encoder->sfe_data_size;
  num_fdes = sframe_encoder_get_num_fidx (encoder);
  all_fdes_size = num_fdes * sizeof (sframe_func_desc_entry);
  ehp = sframe_encoder_get_header (encoder);
  hdr_size = sframe_get_hdr_size (ehp);

  fd_info = encoder->sfe_funcdesc;
  fr_info = encoder->sfe_fres;

  /* Sanity checks:
     - buffers must be malloc'd by the caller.  */
  if ((contents == NULL) || (buf_size < hdr_size))
    return sframe_set_errno (&err, SFRAME_ERR_BUF_INVAL);
  if (fr_info == NULL)
    return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);

  /* Write out the FRE table first.

     Recall that read/write of FREs needs information from the corresponding
     FDE; the latter stores the information about the FRE type record used for
     the function.  Also note that sorting of FDEs does NOT impact the order
     in which FREs are stored in the SFrame's FRE sub-section.  This means
     that writing out FREs after sorting of FDEs will need some additional
     book-keeping.  At this time, we can afford to avoid it by writing out
     the FREs first to the output buffer.  */
  fre_size = 0;
  uint32_t global = 0;
  uint32_t fre_index = 0;

  contents += hdr_size + all_fdes_size;
  for (i = 0; i < num_fdes; i++)
    {
      fdep = &fd_info->entry[i];
      fre_type = sframe_get_fre_type (fdep);
      num_fres = fdep->sfde_func_num_fres;

      for (j = 0; j < num_fres; j++)
	{
	  fre_index = global + j;
	  frep = &fr_info->entry[fre_index];

	  sframe_encoder_write_fre (contents, frep, fre_type, &esz);
	  contents += esz;
	  fre_size += esz; /* For debugging only.  */
	}
      global += j;
    }

  sframe_assert (fre_size == ehp->sfh_fre_len);
  sframe_assert (global == ehp->sfh_num_fres);
  sframe_assert ((size_t)(contents - encoder->sfe_data) == buf_size);

  /* Sort the FDE table */
  sframe_sort_funcdesc (encoder);

  /* Sanity checks:
     - the FDE section must have been sorted by now on the start address
     of each function.  */
  if (!(sframe_encoder_get_flags (encoder) & SFRAME_F_FDE_SORTED)
      || (fd_info == NULL))
    return sframe_set_errno (&err, SFRAME_ERR_FDE_INVAL);

  contents = encoder->sfe_data;
  /* Write out the SFrame header.  The SFrame header in the encoder
     object has already been updated with correct offsets by the caller.  */
  memcpy (contents, ehp, hdr_size);
  contents += hdr_size;

  /* Write out the FDE table sorted on funtion start address.  */
  memcpy (contents, fd_info->entry, all_fdes_size);
  contents += all_fdes_size;

  return 0;
}

/* Serialize the contents of the encoder and return the buffer.  ENCODED_SIZE
   is updated to the size of the buffer.  */

char *
sframe_encoder_write (sframe_encoder_ctx *encoder,
		      size_t *encoded_size, int *errp)
{
  sframe_header *ehp;
  size_t hdrsize, fsz, fresz, bufsize;
  int foreign_endian;

  /* Initialize the encoded_size to zero.  This makes it simpler to just
     return from the function in case of failure.  Free'ing up of
     encoder->sfe_data is the responsibility of the caller.  */
  *encoded_size = 0;

  if (encoder == NULL || encoded_size == NULL || errp == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_INVAL);

  ehp = sframe_encoder_get_header (encoder);
  hdrsize = sframe_get_hdr_size (ehp);
  fsz = sframe_encoder_get_num_fidx (encoder)
    * sizeof (sframe_func_desc_entry);
  fresz = encoder->sfe_fre_nbytes;

  /* The total size of buffer is the sum of header, SFrame Function Descriptor
     Entries section and the FRE section.  */
  bufsize = hdrsize + fsz + fresz;
  encoder->sfe_data = (char *) malloc (bufsize);
  if (encoder->sfe_data == NULL)
    return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
  encoder->sfe_data_size = bufsize;

  /* Update the information in the SFrame header.  */
  /* SFrame FDE section follows immediately after the header.  */
  ehp->sfh_fdeoff = 0;
  /* SFrame FRE section follows immediately after the SFrame FDE section.  */
  ehp->sfh_freoff = fsz;
  ehp->sfh_fre_len = fresz;

  foreign_endian = need_swapping (ehp->sfh_abi_arch);

  /* Write out the FDE Index and the FRE table in the sfe_data. */
  if (sframe_encoder_write_sframe (encoder))
    return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);

  /* Endian flip the contents if necessary.  */
  if (foreign_endian)
    {
      if (flip_sframe (encoder->sfe_data, bufsize, 1))
	return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
      flip_header ((sframe_header*)encoder->sfe_data);
    }

  *encoded_size = bufsize;
  return encoder->sfe_data;
}
