]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/src/Dwarf.cc
5485be7f796fea27de8d038f52063990336fcda1
[thirdparty/binutils-gdb.git] / gprofng / src / Dwarf.cc
1 /* Copyright (C) 2021-2023 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
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
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
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
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 *
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 *
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 *
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 *
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
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 *
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*
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 *
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
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
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
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 *
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
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 *
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
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
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 if (lineReg != NULL)
610 {
611 dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
612 for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
613 {
614 char *fname = lineReg->getPath (i + 1);
615 SourceFile *sf = mod->findSource (fname, true);
616 dwrCU->srcFiles->append (sf);
617 }
618 }
619
620 Dwarf_cnt ctx;
621 ctx.module = mod;
622 dwrCU->parseChild (&ctx);
623 if (dwrCU->dwrInlinedSubrs && DUMP_DWARFLIB)
624 {
625 char msg[128];
626 char *lo_name = mod->loadobject ? mod->loadobject->get_name ()
627 : NULL;
628 snprintf (msg, sizeof (msg), NTXT ("\ndwrCUs[%lld]: %s:%s\n"),
629 (long long) dwrCUs->size (),
630 STR (lo_name), STR (mod->get_name ()));
631 dwrCU->dwrInlinedSubrs->dump (msg);
632 }
633 }
634 }
635 return true;
636 }
637
638 void
639 Dwarf::srcline_Dwarf (Module *module)
640 {
641 if (module == NULL || module->hdrOffset == 0)
642 return;
643 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
644 dwrCU->map_dwarf_lines (module);
645 }
646
647
648 // parse hwcprof info for given module in loadobject
649
650 void
651 Dwarf::read_hwcprof_info (Module *module)
652 {
653 if (module->datatypes || (module->hdrOffset == 0))
654 return;
655 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
656 if (!dwrCU->isMemop)
657 return;
658 module->datatypes = new Vector<datatype_t*>;
659 if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
660 {
661 Dprintf (1, "Dwarf::read_hwcprof_info: CU=%lld (offset=0x%llx); set_die(0x%llx) failed\n",
662 (long long) module->hdrOffset, (long long) dwrCU->cu_offset,
663 (long long) dwrCU->cu_header_offset);
664 return;
665 }
666 Dwarf_cnt ctx;
667 ctx.module = module;
668 ctx.cu_offset = dwrCU->cu_offset; // CU header offset;
669 ctx.dwr_types = new DefaultMap<int64_t, Dwr_type*>;
670 ctx.put_dwr_type (0, 0); // for DOBJ_UNSPECIFIED
671 dwrCU->read_hwcprof_info (&ctx);
672
673 Vector<inst_info_t*> *infoList = module->infoList;
674 Dprintf (DUMP_DWARFLIB,
675 "\n\n ### Dwarf::read_hwcprof_info: module: '%s' infoList->size()=%lld\n",
676 STR (module->get_name ()),
677 (long long) (infoList ? infoList->size () : -1));
678 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
679 {
680 inst_info_t *ip = infoList->fetch (i);
681 memop_info_t *mp = ip->memop;
682 Dwr_type *t = ctx.get_dwr_type (mp->datatype_id);
683 t->get_dobj (&ctx);
684 }
685
686 #ifdef DEBUG
687 Dprintf (DUMP_DWARFLIB,
688 "\n\n ### Dwarf::read_hwcprof_info: '%s' infoList->size()=%lld\n",
689 STR (module->get_name ()),
690 (long long) (infoList ? infoList->size () : 1));
691 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
692 {
693 inst_info_t *ip = infoList->fetch (i);
694 memop_info_t *mp = ip->memop;
695 Dprintf (DUMP_DWARFLIB,
696 " %d id=%lld offset=%lld signature=%lld datatype_id=%lld \n",
697 i, (long long) mp->id, (long long) mp->offset,
698 (long long) mp->signature, (long long) mp->datatype_id);
699 }
700
701 Vector<int64_t> *keys = ctx.dwr_types->keySet ();
702 Dprintf (DUMP_DWARFLIB,
703 "\n\n ### Dwarf::read_hwcprof_info: '%s' keys->size()=%lld\n",
704 STR (module->get_name ()), (long long) (keys ? keys->size () : -1));
705 for (int i = 0, sz = keys->size (); i < sz; i++)
706 {
707 int64_t ind = keys->fetch (i);
708 Dwr_type *t = ctx.get_dwr_type (ind);
709 Dprintf (DUMP_DWARFLIB, NTXT (" %d %lld %s\n"), i,
710 (long long) ind, t->dump ());
711 }
712 #endif
713 }
714
715 void
716 DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
717 {
718 if (!dwrTag.hasChild)
719 return;
720 uint64_t old_size = debug_infoSec->size;
721 uint64_t next_die_offset = 0;
722 Dwarf_Die next_die;
723 if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
724 {
725 next_die_offset = next_die + cu_offset;
726 if (next_die_offset <= debug_infoSec->offset)
727 next_die_offset = 0;
728 else if (debug_infoSec->size > next_die_offset)
729 debug_infoSec->size = next_die_offset;
730 }
731 dwrTag.level++;
732 ctx->level++;
733 for (;;)
734 {
735 if (set_die (0) != DW_DLV_OK)
736 break;
737 Dprintf (DUMP_DWARFLIB, NTXT ("%s:%d <%lld:%lld> cu_die=%lld %-15s\n"),
738 get_basename (__FILE__), (int) __LINE__, (long long) ctx->level,
739 (long long) dwrTag.die, (long long) dwrTag.offset,
740 DwrCU::tag2str (dwrTag.tag));
741 switch (dwrTag.tag)
742 {
743 case DW_TAG_SUN_memop_info:
744 {
745 if (ctx->func == NULL)
746 break;
747 Dwarf_Unsigned mid = Dwarf_data (DW_AT_SUN_profile_id);
748 Dwarf_Unsigned off = Dwarf_data (DW_AT_SUN_func_offset);
749 Dwarf_Unsigned sig = Dwarf_data (DW_AT_SUN_memop_signature);
750 Dwarf_Off ref = Dwarf_ref (DW_AT_SUN_memop_type_ref);
751
752 // define memop entry
753 memop_info_t *memop = new memop_info_t;
754 memop->id = (unsigned) mid;
755 memop->signature = (unsigned) sig;
756 memop->datatype_id = ref ? (unsigned) ref : 0;
757 memop->offset = (unsigned) (ctx->func->img_offset + off);
758
759 // define instop entry
760 inst_info_t *instop = new inst_info_t;
761 instop->type = CPF_INSTR_TYPE_PREFETCH; // XXXX UNKNOWN
762 instop->offset = memop->offset;
763 instop->memop = memop;
764 if (ctx->module->infoList == NULL)
765 ctx->module->infoList = new Vector<inst_info_t*>;
766 ctx->module->infoList->append (instop);
767 break;
768 }
769 case DW_TAG_SUN_codeflags:
770 {
771 if (ctx->func == NULL)
772 break;
773 Dwarf_Unsigned kind = Dwarf_data (DW_AT_SUN_cf_kind);
774 if (kind == DW_ATCF_SUN_branch_target)
775 {
776 DwrSec *secp = Dwarf_block (DW_AT_SUN_func_offsets);
777 if (secp)
778 {
779 int foffset = 0;
780 for (int i = 0; secp->offset < secp->size; i++)
781 {
782 int val = (int) secp->GetSLEB128 ();
783 if (i == 0 || val != 0)
784 {
785 foffset += val;
786 target_info_t *t = new target_info_t;
787 t->offset = (unsigned) (ctx->func->img_offset + foffset);
788 ctx->module->bTargets.incorporate (t, targetOffsetCmp);
789 }
790 }
791 delete(secp);
792 }
793 }
794 break;
795 }
796 case DW_TAG_subprogram:
797 {
798 Function *old_func = ctx->func;
799 if (dwrTag.get_attr (DW_AT_abstract_origin)
800 || dwrTag.get_attr (DW_AT_declaration))
801 ctx->func = NULL;
802 else
803 ctx->func = append_Function (ctx);
804 read_hwcprof_info (ctx);
805 ctx->func = old_func;
806 break;
807 }
808 case DW_TAG_base_type:
809 {
810 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
811 t->name = Dwarf_string (DW_AT_name);
812 t->size = Dwarf_data (DW_AT_byte_size);
813 break;
814 }
815 case DW_TAG_unspecified_type:
816 ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
817 break;
818 case DW_TAG_enumeration_type:
819 {
820 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
821 t->name = Dwarf_string (DW_AT_name);
822 t->size = Dwarf_data (DW_AT_byte_size);
823 break;
824 }
825 case DW_TAG_constant:
826 case DW_TAG_formal_parameter:
827 case DW_TAG_variable:
828 case DW_TAG_typedef:
829 case DW_TAG_const_type:
830 case DW_TAG_volatile_type:
831 {
832 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
833 t->name = Dwarf_string (DW_AT_name);
834 t->ref_type = Dwarf_ref (DW_AT_type);
835 break;
836 }
837 case DW_TAG_pointer_type:
838 case DW_TAG_reference_type:
839 {
840 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
841 t->name = Dwarf_string (DW_AT_name);
842 t->ref_type = Dwarf_ref (DW_AT_type);
843 t->size = (dwarf->stabs->get_class () == W64) ? 8 : 4;
844 break;
845 }
846 case DW_TAG_array_type:
847 {
848 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
849 t->name = Dwarf_string (DW_AT_name);
850 t->ref_type = Dwarf_ref (DW_AT_type);
851 t->size = Dwarf_data (DW_AT_byte_size);
852 ctx->size = -1;
853 read_hwcprof_info (ctx);
854 t->elems = ctx->size;
855 break;
856 }
857 case DW_TAG_subrange_type:
858 {
859 int64_t ref_type = Dwarf_ref (DW_AT_type);
860 int64_t hi = Dwarf_data (DW_AT_upper_bound);
861 int64_t lo = Dwarf_data (DW_AT_lower_bound);
862 int64_t ss = Dwarf_data (DW_AT_stride_size);
863 ctx->size = 1 + hi - lo;
864 if (ss != 0)
865 ctx->size /= ss;
866 Dprintf (DUMP_DWARFLIB,
867 "Got subrange [%lld:%lld:%lld] indexed <%lld>: size=%lld\n",
868 (long long) lo, (long long) hi, (long long) ss,
869 (long long) ref_type, (long long) ctx->size);
870 break;
871 }
872 case DW_TAG_structure_type:
873 case DW_TAG_union_type:
874 case DW_TAG_class_type:
875 {
876 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
877 t->name = Dwarf_string (DW_AT_name);
878 t->size = Dwarf_data (DW_AT_byte_size);
879 t->extent = Dwarf_ref (DW_AT_sibling);
880 int64_t old_parent = ctx->parent;
881 ctx->parent = t->cu_die_offset;
882
883 char *old_name = ctx->name;
884 ctx->name = (dwrTag.tag == DW_TAG_class_type) ? Dwarf_string (DW_AT_name) : NULL;
885 read_hwcprof_info (ctx);
886 ctx->name = old_name;
887 ctx->parent = old_parent;
888 // Reverse children
889 for (int64_t i = t->child, last = 0; i != 0;)
890 {
891 Dwr_type *t1 = ctx->get_dwr_type (i);
892 t->child = i;
893 i = t1->next;
894 t1->next = last;
895 last = t->child;
896 }
897 break;
898 }
899 case DW_TAG_member:
900 {
901 if (ctx->parent == 0)
902 {
903 Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d %s cu_die_offset=%lld\n"),
904 get_basename (__FILE__), (int) __LINE__,
905 DwrCU::tag2str (dwrTag.tag), (long long) dwrTag.die);
906 break;
907 }
908 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
909 t->name = Dwarf_string (DW_AT_name);
910 t->ref_type = Dwarf_ref (DW_AT_type);
911 t->offset = Dwarf_location (DW_AT_data_member_location);
912 Dwr_type *parent = ctx->get_dwr_type (ctx->parent);
913 t->parent = ctx->parent;
914 t->next = parent->child; // a reverse order of members
915 parent->child = t->cu_die_offset;
916 t->bit_size = (uint32_t) Dwarf_data (DW_AT_bit_size);
917 break;
918 }
919 case DW_TAG_module:
920 {
921 char *old_name = ctx->name;
922 ctx->name = Dwarf_string (DW_AT_SUN_link_name);
923 read_hwcprof_info (ctx);
924 ctx->name = old_name;
925 break;
926 }
927 case DW_TAG_namespace:
928 {
929 char *old_name = ctx->name;
930 ctx->name = Dwarf_string (DW_AT_name);
931 read_hwcprof_info (ctx);
932 ctx->name = old_name;
933 break;
934 }
935 case DW_TAG_lexical_block:
936 {
937 char *old_name = ctx->name;
938 ctx->name = NULL;
939 read_hwcprof_info (ctx);
940 ctx->name = old_name;
941 break;
942 }
943 default: // No more special cases
944 read_hwcprof_info (ctx);
945 break;
946 }
947 }
948 ctx->level--;
949 dwrTag.level--;
950 if (next_die_offset != 0)
951 debug_infoSec->offset = next_die_offset;
952 debug_infoSec->size = old_size;
953 }
954
955 // Append function to module
956 Function *
957 DwrCU::append_Function (Dwarf_cnt *ctx)
958 {
959 char *outerName = ctx->name, *name, tmpname[2048];
960 Function *func;
961 char *fname = Dwarf_string (DW_AT_name);
962 if (fname && outerName && !strchr (fname, '.'))
963 {
964 size_t outerlen = strlen (outerName);
965 if (outerlen > 0 && outerName[outerlen - 1] == '_')
966 {
967 outerlen--;
968 snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName);
969 snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname);
970 }
971 else
972 snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname);
973 name = tmpname;
974 Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name);
975 }
976 else
977 name = fname;
978
979 char *link_name = get_linkage_name ();
980 if (link_name == NULL)
981 link_name = name;
982
983 uint64_t pc = get_low_pc ();
984 func = dwarf->stabs->append_Function (module, link_name, pc);
985 if (func != NULL)
986 {
987 int lineno = (int) Dwarf_data (DW_AT_decl_line);
988 func->set_match_name (name);
989 if (lineno > 0)
990 {
991 func->setLineFirst (lineno);
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
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 }