/* Copyright (C) 2021-2025 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 <unistd.h>
#include <ar.h>
#include <ctype.h>
#include <sys/param.h>

#include "util.h"
#include "DbeSession.h"
#include "Experiment.h"
#include "DataObject.h"
#include "Function.h"
#include "DbeView.h"
#include "MetricList.h"
#include "Module.h"
#include "ClassFile.h"
#include "LoadObject.h"
#include "Disasm.h"
#include "CompCom.h"
#include "Dwarf.h"
#include "DbeFile.h"
#include "PathTree.h"
#include "Elf.h"

Module::Module ()
{
  lang_code = Sp_lang_unknown;
  flags = 0;
  status = AE_NOTREAD;
  openSourceFlag = AE_NOTREAD;
  hexVisible = false;
  disPath = NULL;
  stabsPath = NULL;
  stabsTmp = NULL;
  disName = NULL;
  stabsName = NULL;
  indexStabsLink = NULL;
  file_name = NULL;
  functions = new Vector<Function*>;
  loadobject = NULL;
  dot_o_file = NULL;
  main_source = dbeSession->get_Unknown_Source ();
  srcContext = main_source;
  includes = new Vector<SourceFile*>;
  includes->append (main_source);
  curr_inc = NULL;
  fragmented = 0;
  hwcprof = 0;
  hdrOffset = 0;
  hasDwarf = false;
  hasStabs = false;
  readStabs = false;
  comComs = NULL;
  infoList = NULL;
  datatypes = NULL;
  objStabs = NULL;
  disasm = NULL;
  comp_flags = NULL;
  comp_dir = NULL;
  linkerStabName = NULL;
  disMTime = (time_t) 0;
  stabsMTime = (time_t) 0;
  real_timestamp = 0;
  curr_timestamp = 0;
  src_items = NULL;
  dis_items = NULL;
  data_items = NULL;
  cur_dbev = NULL;
  maximum = NULL;
  maximum_inc = NULL;
  empty = NULL;
  inlinedSubr = NULL;
}

Module::~Module ()
{
  removeStabsTmp ();
  delete includes;
  if (comComs != NULL)
    {
      comComs->destroy ();
      delete comComs;
    }
  free (comp_flags);
  free (comp_dir);
  free (linkerStabName);
  free (disPath);
  free (stabsPath);
  free (disName);
  free (stabsName);
  delete functions;
  free (file_name);
  if (indexStabsLink)
    // Remove a link to the current module
    indexStabsLink->indexStabsLink = NULL;

  if (dot_o_file)
    {
      delete dot_o_file->dbeFile;
      delete dot_o_file;
    }
  delete src_items;
  delete dis_items;
  delete disasm;
  free (inlinedSubr);
  if (lang_code != Sp_lang_java)
    delete dbeFile;

}

Stabs *
Module::openDebugInfo ()
{
  setFile ();
  objStabs = loadobject->openDebugInfo (disPath);
  return objStabs;
}

void
Module::removeStabsTmp ()
{
  // Remove temporary *.o (got from *.a) after reading Stabs
  if (stabsTmp != NULL)
    {
      unlink (stabsTmp);
      free (stabsTmp);
      stabsTmp = NULL;
    }
}

int64_t
Module::get_size ()
{
  Function *fp;
  int index;
  int64_t result = 0;
  Vec_loop (Function*, functions, index, fp)
  {
    result += fp->size;
  }
  return result;
}

bool
Module::is_fortran ()
{
  return Stabs::is_fortran (lang_code);
}

SourceFile *
Module::findSource (const char *fname, bool create)
{
  SourceFile *sf = NULL;
  if (loadobject && loadobject->firstExp)
    sf = loadobject->firstExp->get_source (fname);
  if (sf == NULL)
    sf = dbeSession->createSourceFile (fname);
  for (int i = 0, sz = includes ? includes->size () : 0; i < sz; i++)
    {
      SourceFile *sf1 = includes->fetch (i);
      if (sf == sf1)
	return sf;
    }
  if (create)
    {
      if (includes == NULL)
	includes = new Vector<SourceFile*>;
      includes->append (sf);
      return sf;
    }
  return NULL;
}

SourceFile *
Module::setIncludeFile (char *includeFile)
{
  curr_inc = NULL;
  if (includeFile)
    curr_inc = findSource (includeFile, true);
  return curr_inc;
}

char *
Module::anno_str (char *fnm)
{
  char timebuf1[26], timebuf2[26];
  const time_t real_time = (time_t) (unsigned int) real_timestamp;
  const time_t curr_time = (time_t) (unsigned int) curr_timestamp;

  switch (status)
    {
    case AE_OK:
    case AE_NOTREAD:
      return NULL;
    case AE_NOSRC:
      return dbe_sprintf (GTXT ("Source file `%s' not readable"),
			  fnm ? fnm : file_name);
    case AE_NOOBJ:
      if (lang_code == Sp_lang_java)
	{
	  Emsg *emsg = get_error ();
	  if (emsg)
	    {
	      char *s = dbe_strdup (emsg->get_msg ());
	      remove_msg (emsg);
	      return s;
	    }
	  return dbe_sprintf (GTXT ("Object file `%s.class' not readable"),
			      name);
	}
      return dbe_sprintf (GTXT ("Object file `%s' not readable"), get_name ());
    case AE_NOLOBJ:
      if (lang_code == Sp_lang_java)
	return dbe_sprintf (GTXT ("Object file `%s' not readable"),
			    dbeFile ? dbeFile->get_name () : name);
      return dbe_sprintf (GTXT ("Object file `%s' not readable"), loadobject->get_pathname ());
    case AE_NOSTABS:
      return dbe_sprintf (GTXT ("Error reading line-number information in object `%s'; source annotation not available"),
			  stabsPath ? stabsPath : NTXT (""));
    case AE_NOSYMTAB:
      return dbe_sprintf (GTXT ("Error reading symbol table in object `%s'; disassembly annotation not available"),
			  disPath ? disPath : NTXT (""));
    case AE_TIMESRC:
      return dbe_sprintf (GTXT ("Warning! Source file `%s' is newer than the experiment data"),
			  main_source->dbeFile->getResolvedPath ());
    case AE_TIMEDIS:
      return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),
			  disName ? disName : NTXT (""));
    case AE_TIMESTABS:
      return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),
			  stabsName ? stabsName : NTXT (""));
    case AE_TIMESTABS_DIFF:
      snprintf (timebuf1, sizeof (timebuf1), NTXT ("%s"), ctime (&curr_time));
      snprintf (timebuf2, sizeof (timebuf2), NTXT ("%s"), ctime (&real_time));
      timebuf1[24] = timebuf2[24] = '\0';
      return dbe_sprintf (GTXT ("Warning! Object file `%s' is not the same one that was linked into executable.\n"
				"\tObject file: `%s'\n\tcompiled on: %s\n"
				"\tExecutable contains object file compiled on: %s"),
			  getResolvedObjectPath (), getResolvedObjectPath (),
			  timebuf1, timebuf2);
    case AE_OTHER:
    default:
      return dbe_strdup (GTXT ("Annotation computation error"));
    }
}//anno_str

LoadObject *
Module::createLoadObject (const char *lo_name)
{
  LoadObject *lo = new LoadObject (lo_name);
  lo->dbeFile->filetype |= DbeFile::F_DOT_O;
  return lo;
}

static bool
tsIsNewer (time_t t1, time_t t2)
{
  return t1 != 0 && t2 != 0 && t1 < t2;
}

Module::Anno_Errors
Module::checkTimeStamp (bool chkDis)
{
  /* Check the linked and the real object timestamps due to bug #4796329 */
  if (real_timestamp && curr_timestamp && real_timestamp != curr_timestamp)
    return AE_TIMESTABS_DIFF;

  time_t srctime = main_source->getMTime ();
  for (int index = 0; index < dbeSession->nexps (); index++)
    {
      time_t mtime = dbeSession->get_exp (index)->get_mtime ();
      if (tsIsNewer (mtime, srctime))
	return AE_TIMESRC;
      if (tsIsNewer (mtime, stabsMTime))
	return AE_TIMESTABS;
      if (chkDis && tsIsNewer (mtime, disMTime))
	return AE_TIMEDIS;
    }
  return AE_OK;
}//checkTimeStamp

