/* 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 <sys/param.h>

#include "util.h"
#include "Elf.h"
#include "Dwarf.h"
#include "stab.h"
#include "DbeSession.h"
#include "CompCom.h"
#include "Stabs.h"
#include "LoadObject.h"
#include "Module.h"
#include "Function.h"
#include "info.h"
#include "StringBuilder.h"
#include "DbeFile.h"
#include "StringMap.h"

#define DISASM_REL_NONE     0     /* symtab search only */
#define DISASM_REL_ONLY     1     /* relocation search only */
#define DISASM_REL_TARG     2     /* relocatoin then symtab */

///////////////////////////////////////////////////////////////////////////////
// class StabReader
class StabReader
{
public:
  StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec);
  ~StabReader () { };
  char *get_type_name (int t);
  char *get_stab (struct stab *np, bool comdat);
  void parse_N_OPT (Module *mod, char *str);
  int stabCnt;
  int stabNum;

private:
  Elf *elf;
  char *StabData;
  char *StabStrtab;
  char *StabStrtabEnd;
  int StrTabSize;
  int StabEntSize;
};

///////////////////////////////////////////////////////////////////////////////
// class Symbol

class Symbol
{
public:
  Symbol (Vector<Symbol*> *vec = NULL);

  ~Symbol ()
  {
    free (name);
  }

  inline Symbol *
  cardinal ()
  {
    return alias ? alias : this;
  }

  static void dump (Vector<Symbol*> *vec, char*msg);

  Function *func;
  Sp_lang_code lang_code;
  uint64_t value; // st_value used in sym_name()
  uint64_t save;
  int64_t size;
  uint64_t img_offset; // image offset in the ELF file
  char *name;
  Symbol *alias;
  int local_ind;
  int flags;
  bool defined;
};

Symbol::Symbol (Vector<Symbol*> *vec)
{
  func = NULL;
  lang_code = Sp_lang_unknown;
  value = 0;
  save = 0;
  size = 0;
  img_offset = 0;
  name = NULL;
  alias = NULL;
  local_ind = -1;
  flags = 0;
  defined = false;
  if (vec)
    vec->append (this);
}

void
Symbol::dump (Vector<Symbol*> *vec, char*msg)
{
  if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0)
    return;
  printf (NTXT ("======= Symbol::dump: %s =========\n"
		"         value |    img_offset     | flags|local_ind|\n"), msg);
  for (int i = 0; i < vec->size (); i++)
    {
      Symbol *sp = vec->fetch (i);
      printf (NTXT ("  %3d %8lld |0x%016llx |%5d |%8d |%s\n"),
	      i, (long long) sp->value, (long long) sp->img_offset, sp->flags,
	      sp->local_ind, sp->name ? sp->name : NTXT ("NULL"));
    }
  printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg);
}

// end of class Symbol
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// class Reloc
class Reloc
{
public:
  Reloc ();
  ~Reloc ();
  uint64_t type;
  uint64_t value;
  uint64_t addend;
  char *name;
};

Reloc::Reloc ()
{
  type = 0;
  value = 0;
  addend = 0;
  name = NULL;
}

Reloc::~Reloc ()
{
  free (name);
}
// end of class Reloc
///////////////////////////////////////////////////////////////////////////////

enum
{
  SYM_PLT       = 1 << 0,
  SYM_UNDEF     = 1 << 1
};

enum Section_type
{
  COMM1_SEC = 0x10000000,
  COMM_SEC  = 0x20000000,
  INFO_SEC  = 0x30000000,
  LOOP_SEC  = 0x40000000
};

struct cpf_stabs_t
{
  uint32_t type;    // Archive::AnalyzerInfoType
  uint32_t offset;  // offset in .__analyzer_info
  Module *module;   // table for appropriate Module
};

static char *get_info_com (int type, int32_t copy_inout);
static char *get_lp_com (unsigned hints, int parallel, char *dep);
static int ComCmp (const void *a, const void *b);
static ino64_t _src_inode = 0;
static char *_src_name;

// Comparing name
static int
SymNameCmp (const void *a, const void *b)
{
  Symbol *item1 = *((Symbol **) a);
  Symbol *item2 = *((Symbol **) b);
  return (item1->name == NULL) ? -1 :
	  (item2->name == NULL) ? 1 : strcmp (item1->name, item2->name);
}

// Comparing value: for sorting
static int
SymValueCmp (const void *a, const void *b)
{
  Symbol *item1 = *((Symbol **) a);
  Symbol *item2 = *((Symbol **) b);
  return (item1->value > item2->value) ? 1 :
	  (item1->value == item2->value) ? SymNameCmp (a, b) : -1;
}

// Comparing value: for searching (source name is always NULL)
static int
SymFindCmp (const void *a, const void *b)
{
  Symbol *item1 = *((Symbol **) a);
  Symbol *item2 = *((Symbol **) b);
  if (item1->value < item2->value)
    return -1;
  if (item1->value < item2->value + item2->size
      || item1->value == item2->value) // item2->size == 0
    return 0;
  return 1;
}

// Comparing value for sorting. It is used only for searching aliases.
static int
SymImgOffsetCmp (const void *a, const void *b)
{
  Symbol *item1 = *((Symbol **) a);
  Symbol *item2 = *((Symbol **) b);
  return (item1->img_offset > item2->img_offset) ? 1 :
	  (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1;
}

static int
RelValueCmp (const void *a, const void *b)
{
  Reloc *item1 = *((Reloc **) a);
  Reloc *item2 = *((Reloc **) b);
  return (item1->value > item2->value) ? 1 :
	  (item1->value == item2->value) ? 0 : -1;
}

Stabs *
Stabs::NewStabs (char *_path, char *lo_name)
{
  Stabs *stabs = new Stabs (_path, lo_name);
  if (stabs->status != Stabs::DBGD_ERR_NONE)
    {
      delete stabs;
      return NULL;
    }
  return stabs;
}

Stabs::Stabs (char *_path, char *_lo_name)
{
  path = dbe_strdup (_path);
  lo_name = dbe_strdup (_lo_name);
  SymLstByName = NULL;
  pltSym = NULL;
  SymLst = new Vector<Symbol*>;
  RelLst = new Vector<Reloc*>;
  RelPLTLst = new Vector<Reloc*>;
  LocalLst = new Vector<Symbol*>;
  LocalFile = new Vector<char*>;
  LocalFileIdx = new Vector<int>;
  last_PC_to_sym = NULL;
  dwarf = NULL;
  elfDbg = NULL;
  elfDis = NULL;
  stabsModules = NULL;
  textsz = 0;
  wsize = Wnone;
  st_check_symtab = st_check_relocs = false;
  status = DBGD_ERR_NONE;

  if (openElf (false) == NULL)
    return;
  switch (elfDis->elf_getclass ())
    {
    case ELFCLASS32:
      wsize = W32;
      break;
    case ELFCLASS64:
      wsize = W64;
      break;
    }
  isRelocatable = elfDis->elf_getehdr ()->e_type == ET_REL;
  for (unsigned int pnum = 0; pnum < elfDis->elf_getehdr ()->e_phnum; pnum++)
    {
      Elf_Internal_Phdr *phdr = elfDis->get_phdr (pnum);
      if (phdr->p_type == PT_LOAD && phdr->p_flags == (PF_R | PF_X))
	{
	  if (textsz == 0)
	    textsz = phdr->p_memsz;
	  else
	    {
	      textsz = 0;
	      break;
	    }
	}
    }
}

Stabs::~Stabs ()
{
  delete pltSym;
  delete SymLstByName;
  Destroy (SymLst);
  Destroy (RelLst);
  Destroy (RelPLTLst);
  Destroy (LocalFile);
  delete elfDis;
  delete dwarf;
  delete LocalLst;
  delete LocalFileIdx;
  delete stabsModules;
  free (path);
  free (lo_name);
}

Elf *
Stabs::openElf (char *fname, Stab_status &st)
{
  Elf::Elf_status elf_status;
  Elf *elf = Elf::elf_begin (fname, &elf_status);
  if (elf == NULL)
    {
      switch (elf_status)
	{
	case Elf::ELF_ERR_CANT_OPEN_FILE:
	case Elf::ELF_ERR_CANT_MMAP:
	case Elf::ELF_ERR_BIG_FILE:
	  st = DBGD_ERR_CANT_OPEN_FILE;
	  break;
	case Elf::ELF_ERR_BAD_ELF_FORMAT:
	default:
	  st = DBGD_ERR_BAD_ELF_FORMAT;
	  break;
	}
      return NULL;
    }
  if (elf->elf_version (EV_CURRENT) == EV_NONE)
    {
      // ELF library out of date
      delete elf;
      st = DBGD_ERR_BAD_ELF_LIB;
      return NULL;
    }

  Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr ();
  if (ehdrp == NULL)
    {
      // check machine
      delete elf;
      st = DBGD_ERR_BAD_ELF_FORMAT;
      return NULL;
    }
  switch (ehdrp->e_machine)
    {
    case EM_SPARC:
      platform = Sparc;
      break;
    case EM_SPARC32PLUS:
      platform = Sparcv8plus;
      break;
    case EM_SPARCV9:
      platform = Sparcv9;
      break;
    case EM_386:
      //    case EM_486:
      platform = Intel;
      break;
    case EM_X86_64:
      platform = Amd64;
      break;
    case EM_AARCH64:
      platform = Aarch64;
      break;
    default:
      platform = Unknown;
      break;
    }
  return elf;
}

Elf *
Stabs::openElf (bool dbg_info)
{
  if (status != DBGD_ERR_NONE)
    return NULL;
  if (elfDis == NULL)
    {
      elfDis = openElf (path, status);
      if (elfDis == NULL)
	return NULL;
    }
  if (!dbg_info)
    return elfDis;
  if (elfDbg == NULL)
    {
      elfDbg = elfDis->find_ancillary_files (lo_name);
      if (elfDbg == NULL)
	elfDbg = elfDis;
    }
  return elfDbg;
}

bool
Stabs::read_symbols (Vector<Function*> *functions)
{
  if (openElf (true) == NULL)
    return false;
  check_Symtab ();
  check_Relocs ();
  if (functions)
    {
      Function *fp;
      int index;
      Vec_loop (Function*, functions, index, fp)
      {
	fp->img_fname = path;
      }
    }
  return true;
}

char *
Stabs::sym_name (uint64_t target, uint64_t instr, int flag)
{
  long index;
  if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG)
    {
      Reloc *relptr = new Reloc;
      relptr->value = instr;
      index = RelLst->bisearch (0, -1, &relptr, RelValueCmp);
      if (index >= 0)
	{
	  delete relptr;
	  return RelLst->fetch (index)->name;
	}
      if (!is_relocatable ())
	{
	  relptr->value = target;
	  index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp);
	  if (index >= 0)
	    {
	      delete relptr;
	      return RelPLTLst->fetch (index)->name;
	    }
	}
      delete relptr;
    }
  if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ())
    {
      Symbol *sptr;
      sptr = map_PC_to_sym (target);
      if (sptr && sptr->value == target)
	return sptr->name;
    }
  return NULL;
}

