/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of 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, 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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <stdlib.h>
#include <stdarg.h>

#include "util.h"
#include "Application.h"
#include "CallStack.h"
#include "Experiment.h"
#include "Exp_Layout.h"
#include "DataObject.h"
#include "DbeSession.h"
#include "MetricList.h"
#include "Function.h"
#include "Module.h"
#include "MemObject.h"
#include "DbeView.h"
#include "Metric.h"
#include "DataSpace.h"
#include "LoadObject.h"

#include "debug.h"
#include "ABS.h"

//char *DOBJ_UNSPECIFIED  = STXT("(Not identified by the compiler as a memory-referencing instruction)");
char *DOBJ_UNSPECIFIED  = STXT("(No type information)");
char *DOBJ_UNIDENTIFIED = STXT("(No identifying descriptor provided by the compiler)");
char *DOBJ_UNDETERMINED = STXT("(Not determined from the symbolic information provided by the compiler)");
char *DOBJ_ANON         = STXT("(Padding in structure)");

// run-time codes
//  ABS_UNSUPPORTED = 0x01, /* inappropriate HWC event type */
//  ABS_BLOCKED     = 0x02, /* runtime backtrack blocker reached */
//  ABS_INCOMPLETE  = 0x03, /* runtime backtrack limit reached */
//  ABS_REG_LOSS    = 0x04, /* address register contaminated */
//  ABS_INVALID_EA  = 0x05, /* invalid effective address value */

const char *ABS_RT_CODES[NUM_ABS_RT_CODES] = {
  "(OK)",
  "(Dataspace data not requested during data collection)",
  "(Backtracking was prevented by a jump or call instruction)",
  "(Backtracking did not find trigger PC)",
  "(Could not determine VA because registers changed after trigger instruction)",
  "(Memory-referencing instruction did not specify a valid VA)",
  "(UNKNOWN)"
};

// post-processing codes
//  ABS_NO_CTI_INFO = 0x10, /* no AnalyzerInfo for validation */
//  ABS_INFO_FAILED = 0x20, /* info failed to validate backtrack */
//  ABS_CTI_TARGET  = 0x30, /* CTI target invalidated backtrack */
char *DOBJ_UNASCERTAINABLE = STXT("(Module with trigger PC not compiled with -xhwcprof)");
char *DOBJ_UNVERIFIABLE    = STXT("(Backtracking failed to find a valid branch target)");
char *DOBJ_UNRESOLVABLE    = STXT("(Backtracking traversed a branch target)");

char *ABS_PP_CODES[NUM_ABS_PP_CODES] = {
  STXT ("(OK)"),
  DOBJ_UNASCERTAINABLE,
  DOBJ_UNVERIFIABLE,
  DOBJ_UNRESOLVABLE,
  STXT ("(<INTERNAL ERROR DURING POST-PROCESSING>)")
};

DataSpace::DataSpace (DbeView *_dbev, int /* _picked */)
{
  dbev = _dbev;
}

DataSpace::~DataSpace () { }

void
DataSpace::reset () { }

char *
DataSpace::status_str ()
{
  return NULL;
}