static size_t
get_ar_size (char *s, size_t len)
{
  size_t sz = 0;
  for (size_t i = 0; i < len; i++)
    {
      if (s[i] < '0' || s[i] > '9')
	break;
      sz = sz * 10 + (s[i] - '0');
    }
  return sz;
}

static void
dump_hdr_field (char *nm, char *s, size_t len)
{
  Dprintf (DEBUG_READ_AR, NTXT ("  %s "), nm);
  for (size_t i = 0; i < len; i++)
    Dprintf (DEBUG_READ_AR, "%c", isprint (s[i]) ? s[i] : '?');
  Dprintf (DEBUG_READ_AR, NTXT ("  "));
  for (size_t i = 0; i < len; i++)
    Dprintf (DEBUG_READ_AR, NTXT (" %d"), s[i]);
  Dprintf (DEBUG_READ_AR, NTXT (" \n"));
}

static void
dump_ar_hdr (int lineNum, struct ar_hdr *hdr)
{
  if (DEBUG_READ_AR)
    {
      Dprintf (DEBUG_READ_AR, NTXT ("Module::read_ar %d\n"), lineNum);
      dump_hdr_field (NTXT ("ar_name"), hdr->ar_name, sizeof (hdr->ar_name));
      dump_hdr_field (NTXT ("ar_date"), hdr->ar_date, sizeof (hdr->ar_date));
      dump_hdr_field (NTXT ("ar_uid"), hdr->ar_uid, sizeof (hdr->ar_uid));
      dump_hdr_field (NTXT ("ar_gid"), hdr->ar_gid, sizeof (hdr->ar_gid));
      dump_hdr_field (NTXT ("ar_mode"), hdr->ar_mode, sizeof (hdr->ar_mode));
      dump_hdr_field (NTXT ("ar_size"), hdr->ar_size, sizeof (hdr->ar_size));
      dump_hdr_field (NTXT ("ar_fmag"), hdr->ar_fmag, sizeof (hdr->ar_fmag));
    }
}

bool
Module::read_ar (int ar, int obj, char *obj_base)
{
  struct ar_hdr hdr; // Archive header
  char magic[SARMAG]; // Magic string from archive
  Dprintf (DEBUG_READ_AR, "Module::read_ar %d %p %s %s \n", __LINE__,
	   this, STR (obj_base), STR (get_name ()));
  // Check the magic string
  if ((read_from_file (ar, magic, SARMAG) != SARMAG)
       || strncmp (magic, ARMAG, SARMAG))
    return false;

  // Read and skip the first file in the archive (index file to ld)
  if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))
    return false;
  DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);
  if (lseek (ar, get_ar_size (hdr.ar_size, sizeof (hdr.ar_size)), SEEK_CUR)
	     == -1)
    return false;

  // Read the string file where it keeps long file names (if exist)
  if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))
    return false;
  DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);
  char *longnames = NULL; // Area with names longer than ~13
  size_t longnames_size = 0;
  if (!strncmp (hdr.ar_name, NTXT ("//"), 2))
    {
      longnames_size = get_ar_size (hdr.ar_size, sizeof (hdr.ar_size));
      longnames = (char *) xmalloc (longnames_size + 1);
      int64_t cnt = read_from_file (ar, longnames, longnames_size);
      if (cnt != (int64_t) longnames_size)
	{
	  free (longnames);
	  return false;
	}
      longnames[longnames_size] = 0;
    }
  else
    // back out, no long file names
    lseek (ar, -(sizeof (hdr)), SEEK_CUR);

  // Search the ar for the object file name
  char ar_buf[sizeof (hdr.ar_name) + 1];
  ar_buf[sizeof (hdr.ar_name)] = 0;
  while (1)
    {
      if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))
	break;
      DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);
      char *ar_name;
      if (hdr.ar_name[0] != '/')
	{ // Name is in the header
	  for (size_t i = 0; i < sizeof (hdr.ar_name); i++)
	    {
	      if (hdr.ar_name[i] == '/')
		{
		  ar_buf[i] = 0;
		  break;
		}
	      ar_buf[i] = hdr.ar_name[i];
	    }
	  ar_name = ar_buf;
	}
      else if (hdr.ar_name[1] == ' ')
	{ // Name is blank
	  ar_buf[0] = 0;
	  ar_name = ar_buf;
	}
      else
	{ // Name is in the string table
	  if (longnames == NULL)
	    break;
	  size_t offset = get_ar_size (hdr.ar_name + 1,
				       sizeof (hdr.ar_name) - 1);
	  if (offset >= longnames_size)
	    break;
	  for (size_t i = offset; i < longnames_size; i++)
	    {
	      if (longnames[i] == '/')
		{
		  longnames[i] = 0;
		  break;
		}
	    }
	  ar_name = longnames + offset;
	}
      Dprintf (DEBUG_READ_AR, "Module::read_ar %d ar_name=%s\n", __LINE__,
	       ar_name);

      if (streq (ar_name, obj_base))
	{ // create object file
	  free (longnames);
	  for (size_t objsize = get_ar_size (hdr.ar_size, sizeof (hdr.ar_size));
		  objsize > 0;)
	    {
	      char buf[MAXPATHLEN];
	      size_t n = objsize < sizeof (buf) ? objsize : sizeof (buf);
	      int64_t cnt = read_from_file (ar, buf, n);
	      if (cnt != (int64_t) n)
		return false;
	      cnt = write (obj, buf, n);
	      if (cnt != (int64_t) n)
		return false;
	      objsize -= n;
	    }
	  return true;
	}
      if (lseek (ar, get_ar_size (hdr.ar_size, sizeof (hdr.ar_size)),
		 SEEK_CUR) == -1)
	break;
    }
  free (longnames);
  return false;
}

static char *
get_obj_name_from_lib (char *nm)
{
  char *base = strrchr (nm, '(');
  if (base)
    {
      size_t last = strlen (base) - 1;
      if (base[last] == ')')
	return base;
    }
  return NULL;
}