Symbol *
Stabs::map_PC_to_sym (uint64_t pc)
{
  if (pc == 0)
    return NULL;
  if (last_PC_to_sym && last_PC_to_sym->value <= pc
      && last_PC_to_sym->value + last_PC_to_sym->size > pc)
    return last_PC_to_sym;
  Symbol *sym = new Symbol;
  sym->value = pc;
  long index = SymLst->bisearch (0, -1, &sym, SymFindCmp);
  delete sym;
  if (index >= 0)
    {
      last_PC_to_sym = SymLst->fetch (index)->cardinal ();
      return last_PC_to_sym;
    }
  return NULL;
}

Function *
Stabs::map_PC_to_func (uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions)
{
  int index;
  Function *func;
  Symbol *sptr = map_PC_to_sym (pc);
  if (sptr == NULL)
    return NULL;
  if (sptr->func)
    {
      low_pc = sptr->value;
      return sptr->func;
    }
  if (functions)
    {
      Vec_loop (Function*, functions, index, func)
      {
	if (func->img_offset == sptr->img_offset)
	  {
	    sptr->func = func->cardinal ();
	    low_pc = sptr->value;
	    return sptr->func;
	  }
      }
    }
  return NULL;
}

Stabs::Stab_status
Stabs::read_stabs (ino64_t srcInode, Module *module, Vector<ComC*> *comComs,
		   bool readDwarf)
{
  if (module)
    module->setIncludeFile (NULL);

  if (openElf (true) == NULL)
    return status;
  check_Symtab ();

  // read compiler commentary from .compcom1, .compcom,
  // .info, .loops, and .loopview sections
  if (comComs)
    {
      _src_inode = srcInode;
      _src_name = module && module->file_name ? get_basename (module->file_name) : NULL;
      if (!check_Comm (comComs))
	// .loops, and .loopview are now in .compcom
	check_Loop (comComs);

      // should not read it after .info goes into .compcom
      check_Info (comComs);
      comComs->sort (ComCmp);
    }

  // get stabs info
  Stab_status statusStabs = DBGD_ERR_NO_STABS;
#define SRC_LINE_STABS(sec, secStr, comdat) \
    if ((elfDbg->sec)  && (elfDbg->secStr) && \
	srcline_Stabs(module, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
	statusStabs = DBGD_ERR_NONE

  SRC_LINE_STABS (stabExcl, stabExclStr, false);
  SRC_LINE_STABS (stab, stabStr, false);
  SRC_LINE_STABS (stabIndex, stabIndexStr, true);

  // read Dwarf, if any sections found
  if (elfDbg->dwarf && readDwarf)
    {
      openDwarf ()->srcline_Dwarf (module);
      if (dwarf && dwarf->status == DBGD_ERR_NONE)
	return DBGD_ERR_NONE;
    }
  return statusStabs;
}

static int
ComCmp (const void *a, const void *b)
{
  ComC *item1 = *((ComC **) a);
  ComC *item2 = *((ComC **) b);
  return (item1->line > item2->line) ? 1 :
	  (item1->line < item2->line) ? -1 :
	  (item1->sec > item2->sec) ? 1 :
	  (item1->sec < item2->sec) ? -1 : 0;
}

static int
check_src_name (char *srcName)
{
  if (_src_name && srcName && streq (_src_name, get_basename (srcName)))
    return 1;
  if (_src_inode == (ino64_t) - 1)
    return 0;
  DbeFile *dbeFile = dbeSession->getDbeFile (srcName, DbeFile::F_SOURCE);
  char *path = dbeFile->get_location ();
  return (path == NULL || dbeFile->sbuf.st_ino != _src_inode) ? 0 : 1;
}

bool
Stabs::check_Comm (Vector<ComC*> *comComs)
{
  int sz = comComs->size ();
  Elf *elf = openElf (true);
  if (elf == NULL)
    return false;

  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
    {
      char *name = elf->get_sec_name (sec);
      if (name == NULL)
	continue;
      Section_type sec_type;
      if (streq (name, NTXT (".compcom")))
	sec_type = COMM_SEC;
      else if (streq (name, NTXT (".compcom1")))
	sec_type = COMM1_SEC;
      else
	continue;

      // find header, set messages id & visibility if succeed
      CompComment *cc = new CompComment (elf, sec);
      int cnt = cc->compcom_open ((CheckSrcName) check_src_name);
      // process messages
      for (int index = 0; index < cnt; index++)
	{
	  int visible;
	  compmsg msg;
	  char *str = cc->compcom_format (index, &msg, visible);
	  if (str)
	    {
	      ComC *citem = new ComC;
	      citem->sec = sec_type + index;
	      citem->type = msg.msg_type;
	      citem->visible = visible;
	      citem->line = (msg.lineno < 1) ? 1 : msg.lineno;
	      citem->com_str = str;
	      comComs->append (citem);
	    }
	}
      delete cc;
    }
  return (sz != comComs->size ());
}

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

void
Stabs::check_AnalyzerInfo ()
{
  Elf *elf = openElf (true);
  if ((elf == NULL) || (elf->analyzerInfo == 0))
    {
      Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo: Null AnalyzerInfo section\n"));
      return; // inappropriate, but ignored anyway
    }
  Elf_Data *data = elf->elf_getdata (elf->analyzerInfo);
  int InfoSize = (int) data->d_size;
  char *InfoData = (char *) data->d_buf;
  int InfoAlign = (int) data->d_align;
  AnalyzerInfoHdr h;
  unsigned infoHdr_sz = sizeof (AnalyzerInfoHdr);
  int table, entry;
  int read = 0;
  Module *mitem;
  int index = 0;
  if (InfoSize <= 0)
    return;
  uint64_t baseAddr = elf->get_baseAddr ();
  Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo size=%d @0x%lx (align=%d) base=0x%llx\n"),
	   InfoSize, (ul_t) InfoData, InfoAlign, (long long) baseAddr);
  Dprintf (DEBUG_STABS, NTXT ("analyzerInfoMap has %lld entries\n"), (long long) analyzerInfoMap.size ());
  if (analyzerInfoMap.size () == 0)
    {
      Dprintf (DEBUG_STABS, NTXT ("No analyzerInfoMap available!\n"));
      return;
    }

  // verify integrity of analyzerInfoMap before reading analyzerInfo
  unsigned count = 0;
  Module *lastmod = NULL;
  for (index = 0; index < analyzerInfoMap.size (); index++)
    {
      cpf_stabs_t map = analyzerInfoMap.fetch (index);
      if (map.type > 3)
	{
	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains table of unknown type %d for %s\n"),
		   map.type, map.module->get_name ());
	  return;
	}
      if (map.module != lastmod)
	{
	  if (lastmod != NULL)
	    Dprintf (DEBUG_STABS, "analyzerInfo contains %d 0x0 offset tables for %s\n",
		     count, lastmod->get_name ());
	  count = 0;
	}
      count += (map.offset == 0x0); // only check for 0x0 tables for now
      if (count > 4)
	{
	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains too many 0x0 offset tables for %s\n"),
		   map.module->get_name ());
	  return;
	}
      lastmod = map.module;
    }

  index = 0;
  while ((index < analyzerInfoMap.size ()) && (read < InfoSize))
    {
      for (table = 0; table < 3; table++)
	{ // memory operations (ld, st, prefetch)
	  // read the table header
	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
	  InfoData += infoHdr_sz;
	  read += infoHdr_sz;

	  // use map for appropriate module
	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
	  index++;
	  mitem = map.module;
	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
		   "text_labelref=0x%08llx entries=%d version=%d\n"
		   "itype %d offset=0x%04x module=%s\n", table, read,
		   (long long) (h.text_labelref - baseAddr), h.entries,
		   h.version, map.type, map.offset, map.module->get_name ());
	  // read the table entries
	  for (entry = 0; entry < h.entries; entry++)
	    {
	      memop_info_t *m = new memop_info_t;
	      unsigned memop_info_sz = sizeof (memop_info_t);
	      memcpy ((void *) m, (const void *) InfoData, memop_info_sz);
	      InfoData += memop_info_sz;
	      read += memop_info_sz;
	      m->offset += (uint32_t) (h.text_labelref - baseAddr);
	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n"),
		       entry, table, m->offset, m->id, m->signature, m->datatype_id);
	      switch (table)
		{
		case CPF_INSTR_TYPE_LD:
		  mitem->ldMemops.append (m);
		  break;
		case CPF_INSTR_TYPE_ST:
		  mitem->stMemops.append (m);
		  break;
		case CPF_INSTR_TYPE_PREFETCH:
		  mitem->pfMemops.append (m);
		  break;
		}
	    }
	  // following re-alignment should be redundant
	  //InfoData+=(read%InfoAlign); read+=(read%InfoAlign); // re-align
	}
      for (table = 3; table < 4; table++)
	{ // branch targets
	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
	  InfoData += infoHdr_sz;
	  read += infoHdr_sz;

	  // use map for appropriate module
	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
	  index++;
	  mitem = map.module;
	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
		   "text_labelref=0x%08llx entries=%d version=%d\n"
		   "itype %d offset=0x%04x module=%s\n", table, read,
		   (long long) (h.text_labelref - baseAddr), h.entries,
		   h.version, map.type, map.offset, map.module->get_name ());
	  for (entry = 0; entry < h.entries; entry++)
	    {
	      target_info_t *t = new target_info_t;
	      unsigned target_info_sz = sizeof (target_info_t);
	      memcpy ((void *) t, (const void *) InfoData, target_info_sz);
	      InfoData += target_info_sz;
	      read += target_info_sz;
	      t->offset += (uint32_t) (h.text_labelref - baseAddr);
	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x\n"), entry,
		       table, t->offset);
	      // the list of branch targets needs to be in offset sorted order
	      // and doing it here before archiving avoids the need to do it
	      // each time the archive is read.
	      mitem->bTargets.incorporate (t, targetOffsetCmp);
	    }
	  Dprintf (DEBUG_STABS, NTXT ("bTargets for %s has %lld items (last=0x%04x)\n"),
		   mitem->get_name (), (long long) mitem->bTargets.size (),
		   (mitem->bTargets.fetch (mitem->bTargets.size () - 1))->offset);
	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
		   read, (ul_t) InfoData);
	  InfoData += (read % InfoAlign);
	  read += (read % InfoAlign); // re-align
	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
		   read, (ul_t) InfoData);
	}
      Dprintf (DEBUG_STABS, "Stabs::check_AnalyzerInfo bytes read=%lld (index=%lld/%lld)\n",
	       (long long) read, (long long) index,
	       (long long) analyzerInfoMap.size ());
    }
}