Histable *
DataSpace::get_hist_obj (Histable::Type type, DataView *dview, long i)
{
  DataObject *dobj = NULL;
  char *errcode = NTXT ("<internal error>");
  switch (type)
    {
    case Histable::DOBJECT:
      dobj = (DataObject*) dview->getObjValue (PROP_HWCDOBJ, i);
      if (dobj == NULL)
	{
	  Vaddr leafVA = (Vaddr) dview->getLongValue (PROP_VADDR, i);
	  unsigned rt_code = (unsigned) ABS_GET_RT_CODE (leafVA);
	  unsigned pp_code = (unsigned) ABS_GET_PP_CODE (leafVA);
	  if (leafVA < ABS_CODE_RANGE
	      && (pp_code || (rt_code && rt_code != ABS_REG_LOSS)))
	    {
	      if (rt_code >= NUM_ABS_RT_CODES)
		rt_code = NUM_ABS_RT_CODES - 1;
	      if (pp_code >= NUM_ABS_PP_CODES)
		pp_code = NUM_ABS_PP_CODES - 1;
	      if (rt_code)
		errcode = PTXT (ABS_RT_CODES[rt_code]);
	      else
		errcode = PTXT (ABS_PP_CODES[pp_code]);
	    }
	  else
	    {
	      // associate dataobject with event
	      int index;

	      // search for memop in Module infoList
	      void *cstack = dview->getObjValue (PROP_MSTACK, i);
	      Histable *leafPCObj = CallStack::getStackPC (cstack, 0);
	      DbeInstr *leafPC = NULL;
	      if (leafPCObj->get_type () == Histable::INSTR)
		leafPC = (DbeInstr*) leafPCObj;
	      else  // DBELINE
		leafPC = (DbeInstr*) leafPCObj->convertto (Histable::INSTR);
	      Function *func = leafPC->func;
	      uint64_t leafPC_offset = func->img_offset + leafPC->addr;
	      Module *mod = func->module;
	      uint32_t dtype_id = 0;
	      inst_info_t *info = NULL;
	      Vec_loop (inst_info_t*, mod->infoList, index, info)
	      {
		if (info->offset == leafPC_offset)
		  {
		    dtype_id = info->memop->datatype_id;
		    break;
		  }
	      }
	      dobj = mod->get_dobj (dtype_id);
	      if (dobj == NULL)
		{
		  // ensure dobj is determined
		  if (dtype_id == DataObject::UNSPECIFIED_ID)
		    errcode = PTXT (DOBJ_UNSPECIFIED);
		  else
		    errcode = PTXT (DOBJ_UNIDENTIFIED);
		}
	      else
		{
		  // determine associated master dataobject
		  if (!dobj->master && dobj->scope)
		    dobj->master = dbeSession->createMasterDataObject (dobj);
		  if (dobj->scope)
		    dobj = dobj->master;  // use associated master
		}
	    }
	  if (!dobj)
	    {
	      // if dobj is not set yet, supply a dobj for errcode
	      // search for a dobj with the same name
	      dobj = dbeSession->find_dobj_by_name (errcode);
	      if (dobj == NULL)
		{
		  // create new DataObject for unknown code
		  dobj = (DataObject*) dbeSession->createHistObject (Histable::DOBJECT);
		  dobj->size = 0;
		  dobj->offset = -1;
		  dobj->parent = dbeSession->get_Unknown_DataObject ();
		  dobj->set_dobjname (errcode, NULL); // dobj->parent must already be set
		}
	    }
	  dview->setObjValue (PROP_HWCDOBJ, i, dobj);
	}
      break;
    default:
      break;
    }
  return dobj;
}

