/* sframe-state.c - The SFrame state for stacktracing.

   Copyright (C) 2023 Free Software Foundation, Inc.

   This file is part of libsframest.

   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 <link.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <execinfo.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ucontext.h>
#include <stdarg.h>
#include "ansidecl.h"
#include "sframe-api.h"
#include "sframe-stacktrace-api.h"
#include "sframe-stacktrace-regs.h"
#include "sframe-state.h"

#define _sf_printflike_(string_index, first_to_check) ATTRIBUTE_PRINTF (1, 2)

static bool _sframe_unwind_debug;	/* Control for printing out debug info.  */
static const int no_of_entries = NUM_OF_DSOS;

void
sframe_unwind_init_debug (void)
{
  static int inited;

  if (!inited)
    {
      _sframe_unwind_debug = getenv ("SFRAME_UNWIND_DEBUG") != NULL;
      inited = 1;
    }
}

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

      va_start (args, format);
      __builtin_vprintf (format, args);
      va_end (args);
    }
}

#if 0
/* sframe_bt_set_errno - Store the specified error code ERROR into ERRP if
   it is non-NULL.  */

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

#endif

static void
sframest_sfinfo_init (struct sframest_info *sfinfo, const char *buf,
		      int64_t buflen, uint64_t sframe_vma,
		      uint64_t text_vma, int64_t text_size)
{
  if (!sfinfo)
    return;

  sfinfo->buf = buf;
  sfinfo->buflen = buflen;
  sfinfo->sframe_vma = sframe_vma;
  sfinfo->text_vma = text_vma;
  sfinfo->text_size = text_size;
}

/* Return whether the given SFrame stack trace info object SFINFO has (stack
   trace) information corresponding to addr.  */

bool
sframest_sfinfo_addr_range_p (struct sframest_info *sfinfo, uint64_t addr)
{
  if (!sfinfo || !addr)
    return false;

  return (sfinfo->text_vma <= addr
	  && sfinfo->text_vma + sfinfo->text_size > addr);
}

/* Add .sframe info in D_DATA, which is associated with
   a dynamic shared object, to D_LIST.  */

static int
sframe_add_dso (struct sframest_info_list *d_list,
		struct sframest_info d_data)
{
  int err = 0;

  if (!d_list->alloced)
    {
      d_list->entry = malloc (no_of_entries * sizeof (struct sframest_info));
      if (!d_list->entry)
	return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_MALLOC);

      memset (d_list->entry, 0,
	      no_of_entries * sizeof (struct sframest_info));
      d_list->alloced = no_of_entries;
    }
  else if (d_list->used == d_list->alloced)
    {
      d_list->entry = realloc (d_list->entry,
			       ((d_list->alloced + no_of_entries)
				* sizeof (struct sframest_info)));
      if (!d_list->entry)
	return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_REALLOC);

      memset (&d_list->entry[d_list->alloced], 0,
	      no_of_entries * sizeof (struct sframest_info));
      d_list->alloced += no_of_entries;
    }

  sframe_bt_ret_set_errno (&err, SFRAME_BT_OK);
  d_list->entry[d_list->used++] = d_data;

  return SFRAME_BT_OK;
}

/* Free up space allocated SFrame stack trace context object SFCTX.  */

void
sframest_ctx_free (struct sframest_ctx *sfctx)
{
  struct sframest_info_list *d_list;
  int i;

  if (!sfctx)
    return;

  // free (sf->sui_ctx.sfdd_data);
  sframe_decoder_free (&sfctx->prog_sfinfo.dctx);
  close (sfctx->fd);

  d_list = &sfctx->dsos_sfinfo;
  if (!d_list->alloced)
    return;

  for (i = 0; i < d_list->used; ++i)
    {
      // free (d_list->entry[i].sfdd_data);
      sframe_decoder_free (&d_list->entry[i].dctx);
    }

  free (d_list->entry);
}

/* Find the decode data that contains ADDR from SFCTX.
   Return the pointer to the decode data or NULL.  */