void
Stabs::check_Info (Vector<ComC*> *comComs)
{
  Elf *elf = openElf (true);
  if (elf == NULL || elf->info == 0)
    return;
  Elf_Data *data = elf->elf_getdata (elf->info);
  uint64_t InfoSize = data->d_size;
  char *InfoData = (char *) data->d_buf;
  bool get_src = false;
  for (int h_num = 0; InfoSize; h_num++)
    {
      if (InfoSize < sizeof (struct info_header))
	return;
      struct info_header *h = (struct info_header*) InfoData;
      if (h->endian != '\0' || h->magic[0] != 'S' || h->magic[1] != 'U'
	  || h->magic[2] != 'N')
	return;
      if (h->len < InfoSize || h->len < sizeof (struct info_header) || (h->len & 3))
	return;

      char *fname = InfoData + sizeof (struct info_header);
      InfoData += h->len;
      InfoSize -= h->len;
      get_src = check_src_name (fname);
      for (uint32_t e_num = 0; e_num < h->cnt; ++e_num)
	{
	  if (InfoSize < sizeof (struct entry_header))
	    return;
	  struct entry_header *e = (struct entry_header*) InfoData;
	  if (InfoSize < e->len)
	    return;
	  int32_t copy_inout = 0;
	  if (e->len > sizeof (struct entry_header))
	    if (e->type == F95_COPYINOUT)
	      copy_inout = *(int32_t*) (InfoData + sizeof (struct entry_header));
	  InfoData += e->len;
	  InfoSize -= e->len;
	  if (get_src)
	    {
	      ComC *citem = new ComC;
	      citem->sec = INFO_SEC + h_num;
	      citem->type = e->msgnum & 0xFFFFFF;
	      citem->visible = CCMV_ALL;
	      citem->line = e->line;
	      citem->com_str = get_info_com (citem->type, copy_inout);
	      comComs->append (citem);
	    }
	}
      if (get_src)
	break;
    }
}

static char *
get_info_com (int type, int32_t copy_inout)
{
  switch (type)
    {
    case 1:
      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in -- loop(s) inserted"),
			  copy_inout);
    case 2:
      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-out -- loop(s) inserted"),
			  copy_inout);
    case 3:
      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in and a copy-out -- loops inserted"),
			  copy_inout);
    case 4:
      return dbe_strdup (GTXT ("Alignment of variables in common block may cause performance degradation"));
    case 5:
      return dbe_strdup (GTXT ("DO statement bounds lead to no executions of the loop"));
    default:
      return dbe_strdup (NTXT (""));
    }
}

void
Stabs::check_Loop (Vector<ComC*> *comComs)
{
  Elf *elf = openElf (true);
  if (elf == NULL)
    return;

  StringBuilder sb;
  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
    {
      char *name = elf->get_sec_name (sec);
      if (name == NULL)
	continue;
      if (!streq (name, NTXT (".loops")) && !streq (name, NTXT (".loopview")))
	continue;

      Elf_Data *data = elf->elf_getdata (sec);
      size_t LoopSize = (size_t) data->d_size, len;
      char *LoopData = (char *) data->d_buf;
      int remainder, i;
      char src[2 * MAXPATHLEN], buf1[MAXPATHLEN], buf2[MAXPATHLEN];
      char **dep_str = NULL;
      bool get_src = false;
      while ((LoopSize > 0) && !get_src &&
	     (strncmp (LoopData, NTXT ("Source:"), 7) == 0))
	{
	  // The first three items in a .loops subsection are three strings.
	  //	Source: ...
	  //	Version: ...
	  //	Number of loops: ...
	  sscanf (LoopData, NTXT ("%*s%s"), src);
	  len = strlen (LoopData) + 1;
	  LoopData += len;
	  LoopSize -= len;
	  sscanf (LoopData, NTXT ("%*s%*s%s"), buf1);
	  //	double version   = atof(buf1);
	  len = strlen (LoopData) + 1;
	  LoopData += len;
	  LoopSize -= len;
	  get_src = check_src_name (src);
	  sscanf (LoopData, NTXT ("%*s%*s%*s%s%s"), buf1, buf2);
	  int n_loop = atoi (buf1);
	  int n_depend = atoi (buf2);
	  len = strlen (LoopData) + 1;
	  LoopData += len;
	  LoopSize -= len;
	  if (get_src && (n_loop > 0))
	    {
	      dep_str = new char*[n_loop];
	      for (i = 0; i < n_loop; i++)
		dep_str[i] = NULL;
	    }

	  // printf("Source: %s\nVersion: %f\nLoop#: %d\nDepend#: %d\n",
	  //	src, version, n_loop, n_depend);

	  // Read in the strings that contain the list of variables that cause
	  // data dependencies inside of loops. Not every loop has such a list
	  // of variables.
	  //
	  //	Example: if loop #54 has data dependencies caused by the
	  //	variables named i, j and foo, then the string that represents
	  //	this in the .loops section looks like this:
	  //
	  //	.asciz "54:i.j.foo"
	  //
	  //	The variable names are delimited with .
	  //
	  //	For now, store these strings in an array, and add them into
	  //	the loop structure when we read in the numeric loop info
	  //	(that's what we read in next.)
	  //
	  // printf("\tDependenncies:\n");
	  for (i = 0; i < n_depend; i++)
	    {
	      len = strlen (LoopData) + 1;
	      LoopData += len;
	      LoopSize -= len;
	      if (dep_str != NULL)
		{
		  char *dep_buf1 = dbe_strdup (LoopData);
		  char *ptr = strtok (dep_buf1, NTXT (":"));
		  if (ptr != NULL)
		    {
		      int index = atoi (ptr);
		      bool dep_first = true;
		      sb.setLength (0);
		      while ((ptr = strtok (NULL, NTXT (", "))) != NULL)
			{
			  if (dep_first)
			    dep_first = false;
			  else
			    sb.append (NTXT (", "));
			  sb.append (ptr);
			}
		      if (sb.length () > 0 && index < n_loop)
			dep_str[index] = sb.toString ();
		    }
		  free (dep_buf1);
		}
	    }

	  // Adjust Data pointer so that it is word aligned.
	  remainder = (int) (((unsigned long) LoopData) % 4);
	  if (remainder != 0)
	    {
	      len = 4 - remainder;
	      LoopData += len;
	      LoopSize -= len;
	    }

	  // Read in the loop info, one loop at a time.
	  for (i = 0; i < n_loop; i++)
	    {
	      int loopid = *((int *) LoopData);
	      LoopData += 4;
	      int line_no = *((int *) LoopData);
	      if (line_no < 1) // compiler has trouble on this
		line_no = 1;
	      LoopData += 4;
	      //	    int nest = *((int *) LoopData);
	      LoopData += 4;
	      int parallel = *((int *) LoopData);
	      LoopData += 4;
	      unsigned hints = *((unsigned *) LoopData);
	      LoopData += 4;
	      //	    int count = *((int *) LoopData);
	      LoopData += 4;
	      LoopSize -= 24;
	      if (!get_src || (loopid >= n_loop))
		continue;
	      ComC *citem = new ComC;
	      citem->sec = LOOP_SEC + i;
	      citem->type = hints;
	      citem->visible = CCMV_ALL;
	      citem->line = line_no;
	      citem->com_str = get_lp_com (hints, parallel, dep_str[loopid]);
	      comComs->append (citem);
	    }
	  if (dep_str)
	    {
	      for (i = 0; i < n_loop; i++)
		free (dep_str[i]);
	      delete[] dep_str;
	      dep_str = NULL;
	    }
	}
    }
}