Hist_data *
DataSpace::compute_metrics (MetricList *mlist, Histable::Type type,
			    Hist_data::Mode mode, Histable *sel_obj)
{
  int nmetrics = mlist->get_items ()->size ();
  int sort_ind = -1;
  Hist_data::HistItem *hi;
  int index;

  // reset event_data count for all datatypes
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  for (int i = 0, sz = lobjs ? lobjs->size () : -1; i < sz; i++)
    {
      LoadObject *lo = lobjs->fetch (i);
      Vector<Module*> *modules = lo->seg_modules;
      for (int j = 0, msize = modules ? modules->size () : -1; j < msize; j++)
	{
	  Module *mod = modules->fetch (j);
	  mod->reset_datatypes ();
	}
    }
  Hist_data *hist_data = new Hist_data (mlist, type, mode);

  // add each experiment, skipping disabled and broken experiments
  for (index = 0; index < dbeSession->nexps (); index++)
    {
      Experiment *exp = dbeSession->get_exp (index);
      if (exp->broken)
	continue;

      Collection_params *params = exp->get_params ();
      if (!params->xhw_mode)
	continue;

      char *expt_name = exp->get_expt_name ();
      char *base_name = strrchr (expt_name, '/');
      base_name = base_name ? base_name + 1 : expt_name;

      // Determine mapping of experiment HWC metrics to hist_data metric list
      int *xlate = new int[MAX_HWCOUNT];
      for (unsigned i = 0; i < MAX_HWCOUNT; i++)
	{
	  xlate[i] = -1;
	  if (params->hw_interval[i] > 0)
	    {
	      const char *ctr_name = params->hw_aux_name[i];
	      int mindex;
	      Metric *met;
	      Vec_loop (Metric*, mlist->get_items (), mindex, met)
	      {
		if (dbe_strcmp (met->get_cmd (), ctr_name) == 0)
		  xlate[i] = mindex;
	      }
	    }
	}

      //
      // Process hardware profiling data
      //
      DataView *dview = dbev->get_filtered_events (index, DATA_HWC);
      if (dview)
	{
	  DataDescriptor *ddscr = dview ->getDataDescriptor ();
	  if (ddscr->getProp (PROP_HWCDOBJ) == NULL)
	    {
	      PropDescr *prop = new PropDescr (PROP_HWCDOBJ, NTXT ("HWCDOBJ"));
	      prop->uname = NULL;
	      prop->vtype = TYPE_OBJ;
	      ddscr->addProperty (prop);
	    }
	}
      if (dview && dview->getSize () != 0)
	{
	  char *msg = NULL;
	  for (long i = 0; i < dview->getSize (); i++)
	    {
	      if (i % 5000 == 0)
		{
		  int percent = (int) (100.0 * i / dview->getSize ());
		  if (percent == 0 && msg == NULL)
		    msg = dbe_sprintf (GTXT ("Filtering HW Profile Address Data: %s"), base_name);
		  theApplication->set_progress (percent, (percent != 0) ? NULL : msg);
		}

	      uint32_t tag = dview->getIntValue (PROP_HWCTAG, i);
	      if (tag < 0 || tag >= MAX_HWCOUNT)
		continue;  // invalid HWC tag in the record; ignore it
	      int mHwcntr_idx = xlate[tag];
	      if (mHwcntr_idx < 0)
		continue;

	      Vaddr leafVA = (Vaddr) dview->getLongValue (PROP_VADDR, i);
	      if (leafVA == ABS_UNSUPPORTED)
		continue; // skip this record
	      Histable *obj = get_hist_obj (type, dview, i);
	      if (obj == NULL)
		continue;
	      uint64_t interval = dview->getLongValue (PROP_HWCINT, i);
	      if (HWCVAL_HAS_ERR (interval))
		continue;
	      if (mode == Hist_data::ALL)
		{ // data_objects
		  hi = hist_data->append_hist_item (obj);
		  hi->value[mHwcntr_idx].ll += interval;
		  for (DataObject *dobj = ((DataObject *) obj)->parent; dobj; dobj = dobj->parent)
		    {
		      hi = hist_data->append_hist_item (dobj);
		      hi->value[mHwcntr_idx].ll += interval;
		    }
		}
	      else if (mode == Hist_data::LAYOUT || mode == Hist_data::DETAIL)
		{ // data_single
		  {
		    // for data layout, insert elements that have no metrics yet
		    DataObject *tmpParent = ((DataObject *) obj)->parent;
		    if (tmpParent && tmpParent->get_typename ())
		      {
			// dobj is an aggregate element
			if (!hist_data->find_hist_item (tmpParent))
			  {
			    // parent not yet a member of hist_data
			    // supply parent's children with 0 values for layout
			    Vector<DataObject*> *elements = dbeSession->get_dobj_elements (tmpParent);
			    for (long eli = 0, sz = elements->size (); eli < sz; eli++)
			      {
				DataObject* element = elements->fetch (eli);
				assert (!hist_data->find_hist_item (element));
				hi = hist_data->append_hist_item (element);
			      }
			  }
		      }
		  }

		  // Same as for mode == Hist_data::ALL:
		  hi = hist_data->append_hist_item (obj);
		  hi->value[mHwcntr_idx].ll += interval;
		  for (DataObject *dobj = ((DataObject *) obj)->parent; dobj; dobj = dobj->parent)
		    {
		      hi = hist_data->append_hist_item (dobj);
		      hi->value[mHwcntr_idx].ll += interval;
		    }
		}
	      else if (mode == Hist_data::SELF)
		{ // used by dbeGetSummary()
		  if (obj == sel_obj)
		    {
		      hi = hist_data->append_hist_item (obj);
		      hi->value[mHwcntr_idx].ll += interval;
		    }
		  else
		    {
		      for (DataObject *dobj = ((DataObject *) obj)->parent; dobj; dobj = dobj->parent)
			{
			  if ((Histable*) dobj == sel_obj)
			    {
			      hi = hist_data->append_hist_item (dobj);
			      hi->value[mHwcntr_idx].ll += interval;
			      break;
			    }
			}
		    }
		}
	      // Update total
	      hist_data->total->value[mHwcntr_idx].ll += interval;
	    }
	  free (msg);
	  theApplication->set_progress (0, NTXT (""));
	}
      delete[] xlate;
    }

  // include a regular HistItem for <Total> -- for all DataObjects, and MemObjects
  DataObject *dtot = dbeSession->get_Total_DataObject ();
  if (mode == Hist_data::ALL || mode == Hist_data::DETAIL
      || mode == Hist_data::LAYOUT ||
      sel_obj == dtot)
    {
      hi = hist_data->append_hist_item (dtot);
      for (int mind = 0; mind < nmetrics; mind++)
	hi->value[mind] = hist_data->total->value[mind];
    }
  if (hist_data->get_status () != Hist_data::SUCCESS)
    return hist_data;
  theApplication->set_progress (0, GTXT ("Constructing Metrics"));

  // Determine by which metric to sort if any
  bool rev_sort = mlist->get_sort_rev ();

  // Compute static metrics: SIZES, ADDRESS.
  for (int mind = 0; mind < nmetrics; mind++)
    {
      Metric *mtr = mlist->get_items ()->fetch (mind);
      if (mlist->get_sort_ref_index () == mind)
	sort_ind = mind;
      else if (!mtr->is_visible () && !mtr->is_tvisible ()
	       && !mtr->is_pvisible ())
	continue;
      Metric::Type mtype = mtr->get_type ();
      if (mtype == Metric::SIZES)
	{
	  Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	  {
	    Histable *h = mtr->get_comparable_obj (hi->obj);
	    hi->value[mind].tag = VT_LLONG;
	    hi->value[mind].ll = h ? h->get_size () : 0;
	  }
	}
      else if (mtype == Metric::ONAME
	       && (mode == Hist_data::SELF
		   || ((DataObject*) sel_obj == dbeSession->get_Total_DataObject ())))
	{
	  Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	  {
	    hi->value[mind].tag = VT_OFFSET; // offset labels
	  }
	}
      else if (mtype == Metric::ADDRESS)
	{ // pseudo-address
	  Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	  {
	    hi->value[mind].tag = VT_ADDRESS;
	    Histable *h = mtr->get_comparable_obj (hi->obj);
	    hi->value[mind].ll = h ? h->get_addr () : 0;
	  }
	  // force sort by offset // XXXX should visibility also be set?
	  if (mode == Hist_data::SELF)
	    { // used by dbeGetSummary()
	      sort_ind = mind;
	      //hist_data->metrics->fetch(mind)->set_visible(T);
	    }
	}
      else
	{
	  ValueTag vtype = mtr->get_vtype ();
	  switch (vtype)
	    {
	    case VT_ULLONG: // most Data-derived HWC metrics are VT_ULLONG
	      hist_data->total->value[mind].tag = vtype;
	      Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
	      {
		hi->value[mind].tag = vtype;
	      }
	      break;
	    case VT_DOUBLE:
	      {
		double prec = mtr->get_precision ();
		hist_data->total->value[mind].tag = vtype;
		hist_data->total->value[mind].d = hist_data->total->value[mind].ll / prec;
		Vec_loop (Hist_data::HistItem *, hist_data->hist_items, index, hi)
		{
		  hi->value[mind].tag = vtype;
		  hi->value[mind].d = hi->value[mind].ll / prec;
		}
		break;
	      }
	    default:
	      if (mtr->get_subtype () != Metric::STATIC)
		abort ();
	      break;
	    }
	}
    }
  hist_data->sort (sort_ind, rev_sort);
  hist_data->compute_minmax ();
  theApplication->set_progress (0, NTXT (""));
  return hist_data;
}


