/* Copyright (C) 2021-2023 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 <errno.h>

#include "util.h"
#include "StringBuilder.h"
#include "Application.h"
#include "DbeSession.h"
#include "Experiment.h"
#include "Exp_Layout.h"
#include "DataObject.h"
#include "Elf.h"
#include "Function.h"
#include "Module.h"
#include "ClassFile.h"
#include "Stabs.h"
#include "LoadObject.h"
#include "dbe_types.h"
#include "DbeFile.h"
#include "ExpGroup.h"

enum
{
  LO_InstHTableSize     = 4096,
  HTableSize            = 1024
};

LoadObject *
LoadObject::create_item (const char *nm, int64_t chksum)
{
  LoadObject *lo = new LoadObject (nm);
  lo->checksum = chksum;
  dbeSession->append (lo);
  return lo;
}

LoadObject *
LoadObject::create_item (const char *nm, const char *_runTimePath, DbeFile *df)
{
  LoadObject *lo = new LoadObject (nm);
  lo->runTimePath = dbe_strdup (_runTimePath);
  lo->dbeFile->orig_location = dbe_strdup (_runTimePath);
  if (df)
    {
      if ((df->filetype & DbeFile::F_JAR_FILE) != 0)
	{
	  if (lo->dbeFile->find_in_jar_file (nm, df->get_jar_file ()))
	    {
	      lo->dbeFile->inArchive = df->inArchive;
	      lo->dbeFile->container = df;
	    }
	}
      else
	{
	  lo->dbeFile->set_location (df->get_location ());
	  lo->dbeFile->sbuf = df->sbuf;
	  lo->dbeFile->inArchive = df->inArchive;
	}
    }
  dbeSession->append (lo);
  return lo;
}

LoadObject::LoadObject (const char *loname)
{
  flags = 0;
  size = 0;
  type = SEG_UNKNOWN;
  isReadStabs = false;
  need_swap_endian = false;
  instHTable = new DbeInstr*[LO_InstHTableSize];
  for (int i = 0; i < LO_InstHTableSize; i++)
    instHTable[i] = NULL;

  functions = new Vector<Function*>;
  funcHTable = new Function*[HTableSize];
  for (int i = 0; i < HTableSize; i++)
    funcHTable[i] = NULL;

  seg_modules = new Vector<Module*>;
  modules = new HashMap<char*, Module*>;
  platform = Unknown;
  noname = dbeSession->createUnknownModule (this);
  modules->put (noname->get_name (), noname);
  pathname = NULL;
  arch_name = NULL;
  runTimePath = NULL;
  objStabs = NULL;
  firstExp = NULL;
  seg_modules_map = NULL;
  comp_funcs = NULL;
  warnq = new Emsgqueue (NTXT ("lo_warnq"));
  commentq = new Emsgqueue (NTXT ("lo_commentq"));
  elf_lo = NULL;
  elf_inited = false;
  checksum = 0;
  isUsed = false;
  h_function = NULL;
  h_instr = NULL;

  char *nm = (char *) loname;
  if (strncmp (nm, NTXT ("./"), 2) == 0)
    nm += 2;
  set_name (nm);
  dbeFile = new DbeFile (nm);
  dbeFile->filetype |= DbeFile::F_LOADOBJ | DbeFile::F_FILE;
}

LoadObject::~LoadObject ()
{
  delete seg_modules_map;
  delete functions;
  delete[] instHTable;
  delete[] funcHTable;
  delete seg_modules;
  delete modules;
  delete elf_lo;
  free (pathname);
  free (arch_name);
  free (runTimePath);
  delete objStabs;
  delete warnq;
  delete commentq;
  delete h_instr;
}

Elf *
LoadObject::get_elf ()
{
  if (elf_lo == NULL)
    {
      if (dbeFile->get_need_refind ())
	elf_inited = false;
      if (elf_inited)
	return NULL;
      elf_inited = true;
      char *fnm = dbeFile->get_location ();
      if (fnm == NULL)
	{
	  append_msg (CMSG_ERROR, GTXT ("Cannot find file: `%s'"),
		      dbeFile->get_name ());
	  return NULL;
	}
      Elf::Elf_status st = Elf::ELF_ERR_CANT_OPEN_FILE;
      elf_lo = Elf::elf_begin (fnm, &st);
      if (elf_lo == NULL)
	switch (st)
	  {
	  case Elf::ELF_ERR_CANT_OPEN_FILE:
	    append_msg (CMSG_ERROR, GTXT ("Cannot open ELF file `%s'"), fnm);
	    break;
	  case Elf::ELF_ERR_BAD_ELF_FORMAT:
	  default:
	    append_msg (CMSG_ERROR, GTXT ("Cannot read ELF header of `%s'"),
			fnm);
	    break;
	  }
    }
  return elf_lo;
}

Stabs *
LoadObject::openDebugInfo (char *fname, Stabs::Stab_status *stp)
{
  if (objStabs == NULL)
    {
      if (fname == NULL)
	return NULL;
      objStabs = new Stabs (fname, get_pathname ());
      Stabs::Stab_status st = objStabs->get_status ();
      if ((st == Stabs::DBGD_ERR_NONE) && (checksum != 0))
	{
	  Elf *elf = get_elf ();
	  if (elf && (checksum != elf->elf_checksum ()))
	    {
	      char *buf = dbe_sprintf (GTXT ("*** Note: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored"),
				       fname);
	      commentq->append (new Emsg (CMSG_ERROR, buf));
	      delete buf;
	      st = Stabs::DBGD_ERR_CHK_SUM;
	    }
	}
      if (stp)
	*stp = st;
      if (st != Stabs::DBGD_ERR_NONE)
	{
	  delete objStabs;
	  objStabs = NULL;
	}
    }
  return objStabs;
}

uint64_t
LoadObject::get_addr ()
{
  return MAKE_ADDRESS (seg_idx, 0);
}

bool
LoadObject::compare (const char *_path, int64_t _checksum)
{
  return _checksum == checksum && dbe_strcmp (_path, get_pathname ()) == 0;
}

int
LoadObject::compare (const char *_path, const char *_runTimePath, DbeFile *df)
{
  int ret = 0;
  if (dbe_strcmp (_path, get_pathname ()) != 0)
    return ret;
  ret |= CMP_PATH;
  if (_runTimePath)
    {
      if (dbe_strcmp (_runTimePath, runTimePath) != 0)
	return ret;
      ret |= CMP_RUNTIMEPATH;
    }
  if (df && dbeFile->compare (df))
    ret |= CMP_CHKSUM;
  return ret;
}

void
LoadObject::set_platform (Platform_t pltf, int wsz)
{
  switch (pltf)
    {
    case Sparc:
    case Sparcv9:
    case Sparcv8plus:
      platform = (wsz == W64) ? Sparcv9 : Sparc;
      break;
    case Intel:
    case Amd64:
      platform = (wsz == W64) ? Amd64 : Intel;
      break;
    default:
      platform = pltf;
      break;
    }
};

void
LoadObject::set_name (char *string)
{
  char *p;
  pathname = dbe_strdup (string);

  p = get_basename (pathname);
  if (p[0] == '<')
    name = dbe_strdup (p);
  else    // set a short name  to "<basename>"
    name = dbe_sprintf (NTXT ("<%s>"), p);
}

void
LoadObject::dump_functions (FILE *out)
{
  int index;
  Function *fitem;
  char *sname, *mname;
  if (platform == Java)
    {
      JMethod *jmthd;
      Vector<JMethod*> *jmethods = (Vector<JMethod*>*)functions;
      Vec_loop (JMethod*, jmethods, index, jmthd)
      {
	fprintf (out, "id %6llu, @0x%llx sz-%lld %s (module = %s)\n",
		 (unsigned long long) jmthd->id, (long long) jmthd->get_mid (),
		 (long long) jmthd->size, jmthd->get_name (),
		 jmthd->module ? jmthd->module->file_name : noname->file_name);
      }
    }
  else
    {
      Vec_loop (Function*, functions, index, fitem)
      {
	if (fitem->alias && fitem->alias != fitem)
	  fprintf (out, "id %6llu, @0x%llx -        %s == alias of '%s'\n",
		   (ull_t) fitem->id, (ull_t) fitem->img_offset,
		   fitem->get_name (), fitem->alias->get_name ());
	else
	  {
	    mname = fitem->module ? fitem->module->file_name : noname->file_name;
	    sname = fitem->getDefSrcName ();
	    fprintf (out,
		     "id %6llu, @0x%llx - 0x%llx [save 0x%llx] o-%lld sz-%lld %s (module = %s)",
		     (ull_t) fitem->id, (ull_t) fitem->img_offset,
		     (ull_t) (fitem->img_offset + fitem->size),
		     (ull_t) fitem->save_addr, (ull_t) fitem->img_offset,
		     (ll_t) fitem->size, fitem->get_name (), mname);
	    if (sname && !streq (sname, mname))
	      fprintf (out, " (Source = %s)", sname);
	    fprintf (out, "\n");
	  }
      }
    }
}

int
LoadObject::get_index (Function *func)
{
  Function *fp;
  uint64_t offset;
  int x;
  int left = 0;
  int right = functions->size () - 1;
  offset = func->img_offset;
  while (left <= right)
    {
      x = (left + right) / 2;
      fp = functions->fetch (x);

      if (left == right)
	{
	  if (offset >= fp->img_offset + fp->size)
	    return -1;
	  if (offset >= fp->img_offset)
	    return x;
	  return -1;
	}
      if (offset < fp->img_offset)
	right = x - 1;
      else if (offset >= fp->img_offset + fp->size)
	left = x + 1;
      else
	return x;
    }
  return -1;
}

char *
LoadObject::get_alias (Function *func)
{
  Function *fp, *alias;
  int index, nsize;
  static char buf[1024];
  if (func->img_offset == 0 || func->alias == NULL)
    return NULL;
  int fid = get_index (func);
  if (fid == -1)
    return NULL;

  nsize = functions->size ();
  alias = func->alias;
  for (index = fid; index < nsize; index++)
    {
      fp = functions->fetch (index);
      if (fp->alias != alias)
	{
	  fid = index;
	  break;
	}
    }

  *buf = '\0';
  for (index--; index >= 0; index--)
    {
      fp = functions->fetch (index);
      if (fp->alias != alias)
	break;
      if (fp != alias)
	{
	  size_t len = strlen (buf);
	  if (*buf != '\0')
	    {
	      snprintf (buf + len, sizeof (buf) - len, NTXT (", "));
	      len = strlen (buf);
	    }
	  snprintf (buf + len, sizeof (buf) - len, "%s", fp->get_name ());
	}
    }
  return buf;
}

DbeInstr*
LoadObject::find_dbeinstr (uint64_t file_off)
{
  int hash = (((int) file_off) >> 2) & (LO_InstHTableSize - 1);
  DbeInstr *instr = instHTable[hash];
  if (instr && instr->img_offset == file_off)
    return instr;
  Function *fp = find_function (file_off);
  if (fp == NULL)
    fp = dbeSession->get_Unknown_Function ();
  uint64_t func_off = file_off - fp->img_offset;
  instr = fp->find_dbeinstr (0, func_off);
  instHTable[hash] = instr;
  return instr;
}

Function *
LoadObject::find_function (uint64_t foff)
{
  // Look up in the hash table
  int hash = (((int) foff) >> 6) & (HTableSize - 1);
  Function *func = funcHTable[hash];
  if (func && foff >= func->img_offset && foff < func->img_offset + func->size)
    return func->alias ? func->alias : func;

  // Use binary search
  func = NULL;
  int left = 0;
  int right = functions->size () - 1;
  while (left <= right)
    {
      int x = (left + right) / 2;
      Function *fp = functions->fetch (x);
      assert (fp != NULL);

      if (foff < fp->img_offset)
	right = x - 1;
      else if (foff >= fp->img_offset + fp->size)
	left = x + 1;
      else
	{
	  func = fp;
	  break;
	}
    }

  // Plug the hole with a static function
  char *func_name = NULL;
  Size low_bound = 0, high_bound = 0;
  if (func == NULL)
    {
      int last = functions->size () - 1;
      uint64_t usize = (uint64_t) size;
      if (foff >= usize)
	{
	  // Cannot map to this LoadObject. Probably LoadObject was changed.
	  if (last >= 0 && functions->fetch (last)->img_offset == usize)
	    {
	      // Function is already created
	      func = functions->fetch (last);
	      if (func->size < 0 || (uint64_t) func->size < foff - usize)
		func->size = foff - usize;
	    }
	  else
	    {
	      low_bound = size;
	      high_bound = foff;
	      func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s) --  no functions found"),
				       low_bound, name);
	    }
	}
      else if (last < 0)
	{
	  low_bound = 0;
	  high_bound = size;
	  func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s) --  no functions found"),
				   low_bound, name);
	}
      else if (foff < functions->fetch (0)->img_offset)
	{
	  low_bound = 0;
	  high_bound = functions->fetch (0)->img_offset;
	}
      else
	{
	  Function *fp = functions->fetch (last);
	  if (foff >= fp->img_offset + fp->size)
	    {
	      low_bound = fp->img_offset + fp->size;
	      high_bound = size;
	    }
	  else
	    {
	      fp = functions->fetch (left);
	      if (foff >= fp->img_offset + fp->size)
		{
		  low_bound = fp->img_offset + fp->size;
		  high_bound = functions->fetch (left + 1)->img_offset;
		}
	      else
		{
		  Function *fp1 = functions->fetch (left - 1);
		  low_bound = fp1->img_offset + fp1->size;
		  high_bound = fp->img_offset;
		}
	    }
	}
    }

  if (func == NULL)
    {
      func = dbeSession->createFunction ();
      func->size = (unsigned) (high_bound - low_bound);
      func->module = noname;
      func->img_fname = get_pathname ();
      func->img_offset = (off_t) low_bound;
      noname->functions->append (func); // unordered
      if (func_name == NULL)
	func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s)"), low_bound,
				 name);
      func->set_name (func_name);
      free (func_name);

      // now insert the function
      functions->insert (left, func);
    }

  // Update the hash table
  funcHTable[hash] = func;
  return func->alias ? func->alias : func;
}

static void
fixFuncAlias (Vector<Function*> *SymLst)
{
  int ind, i, k;
  int64_t len, bestLen, maxSize;
  Function *sym, *bestAlias;

  // XXXX it is a clone of Stabs::fixSymtabAlias()
  ind = SymLst->size () - 1;
  for (i = 0; i < ind; i++)
    {
      bestAlias = SymLst->fetch (i);
      if (bestAlias->img_offset == 0) // Ignore this bad symbol
	continue;
      sym = SymLst->fetch (i + 1);
      if (bestAlias->img_offset != sym->img_offset)
	{
	  if (bestAlias->size == 0
	      || sym->img_offset < bestAlias->img_offset + bestAlias->size)
	    bestAlias->size = (int) (sym->img_offset - bestAlias->img_offset);
	  continue;
	}

      // Find a "best" alias
      bestLen = strlen (bestAlias->get_name ());
      maxSize = bestAlias->size;
      for (k = i + 1; k <= ind; k++)
	{
	  sym = SymLst->fetch (k);
	  if (bestAlias->img_offset != sym->img_offset)
	    { // no more aliases
	      if ((maxSize == 0) ||
		  (sym->img_offset < bestAlias->img_offset + maxSize))
		maxSize = sym->img_offset - bestAlias->img_offset;
	      break;
	    }
	  if (maxSize < sym->size)
	    maxSize = sym->size;
	  len = strlen (sym->get_name ());
	  if (len < bestLen)
	    {
	      bestAlias = sym;
	      bestLen = len;
	    }
	}
      for (; i < k; i++)
	{
	  sym = SymLst->fetch (i);
	  sym->alias = bestAlias;
	  sym->size = maxSize;
	}
      i--;
    }
}

void
LoadObject::post_process_functions ()
{
  if (flags & SEG_FLAG_DYNAMIC || platform == Java)
    return;

  char *msg = GTXT ("Processing Load Object Data");
  if (dbeSession->is_interactive ())
    theApplication->set_progress (1, msg);

  // First sort the functions
  functions->sort (func_compare);
  fixFuncAlias (functions);

  Module *mitem;
  int index;
  Vec_loop (Module*, seg_modules, index, mitem)
  {
    mitem->functions->sort (func_compare);
  }

  // Find any derived functions, and set their derivedNode
  Function *fitem;
  Vec_loop (Function*, functions, index, fitem)
  {
    if (dbeSession->is_interactive () && index % 5000 == 0)
      {
	int percent = (int) (100.0 * index / functions->size ());
	theApplication->set_progress (percent, (percent != 0) ? NULL : msg);
      }
    fitem->findDerivedFunctions ();
  }

  // 4987698: get the alias name for MAIN_
  fitem = find_function (NTXT ("MAIN_"));
  if (fitem)
    fitem->module->read_stabs ();
  fitem = find_function (NTXT ("@plt"));
  if (fitem)
    fitem->flags |= FUNC_FLAG_PLT;
  if (dbeSession->is_interactive ())
    theApplication->set_progress (0, NTXT (""));
}

int
LoadObject::func_compare (const void *p1, const void *p2)
{
  Function *f1 = *(Function **) p1;
  Function *f2 = *(Function **) p2;
  if (f1->img_offset != f2->img_offset)
    return f1->img_offset > f2->img_offset ? 1 : -1;

  // annotated source not available for weak symbols.
  if ((f1->module->flags & MOD_FLAG_UNKNOWN) != 0)
    {
      if ((f2->module->flags & MOD_FLAG_UNKNOWN) == 0)
	return -1;
    }
  else if ((f2->module->flags & MOD_FLAG_UNKNOWN) != 0)
    return 1;
  return strcoll (f1->get_name (), f2->get_name ());
}

Function *
LoadObject::find_function (char *fname)
{
  Function *fitem;
  int index;
  Vec_loop (Function*, functions, index, fitem)
  {
    if (strcmp (fitem->get_name (), fname) == 0)
      return fitem;
  }
  return (Function *) NULL;
}

Function *
LoadObject::find_function (char *fname, unsigned int chksum)
{
  Function *fitem;
  int index;
  Vec_loop (Function*, functions, index, fitem)
  {
    if (fitem->chksum == chksum && strcmp (fitem->get_name (), fname) == 0)
      return fitem;
  }
  return (Function *) NULL;
}

Module *
LoadObject::find_module (char *mname)
{
  for (int i = 0, sz = seg_modules ? seg_modules->size () : 0; i < sz; i++)
    {
      Module *module = seg_modules->fetch (i);
      if (strcmp (module->get_name (), mname) == 0)
	return module;
    }
  return (Module *) NULL;
}

LoadObject::Arch_status
LoadObject::sync_read_stabs ()
{
  Arch_status st = ARCHIVE_SUCCESS;
  if (!isReadStabs)
    {
      aquireLock ();
      if (!isReadStabs)
	{
	  st = read_stabs ();
	  post_process_functions ();
	  isReadStabs = true;
	}
      releaseLock ();
    }
  return st;
}

LoadObject::Arch_status
LoadObject::read_stabs ()
{
  if ((dbeFile->filetype & DbeFile::F_FICTION) != 0)
    return ARCHIVE_SUCCESS;
  Arch_status stabs_status = ARCHIVE_ERR_OPEN;
  if (platform == Java)
    {
      Module *cf = NULL;
      for (int i = 0, sz = seg_modules ? seg_modules->size () : 0; i < sz; i++)
	{
	  Module *mod = seg_modules->fetch (i);
	  if (mod->dbeFile
	      && (mod->dbeFile->filetype & DbeFile::F_JAVACLASS) != 0)
	    {
	      cf = mod;
	      break;
	    }
	}
      if (cf)
	{
	  int status = cf->readFile ();
	  switch (status)
	    {
	    case Module::AE_OK:
	      stabs_status = ARCHIVE_SUCCESS;
	      break;
	    case Module::AE_NOSTABS:
	      stabs_status = ARCHIVE_NO_STABS;
	      break;
	    case Module::AE_NOTREAD:
	    default:
	      stabs_status = ARCHIVE_ERR_OPEN;
	      break;
	    }
	}
    }
  else if (strchr (pathname, '`'))
    return ARCHIVE_SUCCESS;
  else
    {
      Arch_status st = ARCHIVE_WRONG_ARCH;
      Elf *elf = get_elf ();
      if (elf == NULL)
	{
	  if (read_archive () == 0)
	    st = ARCHIVE_SUCCESS;
	  else
	    {
	      char *msg = dbe_sprintf (GTXT ("*** Warning: Can't open file: %s"),
				       dbeFile->get_name ());
	      warnq->append (new Emsg (CMSG_ERROR, msg));
	      delete msg;
	    }
	}
      else if (checksum != 0 && checksum != elf->elf_checksum ())
	{
	  if (read_archive () == 0)
	    st = ARCHIVE_SUCCESS;
	  else
	    {
	      char *msg = dbe_sprintf (
				       GTXT ("*** Note: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored"),
				       dbeFile->get_location ());
	      commentq->append (new Emsg (CMSG_ERROR, msg));
	      delete msg;
	    }
	}
      if (st == ARCHIVE_SUCCESS)    // An old archive is used
	return st;

      Stabs::Stab_status status = Stabs::DBGD_ERR_CANT_OPEN_FILE;
      char *location = dbeFile->get_location (true);
      if (location == NULL)
	return ARCHIVE_ERR_OPEN;

      if (openDebugInfo (location, &status))
	{
	  status = objStabs->read_archive (this);
	  isRelocatable = objStabs->is_relocatable ();
	  size = objStabs->get_textsz ();
	  platform = objStabs->get_platform ();
	  wsize = objStabs->get_class ();
	}

      switch (status)
	{
	case Stabs::DBGD_ERR_NONE:
	  stabs_status = ARCHIVE_SUCCESS;
	  break;
	case Stabs::DBGD_ERR_CANT_OPEN_FILE:
	  stabs_status = ARCHIVE_ERR_OPEN;
	  break;
	case Stabs::DBGD_ERR_BAD_ELF_LIB:
	case Stabs::DBGD_ERR_BAD_ELF_FORMAT:
	  stabs_status = ARCHIVE_BAD_STABS;
	  break;
	case Stabs::DBGD_ERR_NO_STABS:
	  stabs_status = ARCHIVE_NO_STABS;
	  break;
	case Stabs::DBGD_ERR_NO_DWARF:
	  stabs_status = ARCHIVE_NO_DWARF;
	  break;
	default:
	  stabs_status = ARCHIVE_BAD_STABS;
	  break;
	}
    }
  return stabs_status;
}

#define ARCH_STRLEN(s)      ((strlen(s) + 4) & ~0x3 )

static int
offsetCmp (const void *a, const void *b)
{
  uint32_t o1 = ((inst_info_t *) a)->offset;
  uint32_t o2 = ((inst_info_t *) b)->offset;
  return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1);
}

int
LoadObject::read_archive ()
{
  if (arch_name == NULL)
    return 1;
  Module *mod = NULL;
  Function *func = NULL;
  char *buf;
  Data_window *dwin = new Data_window (arch_name);
  if (dwin->not_opened ())
    {
      delete dwin;
      buf = dbe_sprintf (GTXT ("*** Warning: Error opening file for reading: %s: %s"),
			 arch_name, strerror (errno));
      warnq->append (new Emsg (CMSG_ERROR, buf));
      delete buf;
      return 1;
    }
  dwin->need_swap_endian = need_swap_endian;

  // Prevent reading earlier archive files, which didn't support versioning.
  int64_t offset = 0;
  ARCH_common *cpkt = (ARCH_common*) dwin->bind (offset, sizeof (ARCH_common));
  uint16_t v16;
  if (cpkt)
    {
      v16 = (uint16_t) cpkt->type;
      if (dwin->decode (v16) != ARCH_SEGMENT)
	cpkt = NULL;
    }
  if (cpkt == NULL)
    {
      buf = dbe_sprintf (GTXT ("archive file malformed %s"), arch_name);
      warnq->append (new Emsg (CMSG_WARN, buf));
      delete buf;
      return 1;
    }

  char *msg = NULL;
  unsigned long long pointer_invalid = 0;
  for (int64_t last_offset = -5000;;)
    {
      cpkt = (ARCH_common*) dwin->bind (offset, sizeof (ARCH_common));
      if (cpkt == NULL)
	break;
      v16 = (uint16_t) cpkt->size;
      uint32_t cpktsize = dwin->decode (v16);
      cpkt = (ARCH_common*) dwin->bind (offset, cpktsize);
      if ((cpkt == NULL) || (cpktsize == 0))
	{
	  buf = dbe_sprintf (GTXT ("archive file malformed %s"), arch_name);
	  warnq->append (new Emsg (CMSG_WARN, buf));
	  delete buf;
	  break;
	}

      // Update the progress bar
      if (dbeSession->is_interactive () && ((offset - last_offset) >= 5000))
	{
	  last_offset = offset;
	  int percent = (int) (100.0 * offset / dwin->get_fsize ());
	  if (msg == NULL)
	    msg = dbe_sprintf (GTXT ("Reading Load Object Data: %s"), name);
	  theApplication->set_progress (percent, (percent != 0) ? NULL : msg);
	}
      char *ptr = (char *) cpkt;
      v16 = (uint16_t) cpkt->type;
      switch (dwin->decode (v16))
	{
	case ARCH_SEGMENT:
	  {
	    ARCH_segment *aseg = (ARCH_segment*) cpkt;
	    if (dwin->decode (aseg->version) != ARCH_VERSION)
	      {
		buf = dbe_sprintf (GTXT ("Archive file version mismatch for %s"), arch_name);
		warnq->append (new Emsg (CMSG_ERROR, buf));
		delete buf;
		if (dbeSession->is_interactive ())
		  theApplication->set_progress (0, "");
		return 1;
	      }
	    if (size == 0)
	      size = dwin->decode (aseg->textsz);
	    Platform_t pltf = (Platform_t) dwin->decode (aseg->platform);
	    if (pltf != Unknown)
	      {
		platform = pltf; // override if known
		wsize = (platform == Sparcv9 || platform == Amd64) ? W64 : W32;
	      }
	    break;
	  }
	case ARCH_MSG:
	  {
	    ARCH_message *amsg = (ARCH_message*) cpkt;
	    buf = status_str ((Arch_status) dwin->decode (amsg->errcode));
	    commentq->append (new Emsg (CMSG_ARCHIVE, buf));
	    free (buf);
	    break;
	  }
	case ARCH_INF:
	  {
	    ARCH_info *ainf = (ARCH_info*) cpkt;
	    Emsg *m = new Emsg (CMSG_ARCHIVE, (char*) (ainf + 1));
	    commentq->append (m);
	    break;
	  }
	case ARCH_MODULE:
	  {
	    ARCH_module *amod = (ARCH_module*) cpkt;
	    char *str = ((char*) amod) + sizeof (ARCH_module);
	    if (streq (str, SP_UNKNOWN_NAME) &&
		streq (str + ARCH_STRLEN (str), SP_UNKNOWN_NAME))
	      {
		mod = noname;
		break;
	      }
	    mod = dbeSession->createModule (this, str);
	    mod->lang_code = (Sp_lang_code) dwin->decode (amod->lang_code);
	    mod->fragmented = dwin->decode (amod->fragmented);
	    str += ARCH_STRLEN (str);
	    mod->set_file_name (dbe_strdup (str));
	    modules->put (get_basename (str), mod);
	    break;
	  }
	case ARCH_FUNCTION:
	  {
	    if (mod == NULL)
	      break;
	    ARCH_function *afnc = (ARCH_function*) cpkt;
	    func = dbeSession->createFunction ();
	    func->img_offset = dwin->decode (afnc->offset);
	    func->size = dwin->decode (afnc->size);
	    func->save_addr = dwin->decode (afnc->save_addr)
		    - dwin->decode (afnc->offset);
	    func->module = mod;
	    func->set_name (((char*) afnc) + sizeof (ARCH_function));
	    mod->functions->append (func);
	    functions->append (func);
	    break;
	  }
	case ARCH_LDINSTR:
	  if (mod == NULL)
	    break;
	  Dprintf (DEBUG_LOADOBJ, "LDINSTR list for %s\n", mod->get_name ());
	  if (mod->infoList == NULL)
	    mod->infoList = new Vector<inst_info_t*>;
	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
		  (char*) mp < ptr + cpktsize; mp++)
	    {
	      memop_info_t *memop = new memop_info_t;
	      memop->offset = dwin->decode (mp->offset);
	      memop->id = dwin->decode (mp->id);
	      memop->signature = dwin->decode (mp->signature);
	      memop->datatype_id = dwin->decode (mp->datatype_id);
	      mod->ldMemops.append (memop);

	      inst_info_t *instop = new inst_info_t;
	      instop->type = CPF_INSTR_TYPE_LD;
	      instop->offset = memop->offset;
	      instop->memop = memop;
	      mod->infoList->incorporate (instop, offsetCmp);
	      Dprintf (DEBUG_LOADOBJ,
		       "ld: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
		       memop->offset, memop->id, memop->signature,
		       memop->datatype_id);
	    }
	  Dprintf (DEBUG_LOADOBJ, "LDINSTR list of %lld for %s\n",
		   (long long) mod->ldMemops.size (), mod->get_name ());
	  break;
	case ARCH_STINSTR:
	  if (mod == NULL)
	    break;
	  Dprintf (DEBUG_LOADOBJ, NTXT ("STINSTR list for %s\n"), mod->get_name ());
	  if (mod->infoList == NULL)
	    mod->infoList = new Vector<inst_info_t*>;
	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
		  ((char *) mp) < ptr + cpktsize; mp++)
	    {
	      memop_info_t *memop = new memop_info_t;
	      memop->offset = dwin->decode (mp->offset);
	      memop->id = dwin->decode (mp->id);
	      memop->signature = dwin->decode (mp->signature);
	      memop->datatype_id = dwin->decode (mp->datatype_id);
	      mod->stMemops.append (memop);

	      inst_info_t *instop = new inst_info_t;
	      instop->type = CPF_INSTR_TYPE_ST;
	      instop->offset = memop->offset;
	      instop->memop = memop;
	      mod->infoList->incorporate (instop, offsetCmp);
	      Dprintf (DEBUG_LOADOBJ,
		       "st: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
		       memop->offset, memop->id, memop->signature,
		       memop->datatype_id);
	    }
	  Dprintf (DEBUG_LOADOBJ, "STINSTR list of %lld for %s\n",
		   (long long) mod->stMemops.size (), mod->get_name ());
	  break;
	case ARCH_PREFETCH:
	  if (mod == NULL)
	    break;
	  Dprintf (DEBUG_LOADOBJ, "PFINSTR list for %s\n", mod->get_name ());
	  if (mod->infoList == NULL)
	    mod->infoList = new Vector<inst_info_t*>;
	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
		  ((char*) mp) < ptr + cpkt->size; mp++)
	    {
	      memop_info_t *memop = new memop_info_t;
	      memop->offset = dwin->decode (mp->offset);
	      memop->id = dwin->decode (mp->id);
	      memop->signature = dwin->decode (mp->signature);
	      memop->datatype_id = dwin->decode (mp->datatype_id);
	      mod->pfMemops.append (memop);

	      inst_info_t *instop = new inst_info_t;
	      instop->type = CPF_INSTR_TYPE_PREFETCH;
	      instop->offset = memop->offset;
	      instop->memop = memop;
	      mod->infoList->incorporate (instop, offsetCmp);
	      Dprintf (DEBUG_LOADOBJ,
		       "pf: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
		       memop->offset, memop->id, memop->signature,
		       memop->datatype_id);
	    }
	  Dprintf (DEBUG_LOADOBJ, "PFINSTR list of %lld for %s\n",
		   (long long) mod->pfMemops.size (), mod->get_name ());
	  break;
	case ARCH_BRTARGET:
	  if (mod == NULL)
	    break;
	  for (target_info_t *tp = (target_info_t*) (ptr + sizeof (ARCH_aninfo));
		  ((char*) tp) < ptr + cpkt->size; tp++)
	    {
	      target_info_t *bTarget = new target_info_t;
	      bTarget->offset = dwin->decode (tp->offset);
	      mod->bTargets.append (bTarget);
	    }
	  Dprintf (DEBUG_LOADOBJ, "BRTARGET list of %lld for %s\n",
		   (long long) mod->infoList->size (), mod->get_name ());
	  break;
	default:
	  /* Check if the prointer is valid - should be even. */
	  pointer_invalid = (unsigned long long) (offset + cpktsize) & 1;
	  break; // ignore unknown packets
	}
      if (pointer_invalid)
	break;
      offset += cpktsize;
    }
  delete msg;
  delete dwin;

  if (dbeSession->is_interactive ())
    theApplication->set_progress (0, NTXT (""));
  return 0;
}