static char *
get_lp_com (unsigned hints, int parallel, char *dep)
{
  StringBuilder sb;
  if (parallel == -1)
    sb.append (GTXT ("Loop below is serial, but parallelizable: "));
  else if (parallel == 0)
    sb.append (GTXT ("Loop below is not parallelized: "));
  else
    sb.append (GTXT ("Loop below is parallelized: "));
  switch (hints)
    {
    case 0:
      // No loop mesg will print
      // strcat(com, GTXT("no hint available"));
      break;
    case 1:
      sb.append (GTXT ("loop contains procedure call"));
      break;
    case 2:
      sb.append (GTXT ("compiler generated two versions of this loop"));
      break;
    case 3:
      {
	StringBuilder sb_tmp;
	sb_tmp.sprintf (GTXT ("the variable(s) \"%s\" cause a data dependency in this loop"),
			dep ? dep : GTXT ("<Unknown>"));
	sb.append (&sb_tmp);
      }
      break;
    case 4:
      sb.append (GTXT ("loop was significantly transformed during optimization"));
      break;
    case 5:
      sb.append (GTXT ("loop may or may not hold enough work to be profitably parallelized"));
      break;
    case 6:
      sb.append (GTXT ("loop was marked by user-inserted pragma"));
      break;
    case 7:
      sb.append (GTXT ("loop contains multiple exits"));
      break;
    case 8:
      sb.append (GTXT ("loop contains I/O, or other function calls, that are not MT safe"));
      break;
    case 9:
      sb.append (GTXT ("loop contains backward flow of control"));
      break;
    case 10:
      sb.append (GTXT ("loop may have been distributed"));
      break;
    case 11:
      sb.append (GTXT ("two loops or more may have been fused"));
      break;
    case 12:
      sb.append (GTXT ("two or more loops may have been interchanged"));
      break;
    default:
      break;
    }
  return sb.toString ();
}

StabReader::StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec)
{
  stabCnt = -1;
  stabNum = 0;
  if (_elf == NULL)
    return;
  elf = _elf;

  // Get ELF data
  Elf_Data *data = elf->elf_getdata (StabSec);
  if (data == NULL)
    return;
  uint64_t stabSize = data->d_size;
  StabData = (char *) data->d_buf;
  Elf_Internal_Shdr *shdr = elf->get_shdr (StabSec);
  if (shdr == NULL)
    return;

  // GCC bug: sh_entsize is 20 for 64 apps on Linux
  StabEntSize = (platform == Amd64 || platform == Sparcv9) ? 12 : (unsigned) shdr->sh_entsize;
  if (stabSize == 0 || StabEntSize == 0)
    return;
  data = elf->elf_getdata (StabStrSec);
  if (data == NULL)
    return;
  shdr = elf->get_shdr (StabStrSec);
  if (shdr == NULL)
    return;
  StabStrtab = (char *) data->d_buf;
  StabStrtabEnd = StabStrtab + shdr->sh_size;
  StrTabSize = 0;
  stabCnt = (int) (stabSize / StabEntSize);
}

char *
StabReader::get_stab (struct stab *np, bool comdat)
{
  struct stab *stbp = (struct stab *) (StabData + stabNum * StabEntSize);
  stabNum++;
  *np = *stbp;
  np->n_desc = elf->decode (stbp->n_desc);
  np->n_strx = elf->decode (stbp->n_strx);
  np->n_value = elf->decode (stbp->n_value);
  switch (np->n_type)
    {
    case N_UNDF:
    case N_ILDPAD:
      // Start of new stab section (or padding)
      StabStrtab += StrTabSize;
      StrTabSize = np->n_value;
    }

  char *str = NULL;
  if (np->n_strx)
    {
      if (comdat && np->n_type == N_FUN && np->n_other == 1)
	{
	  if (np->n_strx == 1)
	    StrTabSize++;
	  str = StabStrtab + StrTabSize;
	  // Each COMDAT string must be sized to find the next string:
	  StrTabSize += strlen (str) + 1;
	}
      else
	str = StabStrtab + np->n_strx;
      if (str >= StabStrtabEnd)
	str = NULL;
    }
  if (DEBUG_STABS)
    {
      char buf[128];
      char *s = get_type_name (np->n_type);
      if (s == NULL)
	{
	  snprintf (buf, sizeof (buf), NTXT ("n_type=%d"), np->n_type);
	  s = buf;
	}
      if (str)
	{
	  Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabs \"%s\",%s,0x%x,0x%x,0x%x\n"),
		   stabNum - 1, str, s, (int) np->n_other, (int) np->n_desc,
		   (int) np->n_value);
	}
      else
	Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabn %s,0x%x,0x%x,0x%x\n"),
		 stabNum - 1, s, (int) np->n_other, (int) np->n_desc,
		 (int) np->n_value);
    }
  return str;
}

void
StabReader::parse_N_OPT (Module *mod, char *str)
{
  if (mod == NULL || str == NULL)
      return;
  for (char *s = str; 1; s++)
    {
      switch (*s)
	{
	case 'd':
	  if (s[1] == 'i' && s[2] == ';')
	    {
	      delete mod->dot_o_file;
	      mod->dot_o_file = NULL;
	    }
	  break;
	case 's':
	  if ((s[1] == 'i' || s[1] == 'n') && s[2] == ';')
	    {
	      delete mod->dot_o_file;
	      mod->dot_o_file = NULL;
	    }
	  break;
	}
      s = strchr (s, ';');
      if (s == NULL)
	break;
    }
}

Stabs::Stab_status
Stabs::srcline_Stabs (Module *module, unsigned int StabSec,
		      unsigned int StabStrSec, bool comdat)
{
  StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec);
  int tot = stabReader->stabCnt;
  if (tot < 0)
    {
      delete stabReader;
      return DBGD_ERR_NO_STABS;
    }
  int n, lineno;
  char *sbase, *n_so = NTXT (""), curr_src[2 * MAXPATHLEN];
  Function *newFunc;
  Sp_lang_code _lang_code = module->lang_code;
  Vector<Function*> *functions = module->functions;
  bool no_stabs = true;
  *curr_src = '\0';
  Function *func = NULL;
  int phase = 0;
  int stabs_level = 0;
  int xline = 0;

  // Find module
  for (n = 0; n < tot; n++)
    {
      struct stab stb;
      char *str = stabReader->get_stab (&stb, comdat);
      if (stb.n_type == N_UNDF)
	phase = 0;
      else if (stb.n_type == N_SO)
	{
	  if (str == NULL || *str == '\0')
	    continue;
	  if (phase == 0)
	    {
	      phase = 1;
	      n_so = str;
	      continue;
	    }
	  phase = 0;
	  sbase = str;
	  if (*str == '/')
	    {
	      if (streq (sbase, module->file_name))
		break;
	    }
	  else
	    {
	      size_t last = strlen (n_so);
	      if (n_so[last - 1] == '/')
		last--;
	      if (strncmp (n_so, module->file_name, last) == 0 &&
		  module->file_name[last] == '/' &&
		  streq (sbase, module->file_name + last + 1))
		break;
	    }
	}
    }
  if (n >= tot)
    {
      delete stabReader;
      return DBGD_ERR_NO_STABS;
    }

  Include *includes = new Include;
  includes->new_src_file (module->getMainSrc (), 0, NULL);
  module->hasStabs = true;
  *curr_src = '\0';
  phase = 0;
  for (n++; n < tot; n++)
    {
      struct stab stb;
      char *str = stabReader->get_stab (&stb, comdat);
      int n_desc = (int) ((unsigned short) stb.n_desc);
      switch (stb.n_type)
	{
	case N_UNDF:
	case N_SO:
	case N_ENDM:
	  n = tot;
	  break;
	case N_ALIAS:
	  if (str == NULL)
	    break;
	  if (is_fortran (_lang_code))
	    {
	      char *p = strchr (str, ':');
	      if (p && streq (p + 1, NTXT ("FMAIN")))
		{
		  Function *afunc = find_func (NTXT ("MAIN"), functions, true);
		  if (afunc)
		    afunc->set_match_name (dbe_strndup (str, p - str));
		  break;
		}
	    }
	case N_FUN:
	case N_OUTL:
	  if (str == NULL)
	    break;
	  if (*str == '@')
	    {
	      str++;
	      if (*str == '>' || *str == '<')
		str++;
	    }
	  if (stabs_level != 0)
	    break;

	  // find address of the enclosed function
	  newFunc = find_func (str, functions, is_fortran (_lang_code));
	  if (newFunc == NULL)
	    break;
	  if (func)
	    while (func->popSrcFile ())
	      ;
	  func = newFunc;

	  // First line info to cover function from the beginning
	  lineno = xline + n_desc;
	  if (lineno > 0)
	    {
	      // Set the chain of includes for the new function
	      includes->push_src_files (func);
	      func->add_PC_info (0, lineno);
	      no_stabs = false;
	    }
	  break;
	case N_ENTRY:
	  break;
	case N_CMDLINE:
	  if (str && !module->comp_flags)
	    {
	      char *comp_flags = strchr (str, ';');
	      if (comp_flags)
		{
		  module->comp_flags = dbe_strdup (comp_flags + 1);
		  module->comp_dir = dbe_strndup (str, comp_flags - str);
		}
	    }
	  break;
	case N_LBRAC:
	  stabs_level++;
	  break;
	case N_RBRAC:
	  stabs_level--;
	  break;
	case N_XLINE:
	  xline = n_desc << 16;
	  break;
	case N_SLINE:
	  if (func == NULL)
	    break;
	  no_stabs = false;
	  lineno = xline + n_desc;
	  if (func->line_first <= 0)
	    {
	      // Set the chain of includes for the new function
	      includes->push_src_files (func);
	      func->add_PC_info (0, lineno);
	      break;
	    }
	  if (func->curr_srcfile == NULL)
	    includes->push_src_files (func);
	  if (func->line_first != lineno ||
	      !streq (curr_src, func->getDefSrc ()->get_name ()))
	    func->add_PC_info (stb.n_value, lineno);
	  break;
	case N_OPT:
	  if ((str != NULL) && streq (str, NTXT ("gcc2_compiled.")))
	    _lang_code = Sp_lang_gcc;
	  switch (elfDbg->elf_getehdr ()->e_type)
	    {
	    case ET_EXEC:
	    case ET_DYN:
	      // set the real object timestamp from the executable's N_OPT stab
	      // due to bug #4796329
	      module->real_timestamp = stb.n_value;
	      break;
	    default:
	      module->curr_timestamp = stb.n_value;
	      break;
	    }
	  break;
	case N_GSYM:
	  if ((str == NULL) || strncmp (str, NTXT ("__KAI_K"), 7))
	    break;
	  str += 7;
	  if (!strncmp (str, NTXT ("CC_"), 3))
	    _lang_code = Sp_lang_KAI_KCC;
	  else if (!strncmp (str, NTXT ("cc_"), 3))
	    _lang_code = Sp_lang_KAI_Kcc;
	  else if (!strncmp (str, NTXT ("PTS_"), 4) &&
		   (_lang_code != Sp_lang_KAI_KCC) &&
		   (_lang_code != Sp_lang_KAI_Kcc))
	    _lang_code = Sp_lang_KAI_KPTS;
	  break;
	case N_BINCL:
	  includes->new_include_file (module->setIncludeFile (str), func);
	  break;
	case N_EINCL:
	  includes->end_include_file (func);
	  break;
	case N_SOL:
	  if (str == NULL)
	    break;
	  lineno = xline + n_desc;
	  if (lineno > 0 && func && func->line_first <= 0)
	    {
	      includes->push_src_files (func);
	      func->add_PC_info (0, lineno);
	      no_stabs = false;
	    }
	  if (streq (sbase, str))
	    {
	      module->setIncludeFile (NULL);
	      snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
	      includes->new_src_file (module->getMainSrc (), lineno, func);
	    }
	  else
	    {
	      if (streq (sbase, get_basename (str)))
		{
		  module->setIncludeFile (NULL);
		  snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
		}
	      else
		{
		  if (*str == '/')
		    snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), str);
		  else
		    {
		      size_t last = strlen (n_so);
		      if (last == 0 || n_so[last - 1] != '/')
			snprintf (curr_src, sizeof (curr_src), NTXT ("%s/%s"), n_so, str);
		      else
			snprintf (curr_src, sizeof (curr_src), NTXT ("%s%s"), n_so, str);
		    }
		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
		}
	    }
	  break;
	}
    }
  delete includes;
  delete stabReader;
  return no_stabs ? DBGD_ERR_NO_STABS : DBGD_ERR_NONE;
}//srcline_Stabs

