/* Copyright (C) 2021-2024 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 <assert.h>
#include <string.h>
#include <ctype.h>

#include "util.h"
#include "DbeSession.h"
#include "Application.h"
#include "DataObject.h"
#include "Module.h"
#include "debug.h"

DataObject::DataObject ()
{
  name = NULL;
  parent = NULL;
  master = NULL;
  _unannotated_name = NULL;
  _typename = NULL;
  _instname = NULL;
  scope = NULL;
  EAs = new Vector<DbeEA*>;
  size = 0;
  offset = (uint64_t) (-1);
}

DataObject::~DataObject ()
{
  free (_unannotated_name);
  free (_typename);
  free (_instname);
  EAs->destroy ();
  delete EAs;
}

// get_addr() doesn't return an actual address for a DataObject
// but rather synthesises an address-like identifier tuple.
// XXXX since an aggregate and its first element have identical tuples
// may need to arrange for special-purpose sorting "by address"
uint64_t
DataObject::get_addr ()
{
  uint64_t addr;
  if (parent && parent->get_typename ())
    addr = MAKE_ADDRESS (parent->id, offset);   // element
  else if (parent)
    addr = MAKE_ADDRESS (parent->id, id) | 0x8000000000000000ULL; // Scalar, Unknown
  else if (id == dbeSession->get_Scalars_DataObject ()->id)
    addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Scalar aggregate
  else if (id == dbeSession->get_Unknown_DataObject ()->id)
    addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Unknown aggregate
  else
    addr = MAKE_ADDRESS (id, 0);     // aggregate
  return addr;
}

Histable *
DataObject::convertto (Histable_type type, Histable *)
{
  return type == DOBJECT ? this : NULL;
}

char
DataObject::get_offset_mark ()
{
  enum
  {
    blocksize = 32
  };

  if (size == 0 || offset == -1)
    return '?';     // undefined
  if (size > blocksize)
    return '#';     // requires multiple blocks
  if (size == blocksize && (offset % blocksize == 0))
    return '<';     // fits block entirely
  if (offset % blocksize == 0)
    return '/';     // starts block
  if ((offset + size) % blocksize == 0)
    return '\\';    // closes block
  if (offset / blocksize == ((offset + size) / blocksize))
    return '|';     // inside block
  return 'X';       // crosses blocks unnecessarily
}

char *
DataObject::get_offset_name ()
{
  char *offset_name;
  if (parent && parent->get_typename ()) // element
    offset_name = dbe_sprintf (GTXT ("%c%+6lld .{%s %s}"),
			       get_offset_mark (), (long long) offset,
			       _typename ? _typename : GTXT ("NO_TYPE"),
			       _instname ? _instname : GTXT ("-")); // "NO_NAME"
  else if ((offset != -1) && (offset > 0)) // filler
    offset_name = dbe_sprintf (GTXT ("%c%+6lld %s"), get_offset_mark (),
			       (long long) offset, get_name ());
  else if (parent) // Scalar/Unknown element
    offset_name = dbe_sprintf (GTXT ("        .%s"), get_unannotated_name ());
  else // aggregate
    offset_name = dbe_strdup (get_name ());
  return offset_name;
}

void
DataObject::set_dobjname (char *type_name, char *inst_name)
{
  _unannotated_name = _typename = _instname = NULL;
  if (inst_name)
    _instname = dbe_strdup (inst_name);

  char *buf;
  if (parent == dbeSession->get_Scalars_DataObject ())
    {
      if (type_name)
	_typename = dbe_strdup (type_name);
      _unannotated_name = dbe_sprintf (NTXT ("{%s %s}"), type_name,
				       inst_name ? inst_name : NTXT ("-"));
      buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
    }
  else if (parent == dbeSession->get_Unknown_DataObject ())
    {
      _unannotated_name = dbe_strdup (type_name);
      buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
    }
  else
    {
      if (type_name)
	_typename = dbe_strdup (type_name);
      if (parent && parent->get_typename ())
	buf = dbe_sprintf (NTXT ("%s.{%s %s}"),
			   parent->get_name () ? parent->get_name () : NTXT ("ORPHAN"),
			   type_name ? type_name : NTXT ("NO_TYPE"),
			   inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
      else
	buf = dbe_sprintf (NTXT ("{%s %s}"),
			   type_name ? type_name : NTXT ("NO_TYPE"),
			   inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
    }
  name = buf;
  dbeSession->dobj_updateHT (this);
}

void
DataObject::set_name (char *string)
{
  name = dbe_strdup (string);
  dbeSession->dobj_updateHT (this);
}

DbeEA *
DataObject::find_dbeEA (Vaddr EA)
{
  DbeEA *dbeEA;
  int left = 0;
  int right = EAs->size () - 1;
  while (left <= right)
    {
      int index = (left + right) / 2;
      dbeEA = EAs->fetch (index);
      if (EA < dbeEA->eaddr)
	right = index - 1;
      else if (EA > dbeEA->eaddr)
	left = index + 1;
      else
	return dbeEA;
    }

  // None found, create a new one
  dbeEA = new DbeEA (this, EA);
  EAs->insert (left, dbeEA);
  return dbeEA;
}