bool
Module::setFile ()
{
  if ((loadobject->flags & SEG_FLAG_DYNAMIC) != 0)
    return true;
  if ((loadobject->dbeFile->filetype & DbeFile::F_FICTION) != 0)
    return false;
  if ((flags & MOD_FLAG_UNKNOWN) != 0)
    return true;

  if (lang_code == Sp_lang_java)
    {
      if (dbeFile->get_need_refind ())
	{
	  char *fnm = dbeFile->get_location ();
	  stabsPath = dbe_strdup (fnm);
	  stabsName = dbe_strdup (fnm);
	  disPath = dbe_strdup (fnm);
	  disName = dbe_strdup (fnm);
	  stabsMTime = dbeFile->sbuf.st_mtime;
	}
      return dbeFile->get_location () != NULL;
    }

  if (dbeFile == NULL)
    {
      char *objname = get_obj_name_from_lib (name);
      if (objname)
	{
	  // in the format of libpath(obj)
	  objname = dbe_strdup (objname + 1);
	  size_t last = strlen (objname) - 1;
	  objname[last] = '\0';
	}
      dbeFile = new DbeFile (objname ? objname : name);
      free (objname);
      dbeFile->filetype |= DbeFile::F_DOT_O;
    }
  if (dbeFile->get_need_refind ())
    {
      disMTime = (time_t) 0;
      stabsMTime = (time_t) 0;
      free (disName);
      free (stabsName);
      disName = NULL;
      stabsName = NULL;

      // Find the Executable/Shared-Object file of module
      char *path = loadobject->dbeFile->get_location ();
      if (path)
	{
	  disPath = xstrdup (path);
	  disName = xstrdup (path);
	  disMTime = loadobject->dbeFile->sbuf.st_mtime;
	}

      char *objname = get_obj_name_from_lib (name);
      if (objname)
	{
	  // in the format of libpath(obj)
	  char *namebuf = dbe_strdup (name);
	  char *base = namebuf + (objname - name);
	  *base = '\0';
	  base++;
	  size_t last = strlen (base) - 1;
	  base[last] = '\0';
	  stabsTmp = dbeSession->get_tmp_file_name (base, false);
	  dbeSession->tmp_files->append (xstrdup (stabsTmp));

	  DbeFile *dbf = dbeSession->getDbeFile (namebuf,
					DbeFile::F_DOT_A_LIB | DbeFile::F_FILE);
	  path = dbf->get_location ();
	  int ar = -1, obj = -1;
	  if (path != NULL)
	    {
	      ar = open64 (path, O_RDONLY | O_LARGEFILE);
	      if (ar != -1)
		obj = open64 (stabsTmp, O_CREAT | O_WRONLY | O_LARGEFILE, 0600);
	    }
	  if (ar != -1 && obj != -1 && read_ar (ar, obj, base))
	    {
	      dbeFile->set_location (stabsTmp);
	      dbeFile->check_access (stabsTmp); // init 'sbuf'
	      dbeFile->sbuf.st_mtime = 0; // Don't check timestamps
	      dbeFile->container = dbf;
	      stabsPath = xstrdup (stabsTmp);
	      stabsName = xstrdup (path);
	      stabsMTime = dbeFile->sbuf.st_mtime;
	    }
	  else
	    {
	      removeStabsTmp ();
	      objname = NULL;
	    }
	  if (ar != -1)
	    close (ar);
	  if (obj != -1)
	    close (obj);
	  free (namebuf);
	}
      if (objname == NULL)
	{
	  path = dbeFile->get_location ();
	  if (path != NULL)
	    {
	      stabsPath = xstrdup (path);
	      stabsName = xstrdup (path);
	      stabsMTime = hasDwarf ? 0 : dbeFile->sbuf.st_mtime;
	    }
	}

      // First, try to access the symbol table of the module itself
      // If failed, access the symbol table of the executable
      if (stabsPath == NULL)
	{
	  if (disPath == NULL)
	    return false;
	  stabsPath = xstrdup (disPath);
	  stabsName = xstrdup (disName);
	  stabsMTime = disMTime;
	}
      else if (disPath == NULL)
	{
	  disPath = xstrdup (stabsPath);
	  disName = xstrdup (stabsName);
	  disMTime = stabsMTime;
	}
    }
  return stabsPath != NULL;
}

// openStabs -- open mappings from PCs to source lines
bool
Module::openStabs (bool all)
{
  if ((loadobject->flags & SEG_FLAG_DYNAMIC) != 0
      || (flags & MOD_FLAG_UNKNOWN) != 0)
    return true;
  if (loadobject->platform == Java)
    {
      setIncludeFile (NULL);
      readFile ();
      return ( status == AE_OK);
    }
  if (readStabs)
    return true;

  // Read Stabs info.
  int64_t Inode = main_source->getInode ();
  char *fname = strrchr (file_name, (int) '/');
  char *mname = strrchr (main_source->get_name (), (int) '/');
  if (fname && mname && !streq (fname, mname))
    {
      SourceFile *sf = findSource (file_name, false);
      if (sf != NULL)
	Inode = sf->getInode ();
    }

  comComs = new Vector<ComC*>;
  Stabs *stabs = openDebugInfo ();
  if (stabs == NULL)
    return false;
  int st = stabs->read_stabs (Inode, this, comComs, true);
  if (!hasDwarf && hasStabs && !streq (stabsPath, disPath))
    {
      // Read stabs from .o file
      if (dot_o_file == NULL)
	{
	  if (dbeFile->get_location ())
	    {
	      dot_o_file = createLoadObject (dbeFile->get_name ());
	      dot_o_file->dbeFile->set_location (dbeFile->get_location ());
	      dot_o_file->dbeFile->sbuf = dbeFile->sbuf;
	      dot_o_file->dbeFile->container = dbeFile->container;
	    }
	}
      if (dot_o_file
	  && dot_o_file->sync_read_stabs () == LoadObject::ARCHIVE_SUCCESS)
	{
	  Stabs *stabs_o = dot_o_file->objStabs;
	  if (stabs_o)
	    {
	      st = stabs_o->read_stabs (Inode, this,
					comComs->size () > 0 ? NULL : comComs);
	      Elf *elf_o = stabs_o->openElf (false);
	      if (elf_o->dwarf)
		stabs->read_dwarf_from_dot_o (this);
	    }
	}
    }
  if (all)
    read_hwcprof_info ();

  readStabs = true;
  return st == Stabs::DBGD_ERR_NONE;
}

char *
Module::get_disasm (uint64_t inst_address, uint64_t end_address,
		   uint64_t start_address, uint64_t address, int64_t &inst_size)
{
  return disasm->get_disasm (inst_address, end_address, start_address,
			     address, inst_size);
}

void
Module::read_stabs (bool all)
{
  if (openSourceFlag == AE_NOTREAD)
    {
      openSourceFlag = AE_OK;
      if (lang_code == Sp_lang_java)
	{
	  char *clpath = file_name;
	  if (clpath == NULL || strcmp (clpath, "<Unknown>") == 0)
	    clpath = ClassFile::get_java_file_name (name, false);
	  main_source = findSource (clpath, true);
	  main_source->dbeFile->filetype |= DbeFile::F_JAVA_SOURCE;
	  if (clpath != file_name)
	    free (clpath);
	}
      else
	main_source = findSource (file_name, true);
      if (setFile ())
	openStabs (all);
    }
}

bool
Module::openDisPC ()
{
  if (disasm == NULL)
    {
      if (!(loadobject->flags & SEG_FLAG_DYNAMIC) && loadobject->platform != Java)
	{
	  // Read Stabs & Symbol tables
	  if (openDebugInfo () == NULL)
	    return false;
	  if (!objStabs->read_symbols (functions))
	    return false;
	}
      disasm = new Disasm (loadobject->platform, objStabs);
    }
  return true;
}