static bool
cmp_func_name (char *fname, size_t len, char *name, bool fortran)
{
  return (strncmp (name, fname, len) == 0
	  && (name[len] == 0
	      || (fortran && name[len] == '_' && name[len + 1] == 0)));
}

Function *
Stabs::find_func (char *fname, Vector<Function*> *functions, bool fortran, bool inner_names)
{
  char *arg, *name;
  Function *item;
  int index;
  size_t len;

  len = strlen (fname);
  arg = strchr (fname, ':');
  if (arg != NULL)
    {
      if (arg[1] == 'P') // Prototype for function
	return NULL;
      len -= strlen (arg);
    }

  Vec_loop (Function*, functions, index, item)
  {
    name = item->get_mangled_name ();
    if (cmp_func_name (fname, len, name, fortran))
      return item->cardinal ();
  }

  if (inner_names)
    {
      // Dwarf subprograms may only have plain (non-linker) names
      // Retry with inner names only

      Vec_loop (Function*, functions, index, item)
      {
	name = strrchr (item->get_mangled_name (), '.');
	if (!name) continue;
	name++;
	if (cmp_func_name (fname, len, name, fortran))
	  return item->cardinal ();
      }
    }
  return NULL;
}

Map<const char*, Symbol*> *
Stabs::get_elf_symbols ()
{
  Elf *elf = openElf (false);
  if (elf->elfSymbols == NULL)
    {
      Map<const char*, Symbol*> *elfSymbols = new StringMap<Symbol*>(128, 128);
      elf->elfSymbols = elfSymbols;
      for (int i = 0, sz = SymLst ? SymLst->size () : 0; i < sz; i++)
	{
	  Symbol *sym = SymLst->fetch (i);
	  elfSymbols->put (sym->name, sym);
	}
    }
  return elf->elfSymbols;
}

void
Stabs::read_dwarf_from_dot_o (Module *mod)
{
  Dprintf (DEBUG_STABS, NTXT ("stabsModules: %s\n"), STR (mod->get_name ()));
  Vector<Module*> *mods = mod->dot_o_file->seg_modules;
  char *bname = get_basename (mod->get_name ());
  for (int i1 = 0, sz1 = mods ? mods->size () : 0; i1 < sz1; i1++)
    {
      Module *m = mods->fetch (i1);
      Dprintf (DEBUG_STABS, NTXT ("  MOD: %s\n"), STR (m->get_name ()));
      if (dbe_strcmp (bname, get_basename (m->get_name ())) == 0)
	{
	  mod->indexStabsLink = m;
	  m->indexStabsLink = mod;
	  break;
	}
    }
  if (mod->indexStabsLink)
    {
      mod->dot_o_file->objStabs->openDwarf ()->srcline_Dwarf (mod->indexStabsLink);
      Map<const char*, Symbol*> *elfSymbols = get_elf_symbols ();
      Vector<Function*> *funcs = mod->indexStabsLink->functions;
      for (int i1 = 0, sz1 = funcs ? funcs->size () : 0; i1 < sz1; i1++)
	{
	  Function *f1 = funcs->fetch (i1);
	  Symbol *sym = elfSymbols->get (f1->get_mangled_name ());
	  if (sym == NULL)
	    continue;
	  Dprintf (DEBUG_STABS, NTXT ("  Symbol: %s func=%p\n"), STR (sym->name), sym->func);
	  Function *f = sym->func;
	  if (f->indexStabsLink)
	    continue;
	  f->indexStabsLink = f1;
	  f1->indexStabsLink = f;
	  f->copy_PCInfo (f1);
	}
    }
}

Stabs::Stab_status
Stabs::read_archive (LoadObject *lo)
{
  if (openElf (true) == NULL)
    return status;
  check_Symtab ();
  if (elfDbg->dwarf)
    openDwarf ()->archive_Dwarf (lo);

  // get Module/Function lists from stabs info
  Stab_status statusStabs = DBGD_ERR_NO_STABS;
#define ARCHIVE_STABS(sec, secStr, comdat) \
    if ((elfDbg->sec) != 0  && (elfDbg->secStr) != 0 && \
	archive_Stabs(lo, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
	statusStabs = DBGD_ERR_NONE

  // prefer index stabs (where they exist) since they're most appropriate
  // for loadobjects and might have N_CPROF stabs for ABS/CPF
  ARCHIVE_STABS (stabIndex, stabIndexStr, true);
  ARCHIVE_STABS (stabExcl, stabExclStr, false);
  ARCHIVE_STABS (stab, stabStr, false);

  // Add all unassigned functions to the <unknown> module
  Symbol *sitem, *alias;
  int index;
  Vec_loop (Symbol*, SymLst, index, sitem)
  {
    if (sitem->func || (sitem->size == 0) || (sitem->flags & SYM_UNDEF))
      continue;
    alias = sitem->alias;
    if (alias)
      {
	if (alias->func == NULL)
	  {
	    alias->func = createFunction (lo, lo->noname, alias);
	    alias->func->alias = alias->func;
	  }
	if (alias != sitem)
	  {
	    sitem->func = createFunction (lo, alias->func->module, sitem);
	    sitem->func->alias = alias->func;
	  }
      }
    else
      sitem->func = createFunction (lo, lo->noname, sitem);
  }
  if (pltSym)
    {
      pltSym->func = createFunction (lo, lo->noname, pltSym);
      pltSym->func->flags |= FUNC_FLAG_PLT;
    }

  // need Module association, so this must be done after handling Modules
  check_AnalyzerInfo ();

  if (dwarf && dwarf->status == DBGD_ERR_NONE)
    return DBGD_ERR_NONE;
  return statusStabs;
}//read_archive

Function *
Stabs::createFunction (LoadObject *lo, Module *module, Symbol *sym)
{
  Function *func = dbeSession->createFunction ();
  func->module = module;
  func->img_fname = path;
  func->img_offset = (off_t) sym->img_offset;
  func->save_addr = sym->save;
  func->size = (uint32_t) sym->size;
  func->set_name (sym->name);
  func->elfSym = sym;
  module->functions->append (func);
  lo->functions->append (func);
  return func;
}

void
Stabs::fixSymtabAlias ()
{
  int ind, i, k;
  Symbol *sym, *bestAlias;
  SymLst->sort (SymImgOffsetCmp);
  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 = sym->img_offset - bestAlias->img_offset;
	  continue;
	}

      // Find a "best" alias
      size_t bestLen = strlen (bestAlias->name);
      int64_t 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;
	  size_t len = strlen (sym->name);
	  if (len < bestLen)
	    {
	      bestAlias = sym;
	      bestLen = len;
	    }
	}
      for (; i < k; i++)
	{
	  sym = SymLst->fetch (i);
	  sym->alias = bestAlias;
	  sym->size = maxSize;
	}
      i--;
    }
}

