xref: /netbsd-src/external/gpl3/binutils.old/dist/gprofng/src/Dwarf.cc (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
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 "util.h"
23 #include "DbeSession.h"
24 #include "Elf.h"
25 #include "Stabs.h"
26 #include "Dwarf.h"
27 #include "DataObject.h"
28 #include "Function.h"
29 #include "LoadObject.h"
30 #include "Module.h"
31 #include "DefaultMap.h"
32 
33 static int
datatypeCmp(const void * a,const void * b)34 datatypeCmp (const void *a, const void *b)
35 {
36   uint32_t o1 = ((datatype_t *) a)->datatype_id;
37   uint32_t o2 = ((datatype_t *) b)->datatype_id;
38   return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1);
39 }
40 
41 static int
targetOffsetCmp(const void * a,const void * b)42 targetOffsetCmp (const void *a, const void *b)
43 {
44   uint32_t o1 = ((target_info_t *) a)->offset;
45   uint32_t o2 = ((target_info_t *) b)->offset;
46   return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1);
47 }
48 
49 
50 //////////////////////////////////////////////////////////
51 //  class Dwr_type
52 class Dwr_type
53 {
54 public:
55 
Dwr_type(int64_t _cu_die_offset,int _tag)56   Dwr_type (int64_t _cu_die_offset, int _tag)
57   {
58     cu_die_offset = _cu_die_offset;
59     tag = _tag;
60     name = NULL;
61     dobj_name = NULL;
62     dtype = NULL;
63     extent = 0;
64     parent = 0;
65     child = 0;
66     next = 0;
67     ref_type = 0;
68     size = 0;
69     elems = 0;
70     offset = -1;
71     bit_size = 0;
72   };
73 
74   char *name, *dobj_name;
75   int64_t cu_die_offset, ref_type, extent, parent, child, next;
76   int64_t size, elems, offset;
77   int tag, bit_size;
78 
79   DataObject *get_dobj (Dwarf_cnt *ctx);
80   char *get_dobjname (Dwarf_cnt *ctx);
81   char *dump ();
82 
83 private:
84   datatype_t *dtype;
85   datatype_t *get_datatype (Dwarf_cnt *ctx);
86   void get_dobj_for_members (Dwarf_cnt *ctx);
87   void set_dobjname (char *spec, char *nm);
88 };
89 
90 
91 //////////////////////////////////////////////////////////
92 //  class Dwarf_cnt
Dwarf_cnt()93 Dwarf_cnt::Dwarf_cnt ()
94 {
95   cu_offset = 0;
96   parent = 0;
97   module = NULL;
98   name = NULL;
99   func = NULL;
100   fortranMAIN = NULL;
101   dwr_types = NULL;
102   inlinedSubr = NULL;
103   level = 0;
104 }
105 
106 Dwr_type *
get_dwr_type(int64_t cu_die_offset)107 Dwarf_cnt::get_dwr_type (int64_t cu_die_offset)
108 {
109   Dwr_type *t = dwr_types->get (cu_die_offset);
110   if (t == NULL)
111     {
112       Dprintf (DUMP_DWARFLIB, "DWARF_ERROR: %s:%d wrong cu_die_offset=%lld in Dwarf_cnt::get_dwr_type\n",
113 	       get_basename (__FILE__), (int) __LINE__,
114 	       (long long) cu_die_offset);
115       t = put_dwr_type (cu_die_offset, 0); // DOBJ_UNSPECIFIED
116     }
117   return t;
118 }
119 
120 Dwr_type *
put_dwr_type(int64_t cu_die_offset,int tag)121 Dwarf_cnt::put_dwr_type (int64_t cu_die_offset, int tag)
122 {
123   Dwr_type *t = new Dwr_type (cu_die_offset, tag);
124   dwr_types->put (cu_die_offset, t);
125   return t;
126 }
127 
128 Dwr_type *
put_dwr_type(Dwr_Tag * dwrTag)129 Dwarf_cnt::put_dwr_type (Dwr_Tag *dwrTag)
130 {
131   Dwr_type *t = new Dwr_type (dwrTag->die, dwrTag->tag);
132   dwr_types->put (dwrTag->die, t);
133   return t;
134 }
135 
136 //////////////////////////////////////////////////////////
137 //  class Dwr_type
138 char *
dump()139 Dwr_type::dump ()
140 {
141   char *s = dbe_sprintf ("%lld %-15s name='%s' parent=%lld next=%lld child=%lld dtype=%llx",
142 			 (long long) cu_die_offset, DwrCU::tag2str (tag),
143 			 STR (name), (long long) parent, (long long) next,
144 			 (long long) child, (long long) dtype);
145   return s;
146 }
147 
148 void
set_dobjname(char * spec,char * nm)149 Dwr_type::set_dobjname (char *spec, char *nm)
150 {
151   if (spec)
152     {
153       if (nm)
154 	dobj_name = dbe_sprintf ("%s%s", spec, nm);
155       else
156 	dobj_name = dbe_sprintf ("%s<ANON=%lld>", spec,
157 				 (long long) cu_die_offset);
158     }
159   else
160     {
161       if (nm)
162 	dobj_name = dbe_sprintf ("%s", nm);
163       else
164 	dobj_name = dbe_sprintf ("<ANON=%lld>", (long long) cu_die_offset);
165     }
166 }
167 
168 char *
get_dobjname(Dwarf_cnt * ctx)169 Dwr_type::get_dobjname (Dwarf_cnt *ctx)
170 {
171   if (dobj_name)
172     return dobj_name;
173   switch (tag)
174     {
175     case DW_TAG_base_type:
176       set_dobjname (NULL, name);
177       for (int i = 0, len = (int) strlen (dobj_name); i < len; i++)
178 	{
179 	  if (dobj_name[i] == ' ')
180 	    dobj_name[i] = '_';
181 	}
182       break;
183     case DW_TAG_constant:
184     case DW_TAG_formal_parameter:
185     case DW_TAG_variable:
186       {
187 	Dwr_type *t = ctx->get_dwr_type (ref_type);
188 	set_dobjname (NULL, t->get_dobjname (ctx));
189 	break;
190       }
191     case DW_TAG_unspecified_type:
192       set_dobjname (NTXT ("unspecified:"), name);
193       break;
194     case DW_TAG_enumeration_type:
195       set_dobjname (NTXT ("enumeration:"), name);
196       break;
197     case DW_TAG_typedef:
198       {
199 	Dwr_type *t = ctx->get_dwr_type (ref_type);
200 	dobj_name = dbe_sprintf ("%s=%s", name, t->get_dobjname (ctx));
201 	break;
202       }
203     case DW_TAG_const_type:
204       set_dobjname (NTXT ("const+"), name);
205       break;
206     case DW_TAG_volatile_type:
207       set_dobjname (NTXT ("volatile+"), name);
208       break;
209     case DW_TAG_pointer_type:
210       {
211 	Dwr_type *t = ctx->get_dwr_type (ref_type);
212 	set_dobjname (NTXT ("pointer+"), t->get_dobjname (ctx));
213 	break;
214       }
215     case DW_TAG_reference_type:
216       {
217 	Dwr_type *t = ctx->get_dwr_type (ref_type);
218 	set_dobjname (NTXT ("reference+"), t->get_dobjname (ctx));
219 	break;
220       }
221     case DW_TAG_array_type:
222       {
223 	Dwr_type *t = ctx->get_dwr_type (ref_type);
224 	if (elems > 0)
225 	  dobj_name = dbe_sprintf ("array[%lld]:%s",
226 				   (long long) elems, t->get_dobjname (ctx));
227 	else
228 	  dobj_name = dbe_sprintf ("array[]:%s", t->get_dobjname (ctx));
229 	break;
230       }
231     case DW_TAG_structure_type:
232       set_dobjname (NTXT ("structure:"), name);
233       break;
234     case DW_TAG_union_type:
235       set_dobjname (NTXT ("union:"), name);
236       break;
237     case DW_TAG_class_type:
238       set_dobjname (NTXT ("class:"), name);
239       break;
240     case DW_TAG_member:
241       {
242 	Dwr_type *t = ctx->get_dwr_type (ref_type);
243 	if (bit_size > 0)
244 	  dobj_name = dbe_sprintf (NTXT ("%s:%lld"), t->get_dobjname (ctx),
245 				   (long long) bit_size);
246 	else
247 	  dobj_name = dbe_sprintf (NTXT ("%s"), t->get_dobjname (ctx));
248 	break;
249       }
250     default:
251       Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"),
252 	       get_basename (__FILE__), (int) __LINE__,
253 	       DwrCU::tag2str (tag), (long long) cu_die_offset);
254       set_dobjname (NTXT ("Undefined:"), NULL);
255       break;
256     }
257   return dobj_name;
258 }
259 
260 datatype_t*
get_datatype(Dwarf_cnt * ctx)261 Dwr_type::get_datatype (Dwarf_cnt *ctx)
262 {
263   if (dtype)
264     return dtype;
265   dtype = new datatype_t;
266   dtype->datatype_id = (unsigned) cu_die_offset;
267   dtype->memop_refs = 0;
268   dtype->event_data = 0;
269   dtype->dobj = NULL;
270   ctx->module->datatypes->incorporate (dtype, datatypeCmp);
271   return dtype;
272 }
273 
274 DataObject *
get_dobj(Dwarf_cnt * ctx)275 Dwr_type::get_dobj (Dwarf_cnt *ctx)
276 {
277   if (dtype == NULL)
278     dtype = get_datatype (ctx);
279   dtype->memop_refs++;
280   DataObject *dobj = dtype->dobj;
281   if (dobj)
282     return dobj;
283 
284   if (tag == 0)
285     dobj = dbeSession->find_dobj_by_name (PTXT (DOBJ_UNSPECIFIED));
286   else
287     {
288       dobj = dbeSession->createDataObject ();
289       dobj->size = size;
290       dobj->offset = offset;
291       dobj->scope = ctx->func ? (Histable*) ctx->func : (Histable*) ctx->module;
292     }
293   dtype->dobj = dobj;
294   if (parent)
295     {
296       Dwr_type *t = ctx->get_dwr_type (parent);
297       dobj->parent = t->get_dobj (ctx);
298     }
299 
300   if (ref_type)
301     {
302       Dwr_type *t = ctx->get_dwr_type (ref_type);
303       t->get_dobj (ctx);
304       if (size == 0)
305 	{
306 	  size = t->size;
307 	  dobj->size = size;
308 	}
309     }
310 
311   switch (tag)
312     {
313     case 0:
314       break;
315     case DW_TAG_array_type:
316     case DW_TAG_base_type:
317     case DW_TAG_unspecified_type:
318     case DW_TAG_enumeration_type:
319     case DW_TAG_typedef:
320     case DW_TAG_const_type:
321     case DW_TAG_volatile_type:
322     case DW_TAG_pointer_type:
323     case DW_TAG_reference_type:
324       dobj->set_dobjname (get_dobjname (ctx), NULL);
325       break;
326     case DW_TAG_structure_type:
327     case DW_TAG_union_type:
328     case DW_TAG_class_type:
329       dobj->set_dobjname (get_dobjname (ctx), NULL);
330       dobj->master = dbeSession->find_dobj_by_name (dobj_name);
331       get_dobj_for_members (ctx);
332       break;
333     case DW_TAG_constant:
334     case DW_TAG_formal_parameter:
335     case DW_TAG_member:
336     case DW_TAG_variable:
337       if (dobj->parent == NULL)
338 	dobj->parent = dbeSession->get_Scalars_DataObject ();
339       dobj->set_dobjname (get_dobjname (ctx), name);
340       break;
341     default:
342       Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"),
343 	       get_basename (__FILE__), (int) __LINE__,
344 	       DwrCU::tag2str (tag), (long long) cu_die_offset);
345       break;
346     }
347   return dobj;
348 }
349 
350 void
get_dobj_for_members(Dwarf_cnt * ctx)351 Dwr_type::get_dobj_for_members (Dwarf_cnt *ctx)
352 {
353   for (int64_t i = child; i != 0;)
354     {
355       Dwr_type *t = ctx->get_dwr_type (i);
356       t->get_dobj (ctx);
357       i = t->next;
358     }
359 }
360 
361 //////////////////////////////////////////////////////////
362 //  class Dwarf
Dwarf(Stabs * _stabs)363 Dwarf::Dwarf (Stabs *_stabs)
364 {
365   stabs = _stabs;
366   status = Stabs::DBGD_ERR_NONE;
367   dwrCUs = 0;
368   debug_infoSec = NULL;
369   debug_abbrevSec = NULL;
370   debug_strSec = NULL;
371   debug_lineSec = NULL;
372   debug_rangesSec = NULL;
373   elf = stabs->openElf (true);
374   if (elf == NULL)
375     {
376       status = Stabs::DBGD_ERR_BAD_ELF_FORMAT;
377       return;
378     }
379   debug_infoSec = dwrGetSec (NTXT (".debug_info"));
380   if (debug_infoSec)
381     {
382       debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL);
383       debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc);
384       if (debug_infoSec->reloc)
385 	debug_infoSec->reloc->dump ();
386     }
387   debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev"));
388   debug_strSec = dwrGetSec (NTXT (".debug_str"));
389   debug_lineSec = dwrGetSec (NTXT (".debug_line"));
390   debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
391 
392   if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
393     {
394       status = Stabs::DBGD_ERR_NO_DWARF;
395       return;
396     }
397 }
398 
~Dwarf()399 Dwarf::~Dwarf ()
400 {
401   delete debug_infoSec;
402   delete debug_abbrevSec;
403   delete debug_strSec;
404   delete debug_lineSec;
405   delete debug_rangesSec;
406   Destroy (dwrCUs);
407 }
408 
409 DwrSec *
dwrGetSec(const char * sec_name)410 Dwarf::dwrGetSec (const char *sec_name)
411 {
412   int secN = elf->elf_get_sec_num (sec_name);
413   if (secN > 0)
414     {
415       Elf_Data *elfData = elf->elf_getdata (secN);
416       if (elfData)
417 	return new DwrSec ((unsigned char *) elfData->d_buf, elfData->d_size,
418 			   elf->need_swap_endian,
419 			   elf->elf_getclass () == ELFCLASS32);
420     }
421   return NULL;
422 }
423 
424 uint64_t
get_low_pc()425 DwrCU::get_low_pc ()
426 {
427   uint64_t pc = Dwarf_addr (DW_AT_low_pc);
428   if (pc)
429     return pc;
430   return pc;
431 }
432 
433 char *
get_linkage_name()434 DwrCU::get_linkage_name ()
435 {
436   char *nm = Dwarf_string (DW_AT_linkage_name);
437   if (nm != NULL)
438     return nm;
439   nm = Dwarf_string (DW_AT_SUN_link_name);
440   if (nm != NULL)
441     return nm;
442   return Dwarf_string (DW_AT_MIPS_linkage_name);
443 }
444 
445 void
parseChild(Dwarf_cnt * ctx)446 DwrCU::parseChild (Dwarf_cnt *ctx)
447 {
448   if (!dwrTag.hasChild)
449     return;
450   uint64_t old_size = debug_infoSec->size;
451   uint64_t next_die_offset = 0;
452   Dwarf_Die next_die;
453   if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
454     {
455       next_die_offset = next_die + cu_offset;
456       if (next_die_offset <= debug_infoSec->offset)
457 	{
458 	  Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"),
459 		   (long long) next_die, (long long) debug_infoSec->offset);
460 	  next_die_offset = 0;
461 	}
462       else if (debug_infoSec->size > next_die_offset)
463 	debug_infoSec->size = next_die_offset;
464     }
465   dwrTag.level++;
466   ctx->level++;
467   for (;;)
468     {
469       if (set_die (0) != DW_DLV_OK)
470 	break;
471       Function *func;
472       char *old_name;
473       int hasChild = dwrTag.hasChild;
474       switch (dwrTag.tag)
475 	{
476 	case DW_TAG_imported_declaration:
477 	  if (Stabs::is_fortran (ctx->module->lang_code))
478 	    {
479 	      char *link_name = Dwarf_string (DW_AT_name);
480 	      ctx->fortranMAIN = NULL;
481 	      parseChild (ctx);
482 	      hasChild = 0;
483 	      if (ctx->fortranMAIN)
484 		{
485 		  ctx->fortranMAIN->set_match_name (link_name);
486 		  ctx->fortranMAIN = NULL;
487 		}
488 	    }
489 	  break;
490 	case DW_TAG_subprogram:
491 	  if (dwrTag.get_attr (DW_AT_abstract_origin))
492 	    break;
493 	  if (dwrTag.get_attr (DW_AT_declaration))
494 	    {
495 	      // Only declaration
496 	      if (Stabs::is_fortran (ctx->module->lang_code))
497 		{
498 		  char *link_name = Dwarf_string (DW_AT_name);
499 		  if (link_name && streq (link_name, NTXT ("MAIN")))
500 		    ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true);
501 		}
502 	      if (get_linkage_name () == NULL)
503 		break;
504 	    }
505 	  func = append_Function (ctx);
506 	  if (func)
507 	    {
508 	      if (Stabs::is_fortran (ctx->module->lang_code) &&
509 		  streq (func->get_match_name (), NTXT ("MAIN")))
510 		ctx->fortranMAIN = func;
511 	      old_name = ctx->name;
512 	      Function *old_func = ctx->func;
513 	      ctx->name = func->get_match_name ();
514 	      ctx->func = func;
515 	      parseChild (ctx);
516 	      hasChild = 0;
517 	      ctx->name = old_name;
518 	      ctx->func = old_func;
519 	    }
520 	  break;
521 	case DW_TAG_module:
522 	  old_name = ctx->name;
523 	  ctx->name = Dwarf_string (DW_AT_SUN_link_name);
524 	  parseChild (ctx);
525 	  hasChild = 0;
526 	  ctx->name = old_name;
527 	  break;
528 	case DW_TAG_class_type:
529 	  old_name = ctx->name;
530 	  ctx->name = Dwarf_string (DW_AT_name);
531 	  parseChild (ctx);
532 	  hasChild = 0;
533 	  ctx->name = old_name;
534 	  break;
535 	case DW_TAG_structure_type:
536 	  old_name = ctx->name;
537 	  ctx->name = NULL;
538 	  parseChild (ctx);
539 	  hasChild = 0;
540 	  ctx->name = old_name;
541 	  break;
542 	case DW_TAG_namespace:
543 	  old_name = ctx->name;
544 	  ctx->name = Dwarf_string (DW_AT_name);
545 	  parseChild (ctx);
546 	  hasChild = 0;
547 	  ctx->name = old_name;
548 	  break;
549 	case DW_TAG_lexical_block:
550 	  old_name = ctx->name;
551 	  ctx->name = NULL;
552 	  parseChild (ctx);
553 	  hasChild = 0;
554 	  ctx->name = old_name;
555 	  break;
556 	case DW_TAG_SUN_memop_info:
557 	  isMemop = true;
558 	  break;
559 	case DW_TAG_inlined_subroutine:
560 	  if (ctx->module)
561 	    {
562 	      parse_inlined_subroutine (ctx);
563 	      hasChild = 0;
564 	    }
565 	  break;
566 	default: // No more special cases
567 	  break;
568 	}
569       if (hasChild)
570 	parseChild (ctx);
571     }
572   ctx->level--;
573   dwrTag.level--;
574   if (next_die_offset != 0)
575     debug_infoSec->offset = next_die_offset;
576   debug_infoSec->size = old_size;
577 }
578 
579 bool
archive_Dwarf(LoadObject * lo)580 Dwarf::archive_Dwarf (LoadObject *lo)
581 {
582   if (debug_infoSec == NULL)
583     return false;
584   if (dwrCUs)
585     return true;
586   dwrCUs = new Vector<DwrCU *>;
587 
588   debug_infoSec->offset = 0;
589   while (debug_infoSec->offset < debug_infoSec->sizeSec)
590     {
591       DwrCU *dwrCU = new DwrCU (this);
592       dwrCUs->append (dwrCU);
593       debug_infoSec->size = debug_infoSec->sizeSec;
594       debug_infoSec->offset = dwrCU->next_cu_offset;
595 
596       if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
597 	{
598 	  Dprintf (1, "DwrCU::archive_Dwarf: CU=%lld  (offset=0x%llx); set_die(0x%llx) failed\n",
599 		   (long long) dwrCUs->size (), (long long) dwrCU->cu_offset,
600 		   (long long) dwrCU->cu_header_offset);
601 	  continue;
602 	}
603 
604       Module *mod = dwrCU->parse_cu_header (lo);
605       if (mod)
606 	{
607 	  mod->hdrOffset = dwrCUs->size ();
608 	  DwrLineRegs *lineReg = dwrCU->get_dwrLineReg ();
609 	  dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
610 	  for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
611 	    {
612 	      char *fname = lineReg->getPath (i + 1);
613 	      SourceFile *sf = mod->findSource (fname, true);
614 	      dwrCU->srcFiles->append (sf);
615 	    }
616 
617 	  Dwarf_cnt ctx;
618 	  ctx.module = mod;
619 	  dwrCU->parseChild (&ctx);
620 	  if (dwrCU->dwrInlinedSubrs && DUMP_DWARFLIB)
621 	    {
622 	      char msg[128];
623 	      char *lo_name = mod->loadobject ? mod->loadobject->get_name ()
624 		      : NULL;
625 	      snprintf (msg, sizeof (msg), NTXT ("\ndwrCUs[%lld]: %s:%s\n"),
626 			(long long) dwrCUs->size (),
627 			STR (lo_name), STR (mod->get_name ()));
628 	      dwrCU->dwrInlinedSubrs->dump (msg);
629 	    }
630 	}
631     }
632   return true;
633 }
634 
635 void
srcline_Dwarf(Module * module)636 Dwarf::srcline_Dwarf (Module *module)
637 {
638   if (module == NULL || module->hdrOffset == 0)
639     return;
640   DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
641   dwrCU->map_dwarf_lines (module);
642 }
643 
644 
645 // parse hwcprof info for given module in loadobject
646 
647 void
read_hwcprof_info(Module * module)648 Dwarf::read_hwcprof_info (Module *module)
649 {
650   if (module->datatypes || (module->hdrOffset == 0))
651     return;
652   DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
653   if (!dwrCU->isMemop)
654     return;
655   module->datatypes = new Vector<datatype_t*>;
656   if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
657     {
658       Dprintf (1, "Dwarf::read_hwcprof_info: CU=%lld  (offset=0x%llx); set_die(0x%llx) failed\n",
659 	       (long long) module->hdrOffset, (long long) dwrCU->cu_offset,
660 	       (long long) dwrCU->cu_header_offset);
661       return;
662     }
663   Dwarf_cnt ctx;
664   ctx.module = module;
665   ctx.cu_offset = dwrCU->cu_offset; // CU header offset;
666   ctx.dwr_types = new DefaultMap<int64_t, Dwr_type*>;
667   ctx.put_dwr_type (0, 0); // for DOBJ_UNSPECIFIED
668   dwrCU->read_hwcprof_info (&ctx);
669 
670   Vector<inst_info_t*> *infoList = module->infoList;
671   Dprintf (DUMP_DWARFLIB,
672      "\n\n ### Dwarf::read_hwcprof_info: module: '%s'  infoList->size()=%lld\n",
673      STR (module->get_name ()),
674      (long long) (infoList ? infoList->size () : -1));
675   for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
676     {
677       inst_info_t *ip = infoList->fetch (i);
678       memop_info_t *mp = ip->memop;
679       Dwr_type *t = ctx.get_dwr_type (mp->datatype_id);
680       t->get_dobj (&ctx);
681     }
682 
683 #ifdef DEBUG
684   Dprintf (DUMP_DWARFLIB,
685 	   "\n\n ### Dwarf::read_hwcprof_info: '%s'  infoList->size()=%lld\n",
686 	   STR (module->get_name ()),
687 	   (long long) (infoList ? infoList->size () : 1));
688   for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
689     {
690       inst_info_t *ip = infoList->fetch (i);
691       memop_info_t *mp = ip->memop;
692       Dprintf (DUMP_DWARFLIB,
693 	       "  %d id=%lld  offset=%lld  signature=%lld  datatype_id=%lld \n",
694 	       i, (long long) mp->id, (long long) mp->offset,
695 	       (long long) mp->signature, (long long) mp->datatype_id);
696     }
697 
698   Vector<int64_t> *keys = ctx.dwr_types->keySet ();
699   Dprintf (DUMP_DWARFLIB,
700 	   "\n\n ### Dwarf::read_hwcprof_info: '%s'  keys->size()=%lld\n",
701 	   STR (module->get_name ()), (long long) (keys ? keys->size () : -1));
702   for (int i = 0, sz = keys->size (); i < sz; i++)
703     {
704       int64_t ind = keys->fetch (i);
705       Dwr_type *t = ctx.get_dwr_type (ind);
706       Dprintf (DUMP_DWARFLIB, NTXT ("  %d %lld %s\n"), i,
707 	       (long long) ind, t->dump ());
708     }
709 #endif
710 }
711 
712 void
read_hwcprof_info(Dwarf_cnt * ctx)713 DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
714 {
715   if (!dwrTag.hasChild)
716     return;
717   uint64_t old_size = debug_infoSec->size;
718   uint64_t next_die_offset = 0;
719   Dwarf_Die next_die;
720   if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
721     {
722       next_die_offset = next_die + cu_offset;
723       if (next_die_offset <= debug_infoSec->offset)
724 	next_die_offset = 0;
725       else if (debug_infoSec->size > next_die_offset)
726 	debug_infoSec->size = next_die_offset;
727     }
728   dwrTag.level++;
729   ctx->level++;
730   for (;;)
731     {
732       if (set_die (0) != DW_DLV_OK)
733 	break;
734       Dprintf (DUMP_DWARFLIB, NTXT ("%s:%d <%lld:%lld> cu_die=%lld %-15s\n"),
735 	       get_basename (__FILE__), (int) __LINE__, (long long) ctx->level,
736 	       (long long) dwrTag.die, (long long) dwrTag.offset,
737 	       DwrCU::tag2str (dwrTag.tag));
738       switch (dwrTag.tag)
739 	{
740 	case DW_TAG_SUN_memop_info:
741 	  {
742 	    if (ctx->func == NULL)
743 	      break;
744 	    Dwarf_Unsigned mid = Dwarf_data (DW_AT_SUN_profile_id);
745 	    Dwarf_Unsigned off = Dwarf_data (DW_AT_SUN_func_offset);
746 	    Dwarf_Unsigned sig = Dwarf_data (DW_AT_SUN_memop_signature);
747 	    Dwarf_Off ref = Dwarf_ref (DW_AT_SUN_memop_type_ref);
748 
749 	    // define memop entry
750 	    memop_info_t *memop = new memop_info_t;
751 	    memop->id = (unsigned) mid;
752 	    memop->signature = (unsigned) sig;
753 	    memop->datatype_id = ref ? (unsigned) ref : 0;
754 	    memop->offset = (unsigned) (ctx->func->img_offset + off);
755 
756 	    // define instop entry
757 	    inst_info_t *instop = new inst_info_t;
758 	    instop->type = CPF_INSTR_TYPE_PREFETCH; // XXXX UNKNOWN
759 	    instop->offset = memop->offset;
760 	    instop->memop = memop;
761 	    if (ctx->module->infoList == NULL)
762 	      ctx->module->infoList = new Vector<inst_info_t*>;
763 	    ctx->module->infoList->append (instop);
764 	    break;
765 	  }
766 	case DW_TAG_SUN_codeflags:
767 	  {
768 	    if (ctx->func == NULL)
769 	      break;
770 	    Dwarf_Unsigned kind = Dwarf_data (DW_AT_SUN_cf_kind);
771 	    if (kind == DW_ATCF_SUN_branch_target)
772 	      {
773 		DwrSec *secp = Dwarf_block (DW_AT_SUN_func_offsets);
774 		if (secp)
775 		  {
776 		    int foffset = 0;
777 		    for (int i = 0; secp->offset < secp->size; i++)
778 		      {
779 			int val = (int) secp->GetSLEB128 ();
780 			if (i == 0 || val != 0)
781 			  {
782 			    foffset += val;
783 			    target_info_t *t = new target_info_t;
784 			    t->offset = (unsigned) (ctx->func->img_offset + foffset);
785 			    ctx->module->bTargets.incorporate (t, targetOffsetCmp);
786 			  }
787 		      }
788 		    delete(secp);
789 		  }
790 	      }
791 	    break;
792 	  }
793 	case DW_TAG_subprogram:
794 	  {
795 	    Function *old_func = ctx->func;
796 	    if (dwrTag.get_attr (DW_AT_abstract_origin)
797 				 || dwrTag.get_attr (DW_AT_declaration))
798 	      ctx->func = NULL;
799 	    else
800 	      ctx->func = append_Function (ctx);
801 	    read_hwcprof_info (ctx);
802 	    ctx->func = old_func;
803 	    break;
804 	  }
805 	case DW_TAG_base_type:
806 	  {
807 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
808 	    t->name = Dwarf_string (DW_AT_name);
809 	    t->size = Dwarf_data (DW_AT_byte_size);
810 	    break;
811 	  }
812 	case DW_TAG_unspecified_type:
813 	  ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
814 	  break;
815 	case DW_TAG_enumeration_type:
816 	  {
817 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
818 	    t->name = Dwarf_string (DW_AT_name);
819 	    t->size = Dwarf_data (DW_AT_byte_size);
820 	    break;
821 	  }
822 	case DW_TAG_constant:
823 	case DW_TAG_formal_parameter:
824 	case DW_TAG_variable:
825 	case DW_TAG_typedef:
826 	case DW_TAG_const_type:
827 	case DW_TAG_volatile_type:
828 	  {
829 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
830 	    t->name = Dwarf_string (DW_AT_name);
831 	    t->ref_type = Dwarf_ref (DW_AT_type);
832 	    break;
833 	  }
834 	case DW_TAG_pointer_type:
835 	case DW_TAG_reference_type:
836 	  {
837 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
838 	    t->name = Dwarf_string (DW_AT_name);
839 	    t->ref_type = Dwarf_ref (DW_AT_type);
840 	    t->size = (dwarf->stabs->get_class () == W64) ? 8 : 4;
841 	    break;
842 	  }
843 	case DW_TAG_array_type:
844 	  {
845 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
846 	    t->name = Dwarf_string (DW_AT_name);
847 	    t->ref_type = Dwarf_ref (DW_AT_type);
848 	    t->size = Dwarf_data (DW_AT_byte_size);
849 	    ctx->size = -1;
850 	    read_hwcprof_info (ctx);
851 	    t->elems = ctx->size;
852 	    break;
853 	  }
854 	case DW_TAG_subrange_type:
855 	  {
856 	    int64_t ref_type = Dwarf_ref (DW_AT_type);
857 	    int64_t hi = Dwarf_data (DW_AT_upper_bound);
858 	    int64_t lo = Dwarf_data (DW_AT_lower_bound);
859 	    int64_t ss = Dwarf_data (DW_AT_stride_size);
860 	    ctx->size = 1 + hi - lo;
861 	    if (ss != 0)
862 	      ctx->size /= ss;
863 	    Dprintf (DUMP_DWARFLIB,
864 		    "Got subrange [%lld:%lld:%lld] indexed <%lld>: size=%lld\n",
865 		     (long long) lo, (long long) hi, (long long) ss,
866 		     (long long) ref_type, (long long) ctx->size);
867 	    break;
868 	  }
869 	case DW_TAG_structure_type:
870 	case DW_TAG_union_type:
871 	case DW_TAG_class_type:
872 	  {
873 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
874 	    t->name = Dwarf_string (DW_AT_name);
875 	    t->size = Dwarf_data (DW_AT_byte_size);
876 	    t->extent = Dwarf_ref (DW_AT_sibling);
877 	    int64_t old_parent = ctx->parent;
878 	    ctx->parent = t->cu_die_offset;
879 
880 	    char *old_name = ctx->name;
881 	    ctx->name = (dwrTag.tag == DW_TAG_class_type) ? Dwarf_string (DW_AT_name) : NULL;
882 	    read_hwcprof_info (ctx);
883 	    ctx->name = old_name;
884 	    ctx->parent = old_parent;
885 	    // Reverse children
886 	    for (int64_t i = t->child, last = 0; i != 0;)
887 	      {
888 		Dwr_type *t1 = ctx->get_dwr_type (i);
889 		t->child = i;
890 		i = t1->next;
891 		t1->next = last;
892 		last = t->child;
893 	      }
894 	    break;
895 	  }
896 	case DW_TAG_member:
897 	  {
898 	    if (ctx->parent == 0)
899 	      {
900 		Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d %s cu_die_offset=%lld\n"),
901 			 get_basename (__FILE__), (int) __LINE__,
902 			 DwrCU::tag2str (dwrTag.tag), (long long) dwrTag.die);
903 		break;
904 	      }
905 	    Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
906 	    t->name = Dwarf_string (DW_AT_name);
907 	    t->ref_type = Dwarf_ref (DW_AT_type);
908 	    t->offset = Dwarf_location (DW_AT_data_member_location);
909 	    Dwr_type *parent = ctx->get_dwr_type (ctx->parent);
910 	    t->parent = ctx->parent;
911 	    t->next = parent->child; // a reverse order of members
912 	    parent->child = t->cu_die_offset;
913 	    t->bit_size = (uint32_t) Dwarf_data (DW_AT_bit_size);
914 	    break;
915 	  }
916 	case DW_TAG_module:
917 	  {
918 	    char *old_name = ctx->name;
919 	    ctx->name = Dwarf_string (DW_AT_SUN_link_name);
920 	    read_hwcprof_info (ctx);
921 	    ctx->name = old_name;
922 	    break;
923 	  }
924 	case DW_TAG_namespace:
925 	  {
926 	    char *old_name = ctx->name;
927 	    ctx->name = Dwarf_string (DW_AT_name);
928 	    read_hwcprof_info (ctx);
929 	    ctx->name = old_name;
930 	    break;
931 	  }
932 	case DW_TAG_lexical_block:
933 	  {
934 	    char *old_name = ctx->name;
935 	    ctx->name = NULL;
936 	    read_hwcprof_info (ctx);
937 	    ctx->name = old_name;
938 	    break;
939 	  }
940 	default: // No more special cases
941 	  read_hwcprof_info (ctx);
942 	  break;
943 	}
944     }
945   ctx->level--;
946   dwrTag.level--;
947   if (next_die_offset != 0)
948     debug_infoSec->offset = next_die_offset;
949   debug_infoSec->size = old_size;
950 }
951 
952 // Append function to module
953 Function *
append_Function(Dwarf_cnt * ctx)954 DwrCU::append_Function (Dwarf_cnt *ctx)
955 {
956   char *outerName = ctx->name, *name, tmpname[2048];
957   Function *func;
958   char *fname = Dwarf_string (DW_AT_name);
959   if (fname && outerName && !strchr (fname, '.'))
960     {
961       size_t outerlen = strlen (outerName);
962       if (outerlen > 0 && outerName[outerlen - 1] == '_')
963 	{
964 	  outerlen--;
965 	  snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName);
966 	  snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname);
967 	}
968       else
969 	snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname);
970       name = tmpname;
971       Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name);
972     }
973   else
974     name = fname;
975 
976   char *link_name = get_linkage_name ();
977   if (link_name == NULL)
978     link_name = name;
979 
980   uint64_t pc = get_low_pc ();
981   func = dwarf->stabs->append_Function (module, link_name, pc);
982   if (func != NULL)
983     {
984       int lineno = (int) Dwarf_data (DW_AT_decl_line);
985       func->set_match_name (name);
986       if (lineno > 0)
987 	{
988 	  func->setLineFirst (lineno);
989 	  if (dwrLineReg == NULL)
990 	    dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
991 						   stmt_list_offset), comp_dir);
992 	  int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1;
993 	  SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno)
994 		  : module->getMainSrc ();
995 	  func->setDefSrc (sf);
996 	  func->pushSrcFile (func->def_source, 0);
997 	  func->popSrcFile ();
998 	}
999     }
1000   return func;
1001 }
1002 
1003 // Get language code
1004 Sp_lang_code
Dwarf_lang()1005 DwrCU::Dwarf_lang ()
1006 {
1007   char *str = Dwarf_string (DW_AT_producer);
1008   if (str && strncmp (str, NTXT ("GNU"), 3) == 0)
1009     isGNU = true;
1010   int64_t lang = Dwarf_data (DW_AT_language);
1011   switch (lang)
1012     {
1013     case DW_LANG_C89:
1014     case DW_LANG_C:
1015       return Sp_lang_c; // Sp_lang_ansic?
1016     case DW_LANG_C99:
1017       return Sp_lang_c99;
1018     case DW_LANG_C_plus_plus:
1019       return isGNU ? Sp_lang_gcc : Sp_lang_cplusplus;
1020     case DW_LANG_Fortran90:
1021       return Sp_lang_fortran90;
1022     case DW_LANG_Fortran77:
1023       return Sp_lang_fortran;
1024     case DW_LANG_Java:
1025       return Sp_lang_java;
1026     case DW_LANG_Mips_Assembler:
1027     case DW_LANG_SUN_Assembler:
1028       return Sp_lang_asm;
1029     case DW_LANG_Pascal83:
1030       return Sp_lang_pascal;
1031     default:
1032     case DW_LANG_Ada83:
1033     case DW_LANG_Cobol74:
1034     case DW_LANG_Cobol85:
1035     case DW_LANG_Modula2:
1036     case DW_LANG_Ada95:
1037     case DW_LANG_Fortran95:
1038     case DW_LANG_lo_user:
1039       return Sp_lang_unknown;
1040     }
1041 }
1042