/* Copyright (C) 2021-2024 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 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 = sym->img_offset;
  func->save_addr = sym->save;
  func->size = 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 (elf->plt != 0)
    {
      Elf_Internal_Shdr *shdr = elf->get_shdr (elf->plt);
      if (shdr)
	{
	  pltSym = new Symbol (SymLst);
	  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:
	  if (Sym.st_size == 0)
	    break;
	  if (Sym.st_shndx == 0)
	    {
	      if (Sym.st_value == 0)
		break;
	      sitem = new Symbol (SymLst);
	      sitem->flags |= SYM_UNDEF;
	      if (pltSym)
		sitem->img_offset = 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 = 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 = sitem->img_offset;
      func->save_addr = sitem->save;
      func->size = 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 = sitem->img_offset;
      func->save_addr = sitem->save;
      func->size = 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 = sitem->img_offset;
  func->save_addr = sitem->save;
  func->size = 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;
}
