/* Copyright (C) 2021-2026 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 "util.h"
#include "DbeSession.h"
#include "Elf.h"
#include "Stabs.h"
#include "Dwarf.h"
#include "DataObject.h"
#include "Function.h"
#include "LoadObject.h"
#include "Module.h"
#include "DefaultMap.h"
#include "Symbol.h"

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

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

//////////////////////////////////////////////////////////
//  class Dwr_type
class Dwr_type
{
public:

  Dwr_type (int64_t _cu_die_offset, int _tag)
  {
    cu_die_offset = _cu_die_offset;
    tag = _tag;
    name = NULL;
    dobj_name = NULL;
    dtype = NULL;
    extent = 0;
    parent = 0;
    child = 0;
    next = 0;
    ref_type = 0;
    size = 0;
    elems = 0;
    offset = -1;
    bit_size = 0;
  };

  char *name, *dobj_name;
  int64_t cu_die_offset, ref_type, extent, parent, child, next;
  int64_t size, elems, offset;
  int tag, bit_size;

  DataObject *get_dobj (Dwarf_cnt *ctx);
  char *get_dobjname (Dwarf_cnt *ctx);
  char *dump ();

private:
  datatype_t *dtype;
  datatype_t *get_datatype (Dwarf_cnt *ctx);
  void get_dobj_for_members (Dwarf_cnt *ctx);
  void set_dobjname (char *spec, char *nm);
};


//////////////////////////////////////////////////////////
//  class Dwarf_cnt
Dwarf_cnt::Dwarf_cnt ()
{
  cu_offset = 0;
  parent = 0;
  module = NULL;
  name = NULL;
  func = NULL;
  fortranMAIN = NULL;
  dwr_types = NULL;
  inlinedSubr = NULL;
  level = 0;
}

Dwr_type *
Dwarf_cnt::get_dwr_type (int64_t cu_die_offset)
{
  Dwr_type *t = dwr_types->get (cu_die_offset);
  if (t == NULL)
    {
      Dprintf (DUMP_DWARFLIB, "DWARF_ERROR: %s:%d wrong cu_die_offset=%lld in Dwarf_cnt::get_dwr_type\n",
	       get_basename (__FILE__), (int) __LINE__,
	       (long long) cu_die_offset);
      t = put_dwr_type (cu_die_offset, 0); // DOBJ_UNSPECIFIED
    }
  return t;
}

Dwr_type *
Dwarf_cnt::put_dwr_type (int64_t cu_die_offset, int tag)
{
  Dwr_type *t = new Dwr_type (cu_die_offset, tag);
  dwr_types->put (cu_die_offset, t);
  return t;
}

Dwr_type *
Dwarf_cnt::put_dwr_type (Dwr_Tag *dwrTag)
{
  Dwr_type *t = new Dwr_type (dwrTag->die, dwrTag->tag);
  dwr_types->put (dwrTag->die, t);
  return t;
}

//////////////////////////////////////////////////////////
//  class Dwr_type
char *
Dwr_type::dump ()
{
  char *s = dbe_sprintf ("%lld %-15s name='%s' parent=%lld next=%lld child=%lld dtype=%llx",
			 (long long) cu_die_offset, DwrCU::tag2str (tag),
			 STR (name), (long long) parent, (long long) next,
			 (long long) child, (long long) dtype);
  return s;
}

void
Dwr_type::set_dobjname (char *spec, char *nm)
{
  if (spec)
    {
      if (nm)
	dobj_name = dbe_sprintf ("%s%s", spec, nm);
      else
	dobj_name = dbe_sprintf ("%s<ANON=%lld>", spec,
				 (long long) cu_die_offset);
    }
  else
    {
      if (nm)
	dobj_name = dbe_sprintf ("%s", nm);
      else
	dobj_name = dbe_sprintf ("<ANON=%lld>", (long long) cu_die_offset);
    }
}

char *
Dwr_type::get_dobjname (Dwarf_cnt *ctx)
{
  if (dobj_name)
    return dobj_name;
  switch (tag)
    {
    case DW_TAG_base_type:
      set_dobjname (NULL, name);
      for (int i = 0, len = (int) strlen (dobj_name); i < len; i++)
	{
	  if (dobj_name[i] == ' ')
	    dobj_name[i] = '_';
	}
      break;
    case DW_TAG_constant:
    case DW_TAG_formal_parameter:
    case DW_TAG_variable:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	set_dobjname (NULL, t->get_dobjname (ctx));
	break;
      }
    case DW_TAG_unspecified_type:
      set_dobjname (NTXT ("unspecified:"), name);
      break;
    case DW_TAG_enumeration_type:
      set_dobjname (NTXT ("enumeration:"), name);
      break;
    case DW_TAG_typedef:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	dobj_name = dbe_sprintf ("%s=%s", name, t->get_dobjname (ctx));
	break;
      }
    case DW_TAG_const_type:
      set_dobjname (NTXT ("const+"), name);
      break;
    case DW_TAG_volatile_type:
      set_dobjname (NTXT ("volatile+"), name);
      break;
    case DW_TAG_pointer_type:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	set_dobjname (NTXT ("pointer+"), t->get_dobjname (ctx));
	break;
      }
    case DW_TAG_reference_type:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	set_dobjname (NTXT ("reference+"), t->get_dobjname (ctx));
	break;
      }
    case DW_TAG_array_type:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	if (elems > 0)
	  dobj_name = dbe_sprintf ("array[%lld]:%s",
				   (long long) elems, t->get_dobjname (ctx));
	else
	  dobj_name = dbe_sprintf ("array[]:%s", t->get_dobjname (ctx));
	break;
      }
    case DW_TAG_structure_type:
      set_dobjname (NTXT ("structure:"), name);
      break;
    case DW_TAG_union_type:
      set_dobjname (NTXT ("union:"), name);
      break;
    case DW_TAG_class_type:
      set_dobjname (NTXT ("class:"), name);
      break;
    case DW_TAG_member:
      {
	Dwr_type *t = ctx->get_dwr_type (ref_type);
	if (bit_size > 0)
	  dobj_name = dbe_sprintf (NTXT ("%s:%lld"), t->get_dobjname (ctx),
				   (long long) bit_size);
	else
	  dobj_name = dbe_sprintf (NTXT ("%s"), t->get_dobjname (ctx));
	break;
      }
    default:
      Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"),
	       get_basename (__FILE__), (int) __LINE__,
	       DwrCU::tag2str (tag), (long long) cu_die_offset);
      set_dobjname (NTXT ("Undefined:"), NULL);
      break;
    }
  return dobj_name;
}

datatype_t*
Dwr_type::get_datatype (Dwarf_cnt *ctx)
{
  if (dtype)
    return dtype;
  dtype = new datatype_t;
  dtype->datatype_id = (unsigned) cu_die_offset;
  dtype->memop_refs = 0;
  dtype->event_data = 0;
  dtype->dobj = NULL;
  ctx->module->datatypes->incorporate (dtype, datatypeCmp);
  return dtype;
}

DataObject *
Dwr_type::get_dobj (Dwarf_cnt *ctx)
{
  if (dtype == NULL)
    dtype = get_datatype (ctx);
  dtype->memop_refs++;
  DataObject *dobj = dtype->dobj;
  if (dobj)
    return dobj;

  if (tag == 0)
    dobj = dbeSession->find_dobj_by_name (PTXT (DOBJ_UNSPECIFIED));
  else
    {
      dobj = dbeSession->createDataObject ();
      dobj->size = size;
      dobj->offset = offset;
      dobj->scope = ctx->func ? (Histable*) ctx->func : (Histable*) ctx->module;
    }
  dtype->dobj = dobj;
  if (parent)
    {
      Dwr_type *t = ctx->get_dwr_type (parent);
      dobj->parent = t->get_dobj (ctx);
    }

  if (ref_type)
    {
      Dwr_type *t = ctx->get_dwr_type (ref_type);
      t->get_dobj (ctx);
      if (size == 0)
	{
	  size = t->size;
	  dobj->size = size;
	}
    }

  switch (tag)
    {
    case 0:
      break;
    case DW_TAG_array_type:
    case DW_TAG_base_type:
    case DW_TAG_unspecified_type:
    case DW_TAG_enumeration_type:
    case DW_TAG_typedef:
    case DW_TAG_const_type:
    case DW_TAG_volatile_type:
    case DW_TAG_pointer_type:
    case DW_TAG_reference_type:
      dobj->set_dobjname (get_dobjname (ctx), NULL);
      break;
    case DW_TAG_structure_type:
    case DW_TAG_union_type:
    case DW_TAG_class_type:
      dobj->set_dobjname (get_dobjname (ctx), NULL);
      dobj->master = dbeSession->find_dobj_by_name (dobj_name);
      get_dobj_for_members (ctx);
      break;
    case DW_TAG_constant:
    case DW_TAG_formal_parameter:
    case DW_TAG_member:
    case DW_TAG_variable:
      if (dobj->parent == NULL)
	dobj->parent = dbeSession->get_Scalars_DataObject ();
      dobj->set_dobjname (get_dobjname (ctx), name);
      break;
    default:
      Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"),
	       get_basename (__FILE__), (int) __LINE__,
	       DwrCU::tag2str (tag), (long long) cu_die_offset);
      break;
    }
  return dobj;
}

void
Dwr_type::get_dobj_for_members (Dwarf_cnt *ctx)
{
  for (int64_t i = child; i != 0;)
    {
      Dwr_type *t = ctx->get_dwr_type (i);
      t->get_dobj (ctx);
      i = t->next;
    }
}

//////////////////////////////////////////////////////////
//  class Dwarf
Dwarf::Dwarf (Stabs *_stabs)
{
  stabs = _stabs;
  status = Stabs::DBGD_ERR_NONE;
  dwrCUs = 0;
  debug_infoSec = NULL;
  debug_abbrevSec = NULL;
  debug_strSec = NULL;
  debug_alt_strSec = NULL;
  debug_lineSec = NULL;
  debug_line_strSec = NULL;
  debug_rangesSec = NULL;
  elf = stabs->openElf (true);
  if (elf == NULL)
    {
      status = Stabs::DBGD_ERR_BAD_ELF_FORMAT;
      return;
    }
  debug_infoSec = dwrGetSec (NTXT (".debug_info"));
  debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev"));
  debug_strSec = dwrGetSec (NTXT (".debug_str"));
  debug_lineSec = dwrGetSec (NTXT (".debug_line"));
  debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
  debug_line_strSec = dwrGetSec (".debug_line_str");
  debug_rnglists = NULL;
  if (elf->gnu_debugalt_file)
    debug_alt_strSec = elf->gnu_debugalt_file->get_dwr_section (".debug_str");

  if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
    {
      status = Stabs::DBGD_ERR_NO_DWARF;
      return;
    }
}

Dwarf::~Dwarf ()
{
  Destroy (dwrCUs);
}

DwrSec *
Dwarf::dwrGetSec (const char *sec_name)
{
  DwrSec *p = elf->get_dwr_section (sec_name);
  if (p)
    p->offset = 0;
  return p;
}

uint64_t
DwrCU::get_low_pc ()
{
  uint64_t pc = Dwarf_addr (DW_AT_low_pc);
  if (pc)
    return pc;
  return pc;
}

char *
DwrCU::get_linkage_name ()
{
  char *nm = Dwarf_string (DW_AT_linkage_name);
  if (nm != NULL)
    return nm;
  nm = Dwarf_string (DW_AT_SUN_link_name);
  if (nm != NULL)
    return nm;
  if (nm != NULL)
    return nm;
  nm = Dwarf_string (DW_AT_MIPS_linkage_name);
  if (nm != NULL)
    return nm;
  return Dwarf_string (DW_AT_name);
}

void
DwrCU::parseChild (Dwarf_cnt *ctx)
{
  if (!dwrTag.hasChild)
    return;
  uint64_t old_size = debug_infoSec->size;
  uint64_t next_die_offset = 0;
  Dwarf_Die next_die;
  if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
    {
      next_die_offset = next_die;
      if (next_die_offset <= debug_infoSec->offset)
	{
	  Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"),
		   (long long) next_die, (long long) debug_infoSec->offset);
	  next_die_offset = 0;
	}
      else if (debug_infoSec->size > next_die_offset)
	debug_infoSec->size = next_die_offset;
    }
  dwrTag.level++;
  ctx->level++;
  for (;;)
    {
      if (set_die (0) != DW_DLV_OK)
	break;
      Function *func;
      char *old_name;
      int hasChild = dwrTag.hasChild;
      switch (dwrTag.tag)
	{
	case DW_TAG_imported_declaration:
	  if (Stabs::is_fortran (ctx->module->lang_code))
	    {
	      char *link_name = Dwarf_string (DW_AT_name);
	      ctx->fortranMAIN = NULL;
	      parseChild (ctx);
	      hasChild = 0;
	      if (ctx->fortranMAIN)
		{
		  ctx->fortranMAIN->set_match_name (link_name);
		  ctx->fortranMAIN = NULL;
		}
	    }
	  break;
	case DW_TAG_subprogram:
	{
	  Symbol *sym = NULL;
	  Vector<Symbol *> *syms = NULL;
	  Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_abstract_origin);
	  if (dwrAttr)
	    {
	      // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
	      set_up_funcs (dwrAttr->u.offset);
	      break;
	    }

	  dwrAttr = dwrTag.get_attr (DW_AT_specification);
	  if (dwrAttr)
	    {
	      // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
	      set_up_funcs (dwrAttr->u.offset);
	      break;
	    }

	  if (dwrTag.get_attr (DW_AT_declaration))
	    {
	      // Only declaration
	      if (Stabs::is_fortran (ctx->module->lang_code))
		{
		  char *link_name = Dwarf_string (DW_AT_name);
		  if (link_name && streq (link_name, NTXT ("MAIN")))
		    ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"),
					    ctx->module->functions, true, true);
		}
	      sym = Symbol::get_symbol (symbols_sorted_by_name,
				       get_linkage_name ());
	      if (sym != NULL)
		func = append_Function (sym, ctx->name);
	      break;
	    }

	  func = NULL;
	  syms = get_symbols (tmp_syms);
	  for (int i = 0, sz = VecSize (syms); i < sz; i++)
	    {
	      sym = syms->get (i);
	      func = append_Function (sym, ctx->name);
	      if (Stabs::is_fortran (ctx->module->lang_code) &&
	      streq (func->get_match_name (), "MAIN"))
		ctx->fortranMAIN = func;
	    }
	  if (func == NULL)
	    break;

	  old_name = ctx->name;
	  Function *old_func = ctx->func;
	  ctx->name = func->get_match_name ();
	  ctx->func = func;
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  ctx->func = old_func;
	  break;
	}
	case DW_TAG_module:
	  old_name = ctx->name;
	  ctx->name = Dwarf_string (DW_AT_SUN_link_name);
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  break;
	case DW_TAG_class_type:
	  old_name = ctx->name;
	  ctx->name = Dwarf_string (DW_AT_name);
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  break;
	case DW_TAG_structure_type:
	  old_name = ctx->name;
	  ctx->name = NULL;
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  break;
	case DW_TAG_namespace:
	  old_name = ctx->name;
	  ctx->name = Dwarf_string (DW_AT_name);
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  break;
	case DW_TAG_lexical_block:
	  old_name = ctx->name;
	  ctx->name = NULL;
	  parseChild (ctx);
	  hasChild = 0;
	  ctx->name = old_name;
	  break;
	case DW_TAG_SUN_memop_info:
	  isMemop = true;
	  break;
	case DW_TAG_inlined_subroutine:
	  if (ctx->module)
	    {
	      parse_inlined_subroutine (ctx);
	      hasChild = 0;
	    }
	  break;
	default: // No more special cases
	  break;
	}
      if (hasChild)
	parseChild (ctx);
    }
  ctx->level--;
  dwrTag.level--;
  if (next_die_offset != 0)
    debug_infoSec->offset = next_die_offset;
  debug_infoSec->size = old_size;
}

bool
Dwarf::archive_Dwarf (LoadObject *lo)
{
  if (debug_infoSec == NULL)
    return false;
  if (dwrCUs)
    return true;
  dwrCUs = new Vector<DwrCU *>;

  debug_infoSec->offset = 0;
  while (debug_infoSec->offset < debug_infoSec->sizeSec)
    {
      DwrCU *dwrCU = new DwrCU (this);
      dwrCUs->append (dwrCU);
      debug_infoSec->size = debug_infoSec->sizeSec;
      debug_infoSec->offset = dwrCU->next_cu_offset;

      if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
	{
	  Dprintf (1, "DwrCU::archive_Dwarf: CU=%lld  (offset=0x%llx); set_die(0x%llx) failed\n",
		   (long long) dwrCUs->size (), (long long) dwrCU->cu_offset,
		   (long long) dwrCU->cu_header_offset);
	  continue;
	}

      Module *mod = dwrCU->parse_cu_header (lo);
      if (mod)
	{
	  mod->hdrOffset = dwrCUs->size ();
	  DwrLineRegs *lineReg = dwrCU->get_dwrLineReg ();
	  if (lineReg != NULL)
	    {
	      dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
	      for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
		{
		  char *fname = lineReg->getPath (i);
		  if (fname)
		    dwrCU->srcFiles->append (mod->findSource (fname, true));
		}
	    }

	  Dwarf_cnt ctx;
	  ctx.module = mod;
	  dwrCU->parseChild (&ctx);
	  if (dwrCU->dwrInlinedSubrs && DUMP_DWARFLIB)
	    {
	      char msg[128];
	      char *lo_name = mod->loadobject ? mod->loadobject->get_name ()
		      : NULL;
	      snprintf (msg, sizeof (msg), NTXT ("\ndwrCUs[%lld]: %s:%s\n"),
			(long long) dwrCUs->size (),
			STR (lo_name), STR (mod->get_name ()));
	      dwrCU->dwrInlinedSubrs->dump (msg);
	    }
	  for (int i = 0, sz = VecSize (dwrCU->symbols); i < sz; i++)
	    {
	      Symbol *sp = dwrCU->symbols->get (i);
	      Function *f = sp->func;
	      if (f == NULL)
		{
		  f = sp->createFunction (mod);
		  if (sp->alias && sp->alias->func)
		    {
		      Function *func = sp->alias->func;
		      f->setLineFirst (func->line_first);
		      f->setDefSrc (func->def_source);
		    }
		}
	    }
	}
    }
  return true;
}

void
Dwarf::srcline_Dwarf (Module *module)
{
  if (module == NULL || module->hdrOffset == 0)
    return;
  DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
  dwrCU->map_dwarf_lines (module);
}

Vector<Range *> *
Dwarf::get_ranges (uint64_t offset)
{
  if (debug_rangesSec == NULL)
    return NULL;
  if (offset >= debug_rangesSec->size)
    {
      Dprintf (DUMP_DWARFLIB, "ERROR: Dwarf::get_ranges(0x%llx). size=0x%llx\n",
	       (long long) offset, (long long) debug_rangesSec->size);
      return NULL;
    }
  Vector<Range*> *ranges = new Vector<Range*>();
  debug_rangesSec->offset = offset;
  for (;;)
    {
      uint64_t low_pc = debug_rangesSec->GetADDR ();
      uint64_t high_pc = debug_rangesSec->GetADDR ();
      if (low_pc == 0 || low_pc > high_pc)
	break;
      ranges->append (new Range (low_pc, high_pc));
    }
  return ranges;
}

// parse hwcprof info for given module in loadobject

void
Dwarf::read_hwcprof_info (Module *module)
{
  if (module->datatypes || (module->hdrOffset == 0))
    return;
  DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
  if (!dwrCU->isMemop)
    return;
  module->datatypes = new Vector<datatype_t*>;
  if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
    {
      Dprintf (1, "Dwarf::read_hwcprof_info: CU=%lld  (offset=0x%llx); set_die(0x%llx) failed\n",
	       (long long) module->hdrOffset, (long long) dwrCU->cu_offset,
	       (long long) dwrCU->cu_header_offset);
      return;
    }
  Dwarf_cnt ctx;
  ctx.module = module;
  ctx.cu_offset = dwrCU->cu_offset; // CU header offset;
  ctx.dwr_types = new DefaultMap<int64_t, Dwr_type*>;
  ctx.put_dwr_type (0, 0); // for DOBJ_UNSPECIFIED
  dwrCU->read_hwcprof_info (&ctx);

  Vector<inst_info_t*> *infoList = module->infoList;
  Dprintf (DUMP_DWARFLIB,
     "\n\n ### Dwarf::read_hwcprof_info: module: '%s'  infoList->size()=%lld\n",
     STR (module->get_name ()),
     (long long) (infoList ? infoList->size () : -1));
  for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
    {
      inst_info_t *ip = infoList->fetch (i);
      memop_info_t *mp = ip->memop;
      Dwr_type *t = ctx.get_dwr_type (mp->datatype_id);
      t->get_dobj (&ctx);
    }

#ifdef DEBUG
  Dprintf (DUMP_DWARFLIB,
	   "\n\n ### Dwarf::read_hwcprof_info: '%s'  infoList->size()=%lld\n",
	   STR (module->get_name ()),
	   (long long) (infoList ? infoList->size () : 1));
  for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
    {
      inst_info_t *ip = infoList->fetch (i);
      memop_info_t *mp = ip->memop;
      Dprintf (DUMP_DWARFLIB,
	       "  %d id=%lld  offset=%lld  signature=%lld  datatype_id=%lld \n",
	       i, (long long) mp->id, (long long) mp->offset,
	       (long long) mp->signature, (long long) mp->datatype_id);
    }

  Vector<int64_t> *keys = ctx.dwr_types->keySet ();
  Dprintf (DUMP_DWARFLIB,
	   "\n\n ### Dwarf::read_hwcprof_info: '%s'  keys->size()=%lld\n",
	   STR (module->get_name ()), (long long) (keys ? keys->size () : -1));
  for (int i = 0, sz = keys->size (); i < sz; i++)
    {
      int64_t ind = keys->fetch (i);
      Dwr_type *t = ctx.get_dwr_type (ind);
      Dprintf (DUMP_DWARFLIB, NTXT ("  %d %lld %s\n"), i,
	       (long long) ind, t->dump ());
    }
#endif
}

void
DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
{
  if (!dwrTag.hasChild)
    return;
  uint64_t old_size = debug_infoSec->size;
  uint64_t next_die_offset = 0;
  Dwarf_Die next_die;
  if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
    {
      next_die_offset = next_die;
      if (next_die_offset <= debug_infoSec->offset)
	next_die_offset = 0;
      else if (debug_infoSec->size > next_die_offset)
	debug_infoSec->size = next_die_offset;
    }
  dwrTag.level++;
  ctx->level++;
  for (;;)
    {
      if (set_die (0) != DW_DLV_OK)
	break;
      Dprintf (DUMP_DWARFLIB, NTXT ("%s:%d <%lld:%lld> cu_die=%lld %-15s\n"),
	       get_basename (__FILE__), (int) __LINE__, (long long) ctx->level,
	       (long long) dwrTag.die, (long long) dwrTag.offset,
	       DwrCU::tag2str (dwrTag.tag));
      switch (dwrTag.tag)
	{
	case DW_TAG_SUN_memop_info:
	  {
	    if (ctx->func == NULL)
	      break;
	    Dwarf_Unsigned mid = Dwarf_data (DW_AT_SUN_profile_id);
	    Dwarf_Unsigned off = Dwarf_data (DW_AT_SUN_func_offset);
	    Dwarf_Unsigned sig = Dwarf_data (DW_AT_SUN_memop_signature);
	    Dwarf_Off ref = Dwarf_ref (DW_AT_SUN_memop_type_ref);

	    // define memop entry
	    memop_info_t *memop = new memop_info_t;
	    memop->id = (unsigned) mid;
	    memop->signature = (unsigned) sig;
	    memop->datatype_id = ref ? (unsigned) ref : 0;
	    memop->offset = (unsigned) (ctx->func->img_offset + off);

	    // define instop entry
	    inst_info_t *instop = new inst_info_t;
	    instop->type = CPF_INSTR_TYPE_PREFETCH; // XXXX UNKNOWN
	    instop->offset = memop->offset;
	    instop->memop = memop;
	    if (ctx->module->infoList == NULL)
	      ctx->module->infoList = new Vector<inst_info_t*>;
	    ctx->module->infoList->append (instop);
	    break;
	  }
	case DW_TAG_SUN_codeflags:
	  {
	    if (ctx->func == NULL)
	      break;
	    Dwarf_Unsigned kind = Dwarf_data (DW_AT_SUN_cf_kind);
	    if (kind == DW_ATCF_SUN_branch_target)
	      {
		DwrSec *secp = Dwarf_block (DW_AT_SUN_func_offsets);
		if (secp)
		  {
		    int foffset = 0;
		    for (int i = 0; secp->offset < secp->size; i++)
		      {
			int val = (int) secp->GetSLEB128 ();
			if (i == 0 || val != 0)
			  {
			    foffset += val;
			    target_info_t *t = new target_info_t;
			    t->offset = (unsigned) (ctx->func->img_offset + foffset);
			    ctx->module->bTargets.incorporate (t, targetOffsetCmp);
			  }
		      }
		    delete(secp);
		  }
	      }
	    break;
	  }
	case DW_TAG_subprogram:
	  {
	    Function *old_func = ctx->func;
	    ctx->func = NULL;
	    if (dwrTag.get_attr (DW_AT_abstract_origin) == NULL
				 && dwrTag.get_attr (DW_AT_declaration) == NULL)
	      {
		Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name,
						 get_linkage_name ());
		if (sym == NULL)
		  sym = Symbol::get_symbol (symbols, get_low_pc ());
		if (sym != NULL)
		  ctx->func = sym->func;
	      }
	    read_hwcprof_info (ctx);
	    ctx->func = old_func;
	    break;
	  }
	case DW_TAG_base_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->size = Dwarf_data (DW_AT_byte_size);
	    break;
	  }
	case DW_TAG_unspecified_type:
	  ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	  break;
	case DW_TAG_enumeration_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->size = Dwarf_data (DW_AT_byte_size);
	    break;
	  }
	case DW_TAG_constant:
	case DW_TAG_formal_parameter:
	case DW_TAG_variable:
	case DW_TAG_typedef:
	case DW_TAG_const_type:
	case DW_TAG_volatile_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->ref_type = Dwarf_ref (DW_AT_type);
	    break;
	  }
	case DW_TAG_pointer_type:
	case DW_TAG_reference_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->ref_type = Dwarf_ref (DW_AT_type);
	    t->size = (dwarf->stabs->get_class () == W64) ? 8 : 4;
	    break;
	  }
	case DW_TAG_array_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->ref_type = Dwarf_ref (DW_AT_type);
	    t->size = Dwarf_data (DW_AT_byte_size);
	    ctx->size = -1;
	    read_hwcprof_info (ctx);
	    t->elems = ctx->size;
	    break;
	  }
	case DW_TAG_subrange_type:
	  {
	    int64_t ref_type = Dwarf_ref (DW_AT_type);
	    int64_t hi = Dwarf_data (DW_AT_upper_bound);
	    int64_t lo = Dwarf_data (DW_AT_lower_bound);
	    int64_t ss = Dwarf_data (DW_AT_stride_size);
	    ctx->size = 1 + hi - lo;
	    if (ss != 0)
	      ctx->size /= ss;
	    Dprintf (DUMP_DWARFLIB,
		    "Got subrange [%lld:%lld:%lld] indexed <%lld>: size=%lld\n",
		     (long long) lo, (long long) hi, (long long) ss,
		     (long long) ref_type, (long long) ctx->size);
	    break;
	  }
	case DW_TAG_structure_type:
	case DW_TAG_union_type:
	case DW_TAG_class_type:
	  {
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->size = Dwarf_data (DW_AT_byte_size);
	    t->extent = Dwarf_ref (DW_AT_sibling);
	    int64_t old_parent = ctx->parent;
	    ctx->parent = t->cu_die_offset;

	    char *old_name = ctx->name;
	    ctx->name = (dwrTag.tag == DW_TAG_class_type) ? Dwarf_string (DW_AT_name) : NULL;
	    read_hwcprof_info (ctx);
	    ctx->name = old_name;
	    ctx->parent = old_parent;
	    // Reverse children
	    for (int64_t i = t->child, last = 0; i != 0;)
	      {
		Dwr_type *t1 = ctx->get_dwr_type (i);
		t->child = i;
		i = t1->next;
		t1->next = last;
		last = t->child;
	      }
	    break;
	  }
	case DW_TAG_member:
	  {
	    if (ctx->parent == 0)
	      {
		Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d %s cu_die_offset=%lld\n"),
			 get_basename (__FILE__), (int) __LINE__,
			 DwrCU::tag2str (dwrTag.tag), (long long) dwrTag.die);
		break;
	      }
	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
	    t->name = Dwarf_string (DW_AT_name);
	    t->ref_type = Dwarf_ref (DW_AT_type);
	    t->offset = Dwarf_location (DW_AT_data_member_location);
	    Dwr_type *parent = ctx->get_dwr_type (ctx->parent);
	    t->parent = ctx->parent;
	    t->next = parent->child; // a reverse order of members
	    parent->child = t->cu_die_offset;
	    t->bit_size = (uint32_t) Dwarf_data (DW_AT_bit_size);
	    break;
	  }
	case DW_TAG_module:
	  {
	    char *old_name = ctx->name;
	    ctx->name = Dwarf_string (DW_AT_SUN_link_name);
	    read_hwcprof_info (ctx);
	    ctx->name = old_name;
	    break;
	  }
	case DW_TAG_namespace:
	  {
	    char *old_name = ctx->name;
	    ctx->name = Dwarf_string (DW_AT_name);
	    read_hwcprof_info (ctx);
	    ctx->name = old_name;
	    break;
	  }
	case DW_TAG_lexical_block:
	  {
	    char *old_name = ctx->name;
	    ctx->name = NULL;
	    read_hwcprof_info (ctx);
	    ctx->name = old_name;
	    break;
	  }
	default: // No more special cases
	  read_hwcprof_info (ctx);
	  break;
	}
    }
  ctx->level--;
  dwrTag.level--;
  if (next_die_offset != 0)
    debug_infoSec->offset = next_die_offset;
  debug_infoSec->size = old_size;
}

// Append function to module
Function *
DwrCU::append_Function (Symbol *sym, const char *outerName)
{
  if (sym->func != NULL)
    return sym->func;
  Function *func = sym->createFunction (module);

  char *fname = Dwarf_string (DW_AT_name);
  if (fname)
    {
      if (outerName && !strchr (fname, '.'))
	{
	  char *tmpname;
	  int outerlen = (int) strlen (outerName);
	  if (outerlen > 0 && outerName[outerlen - 1] == '_')
	    tmpname = dbe_sprintf ("%.*s.%s_", outerlen - 1, outerName, fname);
	  else
	    tmpname = dbe_sprintf ("%s.%s", outerName, fname);
	  func->set_match_name (tmpname);
	  Dprintf (DUMP_DWARFLIB, "Generated innerfunc name %s\n", tmpname);
	  free(tmpname);
	}
      else
	func->set_match_name (fname);
    }
  set_source (func);
  return func;
}

// Get language code
Sp_lang_code
DwrCU::Dwarf_lang ()
{
  char *str = Dwarf_string (DW_AT_producer);
  if (str && strncmp (str, NTXT ("GNU"), 3) == 0)
    isGNU = true;
  int64_t lang = Dwarf_data (DW_AT_language);
  switch (lang)
    {
    case DW_LANG_C89:
    case DW_LANG_C:
      return Sp_lang_c; // Sp_lang_ansic?
    case DW_LANG_C99:
      return Sp_lang_c99;
    case DW_LANG_C_plus_plus:
      return isGNU ? Sp_lang_gcc : Sp_lang_cplusplus;
    case DW_LANG_Fortran90:
      return Sp_lang_fortran90;
    case DW_LANG_Fortran77:
      return Sp_lang_fortran;
    case DW_LANG_Java:
      return Sp_lang_java;
    case DW_LANG_Mips_Assembler:
    case DW_LANG_SUN_Assembler:
      return Sp_lang_asm;
    case DW_LANG_Pascal83:
      return Sp_lang_pascal;
    default:
    case DW_LANG_Ada83:
    case DW_LANG_Cobol74:
    case DW_LANG_Cobol85:
    case DW_LANG_Modula2:
    case DW_LANG_Ada95:
    case DW_LANG_Fortran95:
    case DW_LANG_lo_user:
      return Sp_lang_unknown;
    }
}

Vector <Dwr_rng_entry *> *
Dwarf::get_debug_rnglists ()
{
  if (debug_rnglists != NULL)
    return debug_rnglists;
  debug_rnglists = new Vector <Dwr_rng_entry *> ();

  DwrSec *debug_rnglistsSec = dwrGetSec (".debug_rnglists");
  if (debug_rnglistsSec == NULL)
    {
      Dprintf (1, "No section .debug_rnglists\n");
      return debug_rnglists;
    }
  while (debug_rnglistsSec->offset < debug_rnglistsSec->sizeSec)
    {
      uint64_t base_address = 0;
      uint64_t length = debug_rnglistsSec->ReadLength ();
      Dwr_rng_entry *rng = new Dwr_rng_entry ();
      debug_rnglists->append (rng);
      rng->offset = debug_rnglistsSec->offset;
      rng->length = length;
      rng->fmt64 = debug_rnglistsSec->fmt64;
      rng->version = debug_rnglistsSec->Get_16 ();
      rng->address_size = debug_rnglistsSec->Get_8 ();
      rng->segment_selector_size = debug_rnglistsSec->Get_8 ();
      rng->offset_entry_count = debug_rnglistsSec->Get_32 ();
      while (debug_rnglistsSec->offset < debug_rnglistsSec->size)
	{
	  uint64_t off = debug_rnglistsSec->offset;
	  uint64_t low_pc;
	  uint64_t high_pc;
	  int re = debug_rnglistsSec->Get_8 ();
	  switch (re)
	    {
	    case DW_RLE_end_of_list:
	      low_pc = 0;
	      high_pc = 0;
	      break;
	    case DW_RLE_base_address:
	      base_address = debug_rnglistsSec->GetADDR ();
	      low_pc = base_address;
	      high_pc = 0;
	      continue;
	    case DW_RLE_start_length:
	      low_pc = debug_rnglistsSec->GetADDR ();
	      high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
	      break;
	    case DW_RLE_offset_pair:
	      low_pc = base_address + debug_rnglistsSec->GetULEB128 ();
	      high_pc = base_address + debug_rnglistsSec->GetULEB128 ();
	      break;
	    case DW_RLE_start_end:
	      low_pc = debug_rnglistsSec->GetADDR ();
	      high_pc = debug_rnglistsSec->GetADDR ();
	      break;
	    case DW_RLE_base_addressx:
	      base_address = debug_rnglistsSec->GetULEB128 ();
	      low_pc = base_address;
	      high_pc = 0;
	      continue;

	      // TODO x-variants need .debug_addr support used for split-dwarf
	    case DW_RLE_startx_endx:
	      low_pc = debug_rnglistsSec->GetRef ();
	      high_pc = debug_rnglistsSec->GetRef ();
	      Dprintf (1, "DW_RLE_startx_endx is not implemented\n");
	      continue;
	    case DW_RLE_startx_length:
	      low_pc = debug_rnglistsSec->GetRef ();
	      high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
	      Dprintf (1, "DW_RLE_startx_length is not implemented\n");
	      continue;
	    default:
	      Dprintf (1, "Unknown tag DW_RLE: %d, offset=0x%llx\n", re,
		       (long long) off);
	      debug_rnglistsSec->offset = debug_rnglistsSec->size;
	      continue;
	    }
	  Dprintf (DUMP_DWARFLIB, "0x%08llx %d-%-20s [0x%08llx - 0x%08llx)\n",
		   (long long) off, re, Dwr_rng_entry::rng_entry2str (re),
		   (long long) low_pc, (long long) high_pc);
	  rng->ranges->append (new ExtRange (off, low_pc, high_pc));
	}
      debug_rnglistsSec->size = debug_rnglistsSec->sizeSec;
      debug_rnglistsSec->offset = length;
    }
  debug_rnglists->dump ("Dwarf::get_debug_rnglists");
  return debug_rnglists;
}
