]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/Dwarf.cc
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gprofng / src / Dwarf.cc
CommitLineData
fd67aa11 1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
bb368aad
VM
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
33static int
34datatypeCmp (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
41static int
42targetOffsetCmp (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
52class Dwr_type
53{
54public:
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
83private:
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
93Dwarf_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
106Dwr_type *
107Dwarf_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
120Dwr_type *
121Dwarf_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
128Dwr_type *
129Dwarf_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
138char *
139Dwr_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
148void
149Dwr_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
168char *
169Dwr_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
260datatype_t*
261Dwr_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
274DataObject *
275Dwr_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
350void
351Dwr_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
363Dwarf::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;
74f1d7f4 372 debug_line_strSec = NULL;
bb368aad
VM
373 debug_rangesSec = NULL;
374 elf = stabs->openElf (true);
375 if (elf == NULL)
376 {
377 status = Stabs::DBGD_ERR_BAD_ELF_FORMAT;
378 return;
379 }
380 debug_infoSec = dwrGetSec (NTXT (".debug_info"));
381 if (debug_infoSec)
382 {
383 debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL);
384 debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc);
385 if (debug_infoSec->reloc)
386 debug_infoSec->reloc->dump ();
387 }
388 debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev"));
389 debug_strSec = dwrGetSec (NTXT (".debug_str"));
390 debug_lineSec = dwrGetSec (NTXT (".debug_line"));
391 debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
74f1d7f4 392 debug_line_strSec = dwrGetSec (".debug_line_str");
bb368aad
VM
393
394 if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
395 {
396 status = Stabs::DBGD_ERR_NO_DWARF;
397 return;
398 }
399}
400
401Dwarf::~Dwarf ()
402{
403 delete debug_infoSec;
404 delete debug_abbrevSec;
405 delete debug_strSec;
406 delete debug_lineSec;
407 delete debug_rangesSec;
408 Destroy (dwrCUs);
409}
410
411DwrSec *
412Dwarf::dwrGetSec (const char *sec_name)
413{
414 int secN = elf->elf_get_sec_num (sec_name);
415 if (secN > 0)
416 {
417 Elf_Data *elfData = elf->elf_getdata (secN);
418 if (elfData)
419 return new DwrSec ((unsigned char *) elfData->d_buf, elfData->d_size,
420 elf->need_swap_endian,
421 elf->elf_getclass () == ELFCLASS32);
422 }
423 return NULL;
424}
425
426uint64_t
427DwrCU::get_low_pc ()
428{
429 uint64_t pc = Dwarf_addr (DW_AT_low_pc);
430 if (pc)
431 return pc;
432 return pc;
433}
434
435char *
436DwrCU::get_linkage_name ()
437{
438 char *nm = Dwarf_string (DW_AT_linkage_name);
439 if (nm != NULL)
440 return nm;
441 nm = Dwarf_string (DW_AT_SUN_link_name);
442 if (nm != NULL)
443 return nm;
444 return Dwarf_string (DW_AT_MIPS_linkage_name);
445}
446
447void
448DwrCU::parseChild (Dwarf_cnt *ctx)
449{
450 if (!dwrTag.hasChild)
451 return;
452 uint64_t old_size = debug_infoSec->size;
453 uint64_t next_die_offset = 0;
454 Dwarf_Die next_die;
455 if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
456 {
457 next_die_offset = next_die + cu_offset;
458 if (next_die_offset <= debug_infoSec->offset)
459 {
460 Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"),
461 (long long) next_die, (long long) debug_infoSec->offset);
462 next_die_offset = 0;
463 }
464 else if (debug_infoSec->size > next_die_offset)
465 debug_infoSec->size = next_die_offset;
466 }
467 dwrTag.level++;
468 ctx->level++;
469 for (;;)
470 {
471 if (set_die (0) != DW_DLV_OK)
472 break;
473 Function *func;
474 char *old_name;
475 int hasChild = dwrTag.hasChild;
476 switch (dwrTag.tag)
477 {
478 case DW_TAG_imported_declaration:
479 if (Stabs::is_fortran (ctx->module->lang_code))
480 {
481 char *link_name = Dwarf_string (DW_AT_name);
482 ctx->fortranMAIN = NULL;
483 parseChild (ctx);
484 hasChild = 0;
485 if (ctx->fortranMAIN)
486 {
487 ctx->fortranMAIN->set_match_name (link_name);
488 ctx->fortranMAIN = NULL;
489 }
490 }
491 break;
492 case DW_TAG_subprogram:
493 if (dwrTag.get_attr (DW_AT_abstract_origin))
494 break;
495 if (dwrTag.get_attr (DW_AT_declaration))
496 {
497 // Only declaration
498 if (Stabs::is_fortran (ctx->module->lang_code))
499 {
500 char *link_name = Dwarf_string (DW_AT_name);
501 if (link_name && streq (link_name, NTXT ("MAIN")))
502 ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true);
503 }
490ea364 504 break;
bb368aad
VM
505 }
506 func = append_Function (ctx);
507 if (func)
508 {
509 if (Stabs::is_fortran (ctx->module->lang_code) &&
510 streq (func->get_match_name (), NTXT ("MAIN")))
511 ctx->fortranMAIN = func;
512 old_name = ctx->name;
513 Function *old_func = ctx->func;
514 ctx->name = func->get_match_name ();
515 ctx->func = func;
516 parseChild (ctx);
517 hasChild = 0;
518 ctx->name = old_name;
519 ctx->func = old_func;
520 }
521 break;
522 case DW_TAG_module:
523 old_name = ctx->name;
524 ctx->name = Dwarf_string (DW_AT_SUN_link_name);
525 parseChild (ctx);
526 hasChild = 0;
527 ctx->name = old_name;
528 break;
529 case DW_TAG_class_type:
530 old_name = ctx->name;
531 ctx->name = Dwarf_string (DW_AT_name);
532 parseChild (ctx);
533 hasChild = 0;
534 ctx->name = old_name;
535 break;
536 case DW_TAG_structure_type:
537 old_name = ctx->name;
538 ctx->name = NULL;
539 parseChild (ctx);
540 hasChild = 0;
541 ctx->name = old_name;
542 break;
543 case DW_TAG_namespace:
544 old_name = ctx->name;
545 ctx->name = Dwarf_string (DW_AT_name);
546 parseChild (ctx);
547 hasChild = 0;
548 ctx->name = old_name;
549 break;
550 case DW_TAG_lexical_block:
551 old_name = ctx->name;
552 ctx->name = NULL;
553 parseChild (ctx);
554 hasChild = 0;
555 ctx->name = old_name;
556 break;
557 case DW_TAG_SUN_memop_info:
558 isMemop = true;
559 break;
560 case DW_TAG_inlined_subroutine:
561 if (ctx->module)
562 {
563 parse_inlined_subroutine (ctx);
564 hasChild = 0;
565 }
566 break;
567 default: // No more special cases
568 break;
569 }
570 if (hasChild)
571 parseChild (ctx);
572 }
573 ctx->level--;
574 dwrTag.level--;
575 if (next_die_offset != 0)
576 debug_infoSec->offset = next_die_offset;
577 debug_infoSec->size = old_size;
578}
579
580bool
581Dwarf::archive_Dwarf (LoadObject *lo)
582{
583 if (debug_infoSec == NULL)
584 return false;
585 if (dwrCUs)
586 return true;
587 dwrCUs = new Vector<DwrCU *>;
588
589 debug_infoSec->offset = 0;
590 while (debug_infoSec->offset < debug_infoSec->sizeSec)
591 {
592 DwrCU *dwrCU = new DwrCU (this);
593 dwrCUs->append (dwrCU);
594 debug_infoSec->size = debug_infoSec->sizeSec;
595 debug_infoSec->offset = dwrCU->next_cu_offset;
596
597 if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
598 {
599 Dprintf (1, "DwrCU::archive_Dwarf: CU=%lld (offset=0x%llx); set_die(0x%llx) failed\n",
600 (long long) dwrCUs->size (), (long long) dwrCU->cu_offset,
601 (long long) dwrCU->cu_header_offset);
602 continue;
603 }
604
605 Module *mod = dwrCU->parse_cu_header (lo);
606 if (mod)
607 {
608 mod->hdrOffset = dwrCUs->size ();
609 DwrLineRegs *lineReg = dwrCU->get_dwrLineReg ();
e02841b0 610 if (lineReg != NULL)
bb368aad 611 {
e02841b0
VM
612 dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
613 for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
614 {
74f1d7f4
VM
615 char *fname = lineReg->getPath (i);
616 if (fname)
617 dwrCU->srcFiles->append (mod->findSource (fname, true));
e02841b0 618 }
bb368aad
VM
619 }
620
621 Dwarf_cnt ctx;
622 ctx.module = mod;
623 dwrCU->parseChild (&ctx);
624 if (dwrCU->dwrInlinedSubrs && DUMP_DWARFLIB)
625 {
626 char msg[128];
627 char *lo_name = mod->loadobject ? mod->loadobject->get_name ()
628 : NULL;
629 snprintf (msg, sizeof (msg), NTXT ("\ndwrCUs[%lld]: %s:%s\n"),
630 (long long) dwrCUs->size (),
631 STR (lo_name), STR (mod->get_name ()));
632 dwrCU->dwrInlinedSubrs->dump (msg);
633 }
634 }
635 }
636 return true;
637}
638
639void
640Dwarf::srcline_Dwarf (Module *module)
641{
642 if (module == NULL || module->hdrOffset == 0)
643 return;
644 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
645 dwrCU->map_dwarf_lines (module);
646}
647
648
649// parse hwcprof info for given module in loadobject
650
651void
652Dwarf::read_hwcprof_info (Module *module)
653{
654 if (module->datatypes || (module->hdrOffset == 0))
655 return;
656 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1);
657 if (!dwrCU->isMemop)
658 return;
659 module->datatypes = new Vector<datatype_t*>;
660 if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK)
661 {
662 Dprintf (1, "Dwarf::read_hwcprof_info: CU=%lld (offset=0x%llx); set_die(0x%llx) failed\n",
663 (long long) module->hdrOffset, (long long) dwrCU->cu_offset,
664 (long long) dwrCU->cu_header_offset);
665 return;
666 }
667 Dwarf_cnt ctx;
668 ctx.module = module;
669 ctx.cu_offset = dwrCU->cu_offset; // CU header offset;
670 ctx.dwr_types = new DefaultMap<int64_t, Dwr_type*>;
671 ctx.put_dwr_type (0, 0); // for DOBJ_UNSPECIFIED
672 dwrCU->read_hwcprof_info (&ctx);
673
674 Vector<inst_info_t*> *infoList = module->infoList;
675 Dprintf (DUMP_DWARFLIB,
676 "\n\n ### Dwarf::read_hwcprof_info: module: '%s' infoList->size()=%lld\n",
677 STR (module->get_name ()),
678 (long long) (infoList ? infoList->size () : -1));
679 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
680 {
681 inst_info_t *ip = infoList->fetch (i);
682 memop_info_t *mp = ip->memop;
683 Dwr_type *t = ctx.get_dwr_type (mp->datatype_id);
684 t->get_dobj (&ctx);
685 }
686
687#ifdef DEBUG
688 Dprintf (DUMP_DWARFLIB,
689 "\n\n ### Dwarf::read_hwcprof_info: '%s' infoList->size()=%lld\n",
690 STR (module->get_name ()),
691 (long long) (infoList ? infoList->size () : 1));
692 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++)
693 {
694 inst_info_t *ip = infoList->fetch (i);
695 memop_info_t *mp = ip->memop;
696 Dprintf (DUMP_DWARFLIB,
697 " %d id=%lld offset=%lld signature=%lld datatype_id=%lld \n",
698 i, (long long) mp->id, (long long) mp->offset,
699 (long long) mp->signature, (long long) mp->datatype_id);
700 }
701
702 Vector<int64_t> *keys = ctx.dwr_types->keySet ();
703 Dprintf (DUMP_DWARFLIB,
704 "\n\n ### Dwarf::read_hwcprof_info: '%s' keys->size()=%lld\n",
705 STR (module->get_name ()), (long long) (keys ? keys->size () : -1));
706 for (int i = 0, sz = keys->size (); i < sz; i++)
707 {
708 int64_t ind = keys->fetch (i);
709 Dwr_type *t = ctx.get_dwr_type (ind);
710 Dprintf (DUMP_DWARFLIB, NTXT (" %d %lld %s\n"), i,
711 (long long) ind, t->dump ());
712 }
713#endif
714}
715
716void
717DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
718{
719 if (!dwrTag.hasChild)
720 return;
721 uint64_t old_size = debug_infoSec->size;
722 uint64_t next_die_offset = 0;
723 Dwarf_Die next_die;
724 if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
725 {
726 next_die_offset = next_die + cu_offset;
727 if (next_die_offset <= debug_infoSec->offset)
728 next_die_offset = 0;
729 else if (debug_infoSec->size > next_die_offset)
730 debug_infoSec->size = next_die_offset;
731 }
732 dwrTag.level++;
733 ctx->level++;
734 for (;;)
735 {
736 if (set_die (0) != DW_DLV_OK)
737 break;
738 Dprintf (DUMP_DWARFLIB, NTXT ("%s:%d <%lld:%lld> cu_die=%lld %-15s\n"),
739 get_basename (__FILE__), (int) __LINE__, (long long) ctx->level,
740 (long long) dwrTag.die, (long long) dwrTag.offset,
741 DwrCU::tag2str (dwrTag.tag));
742 switch (dwrTag.tag)
743 {
744 case DW_TAG_SUN_memop_info:
745 {
746 if (ctx->func == NULL)
747 break;
748 Dwarf_Unsigned mid = Dwarf_data (DW_AT_SUN_profile_id);
749 Dwarf_Unsigned off = Dwarf_data (DW_AT_SUN_func_offset);
750 Dwarf_Unsigned sig = Dwarf_data (DW_AT_SUN_memop_signature);
751 Dwarf_Off ref = Dwarf_ref (DW_AT_SUN_memop_type_ref);
752
753 // define memop entry
754 memop_info_t *memop = new memop_info_t;
755 memop->id = (unsigned) mid;
756 memop->signature = (unsigned) sig;
757 memop->datatype_id = ref ? (unsigned) ref : 0;
758 memop->offset = (unsigned) (ctx->func->img_offset + off);
759
760 // define instop entry
761 inst_info_t *instop = new inst_info_t;
762 instop->type = CPF_INSTR_TYPE_PREFETCH; // XXXX UNKNOWN
763 instop->offset = memop->offset;
764 instop->memop = memop;
765 if (ctx->module->infoList == NULL)
766 ctx->module->infoList = new Vector<inst_info_t*>;
767 ctx->module->infoList->append (instop);
768 break;
769 }
770 case DW_TAG_SUN_codeflags:
771 {
772 if (ctx->func == NULL)
773 break;
774 Dwarf_Unsigned kind = Dwarf_data (DW_AT_SUN_cf_kind);
775 if (kind == DW_ATCF_SUN_branch_target)
776 {
777 DwrSec *secp = Dwarf_block (DW_AT_SUN_func_offsets);
778 if (secp)
779 {
780 int foffset = 0;
781 for (int i = 0; secp->offset < secp->size; i++)
782 {
783 int val = (int) secp->GetSLEB128 ();
784 if (i == 0 || val != 0)
785 {
786 foffset += val;
787 target_info_t *t = new target_info_t;
788 t->offset = (unsigned) (ctx->func->img_offset + foffset);
789 ctx->module->bTargets.incorporate (t, targetOffsetCmp);
790 }
791 }
792 delete(secp);
793 }
794 }
795 break;
796 }
797 case DW_TAG_subprogram:
798 {
799 Function *old_func = ctx->func;
800 if (dwrTag.get_attr (DW_AT_abstract_origin)
801 || dwrTag.get_attr (DW_AT_declaration))
802 ctx->func = NULL;
803 else
804 ctx->func = append_Function (ctx);
805 read_hwcprof_info (ctx);
806 ctx->func = old_func;
807 break;
808 }
809 case DW_TAG_base_type:
810 {
811 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
812 t->name = Dwarf_string (DW_AT_name);
813 t->size = Dwarf_data (DW_AT_byte_size);
814 break;
815 }
816 case DW_TAG_unspecified_type:
817 ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
818 break;
819 case DW_TAG_enumeration_type:
820 {
821 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
822 t->name = Dwarf_string (DW_AT_name);
823 t->size = Dwarf_data (DW_AT_byte_size);
824 break;
825 }
826 case DW_TAG_constant:
827 case DW_TAG_formal_parameter:
828 case DW_TAG_variable:
829 case DW_TAG_typedef:
830 case DW_TAG_const_type:
831 case DW_TAG_volatile_type:
832 {
833 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
834 t->name = Dwarf_string (DW_AT_name);
835 t->ref_type = Dwarf_ref (DW_AT_type);
836 break;
837 }
838 case DW_TAG_pointer_type:
839 case DW_TAG_reference_type:
840 {
841 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
842 t->name = Dwarf_string (DW_AT_name);
843 t->ref_type = Dwarf_ref (DW_AT_type);
844 t->size = (dwarf->stabs->get_class () == W64) ? 8 : 4;
845 break;
846 }
847 case DW_TAG_array_type:
848 {
849 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
850 t->name = Dwarf_string (DW_AT_name);
851 t->ref_type = Dwarf_ref (DW_AT_type);
852 t->size = Dwarf_data (DW_AT_byte_size);
853 ctx->size = -1;
854 read_hwcprof_info (ctx);
855 t->elems = ctx->size;
856 break;
857 }
858 case DW_TAG_subrange_type:
859 {
860 int64_t ref_type = Dwarf_ref (DW_AT_type);
861 int64_t hi = Dwarf_data (DW_AT_upper_bound);
862 int64_t lo = Dwarf_data (DW_AT_lower_bound);
863 int64_t ss = Dwarf_data (DW_AT_stride_size);
864 ctx->size = 1 + hi - lo;
865 if (ss != 0)
866 ctx->size /= ss;
867 Dprintf (DUMP_DWARFLIB,
868 "Got subrange [%lld:%lld:%lld] indexed <%lld>: size=%lld\n",
869 (long long) lo, (long long) hi, (long long) ss,
870 (long long) ref_type, (long long) ctx->size);
871 break;
872 }
873 case DW_TAG_structure_type:
874 case DW_TAG_union_type:
875 case DW_TAG_class_type:
876 {
877 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
878 t->name = Dwarf_string (DW_AT_name);
879 t->size = Dwarf_data (DW_AT_byte_size);
880 t->extent = Dwarf_ref (DW_AT_sibling);
881 int64_t old_parent = ctx->parent;
882 ctx->parent = t->cu_die_offset;
883
884 char *old_name = ctx->name;
885 ctx->name = (dwrTag.tag == DW_TAG_class_type) ? Dwarf_string (DW_AT_name) : NULL;
886 read_hwcprof_info (ctx);
887 ctx->name = old_name;
888 ctx->parent = old_parent;
889 // Reverse children
890 for (int64_t i = t->child, last = 0; i != 0;)
891 {
892 Dwr_type *t1 = ctx->get_dwr_type (i);
893 t->child = i;
894 i = t1->next;
895 t1->next = last;
896 last = t->child;
897 }
898 break;
899 }
900 case DW_TAG_member:
901 {
902 if (ctx->parent == 0)
903 {
904 Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d %s cu_die_offset=%lld\n"),
905 get_basename (__FILE__), (int) __LINE__,
906 DwrCU::tag2str (dwrTag.tag), (long long) dwrTag.die);
907 break;
908 }
909 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag);
910 t->name = Dwarf_string (DW_AT_name);
911 t->ref_type = Dwarf_ref (DW_AT_type);
912 t->offset = Dwarf_location (DW_AT_data_member_location);
913 Dwr_type *parent = ctx->get_dwr_type (ctx->parent);
914 t->parent = ctx->parent;
915 t->next = parent->child; // a reverse order of members
916 parent->child = t->cu_die_offset;
917 t->bit_size = (uint32_t) Dwarf_data (DW_AT_bit_size);
918 break;
919 }
920 case DW_TAG_module:
921 {
922 char *old_name = ctx->name;
923 ctx->name = Dwarf_string (DW_AT_SUN_link_name);
924 read_hwcprof_info (ctx);
925 ctx->name = old_name;
926 break;
927 }
928 case DW_TAG_namespace:
929 {
930 char *old_name = ctx->name;
931 ctx->name = Dwarf_string (DW_AT_name);
932 read_hwcprof_info (ctx);
933 ctx->name = old_name;
934 break;
935 }
936 case DW_TAG_lexical_block:
937 {
938 char *old_name = ctx->name;
939 ctx->name = NULL;
940 read_hwcprof_info (ctx);
941 ctx->name = old_name;
942 break;
943 }
944 default: // No more special cases
945 read_hwcprof_info (ctx);
946 break;
947 }
948 }
949 ctx->level--;
950 dwrTag.level--;
951 if (next_die_offset != 0)
952 debug_infoSec->offset = next_die_offset;
953 debug_infoSec->size = old_size;
954}
955
956// Append function to module
957Function *
958DwrCU::append_Function (Dwarf_cnt *ctx)
959{
960 char *outerName = ctx->name, *name, tmpname[2048];
961 Function *func;
962 char *fname = Dwarf_string (DW_AT_name);
963 if (fname && outerName && !strchr (fname, '.'))
964 {
965 size_t outerlen = strlen (outerName);
966 if (outerlen > 0 && outerName[outerlen - 1] == '_')
967 {
968 outerlen--;
969 snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName);
970 snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname);
971 }
972 else
973 snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname);
974 name = tmpname;
975 Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name);
976 }
977 else
978 name = fname;
979
980 char *link_name = get_linkage_name ();
981 if (link_name == NULL)
982 link_name = name;
983
984 uint64_t pc = get_low_pc ();
985 func = dwarf->stabs->append_Function (module, link_name, pc);
986 if (func != NULL)
987 {
988 int lineno = (int) Dwarf_data (DW_AT_decl_line);
989 func->set_match_name (name);
990 if (lineno > 0)
991 {
992 func->setLineFirst (lineno);
74f1d7f4 993 int fileno = ((int) Dwarf_data (DW_AT_decl_file));
bb368aad
VM
994 SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno)
995 : module->getMainSrc ();
996 func->setDefSrc (sf);
997 func->pushSrcFile (func->def_source, 0);
998 func->popSrcFile ();
999 }
1000 }
1001 return func;
1002}
1003
1004// Get language code
1005Sp_lang_code
1006DwrCU::Dwarf_lang ()
1007{
1008 char *str = Dwarf_string (DW_AT_producer);
1009 if (str && strncmp (str, NTXT ("GNU"), 3) == 0)
1010 isGNU = true;
1011 int64_t lang = Dwarf_data (DW_AT_language);
1012 switch (lang)
1013 {
1014 case DW_LANG_C89:
1015 case DW_LANG_C:
1016 return Sp_lang_c; // Sp_lang_ansic?
1017 case DW_LANG_C99:
1018 return Sp_lang_c99;
1019 case DW_LANG_C_plus_plus:
1020 return isGNU ? Sp_lang_gcc : Sp_lang_cplusplus;
1021 case DW_LANG_Fortran90:
1022 return Sp_lang_fortran90;
1023 case DW_LANG_Fortran77:
1024 return Sp_lang_fortran;
1025 case DW_LANG_Java:
1026 return Sp_lang_java;
1027 case DW_LANG_Mips_Assembler:
1028 case DW_LANG_SUN_Assembler:
1029 return Sp_lang_asm;
1030 case DW_LANG_Pascal83:
1031 return Sp_lang_pascal;
1032 default:
1033 case DW_LANG_Ada83:
1034 case DW_LANG_Cobol74:
1035 case DW_LANG_Cobol85:
1036 case DW_LANG_Modula2:
1037 case DW_LANG_Ada95:
1038 case DW_LANG_Fortran95:
1039 case DW_LANG_lo_user:
1040 return Sp_lang_unknown;
1041 }
1042}