void
Stabs::check_Symtab ()
{
  if (st_check_symtab)
    return;
  st_check_symtab = true;

  Elf *elf = openElf (true);
  if (elf == NULL)
    return;
  if (elfDis->plt != 0)
    {
      Elf_Internal_Shdr *shdr = elfDis->get_shdr (elfDis->plt);
      if (shdr)
	{
	  pltSym = new Symbol ();
	  pltSym->value = shdr->sh_addr;
	  pltSym->size = shdr->sh_size;
	  pltSym->img_offset = shdr->sh_offset;
	  pltSym->name = dbe_strdup (NTXT ("@plt"));
	  pltSym->flags |= SYM_PLT;
	}
    }
  if (elf->symtab)
    readSymSec (elf->symtab, elf);
  else
    {
      readSymSec (elf->SUNW_ldynsym, elf);
      readSymSec (elf->dynsym, elf);
    }
}

void
Stabs::readSymSec (unsigned int sec, Elf *elf)
{
  Symbol *sitem;
  Sp_lang_code local_lcode;
  if (sec == 0)
    return;
  // Get ELF data
  Elf_Data *data = elf->elf_getdata (sec);
  if (data == NULL)
    return;
  uint64_t SymtabSize = data->d_size;
  Elf_Internal_Shdr *shdr = elf->get_shdr (sec);

  if ((SymtabSize == 0) || (shdr->sh_entsize == 0))
    return;
  Elf_Data *data_str = elf->elf_getdata (shdr->sh_link);
  if (data_str == NULL)
    return;
  char *Strtab = (char *) data_str->d_buf;

  // read func symbolic table
  for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++)
    {
      Elf_Internal_Sym Sym;
      elf->elf_getsym (data, n, &Sym);
      const char *st_name = Sym.st_name < data_str->d_size ?
	  (Strtab + Sym.st_name) : NTXT ("no_name");
      switch (GELF_ST_TYPE (Sym.st_info))
	{
	case STT_FUNC:
	  // Skip UNDEF symbols (bug 4817083)
	  if (Sym.st_shndx == 0)
	    {
	      if (Sym.st_value == 0)
		break;
	      sitem = new Symbol (SymLst);
	      sitem->flags |= SYM_UNDEF;
	      if (pltSym)
		sitem->img_offset = (uint32_t) (pltSym->img_offset +
						Sym.st_value - pltSym->value);
	    }
	  else
	    {
	      Elf_Internal_Shdr *shdrp = elfDis->get_shdr (Sym.st_shndx);
	      if (shdrp == NULL)
		break;
	      sitem = new Symbol (SymLst);
	      sitem->img_offset = (uint32_t) (shdrp->sh_offset +
					      Sym.st_value - shdrp->sh_addr);
	    }
	  sitem->size = Sym.st_size;
	  sitem->name = dbe_strdup (st_name);
	  sitem->value = is_relocatable () ? sitem->img_offset : Sym.st_value;
	  if (GELF_ST_BIND (Sym.st_info) == STB_LOCAL)
	    {
	      sitem->local_ind = LocalFile->size () - 1;
	      LocalLst->append (sitem);
	    }
	  break;
	case STT_NOTYPE:
	  if (streq (st_name, NTXT ("gcc2_compiled.")))
	    {
	      sitem = new Symbol (SymLst);
	      sitem->lang_code = Sp_lang_gcc;
	      sitem->name = dbe_strdup (st_name);
	      sitem->local_ind = LocalFile->size () - 1;
	      LocalLst->append (sitem);
	    }
	  break;
	case STT_OBJECT:
	  if (!strncmp (st_name, NTXT ("__KAI_KPTS_"), 11))
	    local_lcode = Sp_lang_KAI_KPTS;
	  else if (!strncmp (st_name, NTXT ("__KAI_KCC_"), 10))
	    local_lcode = Sp_lang_KAI_KCC;
	  else if (!strncmp (st_name, NTXT ("__KAI_Kcc_"), 10))
	    local_lcode = Sp_lang_KAI_Kcc;
	  else
	    break;
	  sitem = new Symbol (LocalLst);
	  sitem->lang_code = local_lcode;
	  sitem->name = dbe_strdup (st_name);
	  break;
	case STT_FILE:
	  {
	    int last = LocalFile->size () - 1;
	    if (last >= 0 && LocalFileIdx->fetch (last) == LocalLst->size ())
	      {
		// There were no local functions in the latest file.
		free (LocalFile->get (last));
		LocalFile->store (last, dbe_strdup (st_name));
	      }
	    else
	      {
		LocalFile->append (dbe_strdup (st_name));
		LocalFileIdx->append (LocalLst->size ());
	      }
	    break;
	  }
	}
    }
  fixSymtabAlias ();
  SymLst->sort (SymValueCmp);
  get_save_addr (elf->need_swap_endian);
  dump ();
}//check_Symtab

void
Stabs::check_Relocs ()
{
  // We may have many relocation tables to process: .rela.text%foo,
  // rela.text%bar, etc. On Intel, compilers generate .rel.text sections
  // which have to be processed as well. A lot of rework is needed here.
  Symbol *sptr = NULL;
  if (st_check_relocs)
    return;
  st_check_relocs = true;

  Elf *elf = openElf (false);
  if (elf == NULL)
    return;
  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
    {
      bool use_rela, use_PLT;
      char *name = elf->get_sec_name (sec);
      if (name == NULL)
	continue;
      if (strncmp (name, NTXT (".rela.text"), 10) == 0)
	{
	  use_rela = true;
	  use_PLT = false;
	}
      else if (streq (name, NTXT (".rela.plt")))
	{
	  use_rela = true;
	  use_PLT = true;
	}
      else if (strncmp (name, NTXT (".rel.text"), 9) == 0)
	{
	  use_rela = false;
	  use_PLT = false;
	}
      else if (streq (name, NTXT (".rel.plt")))
	{
	  use_rela = false;
	  use_PLT = true;
	}
      else
	continue;

      Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
      if (shdr == NULL)
	continue;

      // Get ELF data
      Elf_Data *data = elf->elf_getdata (sec);
      if (data == NULL)
	continue;
      uint64_t ScnSize = data->d_size;
      uint64_t EntSize = shdr->sh_entsize;
      if ((ScnSize == 0) || (EntSize == 0))
	continue;
      int tot = (int) (ScnSize / EntSize);

      // Get corresponding text section
      Elf_Internal_Shdr *shdr_txt = elf->get_shdr (shdr->sh_info);
      if (shdr_txt == NULL)
	continue;
      if (!(shdr_txt->sh_flags & SHF_EXECINSTR))
	continue;

      // Get corresponding symbol table section
      Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
      if (shdr_sym == NULL)
	continue;
      Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);

      // Get corresponding string table section
      Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
      if (data_str == NULL)
	continue;
      char *Strtab = (char*) data_str->d_buf;
      for (int n = 0; n < tot; n++)
	{
	  Elf_Internal_Sym sym;
	  Elf_Internal_Rela rela;
	  char *symName;
	  if (use_rela)
	    elf->elf_getrela (data, n, &rela);
	  else
	    {
	      // GElf_Rela is extended GElf_Rel
	      elf->elf_getrel (data, n, &rela);
	      rela.r_addend = 0;
	    }

	  int ndx = (int) GELF_R_SYM (rela.r_info);
	  elf->elf_getsym (data_sym, ndx, &sym);
	  switch (GELF_ST_TYPE (sym.st_info))
	    {
	    case STT_FUNC:
	    case STT_OBJECT:
	    case STT_NOTYPE:
	      if (sym.st_name == 0 || sym.st_name >= data_str->d_size)
		continue;
	      symName = Strtab + sym.st_name;
	      break;
	    case STT_SECTION:
	      {
		Elf_Internal_Shdr *secHdr = elf->get_shdr (sym.st_shndx);
		if (secHdr == NULL)
		  continue;
		if (sptr == NULL)
		  sptr = new Symbol;
		sptr->value = secHdr->sh_offset + rela.r_addend;
		long index = SymLst->bisearch (0, -1, &sptr, SymFindCmp);
		if (index == -1)
		  continue;
		Symbol *sp = SymLst->fetch (index);
		if (sptr->value != sp->value)
		  continue;
		symName = sp->name;
		break;
	      }
	    default:
	      continue;
	    }
	  Reloc *reloc = new Reloc;
	  reloc->name = dbe_strdup (symName);
	  reloc->type = GELF_R_TYPE (rela.r_info);
	  reloc->value = use_PLT ? rela.r_offset
		  : rela.r_offset + shdr_txt->sh_offset;
	  reloc->addend = rela.r_addend;
	  if (use_PLT)
	    RelPLTLst->append (reloc);
	  else
	    RelLst->append (reloc);
	}
    }
  delete sptr;
  RelLst->sort (RelValueCmp);
} //check_Relocs

void
Stabs::get_save_addr (bool need_swap_endian)
{
  if (elfDis->is_Intel ())
    {
      for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++)
	{
	  Symbol *sitem = SymLst->fetch (j);
	  sitem->save = 0;
	}
      return;
    }
  for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++)
    {
      Symbol *sitem = SymLst->fetch (j);
      sitem->save = FUNC_NO_SAVE;

      // If an image offset is not known skip it.
      // Works for artificial symbols like '@plt' as well.
      if (sitem->img_offset == 0)
	continue;

      bool is_o7_moved = false;
      int64_t off = sitem->img_offset;
      for (int i = 0; i < sitem->size; i += 4)
	{
	  unsigned int cmd;
	  if (elfDis->get_data (off, sizeof (cmd), &cmd) == NULL)
	    break;
	  if (need_swap_endian)
	    SWAP_ENDIAN (cmd);
	  off += sizeof (cmd);
	  if ((cmd & 0xffffc000) == 0x9de38000)
	    { // save %sp, ??, %sp
	      sitem->save = i;
	      break;
	    }
	  else if ((cmd & 0xc0000000) == 0x40000000 || // call ??
	 (cmd & 0xfff80000) == 0xbfc00000)
	    { // jmpl ??, %o7
	      if (!is_o7_moved)
		{
		  sitem->save = FUNC_ROOT;
		  break;
		}
	    }
	  else if ((cmd & 0xc1ffe01f) == 0x8010000f)    // or %g0,%o7,??
	    is_o7_moved = true;
	}
    }
}