static SourceFile *cmpSrcContext; // Use only for func_cmp

static int
func_cmp (const void *a, const void *b)
{
  Function *fp1 = *((Function **) a);
  Function *fp2 = *((Function **) b);
  return fp1->func_cmp (fp2, cmpSrcContext);
}

bool
Module::computeMetrics (DbeView *dbev, Function *func, MetricList *metrics,
			Histable::Type type, bool src_metric,
			bool func_scope, SourceFile *source)
{
  name_idx = metrics->get_listorder (NTXT ("name"), Metric::STATIC);
  if (name_idx < 0)
    {
      metrics->print_metric_list (stderr,
				  GTXT ("Fatal: no name metric in Module::computeMetrics mlist:\n"),
				  1);
      abort ();
    }

  // Now find the metrics for size and address, if present
  size_index = metrics->get_listorder (NTXT ("size"), Metric::STATIC);
  addr_index = metrics->get_listorder (NTXT ("address"), Metric::STATIC);

  // free the old cached data for both src and disassembly
  //   If it's disassembly with visible source metrics, we use both
  if (dis_items)
    {
      delete dis_items;
      dis_items = NULL;
    }
  if (src_items)
    {
      delete src_items;
      src_items = NULL;
    }

  // ask the DbeView to generate new data to be cached
  if (src_metric || type == Histable::LINE)
    {
      Histable *obj = (func_scope) ? (Histable*) func : (Histable*)this;
      if (lang_code == Sp_lang_java)
	obj = func_scope ? (Histable *) func :
	      (source && source->get_type () == Histable::SOURCEFILE ?
	       (Histable *) source : (Histable *) this);
      src_items = dbev->get_hist_data (metrics, Histable::LINE, 0,
				       Hist_data::MODL, obj, source);
    }
  if (type == Histable::INSTR)
    dis_items = dbev->get_hist_data (metrics, Histable::INSTR, 0,
			       Hist_data::MODL,
			       func_scope ? (Histable*) func : (Histable*) this,
			       source);

  Hist_data *cur_hist_data;
  if (type == Histable::INSTR)
    cur_hist_data = dis_items;
  else
    cur_hist_data = src_items;

  Vector<Metric*> *items = cur_hist_data->get_metric_list ()->get_items ();
  long sz = items->size ();
  empty = new TValue[sz];
  memset (empty, 0, sizeof (TValue) * sz);
  for (long i = 0; i < sz; i++)
    empty[i].tag = items->get (i)->get_vtype ();
  return true;
}

