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

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include "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"

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_lineSec = 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"));
  if (debug_infoSec)
    {
      debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL);
      debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc);
      if (debug_infoSec->reloc)
	debug_infoSec->reloc->dump ();
    }
  debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev"));
  debug_strSec = dwrGetSec (NTXT (".debug_str"));
  debug_lineSec = dwrGetSec (NTXT (".debug_line"));
  debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));

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

Dwarf::~Dwarf ()
{
  delete debug_infoSec;
  delete debug_abbrevSec;
  delete debug_strSec;
  delete debug_lineSec;
  delete debug_rangesSec;
  Destroy (dwrCUs);
}

DwrSec *
Dwarf::dwrGetSec (const char *sec_name)
{
  int secN = elf->elf_get_sec_num (sec_name);
  if (secN > 0)
    {
      Elf_Data *elfData = elf->elf_getdata (secN);
      if (elfData)
	return new DwrSec ((unsigned char *) elfData->d_buf, elfData->d_size,
			   elf->need_swap_endian,
			   elf->elf_getclass () == ELFCLASS32);
    }
  return NULL;
}

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;
  return Dwarf_string (DW_AT_MIPS_linkage_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 + cu_offset;
      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:
	  if (dwrTag.get_attr (DW_AT_abstract_origin))
	    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);
		}
	      if (get_linkage_name () == NULL)
		break;
	    }
	  func = append_Function (ctx);
	  if (func)
	    {
	      if (Stabs::is_fortran (ctx->module->lang_code) &&
		  streq (func->get_match_name (), NTXT ("MAIN")))
		ctx->fortranMAIN = func;
	      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 ();
	  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 + 1);
	      SourceFile *sf = mod->findSource (fname, true);
	      dwrCU->srcFiles->append (sf);
	    }

	  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);
	    }
	}
    }
  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);
}


// 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 + cu_offset;
      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;
	    if (dwrTag.get_attr (DW_AT_abstract_origin)
				 || dwrTag.get_attr (DW_AT_declaration))
	      ctx->func = NULL;
	    else
	      ctx->func = append_Function (ctx);
	    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 (Dwarf_cnt *ctx)
{
  char *outerName = ctx->name, *name, tmpname[2048];
  Function *func;
  char *fname = Dwarf_string (DW_AT_name);
  if (fname && outerName && !strchr (fname, '.'))
    {
      size_t outerlen = strlen (outerName);
      if (outerlen > 0 && outerName[outerlen - 1] == '_')
	{
	  outerlen--;
	  snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName);
	  snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname);
	}
      else
	snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname);
      name = tmpname;
      Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name);
    }
  else
    name = fname;

  char *link_name = get_linkage_name ();
  if (link_name == NULL)
    link_name = name;

  uint64_t pc = get_low_pc ();
  func = dwarf->stabs->append_Function (module, link_name, pc);
  if (func != NULL)
    {
      int lineno = (int) Dwarf_data (DW_AT_decl_line);
      func->set_match_name (name);
      if (lineno > 0)
	{
	  func->setLineFirst (lineno);
	  if (dwrLineReg == NULL)
	    dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
						   stmt_list_offset), comp_dir);
	  int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1;
	  SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno)
		  : module->getMainSrc ();
	  func->setDefSrc (sf);
	  func->pushSrcFile (func->def_source, 0);
	  func->popSrcFile ();
	}
    }
  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;
    }
}