struct sframest_info *
sframe_find_context (struct sframest_ctx *sfctx, uint64_t addr)
{
  struct sframest_info_list *d_list;
  struct sframest_info sfinfo;
  int i;

  if (!sfctx)
    return NULL;

  if (sframest_sfinfo_addr_range_p (&sfctx->prog_sfinfo, addr))
    return &sfctx->prog_sfinfo;

  d_list = &sfctx->dsos_sfinfo;
  for (i = 0; i < sfctx->dsos_sfinfo.used; ++i)
    {
      sfinfo = d_list->entry[i];
      if (sframest_sfinfo_addr_range_p (&sfinfo, addr))
	return &d_list->entry[i];
    }

  return NULL;
}

/* Call decoder to create and set up the SFrame info for either the main module
   or one of the DSOs from SFCTX, based on the input RADDR argument.
   Return the newly created decode context or NULL.  */

struct sframest_info *
sframest_get_sfinfo (struct sframest_ctx *sfctx, uint64_t raddr)
{
  struct sframest_info *sfinfo = NULL;
  int err = 0;

  if (!sfctx)
    return NULL;

  sfinfo = sframe_find_context (sfctx, raddr);
  if (!sfinfo)
    return NULL;

  /* Decode the SFrame section the first time.  */
  if (!sfinfo->dctx)
    sfinfo->dctx = sframe_decode (sfinfo->buf, sfinfo->buflen, &err);

  return sfinfo;
}

/* Open /proc image associated with the process id and return the file
   descriptor.  */

static int
get_proc_mem_fd (int *errp)
{
  int fd;

  if ((fd = open ("/proc/self/mem", O_CLOEXEC)) == -1)
    {
      sframe_bt_ret_set_errno (errp, SFRAME_BT_ERR_OPEN);
      return -1;
    }

  return fd;
}

/* The callback from dl_iterate_phdr with header info in INFO.
   Return SFrame info for either the main module or a DSO in DATA.  */

int
sframe_callback (struct dl_phdr_info *info,
		 size_t size ATTRIBUTE_UNUSED,
		 void *data)
{
  struct sframest_ctx *sfctx = (struct sframest_ctx *) data;
  int p_type, i, fd, sframe_err;
  uint64_t text_vma = 0;
  uint64_t text_size = 0;

  if (!data || !info)
    return 1;

  debug_printf ("-- name: %s %14p\n", info->dlpi_name, (void *)info->dlpi_addr);

  for (i = 0; i < info->dlpi_phnum; i++)
    {
      debug_printf ("  %2d: [%" PRIu64 "; memsz %" PRIu64 "] flags: 0x%x; \n", i,
		   (uint64_t) info->dlpi_phdr[i].p_vaddr,
		   (uint64_t) info->dlpi_phdr[i].p_memsz,
		   info->dlpi_phdr[i].p_flags);

      p_type = info->dlpi_phdr[i].p_type;
      if (p_type == PT_LOAD && info->dlpi_phdr[i].p_flags & PF_X)
	{
	  text_vma = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr;
	  text_size = info->dlpi_phdr[i].p_memsz;
	  continue;
	}
      if (p_type != PT_SFRAME)
	continue;

      if (info->dlpi_name[0] == '\0')
	{
	  /* the main module.  */
	  fd = get_proc_mem_fd (&sframe_err);
	  if (fd == -1)
	    return 1;

	  assert (text_vma);
	  sframest_sfinfo_init (&sfctx->prog_sfinfo,
				(char *)(info->dlpi_addr
					 + info->dlpi_phdr[i].p_vaddr),
				info->dlpi_phdr[i].p_memsz,
				info->dlpi_addr + info->dlpi_phdr[i].p_vaddr,
				text_vma, text_size);
	  sfctx->fd = fd;
	  text_vma = 0;
	  return 0;
	}
      else
	{
	  /* a dynamic shared object.  */
	  struct sframest_info sfinfo;
	  memset (&sfinfo, 0, sizeof (struct sframest_info));
	  assert (sfctx->fd);

	  assert (text_vma);
	  sframest_sfinfo_init (&sfinfo,
				(char *)(info->dlpi_addr
					 + info->dlpi_phdr[i].p_vaddr),
				info->dlpi_phdr[i].p_memsz,
				info->dlpi_addr + info->dlpi_phdr[i].p_vaddr,
				text_vma, text_size);

	  text_vma = 0;
	  
	  sframe_err = sframe_add_dso (&sfctx->dsos_sfinfo, sfinfo);
	  // FIXME TODO
	  if (sframe_err != SFRAME_BT_OK)
	    return 1;
	  return 0;
	}
    }

    return 0;
}