// Method to get annotated source or disassembly for the module
//	or a function within it
Hist_data *
Module::get_data (DbeView *dbev, MetricList *mlist, Histable::Type type,
		  TValue *ftotal, SourceFile *srcFile, Function *func,
		  Vector<int> *marks, int threshold, int vis_bits,
		  int src_visible, bool hex_vis, bool func_scope,
		  bool /*src_only*/, Vector<int_pair_t> *marks2d,
		  Vector<int_pair_t> *marks2d_inc)
{
  cur_dbev = dbev;
  srcContext = srcFile ? srcFile : main_source;
  read_stabs ();
  status = AE_OK;
  dbev->warning_msg = NULL;
  dbev->error_msg = NULL;
  if (type == Histable::LINE)
    {
      if (!srcContext->readSource ())
	{
	  status = AE_NOSRC;
	  dbev->error_msg = anno_str (srcContext->get_name ());
	  return NULL;
	}
      if (!computeMetrics (dbev, func, mlist, type, false, func_scope, srcContext))
	{
	  status = AE_OTHER;
	  dbev->error_msg = anno_str ();
	  return NULL;
	}
      status = checkTimeStamp (false);
    }
  else
    { // Histable::INSTR
      Anno_Errors src_status = AE_OK;
      if (!srcContext->readSource ())
	{
	  src_status = AE_NOSRC;
	  dbev->error_msg = anno_str (srcContext->get_name ());
	}
      if (!setFile ())
	status = AE_NOLOBJ;
      else
	{
	  if (!openStabs ())
	    src_status = AE_NOSTABS;
	  if (!openDisPC ())
	    status = AE_NOSYMTAB;
	}
      if (status != AE_OK)
	{
	  dbev->error_msg = anno_str ();
	  return NULL;
	}
      if (src_status != AE_OK && func != NULL)
	{
	  if (loadobject->platform == Java && (func->flags & FUNC_FLAG_NATIVE) != 0)
	    {
	      append_msg (CMSG_ERROR,
			  GTXT ("`%s' is a native method; byte code not available\n"),
			  func->get_name ());
	      status = AE_NOOBJ;
	      dbev->error_msg = anno_str ();
	      return NULL;
	    }
	  func_scope = true;
	}
      // get the disassembly-line metric data
      if (!computeMetrics (dbev, func, mlist, type,
			   (src_visible & SRC_METRIC) != 0,
			   func_scope, srcContext))
	{
	  status = AE_OTHER;
	  dbev->error_msg = anno_str ();
	  return NULL;
	}
      status = checkTimeStamp (true);
    }
  total = ftotal;

  // initialize line number
  init_line ();

  // initialize data -- get duplicate metric list for the line texts
  // pick up the metric list from the computed data
  MetricList *nmlist = NULL;
  if (type == Histable::INSTR)
    {
      mlist = dis_items->get_metric_list ();
      nmlist = new MetricList (mlist);
      data_items = new Hist_data (nmlist, Histable::INSTR, Hist_data::MODL);
      data_items->set_status (dis_items->get_status ());
      set_dis_data (func, vis_bits, dbev->get_cmpline_visible (),
		    src_visible, hex_vis, func_scope,
		    dbev->get_funcline_visible ());
    }
  else
    {
      mlist = src_items->get_metric_list ();
      nmlist = new MetricList (mlist);
      data_items = new Hist_data (nmlist, Histable::LINE, Hist_data::MODL);
      data_items->set_status (src_items->get_status ());
      set_src_data (func_scope ? func : NULL, vis_bits,
		    dbev->get_cmpline_visible (),
		    dbev->get_funcline_visible ());
    }
  data_items->compute_minmax ();

  Metric *mitem;
  int index;
  Hist_data::HistItem *max_item;
  TValue *value;
  Hist_data::HistItem *max_item_inc;
  TValue *value_inc;
  double dthreshold = threshold / 100.0;

  int sz = data_items->get_metric_list ()->get_items ()->size ();
  maximum = new TValue[sz];
  maximum_inc = new TValue[sz];
  memset (maximum, 0, sizeof (TValue) * sz);
  memset (maximum_inc, 0, sizeof (TValue) * sz);
  max_item = data_items->get_maximums ();
  max_item_inc = data_items->get_maximums_inc ();

  Vec_loop (Metric*, data_items->get_metric_list ()->get_items (), index, mitem)
  {
    maximum_inc[index].tag = maximum[index].tag = mitem->get_vtype ();

    if (mitem->get_subtype () == Metric::STATIC)
      continue;
    if (!mitem->is_visible () && !mitem->is_tvisible ()
	&& !mitem->is_pvisible ())
      continue;

    value = &max_item->value[index];
    value_inc = &max_item_inc->value[index];

    double dthresh;
    if (mitem->is_zeroThreshold () == true)
      dthresh = 0;
    else
      dthresh = dthreshold;
    switch (value->tag)
      {
      case VT_INT:
	maximum[index].i = (int) (dthresh * (double) value->i);
	maximum_inc[index].i = (int) (dthresh * (double) value_inc->i);
	break;
      case VT_DOUBLE:
	maximum[index].d = dthresh * value->d;
	maximum_inc[index].d = dthresh * value_inc->d;
	break;
      case VT_LLONG:
	maximum[index].ll = (unsigned long long) (dthresh * (double) value->ll);
	maximum_inc[index].ll = (unsigned long long)
		(dthresh * (double) value_inc->ll);
	break;
      case VT_ULLONG:
	maximum[index].ull = (unsigned long long)
		(dthresh * (double) value->ull);
	maximum_inc[index].ull = (unsigned long long)
		(dthresh * (double) value_inc->ull);
	break;
      default:
	// not needed for non-numerical metrics
	break;
      }
  }

  // mark all high values
  for (int index1 = 0; index1 < data_items->size (); index1++)
    {
      Hist_data::HistItem *hi = data_items->fetch (index1);
      int index2;
      Vec_loop (Metric*, nmlist->get_items (), index2, mitem)
      {
	bool mark = false;
	if (mitem->get_subtype () == Metric::STATIC)
	  continue;
	if (!mitem->is_visible () && !mitem->is_tvisible ()
	    && !mitem->is_pvisible ())
	  continue;

	switch (hi->value[index2].tag)
	  {
	  case VT_DOUBLE:
	    if (nmlist->get_type () == MET_SRCDIS
		&& data_items->get_callsite_mark ()->get (hi->obj))
	      {
		if (hi->value[index2].d > maximum_inc[index2].d)
		  mark = true;
		break;
	      }
	    if (hi->value[index2].d > maximum[index2].d)
	      mark = true;
	    break;
	  case VT_INT:
	    if (nmlist->get_type () == MET_SRCDIS
		&& data_items->get_callsite_mark ()->get (hi->obj))
	      {
		if (hi->value[index2].i > maximum_inc[index2].i)
		  mark = true;
		break;
	      }
	    if (hi->value[index2].i > maximum[index2].i)
	      mark = true;
	    break;
	  case VT_LLONG:
	    if (nmlist->get_type () == MET_SRCDIS
		&& data_items->get_callsite_mark ()->get (hi->obj))
	      {
		if (hi->value[index2].ll > maximum_inc[index2].ll)
		  mark = true;
		break;
	      }
	    if (hi->value[index2].ll > maximum[index2].ll)
	      mark = true;
	    break;
	  case VT_ULLONG:
	    if (nmlist->get_type () == MET_SRCDIS
		&& data_items->get_callsite_mark ()->get (hi->obj))
	      {
		if (hi->value[index2].ull > maximum_inc[index2].ull)
		  mark = true;
		break;
	      }
	    if (hi->value[index2].ull > maximum[index2].ull)
	      mark = true;
	    break;
	    // ignoring the following cases (why?)
	  case VT_SHORT:
	  case VT_FLOAT:
	  case VT_HRTIME:
	  case VT_LABEL:
	  case VT_ADDRESS:
	  case VT_OFFSET:
	    break;
	  }
	if (mark)
	  {
	    marks->append (index1);
	    break;
	  }
      }
    }

  // mark all high values to marks2d
  if (marks2d != NULL && marks2d_inc != NULL)
    {
      for (int index1 = 0; index1 < data_items->size (); index1++)
	{
	  Hist_data::HistItem *hi = data_items->fetch (index1);
	  int index2;
	  Vec_loop (Metric*, nmlist->get_items (), index2, mitem)
	  {
	    Metric::SubType subType = mitem->get_subtype ();
	    if (subType == Metric::STATIC)
	      continue;
	    if (!mitem->is_visible () && !mitem->is_tvisible ()
		&& !mitem->is_pvisible ())
	      continue;
	    switch (hi->value[index2].tag)
	      {
	      case VT_DOUBLE:
		if (nmlist->get_type () == MET_SRCDIS
		    && data_items->get_callsite_mark ()->get (hi->obj))
		  {
		    if (hi->value[index2].d > maximum_inc[index2].d)
		      {
			int_pair_t pair = {index1, index2};
			marks2d_inc->append (pair);
		      }
		    break;
		  }
		if (hi->value[index2].d > maximum[index2].d)
		  {
		    int_pair_t pair = {index1, index2};
		    marks2d->append (pair);
		  }
		break;
	      case VT_INT:
		if (nmlist->get_type () == MET_SRCDIS
		    && data_items->get_callsite_mark ()->get (hi->obj))
		  {
		    if (hi->value[index2].i > maximum_inc[index2].i)
		      {
			int_pair_t pair = {index1, index2};
			marks2d_inc->append (pair);
		      }
		    break;
		  }
		if (hi->value[index2].i > maximum[index2].i)
		  {
		    int_pair_t pair = {index1, index2};
		    marks2d->append (pair);
		  }
		break;
	      case VT_LLONG:
		if (nmlist->get_type () == MET_SRCDIS
		    && data_items->get_callsite_mark ()->get (hi->obj))
		  {
		    if (hi->value[index2].ll > maximum_inc[index2].ll)
		      {
			int_pair_t pair = {index1, index2};
			marks2d_inc->append (pair);
		      }
		    break;
		  }
		if (hi->value[index2].ll > maximum[index2].ll)
		  {
		    int_pair_t pair = {index1, index2};
		    marks2d->append (pair);
		  }
		break;
	      case VT_ULLONG:
		if (nmlist->get_type () == MET_SRCDIS
		    && data_items->get_callsite_mark ()->get (hi->obj))
		  {
		    if (hi->value[index2].ull > maximum_inc[index2].ull)
		      {
			int_pair_t pair = {index1, index2};
			marks2d_inc->append (pair);
		      }
		    break;
		  }
		if (hi->value[index2].ull > maximum[index2].ull)
		  {
		    int_pair_t pair = {index1, index2};
		    marks2d->append (pair);
		  }
		break;
	      case VT_SHORT:
	      case VT_FLOAT:
	      case VT_HRTIME:
	      case VT_LABEL:
	      case VT_ADDRESS:
	      case VT_OFFSET:
		break;
	      }
	  }
	}
    }

  // free memory used by Computing & Printing metrics
  delete[] maximum;
  delete[] maximum_inc;
  delete[] empty;
  maximum = NULL;
  maximum_inc = NULL;
  empty = NULL;
  dbev->warning_msg = anno_str ();
  return data_items;
}

Vector<uint64_t> *
Module::getAddrs (Function *func)
{
  uint64_t start_address = func->img_offset;
  uint64_t end_address = start_address + func->size;
  int64_t inst_size = 0;

  // initialize "disasm" if necessary
  if (!openDisPC ())
    return NULL;

  Vector<uint64_t> *addrs = new Vector<uint64_t>;
  for (uint64_t inst_address = start_address; inst_address < end_address;)
    {
      char *s = disasm->get_disasm (inst_address, end_address, start_address,
				    func->img_offset, inst_size);
      free (s);
      addrs->append (inst_address - start_address);
      inst_address += inst_size;
      if (inst_size == 0)
	break;
    }
  return addrs;
}

