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
45 class StabReader
46 {
47 public:
48   StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec);
~StabReader()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 
56 private:
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 
68 class Symbol
69 {
70 public:
71   Symbol (Vector<Symbol*> *vec = NULL);
72 
~Symbol()73   ~Symbol ()
74   {
75     free (name);
76   }
77 
78   inline Symbol *
cardinal()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 
Symbol(Vector<Symbol * > * vec)99 Symbol::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 
116 void
dump(Vector<Symbol * > * vec,char * msg)117 Symbol::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
138 class Reloc
139 {
140 public:
141   Reloc ();
142   ~Reloc ();
143   uint64_t type;
144   uint64_t value;
145   uint64_t addend;
146   char *name;
147 };
148 
Reloc()149 Reloc::Reloc ()
150 {
151   type = 0;
152   value = 0;
153   addend = 0;
154   name = NULL;
155 }
156 
~Reloc()157 Reloc::~Reloc ()
158 {
159   free (name);
160 }
161 // end of class Reloc
162 ///////////////////////////////////////////////////////////////////////////////
163 
164 enum
165 {
166   SYM_PLT       = 1 << 0,
167   SYM_UNDEF     = 1 << 1
168 };
169 
170 enum Section_type
171 {
172   COMM1_SEC = 0x10000000,
173   COMM_SEC  = 0x20000000,
174   INFO_SEC  = 0x30000000,
175   LOOP_SEC  = 0x40000000
176 };
177 
178 struct 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 
185 static char *get_info_com (int type, int32_t copy_inout);
186 static char *get_lp_com (unsigned hints, int parallel, char *dep);
187 static int ComCmp (const void *a, const void *b);
188 static ino64_t _src_inode = 0;
189 static char *_src_name;
190 
191 // Comparing name
192 static int
SymNameCmp(const void * a,const void * b)193 SymNameCmp (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
202 static int
SymValueCmp(const void * a,const void * b)203 SymValueCmp (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)
212 static int
SymFindCmp(const void * a,const void * b)213 SymFindCmp (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.
226 static int
SymImgOffsetCmp(const void * a,const void * b)227 SymImgOffsetCmp (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 
235 static int
RelValueCmp(const void * a,const void * b)236 RelValueCmp (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 
244 Stabs *
NewStabs(char * _path,char * lo_name)245 Stabs::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 
Stabs(char * _path,char * _lo_name)256 Stabs::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 
~Stabs()306 Stabs::~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 
323 Elf *
openElf(char * fname,Stab_status & st)324 Stabs::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 
388 Elf *
openElf(bool dbg_info)389 Stabs::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 
410 bool
read_symbols(Vector<Function * > * functions)411 Stabs::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 
429 char *
sym_name(uint64_t target,uint64_t instr,int flag)430 Stabs::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 
465 Symbol *
map_PC_to_sym(uint64_t pc)466 Stabs::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 
485 Function *
map_PC_to_func(uint64_t pc,uint64_t & low_pc,Vector<Function * > * functions)486 Stabs::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 
513 Stabs::Stab_status
read_stabs(ino64_t srcInode,Module * module,Vector<ComC * > * comComs,bool readDwarf)514 Stabs::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 
560 static int
ComCmp(const void * a,const void * b)561 ComCmp (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 
571 static int
check_src_name(char * srcName)572 check_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 
583 bool
check_Comm(Vector<ComC * > * comComs)584 Stabs::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 
629 static int
targetOffsetCmp(const void * a,const void * b)630 targetOffsetCmp (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 
637 void
check_AnalyzerInfo()638 Stabs::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 
789 void
check_Info(Vector<ComC * > * comComs)790 Stabs::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 
843 static char *
get_info_com(int type,int32_t copy_inout)844 get_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 
866 void
check_Loop(Vector<ComC * > * comComs)867 Stabs::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 
1016 static char *
get_lp_com(unsigned hints,int parallel,char * dep)1017 get_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 
StabReader(Elf * _elf,Platform_t platform,int StabSec,int StabStrSec)1079 StabReader::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 
1113 char *
get_stab(struct stab * np,bool comdat)1114 StabReader::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 
1170 void
parse_N_OPT(Module * mod,char * str)1171 StabReader::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 
1200 Stabs::Stab_status
srcline_Stabs(Module * module,unsigned int StabSec,unsigned int StabStrSec,bool comdat)1201 Stabs::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 
1450 static bool
cmp_func_name(char * fname,size_t len,char * name,bool fortran)1451 cmp_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 
1458 Function *
find_func(char * fname,Vector<Function * > * functions,bool fortran,bool inner_names)1459 Stabs::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 
1499 Map<const char*, Symbol*> *
get_elf_symbols()1500 Stabs::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 
1516 void
read_dwarf_from_dot_o(Module * mod)1517 Stabs::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 
1555 Stabs::Stab_status
read_archive(LoadObject * lo)1556 Stabs::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 
1615 Function *
createFunction(LoadObject * lo,Module * module,Symbol * sym)1616 Stabs::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 
1631 void
fixSymtabAlias()1632 Stabs::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 
1684 void
check_Symtab()1685 Stabs::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 
1716 void
readSymSec(unsigned int sec,Elf * elf)1717 Stabs::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 
1823 void
check_Relocs()1824 Stabs::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 
1959 void
get_save_addr(bool need_swap_endian)1960 Stabs::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 
2011 uint64_t
mapOffsetToAddress(uint64_t img_offset)2012 Stabs::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 
2031 Stabs::Stab_status
archive_Stabs(LoadObject * lo,unsigned int StabSec,unsigned int StabStrSec,bool comdat)2032 Stabs::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 
2230 Module *
append_Module(LoadObject * lo,char * name,int lastMod)2231 Stabs::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 
2283 void
append_local_funcs(Module * module,int first_ind)2284 Stabs::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 
2318 Function *
append_Function(Module * module,char * fname)2319 Stabs::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 
2398 Function *
append_Function(Module * module,char * linkerName,uint64_t pc)2399 Stabs::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 
2449 Dwarf *
openDwarf()2450 Stabs::openDwarf ()
2451 {
2452   if (dwarf == NULL)
2453     {
2454       dwarf = new Dwarf (this);
2455       check_Symtab ();
2456     }
2457   return dwarf;
2458 }
2459 
2460 void
read_hwcprof_info(Module * module)2461 Stabs::read_hwcprof_info (Module *module)
2462 {
2463   openDwarf ()->read_hwcprof_info (module);
2464 }
2465 
2466 void
dump()2467 Stabs::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
Include()2488 Include::Include ()
2489 {
2490   stack = new Vector<SrcFileInfo*>;
2491 }
2492 
~Include()2493 Include::~Include ()
2494 {
2495   Destroy (stack);
2496 }
2497 
2498 void
new_src_file(SourceFile * source,int lineno,Function * func)2499 Include::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 
2523 void
push_src_files(Function * func)2524 Include::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 
2540 void
new_include_file(SourceFile * source,Function * func)2541 Include::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 
2555 void
end_include_file(Function * func)2556 Include::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
2568 char *
get_type_name(int t)2569 StabReader::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