uint64_t
Stabs::mapOffsetToAddress (uint64_t img_offset)
{
  Elf *elf = openElf (false);
  if (elf == NULL)
    return 0;
  if (is_relocatable ())
    return img_offset;
  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
    {
      Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
      if (shdr == NULL)
	continue;
      if (img_offset >= (uint64_t) shdr->sh_offset
	  && img_offset < (uint64_t) (shdr->sh_offset + shdr->sh_size))
	return shdr->sh_addr + (img_offset - shdr->sh_offset);
    }
  return 0;
}

Stabs::Stab_status
Stabs::archive_Stabs (LoadObject *lo, unsigned int StabSec,
		      unsigned int StabStrSec, bool comdat)
{
  StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec);
  int tot = stabReader->stabCnt;
  if (tot < 0)
    {
      delete stabReader;
      return DBGD_ERR_NO_STABS;
    }

  char *sbase = NTXT (""), *arg, *fname, sname[2 * MAXPATHLEN];
  int lastMod, phase, stabs_level, modCnt = 0;
  Function *func = NULL;
  Module *mod;
#define INIT_MOD    phase = 0; stabs_level = 0; *sname = '\0'; mod = NULL

  bool updateStabsMod = false;
  if (comdat && ((elfDbg->elf_getehdr ()->e_type == ET_EXEC) || (elfDbg->elf_getehdr ()->e_type == ET_DYN)))
    {
      if (stabsModules == NULL)
	stabsModules = new Vector<Module*>();
      updateStabsMod = true;
    }
  INIT_MOD;
  lastMod = lo->seg_modules->size ();

  for (int n = 0; n < tot; n++)
    {
      struct stab stb;
      char *str = stabReader->get_stab (&stb, comdat);
      switch (stb.n_type)
	{
	case N_FUN:
	  // Ignore a COMDAT function, if there are two or more modules in 'lo'
	  if (comdat && stb.n_other == 1 && modCnt > 1)
	    break;
	case N_OUTL:
	case N_ALIAS:
	case N_ENTRY:
	  if (mod == NULL || str == NULL
	      || (stb.n_type != N_ENTRY && stabs_level != 0))
	    break;
	  if (*str == '@')
	    {
	      str++;
	      if (*str == '>' || *str == '<')
		str++;
	    }

	  fname = dbe_strdup (str);
	  arg = strchr (fname, ':');
	  if (arg != NULL)
	    {
	      if (!strncmp (arg, NTXT (":P"), 2))
		{ // just prototype
		  free (fname);
		  break;
		}
	      *arg = '\0';
	    }

	  func = append_Function (mod, fname);
	  free (fname);
	  break;
	case N_CMDLINE:
	  if (str && mod)
	    {
	      char *comp_flags = strchr (str, ';');
	      if (comp_flags)
		{
		  mod->comp_flags = dbe_strdup (comp_flags + 1);
		  mod->comp_dir = dbe_strndup (str, comp_flags - str);
		}
	    }
	  break;
	case N_LBRAC:
	  stabs_level++;
	  break;
	case N_RBRAC:
	  stabs_level--;
	  break;
	case N_UNDF:
	  INIT_MOD;
	  break;
	case N_ENDM:
	  INIT_MOD;
	  break;
	case N_OPT:
	  stabReader->parse_N_OPT (mod, str);
	  if (mod && (str != NULL) && streq (str, NTXT ("gcc2_compiled.")))
	    // Is it anachronism ?
	    mod->lang_code = Sp_lang_gcc;
	  break;
	case N_GSYM:
	  if (mod && (str != NULL))
	    {
	      if (strncmp (str, NTXT ("__KAI_K"), 7))
		break;
	      str += 7;
	      if (!strncmp (str, NTXT ("CC_"), 3))
		mod->lang_code = Sp_lang_KAI_KCC;
	      else if (!strncmp (str, NTXT ("cc_"), 3))
		mod->lang_code = Sp_lang_KAI_Kcc;
	      else if (!strncmp (str, NTXT ("PTS_"), 4) &&
		       (mod->lang_code != Sp_lang_KAI_KCC) &&
		       (mod->lang_code != Sp_lang_KAI_Kcc))
		mod->lang_code = Sp_lang_KAI_KPTS;
	    }
	  break;
	case N_SO:
	  if (str == NULL || *str == '\0')
	    {
	      INIT_MOD;
	      break;
	    }
	  if (phase == 0)
	    {
	      phase = 1;
	      sbase = str;
	    }
	  else
	    {
	      if (*str == '/')
		sbase = str;
	      else
		{
		  size_t last = strlen (sbase);
		  if (last == 0 || sbase[last - 1] != '/')
		    snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str);
		  else
		    snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str);
		  sbase = sname;
		}
	      mod = append_Module (lo, sbase, lastMod);
	      if (updateStabsMod)
		stabsModules->append (mod);
	      mod->hasStabs = true;
	      modCnt++;
	      if ((mod->lang_code != Sp_lang_gcc) &&
		  (mod->lang_code != Sp_lang_KAI_KPTS) &&
		  (mod->lang_code != Sp_lang_KAI_KCC) &&
		  (mod->lang_code != Sp_lang_KAI_Kcc))
		mod->lang_code = (Sp_lang_code) stb.n_desc;
	      *sname = '\0';
	      phase = 0;
	    }
	  break;
	case N_OBJ:
	  if (str == NULL)
	    break;
	  if (phase == 0)
	    {
	      phase = 1;
	      sbase = str;
	    }
	  else
	    {
	      if (*str == '/')
		sbase = str;
	      else
		{
		  size_t last = strlen (sbase);
		  if (last == 0 || sbase[last - 1] != '/')
		    snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str);
		  else
		    snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str);
		  sbase = sname;
		}
	      if (mod && (mod->dot_o_file == NULL))
		{
		  if (strcmp (sbase, NTXT ("/")) == 0)
		    mod->set_name (dbe_strdup (path));
		  else
		    {
		      mod->set_name (dbe_strdup (sbase));
		      mod->dot_o_file = mod->createLoadObject (sbase);
		    }
		}
	      *sname = '\0';
	      phase = 0;
	    }
	  break;
	case N_CPROF:
	  cpf_stabs_t map;
	  Dprintf (DEBUG_STABS, NTXT ("N_CPROF n_desc=%x n_value=0x%04x mod=%s\n"),
		   stb.n_desc, stb.n_value, (mod == NULL) ? NTXT ("???") : mod->get_name ());
	  map.type = stb.n_desc;
	  map.offset = stb.n_value;
	  map.module = mod;
	  analyzerInfoMap.append (map);
	  break;
	}
    }
  delete stabReader;
  return func ? DBGD_ERR_NONE : DBGD_ERR_NO_STABS;
}

Module *
Stabs::append_Module (LoadObject *lo, char *name, int lastMod)
{
  Module *module;
  int size;
  Symbol *sitem;

  if (lo->seg_modules != NULL)
    {
      size = lo->seg_modules->size ();
      if (size < lastMod)
	lastMod = size;
      for (int i = 0; i < lastMod; i++)
	{
	  module = lo->seg_modules->fetch (i);
	  if (module->linkerStabName && streq (module->linkerStabName, name))
	    return module;
	}
    }
  module = dbeSession->createModule (lo, NULL);
  module->set_file_name (dbe_strdup (name));
  module->linkerStabName = dbe_strdup (module->file_name);

  // Append all functions with 'local_ind == -1' to the module.
  if (LocalLst->size () > 0)
    {
      sitem = LocalLst->fetch (0);
      if (!sitem->defined && sitem->local_ind == -1)
	// Append all functions with 'local_ind == -1' to the module.
	append_local_funcs (module, 0);
    }

  // Append local func
  char *basename = get_basename (name);
  size = LocalFile->size ();
  for (int i = 0; i < size; i++)
    {
      if (streq (basename, LocalFile->fetch (i)))
	{
	  int local_ind = LocalFileIdx->fetch (i);
	  if (local_ind >= LocalLst->size ())
	    break;
	  sitem = LocalLst->fetch (local_ind);
	  if (!sitem->defined)
	    {
	      append_local_funcs (module, local_ind);
	      break;
	    }
	}
    }
  return module;
}

void
Stabs::append_local_funcs (Module *module, int first_ind)
{
  Symbol *sitem = LocalLst->fetch (first_ind);
  int local_ind = sitem->local_ind;
  int size = LocalLst->size ();
  for (int i = first_ind; i < size; i++)
    {
      sitem = LocalLst->fetch (i);
      if (sitem->local_ind != local_ind)
	break;
      sitem->defined = true;

      // 3rd party compiled. e.g., Gcc or KAI compiled
      if (sitem->lang_code != Sp_lang_unknown)
	{
	  if (module->lang_code == Sp_lang_unknown)
	    module->lang_code = sitem->lang_code;
	  continue;
	}
      if (sitem->func)
	continue;
      Function *func = dbeSession->createFunction ();
      sitem->func = func;
      func->img_fname = path;
      func->img_offset = (off_t) sitem->img_offset;
      func->save_addr = (uint32_t) sitem->save;
      func->size = (uint32_t) sitem->size;
      func->module = module;
      func->set_name (sitem->name);
      module->functions->append (func);
      module->loadobject->functions->append (func);
    }
}