void
Module::init_line ()
{
  // initialize the compiler commentary data
  cindex = 0;
  if (comComs != NULL && comComs->size () > 0)
    cline = comComs->fetch (cindex)->line;
  else
    cline = -1;

  sindex = 0;
  if (src_items && src_items->size () > 0)
    sline = ((DbeLine*) src_items->fetch (0)->obj)->lineno;
  else
    sline = -1;

  dindex = 0;
  mindex = 0;
  mline = -1;
  if (dis_items && dis_items->size () > 0)
    {
      daddr = (DbeInstr*) dis_items->fetch (0)->obj;

      // After sorting all HistItems with PCLineFlag appear
      // at the end of the list. Find the first one.
      for (mindex = dis_items->size () - 1; mindex >= 0; mindex--)
	{
	  Hist_data::HistItem *item = dis_items->fetch (mindex);
	  if (!(((DbeInstr*) item->obj)->flags & PCLineFlag))
	    break;
	  mline = (unsigned) (((DbeInstr*) item->obj)->addr);
	}
      mindex++;
    }
  else
    daddr = NULL;
}

void
Module::set_src_data (Function *func, int vis_bits, int cmpline_visible,
		      int funcline_visible)
{
  Function *curr_func = NULL;

  // start at the top of the file, and loop over all lines in the file (source context)
  for (curline = 1; curline <= srcContext->getLineCount (); curline++)
    {
      // Before writing the line, see if there's compiler commentary to insert
      if (cline == curline)
	set_ComCom (vis_bits);

      // Find out if we need to print zero metrics with the line
      DbeLine *dbeline = srcContext->find_dbeline (NULL, curline);
      Anno_Types type = AT_SRC_ONLY;
      if (dbeline->dbeline_func_next)
	{
	  if (func)
	    for (DbeLine *dl = dbeline->dbeline_func_next; dl; dl = dl->dbeline_func_next)
	      {
		if (dl->func == func)
		  {
		    type = AT_SRC;
		    break;
		  }
	      }
	  else
	    type = AT_SRC;
	}

      if (funcline_visible)
	{ // show red lines
	  // is there a function index line to insert?
	  Function *func_next = NULL;
	  for (DbeLine *dl = dbeline; dl; dl = dl->dbeline_func_next)
	    {
	      Function *f = dl->func;
	      if (f && f->line_first == curline
		  && f->getDefSrc () == srcContext)
		{
		  if (lang_code == Sp_lang_java
		      && (f->flags & FUNC_FLAG_DYNAMIC))
		    continue;
		  if (cur_dbev && cur_dbev->get_path_tree ()->get_func_nodeidx (f))
		    {
		      func_next = f;
		      break;
		    }
		  else if (func_next == NULL)
		    func_next = f;
		}
	    }
	  if (func_next && curr_func != func_next)
	    {
	      curr_func = func_next;
	      char *func_name = curr_func->get_name ();
	      if (is_fortran () && streq (func_name, NTXT ("MAIN_")))
		func_name = curr_func->get_match_name ();
	      Hist_data::HistItem *item =
		      src_items->new_hist_item (curr_func, AT_FUNC, empty);
	      item->value[name_idx].l = dbe_sprintf (GTXT ("<Function: %s>"),
						     func_name);
	      data_items->append_hist_item (item);
	    }
	} // end of red line
      set_src (type, dbeline); // add the source line
    } //  end of loop over source lines

  // See if compiler flags are set; if so, append them
  if (cmpline_visible && comp_flags)
    {
      Hist_data::HistItem *item = src_items->new_hist_item (NULL, AT_EMPTY,
							    empty);
      item->value[name_idx].l = xstrdup (NTXT (""));
      data_items->append_hist_item (item);
      item = src_items->new_hist_item (NULL, AT_COM, empty);
      item->value[name_idx].l = dbe_sprintf (GTXT ("Compile flags: %s"),
					     comp_flags);
      data_items->append_hist_item (item);
    }
}

