xref: /netbsd-src/external/gpl3/binutils/dist/gprofng/src/Stabs.cc (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* Copyright (C) 2021-2024 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 SymLstByName;
309   Destroy (SymLst);
310   Destroy (RelLst);
311   Destroy (RelPLTLst);
312   Destroy (LocalFile);
313   delete elfDis;
314   delete dwarf;
315   delete LocalLst;
316   delete LocalFileIdx;
317   delete stabsModules;
318   free (path);
319   free (lo_name);
320 }
321 
322 Elf *
openElf(char * fname,Stab_status & st)323 Stabs::openElf (char *fname, Stab_status &st)
324 {
325   Elf::Elf_status elf_status;
326   Elf *elf = Elf::elf_begin (fname, &elf_status);
327   if (elf == NULL)
328     {
329       switch (elf_status)
330 	{
331 	case Elf::ELF_ERR_CANT_OPEN_FILE:
332 	case Elf::ELF_ERR_CANT_MMAP:
333 	case Elf::ELF_ERR_BIG_FILE:
334 	  st = DBGD_ERR_CANT_OPEN_FILE;
335 	  break;
336 	case Elf::ELF_ERR_BAD_ELF_FORMAT:
337 	default:
338 	  st = DBGD_ERR_BAD_ELF_FORMAT;
339 	  break;
340 	}
341       return NULL;
342     }
343   if (elf->elf_version (EV_CURRENT) == EV_NONE)
344     {
345       // ELF library out of date
346       delete elf;
347       st = DBGD_ERR_BAD_ELF_LIB;
348       return NULL;
349     }
350 
351   Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr ();
352   if (ehdrp == NULL)
353     {
354       // check machine
355       delete elf;
356       st = DBGD_ERR_BAD_ELF_FORMAT;
357       return NULL;
358     }
359   switch (ehdrp->e_machine)
360     {
361     case EM_SPARC:
362       platform = Sparc;
363       break;
364     case EM_SPARC32PLUS:
365       platform = Sparcv8plus;
366       break;
367     case EM_SPARCV9:
368       platform = Sparcv9;
369       break;
370     case EM_386:
371       //    case EM_486:
372       platform = Intel;
373       break;
374     case EM_X86_64:
375       platform = Amd64;
376       break;
377     case EM_AARCH64:
378       platform = Aarch64;
379       break;
380     default:
381       platform = Unknown;
382       break;
383     }
384   return elf;
385 }
386 
387 Elf *
openElf(bool dbg_info)388 Stabs::openElf (bool dbg_info)
389 {
390   if (status != DBGD_ERR_NONE)
391     return NULL;
392   if (elfDis == NULL)
393     {
394       elfDis = openElf (path, status);
395       if (elfDis == NULL)
396 	return NULL;
397     }
398   if (!dbg_info)
399     return elfDis;
400   if (elfDbg == NULL)
401     {
402       elfDbg = elfDis->find_ancillary_files (lo_name);
403       if (elfDbg == NULL)
404 	elfDbg = elfDis;
405     }
406   return elfDbg;
407 }
408 
409 bool
read_symbols(Vector<Function * > * functions)410 Stabs::read_symbols (Vector<Function*> *functions)
411 {
412   if (openElf (true) == NULL)
413     return false;
414   check_Symtab ();
415   check_Relocs ();
416   if (functions)
417     {
418       Function *fp;
419       int index;
420       Vec_loop (Function*, functions, index, fp)
421       {
422 	fp->img_fname = path;
423       }
424     }
425   return true;
426 }
427 
428 char *
sym_name(uint64_t target,uint64_t instr,int flag)429 Stabs::sym_name (uint64_t target, uint64_t instr, int flag)
430 {
431   long index;
432   if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG)
433     {
434       Reloc *relptr = new Reloc;
435       relptr->value = instr;
436       index = RelLst->bisearch (0, -1, &relptr, RelValueCmp);
437       if (index >= 0)
438 	{
439 	  delete relptr;
440 	  return RelLst->fetch (index)->name;
441 	}
442       if (!is_relocatable ())
443 	{
444 	  relptr->value = target;
445 	  index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp);
446 	  if (index >= 0)
447 	    {
448 	      delete relptr;
449 	      return RelPLTLst->fetch (index)->name;
450 	    }
451 	}
452       delete relptr;
453     }
454   if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ())
455     {
456       Symbol *sptr;
457       sptr = map_PC_to_sym (target);
458       if (sptr && sptr->value == target)
459 	return sptr->name;
460     }
461   return NULL;
462 }
463 
464 Symbol *
map_PC_to_sym(uint64_t pc)465 Stabs::map_PC_to_sym (uint64_t pc)
466 {
467   if (pc == 0)
468     return NULL;
469   if (last_PC_to_sym && last_PC_to_sym->value <= pc
470       && last_PC_to_sym->value + last_PC_to_sym->size > pc)
471     return last_PC_to_sym;
472   Symbol *sym = new Symbol;
473   sym->value = pc;
474   long index = SymLst->bisearch (0, -1, &sym, SymFindCmp);
475   delete sym;
476   if (index >= 0)
477     {
478       last_PC_to_sym = SymLst->fetch (index)->cardinal ();
479       return last_PC_to_sym;
480     }
481   return NULL;
482 }
483 
484 Function *
map_PC_to_func(uint64_t pc,uint64_t & low_pc,Vector<Function * > * functions)485 Stabs::map_PC_to_func (uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions)
486 {
487   int index;
488   Function *func;
489   Symbol *sptr = map_PC_to_sym (pc);
490   if (sptr == NULL)
491     return NULL;
492   if (sptr->func)
493     {
494       low_pc = sptr->value;
495       return sptr->func;
496     }
497   if (functions)
498     {
499       Vec_loop (Function*, functions, index, func)
500       {
501 	if (func->img_offset == sptr->img_offset)
502 	  {
503 	    sptr->func = func->cardinal ();
504 	    low_pc = sptr->value;
505 	    return sptr->func;
506 	  }
507       }
508     }
509   return NULL;
510 }
511 
512 Stabs::Stab_status
read_stabs(ino64_t srcInode,Module * module,Vector<ComC * > * comComs,bool readDwarf)513 Stabs::read_stabs (ino64_t srcInode, Module *module, Vector<ComC*> *comComs,
514 		   bool readDwarf)
515 {
516   if (module)
517     module->setIncludeFile (NULL);
518 
519   if (openElf (true) == NULL)
520     return status;
521   check_Symtab ();
522 
523   // read compiler commentary from .compcom1, .compcom,
524   // .info, .loops, and .loopview sections
525   if (comComs)
526     {
527       _src_inode = srcInode;
528       _src_name = module && module->file_name ? get_basename (module->file_name) : NULL;
529       if (!check_Comm (comComs))
530 	// .loops, and .loopview are now in .compcom
531 	check_Loop (comComs);
532 
533       // should not read it after .info goes into .compcom
534       check_Info (comComs);
535       comComs->sort (ComCmp);
536     }
537 
538   // get stabs info
539   Stab_status statusStabs = DBGD_ERR_NO_STABS;
540 #define SRC_LINE_STABS(sec, secStr, comdat) \
541     if ((elfDbg->sec)  && (elfDbg->secStr) && \
542 	srcline_Stabs(module, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
543 	statusStabs = DBGD_ERR_NONE
544 
545   SRC_LINE_STABS (stabExcl, stabExclStr, false);
546   SRC_LINE_STABS (stab, stabStr, false);
547   SRC_LINE_STABS (stabIndex, stabIndexStr, true);
548 
549   // read Dwarf, if any sections found
550   if (elfDbg->dwarf && readDwarf)
551     {
552       openDwarf ()->srcline_Dwarf (module);
553       if (dwarf && dwarf->status == DBGD_ERR_NONE)
554 	return DBGD_ERR_NONE;
555     }
556   return statusStabs;
557 }
558 
559 static int
ComCmp(const void * a,const void * b)560 ComCmp (const void *a, const void *b)
561 {
562   ComC *item1 = *((ComC **) a);
563   ComC *item2 = *((ComC **) b);
564   return (item1->line > item2->line) ? 1 :
565 	  (item1->line < item2->line) ? -1 :
566 	  (item1->sec > item2->sec) ? 1 :
567 	  (item1->sec < item2->sec) ? -1 : 0;
568 }
569 
570 static int
check_src_name(char * srcName)571 check_src_name (char *srcName)
572 {
573   if (_src_name && srcName && streq (_src_name, get_basename (srcName)))
574     return 1;
575   if (_src_inode == (ino64_t) - 1)
576     return 0;
577   DbeFile *dbeFile = dbeSession->getDbeFile (srcName, DbeFile::F_SOURCE);
578   char *path = dbeFile->get_location ();
579   return (path == NULL || dbeFile->sbuf.st_ino != _src_inode) ? 0 : 1;
580 }
581 
582 bool
check_Comm(Vector<ComC * > * comComs)583 Stabs::check_Comm (Vector<ComC*> *comComs)
584 {
585   int sz = comComs->size ();
586   Elf *elf = openElf (true);
587   if (elf == NULL)
588     return false;
589 
590   for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
591     {
592       char *name = elf->get_sec_name (sec);
593       if (name == NULL)
594 	continue;
595       Section_type sec_type;
596       if (streq (name, NTXT (".compcom")))
597 	sec_type = COMM_SEC;
598       else if (streq (name, NTXT (".compcom1")))
599 	sec_type = COMM1_SEC;
600       else
601 	continue;
602 
603       // find header, set messages id & visibility if succeed
604       CompComment *cc = new CompComment (elf, sec);
605       int cnt = cc->compcom_open ((CheckSrcName) check_src_name);
606       // process messages
607       for (int index = 0; index < cnt; index++)
608 	{
609 	  int visible;
610 	  compmsg msg;
611 	  char *str = cc->compcom_format (index, &msg, visible);
612 	  if (str)
613 	    {
614 	      ComC *citem = new ComC;
615 	      citem->sec = sec_type + index;
616 	      citem->type = msg.msg_type;
617 	      citem->visible = visible;
618 	      citem->line = (msg.lineno < 1) ? 1 : msg.lineno;
619 	      citem->com_str = str;
620 	      comComs->append (citem);
621 	    }
622 	}
623       delete cc;
624     }
625   return (sz != comComs->size ());
626 }
627 
628 static int
targetOffsetCmp(const void * a,const void * b)629 targetOffsetCmp (const void *a, const void *b)
630 {
631   uint32_t o1 = ((target_info_t *) a)->offset;
632   uint32_t o2 = ((target_info_t *) b)->offset;
633   return (o1 >= o2);
634 }
635 
636 void
check_AnalyzerInfo()637 Stabs::check_AnalyzerInfo ()
638 {
639   Elf *elf = openElf (true);
640   if ((elf == NULL) || (elf->analyzerInfo == 0))
641     {
642       Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo: Null AnalyzerInfo section\n"));
643       return; // inappropriate, but ignored anyway
644     }
645   Elf_Data *data = elf->elf_getdata (elf->analyzerInfo);
646   int InfoSize = (int) data->d_size;
647   char *InfoData = (char *) data->d_buf;
648   int InfoAlign = (int) data->d_align;
649   AnalyzerInfoHdr h;
650   unsigned infoHdr_sz = sizeof (AnalyzerInfoHdr);
651   int table, entry;
652   int read = 0;
653   Module *mitem;
654   int index = 0;
655   if (InfoSize <= 0)
656     return;
657   uint64_t baseAddr = elf->get_baseAddr ();
658   Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo size=%d @0x%lx (align=%d) base=0x%llx\n"),
659 	   InfoSize, (ul_t) InfoData, InfoAlign, (long long) baseAddr);
660   Dprintf (DEBUG_STABS, NTXT ("analyzerInfoMap has %lld entries\n"), (long long) analyzerInfoMap.size ());
661   if (analyzerInfoMap.size () == 0)
662     {
663       Dprintf (DEBUG_STABS, NTXT ("No analyzerInfoMap available!\n"));
664       return;
665     }
666 
667   // verify integrity of analyzerInfoMap before reading analyzerInfo
668   unsigned count = 0;
669   Module *lastmod = NULL;
670   for (index = 0; index < analyzerInfoMap.size (); index++)
671     {
672       cpf_stabs_t map = analyzerInfoMap.fetch (index);
673       if (map.type > 3)
674 	{
675 	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains table of unknown type %d for %s\n"),
676 		   map.type, map.module->get_name ());
677 	  return;
678 	}
679       if (map.module != lastmod)
680 	{
681 	  if (lastmod != NULL)
682 	    Dprintf (DEBUG_STABS, "analyzerInfo contains %d 0x0 offset tables for %s\n",
683 		     count, lastmod->get_name ());
684 	  count = 0;
685 	}
686       count += (map.offset == 0x0); // only check for 0x0 tables for now
687       if (count > 4)
688 	{
689 	  Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains too many 0x0 offset tables for %s\n"),
690 		   map.module->get_name ());
691 	  return;
692 	}
693       lastmod = map.module;
694     }
695 
696   index = 0;
697   while ((index < analyzerInfoMap.size ()) && (read < InfoSize))
698     {
699       for (table = 0; table < 3; table++)
700 	{ // memory operations (ld, st, prefetch)
701 	  // read the table header
702 	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
703 	  InfoData += infoHdr_sz;
704 	  read += infoHdr_sz;
705 
706 	  // use map for appropriate module
707 	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
708 	  index++;
709 	  mitem = map.module;
710 	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
711 		   "text_labelref=0x%08llx entries=%d version=%d\n"
712 		   "itype %d offset=0x%04x module=%s\n", table, read,
713 		   (long long) (h.text_labelref - baseAddr), h.entries,
714 		   h.version, map.type, map.offset, map.module->get_name ());
715 	  // read the table entries
716 	  for (entry = 0; entry < h.entries; entry++)
717 	    {
718 	      memop_info_t *m = new memop_info_t;
719 	      unsigned memop_info_sz = sizeof (memop_info_t);
720 	      memcpy ((void *) m, (const void *) InfoData, memop_info_sz);
721 	      InfoData += memop_info_sz;
722 	      read += memop_info_sz;
723 	      m->offset += (uint32_t) (h.text_labelref - baseAddr);
724 	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n"),
725 		       entry, table, m->offset, m->id, m->signature, m->datatype_id);
726 	      switch (table)
727 		{
728 		case CPF_INSTR_TYPE_LD:
729 		  mitem->ldMemops.append (m);
730 		  break;
731 		case CPF_INSTR_TYPE_ST:
732 		  mitem->stMemops.append (m);
733 		  break;
734 		case CPF_INSTR_TYPE_PREFETCH:
735 		  mitem->pfMemops.append (m);
736 		  break;
737 		}
738 	    }
739 	  // following re-alignment should be redundant
740 	  //InfoData+=(read%InfoAlign); read+=(read%InfoAlign); // re-align
741 	}
742       for (table = 3; table < 4; table++)
743 	{ // branch targets
744 	  memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz);
745 	  InfoData += infoHdr_sz;
746 	  read += infoHdr_sz;
747 
748 	  // use map for appropriate module
749 	  cpf_stabs_t map = analyzerInfoMap.fetch (index);
750 	  index++;
751 	  mitem = map.module;
752 	  Dprintf (DEBUG_STABS, "Table %d offset=0x%04x "
753 		   "text_labelref=0x%08llx entries=%d version=%d\n"
754 		   "itype %d offset=0x%04x module=%s\n", table, read,
755 		   (long long) (h.text_labelref - baseAddr), h.entries,
756 		   h.version, map.type, map.offset, map.module->get_name ());
757 	  for (entry = 0; entry < h.entries; entry++)
758 	    {
759 	      target_info_t *t = new target_info_t;
760 	      unsigned target_info_sz = sizeof (target_info_t);
761 	      memcpy ((void *) t, (const void *) InfoData, target_info_sz);
762 	      InfoData += target_info_sz;
763 	      read += target_info_sz;
764 	      t->offset += (uint32_t) (h.text_labelref - baseAddr);
765 	      Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x\n"), entry,
766 		       table, t->offset);
767 	      // the list of branch targets needs to be in offset sorted order
768 	      // and doing it here before archiving avoids the need to do it
769 	      // each time the archive is read.
770 	      mitem->bTargets.incorporate (t, targetOffsetCmp);
771 	    }
772 	  Dprintf (DEBUG_STABS, NTXT ("bTargets for %s has %lld items (last=0x%04x)\n"),
773 		   mitem->get_name (), (long long) mitem->bTargets.size (),
774 		   (mitem->bTargets.fetch (mitem->bTargets.size () - 1))->offset);
775 	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
776 		   read, (ul_t) InfoData);
777 	  InfoData += (read % InfoAlign);
778 	  read += (read % InfoAlign); // re-align
779 	  Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n",
780 		   read, (ul_t) InfoData);
781 	}
782       Dprintf (DEBUG_STABS, "Stabs::check_AnalyzerInfo bytes read=%lld (index=%lld/%lld)\n",
783 	       (long long) read, (long long) index,
784 	       (long long) analyzerInfoMap.size ());
785     }
786 }
787 
788 void
check_Info(Vector<ComC * > * comComs)789 Stabs::check_Info (Vector<ComC*> *comComs)
790 {
791   Elf *elf = openElf (true);
792   if (elf == NULL || elf->info == 0)
793     return;
794   Elf_Data *data = elf->elf_getdata (elf->info);
795   uint64_t InfoSize = data->d_size;
796   char *InfoData = (char *) data->d_buf;
797   bool get_src = false;
798   for (int h_num = 0; InfoSize; h_num++)
799     {
800       if (InfoSize < sizeof (struct info_header))
801 	return;
802       struct info_header *h = (struct info_header*) InfoData;
803       if (h->endian != '\0' || h->magic[0] != 'S' || h->magic[1] != 'U'
804 	  || h->magic[2] != 'N')
805 	return;
806       if (h->len < InfoSize || h->len < sizeof (struct info_header) || (h->len & 3))
807 	return;
808 
809       char *fname = InfoData + sizeof (struct info_header);
810       InfoData += h->len;
811       InfoSize -= h->len;
812       get_src = check_src_name (fname);
813       for (uint32_t e_num = 0; e_num < h->cnt; ++e_num)
814 	{
815 	  if (InfoSize < sizeof (struct entry_header))
816 	    return;
817 	  struct entry_header *e = (struct entry_header*) InfoData;
818 	  if (InfoSize < e->len)
819 	    return;
820 	  int32_t copy_inout = 0;
821 	  if (e->len > sizeof (struct entry_header))
822 	    if (e->type == F95_COPYINOUT)
823 	      copy_inout = *(int32_t*) (InfoData + sizeof (struct entry_header));
824 	  InfoData += e->len;
825 	  InfoSize -= e->len;
826 	  if (get_src)
827 	    {
828 	      ComC *citem = new ComC;
829 	      citem->sec = INFO_SEC + h_num;
830 	      citem->type = e->msgnum & 0xFFFFFF;
831 	      citem->visible = CCMV_ALL;
832 	      citem->line = e->line;
833 	      citem->com_str = get_info_com (citem->type, copy_inout);
834 	      comComs->append (citem);
835 	    }
836 	}
837       if (get_src)
838 	break;
839     }
840 }
841 
842 static char *
get_info_com(int type,int32_t copy_inout)843 get_info_com (int type, int32_t copy_inout)
844 {
845   switch (type)
846     {
847     case 1:
848       return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in -- loop(s) inserted"),
849 			  copy_inout);
850     case 2:
851       return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-out -- loop(s) inserted"),
852 			  copy_inout);
853     case 3:
854       return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in and a copy-out -- loops inserted"),
855 			  copy_inout);
856     case 4:
857       return dbe_strdup (GTXT ("Alignment of variables in common block may cause performance degradation"));
858     case 5:
859       return dbe_strdup (GTXT ("DO statement bounds lead to no executions of the loop"));
860     default:
861       return dbe_strdup (NTXT (""));
862     }
863 }
864 
865 void
check_Loop(Vector<ComC * > * comComs)866 Stabs::check_Loop (Vector<ComC*> *comComs)
867 {
868   Elf *elf = openElf (true);
869   if (elf == NULL)
870     return;
871 
872   StringBuilder sb;
873   for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
874     {
875       char *name = elf->get_sec_name (sec);
876       if (name == NULL)
877 	continue;
878       if (!streq (name, NTXT (".loops")) && !streq (name, NTXT (".loopview")))
879 	continue;
880 
881       Elf_Data *data = elf->elf_getdata (sec);
882       size_t LoopSize = (size_t) data->d_size, len;
883       char *LoopData = (char *) data->d_buf;
884       int remainder, i;
885       char src[2 * MAXPATHLEN], buf1[MAXPATHLEN], buf2[MAXPATHLEN];
886       char **dep_str = NULL;
887       bool get_src = false;
888       while ((LoopSize > 0) && !get_src &&
889 	     (strncmp (LoopData, NTXT ("Source:"), 7) == 0))
890 	{
891 	  // The first three items in a .loops subsection are three strings.
892 	  //	Source: ...
893 	  //	Version: ...
894 	  //	Number of loops: ...
895 	  sscanf (LoopData, NTXT ("%*s%s"), src);
896 	  len = strlen (LoopData) + 1;
897 	  LoopData += len;
898 	  LoopSize -= len;
899 	  sscanf (LoopData, NTXT ("%*s%*s%s"), buf1);
900 	  //	double version   = atof(buf1);
901 	  len = strlen (LoopData) + 1;
902 	  LoopData += len;
903 	  LoopSize -= len;
904 	  get_src = check_src_name (src);
905 	  sscanf (LoopData, NTXT ("%*s%*s%*s%s%s"), buf1, buf2);
906 	  int n_loop = atoi (buf1);
907 	  int n_depend = atoi (buf2);
908 	  len = strlen (LoopData) + 1;
909 	  LoopData += len;
910 	  LoopSize -= len;
911 	  if (get_src && (n_loop > 0))
912 	    {
913 	      dep_str = new char*[n_loop];
914 	      for (i = 0; i < n_loop; i++)
915 		dep_str[i] = NULL;
916 	    }
917 
918 	  // printf("Source: %s\nVersion: %f\nLoop#: %d\nDepend#: %d\n",
919 	  //	src, version, n_loop, n_depend);
920 
921 	  // Read in the strings that contain the list of variables that cause
922 	  // data dependencies inside of loops. Not every loop has such a list
923 	  // of variables.
924 	  //
925 	  //	Example: if loop #54 has data dependencies caused by the
926 	  //	variables named i, j and foo, then the string that represents
927 	  //	this in the .loops section looks like this:
928 	  //
929 	  //	.asciz "54:i.j.foo"
930 	  //
931 	  //	The variable names are delimited with .
932 	  //
933 	  //	For now, store these strings in an array, and add them into
934 	  //	the loop structure when we read in the numeric loop info
935 	  //	(that's what we read in next.)
936 	  //
937 	  // printf("\tDependenncies:\n");
938 	  for (i = 0; i < n_depend; i++)
939 	    {
940 	      len = strlen (LoopData) + 1;
941 	      LoopData += len;
942 	      LoopSize -= len;
943 	      if (dep_str != NULL)
944 		{
945 		  char *dep_buf1 = dbe_strdup (LoopData);
946 		  char *ptr = strtok (dep_buf1, NTXT (":"));
947 		  if (ptr != NULL)
948 		    {
949 		      int index = atoi (ptr);
950 		      bool dep_first = true;
951 		      sb.setLength (0);
952 		      while ((ptr = strtok (NULL, NTXT (", "))) != NULL)
953 			{
954 			  if (dep_first)
955 			    dep_first = false;
956 			  else
957 			    sb.append (NTXT (", "));
958 			  sb.append (ptr);
959 			}
960 		      if (sb.length () > 0 && index < n_loop)
961 			dep_str[index] = sb.toString ();
962 		    }
963 		  free (dep_buf1);
964 		}
965 	    }
966 
967 	  // Adjust Data pointer so that it is word aligned.
968 	  remainder = (int) (((unsigned long) LoopData) % 4);
969 	  if (remainder != 0)
970 	    {
971 	      len = 4 - remainder;
972 	      LoopData += len;
973 	      LoopSize -= len;
974 	    }
975 
976 	  // Read in the loop info, one loop at a time.
977 	  for (i = 0; i < n_loop; i++)
978 	    {
979 	      int loopid = *((int *) LoopData);
980 	      LoopData += 4;
981 	      int line_no = *((int *) LoopData);
982 	      if (line_no < 1) // compiler has trouble on this
983 		line_no = 1;
984 	      LoopData += 4;
985 	      //	    int nest = *((int *) LoopData);
986 	      LoopData += 4;
987 	      int parallel = *((int *) LoopData);
988 	      LoopData += 4;
989 	      unsigned hints = *((unsigned *) LoopData);
990 	      LoopData += 4;
991 	      //	    int count = *((int *) LoopData);
992 	      LoopData += 4;
993 	      LoopSize -= 24;
994 	      if (!get_src || (loopid >= n_loop))
995 		continue;
996 	      ComC *citem = new ComC;
997 	      citem->sec = LOOP_SEC + i;
998 	      citem->type = hints;
999 	      citem->visible = CCMV_ALL;
1000 	      citem->line = line_no;
1001 	      citem->com_str = get_lp_com (hints, parallel, dep_str[loopid]);
1002 	      comComs->append (citem);
1003 	    }
1004 	  if (dep_str)
1005 	    {
1006 	      for (i = 0; i < n_loop; i++)
1007 		free (dep_str[i]);
1008 	      delete[] dep_str;
1009 	      dep_str = NULL;
1010 	    }
1011 	}
1012     }
1013 }
1014 
1015 static char *
get_lp_com(unsigned hints,int parallel,char * dep)1016 get_lp_com (unsigned hints, int parallel, char *dep)
1017 {
1018   StringBuilder sb;
1019   if (parallel == -1)
1020     sb.append (GTXT ("Loop below is serial, but parallelizable: "));
1021   else if (parallel == 0)
1022     sb.append (GTXT ("Loop below is not parallelized: "));
1023   else
1024     sb.append (GTXT ("Loop below is parallelized: "));
1025   switch (hints)
1026     {
1027     case 0:
1028       // No loop mesg will print
1029       // strcat(com, GTXT("no hint available"));
1030       break;
1031     case 1:
1032       sb.append (GTXT ("loop contains procedure call"));
1033       break;
1034     case 2:
1035       sb.append (GTXT ("compiler generated two versions of this loop"));
1036       break;
1037     case 3:
1038       {
1039 	StringBuilder sb_tmp;
1040 	sb_tmp.sprintf (GTXT ("the variable(s) \"%s\" cause a data dependency in this loop"),
1041 			dep ? dep : GTXT ("<Unknown>"));
1042 	sb.append (&sb_tmp);
1043       }
1044       break;
1045     case 4:
1046       sb.append (GTXT ("loop was significantly transformed during optimization"));
1047       break;
1048     case 5:
1049       sb.append (GTXT ("loop may or may not hold enough work to be profitably parallelized"));
1050       break;
1051     case 6:
1052       sb.append (GTXT ("loop was marked by user-inserted pragma"));
1053       break;
1054     case 7:
1055       sb.append (GTXT ("loop contains multiple exits"));
1056       break;
1057     case 8:
1058       sb.append (GTXT ("loop contains I/O, or other function calls, that are not MT safe"));
1059       break;
1060     case 9:
1061       sb.append (GTXT ("loop contains backward flow of control"));
1062       break;
1063     case 10:
1064       sb.append (GTXT ("loop may have been distributed"));
1065       break;
1066     case 11:
1067       sb.append (GTXT ("two loops or more may have been fused"));
1068       break;
1069     case 12:
1070       sb.append (GTXT ("two or more loops may have been interchanged"));
1071       break;
1072     default:
1073       break;
1074     }
1075   return sb.toString ();
1076 }
1077 
StabReader(Elf * _elf,Platform_t platform,int StabSec,int StabStrSec)1078 StabReader::StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec)
1079 {
1080   stabCnt = -1;
1081   stabNum = 0;
1082   if (_elf == NULL)
1083     return;
1084   elf = _elf;
1085 
1086   // Get ELF data
1087   Elf_Data *data = elf->elf_getdata (StabSec);
1088   if (data == NULL)
1089     return;
1090   uint64_t stabSize = data->d_size;
1091   StabData = (char *) data->d_buf;
1092   Elf_Internal_Shdr *shdr = elf->get_shdr (StabSec);
1093   if (shdr == NULL)
1094     return;
1095 
1096   // GCC bug: sh_entsize is 20 for 64 apps on Linux
1097   StabEntSize = (platform == Amd64 || platform == Sparcv9) ? 12 : (unsigned) shdr->sh_entsize;
1098   if (stabSize == 0 || StabEntSize == 0)
1099     return;
1100   data = elf->elf_getdata (StabStrSec);
1101   if (data == NULL)
1102     return;
1103   shdr = elf->get_shdr (StabStrSec);
1104   if (shdr == NULL)
1105     return;
1106   StabStrtab = (char *) data->d_buf;
1107   StabStrtabEnd = StabStrtab + shdr->sh_size;
1108   StrTabSize = 0;
1109   stabCnt = (int) (stabSize / StabEntSize);
1110 }
1111 
1112 char *
get_stab(struct stab * np,bool comdat)1113 StabReader::get_stab (struct stab *np, bool comdat)
1114 {
1115   struct stab *stbp = (struct stab *) (StabData + stabNum * StabEntSize);
1116   stabNum++;
1117   *np = *stbp;
1118   np->n_desc = elf->decode (stbp->n_desc);
1119   np->n_strx = elf->decode (stbp->n_strx);
1120   np->n_value = elf->decode (stbp->n_value);
1121   switch (np->n_type)
1122     {
1123     case N_UNDF:
1124     case N_ILDPAD:
1125       // Start of new stab section (or padding)
1126       StabStrtab += StrTabSize;
1127       StrTabSize = np->n_value;
1128     }
1129 
1130   char *str = NULL;
1131   if (np->n_strx)
1132     {
1133       if (comdat && np->n_type == N_FUN && np->n_other == 1)
1134 	{
1135 	  if (np->n_strx == 1)
1136 	    StrTabSize++;
1137 	  str = StabStrtab + StrTabSize;
1138 	  // Each COMDAT string must be sized to find the next string:
1139 	  StrTabSize += strlen (str) + 1;
1140 	}
1141       else
1142 	str = StabStrtab + np->n_strx;
1143       if (str >= StabStrtabEnd)
1144 	str = NULL;
1145     }
1146   if (DEBUG_STABS)
1147     {
1148       char buf[128];
1149       char *s = get_type_name (np->n_type);
1150       if (s == NULL)
1151 	{
1152 	  snprintf (buf, sizeof (buf), NTXT ("n_type=%d"), np->n_type);
1153 	  s = buf;
1154 	}
1155       if (str)
1156 	{
1157 	  Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabs \"%s\",%s,0x%x,0x%x,0x%x\n"),
1158 		   stabNum - 1, str, s, (int) np->n_other, (int) np->n_desc,
1159 		   (int) np->n_value);
1160 	}
1161       else
1162 	Dprintf (DEBUG_STABS, NTXT ("%4d:  .stabn %s,0x%x,0x%x,0x%x\n"),
1163 		 stabNum - 1, s, (int) np->n_other, (int) np->n_desc,
1164 		 (int) np->n_value);
1165     }
1166   return str;
1167 }
1168 
1169 void
parse_N_OPT(Module * mod,char * str)1170 StabReader::parse_N_OPT (Module *mod, char *str)
1171 {
1172   if (mod == NULL || str == NULL)
1173       return;
1174   for (char *s = str; 1; s++)
1175     {
1176       switch (*s)
1177 	{
1178 	case 'd':
1179 	  if (s[1] == 'i' && s[2] == ';')
1180 	    {
1181 	      delete mod->dot_o_file;
1182 	      mod->dot_o_file = NULL;
1183 	    }
1184 	  break;
1185 	case 's':
1186 	  if ((s[1] == 'i' || s[1] == 'n') && s[2] == ';')
1187 	    {
1188 	      delete mod->dot_o_file;
1189 	      mod->dot_o_file = NULL;
1190 	    }
1191 	  break;
1192 	}
1193       s = strchr (s, ';');
1194       if (s == NULL)
1195 	break;
1196     }
1197 }
1198 
1199 Stabs::Stab_status
srcline_Stabs(Module * module,unsigned int StabSec,unsigned int StabStrSec,bool comdat)1200 Stabs::srcline_Stabs (Module *module, unsigned int StabSec,
1201 		      unsigned int StabStrSec, bool comdat)
1202 {
1203   StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec);
1204   int tot = stabReader->stabCnt;
1205   if (tot < 0)
1206     {
1207       delete stabReader;
1208       return DBGD_ERR_NO_STABS;
1209     }
1210   int n, lineno;
1211   char *sbase, *n_so = NTXT (""), curr_src[2 * MAXPATHLEN];
1212   Function *newFunc;
1213   Sp_lang_code _lang_code = module->lang_code;
1214   Vector<Function*> *functions = module->functions;
1215   bool no_stabs = true;
1216   *curr_src = '\0';
1217   Function *func = NULL;
1218   int phase = 0;
1219   int stabs_level = 0;
1220   int xline = 0;
1221 
1222   // Find module
1223   for (n = 0; n < tot; n++)
1224     {
1225       struct stab stb;
1226       char *str = stabReader->get_stab (&stb, comdat);
1227       if (stb.n_type == N_UNDF)
1228 	phase = 0;
1229       else if (stb.n_type == N_SO)
1230 	{
1231 	  if (str == NULL || *str == '\0')
1232 	    continue;
1233 	  if (phase == 0)
1234 	    {
1235 	      phase = 1;
1236 	      n_so = str;
1237 	      continue;
1238 	    }
1239 	  phase = 0;
1240 	  sbase = str;
1241 	  if (*str == '/')
1242 	    {
1243 	      if (streq (sbase, module->file_name))
1244 		break;
1245 	    }
1246 	  else
1247 	    {
1248 	      size_t last = strlen (n_so);
1249 	      if (n_so[last - 1] == '/')
1250 		last--;
1251 	      if (strncmp (n_so, module->file_name, last) == 0 &&
1252 		  module->file_name[last] == '/' &&
1253 		  streq (sbase, module->file_name + last + 1))
1254 		break;
1255 	    }
1256 	}
1257     }
1258   if (n >= tot)
1259     {
1260       delete stabReader;
1261       return DBGD_ERR_NO_STABS;
1262     }
1263 
1264   Include *includes = new Include;
1265   includes->new_src_file (module->getMainSrc (), 0, NULL);
1266   module->hasStabs = true;
1267   *curr_src = '\0';
1268   phase = 0;
1269   for (n++; n < tot; n++)
1270     {
1271       struct stab stb;
1272       char *str = stabReader->get_stab (&stb, comdat);
1273       int n_desc = (int) ((unsigned short) stb.n_desc);
1274       switch (stb.n_type)
1275 	{
1276 	case N_UNDF:
1277 	case N_SO:
1278 	case N_ENDM:
1279 	  n = tot;
1280 	  break;
1281 	case N_ALIAS:
1282 	  if (str == NULL)
1283 	    break;
1284 	  if (is_fortran (_lang_code))
1285 	    {
1286 	      char *p = strchr (str, ':');
1287 	      if (p && streq (p + 1, NTXT ("FMAIN")))
1288 		{
1289 		  Function *afunc = find_func (NTXT ("MAIN"), functions, true);
1290 		  if (afunc)
1291 		    afunc->set_match_name (dbe_strndup (str, p - str));
1292 		  break;
1293 		}
1294 	    }
1295 	case N_FUN:
1296 	case N_OUTL:
1297 	  if (str == NULL)
1298 	    break;
1299 	  if (*str == '@')
1300 	    {
1301 	      str++;
1302 	      if (*str == '>' || *str == '<')
1303 		str++;
1304 	    }
1305 	  if (stabs_level != 0)
1306 	    break;
1307 
1308 	  // find address of the enclosed function
1309 	  newFunc = find_func (str, functions, is_fortran (_lang_code));
1310 	  if (newFunc == NULL)
1311 	    break;
1312 	  if (func)
1313 	    while (func->popSrcFile ())
1314 	      ;
1315 	  func = newFunc;
1316 
1317 	  // First line info to cover function from the beginning
1318 	  lineno = xline + n_desc;
1319 	  if (lineno > 0)
1320 	    {
1321 	      // Set the chain of includes for the new function
1322 	      includes->push_src_files (func);
1323 	      func->add_PC_info (0, lineno);
1324 	      no_stabs = false;
1325 	    }
1326 	  break;
1327 	case N_ENTRY:
1328 	  break;
1329 	case N_CMDLINE:
1330 	  if (str && !module->comp_flags)
1331 	    {
1332 	      char *comp_flags = strchr (str, ';');
1333 	      if (comp_flags)
1334 		{
1335 		  module->comp_flags = dbe_strdup (comp_flags + 1);
1336 		  module->comp_dir = dbe_strndup (str, comp_flags - str);
1337 		}
1338 	    }
1339 	  break;
1340 	case N_LBRAC:
1341 	  stabs_level++;
1342 	  break;
1343 	case N_RBRAC:
1344 	  stabs_level--;
1345 	  break;
1346 	case N_XLINE:
1347 	  xline = n_desc << 16;
1348 	  break;
1349 	case N_SLINE:
1350 	  if (func == NULL)
1351 	    break;
1352 	  no_stabs = false;
1353 	  lineno = xline + n_desc;
1354 	  if (func->line_first <= 0)
1355 	    {
1356 	      // Set the chain of includes for the new function
1357 	      includes->push_src_files (func);
1358 	      func->add_PC_info (0, lineno);
1359 	      break;
1360 	    }
1361 	  if (func->curr_srcfile == NULL)
1362 	    includes->push_src_files (func);
1363 	  if (func->line_first != lineno ||
1364 	      !streq (curr_src, func->getDefSrc ()->get_name ()))
1365 	    func->add_PC_info (stb.n_value, lineno);
1366 	  break;
1367 	case N_OPT:
1368 	  if ((str != NULL) && streq (str, NTXT ("gcc2_compiled.")))
1369 	    _lang_code = Sp_lang_gcc;
1370 	  switch (elfDbg->elf_getehdr ()->e_type)
1371 	    {
1372 	    case ET_EXEC:
1373 	    case ET_DYN:
1374 	      // set the real object timestamp from the executable's N_OPT stab
1375 	      // due to bug #4796329
1376 	      module->real_timestamp = stb.n_value;
1377 	      break;
1378 	    default:
1379 	      module->curr_timestamp = stb.n_value;
1380 	      break;
1381 	    }
1382 	  break;
1383 	case N_GSYM:
1384 	  if ((str == NULL) || strncmp (str, NTXT ("__KAI_K"), 7))
1385 	    break;
1386 	  str += 7;
1387 	  if (!strncmp (str, NTXT ("CC_"), 3))
1388 	    _lang_code = Sp_lang_KAI_KCC;
1389 	  else if (!strncmp (str, NTXT ("cc_"), 3))
1390 	    _lang_code = Sp_lang_KAI_Kcc;
1391 	  else if (!strncmp (str, NTXT ("PTS_"), 4) &&
1392 		   (_lang_code != Sp_lang_KAI_KCC) &&
1393 		   (_lang_code != Sp_lang_KAI_Kcc))
1394 	    _lang_code = Sp_lang_KAI_KPTS;
1395 	  break;
1396 	case N_BINCL:
1397 	  includes->new_include_file (module->setIncludeFile (str), func);
1398 	  break;
1399 	case N_EINCL:
1400 	  includes->end_include_file (func);
1401 	  break;
1402 	case N_SOL:
1403 	  if (str == NULL)
1404 	    break;
1405 	  lineno = xline + n_desc;
1406 	  if (lineno > 0 && func && func->line_first <= 0)
1407 	    {
1408 	      includes->push_src_files (func);
1409 	      func->add_PC_info (0, lineno);
1410 	      no_stabs = false;
1411 	    }
1412 	  if (streq (sbase, str))
1413 	    {
1414 	      module->setIncludeFile (NULL);
1415 	      snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
1416 	      includes->new_src_file (module->getMainSrc (), lineno, func);
1417 	    }
1418 	  else
1419 	    {
1420 	      if (streq (sbase, get_basename (str)))
1421 		{
1422 		  module->setIncludeFile (NULL);
1423 		  snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name);
1424 		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
1425 		}
1426 	      else
1427 		{
1428 		  if (*str == '/')
1429 		    snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), str);
1430 		  else
1431 		    {
1432 		      size_t last = strlen (n_so);
1433 		      if (last == 0 || n_so[last - 1] != '/')
1434 			snprintf (curr_src, sizeof (curr_src), NTXT ("%s/%s"), n_so, str);
1435 		      else
1436 			snprintf (curr_src, sizeof (curr_src), NTXT ("%s%s"), n_so, str);
1437 		    }
1438 		  includes->new_src_file (module->setIncludeFile (curr_src), lineno, func);
1439 		}
1440 	    }
1441 	  break;
1442 	}
1443     }
1444   delete includes;
1445   delete stabReader;
1446   return no_stabs ? DBGD_ERR_NO_STABS : DBGD_ERR_NONE;
1447 }//srcline_Stabs
1448 
1449 static bool
cmp_func_name(char * fname,size_t len,char * name,bool fortran)1450 cmp_func_name (char *fname, size_t len, char *name, bool fortran)
1451 {
1452   return (strncmp (name, fname, len) == 0
1453 	  && (name[len] == 0
1454 	      || (fortran && name[len] == '_' && name[len + 1] == 0)));
1455 }
1456 
1457 Function *
find_func(char * fname,Vector<Function * > * functions,bool fortran,bool inner_names)1458 Stabs::find_func (char *fname, Vector<Function*> *functions, bool fortran, bool inner_names)
1459 {
1460   char *arg, *name;
1461   Function *item;
1462   int index;
1463   size_t len;
1464 
1465   len = strlen (fname);
1466   arg = strchr (fname, ':');
1467   if (arg != NULL)
1468     {
1469       if (arg[1] == 'P') // Prototype for function
1470 	return NULL;
1471       len -= strlen (arg);
1472     }
1473 
1474   Vec_loop (Function*, functions, index, item)
1475   {
1476     name = item->get_mangled_name ();
1477     if (cmp_func_name (fname, len, name, fortran))
1478       return item->cardinal ();
1479   }
1480 
1481   if (inner_names)
1482     {
1483       // Dwarf subprograms may only have plain (non-linker) names
1484       // Retry with inner names only
1485 
1486       Vec_loop (Function*, functions, index, item)
1487       {
1488 	name = strrchr (item->get_mangled_name (), '.');
1489 	if (!name) continue;
1490 	name++;
1491 	if (cmp_func_name (fname, len, name, fortran))
1492 	  return item->cardinal ();
1493       }
1494     }
1495   return NULL;
1496 }
1497 
1498 Map<const char*, Symbol*> *
get_elf_symbols()1499 Stabs::get_elf_symbols ()
1500 {
1501   Elf *elf = openElf (false);
1502   if (elf->elfSymbols == NULL)
1503     {
1504       Map<const char*, Symbol*> *elfSymbols = new StringMap<Symbol*>(128, 128);
1505       elf->elfSymbols = elfSymbols;
1506       for (int i = 0, sz = SymLst ? SymLst->size () : 0; i < sz; i++)
1507 	{
1508 	  Symbol *sym = SymLst->fetch (i);
1509 	  elfSymbols->put (sym->name, sym);
1510 	}
1511     }
1512   return elf->elfSymbols;
1513 }
1514 
1515 void
read_dwarf_from_dot_o(Module * mod)1516 Stabs::read_dwarf_from_dot_o (Module *mod)
1517 {
1518   Dprintf (DEBUG_STABS, NTXT ("stabsModules: %s\n"), STR (mod->get_name ()));
1519   Vector<Module*> *mods = mod->dot_o_file->seg_modules;
1520   char *bname = get_basename (mod->get_name ());
1521   for (int i1 = 0, sz1 = mods ? mods->size () : 0; i1 < sz1; i1++)
1522     {
1523       Module *m = mods->fetch (i1);
1524       Dprintf (DEBUG_STABS, NTXT ("  MOD: %s\n"), STR (m->get_name ()));
1525       if (dbe_strcmp (bname, get_basename (m->get_name ())) == 0)
1526 	{
1527 	  mod->indexStabsLink = m;
1528 	  m->indexStabsLink = mod;
1529 	  break;
1530 	}
1531     }
1532   if (mod->indexStabsLink)
1533     {
1534       mod->dot_o_file->objStabs->openDwarf ()->srcline_Dwarf (mod->indexStabsLink);
1535       Map<const char*, Symbol*> *elfSymbols = get_elf_symbols ();
1536       Vector<Function*> *funcs = mod->indexStabsLink->functions;
1537       for (int i1 = 0, sz1 = funcs ? funcs->size () : 0; i1 < sz1; i1++)
1538 	{
1539 	  Function *f1 = funcs->fetch (i1);
1540 	  Symbol *sym = elfSymbols->get (f1->get_mangled_name ());
1541 	  if (sym == NULL)
1542 	    continue;
1543 	  Dprintf (DEBUG_STABS, NTXT ("  Symbol: %s func=%p\n"), STR (sym->name), sym->func);
1544 	  Function *f = sym->func;
1545 	  if (f->indexStabsLink)
1546 	    continue;
1547 	  f->indexStabsLink = f1;
1548 	  f1->indexStabsLink = f;
1549 	  f->copy_PCInfo (f1);
1550 	}
1551     }
1552 }
1553 
1554 Stabs::Stab_status
read_archive(LoadObject * lo)1555 Stabs::read_archive (LoadObject *lo)
1556 {
1557   if (openElf (true) == NULL)
1558     return status;
1559   check_Symtab ();
1560   if (elfDbg->dwarf)
1561     openDwarf ()->archive_Dwarf (lo);
1562 
1563   // get Module/Function lists from stabs info
1564   Stab_status statusStabs = DBGD_ERR_NO_STABS;
1565 #define ARCHIVE_STABS(sec, secStr, comdat) \
1566     if ((elfDbg->sec) != 0  && (elfDbg->secStr) != 0 && \
1567 	archive_Stabs(lo, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \
1568 	statusStabs = DBGD_ERR_NONE
1569 
1570   // prefer index stabs (where they exist) since they're most appropriate
1571   // for loadobjects and might have N_CPROF stabs for ABS/CPF
1572   ARCHIVE_STABS (stabIndex, stabIndexStr, true);
1573   ARCHIVE_STABS (stabExcl, stabExclStr, false);
1574   ARCHIVE_STABS (stab, stabStr, false);
1575 
1576   // Add all unassigned functions to the <unknown> module
1577   Symbol *sitem, *alias;
1578   int index;
1579   Vec_loop (Symbol*, SymLst, index, sitem)
1580   {
1581     if (sitem->func || (sitem->size == 0) || (sitem->flags & SYM_UNDEF))
1582       continue;
1583     alias = sitem->alias;
1584     if (alias)
1585       {
1586 	if (alias->func == NULL)
1587 	  {
1588 	    alias->func = createFunction (lo, lo->noname, alias);
1589 	    alias->func->alias = alias->func;
1590 	  }
1591 	if (alias != sitem)
1592 	  {
1593 	    sitem->func = createFunction (lo, alias->func->module, sitem);
1594 	    sitem->func->alias = alias->func;
1595 	  }
1596       }
1597     else
1598       sitem->func = createFunction (lo, lo->noname, sitem);
1599   }
1600   if (pltSym)
1601     {
1602       pltSym->func = createFunction (lo, lo->noname, pltSym);
1603       pltSym->func->flags |= FUNC_FLAG_PLT;
1604     }
1605 
1606   // need Module association, so this must be done after handling Modules
1607   check_AnalyzerInfo ();
1608 
1609   if (dwarf && dwarf->status == DBGD_ERR_NONE)
1610     return DBGD_ERR_NONE;
1611   return statusStabs;
1612 }//read_archive
1613 
1614 Function *
createFunction(LoadObject * lo,Module * module,Symbol * sym)1615 Stabs::createFunction (LoadObject *lo, Module *module, Symbol *sym)
1616 {
1617   Function *func = dbeSession->createFunction ();
1618   func->module = module;
1619   func->img_fname = path;
1620   func->img_offset = sym->img_offset;
1621   func->save_addr = sym->save;
1622   func->size = sym->size;
1623   func->set_name (sym->name);
1624   func->elfSym = sym;
1625   module->functions->append (func);
1626   lo->functions->append (func);
1627   return func;
1628 }
1629 
1630 void
fixSymtabAlias()1631 Stabs::fixSymtabAlias ()
1632 {
1633   int ind, i, k;
1634   Symbol *sym, *bestAlias;
1635   SymLst->sort (SymImgOffsetCmp);
1636   ind = SymLst->size () - 1;
1637   for (i = 0; i < ind; i++)
1638     {
1639       bestAlias = SymLst->fetch (i);
1640       if (bestAlias->img_offset == 0) // Ignore this bad symbol
1641 	continue;
1642       sym = SymLst->fetch (i + 1);
1643       if (bestAlias->img_offset != sym->img_offset)
1644 	{
1645 	  if ((bestAlias->size == 0) ||
1646 	      (sym->img_offset < bestAlias->img_offset + bestAlias->size))
1647 	    bestAlias->size = sym->img_offset - bestAlias->img_offset;
1648 	  continue;
1649 	}
1650 
1651       // Find a "best" alias
1652       size_t bestLen = strlen (bestAlias->name);
1653       int64_t maxSize = bestAlias->size;
1654       for (k = i + 1; k <= ind; k++)
1655 	{
1656 	  sym = SymLst->fetch (k);
1657 	  if (bestAlias->img_offset != sym->img_offset)
1658 	    { // no more aliases
1659 	      if ((maxSize == 0) ||
1660 		  (sym->img_offset < bestAlias->img_offset + maxSize))
1661 		maxSize = sym->img_offset - bestAlias->img_offset;
1662 	      break;
1663 	    }
1664 	  if (maxSize < sym->size)
1665 	    maxSize = sym->size;
1666 	  size_t len = strlen (sym->name);
1667 	  if (len < bestLen)
1668 	    {
1669 	      bestAlias = sym;
1670 	      bestLen = len;
1671 	    }
1672 	}
1673       for (; i < k; i++)
1674 	{
1675 	  sym = SymLst->fetch (i);
1676 	  sym->alias = bestAlias;
1677 	  sym->size = maxSize;
1678 	}
1679       i--;
1680     }
1681 }
1682 
1683 void
check_Symtab()1684 Stabs::check_Symtab ()
1685 {
1686   if (st_check_symtab)
1687     return;
1688   st_check_symtab = true;
1689 
1690   Elf *elf = openElf (true);
1691   if (elf == NULL)
1692     return;
1693   if (elf->plt != 0)
1694     {
1695       Elf_Internal_Shdr *shdr = elf->get_shdr (elf->plt);
1696       if (shdr)
1697 	{
1698 	  pltSym = new Symbol (SymLst);
1699 	  pltSym->value = shdr->sh_addr;
1700 	  pltSym->size = shdr->sh_size;
1701 	  pltSym->img_offset = shdr->sh_offset;
1702 	  pltSym->name = dbe_strdup (NTXT ("@plt"));
1703 	  pltSym->flags |= SYM_PLT;
1704 	}
1705     }
1706   if (elf->symtab)
1707     readSymSec (elf->symtab, elf);
1708   else
1709     {
1710       readSymSec (elf->SUNW_ldynsym, elf);
1711       readSymSec (elf->dynsym, elf);
1712     }
1713 }
1714 
1715 void
readSymSec(unsigned int sec,Elf * elf)1716 Stabs::readSymSec (unsigned int sec, Elf *elf)
1717 {
1718   Symbol *sitem;
1719   Sp_lang_code local_lcode;
1720   if (sec == 0)
1721     return;
1722   // Get ELF data
1723   Elf_Data *data = elf->elf_getdata (sec);
1724   if (data == NULL)
1725     return;
1726   uint64_t SymtabSize = data->d_size;
1727   Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
1728 
1729   if ((SymtabSize == 0) || (shdr->sh_entsize == 0))
1730     return;
1731   Elf_Data *data_str = elf->elf_getdata (shdr->sh_link);
1732   if (data_str == NULL)
1733     return;
1734   char *Strtab = (char *) data_str->d_buf;
1735 
1736   // read func symbolic table
1737   for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++)
1738     {
1739       Elf_Internal_Sym Sym;
1740       elf->elf_getsym (data, n, &Sym);
1741       const char *st_name = Sym.st_name < data_str->d_size ?
1742 	  (Strtab + Sym.st_name) : NTXT ("no_name");
1743       switch (GELF_ST_TYPE (Sym.st_info))
1744 	{
1745 	case STT_FUNC:
1746 	  if (Sym.st_size == 0)
1747 	    break;
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 = 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 = 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 = sitem->img_offset;
2309       func->save_addr = sitem->save;
2310       func->size = 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 = sitem->img_offset;
2385       func->save_addr = sitem->save;
2386       func->size = 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 = sitem->img_offset;
2440   func->save_addr = sitem->save;
2441   func->size = 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