1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#include "config.h"
22#include <sys/param.h>
23
24#include "util.h"
25#include "Elf.h"
26#include "Dwarf.h"
27#include "stab.h"
28#include "DbeSession.h"
29#include "CompCom.h"
30#include "Stabs.h"
31#include "LoadObject.h"
32#include "Module.h"
33#include "Function.h"
34#include "info.h"
35#include "StringBuilder.h"
36#include "DbeFile.h"
37#include "StringMap.h"
38
39#define DISASM_REL_NONE     0     /* symtab search only */
40#define DISASM_REL_ONLY     1     /* relocation search only */
41#define DISASM_REL_TARG     2     /* relocatoin then symtab */
42
43///////////////////////////////////////////////////////////////////////////////
44// class StabReader
45class StabReader
46{
47public:
48  StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec);
49  ~StabReader () { };
50  char *get_type_name (int t);
51  char *get_stab (struct stab *np, bool comdat);
52  void parse_N_OPT (Module *mod, char *str);
53  int stabCnt;
54  int stabNum;
55
56private:
57  Elf *elf;
58  char *StabData;
59  char *StabStrtab;
60  char *StabStrtabEnd;
61  int StrTabSize;
62  int StabEntSize;
63};
64
65///////////////////////////////////////////////////////////////////////////////
66// class Symbol
67
68class Symbol
69{
70public:
71  Symbol (Vector<Symbol*> *vec = NULL);
72
73  ~Symbol ()
74  {
75    free (name);
76  }
77
78  inline Symbol *
79  cardinal ()
80  {
81    return alias ? alias : this;
82  }
83
84  static void dump (Vector<Symbol*> *vec, char*msg);
85
86  Function *func;
87  Sp_lang_code lang_code;
88  uint64_t value; // st_value used in sym_name()
89  uint64_t save;
90  int64_t size;
91  uint64_t img_offset; // image offset in the ELF file
92  char *name;
93  Symbol *alias;
94  int local_ind;
95  int flags;
96  bool defined;
97};
98
99Symbol::Symbol (Vector<Symbol*> *vec)
100{
101  func = NULL;
102  lang_code = Sp_lang_unknown;
103  value = 0;
104  save = 0;
105  size = 0;
106  img_offset = 0;
107  name = NULL;
108  alias = NULL;
109  local_ind = -1;
110  flags = 0;
111  defined = false;
112  if (vec)
113    vec->append (this);
114}
115
116void
117Symbol::dump (Vector<Symbol*> *vec, char*msg)
118{
119  if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0)
120    return;
121  printf (NTXT ("======= Symbol::dump: %s =========\n"
122		"         value |    img_offset     | flags|local_ind|\n"), msg);
123  for (int i = 0; i < vec->size (); i++)
124    {
125      Symbol *sp = vec->fetch (i);
126      printf (NTXT ("  %3d %8lld |0x%016llx |%5d |%8d |%s\n"),
127	      i, (long long) sp->value, (long long) sp->img_offset, sp->flags,
128	      sp->local_ind, sp->name ? sp->name : NTXT ("NULL"));
129    }
130  printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg);
131}
132
133// end of class Symbol
134///////////////////////////////////////////////////////////////////////////////
135
136///////////////////////////////////////////////////////////////////////////////
137// class Reloc
138class Reloc
139{
140public:
141  Reloc ();
142  ~Reloc ();
143  uint64_t type;
144  uint64_t value;
145  uint64_t addend;
146  char *name;
147};
148
149Reloc::Reloc ()
150{
151  type = 0;
152  value = 0;
153  addend = 0;
154  name = NULL;
155}
156
157Reloc::~Reloc ()
158{
159  free (name);
160}
161// end of class Reloc
162///////////////////////////////////////////////////////////////////////////////
163
164enum
165{
166  SYM_PLT       = 1 << 0,
167  SYM_UNDEF     = 1 << 1
168};
169
170enum Section_type
171{
172  COMM1_SEC = 0x10000000,
173  COMM_SEC  = 0x20000000,
174  INFO_SEC  = 0x30000000,
175  LOOP_SEC  = 0x40000000
176};
177
178struct cpf_stabs_t
179{
180  uint32_t type;    // Archive::AnalyzerInfoType
181  uint32_t offset;  // offset in .__analyzer_info
182  Module *module;   // table for appropriate Module
183};
184
185static char *get_info_com (int type, int32_t copy_inout);
186static char *get_lp_com (unsigned hints, int parallel, char *dep);
187static int ComCmp (const void *a, const void *b);
188static ino64_t _src_inode = 0;
189static char *_src_name;
190
191// Comparing name
192static int
193SymNameCmp (const void *a, const void *b)
194{
195  Symbol *item1 = *((Symbol **) a);
196  Symbol *item2 = *((Symbol **) b);
197  return (item1->name == NULL) ? -1 :
198	  (item2->name == NULL) ? 1 : strcmp (item1->name, item2->name);
199}
200
201// Comparing value: for sorting
202static int
203SymValueCmp (const void *a, const void *b)
204{
205  Symbol *item1 = *((Symbol **) a);
206  Symbol *item2 = *((Symbol **) b);
207  return (item1->value > item2->value) ? 1 :
208	  (item1->value == item2->value) ? SymNameCmp (a, b) : -1;
209}
210
211// Comparing value: for searching (source name is always NULL)
212static int
213SymFindCmp (const void *a, const void *b)
214{
215  Symbol *item1 = *((Symbol **) a);
216  Symbol *item2 = *((Symbol **) b);
217  if (item1->value < item2->value)
218    return -1;
219  if (item1->value < item2->value + item2->size
220      || item1->value == item2->value) // item2->size == 0
221    return 0;
222  return 1;
223}
224
225// Comparing value for sorting. It is used only for searching aliases.
226static int
227SymImgOffsetCmp (const void *a, const void *b)
228{
229  Symbol *item1 = *((Symbol **) a);
230  Symbol *item2 = *((Symbol **) b);
231  return (item1->img_offset > item2->img_offset) ? 1 :
232	  (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1;
233}
234
235static int
236RelValueCmp (const void *a, const void *b)
237{
238  Reloc *item1 = *((Reloc **) a);
239  Reloc *item2 = *((Reloc **) b);
240  return (item1->value > item2->value) ? 1 :
241	  (item1->value == item2->value) ? 0 : -1;
242}
243
244Stabs *
245Stabs::NewStabs (char *_path, char *lo_name)
246{
247  Stabs *stabs = new Stabs (_path, lo_name);
248  if (stabs->status != Stabs::DBGD_ERR_NONE)
249    {
250      delete stabs;
251      return NULL;
252    }
253  return stabs;
254}
255
256Stabs::Stabs (char *_path, char *_lo_name)
257{
258  path = dbe_strdup (_path);
259  lo_name = dbe_strdup (_lo_name);
260  SymLstByName = NULL;
261  pltSym = NULL;
262  SymLst = new Vector<Symbol*>;
263  RelLst = new Vector<Reloc*>;
264  RelPLTLst = new Vector<Reloc*>;
265  LocalLst = new Vector<Symbol*>;
266  LocalFile = new Vector<char*>;
267  LocalFileIdx = new Vector<int>;
268  last_PC_to_sym = NULL;
269  dwarf = NULL;
270  elfDbg = NULL;
271  elfDis = NULL;
272  stabsModules = NULL;
273  textsz = 0;
274  wsize = Wnone;
275  st_check_symtab = st_check_relocs = false;
276  status = DBGD_ERR_NONE;
277
278  if (openElf (false) == NULL)
279    return;
280  switch (elfDis->elf_getclass ())
281    {
282    case ELFCLASS32:
283      wsize = W32;
284      break;
285    case ELFCLASS64:
286      wsize = W64;
287      break;
288    }
289  isRelocatable = elfDis->elf_getehdr ()->e_type == ET_REL;
290  for (unsigned int pnum = 0; pnum < elfDis->elf_getehdr ()->e_phnum; pnum++)
291    {
292      Elf_Internal_Phdr *phdr = elfDis->get_phdr (pnum);
293      if (phdr->p_type == PT_LOAD && phdr->p_flags == (PF_R | PF_X))
294	{
295	  if (textsz == 0)
296	    textsz = phdr->p_memsz;
297	  else
298	    {
299	      textsz = 0;
300	      break;
301	    }
302	}
303    }
304}
305
306Stabs::~Stabs ()
307{
308  delete pltSym;
309  delete SymLstByName;
310  Destroy (SymLst);
311  Destroy (RelLst);
312  Destroy (RelPLTLst);
313  Destroy (LocalFile);
314  delete elfDis;
315  delete dwarf;
316  delete LocalLst;
317  delete LocalFileIdx;
318  delete stabsModules;
319  free (path);
320  free (lo_name);
321}
322
323Elf *
324Stabs::openElf (char *fname, Stab_status &st)
325{
326  Elf::Elf_status elf_status;
327  Elf *elf = Elf::elf_begin (fname, &elf_status);
328  if (elf == NULL)
329    {
330      switch (elf_status)
331	{
332	case Elf::ELF_ERR_CANT_OPEN_FILE:
333	case Elf::ELF_ERR_CANT_MMAP:
334	case Elf::ELF_ERR_BIG_FILE:
335	  st = DBGD_ERR_CANT_OPEN_FILE;
336	  break;
337	case Elf::ELF_ERR_BAD_ELF_FORMAT:
338	default:
339	  st = DBGD_ERR_BAD_ELF_FORMAT;
340	  break;
341	}
342      return NULL;
343    }
344  if (elf->elf_version (EV_CURRENT) == EV_NONE)
345    {
346      // ELF library out of date
347      delete elf;
348      st = DBGD_ERR_BAD_ELF_LIB;
349      return NULL;
350    }
351
352  Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr ();
353  if (ehdrp == NULL)
354    {
355      // check machine
356      delete elf;
357      st = DBGD_ERR_BAD_ELF_FORMAT;
358      return NULL;
359    }
360  switch (ehdrp->e_machine)
361    {
362    case EM_SPARC:
363      platform = Sparc;
364      break;
365    case EM_SPARC32PLUS:
366      platform = Sparcv8plus;
367      break;
368    case EM_SPARCV9:
369      platform = Sparcv9;
370      break;
371    case EM_386:
372      //    case EM_486:
373      platform = Intel;
374      break;
375    case EM_X86_64:
376      platform = Amd64;
377      break;
378    case EM_AARCH64:
379      platform = Aarch64;
380      break;
381    default:
382      platform = Unknown;
383      break;
384    }
385  return elf;
386}
387
388Elf *
389Stabs::openElf (bool dbg_info)
390{
391  if (status != DBGD_ERR_NONE)
392    return NULL;
393  if (elfDis == NULL)
394    {
395      elfDis = openElf (path, status);
396      if (elfDis == NULL)
397	return NULL;
398    }
399  if (!dbg_info)
400    return elfDis;
401  if (elfDbg == NULL)
402    {
403      elfDbg = elfDis->find_ancillary_files (lo_name);
404      if (elfDbg == NULL)
405	elfDbg = elfDis;
406    }
407  return elfDbg;
408}
409
410bool
411Stabs::read_symbols (Vector<Function*> *functions)
412{
413  if (openElf (true) == NULL)
414    return false;
415  check_Symtab ();
416  check_Relocs ();
417  if (functions)
418    {
419      Function *fp;
420      int index;
421      Vec_loop (Function*, functions, index, fp)
422      {
423	fp->img_fname = path;
424      }
425    }
426  return true;
427}
428
429char *
430Stabs::sym_name (uint64_t target, uint64_t instr, int flag)
431{
432  long index;
433  if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG)
434    {
435      Reloc *relptr = new Reloc;
436      relptr->value = instr;
437      index = RelLst->bisearch (0, -1, &relptr, RelValueCmp);
438      if (index >= 0)
439	{
440	  delete relptr;
441	  return RelLst->fetch (index)->name;
442	}
443      if (!is_relocatable ())
444	{
445	  relptr->value = target;
446	  index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp);
447	  if (index >= 0)
448	    {
449	      delete relptr;
450	      return RelPLTLst->fetch (index)->name;
451	    }
452	}
453      delete relptr;
454    }
455  if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ())
456    {
457      Symbol *sptr;
458      sptr = map_PC_to_sym (target);
459      if (sptr && sptr->value == target)
460	return sptr->name;
461    }
462  return NULL;
463}
464
465Symbol *
466Stabs::map_PC_to_sym (uint64_t pc)
467{
468  if (pc == 0)
469    return NULL;
470  if (last_PC_to_sym && last_PC_to_sym->value <= pc
471      && last_PC_to_sym->value + last_PC_to_sym->size > pc)
472    return last_PC_to_sym;
473  Symbol *sym = new Symbol;
474  sym->value = pc;
475  long index = SymLst->bisearch (0, -1, &sym, SymFindCmp);
476  delete sym;
477  if (index >= 0)
478    {
479      last_PC_to_sym = SymLst->fetch (index)->cardinal ();
480      return last_PC_to_sym;
481    }
482  return NULL;
483}
484
485Function *
486Stabs::map_PC_to_func (uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions)
487{
488  int index;
489  Function *func;
490  Symbol *sptr = map_PC_to_sym (pc);
491  if (sptr == NULL)
492    return NULL;
493  if (sptr->func)
494    {
495      low_pc = sptr->value;
496      return sptr->func;
497    }
498  if (functions)
499    {
500      Vec_loop (Function*, functions, index, func)
501      {
502	if (func->img_offset == sptr->img_offset)
503	  {
504	    sptr->func = func->cardinal ();
505	    low_pc = sptr->value;
506	    return sptr->func;
507	  }
508      }
509    }
510  return NULL;
511}
512
513Stabs::Stab_status
514Stabs::read_stabs (ino64_t srcInode, Module *module, Vector<ComC*> *comComs,
515		   bool readDwarf)
516{
517  if (module)
518    module->setIncludeFile (NULL);
519
520  if (openElf (true) == NULL)
521    return status;
522  check_Symtab ();
523
524  // read compiler commentary from .compcom1, .compcom,
525  // .info, .loops, and .loopview sections
526  if (comComs)
527    {
528      _src_inode = srcInode;
529      _src_name = module && module->file_name ? get_basename (module->file_name) : NULL;
530      if (!check_Comm (comComs))
531	// .loops, and .loopview are now in .compcom
532	check_Loop (comComs);
533
534      // should not read it after .info goes into .compcom
535      check_Info (comComs);
536      comComs->sort (ComCmp);
537    }
538
539  // get stabs info
540  Stab_status statusStabs = DBGD_ERR_NO_STABS;
541#define SRC_LINE_STABS(sec, secStr, comdat) \
542    if ((elfDbg->sec)  && (elfDbg->secStr) && \
543	srcline_Stabs(module, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
544	statusStabs = DBGD_ERR_NONE
545
546  SRC_LINE_STABS (stabExcl, stabExclStr, false);
547  SRC_LINE_STABS (stab, stabStr, false);
548  SRC_LINE_STABS (stabIndex, stabIndexStr, true);
549
550  // read Dwarf, if any sections found
551  if (elfDbg->dwarf && readDwarf)
552    {
553      openDwarf ()->srcline_Dwarf (module);
554      if (dwarf && dwarf->status == DBGD_ERR_NONE)
555	return DBGD_ERR_NONE;
556    }
557  return statusStabs;
558}
559
560static int
561ComCmp (const void *a, const void *b)
562{
563  ComC *item1 = *((ComC **) a);
564  ComC *item2 = *((ComC **) b);
565  return (item1->line > item2->line) ? 1 :
566	  (item1->line < item2->line) ? -1 :
567	  (item1->sec > item2->sec) ? 1 :
568	  (item1->sec < item2->sec) ? -1 : 0;
569}
570
571static int
572check_src_name (char *srcName)
573{
574  if (_src_name && srcName && streq (_src_name, get_basename (srcName)))
575    return 1;
576  if (_src_inode == (ino64_t) - 1)
577    return 0;
578  DbeFile *dbeFile = dbeSession->getDbeFile (srcName, DbeFile::F_SOURCE);
579  char *path = dbeFile->get_location ();
580  return (path == NULL || dbeFile->sbuf.st_ino != _src_inode) ? 0 : 1;
581}
582
583bool
584Stabs::check_Comm (Vector<ComC*> *comComs)
585{
586  int sz = comComs->size ();
587  Elf *elf = openElf (true);
588  if (elf == NULL)
589    return false;
590
591  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
592    {
593      char *name = elf->get_sec_name (sec);
594      if (name == NULL)
595	continue;
596      Section_type sec_type;
597      if (streq (name, NTXT (".compcom")))
598	sec_type = COMM_SEC;
599      else if (streq (name, NTXT (".compcom1")))
600	sec_type = COMM1_SEC;
601      else
602	continue;
603
604      // find header, set messages id & visibility if succeed
605      CompComment *cc = new CompComment (elf, sec);
606      int cnt = cc->compcom_open ((CheckSrcName) check_src_name);
607      // process messages
608      for (int index = 0; index < cnt; index++)
609	{
610	  int visible;
611	  compmsg msg;
612	  char *str = cc->compcom_format (index, &msg, visible);
613	  if (str)
614	    {
615	      ComC *citem = new ComC;
616	      citem->sec = sec_type + index;
617	      citem->type = msg.msg_type;
618	      citem->visible = visible;
619	      citem->line = (msg.lineno < 1) ? 1 : msg.lineno;
620	      citem->com_str = str;
621	      comComs->append (citem);
622	    }
623	}
624      delete cc;
625    }
626  return (sz != comComs->size ());
627}
628
629static int
630targetOffsetCmp (const void *a, const void *b)
631{
632  uint32_t o1 = ((target_info_t *) a)->offset;
633  uint32_t o2 = ((target_info_t *) b)->offset;
634  return (o1 >= o2);
635}
636
637void
638Stabs::check_AnalyzerInfo ()
639{
640  Elf *elf = openElf (true);
641  if ((elf == NULL) || (elf->analyzerInfo == 0))
642    {
643      Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo: Null AnalyzerInfo section\n"));
644      return; // inappropriate, but ignored anyway
645    }
646  Elf_Data *data = elf->elf_getdata (elf->analyzerInfo);
647  int InfoSize = (int) data->d_size;
648  char *InfoData = (char *) data->d_buf;
649  int InfoAlign = (int) data->d_align;
650  AnalyzerInfoHdr h;
651  unsigned infoHdr_sz = sizeof (AnalyzerInfoHdr);
652  int table, entry;
653  int read = 0;
654  Module *mitem;
655  int index = 0;
656  if (InfoSize <= 0)
657    return;
658  uint64_t baseAddr = elf->get_baseAddr ();
659  Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo size=%d @0x%lx (align=%d) base=0x%llx\n"),
660	   InfoSize, (ul_t) InfoData, InfoAlign, (long long) baseAddr);
661  Dprintf (DEBUG_STABS, NTXT ("analyzerInfoMap has %lld entries\n"), (long long) analyzerInfoMap.size ());
662  if (analyzerInfoMap.size () == 0)
663    {
664      Dprintf (DEBUG_STABS, NTXT ("No analyzerInfoMap available!\n"));
665      return;
666    }
667
668  // verify integrity of analyzerInfoMap before reading analyzerInfo
669  unsigned count = 0;
670  Module *lastmod = NULL;
671  for (index = 0; index < analyzerInfoMap.size (); index++)
672    {
673      cpf_stabs_t map = analyzerInfoMap.fetch (index);
674      if (map.type > 3)
675	{
676	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains table of unknown type %d for %s\n"),
677		   map.type, map.module->get_name ());
678	  return;
679	}
680      if (map.module != lastmod)
681	{
682	  if (lastmod != NULL)
683	    Dprintf (DEBUG_STABS, "analyzerInfo contains %d 0x0 offset tables for %s\n",
684		     count, lastmod->get_name ());
685	  count = 0;
686	}
687      count += (map.offset == 0x0); // only check for 0x0 tables for now
688      if (count > 4)
689	{
690	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains too many 0x0 offset tables for %s\n"),
691		   map.module->get_name ());
692	  return;
693	}
694      lastmod = map.module;
695    }
696
697  index = 0;
698  while ((index < analyzerInfoMap.size ()) && (read < InfoSize))
699    {
700      for (table = 0; table < 3; table++)
701	{ // memory operations (ld, st, prefetch)
702	  // read the table header
703	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
704	  InfoData += infoHdr_sz;
705	  read += infoHdr_sz;
706
707	  // use map for appropriate module
708	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
709	  index++;
710	  mitem = map.module;
711	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
712		   "text_labelref=0x%08llx entries=%d version=%d\n"
713		   "itype %d offset=0x%04x module=%s\n", table, read,
714		   (long long) (h.text_labelref - baseAddr), h.entries,
715		   h.version, map.type, map.offset, map.module->get_name ());
716	  // read the table entries
717	  for (entry = 0; entry < h.entries; entry++)
718	    {
719	      memop_info_t *m = new memop_info_t;
720	      unsigned memop_info_sz = sizeof (memop_info_t);
721	      memcpy ((void *) m, (const void *) InfoData, memop_info_sz);
722	      InfoData += memop_info_sz;
723	      read += memop_info_sz;
724	      m->offset += (uint32_t) (h.text_labelref - baseAddr);
725	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n"),
726		       entry, table, m->offset, m->id, m->signature, m->datatype_id);
727	      switch (table)
728		{
729		case CPF_INSTR_TYPE_LD:
730		  mitem->ldMemops.append (m);
731		  break;
732		case CPF_INSTR_TYPE_ST:
733		  mitem->stMemops.append (m);
734		  break;
735		case CPF_INSTR_TYPE_PREFETCH:
736		  mitem->pfMemops.append (m);
737		  break;
738		}
739	    }
740	  // following re-alignment should be redundant
741	  //InfoData+=(read%InfoAlign); read+=(read%InfoAlign); // re-align
742	}
743      for (table = 3; table < 4; table++)
744	{ // branch targets
745	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
746	  InfoData += infoHdr_sz;
747	  read += infoHdr_sz;
748
749	  // use map for appropriate module
750	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
751	  index++;
752	  mitem = map.module;
753	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
754		   "text_labelref=0x%08llx entries=%d version=%d\n"
755		   "itype %d offset=0x%04x module=%s\n", table, read,
756		   (long long) (h.text_labelref - baseAddr), h.entries,
757		   h.version, map.type, map.offset, map.module->get_name ());
758	  for (entry = 0; entry < h.entries; entry++)
759	    {
760	      target_info_t *t = new target_info_t;
761	      unsigned target_info_sz = sizeof (target_info_t);
762	      memcpy ((void *) t, (const void *) InfoData, target_info_sz);
763	      InfoData += target_info_sz;
764	      read += target_info_sz;
765	      t->offset += (uint32_t) (h.text_labelref - baseAddr);
766	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x\n"), entry,
767		       table, t->offset);
768	      // the list of branch targets needs to be in offset sorted order
769	      // and doing it here before archiving avoids the need to do it
770	      // each time the archive is read.
771	      mitem->bTargets.incorporate (t, targetOffsetCmp);
772	    }
773	  Dprintf (DEBUG_STABS, NTXT ("bTargets for %s has %lld items (last=0x%04x)\n"),
774		   mitem->get_name (), (long long) mitem->bTargets.size (),
775		   (mitem->bTargets.fetch (mitem->bTargets.size () - 1))->offset);
776	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
777		   read, (ul_t) InfoData);
778	  InfoData += (read % InfoAlign);
779	  read += (read % InfoAlign); // re-align
780	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
781		   read, (ul_t) InfoData);
782	}
783      Dprintf (DEBUG_STABS, "Stabs::check_AnalyzerInfo bytes read=%lld (index=%lld/%lld)\n",
784	       (long long) read, (long long) index,
785	       (long long) analyzerInfoMap.size ());
786    }
787}
788
789void
790Stabs::check_Info (Vector<ComC*> *comComs)
791{
792  Elf *elf = openElf (true);
793  if (elf == NULL || elf->info == 0)
794    return;
795  Elf_Data *data = elf->elf_getdata (elf->info);
796  uint64_t InfoSize = data->d_size;
797  char *InfoData = (char *) data->d_buf;
798  bool get_src = false;
799  for (int h_num = 0; InfoSize; h_num++)
800    {
801      if (InfoSize < sizeof (struct info_header))
802	return;
803      struct info_header *h = (struct info_header*) InfoData;
804      if (h->endian != '\0' || h->magic[0] != 'S' || h->magic[1] != 'U'
805	  || h->magic[2] != 'N')
806	return;
807      if (h->len < InfoSize || h->len < sizeof (struct info_header) || (h->len & 3))
808	return;
809
810      char *fname = InfoData + sizeof (struct info_header);
811      InfoData += h->len;
812      InfoSize -= h->len;
813      get_src = check_src_name (fname);
814      for (uint32_t e_num = 0; e_num < h->cnt; ++e_num)
815	{
816	  if (InfoSize < sizeof (struct entry_header))
817	    return;
818	  struct entry_header *e = (struct entry_header*) InfoData;
819	  if (InfoSize < e->len)
820	    return;
821	  int32_t copy_inout = 0;
822	  if (e->len > sizeof (struct entry_header))
823	    if (e->type == F95_COPYINOUT)
824	      copy_inout = *(int32_t*) (InfoData + sizeof (struct entry_header));
825	  InfoData += e->len;
826	  InfoSize -= e->len;
827	  if (get_src)
828	    {
829	      ComC *citem = new ComC;
830	      citem->sec = INFO_SEC + h_num;
831	      citem->type = e->msgnum & 0xFFFFFF;
832	      citem->visible = CCMV_ALL;
833	      citem->line = e->line;
834	      citem->com_str = get_info_com (citem->type, copy_inout);
835	      comComs->append (citem);
836	    }
837	}
838      if (get_src)
839	break;
840    }
841}
842
843static char *
844get_info_com (int type, int32_t copy_inout)
845{
846  switch (type)
847    {
848    case 1:
849      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in -- loop(s) inserted"),
850			  copy_inout);
851    case 2:
852      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-out -- loop(s) inserted"),
853			  copy_inout);
854    case 3:
855      return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in and a copy-out -- loops inserted"),
856			  copy_inout);
857    case 4:
858      return dbe_strdup (GTXT ("Alignment of variables in common block may cause performance degradation"));
859    case 5:
860      return dbe_strdup (GTXT ("DO statement bounds lead to no executions of the loop"));
861    default:
862      return dbe_strdup (NTXT (""));
863    }
864}
865
866void
867Stabs::check_Loop (Vector<ComC*> *comComs)
868{
869  Elf *elf = openElf (true);
870  if (elf == NULL)
871    return;
872
873  StringBuilder sb;
874  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
875    {
876      char *name = elf->get_sec_name (sec);
877      if (name == NULL)
878	continue;
879      if (!streq (name, NTXT (".loops")) && !streq (name, NTXT (".loopview")))
880	continue;
881
882      Elf_Data *data = elf->elf_getdata (sec);
883      size_t LoopSize = (size_t) data->d_size, len;
884      char *LoopData = (char *) data->d_buf;
885      int remainder, i;
886      char src[2 * MAXPATHLEN], buf1[MAXPATHLEN], buf2[MAXPATHLEN];
887      char **dep_str = NULL;
888      bool get_src = false;
889      while ((LoopSize > 0) && !get_src &&
890	     (strncmp (LoopData, NTXT ("Source:"), 7) == 0))
891	{
892	  // The first three items in a .loops subsection are three strings.
893	  //	Source: ...
894	  //	Version: ...
895	  //	Number of loops: ...
896	  sscanf (LoopData, NTXT ("%*s%s"), src);
897	  len = strlen (LoopData) + 1;
898	  LoopData += len;
899	  LoopSize -= len;
900	  sscanf (LoopData, NTXT ("%*s%*s%s"), buf1);
901	  //	double version   = atof(buf1);
902	  len = strlen (LoopData) + 1;
903	  LoopData += len;
904	  LoopSize -= len;
905	  get_src = check_src_name (src);
906	  sscanf (LoopData, NTXT ("%*s%*s%*s%s%s"), buf1, buf2);
907	  int n_loop = atoi (buf1);
908	  int n_depend = atoi (buf2);
909	  len = strlen (LoopData) + 1;
910	  LoopData += len;
911	  LoopSize -= len;
912	  if (get_src && (n_loop > 0))
913	    {
914	      dep_str = new char*[n_loop];
915	      for (i = 0; i < n_loop; i++)
916		dep_str[i] = NULL;
917	    }
918
919	  // printf("Source: %s\nVersion: %f\nLoop#: %d\nDepend#: %d\n",
920	  //	src, version, n_loop, n_depend);
921
922	  // Read in the strings that contain the list of variables that cause
923	  // data dependencies inside of loops. Not every loop has such a list
924	  // of variables.
925	  //
926	  //	Example: if loop #54 has data dependencies caused by the
927	  //	variables named i, j and foo, then the string that represents
928	  //	this in the .loops section looks like this:
929	  //
930	  //	.asciz "54:i.j.foo"
931	  //
932	  //	The variable names are delimited with .
933	  //
934	  //	For now, store these strings in an array, and add them into
935	  //	the loop structure when we read in the numeric loop info
936	  //	(that's what we read in next.)
937	  //
938	  // printf("\tDependenncies:\n");
939	  for (i = 0; i < n_depend; i++)
940	    {
941	      len = strlen (LoopData) + 1;
942	      LoopData += len;
943	      LoopSize -= len;
944	      if (dep_str != NULL)
945		{
946		  char *dep_buf1 = dbe_strdup (LoopData);
947		  char *ptr = strtok (dep_buf1, NTXT (":"));
948		  if (ptr != NULL)
949		    {
950		      int index = atoi (ptr);
951		      bool dep_first = true;
952		      sb.setLength (0);
953		      while ((ptr = strtok (NULL, NTXT (", "))) != NULL)
954			{
955			  if (dep_first)
956			    dep_first = false;
957			  else
958			    sb.append (NTXT (", "));
959			  sb.append (ptr);
960			}
961		      if (sb.length () > 0 && index < n_loop)
962			dep_str[index] = sb.toString ();
963		    }
964		  free (dep_buf1);
965		}
966	    }
967
968	  // Adjust Data pointer so that it is word aligned.
969	  remainder = (int) (((unsigned long) LoopData) % 4);
970	  if (remainder != 0)
971	    {
972	      len = 4 - remainder;
973	      LoopData += len;
974	      LoopSize -= len;
975	    }
976
977	  // Read in the loop info, one loop at a time.
978	  for (i = 0; i < n_loop; i++)
979	    {
980	      int loopid = *((int *) LoopData);
981	      LoopData += 4;
982	      int line_no = *((int *) LoopData);
983	      if (line_no < 1) // compiler has trouble on this
984		line_no = 1;
985	      LoopData += 4;
986	      //	    int nest = *((int *) LoopData);
987	      LoopData += 4;
988	      int parallel = *((int *) LoopData);
989	      LoopData += 4;
990	      unsigned hints = *((unsigned *) LoopData);
991	      LoopData += 4;
992	      //	    int count = *((int *) LoopData);
993	      LoopData += 4;
994	      LoopSize -= 24;
995	      if (!get_src || (loopid >= n_loop))
996		continue;
997	      ComC *citem = new ComC;
998	      citem->sec = LOOP_SEC + i;
999	      citem->type = hints;
1000	      citem->visible = CCMV_ALL;
1001	      citem->line = line_no;
1002	      citem->com_str = get_lp_com (hints, parallel, dep_str[loopid]);
1003	      comComs->append (citem);
1004	    }
1005	  if (dep_str)
1006	    {
1007	      for (i = 0; i < n_loop; i++)
1008		free (dep_str[i]);
1009	      delete[] dep_str;
1010	      dep_str = NULL;
1011	    }
1012	}
1013    }
1014}
1015
1016static char *
1017get_lp_com (unsigned hints, int parallel, char *dep)
1018{
1019  StringBuilder sb;
1020  if (parallel == -1)
1021    sb.append (GTXT ("Loop below is serial, but parallelizable: "));
1022  else if (parallel == 0)
1023    sb.append (GTXT ("Loop below is not parallelized: "));
1024  else
1025    sb.append (GTXT ("Loop below is parallelized: "));
1026  switch (hints)
1027    {
1028    case 0:
1029      // No loop mesg will print
1030      // strcat(com, GTXT("no hint available"));
1031      break;
1032    case 1:
1033      sb.append (GTXT ("loop contains procedure call"));
1034      break;
1035    case 2:
1036      sb.append (GTXT ("compiler generated two versions of this loop"));
1037      break;
1038    case 3:
1039      {
1040	StringBuilder sb_tmp;
1041	sb_tmp.sprintf (GTXT ("the variable(s) \"%s\" cause a data dependency in this loop"),
1042			dep ? dep : GTXT ("<Unknown>"));
1043	sb.append (&sb_tmp);
1044      }
1045      break;
1046    case 4:
1047      sb.append (GTXT ("loop was significantly transformed during optimization"));
1048      break;
1049    case 5:
1050      sb.append (GTXT ("loop may or may not hold enough work to be profitably parallelized"));
1051      break;
1052    case 6:
1053      sb.append (GTXT ("loop was marked by user-inserted pragma"));
1054      break;
1055    case 7:
1056      sb.append (GTXT ("loop contains multiple exits"));
1057      break;
1058    case 8:
1059      sb.append (GTXT ("loop contains I/O, or other function calls, that are not MT safe"));
1060      break;
1061    case 9:
1062      sb.append (GTXT ("loop contains backward flow of control"));
1063      break;
1064    case 10:
1065      sb.append (GTXT ("loop may have been distributed"));
1066      break;
1067    case 11:
1068      sb.append (GTXT ("two loops or more may have been fused"));
1069      break;
1070    case 12:
1071      sb.append (GTXT ("two or more loops may have been interchanged"));
1072      break;
1073    default:
1074      break;
1075    }
1076  return sb.toString ();
1077}
1078
1079StabReader::StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec)
1080{
1081  stabCnt = -1;
1082  stabNum = 0;
1083  if (_elf == NULL)
1084    return;
1085  elf = _elf;
1086
1087  // Get ELF data
1088  Elf_Data *data = elf->elf_getdata (StabSec);
1089  if (data == NULL)
1090    return;
1091  uint64_t stabSize = data->d_size;
1092  StabData = (char *) data->d_buf;
1093  Elf_Internal_Shdr *shdr = elf->get_shdr (StabSec);
1094  if (shdr == NULL)
1095    return;
1096
1097  // GCC bug: sh_entsize is 20 for 64 apps on Linux
1098  StabEntSize = (platform == Amd64 || platform == Sparcv9) ? 12 : (unsigned) shdr->sh_entsize;
1099  if (stabSize == 0 || StabEntSize == 0)
1100    return;
1101  data = elf->elf_getdata (StabStrSec);
1102  if (data == NULL)
1103    return;
1104  shdr = elf->get_shdr (StabStrSec);
1105  if (shdr == NULL)
1106    return;
1107  StabStrtab = (char *) data->d_buf;
1108  StabStrtabEnd = StabStrtab + shdr->sh_size;
1109  StrTabSize = 0;
1110  stabCnt = (int) (stabSize / StabEntSize);
1111}
1112
1113char *
1114StabReader::get_stab (struct stab *np, bool comdat)
1115{
1116  struct stab *stbp = (struct stab *) (StabData + stabNum * StabEntSize);
1117  stabNum++;
1118  *np = *stbp;
1119  np->n_desc = elf->decode (stbp->n_desc);
1120  np->n_strx = elf->decode (stbp->n_strx);
1121  np->n_value = elf->decode (stbp->n_value);
1122  switch (np->n_type)
1123    {
1124    case N_UNDF:
1125    case N_ILDPAD:
1126      // Start of new stab section (or padding)
1127      StabStrtab += StrTabSize;
1128      StrTabSize = np->n_value;
1129    }
1130
1131  char *str = NULL;
1132  if (np->n_strx)
1133    {
1134      if (comdat && np->n_type == N_FUN && np->n_other == 1)
1135	{
1136	  if (np->n_strx == 1)
1137	    StrTabSize++;
1138	  str = StabStrtab + StrTabSize;
1139	  // Each COMDAT string must be sized to find the next string:
1140	  StrTabSize += strlen (str) + 1;
1141	}
1142      else
1143	str = StabStrtab + np->n_strx;
1144      if (str >= StabStrtabEnd)
1145	str = NULL;
1146    }
1147  if (DEBUG_STABS)
1148    {
1149      char buf[128];
1150      char *s = get_type_name (np->n_type);
1151      if (s == NULL)
1152	{
1153	  snprintf (buf, sizeof (buf), NTXT ("n_type=%d"), np->n_type);
1154	  s = buf;
1155	}
1156      if (str)
1157	{
1158	  Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabs \"%s\",%s,0x%x,0x%x,0x%x\n"),
1159		   stabNum - 1, str, s, (int) np->n_other, (int) np->n_desc,
1160		   (int) np->n_value);
1161	}
1162      else
1163	Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabn %s,0x%x,0x%x,0x%x\n"),
1164		 stabNum - 1, s, (int) np->n_other, (int) np->n_desc,
1165		 (int) np->n_value);
1166    }
1167  return str;
1168}
1169
1170void
1171StabReader::parse_N_OPT (Module *mod, char *str)
1172{
1173  if (mod == NULL || str == NULL)
1174      return;
1175  for (char *s = str; 1; s++)
1176    {
1177      switch (*s)
1178	{
1179	case 'd':
1180	  if (s[1] == 'i' && s[2] == ';')
1181	    {
1182	      delete mod->dot_o_file;
1183	      mod->dot_o_file = NULL;
1184	    }
1185	  break;
1186	case 's':
1187	  if ((s[1] == 'i' || s[1] == 'n') && s[2] == ';')
1188	    {
1189	      delete mod->dot_o_file;
1190	      mod->dot_o_file = NULL;
1191	    }
1192	  break;
1193	}
1194      s = strchr (s, ';');
1195      if (s == NULL)
1196	break;
1197    }
1198}
1199
1200Stabs::Stab_status
1201Stabs::srcline_Stabs (Module *module, unsigned int StabSec,
1202		      unsigned int StabStrSec, bool comdat)
1203{
1204  StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec);
1205  int tot = stabReader->stabCnt;
1206  if (tot < 0)
1207    {
1208      delete stabReader;
1209      return DBGD_ERR_NO_STABS;
1210    }
1211  int n, lineno;
1212  char *sbase, *n_so = NTXT (""), curr_src[2 * MAXPATHLEN];
1213  Function *newFunc;
1214  Sp_lang_code _lang_code = module->lang_code;
1215  Vector<Function*> *functions = module->functions;
1216  bool no_stabs = true;
1217  *curr_src = '\0';
1218  Function *func = NULL;
1219  int phase = 0;
1220  int stabs_level = 0;
1221  int xline = 0;
1222
1223  // Find module
1224  for (n = 0; n < tot; n++)
1225    {
1226      struct stab stb;
1227      char *str = stabReader->get_stab (&stb, comdat);
1228      if (stb.n_type == N_UNDF)
1229	phase = 0;
1230      else if (stb.n_type == N_SO)
1231	{
1232	  if (str == NULL || *str == '\0')
1233	    continue;
1234	  if (phase == 0)
1235	    {
1236	      phase = 1;
1237	      n_so = str;
1238	      continue;
1239	    }
1240	  phase = 0;
1241	  sbase = str;
1242	  if (*str == '/')
1243	    {
1244	      if (streq (sbase, module->file_name))
1245		break;
1246	    }
1247	  else
1248	    {
1249	      size_t last = strlen (n_so);
1250	      if (n_so[last - 1] == '/')
1251		last--;
1252	      if (strncmp (n_so, module->file_name, last) == 0 &&
1253		  module->file_name[last] == '/' &&
1254		  streq (sbase, module->file_name + last + 1))
1255		break;
1256	    }
1257	}
1258    }
1259  if (n >= tot)
1260    {
1261      delete stabReader;
1262      return DBGD_ERR_NO_STABS;
1263    }
1264
1265  Include *includes = new Include;
1266  includes->new_src_file (module->getMainSrc (), 0, NULL);
1267  module->hasStabs = true;
1268  *curr_src = '\0';
1269  phase = 0;
1270  for (n++; n < tot; n++)
1271    {
1272      struct stab stb;
1273      char *str = stabReader->get_stab (&stb, comdat);
1274      int n_desc = (int) ((unsigned short) stb.n_desc);
1275      switch (stb.n_type)
1276	{
1277	case N_UNDF:
1278	case N_SO:
1279	case N_ENDM:
1280	  n = tot;
1281	  break;
1282	case N_ALIAS:
1283	  if (str == NULL)
1284	    break;
1285	  if (is_fortran (_lang_code))
1286	    {
1287	      char *p = strchr (str, ':');
1288	      if (p && streq (p + 1, NTXT ("FMAIN")))
1289		{
1290		  Function *afunc = find_func (NTXT ("MAIN"), functions, true);
1291		  if (afunc)
1292		    afunc->set_match_name (dbe_strndup (str, p - str));
1293		  break;
1294		}
1295	    }
1296	case N_FUN:
1297	case N_OUTL:
1298	  if (str == NULL)
1299	    break;
1300	  if (*str == '@')
1301	    {
1302	      str++;
1303	      if (*str == '>' || *str == '<')
1304		str++;
1305	    }
1306	  if (stabs_level != 0)
1307	    break;
1308
1309	  // find address of the enclosed function
1310	  newFunc = find_func (str, functions, is_fortran (_lang_code));
1311	  if (newFunc == NULL)
1312	    break;
1313	  if (func)
1314	    while (func->popSrcFile ())
1315	      ;
1316	  func = newFunc;
1317
1318	  // First line info to cover function from the beginning
1319	  lineno = xline + n_desc;
1320	  if (lineno > 0)
1321	    {
1322	      // Set the chain of includes for the new function
1323	      includes->push_src_files (func);
1324	      func->add_PC_info (0, lineno);
1325	      no_stabs = false;
1326	    }
1327	  break;
1328	case N_ENTRY:
1329	  break;
1330	case N_CMDLINE:
1331	  if (str && !module->comp_flags)
1332	    {
1333	      char *comp_flags = strchr (str, ';');
1334	      if (comp_flags)
1335		{
1336		  module->comp_flags = dbe_strdup (comp_flags + 1);
1337		  module->comp_dir = dbe_strndup (str, comp_flags - str);
1338		}
1339	    }
1340	  break;
1341	case N_LBRAC:
1342	  stabs_level++;
1343	  break;
1344	case N_RBRAC:
1345	  stabs_level--;
1346	  break;
1347	case N_XLINE:
1348	  xline = n_desc << 16;
1349	  break;
1350	case N_SLINE:
1351	  if (func == NULL)
1352	    break;
1353	  no_stabs = false;
1354	  lineno = xline + n_desc;
1355	  if (func->line_first <= 0)
1356	    {
1357	      // Set the chain of includes for the new function
1358	      includes->push_src_files (func);
1359	      func->add_PC_info (0, lineno);
1360	      break;
1361	    }
1362	  if (func->curr_srcfile == NULL)
1363	    includes->push_src_files (func);
1364	  if (func->line_first != lineno ||
1365	      !streq (curr_src, func->getDefSrc ()->get_name ()))
1366	    func->add_PC_info (stb.n_value, lineno);
1367	  break;
1368	case N_OPT:
1369	  if ((str != NULL) && streq (str, NTXT ("gcc2_compiled.")))
1370	    _lang_code = Sp_lang_gcc;
1371	  switch (elfDbg->elf_getehdr ()->e_type)
1372	    {
1373	    case ET_EXEC:
1374	    case ET_DYN:
1375	      // set the real object timestamp from the executable's N_OPT stab
1376	      // due to bug #4796329
1377	      module->real_timestamp = stb.n_value;
1378	      break;
1379	    default:
1380	      module->curr_timestamp = stb.n_value;
1381	      break;
1382	    }
1383	  break;
1384	case N_GSYM:
1385	  if ((str == NULL) || strncmp (str, NTXT ("__KAI_K"), 7))
1386	    break;
1387	  str += 7;
1388	  if (!strncmp (str, NTXT ("CC_"), 3))
1389	    _lang_code = Sp_lang_KAI_KCC;
1390	  else if (!strncmp (str, NTXT ("cc_"), 3))
1391	    _lang_code = Sp_lang_KAI_Kcc;
1392	  else if (!strncmp (str, NTXT ("PTS_"), 4) &&
1393		   (_lang_code != Sp_lang_KAI_KCC) &&
1394		   (_lang_code != Sp_lang_KAI_Kcc))
1395	    _lang_code = Sp_lang_KAI_KPTS;
1396	  break;
1397	case N_BINCL:
1398	  includes->new_include_file (module->setIncludeFile (str), func);
1399	  break;
1400	case N_EINCL:
1401	  includes->end_include_file (func);
1402	  break;
1403	case N_SOL:
1404	  if (str == NULL)
1405	    break;
1406	  lineno = xline + n_desc;
1407	  if (lineno > 0 && func && func->line_first <= 0)
1408	    {
1409	      includes->push_src_files (func);
1410	      func->add_PC_info (0, lineno);
1411	      no_stabs = false;
1412	    }
1413	  if (streq (sbase, str))
1414	    {
1415	      module->setIncludeFile (NULL);
1416	      snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
1417	      includes->new_src_file (module->getMainSrc (), lineno, func);
1418	    }
1419	  else
1420	    {
1421	      if (streq (sbase, get_basename (str)))
1422		{
1423		  module->setIncludeFile (NULL);
1424		  snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
1425		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
1426		}
1427	      else
1428		{
1429		  if (*str == '/')
1430		    snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), str);
1431		  else
1432		    {
1433		      size_t last = strlen (n_so);
1434		      if (last == 0 || n_so[last - 1] != '/')
1435			snprintf (curr_src, sizeof (curr_src), NTXT ("%s/%s"), n_so, str);
1436		      else
1437			snprintf (curr_src, sizeof (curr_src), NTXT ("%s%s"), n_so, str);
1438		    }
1439		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
1440		}
1441	    }
1442	  break;
1443	}
1444    }
1445  delete includes;
1446  delete stabReader;
1447  return no_stabs ? DBGD_ERR_NO_STABS : DBGD_ERR_NONE;
1448}//srcline_Stabs
1449
1450static bool
1451cmp_func_name (char *fname, size_t len, char *name, bool fortran)
1452{
1453  return (strncmp (name, fname, len) == 0
1454	  && (name[len] == 0
1455	      || (fortran && name[len] == '_' && name[len + 1] == 0)));
1456}
1457
1458Function *
1459Stabs::find_func (char *fname, Vector<Function*> *functions, bool fortran, bool inner_names)
1460{
1461  char *arg, *name;
1462  Function *item;
1463  int index;
1464  size_t len;
1465
1466  len = strlen (fname);
1467  arg = strchr (fname, ':');
1468  if (arg != NULL)
1469    {
1470      if (arg[1] == 'P') // Prototype for function
1471	return NULL;
1472      len -= strlen (arg);
1473    }
1474
1475  Vec_loop (Function*, functions, index, item)
1476  {
1477    name = item->get_mangled_name ();
1478    if (cmp_func_name (fname, len, name, fortran))
1479      return item->cardinal ();
1480  }
1481
1482  if (inner_names)
1483    {
1484      // Dwarf subprograms may only have plain (non-linker) names
1485      // Retry with inner names only
1486
1487      Vec_loop (Function*, functions, index, item)
1488      {
1489	name = strrchr (item->get_mangled_name (), '.');
1490	if (!name) continue;
1491	name++;
1492	if (cmp_func_name (fname, len, name, fortran))
1493	  return item->cardinal ();
1494      }
1495    }
1496  return NULL;
1497}
1498
1499Map<const char*, Symbol*> *
1500Stabs::get_elf_symbols ()
1501{
1502  Elf *elf = openElf (false);
1503  if (elf->elfSymbols == NULL)
1504    {
1505      Map<const char*, Symbol*> *elfSymbols = new StringMap<Symbol*>(128, 128);
1506      elf->elfSymbols = elfSymbols;
1507      for (int i = 0, sz = SymLst ? SymLst->size () : 0; i < sz; i++)
1508	{
1509	  Symbol *sym = SymLst->fetch (i);
1510	  elfSymbols->put (sym->name, sym);
1511	}
1512    }
1513  return elf->elfSymbols;
1514}
1515
1516void
1517Stabs::read_dwarf_from_dot_o (Module *mod)
1518{
1519  Dprintf (DEBUG_STABS, NTXT ("stabsModules: %s\n"), STR (mod->get_name ()));
1520  Vector<Module*> *mods = mod->dot_o_file->seg_modules;
1521  char *bname = get_basename (mod->get_name ());
1522  for (int i1 = 0, sz1 = mods ? mods->size () : 0; i1 < sz1; i1++)
1523    {
1524      Module *m = mods->fetch (i1);
1525      Dprintf (DEBUG_STABS, NTXT ("  MOD: %s\n"), STR (m->get_name ()));
1526      if (dbe_strcmp (bname, get_basename (m->get_name ())) == 0)
1527	{
1528	  mod->indexStabsLink = m;
1529	  m->indexStabsLink = mod;
1530	  break;
1531	}
1532    }
1533  if (mod->indexStabsLink)
1534    {
1535      mod->dot_o_file->objStabs->openDwarf ()->srcline_Dwarf (mod->indexStabsLink);
1536      Map<const char*, Symbol*> *elfSymbols = get_elf_symbols ();
1537      Vector<Function*> *funcs = mod->indexStabsLink->functions;
1538      for (int i1 = 0, sz1 = funcs ? funcs->size () : 0; i1 < sz1; i1++)
1539	{
1540	  Function *f1 = funcs->fetch (i1);
1541	  Symbol *sym = elfSymbols->get (f1->get_mangled_name ());
1542	  if (sym == NULL)
1543	    continue;
1544	  Dprintf (DEBUG_STABS, NTXT ("  Symbol: %s func=%p\n"), STR (sym->name), sym->func);
1545	  Function *f = sym->func;
1546	  if (f->indexStabsLink)
1547	    continue;
1548	  f->indexStabsLink = f1;
1549	  f1->indexStabsLink = f;
1550	  f->copy_PCInfo (f1);
1551	}
1552    }
1553}
1554
1555Stabs::Stab_status
1556Stabs::read_archive (LoadObject *lo)
1557{
1558  if (openElf (true) == NULL)
1559    return status;
1560  check_Symtab ();
1561  if (elfDbg->dwarf)
1562    openDwarf ()->archive_Dwarf (lo);
1563
1564  // get Module/Function lists from stabs info
1565  Stab_status statusStabs = DBGD_ERR_NO_STABS;
1566#define ARCHIVE_STABS(sec, secStr, comdat) \
1567    if ((elfDbg->sec) != 0  && (elfDbg->secStr) != 0 && \
1568	archive_Stabs(lo, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
1569	statusStabs = DBGD_ERR_NONE
1570
1571  // prefer index stabs (where they exist) since they're most appropriate
1572  // for loadobjects and might have N_CPROF stabs for ABS/CPF
1573  ARCHIVE_STABS (stabIndex, stabIndexStr, true);
1574  ARCHIVE_STABS (stabExcl, stabExclStr, false);
1575  ARCHIVE_STABS (stab, stabStr, false);
1576
1577  // Add all unassigned functions to the <unknown> module
1578  Symbol *sitem, *alias;
1579  int index;
1580  Vec_loop (Symbol*, SymLst, index, sitem)
1581  {
1582    if (sitem->func || (sitem->size == 0) || (sitem->flags & SYM_UNDEF))
1583      continue;
1584    alias = sitem->alias;
1585    if (alias)
1586      {
1587	if (alias->func == NULL)
1588	  {
1589	    alias->func = createFunction (lo, lo->noname, alias);
1590	    alias->func->alias = alias->func;
1591	  }
1592	if (alias != sitem)
1593	  {
1594	    sitem->func = createFunction (lo, alias->func->module, sitem);
1595	    sitem->func->alias = alias->func;
1596	  }
1597      }
1598    else
1599      sitem->func = createFunction (lo, lo->noname, sitem);
1600  }
1601  if (pltSym)
1602    {
1603      pltSym->func = createFunction (lo, lo->noname, pltSym);
1604      pltSym->func->flags |= FUNC_FLAG_PLT;
1605    }
1606
1607  // need Module association, so this must be done after handling Modules
1608  check_AnalyzerInfo ();
1609
1610  if (dwarf && dwarf->status == DBGD_ERR_NONE)
1611    return DBGD_ERR_NONE;
1612  return statusStabs;
1613}//read_archive
1614
1615Function *
1616Stabs::createFunction (LoadObject *lo, Module *module, Symbol *sym)
1617{
1618  Function *func = dbeSession->createFunction ();
1619  func->module = module;
1620  func->img_fname = path;
1621  func->img_offset = (off_t) sym->img_offset;
1622  func->save_addr = sym->save;
1623  func->size = (uint32_t) sym->size;
1624  func->set_name (sym->name);
1625  func->elfSym = sym;
1626  module->functions->append (func);
1627  lo->functions->append (func);
1628  return func;
1629}
1630
1631void
1632Stabs::fixSymtabAlias ()
1633{
1634  int ind, i, k;
1635  Symbol *sym, *bestAlias;
1636  SymLst->sort (SymImgOffsetCmp);
1637  ind = SymLst->size () - 1;
1638  for (i = 0; i < ind; i++)
1639    {
1640      bestAlias = SymLst->fetch (i);
1641      if (bestAlias->img_offset == 0) // Ignore this bad symbol
1642	continue;
1643      sym = SymLst->fetch (i + 1);
1644      if (bestAlias->img_offset != sym->img_offset)
1645	{
1646	  if ((bestAlias->size == 0) ||
1647	      (sym->img_offset < bestAlias->img_offset + bestAlias->size))
1648	    bestAlias->size = sym->img_offset - bestAlias->img_offset;
1649	  continue;
1650	}
1651
1652      // Find a "best" alias
1653      size_t bestLen = strlen (bestAlias->name);
1654      int64_t maxSize = bestAlias->size;
1655      for (k = i + 1; k <= ind; k++)
1656	{
1657	  sym = SymLst->fetch (k);
1658	  if (bestAlias->img_offset != sym->img_offset)
1659	    { // no more aliases
1660	      if ((maxSize == 0) ||
1661		  (sym->img_offset < bestAlias->img_offset + maxSize))
1662		maxSize = sym->img_offset - bestAlias->img_offset;
1663	      break;
1664	    }
1665	  if (maxSize < sym->size)
1666	    maxSize = sym->size;
1667	  size_t len = strlen (sym->name);
1668	  if (len < bestLen)
1669	    {
1670	      bestAlias = sym;
1671	      bestLen = len;
1672	    }
1673	}
1674      for (; i < k; i++)
1675	{
1676	  sym = SymLst->fetch (i);
1677	  sym->alias = bestAlias;
1678	  sym->size = maxSize;
1679	}
1680      i--;
1681    }
1682}
1683
1684void
1685Stabs::check_Symtab ()
1686{
1687  if (st_check_symtab)
1688    return;
1689  st_check_symtab = true;
1690
1691  Elf *elf = openElf (true);
1692  if (elf == NULL)
1693    return;
1694  if (elfDis->plt != 0)
1695    {
1696      Elf_Internal_Shdr *shdr = elfDis->get_shdr (elfDis->plt);
1697      if (shdr)
1698	{
1699	  pltSym = new Symbol ();
1700	  pltSym->value = shdr->sh_addr;
1701	  pltSym->size = shdr->sh_size;
1702	  pltSym->img_offset = shdr->sh_offset;
1703	  pltSym->name = dbe_strdup (NTXT ("@plt"));
1704	  pltSym->flags |= SYM_PLT;
1705	}
1706    }
1707  if (elf->symtab)
1708    readSymSec (elf->symtab, elf);
1709  else
1710    {
1711      readSymSec (elf->SUNW_ldynsym, elf);
1712      readSymSec (elf->dynsym, elf);
1713    }
1714}
1715
1716void
1717Stabs::readSymSec (unsigned int sec, Elf *elf)
1718{
1719  Symbol *sitem;
1720  Sp_lang_code local_lcode;
1721  if (sec == 0)
1722    return;
1723  // Get ELF data
1724  Elf_Data *data = elf->elf_getdata (sec);
1725  if (data == NULL)
1726    return;
1727  uint64_t SymtabSize = data->d_size;
1728  Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
1729
1730  if ((SymtabSize == 0) || (shdr->sh_entsize == 0))
1731    return;
1732  Elf_Data *data_str = elf->elf_getdata (shdr->sh_link);
1733  if (data_str == NULL)
1734    return;
1735  char *Strtab = (char *) data_str->d_buf;
1736
1737  // read func symbolic table
1738  for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++)
1739    {
1740      Elf_Internal_Sym Sym;
1741      elf->elf_getsym (data, n, &Sym);
1742      const char *st_name = Sym.st_name < data_str->d_size ?
1743	  (Strtab + Sym.st_name) : NTXT ("no_name");
1744      switch (GELF_ST_TYPE (Sym.st_info))
1745	{
1746	case STT_FUNC:
1747	  // Skip UNDEF symbols (bug 4817083)
1748	  if (Sym.st_shndx == 0)
1749	    {
1750	      if (Sym.st_value == 0)
1751		break;
1752	      sitem = new Symbol (SymLst);
1753	      sitem->flags |= SYM_UNDEF;
1754	      if (pltSym)
1755		sitem->img_offset = (uint32_t) (pltSym->img_offset +
1756						Sym.st_value - pltSym->value);
1757	    }
1758	  else
1759	    {
1760	      Elf_Internal_Shdr *shdrp = elfDis->get_shdr (Sym.st_shndx);
1761	      if (shdrp == NULL)
1762		break;
1763	      sitem = new Symbol (SymLst);
1764	      sitem->img_offset = (uint32_t) (shdrp->sh_offset +
1765					      Sym.st_value - shdrp->sh_addr);
1766	    }
1767	  sitem->size = Sym.st_size;
1768	  sitem->name = dbe_strdup (st_name);
1769	  sitem->value = is_relocatable () ? sitem->img_offset : Sym.st_value;
1770	  if (GELF_ST_BIND (Sym.st_info) == STB_LOCAL)
1771	    {
1772	      sitem->local_ind = LocalFile->size () - 1;
1773	      LocalLst->append (sitem);
1774	    }
1775	  break;
1776	case STT_NOTYPE:
1777	  if (streq (st_name, NTXT ("gcc2_compiled.")))
1778	    {
1779	      sitem = new Symbol (SymLst);
1780	      sitem->lang_code = Sp_lang_gcc;
1781	      sitem->name = dbe_strdup (st_name);
1782	      sitem->local_ind = LocalFile->size () - 1;
1783	      LocalLst->append (sitem);
1784	    }
1785	  break;
1786	case STT_OBJECT:
1787	  if (!strncmp (st_name, NTXT ("__KAI_KPTS_"), 11))
1788	    local_lcode = Sp_lang_KAI_KPTS;
1789	  else if (!strncmp (st_name, NTXT ("__KAI_KCC_"), 10))
1790	    local_lcode = Sp_lang_KAI_KCC;
1791	  else if (!strncmp (st_name, NTXT ("__KAI_Kcc_"), 10))
1792	    local_lcode = Sp_lang_KAI_Kcc;
1793	  else
1794	    break;
1795	  sitem = new Symbol (LocalLst);
1796	  sitem->lang_code = local_lcode;
1797	  sitem->name = dbe_strdup (st_name);
1798	  break;
1799	case STT_FILE:
1800	  {
1801	    int last = LocalFile->size () - 1;
1802	    if (last >= 0 && LocalFileIdx->fetch (last) == LocalLst->size ())
1803	      {
1804		// There were no local functions in the latest file.
1805		free (LocalFile->get (last));
1806		LocalFile->store (last, dbe_strdup (st_name));
1807	      }
1808	    else
1809	      {
1810		LocalFile->append (dbe_strdup (st_name));
1811		LocalFileIdx->append (LocalLst->size ());
1812	      }
1813	    break;
1814	  }
1815	}
1816    }
1817  fixSymtabAlias ();
1818  SymLst->sort (SymValueCmp);
1819  get_save_addr (elf->need_swap_endian);
1820  dump ();
1821}//check_Symtab
1822
1823void
1824Stabs::check_Relocs ()
1825{
1826  // We may have many relocation tables to process: .rela.text%foo,
1827  // rela.text%bar, etc. On Intel, compilers generate .rel.text sections
1828  // which have to be processed as well. A lot of rework is needed here.
1829  Symbol *sptr = NULL;
1830  if (st_check_relocs)
1831    return;
1832  st_check_relocs = true;
1833
1834  Elf *elf = openElf (false);
1835  if (elf == NULL)
1836    return;
1837  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
1838    {
1839      bool use_rela, use_PLT;
1840      char *name = elf->get_sec_name (sec);
1841      if (name == NULL)
1842	continue;
1843      if (strncmp (name, NTXT (".rela.text"), 10) == 0)
1844	{
1845	  use_rela = true;
1846	  use_PLT = false;
1847	}
1848      else if (streq (name, NTXT (".rela.plt")))
1849	{
1850	  use_rela = true;
1851	  use_PLT = true;
1852	}
1853      else if (strncmp (name, NTXT (".rel.text"), 9) == 0)
1854	{
1855	  use_rela = false;
1856	  use_PLT = false;
1857	}
1858      else if (streq (name, NTXT (".rel.plt")))
1859	{
1860	  use_rela = false;
1861	  use_PLT = true;
1862	}
1863      else
1864	continue;
1865
1866      Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
1867      if (shdr == NULL)
1868	continue;
1869
1870      // Get ELF data
1871      Elf_Data *data = elf->elf_getdata (sec);
1872      if (data == NULL)
1873	continue;
1874      uint64_t ScnSize = data->d_size;
1875      uint64_t EntSize = shdr->sh_entsize;
1876      if ((ScnSize == 0) || (EntSize == 0))
1877	continue;
1878      int tot = (int) (ScnSize / EntSize);
1879
1880      // Get corresponding text section
1881      Elf_Internal_Shdr *shdr_txt = elf->get_shdr (shdr->sh_info);
1882      if (shdr_txt == NULL)
1883	continue;
1884      if (!(shdr_txt->sh_flags & SHF_EXECINSTR))
1885	continue;
1886
1887      // Get corresponding symbol table section
1888      Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
1889      if (shdr_sym == NULL)
1890	continue;
1891      Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
1892
1893      // Get corresponding string table section
1894      Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
1895      if (data_str == NULL)
1896	continue;
1897      char *Strtab = (char*) data_str->d_buf;
1898      for (int n = 0; n < tot; n++)
1899	{
1900	  Elf_Internal_Sym sym;
1901	  Elf_Internal_Rela rela;
1902	  char *symName;
1903	  if (use_rela)
1904	    elf->elf_getrela (data, n, &rela);
1905	  else
1906	    {
1907	      // GElf_Rela is extended GElf_Rel
1908	      elf->elf_getrel (data, n, &rela);
1909	      rela.r_addend = 0;
1910	    }
1911
1912	  int ndx = (int) GELF_R_SYM (rela.r_info);
1913	  elf->elf_getsym (data_sym, ndx, &sym);
1914	  switch (GELF_ST_TYPE (sym.st_info))
1915	    {
1916	    case STT_FUNC:
1917	    case STT_OBJECT:
1918	    case STT_NOTYPE:
1919	      if (sym.st_name == 0 || sym.st_name >= data_str->d_size)
1920		continue;
1921	      symName = Strtab + sym.st_name;
1922	      break;
1923	    case STT_SECTION:
1924	      {
1925		Elf_Internal_Shdr *secHdr = elf->get_shdr (sym.st_shndx);
1926		if (secHdr == NULL)
1927		  continue;
1928		if (sptr == NULL)
1929		  sptr = new Symbol;
1930		sptr->value = secHdr->sh_offset + rela.r_addend;
1931		long index = SymLst->bisearch (0, -1, &sptr, SymFindCmp);
1932		if (index == -1)
1933		  continue;
1934		Symbol *sp = SymLst->fetch (index);
1935		if (sptr->value != sp->value)
1936		  continue;
1937		symName = sp->name;
1938		break;
1939	      }
1940	    default:
1941	      continue;
1942	    }
1943	  Reloc *reloc = new Reloc;
1944	  reloc->name = dbe_strdup (symName);
1945	  reloc->type = GELF_R_TYPE (rela.r_info);
1946	  reloc->value = use_PLT ? rela.r_offset
1947		  : rela.r_offset + shdr_txt->sh_offset;
1948	  reloc->addend = rela.r_addend;
1949	  if (use_PLT)
1950	    RelPLTLst->append (reloc);
1951	  else
1952	    RelLst->append (reloc);
1953	}
1954    }
1955  delete sptr;
1956  RelLst->sort (RelValueCmp);
1957} //check_Relocs
1958
1959void
1960Stabs::get_save_addr (bool need_swap_endian)
1961{
1962  if (elfDis->is_Intel ())
1963    {
1964      for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++)
1965	{
1966	  Symbol *sitem = SymLst->fetch (j);
1967	  sitem->save = 0;
1968	}
1969      return;
1970    }
1971  for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++)
1972    {
1973      Symbol *sitem = SymLst->fetch (j);
1974      sitem->save = FUNC_NO_SAVE;
1975
1976      // If an image offset is not known skip it.
1977      // Works for artificial symbols like '@plt' as well.
1978      if (sitem->img_offset == 0)
1979	continue;
1980
1981      bool is_o7_moved = false;
1982      int64_t off = sitem->img_offset;
1983      for (int i = 0; i < sitem->size; i += 4)
1984	{
1985	  unsigned int cmd;
1986	  if (elfDis->get_data (off, sizeof (cmd), &cmd) == NULL)
1987	    break;
1988	  if (need_swap_endian)
1989	    SWAP_ENDIAN (cmd);
1990	  off += sizeof (cmd);
1991	  if ((cmd & 0xffffc000) == 0x9de38000)
1992	    { // save %sp, ??, %sp
1993	      sitem->save = i;
1994	      break;
1995	    }
1996	  else if ((cmd & 0xc0000000) == 0x40000000 || // call ??
1997	 (cmd & 0xfff80000) == 0xbfc00000)
1998	    { // jmpl ??, %o7
1999	      if (!is_o7_moved)
2000		{
2001		  sitem->save = FUNC_ROOT;
2002		  break;
2003		}
2004	    }
2005	  else if ((cmd & 0xc1ffe01f) == 0x8010000f)    // or %g0,%o7,??
2006	    is_o7_moved = true;
2007	}
2008    }
2009}
2010
2011uint64_t
2012Stabs::mapOffsetToAddress (uint64_t img_offset)
2013{
2014  Elf *elf = openElf (false);
2015  if (elf == NULL)
2016    return 0;
2017  if (is_relocatable ())
2018    return img_offset;
2019  for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
2020    {
2021      Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
2022      if (shdr == NULL)
2023	continue;
2024      if (img_offset >= (uint64_t) shdr->sh_offset
2025	  && img_offset < (uint64_t) (shdr->sh_offset + shdr->sh_size))
2026	return shdr->sh_addr + (img_offset - shdr->sh_offset);
2027    }
2028  return 0;
2029}
2030
2031Stabs::Stab_status
2032Stabs::archive_Stabs (LoadObject *lo, unsigned int StabSec,
2033		      unsigned int StabStrSec, bool comdat)
2034{
2035  StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec);
2036  int tot = stabReader->stabCnt;
2037  if (tot < 0)
2038    {
2039      delete stabReader;
2040      return DBGD_ERR_NO_STABS;
2041    }
2042
2043  char *sbase = NTXT (""), *arg, *fname, sname[2 * MAXPATHLEN];
2044  int lastMod, phase, stabs_level, modCnt = 0;
2045  Function *func = NULL;
2046  Module *mod;
2047#define INIT_MOD    phase = 0; stabs_level = 0; *sname = '\0'; mod = NULL
2048
2049  bool updateStabsMod = false;
2050  if (comdat && ((elfDbg->elf_getehdr ()->e_type == ET_EXEC) || (elfDbg->elf_getehdr ()->e_type == ET_DYN)))
2051    {
2052      if (stabsModules == NULL)
2053	stabsModules = new Vector<Module*>();
2054      updateStabsMod = true;
2055    }
2056  INIT_MOD;
2057  lastMod = lo->seg_modules->size ();
2058
2059  for (int n = 0; n < tot; n++)
2060    {
2061      struct stab stb;
2062      char *str = stabReader->get_stab (&stb, comdat);
2063      switch (stb.n_type)
2064	{
2065	case N_FUN:
2066	  // Ignore a COMDAT function, if there are two or more modules in 'lo'
2067	  if (comdat && stb.n_other == 1 && modCnt > 1)
2068	    break;
2069	case N_OUTL:
2070	case N_ALIAS:
2071	case N_ENTRY:
2072	  if (mod == NULL || str == NULL
2073	      || (stb.n_type != N_ENTRY && stabs_level != 0))
2074	    break;
2075	  if (*str == '@')
2076	    {
2077	      str++;
2078	      if (*str == '>' || *str == '<')
2079		str++;
2080	    }
2081
2082	  fname = dbe_strdup (str);
2083	  arg = strchr (fname, ':');
2084	  if (arg != NULL)
2085	    {
2086	      if (!strncmp (arg, NTXT (":P"), 2))
2087		{ // just prototype
2088		  free (fname);
2089		  break;
2090		}
2091	      *arg = '\0';
2092	    }
2093
2094	  func = append_Function (mod, fname);
2095	  free (fname);
2096	  break;
2097	case N_CMDLINE:
2098	  if (str && mod)
2099	    {
2100	      char *comp_flags = strchr (str, ';');
2101	      if (comp_flags)
2102		{
2103		  mod->comp_flags = dbe_strdup (comp_flags + 1);
2104		  mod->comp_dir = dbe_strndup (str, comp_flags - str);
2105		}
2106	    }
2107	  break;
2108	case N_LBRAC:
2109	  stabs_level++;
2110	  break;
2111	case N_RBRAC:
2112	  stabs_level--;
2113	  break;
2114	case N_UNDF:
2115	  INIT_MOD;
2116	  break;
2117	case N_ENDM:
2118	  INIT_MOD;
2119	  break;
2120	case N_OPT:
2121	  stabReader->parse_N_OPT (mod, str);
2122	  if (mod && (str != NULL) && streq (str, NTXT ("gcc2_compiled.")))
2123	    // Is it anachronism ?
2124	    mod->lang_code = Sp_lang_gcc;
2125	  break;
2126	case N_GSYM:
2127	  if (mod && (str != NULL))
2128	    {
2129	      if (strncmp (str, NTXT ("__KAI_K"), 7))
2130		break;
2131	      str += 7;
2132	      if (!strncmp (str, NTXT ("CC_"), 3))
2133		mod->lang_code = Sp_lang_KAI_KCC;
2134	      else if (!strncmp (str, NTXT ("cc_"), 3))
2135		mod->lang_code = Sp_lang_KAI_Kcc;
2136	      else if (!strncmp (str, NTXT ("PTS_"), 4) &&
2137		       (mod->lang_code != Sp_lang_KAI_KCC) &&
2138		       (mod->lang_code != Sp_lang_KAI_Kcc))
2139		mod->lang_code = Sp_lang_KAI_KPTS;
2140	    }
2141	  break;
2142	case N_SO:
2143	  if (str == NULL || *str == '\0')
2144	    {
2145	      INIT_MOD;
2146	      break;
2147	    }
2148	  if (phase == 0)
2149	    {
2150	      phase = 1;
2151	      sbase = str;
2152	    }
2153	  else
2154	    {
2155	      if (*str == '/')
2156		sbase = str;
2157	      else
2158		{
2159		  size_t last = strlen (sbase);
2160		  if (last == 0 || sbase[last - 1] != '/')
2161		    snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str);
2162		  else
2163		    snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str);
2164		  sbase = sname;
2165		}
2166	      mod = append_Module (lo, sbase, lastMod);
2167	      if (updateStabsMod)
2168		stabsModules->append (mod);
2169	      mod->hasStabs = true;
2170	      modCnt++;
2171	      if ((mod->lang_code != Sp_lang_gcc) &&
2172		  (mod->lang_code != Sp_lang_KAI_KPTS) &&
2173		  (mod->lang_code != Sp_lang_KAI_KCC) &&
2174		  (mod->lang_code != Sp_lang_KAI_Kcc))
2175		mod->lang_code = (Sp_lang_code) stb.n_desc;
2176	      *sname = '\0';
2177	      phase = 0;
2178	    }
2179	  break;
2180	case N_OBJ:
2181	  if (str == NULL)
2182	    break;
2183	  if (phase == 0)
2184	    {
2185	      phase = 1;
2186	      sbase = str;
2187	    }
2188	  else
2189	    {
2190	      if (*str == '/')
2191		sbase = str;
2192	      else
2193		{
2194		  size_t last = strlen (sbase);
2195		  if (last == 0 || sbase[last - 1] != '/')
2196		    snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str);
2197		  else
2198		    snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str);
2199		  sbase = sname;
2200		}
2201	      if (mod && (mod->dot_o_file == NULL))
2202		{
2203		  if (strcmp (sbase, NTXT ("/")) == 0)
2204		    mod->set_name (dbe_strdup (path));
2205		  else
2206		    {
2207		      mod->set_name (dbe_strdup (sbase));
2208		      mod->dot_o_file = mod->createLoadObject (sbase);
2209		    }
2210		}
2211	      *sname = '\0';
2212	      phase = 0;
2213	    }
2214	  break;
2215	case N_CPROF:
2216	  cpf_stabs_t map;
2217	  Dprintf (DEBUG_STABS, NTXT ("N_CPROF n_desc=%x n_value=0x%04x mod=%s\n"),
2218		   stb.n_desc, stb.n_value, (mod == NULL) ? NTXT ("???") : mod->get_name ());
2219	  map.type = stb.n_desc;
2220	  map.offset = stb.n_value;
2221	  map.module = mod;
2222	  analyzerInfoMap.append (map);
2223	  break;
2224	}
2225    }
2226  delete stabReader;
2227  return func ? DBGD_ERR_NONE : DBGD_ERR_NO_STABS;
2228}
2229
2230Module *
2231Stabs::append_Module (LoadObject *lo, char *name, int lastMod)
2232{
2233  Module *module;
2234  int size;
2235  Symbol *sitem;
2236
2237  if (lo->seg_modules != NULL)
2238    {
2239      size = lo->seg_modules->size ();
2240      if (size < lastMod)
2241	lastMod = size;
2242      for (int i = 0; i < lastMod; i++)
2243	{
2244	  module = lo->seg_modules->fetch (i);
2245	  if (module->linkerStabName && streq (module->linkerStabName, name))
2246	    return module;
2247	}
2248    }
2249  module = dbeSession->createModule (lo, NULL);
2250  module->set_file_name (dbe_strdup (name));
2251  module->linkerStabName = dbe_strdup (module->file_name);
2252
2253  // Append all functions with 'local_ind == -1' to the module.
2254  if (LocalLst->size () > 0)
2255    {
2256      sitem = LocalLst->fetch (0);
2257      if (!sitem->defined && sitem->local_ind == -1)
2258	// Append all functions with 'local_ind == -1' to the module.
2259	append_local_funcs (module, 0);
2260    }
2261
2262  // Append local func
2263  char *basename = get_basename (name);
2264  size = LocalFile->size ();
2265  for (int i = 0; i < size; i++)
2266    {
2267      if (streq (basename, LocalFile->fetch (i)))
2268	{
2269	  int local_ind = LocalFileIdx->fetch (i);
2270	  if (local_ind >= LocalLst->size ())
2271	    break;
2272	  sitem = LocalLst->fetch (local_ind);
2273	  if (!sitem->defined)
2274	    {
2275	      append_local_funcs (module, local_ind);
2276	      break;
2277	    }
2278	}
2279    }
2280  return module;
2281}
2282
2283void
2284Stabs::append_local_funcs (Module *module, int first_ind)
2285{
2286  Symbol *sitem = LocalLst->fetch (first_ind);
2287  int local_ind = sitem->local_ind;
2288  int size = LocalLst->size ();
2289  for (int i = first_ind; i < size; i++)
2290    {
2291      sitem = LocalLst->fetch (i);
2292      if (sitem->local_ind != local_ind)
2293	break;
2294      sitem->defined = true;
2295
2296      // 3rd party compiled. e.g., Gcc or KAI compiled
2297      if (sitem->lang_code != Sp_lang_unknown)
2298	{
2299	  if (module->lang_code == Sp_lang_unknown)
2300	    module->lang_code = sitem->lang_code;
2301	  continue;
2302	}
2303      if (sitem->func)
2304	continue;
2305      Function *func = dbeSession->createFunction ();
2306      sitem->func = func;
2307      func->img_fname = path;
2308      func->img_offset = (off_t) sitem->img_offset;
2309      func->save_addr = (uint32_t) sitem->save;
2310      func->size = (uint32_t) sitem->size;
2311      func->module = module;
2312      func->set_name (sitem->name);
2313      module->functions->append (func);
2314      module->loadobject->functions->append (func);
2315    }
2316}
2317
2318Function *
2319Stabs::append_Function (Module *module, char *fname)
2320{
2321  Symbol *sitem, *sptr;
2322  Function *func;
2323  long sid, index;
2324  char *name;
2325  if (SymLstByName == NULL)
2326    {
2327      SymLstByName = SymLst->copy ();
2328      SymLstByName->sort (SymNameCmp);
2329    }
2330  sptr = new Symbol;
2331  if (module->lang_code == N_SO_FORTRAN || module->lang_code == N_SO_FORTRAN90)
2332    {
2333      char *fortran = dbe_sprintf (NTXT ("%s_"), fname); // FORTRAN name
2334      sptr->name = fortran;
2335      sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
2336      if (sid == -1)
2337	{
2338	  free (fortran);
2339	  sptr->name = fname;
2340	  sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
2341	}
2342      else
2343	fname = fortran;
2344    }
2345  else
2346    {
2347      sptr->name = fname;
2348      sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp);
2349    }
2350  sptr->name = NULL;
2351  delete sptr;
2352
2353  if (sid == -1)
2354    {
2355      Vec_loop (Symbol*, SymLstByName, index, sitem)
2356      {
2357	if (strncmp (sitem->name, NTXT ("$X"), 2) == 0
2358	    || strncmp (sitem->name, NTXT (".X"), 2) == 0)
2359	  {
2360	    char *n = strchr (((sitem->name) + 2), (int) '.');
2361	    if (n != NULL)
2362	      name = n + 1;
2363	    else
2364	      name = sitem->name;
2365	  }
2366	else
2367	  name = sitem->name;
2368	if (name != NULL && fname != NULL && (strcmp (name, fname) == 0))
2369	  {
2370	    sid = index;
2371	    break;
2372	  }
2373      }
2374    }
2375  if (sid != -1)
2376    {
2377      sitem = SymLstByName->fetch (sid);
2378      if (sitem->alias)
2379	sitem = sitem->alias;
2380      if (sitem->func)
2381	return sitem->func;
2382      sitem->func = func = dbeSession->createFunction ();
2383      func->img_fname = path;
2384      func->img_offset = (off_t) sitem->img_offset;
2385      func->save_addr = (uint32_t) sitem->save;
2386      func->size = (uint32_t) sitem->size;
2387    }
2388  else
2389    func = dbeSession->createFunction ();
2390
2391  func->module = module;
2392  func->set_name (fname);
2393  module->functions->append (func);
2394  module->loadobject->functions->append (func);
2395  return func;
2396}
2397
2398Function *
2399Stabs::append_Function (Module *module, char *linkerName, uint64_t pc)
2400{
2401  Dprintf (DEBUG_STABS, NTXT ("Stabs::append_Function: module=%s linkerName=%s pc=0x%llx\n"),
2402	   STR (module->get_name ()), STR (linkerName), (unsigned long long) pc);
2403  long i;
2404  Symbol *sitem = NULL, *sp;
2405  Function *func;
2406  sp = new Symbol;
2407  if (pc)
2408    {
2409      sp->value = pc;
2410      i = SymLst->bisearch (0, -1, &sp, SymFindCmp);
2411      if (i != -1)
2412	sitem = SymLst->fetch (i);
2413    }
2414
2415  if (!sitem && linkerName)
2416    {
2417      if (SymLstByName == NULL)
2418	{
2419	  SymLstByName = SymLst->copy ();
2420	  SymLstByName->sort (SymNameCmp);
2421	}
2422      sp->name = linkerName;
2423      i = SymLstByName->bisearch (0, -1, &sp, SymNameCmp);
2424      sp->name = NULL;
2425      if (i != -1)
2426	sitem = SymLstByName->fetch (i);
2427    }
2428  delete sp;
2429
2430  if (!sitem)
2431    return NULL;
2432  if (sitem->alias)
2433    sitem = sitem->alias;
2434  if (sitem->func)
2435    return sitem->func;
2436
2437  sitem->func = func = dbeSession->createFunction ();
2438  func->img_fname = path;
2439  func->img_offset = (off_t) sitem->img_offset;
2440  func->save_addr = (uint32_t) sitem->save;
2441  func->size = (uint32_t) sitem->size;
2442  func->module = module;
2443  func->set_name (sitem->name); //XXXX ?? Now call it to set obj->name
2444  module->functions->append (func);
2445  module->loadobject->functions->append (func);
2446  return func;
2447}// Stabs::append_Function
2448
2449Dwarf *
2450Stabs::openDwarf ()
2451{
2452  if (dwarf == NULL)
2453    {
2454      dwarf = new Dwarf (this);
2455      check_Symtab ();
2456    }
2457  return dwarf;
2458}
2459
2460void
2461Stabs::read_hwcprof_info (Module *module)
2462{
2463  openDwarf ()->read_hwcprof_info (module);
2464}
2465
2466void
2467Stabs::dump ()
2468{
2469  if (!DUMP_ELF_SYM)
2470    return;
2471  printf (NTXT ("\n======= Stabs::dump: %s =========\n"), path ? path : NTXT ("NULL"));
2472  int i, sz;
2473  if (LocalFile)
2474    {
2475      sz = LocalFile->size ();
2476      for (i = 0; i < sz; i++)
2477	printf ("  %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i),
2478		LocalFile->fetch (i));
2479    }
2480  Symbol::dump (SymLst, NTXT ("SymLst"));
2481  Symbol::dump (LocalLst, NTXT ("LocalLst"));
2482  printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"),
2483  path ? path : NTXT ("NULL"));
2484}
2485
2486///////////////////////////////////////////////////////////////////////////////
2487//  Class Include
2488Include::Include ()
2489{
2490  stack = new Vector<SrcFileInfo*>;
2491}
2492
2493Include::~Include ()
2494{
2495  Destroy (stack);
2496}
2497
2498void
2499Include::new_src_file (SourceFile *source, int lineno, Function *func)
2500{
2501  for (int index = stack->size () - 1; index >= 0; index--)
2502    {
2503      if (source == stack->fetch (index)->srcfile)
2504	{
2505	  for (int i = stack->size () - 1; i > index; i--)
2506	    {
2507	      delete stack->remove (i);
2508	      if (func && func->line_first > 0)
2509		func->popSrcFile ();
2510	    }
2511	  return;
2512	}
2513    }
2514  if (func && func->line_first > 0)
2515    func->pushSrcFile (source, lineno);
2516
2517  SrcFileInfo *sfinfo = new SrcFileInfo;
2518  sfinfo->srcfile = source;
2519  sfinfo->lineno = lineno;
2520  stack->append (sfinfo);
2521}
2522
2523void
2524Include::push_src_files (Function *func)
2525{
2526  int index;
2527  SrcFileInfo *sfinfo;
2528
2529  if (func->line_first <= 0 && stack->size () > 0)
2530    {
2531      sfinfo = stack->fetch (stack->size () - 1);
2532      func->setDefSrc (sfinfo->srcfile);
2533    }
2534  Vec_loop (SrcFileInfo*, stack, index, sfinfo)
2535  {
2536    func->pushSrcFile (sfinfo->srcfile, sfinfo->lineno);
2537  }
2538}
2539
2540void
2541Include::new_include_file (SourceFile *source, Function *func)
2542{
2543  if (stack->size () == 1 && stack->fetch (0)->srcfile == source)
2544    // workaroud for gcc; gcc creates 'N_BINCL' stab for main source
2545    return;
2546  if (func && func->line_first > 0)
2547    func->pushSrcFile (source, 0);
2548
2549  SrcFileInfo *sfinfo = new SrcFileInfo;
2550  sfinfo->srcfile = source;
2551  sfinfo->lineno = 0;
2552  stack->append (sfinfo);
2553}
2554
2555void
2556Include::end_include_file (Function *func)
2557{
2558  int index = stack->size () - 1;
2559  if (index > 0)
2560    {
2561      delete stack->remove (index);
2562      if (func && func->line_first > 0)
2563	func->popSrcFile ();
2564    }
2565}
2566
2567#define RET_S(x)   if (t == x) return (char *) #x
2568char *
2569StabReader::get_type_name (int t)
2570{
2571  RET_S (N_UNDF);
2572  RET_S (N_ABS);
2573  RET_S (N_TEXT);
2574  RET_S (N_DATA);
2575  RET_S (N_BSS);
2576  RET_S (N_COMM);
2577  RET_S (N_FN);
2578  RET_S (N_EXT);
2579  RET_S (N_TYPE);
2580  RET_S (N_GSYM);
2581  RET_S (N_FNAME);
2582  RET_S (N_FUN);
2583  RET_S (N_OUTL);
2584  RET_S (N_STSYM);
2585  RET_S (N_TSTSYM);
2586  RET_S (N_LCSYM);
2587  RET_S (N_TLCSYM);
2588  RET_S (N_MAIN);
2589  RET_S (N_ROSYM);
2590  RET_S (N_FLSYM);
2591  RET_S (N_TFLSYM);
2592  RET_S (N_PC);
2593  RET_S (N_CMDLINE);
2594  RET_S (N_OBJ);
2595  RET_S (N_OPT);
2596  RET_S (N_RSYM);
2597  RET_S (N_SLINE);
2598  RET_S (N_XLINE);
2599  RET_S (N_ILDPAD);
2600  RET_S (N_SSYM);
2601  RET_S (N_ENDM);
2602  RET_S (N_SO);
2603  RET_S (N_MOD);
2604  RET_S (N_EMOD);
2605  RET_S (N_READ_MOD);
2606  RET_S (N_ALIAS);
2607  RET_S (N_LSYM);
2608  RET_S (N_BINCL);
2609  RET_S (N_SOL);
2610  RET_S (N_PSYM);
2611  RET_S (N_EINCL);
2612  RET_S (N_ENTRY);
2613  RET_S (N_SINCL);
2614  RET_S (N_LBRAC);
2615  RET_S (N_EXCL);
2616  RET_S (N_USING);
2617  RET_S (N_ISYM);
2618  RET_S (N_ESYM);
2619  RET_S (N_PATCH);
2620  RET_S (N_CONSTRUCT);
2621  RET_S (N_DESTRUCT);
2622  RET_S (N_CODETAG);
2623  RET_S (N_FUN_CHILD);
2624  RET_S (N_RBRAC);
2625  RET_S (N_BCOMM);
2626  RET_S (N_TCOMM);
2627  RET_S (N_ECOMM);
2628  RET_S (N_XCOMM);
2629  RET_S (N_ECOML);
2630  RET_S (N_WITH);
2631  RET_S (N_LENG);
2632  RET_S (N_CPROF);
2633  RET_S (N_BROWS);
2634  RET_S (N_FUN_PURE);
2635  RET_S (N_FUN_ELEMENTAL);
2636  RET_S (N_FUN_RECURSIVE);
2637  RET_S (N_FUN_AMD64_PARMDUMP);
2638  RET_S (N_SYM_OMP_TLS);
2639  RET_S (N_SO_AS);
2640  RET_S (N_SO_C);
2641  RET_S (N_SO_ANSI_C);
2642  RET_S (N_SO_CC);
2643  RET_S (N_SO_FORTRAN);
2644  RET_S (N_SO_FORTRAN77);
2645  RET_S (N_SO_PASCAL);
2646  RET_S (N_SO_FORTRAN90);
2647  RET_S (N_SO_JAVA);
2648  RET_S (N_SO_C99);
2649  return NULL;
2650}
2651