char *
LoadObject::status_str (Arch_status rv, char */*arg*/)
{
  switch (rv)
    {
    case ARCHIVE_SUCCESS:
    case ARCHIVE_EXIST:
      return NULL;
    case ARCHIVE_BAD_STABS:
      return dbe_sprintf (GTXT ("Error: unable to read symbol table of %s"),
			  name);
    case ARCHIVE_ERR_SEG:
      return dbe_sprintf (GTXT ("Error: unable to read load object file %s"),
			  pathname);
    case ARCHIVE_ERR_OPEN:
      return dbe_sprintf (GTXT ("Error: unable to open file %s"),
			  pathname);
    case ARCHIVE_ERR_MAP:
      return dbe_sprintf (GTXT ("Error: unable to map file %s"),
			  pathname);
    case ARCHIVE_WARN_CHECKSUM:
      return dbe_sprintf (GTXT ("Note: checksum differs from that recorded in experiment for %s"),
			  name);
    case ARCHIVE_WARN_MTIME:
      return dbe_sprintf (GTXT ("Warning: last-modified time differs from that recorded in experiment for %s"),
			  name);
    case ARCHIVE_WARN_HOST:
      return dbe_sprintf (GTXT ("Try running er_archive -F on the experiment, on the host where it was recorded"));
    case ARCHIVE_ERR_VERSION:
      return dbe_sprintf (GTXT ("Error: Wrong version of archive for %s"),
			  pathname);
    case ARCHIVE_NO_STABS:
      return dbe_sprintf (GTXT ("Note: no stabs or dwarf information in %s"),
			  name);
    case ARCHIVE_WRONG_ARCH:
#if ARCH(SPARC)
      return dbe_sprintf (GTXT ("Error: file %s is built for Intel, and can't be read on SPARC"),
			  name);
#else
      return dbe_sprintf (GTXT ("Error: file %s is built for SPARC, and can't be read on Intel"),
			  name);
#endif
    case ARCHIVE_NO_LIBDWARF:
      return dbe_strdup (GTXT ("Warning: no libdwarf found to read DWARF symbol tables"));
    case ARCHIVE_NO_DWARF:
      return dbe_sprintf (GTXT ("Note: no DWARF symbol table in %s"), name);
    default:
      return dbe_sprintf (GTXT ("Warning: unexpected archive error %d"),
			  (int) rv);
    }
}