Function *
Stabs::append_Function (Module *module, char *fname)
{
  Symbol *sitem, *sptr;
  Function *func;
  long sid, index;
  char *name;
  if (SymLstByName == NULL)
    {
      SymLstByName = SymLst->copy ();
      SymLstByName->sort (SymNameCmp);
    }
  sptr = new Symbol;
  if (module->lang_code == N_SO_FORTRAN || module->lang_code == N_SO_FORTRAN90)
    {
      char *fortran = dbe_sprintf (NTXT ("%s_"), fname); // FORTRAN name
      sptr->name = fortran;
      sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
      if (sid == -1)
	{
	  free (fortran);
	  sptr->name = fname;
	  sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
	}
      else
	fname = fortran;
    }
  else
    {
      sptr->name = fname;
      sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
    }
  sptr->name = NULL;
  delete sptr;

  if (sid == -1)
    {
      Vec_loop (Symbol*, SymLstByName, index, sitem)
      {
	if (strncmp (sitem->name, NTXT ("$X"), 2) == 0
	    || strncmp (sitem->name, NTXT (".X"), 2) == 0)
	  {
	    char *n = strchr (((sitem->name) + 2), (int) '.');
	    if (n != NULL)
	      name = n + 1;
	    else
	      name = sitem->name;
	  }
	else
	  name = sitem->name;
	if (name != NULL && fname != NULL && (strcmp (name, fname) == 0))
	  {
	    sid = index;
	    break;
	  }
      }
    }
  if (sid != -1)
    {
      sitem = SymLstByName->fetch (sid);
      if (sitem->alias)
	sitem = sitem->alias;
      if (sitem->func)
	return sitem->func;
      sitem->func = func = dbeSession->createFunction ();
      func->img_fname = path;
      func->img_offset = (off_t) sitem->img_offset;
      func->save_addr = (uint32_t) sitem->save;
      func->size = (uint32_t) sitem->size;
    }
  else
    func = dbeSession->createFunction ();

  func->module = module;
  func->set_name (fname);
  module->functions->append (func);
  module->loadobject->functions->append (func);
  return func;
}

Function *
Stabs::append_Function (Module *module, char *linkerName, uint64_t pc)
{
  Dprintf (DEBUG_STABS, NTXT ("Stabs::append_Function: module=%s linkerName=%s pc=0x%llx\n"),
	   STR (module->get_name ()), STR (linkerName), (unsigned long long) pc);
  long i;
  Symbol *sitem = NULL, *sp;
  Function *func;
  sp = new Symbol;
  if (pc)
    {
      sp->value = pc;
      i = SymLst->bisearch (0, -1, &sp, SymFindCmp);
      if (i != -1)
	sitem = SymLst->fetch (i);
    }

  if (!sitem && linkerName)
    {
      if (SymLstByName == NULL)
	{
	  SymLstByName = SymLst->copy ();
	  SymLstByName->sort (SymNameCmp);
	}
      sp->name = linkerName;
      i = SymLstByName->bisearch (0, -1, &sp, SymNameCmp);
      sp->name = NULL;
      if (i != -1)
	sitem = SymLstByName->fetch (i);
    }
  delete sp;

  if (!sitem)
    return NULL;
  if (sitem->alias)
    sitem = sitem->alias;
  if (sitem->func)
    return sitem->func;

  sitem->func = func = dbeSession->createFunction ();
  func->img_fname = path;
  func->img_offset = (off_t) sitem->img_offset;
  func->save_addr = (uint32_t) sitem->save;
  func->size = (uint32_t) sitem->size;
  func->module = module;
  func->set_name (sitem->name); //XXXX ?? Now call it to set obj->name
  module->functions->append (func);
  module->loadobject->functions->append (func);
  return func;
}// Stabs::append_Function

Dwarf *
Stabs::openDwarf ()
{
  if (dwarf == NULL)
    {
      dwarf = new Dwarf (this);
      check_Symtab ();
    }
  return dwarf;
}

void
Stabs::read_hwcprof_info (Module *module)
{
  openDwarf ()->read_hwcprof_info (module);
}

void
Stabs::dump ()
{
  if (!DUMP_ELF_SYM)
    return;
  printf (NTXT ("\n======= Stabs::dump: %s =========\n"), path ? path : NTXT ("NULL"));
  int i, sz;
  if (LocalFile)
    {
      sz = LocalFile->size ();
      for (i = 0; i < sz; i++)
	printf ("  %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i),
		LocalFile->fetch (i));
    }
  Symbol::dump (SymLst, NTXT ("SymLst"));
  Symbol::dump (LocalLst, NTXT ("LocalLst"));
  printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"),
  path ? path : NTXT ("NULL"));
}

///////////////////////////////////////////////////////////////////////////////
//  Class Include
Include::Include ()
{
  stack = new Vector<SrcFileInfo*>;
}

Include::~Include ()
{
  Destroy (stack);
}

void
Include::new_src_file (SourceFile *source, int lineno, Function *func)
{
  for (int index = stack->size () - 1; index >= 0; index--)
    {
      if (source == stack->fetch (index)->srcfile)
	{
	  for (int i = stack->size () - 1; i > index; i--)
	    {
	      delete stack->remove (i);
	      if (func && func->line_first > 0)
		func->popSrcFile ();
	    }
	  return;
	}
    }
  if (func && func->line_first > 0)
    func->pushSrcFile (source, lineno);

  SrcFileInfo *sfinfo = new SrcFileInfo;
  sfinfo->srcfile = source;
  sfinfo->lineno = lineno;
  stack->append (sfinfo);
}

void
Include::push_src_files (Function *func)
{
  int index;
  SrcFileInfo *sfinfo;

  if (func->line_first <= 0 && stack->size () > 0)
    {
      sfinfo = stack->fetch (stack->size () - 1);
      func->setDefSrc (sfinfo->srcfile);
    }
  Vec_loop (SrcFileInfo*, stack, index, sfinfo)
  {
    func->pushSrcFile (sfinfo->srcfile, sfinfo->lineno);
  }
}

void
Include::new_include_file (SourceFile *source, Function *func)
{
  if (stack->size () == 1 && stack->fetch (0)->srcfile == source)
    // workaroud for gcc; gcc creates 'N_BINCL' stab for main source
    return;
  if (func && func->line_first > 0)
    func->pushSrcFile (source, 0);

  SrcFileInfo *sfinfo = new SrcFileInfo;
  sfinfo->srcfile = source;
  sfinfo->lineno = 0;
  stack->append (sfinfo);
}

void
Include::end_include_file (Function *func)
{
  int index = stack->size () - 1;
  if (index > 0)
    {
      delete stack->remove (index);
      if (func && func->line_first > 0)
	func->popSrcFile ();
    }
}

#define RET_S(x)   if (t == x) return (char *) #x
char *
StabReader::get_type_name (int t)
{
  RET_S (N_UNDF);
  RET_S (N_ABS);
  RET_S (N_TEXT);
  RET_S (N_DATA);
  RET_S (N_BSS);
  RET_S (N_COMM);
  RET_S (N_FN);
  RET_S (N_EXT);
  RET_S (N_TYPE);
  RET_S (N_GSYM);
  RET_S (N_FNAME);
  RET_S (N_FUN);
  RET_S (N_OUTL);
  RET_S (N_STSYM);
  RET_S (N_TSTSYM);
  RET_S (N_LCSYM);
  RET_S (N_TLCSYM);
  RET_S (N_MAIN);
  RET_S (N_ROSYM);
  RET_S (N_FLSYM);
  RET_S (N_TFLSYM);
  RET_S (N_PC);
  RET_S (N_CMDLINE);
  RET_S (N_OBJ);
  RET_S (N_OPT);
  RET_S (N_RSYM);
  RET_S (N_SLINE);
  RET_S (N_XLINE);
  RET_S (N_ILDPAD);
  RET_S (N_SSYM);
  RET_S (N_ENDM);
  RET_S (N_SO);
  RET_S (N_MOD);
  RET_S (N_EMOD);
  RET_S (N_READ_MOD);
  RET_S (N_ALIAS);
  RET_S (N_LSYM);
  RET_S (N_BINCL);
  RET_S (N_SOL);
  RET_S (N_PSYM);
  RET_S (N_EINCL);
  RET_S (N_ENTRY);
  RET_S (N_SINCL);
  RET_S (N_LBRAC);
  RET_S (N_EXCL);
  RET_S (N_USING);
  RET_S (N_ISYM);
  RET_S (N_ESYM);
  RET_S (N_PATCH);
  RET_S (N_CONSTRUCT);
  RET_S (N_DESTRUCT);
  RET_S (N_CODETAG);
  RET_S (N_FUN_CHILD);
  RET_S (N_RBRAC);
  RET_S (N_BCOMM);
  RET_S (N_TCOMM);
  RET_S (N_ECOMM);
  RET_S (N_XCOMM);
  RET_S (N_ECOML);
  RET_S (N_WITH);
  RET_S (N_LENG);
  RET_S (N_CPROF);
  RET_S (N_BROWS);
  RET_S (N_FUN_PURE);
  RET_S (N_FUN_ELEMENTAL);
  RET_S (N_FUN_RECURSIVE);
  RET_S (N_FUN_AMD64_PARMDUMP);
  RET_S (N_SYM_OMP_TLS);
  RET_S (N_SO_AS);
  RET_S (N_SO_C);
  RET_S (N_SO_ANSI_C);
  RET_S (N_SO_CC);
  RET_S (N_SO_FORTRAN);
  RET_S (N_SO_FORTRAN77);
  RET_S (N_SO_PASCAL);
  RET_S (N_SO_FORTRAN90);
  RET_S (N_SO_JAVA);
  RET_S (N_SO_C99);
  return NULL;
}