void
Module::set_dis_data (Function *func, int vis_bits, int cmpline_visible,
		      int src_visible, bool hex_vis, bool func_scope,
		      int funcline_visible)
{
  bool nextFile = false;

  // initialize the source output, if any
  curline = (srcContext->getLineCount () > 0) ? 1 : -1;
  if (func)
    nextFile = srcContext != func->getDefSrc ();
  curr_inc = srcContext;

  bool src_code = (src_visible & SRC_CODE);
  Anno_Types src_type = (src_visible & SRC_METRIC) ? AT_SRC : AT_SRC_ONLY;

  char *img_fname = func ? func->img_fname : NULL;

  // Build a new Function list
  Vector<Function*> *FuncLst = new Vector<Function*>;
  if (func_scope)
    {
      if (func)
	FuncLst->append (func);
    }
  else
    {
      for (int i = 0, sz = functions ? functions->size () : 0; i < sz; i++)
	{
	  Function *fitem = functions->fetch (i);
	  if (fitem != fitem->cardinal ())
	    continue;
	  if (img_fname == NULL)
	    img_fname = fitem->img_fname;
	  if (fitem->img_fname == NULL || strcmp (fitem->img_fname, img_fname))
	    continue;
	  FuncLst->append (fitem);
	}
    }
  if (FuncLst->size () == 0)
    { // no function is good
      delete FuncLst;
      return;
    }
  cmpSrcContext = srcContext;
  FuncLst->sort (func_cmp);

  disasm->set_hex_visible (hex_vis);
  for (int index = 0, sz = FuncLst->size (); index < sz; index++)
    {
      Function *fitem = FuncLst->fetch (index);
      uint64_t start_address, end_address;
      int64_t inst_size;
      if (fitem->getDefSrc () != srcContext && curline > 0)
	{
	  // now flush the left source line, if available
	  for (; curline <= srcContext->getLineCount (); curline++)
	    {
	      // see if there's a compiler comment line to dump
	      if (cline == curline)
		set_ComCom (vis_bits);
	      if (src_code)
		set_src (src_type, srcContext->find_dbeline (curline));
	    }
	  curline = -1;
	}

      curr_inc = NULL;
      // disassemble one function
      start_address = objStabs ?
	      objStabs->mapOffsetToAddress (fitem->img_offset) : 0;
      end_address = start_address + fitem->size;
      inst_size = 0;

      disasm->set_addr_end (end_address);
      if ((loadobject->flags & SEG_FLAG_DYNAMIC)
	   && loadobject->platform != Java)
	disasm->set_img_name (img_fname);

      for (uint64_t inst_address = start_address; inst_address < end_address;)
	{
	  uint64_t address = inst_address - start_address;
	  DbeInstr *instr = fitem->find_dbeinstr (0, address);
	  DbeLine *dbeline = (DbeLine *) (instr->convertto (Histable::LINE));
	  if (instr->lineno == -1 && dbeline && dbeline->lineno > 0)
	    instr->lineno = dbeline->lineno;

	  // now write the unannotated source line, if available
	  if (curline > 0)
	    { // source is present
	      int lineno = curline - 1;
	      if (instr->lineno != -1)
		{
		  if (dbeline && streq (dbeline->sourceFile->get_name (),
					srcContext->get_name ()))
		    lineno = instr->lineno;
		}
	      else if (curr_inc == NULL && srcContext == fitem->def_source
		       && fitem->line_first > 0)
		lineno = fitem->line_first;

	      for (; curline <= lineno; curline++)
		{
		  // see if there's a compiler comment line to dump
		  if (cline == curline)
		    set_ComCom (vis_bits);
		  if (mline == curline)
		    set_MPSlave ();
		  if (src_code)
		    set_src (src_type, srcContext->find_dbeline (curline));
		  if (curline >= srcContext->getLineCount ())
		    {
		      curline = -1;
		      break;
		    }
		}
	    }

	  if (funcline_visible)
	    { // show red lines
	      if (!curr_inc || (dbeline && curr_inc != dbeline->sourceFile))
		{
		  Hist_data::HistItem *item = dis_items->new_hist_item (dbeline, AT_FUNC, empty);
		  curr_inc = dbeline ? dbeline->sourceFile : srcContext;
		  char *str;
		  if (curr_inc != srcContext)
		    {
		      char *fileName = curr_inc->dbeFile->getResolvedPath ();
		      str = dbe_sprintf (GTXT ("<Function: %s, instructions from source file %s>"),
					 fitem->get_name (), fileName);
		    }
		  else
		    str = dbe_sprintf (GTXT ("<Function: %s>"),
				       fitem->get_name ());
		  item->value[name_idx].l = str;
		  data_items->append_hist_item (item);
		}
	    }

	  char *dis_str = get_disasm (inst_address, end_address, start_address,
				      fitem->img_offset, inst_size);
	  if (inst_size == 0)
	    break;
	  else if (instr->size == 0)
	    instr->size = (unsigned int) inst_size;
	  inst_address += inst_size;

	  // stomp out control characters
	  for (size_t i = 0, len = strlen (dis_str); i < len; i++)
	    {
	      if (dis_str[i] == '\t')
		dis_str[i] = ' ';
	    }

	  for (int i = 0; i < bTargets.size (); i++)
	    {
	      target_info_t *bTarget = bTargets.fetch (i);
	      if (bTarget->offset == fitem->img_offset + address)
		{
		  // insert a new line for the bTarget
		  size_t colon = strcspn (dis_str, NTXT (":"));
		  char *msg = GTXT ("*  <branch target>");
		  size_t len = colon + strlen (msg);
		  len = (len < 50) ? (50 - len) : 1;
		  char *new_dis_str = dbe_sprintf ("%.*s%s%*c  <===----<<<",
						   (int) colon, dis_str, msg,
						   (int) len, ' ');
		  DbeInstr *bt = fitem->find_dbeinstr (PCTrgtFlag, address);
		  bt->lineno = instr->lineno;
		  bt->size = 0;
		  set_dis (bt, AT_DIS, nextFile, new_dis_str);
		  break;
		}
	    }

	  // AnalyzerInfo/Datatype annotations
	  if (infoList != NULL)
	    {
	      inst_info_t *info = NULL;
	      int pinfo;
	      Vec_loop (inst_info_t*, infoList, pinfo, info)
	      {
		if (info->offset == fitem->img_offset + address) break;
	      }
	      if (info != NULL)
		{ // got a matching memop
		  char typetag[400];
		  typetag[0] = '\0';
		  long t;
		  datatype_t *dtype = NULL;
		  Vec_loop (datatype_t*, datatypes, t, dtype)
		  {
		    if (dtype->datatype_id == info->memop->datatype_id)
		      break;
		  }
		  if (datatypes != NULL)
		    {
		      size_t len = strlen (typetag);
		      if (dtype == NULL || t == datatypes->size ())
			snprintf (typetag + len, sizeof (typetag) - len, "%s",
				  PTXT (DOBJ_UNSPECIFIED));
		      else if (dtype->dobj == NULL)
			snprintf (typetag + len, sizeof (typetag) - len, "%s",
				  PTXT (DOBJ_UNDETERMINED));
		      else
			snprintf (typetag + len, sizeof (typetag) - len, "%s",
				  dtype->dobj->get_name ());
		    }
		  if (strlen (typetag) > 1)
		    {
		      char *new_dis_str;
		      new_dis_str = dbe_sprintf ("%-50s  %s", dis_str, typetag);
		      free (dis_str);
		      dis_str = new_dis_str;
		    }
		}
	    }
	  set_dis (instr, AT_DIS, nextFile, dis_str);
	}
    }

  // now flush the left source line, if available
  if (curline > 0)
    { // source is present
      for (; curline <= srcContext->getLineCount (); curline++)
	{
	  // see if there's a compiler comment line to dump
	  if (cline == curline)
	    set_ComCom (vis_bits);

	  if (src_code)
	    set_src (src_type, srcContext->find_dbeline (curline));
	}
    }

  // See if compiler flags are set; if so, append them
  if (cmpline_visible && comp_flags)
    {
      Hist_data::HistItem *item = dis_items->new_hist_item (NULL, AT_EMPTY,
							    empty);
      item->value[name_idx].l = dbe_strdup (NTXT (""));
      data_items->append_hist_item (item);
      item = dis_items->new_hist_item (NULL, AT_COM, empty);
      item->value[name_idx].l = dbe_sprintf (GTXT ("Compile flags: %s"),
					     comp_flags);
      data_items->append_hist_item (item);
    }
  delete FuncLst;
}

// set_src -- inserts one or more lines into the growing data list
void
Module::set_src (Anno_Types type, DbeLine *dbeline)
{
  Hist_data::HistItem *item;

  // Flush items that are not represented in source
  while (sline >= 0 && sline < curline)
    {
      item = src_items->fetch (sindex);
      if (((DbeLine*) item->obj)->lineno > 0)
	set_one (item, AT_QUOTE, item->obj->get_name ());

      if (++sindex < src_items->size ()) // get next line with metrics
	sline = ((DbeLine*) src_items->fetch (sindex)->obj)->lineno;
      else
	sline = -1;
    }

  //  write values in the metric fields for the given source line
  if (curline == sline)
    { // got metrics for this line
      item = src_items->fetch (sindex);
      if (((DbeLine*) item->obj)->lineno > 0)
	set_one (item, AT_SRC, srcContext->getLine (curline));

      if (++sindex < src_items->size ()) // get next line metric index
	sline = ((DbeLine*) src_items->fetch (sindex)->obj)->lineno;
      else
	sline = -1;
    }
  else
    {
      item = data_items->new_hist_item (dbeline, type, empty);
      if (size_index != -1)
	item->value[size_index].ll = dbeline->get_size ();
      if (addr_index != -1)
	item->value[addr_index].ll = dbeline->get_addr ();
      item->value[name_idx].l = dbe_strdup (srcContext->getLine (curline));
      data_items->append_hist_item (item);
    }
}

