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