uint32_t
LoadObject::get_checksum ()
{
  char *errmsg = NULL;
  uint32_t crcval = get_cksum (pathname, &errmsg);
  if (0 == crcval && errmsg)
    {
      warnq->append (new Emsg (CMSG_ERROR, errmsg));
      free (errmsg);
    }
  return crcval;
}

static char*
get_module_map_key (Module *mod)
{
  return mod->lang_code == Sp_lang_java ? mod->get_name () : mod->file_name;
}

Module *
LoadObject::get_comparable_Module (Module *mod)
{
  if (mod->loadobject == this)
    return mod;
  if (get_module_map_key (mod) == NULL)
    return NULL;
  if (seg_modules_map == NULL)
    {
      seg_modules_map = new HashMap<char*, Module*>;
      for (int i = 0; i < seg_modules->size (); i++)
	{
	  Module *m = seg_modules->fetch (i);
	  char *key = get_module_map_key (m);
	  if (key)
	    {
	      seg_modules_map->put (m->file_name, m);
	      char *bname = get_basename (key);
	      if (bname != key)
		seg_modules_map->put (bname, m);
	    }
	}
    }

  char *key = get_module_map_key (mod);
  Module *cmpMod = seg_modules_map->get (key);
  if (cmpMod && cmpMod->comparable_objs == NULL)
    return cmpMod;
  char *bname = get_basename (key);
  if (bname != key)
    {
      cmpMod = seg_modules_map->get (bname);
      if (cmpMod && cmpMod->comparable_objs == NULL)
	return cmpMod;
    }
  return NULL;
}