void
Module::set_dis (DbeInstr *instr, Anno_Types type, bool nextFile, char *dis_str)
{
  // Flush items that are not represented in disassembly
  while (daddr && daddr->pc_cmp (instr) < 0)
    {
      if (!nextFile)
	set_one (dis_items->fetch (dindex), AT_QUOTE, daddr->get_name ());
      if (++dindex < dis_items->size ()) // get next line metric index
	daddr = (DbeInstr*) dis_items->fetch (dindex)->obj;
      else
	daddr = NULL;
    }

  // Write values in the metric fields for the given pc index value
  if (instr->inlinedInd >= 0)
    {
      StringBuilder sb;
      sb.append (dis_str);
      instr->add_inlined_info (&sb);
      free (dis_str);
      dis_str = sb.toString ();
    }
  if (daddr && daddr->pc_cmp (instr) == 0)
    {
      Hist_data::HistItem *item = data_items->new_hist_item (instr, type,
					      dis_items->fetch (dindex)->value);
      item->value[name_idx].tag = VT_LABEL;
      item->value[name_idx].l = dis_str;
      data_items->append_hist_item (item);
      if (dis_items->get_callsite_mark ()->get (dis_items->fetch (dindex)->obj))
	data_items->get_callsite_mark ()->put (item->obj, 1);

      if (++dindex < dis_items->size ()) // get next line metric index
	daddr = (DbeInstr*) dis_items->fetch (dindex)->obj;
      else
	daddr = NULL;
    }
  else
    {
      // create a new item for this PC
      Hist_data::HistItem *item = dis_items->new_hist_item (instr, type, empty);
      if (size_index != -1)
	item->value[size_index].ll = instr->size;
      if (addr_index != -1)
	item->value[addr_index].ll = instr->get_addr ();
      item->value[name_idx].tag = VT_LABEL;
      item->value[name_idx].l = dis_str;
      data_items->append_hist_item (item);
    }
}

void
Module::set_MPSlave ()
{
  Hist_data::HistItem *item;
  Function *fp;
  int index;

  // write the inclusive metrics for slave threads
  while (mline == curline)
    {
      item = dis_items->fetch (mindex);
      DbeInstr *instr = (DbeInstr *) item->obj;
      Vec_loop (Function*, functions, index, fp)
      {
	if (fp->derivedNode == instr)
	  {
	    set_one (item, AT_QUOTE, (fp->isOutlineFunction) ?
		     GTXT ("<inclusive metrics for outlined functions>") :
		     GTXT ("<inclusive metrics for slave threads>"));
	    break;
	  }
      }

      mindex++;
      if (mindex < dis_items->size ())
	mline = (unsigned) ((DbeInstr*) (dis_items->fetch (mindex)->obj))->addr;
      else
	mline = -1;
    }
}//set_MPSlave

void
Module::set_one (Hist_data::HistItem *org_item, Anno_Types type,
		 const char *text)
{
  if (org_item == NULL)
    return;
  Hist_data::HistItem *item = data_items->new_hist_item (org_item->obj, type,
							 org_item->value);
  item->value[name_idx].tag = VT_LABEL;
  item->value[name_idx].l = dbe_strdup (text);
  data_items->append_hist_item (item);
  if (org_item != NULL && src_items != NULL
      && src_items->get_callsite_mark ()->get (org_item->obj))
    data_items->get_callsite_mark ()->put (item->obj, 1);
}//set_one

void
Module::set_ComCom (int vis_bits)
{
  Hist_data::HistItem *item;
  Function *func = dbeSession->get_Unknown_Function ();

  if (vis_bits)
    {
      // precede the compiler commentary with a blank line
      item = data_items->new_hist_item (func, AT_EMPTY, empty);
      item->value[name_idx].l = dbe_strdup (NTXT (""));
      data_items->append_hist_item (item);
    }
  while (cline == curline)
    {
      ComC *comm = comComs->fetch (cindex);
      if (comm->visible & vis_bits)
	{
	  // write the compiler commentary
	  item = data_items->new_hist_item (func, AT_COM, empty);
	  item->value[name_idx].l = dbe_strdup (comm->com_str);
	  data_items->append_hist_item (item);
	}
      if (++cindex < comComs->size ())
	cline = comComs->fetch (cindex)->line;
      else
	cline = -1;
    }
}

void
Module::dump_dataobjects (FILE *out)
{
  int index;
  datatype_t *dtype;
  Vec_loop (datatype_t*, datatypes, index, dtype)
  {
    fprintf (out, NTXT ("[0x%08X,%6lld] %4d %6d %s "), dtype->datatype_id,
	     dtype->dobj ? dtype->dobj->id : 0LL,
	     dtype->memop_refs, dtype->event_data,
	     (dtype->dobj != NULL ? (dtype->dobj->get_name () ?
		 dtype->dobj->get_name () : "<NULL>") : "<no object>"));
#if DEBUG
    Histable* scope = dtype->dobj ? dtype->dobj->get_scope () : NULL;
    if (scope != NULL)
      {
	switch (scope->get_type ())
	  {
	  case Histable::LOADOBJECT:
	  case Histable::FUNCTION:
	    fprintf (out, NTXT ("%s"), scope->get_name ());
	    break;
	  case Histable::MODULE:
	    {
	      char *filename = get_basename (scope->get_name ());
	      fprintf (out, NTXT ("%s"), filename);
	      break;
	    }
	  default:
	    fprintf (out, NTXT ("\tUnexpected scope %d:%s"),
		     scope->get_type (), scope->get_name ());
	  }
      }
#endif
    fprintf (out, NTXT ("\n"));
  }
}

void
Module::set_name (char *str)
{
  free (name);
  name = str;
}

void
Module::read_hwcprof_info ()
{
  if (hwcprof == 0)
    {
      hwcprof = 1;
      Stabs *stabs = openDebugInfo ();
      if (stabs)
	stabs->read_hwcprof_info (this);
    }
}

void
Module::reset_datatypes ()
{
  for (int i = 0, sz = datatypes ? datatypes->size () : -1; i < sz; i++)
    {
      datatype_t *t = datatypes->fetch (i);
      t->event_data = 0;
    }
}

DataObject *
Module::get_dobj (uint32_t dtype_id)
{
  read_hwcprof_info ();
  for (int i = 0, sz = datatypes ? datatypes->size () : -1; i < sz; i++)
    {
      datatype_t *t = datatypes->fetch (i);
      if (t->datatype_id == dtype_id)
	{
	  t->event_data++;
	  return t->dobj;
	}
    }
  return NULL;
}

int
Module::readFile ()
{
  return AE_OK;
}

Vector<Histable*> *
Module::get_comparable_objs ()
{
  update_comparable_objs ();
  if (comparable_objs || dbeSession->expGroups->size () <= 1 || loadobject == NULL)
    return comparable_objs;
  Vector<Histable*> *comparableLoadObjs = loadobject->get_comparable_objs ();
  if (comparableLoadObjs == NULL)
    return NULL;
  comparable_objs = new Vector<Histable*>(comparableLoadObjs->size ());
  for (int i = 0, sz = comparableLoadObjs->size (); i < sz; i++)
    {
      Module *mod = NULL;
      LoadObject *lo = (LoadObject*) comparableLoadObjs->fetch (i);
      if (lo)
	{
	  mod = lo->get_comparable_Module (this);
	  if (mod)
	    mod->comparable_objs = comparable_objs;
	}
      comparable_objs->store (i, mod);
    }
  dump_comparable_objs ();
  return comparable_objs;
}

JMethod *
Module::find_jmethod (const char *nm, const char *sig)
{
  // Vladimir: Probably we should not use linear search
  for (long i = 0, sz = VecSize (functions); i < sz; i++)
    {
      JMethod *jmthd = (JMethod*) functions->get (i);
      char *jmt_name = jmthd->get_name (Histable::SHORT);
      if (strcmp (jmt_name, nm) == 0
	  && strcmp (jmthd->get_signature (), sig) == 0)
	return jmthd;
    }
  return NULL;
}