// generate annotated structure info for data_layout
// note: similar data traversal found in er_print_histogram::dump_detail()
Hist_data *
DataSpace::get_layout_data (Hist_data *sorted_data,
			    Vector<int> *marks, int /* _threshold */)
{
  Hist_data *data_items = NULL;
  Hist_data::HistItem *new_item;
  MetricList *mlist = new MetricList (sorted_data->get_metric_list ());
  int no_metrics = mlist->get_items ()->size ();
  int index, addr_index = -1, name_index = -1;
  Dprintf (DEBUG_DATAOBJ, NTXT ("DataSpace::get_layout_data(ALL)\n"));

  // Allocate a new Hist_data for the list, to be copied from the DataObect list
  data_items = new Hist_data (mlist, Histable::DOBJECT, Hist_data::MODL);
  data_items->set_status (sorted_data->get_status ());

  // suppress threshold setting
  // XXX this threshold should probably not be used
  sorted_data->set_threshold ((double) 75. / 100.0);
  TValue* all_empty = new TValue[no_metrics];
  memset (all_empty, 0, sizeof (TValue) * no_metrics);

  Metric *mitem;
  Vec_loop (Metric*, mlist->get_items (), index, mitem)
  {
    // new data items have same total as original items
    data_items->total->value[index] = sorted_data->total->value[index];
    // empty metric items need matching types
    all_empty[index].tag = mitem->get_vtype ();
    if (mitem->get_type () == Metric::ONAME) name_index = index;
    if (mitem->get_type () == Metric::ADDRESS) addr_index = index;
  }

  int64_t next_elem_offset = 0;
  for (long i = 0; i < sorted_data->size (); i++)
    {
      Hist_data::HistItem* ditem = sorted_data->fetch (i);
      DataObject* dobj = (DataObject*) (ditem->obj);
      if (!dobj->get_parent ())
	{ // doesn't have a parent; top level item
	  next_elem_offset = 0;
	  if (i > 0)
	    { // add a blank line as separator
	      // fixme xxxxx, is it really ok to create a DataObject just for this?
	      DataObject* empty = new DataObject ();
	      empty->size = 0;
	      empty->offset = 0;
	      empty->set_name (NTXT (""));
	      new_item = sorted_data->new_hist_item (empty, Module::AT_EMPTY, all_empty);
	      new_item->value[name_index].tag = VT_LABEL;
	      new_item->value[name_index].l = NULL;
	      data_items->append_hist_item (new_item);
	    }
	  // then add the aggregate
	  new_item = sorted_data->new_hist_item (dobj, Module::AT_SRC, ditem->value);
	  new_item->value[name_index].tag = VT_OFFSET;
	  new_item->value[name_index].l = dbe_strdup (dobj->get_name ());
	  data_items->append_hist_item (new_item);
	}
      else
	{ // is a child
	  if (dobj->get_parent ()->get_typename ())
	    { // typed sub-element that has offset
	      if (dobj->offset > next_elem_offset)
		{ // filler entry
		  // hole in offsets
		  // fixme xxxxx, is it really ok to create a DataObject just for this?
		  DataObject* filler = new DataObject ();
		  filler->set_name (PTXT (DOBJ_ANON));
		  filler->size = (dobj->offset - next_elem_offset);
		  filler->offset = next_elem_offset;
		  new_item = sorted_data->new_hist_item (filler, Module::AT_EMPTY, all_empty);
		  new_item->value[name_index].tag = VT_OFFSET;
		  new_item->value[name_index].l = dbe_strdup (filler->get_offset_name ());
		  if (addr_index >= 0)
		    {
		      new_item->value[addr_index].tag = VT_ADDRESS;
		      new_item->value[addr_index].ll = (dobj->get_addr () - filler->size);
		    }
		  data_items->append_hist_item (new_item);
		}
	      next_elem_offset = dobj->offset + dobj->size;
	    }
	  // then add the aggregate's subelement
	  if (marks)
	    if (sorted_data->above_threshold (ditem))
	      marks->append (data_items->size ());
	  new_item = sorted_data->new_hist_item (dobj, Module::AT_DIS, ditem->value);
	  new_item->value[name_index].tag = VT_OFFSET;
	  new_item->value[name_index].l = dbe_strdup (dobj->get_offset_name ());
	  data_items->append_hist_item (new_item);
	}
    }
  delete[] all_empty;
  return data_items;
}