Vector<Histable*> *
LoadObject::get_comparable_objs ()
{
  update_comparable_objs ();
  if (comparable_objs || dbeSession->expGroups->size () <= 1)
    return comparable_objs;
  comparable_objs = new Vector<Histable*>(dbeSession->expGroups->size ());
  for (int i = 0, sz = dbeSession->expGroups->size (); i < sz; i++)
    {
      ExpGroup *gr = dbeSession->expGroups->fetch (i);
      Histable *h = gr->get_comparable_loadObject (this);
      comparable_objs->append (h);
      if (h)
	h->comparable_objs = comparable_objs;
    }
  dump_comparable_objs ();
  return comparable_objs;
}

void
LoadObject::append_module (Module *mod)
{
  seg_modules->append (mod);
  if (seg_modules_map == NULL)
    seg_modules_map = new HashMap<char*, Module*>;
  char *key = get_module_map_key (mod);
  if (key)
    {
      seg_modules_map->put (key, mod);
      char *bname = get_basename (key);
      if (bname != key)
	seg_modules_map->put (bname, mod);
    }
}

// LIBRARY_VISIBILITY
Function *
LoadObject::get_hide_function ()
{
  if (h_function == NULL)
    h_function = dbeSession->create_hide_function (this);
  return h_function;
}

DbeInstr *
LoadObject::get_hide_instr (DbeInstr *instr)
{
  if (h_instr == NULL)
    {
      Function *hf = get_hide_function ();
      h_instr = hf->create_hide_instr (instr);
    }
  return h_instr;
}
