Automatic date update in version.in
[binutils-gdb.git] / gprofng / src / DwarfLib.cc
blobc8af0ab5e60ad4fa9282f0db3c34fcf375a90030
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2 Contributed by Oracle.
4 This file is part of GNU Binutils.
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.
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.
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. */
21 #include "config.h"
22 #include <ctype.h>
24 #include "util.h"
25 #include "Dwarf.h"
26 #include "DwarfLib.h"
27 #include "Elf.h"
28 #include "Function.h"
29 #include "Module.h"
30 #include "StringBuilder.h"
31 #include "DbeArray.h"
32 #include "DbeSession.h"
34 #define CASE_S(x) case x: s = (char *) #x; break
36 static char *
37 gelf_st_type2str (int type)
39 static char buf[128];
40 char *s;
41 switch (type)
43 CASE_S (STT_NOTYPE);
44 CASE_S (STT_OBJECT);
45 CASE_S (STT_FUNC);
46 CASE_S (STT_SECTION);
47 CASE_S (STT_FILE);
48 CASE_S (STT_COMMON);
49 CASE_S (STT_TLS);
50 // CASE_S(STT_NUM);
51 CASE_S (STT_LOPROC);
52 CASE_S (STT_HIPROC);
53 default: s = NTXT ("???");
54 break;
56 snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type);
57 buf[sizeof (buf) - 1] = 0;
58 return buf;
61 static char *
62 special_opcode2str (int opcode)
64 static char buf[128];
65 snprintf (buf, sizeof (buf), NTXT ("SpecialOpcode: %3d"), opcode);
66 buf[sizeof (buf) - 1] = 0;
67 return buf;
70 static char *
71 extended_opcode2str (int opcode)
73 static char buf[128];
74 char *s;
75 switch (opcode)
77 CASE_S (DW_LNE_end_sequence);
78 CASE_S (DW_LNE_set_address);
79 CASE_S (DW_LNE_define_file);
80 default:
81 snprintf (buf, sizeof (buf), NTXT ("??? (%d)"), opcode);
82 buf[sizeof (buf) - 1] = 0;
83 s = buf;
84 break;
86 return s;
89 static char *
90 standard_opcode2str (int opcode)
92 static char buf[128];
93 char *s;
94 switch (opcode)
96 CASE_S (DW_LNS_copy);
97 CASE_S (DW_LNS_advance_pc);
98 CASE_S (DW_LNS_advance_line);
99 CASE_S (DW_LNS_set_file);
100 CASE_S (DW_LNS_set_column);
101 CASE_S (DW_LNS_negate_stmt);
102 CASE_S (DW_LNS_set_basic_block);
103 CASE_S (DW_LNS_const_add_pc);
104 CASE_S (DW_LNS_fixed_advance_pc);
105 default:
106 snprintf (buf, sizeof (buf), NTXT ("??? (%d)"), opcode);
107 buf[sizeof (buf) - 1] = 0;
108 s = buf;
109 break;
111 return s;
114 template<> void Vector<DwrInlinedSubr *>
115 ::dump (const char *msg)
117 Dprintf (1, NTXT ("%s Vector<DwrInlinedSubr *> [%lld]\n"),
118 msg ? msg : NTXT (""), (long long) size ());
119 for (long i = 0, sz = size (); i < sz; i++)
121 DwrInlinedSubr *p = get (i);
122 Dprintf (1, NTXT ("%ld: "), (long) i);
123 p->dump ();
127 template<> void Vector<DwrLine *>
128 ::dump (const char *msg)
130 Dprintf (1, "%s Vector<DwrLine *> [%lld]:\n address [file line column]\n",
131 msg ? msg : NTXT (""), (long long) size ());
132 for (long i = 0, sz = size (); i < sz; i++)
134 DwrLine *lnp = get (i);
135 Dprintf (1, NTXT (" %2lld 0x%08llx [ %2lld, %lld, %lld ] \n"),
136 (long long) i, (long long) lnp->address, (long long) lnp->file,
137 (long long) lnp->line, (long long) lnp->column);
139 Dprintf (1, NTXT ("\n\n"));
142 //////////////////////////////////////////////////////////
143 // class ElfReloc
145 ElfReloc::ElfReloc (Elf *_elf)
147 elf = _elf;
148 reloc = NULL;
149 cur_reloc_ind = 0;
152 ElfReloc::~ElfReloc ()
154 if (reloc)
156 reloc->destroy ();
157 delete reloc;
161 void
162 ElfReloc::dump_rela_debug_sec (int sec)
164 if (!DUMP_RELA_SEC)
165 return;
166 Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
167 if (shdr == NULL)
168 return;
170 Elf_Data *data = elf->elf_getdata (sec);
171 if (data == NULL)
172 return;
174 uint64_t ScnSize = data->d_size;
175 uint64_t EntSize = shdr->sh_entsize;
176 if (ScnSize == 0 || EntSize == 0)
177 return;
179 Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
180 if (shdr_sym == NULL)
181 return;
182 Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
183 Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
184 char *Strtab = data_str ? (char*) data_str->d_buf : NULL;
185 Elf_Internal_Rela rela;
186 int n, cnt = (int) (ScnSize / EntSize);
188 char *sec_name = elf->get_sec_name (sec);
189 if (sec_name == NULL) // It can not be, but let's check
190 return;
191 Dprintf (DUMP_RELA_SEC,
192 "======= DwarfLib::dump_rela_debug_sec Section:%2d '%s'\n",
193 sec, sec_name);
194 Dprintf (DUMP_RELA_SEC,
195 " N |addend| offset | r_info | stt_type |\n");
196 for (n = 0; n < cnt; n++)
198 if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
199 elf->elf_getrela (data, n, &rela);
200 else
202 elf->elf_getrel (data, n, &rela);
203 rela.r_addend = 0;
205 int ndx = (int) GELF_R_SYM (rela.r_info);
206 Elf_Internal_Shdr *secHdr;
207 Elf_Internal_Sym sym;
208 elf->elf_getsym (data_sym, ndx, &sym);
209 Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
210 n, (int) rela.r_addend,
211 (long long) rela.r_offset, (long long) rela.r_info,
212 gelf_st_type2str ((int) GELF_ST_TYPE (sym.st_info)));
213 switch (GELF_ST_TYPE (sym.st_info))
215 case STT_FUNC:
216 case STT_OBJECT:
217 case STT_NOTYPE:
218 secHdr = elf->get_shdr (sym.st_shndx);
219 if (secHdr)
220 Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
221 (long long) (sym.st_value + secHdr->sh_offset));
222 if (Strtab && sym.st_name)
223 Dprintf (DUMP_RELA_SEC, NTXT (" %s"), Strtab + sym.st_name);
224 break;
225 case STT_SECTION:
226 secHdr = elf->get_shdr (sym.st_shndx);
227 if (secHdr)
229 Dprintf (DUMP_RELA_SEC, NTXT (" value=0x%016llx (%lld)"),
230 (long long) (secHdr->sh_offset + rela.r_addend),
231 (long long) (secHdr->sh_offset + rela.r_addend));
233 break;
234 default:
235 break;
237 Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
239 Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
242 void
243 ElfReloc::dump ()
245 if (!DUMP_ELF_RELOC || (reloc == NULL) || (reloc->size () == 0))
246 return;
247 Dprintf (DUMP_ELF_RELOC, NTXT ("======= ElfReloc::dump\n"));
248 Dprintf (DUMP_ELF_RELOC, NTXT (" N | offset | value | STT_TYPE\n"));
249 for (int i = 0; i < reloc->size (); i++)
251 Sreloc *srlc = reloc->fetch (i);
252 Dprintf (DUMP_ELF_RELOC, NTXT ("%3d:%11lld |%11lld | %s\n"),
253 i, (long long) srlc->offset, (long long) srlc->value,
254 gelf_st_type2str (srlc->stt_type));
256 Dprintf (DUMP_ELF_RELOC, NTXT ("\n"));
259 static int
260 DwrRelocOffsetCmp (const void *a, const void *b)
262 ElfReloc::Sreloc *item1 = *((ElfReloc::Sreloc **) a);
263 ElfReloc::Sreloc *item2 = *((ElfReloc::Sreloc **) b);
264 return item1->offset < item2->offset ? -1 :
265 item1->offset == item2->offset ? 0 : 1;
268 ElfReloc *
269 ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
271 int et = elfp->elf_getehdr ()->e_type;
272 if (et == ET_EXEC || et == ET_DYN)
273 return rlc;
274 int sec = elfp->elf_get_sec_num (sec_name);
275 if (sec == 0)
276 return rlc;
277 Elf_Internal_Shdr *shdr = elfp->get_shdr (sec);
278 if (shdr == NULL || shdr->sh_entsize == 0)
279 return rlc;
281 Elf_Data *data = elfp->elf_getdata (sec);
282 if (data == NULL || data->d_size == 0)
283 return rlc;
285 int cnt = (int) (data->d_size / shdr->sh_entsize);
286 Elf_Internal_Shdr *shdr_sym = elfp->get_shdr (shdr->sh_link);
287 if (shdr_sym == NULL)
288 return rlc;
289 Elf_Data *data_sym = elfp->elf_getdata (shdr->sh_link);
290 Vector<Sreloc *> *vp = NULL;
292 for (int n = 0; n < cnt; n++)
294 Elf_Internal_Shdr *secHdr;
295 Sreloc *srlc;
296 Elf_Internal_Rela rela;
297 if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
298 elfp->elf_getrela (data, n, &rela);
299 else
301 elfp->elf_getrel (data, n, &rela);
302 rela.r_addend = 0;
304 int ndx = (int) GELF_R_SYM (rela.r_info);
305 Elf_Internal_Sym sym;
306 elfp->elf_getsym (data_sym, ndx, &sym);
308 srlc = new Sreloc;
309 srlc->offset = rela.r_offset;
310 srlc->value = 0;
311 srlc->stt_type = (int) GELF_ST_TYPE (sym.st_info);
312 switch (GELF_ST_TYPE (sym.st_info))
314 case STT_FUNC:
315 secHdr = elfp->get_shdr (sym.st_shndx);
316 if (secHdr)
317 srlc->value = secHdr->sh_offset + sym.st_value;
318 break;
319 case STT_OBJECT:
320 case STT_NOTYPE:
321 secHdr = elfp->get_shdr (shdr->sh_info);
322 if (secHdr)
324 srlc->offset = rela.r_info;
325 srlc->value = secHdr->sh_offset + rela.r_addend;
327 break;
328 case STT_SECTION:
329 secHdr = elfp->get_shdr (sym.st_shndx);
330 if (secHdr)
331 srlc->value = rela.r_addend;
332 break;
333 default:
334 srlc->value = 0;
335 break;
337 if (rlc == NULL)
339 rlc = new ElfReloc (elfp);
340 vp = rlc->reloc;
342 if (vp == NULL)
344 vp = new Vector<Sreloc*>;
345 rlc->reloc = vp;
347 vp->append (srlc);
349 if (vp)
350 vp->sort (DwrRelocOffsetCmp);
351 if (rlc)
353 rlc->dump_rela_debug_sec (sec);
354 rlc->dump ();
356 return rlc;
359 long long
360 ElfReloc::get_reloc_addr (long long offset)
362 Sreloc *srlc;
363 int i = cur_reloc_ind - 1;
364 if (i >= 0 && i < reloc->size ())
366 srlc = reloc->fetch (i);
367 if (srlc->offset > offset) // need to reset
368 cur_reloc_ind = 0;
370 for (; cur_reloc_ind < reloc->size (); cur_reloc_ind++)
372 srlc = reloc->fetch (cur_reloc_ind);
373 if (srlc->offset == offset)
374 return srlc->value;
375 if (srlc->offset > offset)
376 return 0;
378 return 0;
381 DwrLocation *
382 DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp)
384 lp->offset = secp->offset;
385 lp->lc_number = 0;
386 lp->lc_number2 = 0;
387 lp->op = secp->Get_8 ();
388 switch (lp->op)
390 // registers
391 case DW_OP_reg0:
392 case DW_OP_reg1:
393 case DW_OP_reg2:
394 case DW_OP_reg3:
395 case DW_OP_reg4:
396 case DW_OP_reg5:
397 case DW_OP_reg6:
398 case DW_OP_reg7:
399 case DW_OP_reg8:
400 case DW_OP_reg9:
401 case DW_OP_reg10:
402 case DW_OP_reg11:
403 case DW_OP_reg12:
404 case DW_OP_reg13:
405 case DW_OP_reg14:
406 case DW_OP_reg15:
407 case DW_OP_reg16:
408 case DW_OP_reg17:
409 case DW_OP_reg18:
410 case DW_OP_reg19:
411 case DW_OP_reg20:
412 case DW_OP_reg21:
413 case DW_OP_reg22:
414 case DW_OP_reg23:
415 case DW_OP_reg24:
416 case DW_OP_reg25:
417 case DW_OP_reg26:
418 case DW_OP_reg27:
419 case DW_OP_reg28:
420 case DW_OP_reg29:
421 case DW_OP_reg30:
422 case DW_OP_reg31:
423 break;
424 case DW_OP_regx:
425 lp->lc_number = secp->GetULEB128 ();
426 break;
427 case DW_OP_breg0:
428 case DW_OP_breg1:
429 case DW_OP_breg2:
430 case DW_OP_breg3:
431 case DW_OP_breg4:
432 case DW_OP_breg5:
433 case DW_OP_breg6:
434 case DW_OP_breg7:
435 case DW_OP_breg8:
436 case DW_OP_breg9:
437 case DW_OP_breg10:
438 case DW_OP_breg11:
439 case DW_OP_breg12:
440 case DW_OP_breg13:
441 case DW_OP_breg14:
442 case DW_OP_breg15:
443 case DW_OP_breg16:
444 case DW_OP_breg17:
445 case DW_OP_breg18:
446 case DW_OP_breg19:
447 case DW_OP_breg20:
448 case DW_OP_breg21:
449 case DW_OP_breg22:
450 case DW_OP_breg23:
451 case DW_OP_breg24:
452 case DW_OP_breg25:
453 case DW_OP_breg26:
454 case DW_OP_breg27:
455 case DW_OP_breg28:
456 case DW_OP_breg29:
457 case DW_OP_breg30:
458 case DW_OP_breg31:
459 lp->lc_number = secp->GetSLEB128 ();
460 break;
461 case DW_OP_fbreg:
462 lp->lc_number = secp->GetSLEB128 ();
463 break;
464 case DW_OP_bregx:
465 lp->lc_number = secp->GetULEB128 ();
466 lp->lc_number2 = secp->GetSLEB128 ();
467 break;
468 case DW_OP_lit0:
469 case DW_OP_lit1:
470 case DW_OP_lit2:
471 case DW_OP_lit3:
472 case DW_OP_lit4:
473 case DW_OP_lit5:
474 case DW_OP_lit6:
475 case DW_OP_lit7:
476 case DW_OP_lit8:
477 case DW_OP_lit9:
478 case DW_OP_lit10:
479 case DW_OP_lit11:
480 case DW_OP_lit12:
481 case DW_OP_lit13:
482 case DW_OP_lit14:
483 case DW_OP_lit15:
484 case DW_OP_lit16:
485 case DW_OP_lit17:
486 case DW_OP_lit18:
487 case DW_OP_lit19:
488 case DW_OP_lit20:
489 case DW_OP_lit21:
490 case DW_OP_lit22:
491 case DW_OP_lit23:
492 case DW_OP_lit24:
493 case DW_OP_lit25:
494 case DW_OP_lit26:
495 case DW_OP_lit27:
496 case DW_OP_lit28:
497 case DW_OP_lit29:
498 case DW_OP_lit30:
499 case DW_OP_lit31:
500 lp->lc_number = lp->op - DW_OP_lit0;
501 break;
502 case DW_OP_addr:
503 lp->lc_number = secp->GetADDR ();
504 break;
505 case DW_OP_const1u:
506 lp->lc_number = secp->Get_8 ();
507 break;
508 case DW_OP_const1s:
510 signed char x;
511 x = secp->Get_8 ();
512 lp->lc_number = x;
514 break;
515 case DW_OP_const2u:
516 lp->lc_number = secp->Get_16 ();
517 break;
518 case DW_OP_const2s:
520 signed short x;
521 x = secp->Get_16 ();
522 lp->lc_number = x;
524 break;
525 case DW_OP_const4u:
526 lp->lc_number = secp->Get_32 ();
527 break;
528 case DW_OP_const4s:
530 signed int x;
531 x = secp->Get_32 ();
532 lp->lc_number = x;
534 break;
535 case DW_OP_const8u:
536 lp->lc_number = secp->Get_64 ();
537 break;
538 case DW_OP_const8s:
540 signed long long x;
541 x = secp->Get_64 ();
542 lp->lc_number = x;
544 break;
545 case DW_OP_plus_uconst:
546 case DW_OP_constu:
547 lp->lc_number = secp->GetULEB128 ();
548 break;
549 case DW_OP_consts:
550 lp->lc_number = secp->GetSLEB128 ();
551 break;
553 // Stack operations
554 case DW_OP_pick:
555 case DW_OP_deref_size:
556 case DW_OP_xderef_size:
557 lp->lc_number = secp->Get_8 ();
558 break;
559 case DW_OP_dup:
560 case DW_OP_drop:
561 case DW_OP_over:
562 case DW_OP_swap:
563 case DW_OP_rot:
564 case DW_OP_deref:
565 case DW_OP_xderef:
566 // Arithmetic and Logical Operations
567 case DW_OP_abs:
568 case DW_OP_and:
569 case DW_OP_div:
570 case DW_OP_minus:
571 case DW_OP_mod:
572 case DW_OP_mul:
573 case DW_OP_neg:
574 case DW_OP_not:
575 case DW_OP_or:
576 case DW_OP_plus:
577 case DW_OP_shl:
578 case DW_OP_shr:
579 case DW_OP_shra:
580 case DW_OP_xor:
581 case DW_OP_le:
582 case DW_OP_ge:
583 case DW_OP_eq:
584 case DW_OP_lt:
585 case DW_OP_gt:
586 case DW_OP_ne:
587 case DW_OP_nop:
588 break;
589 case DW_OP_skip:
590 case DW_OP_bra:
591 lp->lc_number = secp->Get_16 ();
592 break;
593 case DW_OP_piece:
594 lp->lc_number = secp->GetULEB128 ();
595 break;
596 case DW_OP_push_object_address: /* DWARF3 */
597 break;
598 case DW_OP_call2: /* DWARF3 */
599 lp->lc_number = secp->Get_16 ();
600 break;
601 case DW_OP_call4: /* DWARF3 */
602 lp->lc_number = secp->Get_32 ();
603 break;
604 case DW_OP_call_ref: /* DWARF3 */
605 lp->lc_number = secp->GetADDR ();
606 break;
607 default:
608 return (NULL);
610 return lp;
613 char *
614 DwrCU::tag2str (int tag)
616 static char buf[128];
617 char *s;
619 switch (tag)
621 CASE_S (DW_TAG_array_type);
622 CASE_S (DW_TAG_class_type);
623 CASE_S (DW_TAG_entry_point);
624 CASE_S (DW_TAG_enumeration_type);
625 CASE_S (DW_TAG_formal_parameter);
626 CASE_S (DW_TAG_imported_declaration);
627 CASE_S (DW_TAG_label);
628 CASE_S (DW_TAG_lexical_block);
629 CASE_S (DW_TAG_member);
630 CASE_S (DW_TAG_pointer_type);
631 CASE_S (DW_TAG_reference_type);
632 CASE_S (DW_TAG_compile_unit);
633 CASE_S (DW_TAG_string_type);
634 CASE_S (DW_TAG_structure_type);
635 CASE_S (DW_TAG_subroutine_type);
636 CASE_S (DW_TAG_typedef);
637 CASE_S (DW_TAG_union_type);
638 CASE_S (DW_TAG_unspecified_parameters);
639 CASE_S (DW_TAG_variant);
640 CASE_S (DW_TAG_common_block);
641 CASE_S (DW_TAG_common_inclusion);
642 CASE_S (DW_TAG_inheritance);
643 CASE_S (DW_TAG_inlined_subroutine);
644 CASE_S (DW_TAG_module);
645 CASE_S (DW_TAG_ptr_to_member_type);
646 CASE_S (DW_TAG_set_type);
647 CASE_S (DW_TAG_subrange_type);
648 CASE_S (DW_TAG_with_stmt);
649 CASE_S (DW_TAG_access_declaration);
650 CASE_S (DW_TAG_base_type);
651 CASE_S (DW_TAG_catch_block);
652 CASE_S (DW_TAG_const_type);
653 CASE_S (DW_TAG_constant);
654 CASE_S (DW_TAG_enumerator);
655 CASE_S (DW_TAG_file_type);
656 CASE_S (DW_TAG_friend);
657 CASE_S (DW_TAG_namelist);
658 CASE_S (DW_TAG_namelist_item);
659 CASE_S (DW_TAG_packed_type);
660 CASE_S (DW_TAG_subprogram);
661 CASE_S (DW_TAG_template_type_param);
662 CASE_S (DW_TAG_template_value_param);
663 CASE_S (DW_TAG_thrown_type);
664 CASE_S (DW_TAG_try_block);
665 CASE_S (DW_TAG_variant_part);
666 CASE_S (DW_TAG_variable);
667 CASE_S (DW_TAG_volatile_type);
668 CASE_S (DW_TAG_dwarf_procedure);
669 CASE_S (DW_TAG_restrict_type);
670 CASE_S (DW_TAG_interface_type);
671 CASE_S (DW_TAG_namespace);
672 CASE_S (DW_TAG_imported_module);
673 CASE_S (DW_TAG_unspecified_type);
674 CASE_S (DW_TAG_partial_unit);
675 CASE_S (DW_TAG_imported_unit);
676 CASE_S (DW_TAG_lo_user);
677 CASE_S (DW_TAG_MIPS_loop);
678 CASE_S (DW_TAG_format_label);
679 CASE_S (DW_TAG_function_template);
680 CASE_S (DW_TAG_class_template);
681 CASE_S (DW_TAG_GNU_BINCL);
682 CASE_S (DW_TAG_GNU_EINCL);
683 CASE_S (DW_TAG_GNU_call_site);
684 CASE_S (DW_TAG_GNU_call_site_parameter);
685 CASE_S (DW_TAG_SUN_codeflags);
686 CASE_S (DW_TAG_SUN_memop_info);
687 CASE_S (DW_TAG_hi_user);
688 CASE_S (DW_TAG_icc_compile_unit);
689 default: s = NTXT ("???");
690 break;
692 snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
693 buf[sizeof (buf) - 1] = 0;
694 return buf;
697 char *
698 DwrCU::at2str (int tag)
700 static char buf[128];
701 char *s;
702 switch (tag)
704 CASE_S (DW_AT_sibling);
705 CASE_S (DW_AT_location);
706 CASE_S (DW_AT_name);
707 CASE_S (DW_AT_ordering);
708 CASE_S (DW_AT_subscr_data);
709 CASE_S (DW_AT_byte_size);
710 CASE_S (DW_AT_bit_offset);
711 CASE_S (DW_AT_bit_size);
712 CASE_S (DW_AT_element_list);
713 CASE_S (DW_AT_stmt_list);
714 CASE_S (DW_AT_low_pc);
715 CASE_S (DW_AT_high_pc);
716 CASE_S (DW_AT_language);
717 CASE_S (DW_AT_member);
718 CASE_S (DW_AT_discr);
719 CASE_S (DW_AT_discr_value);
720 CASE_S (DW_AT_visibility);
721 CASE_S (DW_AT_import);
722 CASE_S (DW_AT_string_length);
723 CASE_S (DW_AT_common_reference);
724 CASE_S (DW_AT_comp_dir);
725 CASE_S (DW_AT_const_value);
726 CASE_S (DW_AT_containing_type);
727 CASE_S (DW_AT_default_value);
728 CASE_S (DW_AT_inline);
729 CASE_S (DW_AT_is_optional);
730 CASE_S (DW_AT_lower_bound);
731 CASE_S (DW_AT_producer);
732 CASE_S (DW_AT_prototyped);
733 CASE_S (DW_AT_return_addr);
734 CASE_S (DW_AT_start_scope);
735 CASE_S (DW_AT_stride_size);
736 CASE_S (DW_AT_upper_bound);
737 CASE_S (DW_AT_abstract_origin);
738 CASE_S (DW_AT_accessibility);
739 CASE_S (DW_AT_address_class);
740 CASE_S (DW_AT_artificial);
741 CASE_S (DW_AT_base_types);
742 CASE_S (DW_AT_calling_convention);
743 CASE_S (DW_AT_count);
744 CASE_S (DW_AT_data_member_location);
745 CASE_S (DW_AT_decl_column);
746 CASE_S (DW_AT_decl_file);
747 CASE_S (DW_AT_decl_line);
748 CASE_S (DW_AT_declaration);
749 CASE_S (DW_AT_discr_list);
750 CASE_S (DW_AT_encoding);
751 CASE_S (DW_AT_external);
752 CASE_S (DW_AT_frame_base);
753 CASE_S (DW_AT_friend);
754 CASE_S (DW_AT_identifier_case);
755 CASE_S (DW_AT_macro_info);
756 CASE_S (DW_AT_namelist_item);
757 CASE_S (DW_AT_priority);
758 CASE_S (DW_AT_segment);
759 CASE_S (DW_AT_specification);
760 CASE_S (DW_AT_static_link);
761 CASE_S (DW_AT_type);
762 CASE_S (DW_AT_use_location);
763 CASE_S (DW_AT_variable_parameter);
764 CASE_S (DW_AT_virtuality);
765 CASE_S (DW_AT_vtable_elem_location);
766 CASE_S (DW_AT_allocated);
767 CASE_S (DW_AT_associated);
768 CASE_S (DW_AT_data_location);
769 CASE_S (DW_AT_byte_stride);
770 CASE_S (DW_AT_entry_pc);
771 CASE_S (DW_AT_use_UTF8);
772 CASE_S (DW_AT_extension);
773 CASE_S (DW_AT_ranges);
774 CASE_S (DW_AT_trampoline);
775 CASE_S (DW_AT_call_column);
776 CASE_S (DW_AT_call_file);
777 CASE_S (DW_AT_call_line);
778 CASE_S (DW_AT_description);
779 CASE_S (DW_AT_binary_scale);
780 CASE_S (DW_AT_decimal_scale);
781 CASE_S (DW_AT_small);
782 CASE_S (DW_AT_decimal_sign);
783 CASE_S (DW_AT_digit_count);
784 CASE_S (DW_AT_picture_string);
785 CASE_S (DW_AT_mutable);
786 CASE_S (DW_AT_threads_scaled);
787 CASE_S (DW_AT_explicit);
788 CASE_S (DW_AT_object_pointer);
789 CASE_S (DW_AT_endianity);
790 CASE_S (DW_AT_elemental);
791 CASE_S (DW_AT_pure);
792 CASE_S (DW_AT_recursive);
793 CASE_S (DW_AT_signature);
794 CASE_S (DW_AT_main_subprogram);
795 CASE_S (DW_AT_data_bit_offset);
796 CASE_S (DW_AT_const_expr);
797 CASE_S (DW_AT_enum_class);
798 CASE_S (DW_AT_linkage_name);
799 CASE_S (DW_AT_lo_user);
800 CASE_S (DW_AT_MIPS_fde);
801 CASE_S (DW_AT_MIPS_loop_begin);
802 CASE_S (DW_AT_MIPS_tail_loop_begin);
803 CASE_S (DW_AT_MIPS_epilog_begin);
804 CASE_S (DW_AT_MIPS_loop_unroll_factor);
805 CASE_S (DW_AT_MIPS_software_pipeline_depth);
806 CASE_S (DW_AT_MIPS_linkage_name);
807 CASE_S (DW_AT_MIPS_stride);
808 CASE_S (DW_AT_MIPS_abstract_name);
809 CASE_S (DW_AT_MIPS_clone_origin);
810 CASE_S (DW_AT_MIPS_has_inlines);
811 CASE_S (DW_AT_sf_names);
812 CASE_S (DW_AT_src_info);
813 CASE_S (DW_AT_mac_info);
814 CASE_S (DW_AT_src_coords);
815 CASE_S (DW_AT_body_begin);
816 CASE_S (DW_AT_body_end);
817 CASE_S (DW_AT_GNU_vector);
818 CASE_S (DW_AT_GNU_guarded_by);
819 CASE_S (DW_AT_GNU_pt_guarded_by);
820 CASE_S (DW_AT_GNU_guarded);
821 CASE_S (DW_AT_GNU_pt_guarded);
822 CASE_S (DW_AT_GNU_locks_excluded);
823 CASE_S (DW_AT_GNU_exclusive_locks_required);
824 CASE_S (DW_AT_GNU_shared_locks_required);
825 CASE_S (DW_AT_GNU_odr_signature);
826 CASE_S (DW_AT_GNU_template_name);
827 CASE_S (DW_AT_GNU_call_site_value);
828 CASE_S (DW_AT_GNU_call_site_data_value);
829 CASE_S (DW_AT_GNU_call_site_target);
830 CASE_S (DW_AT_GNU_call_site_target_clobbered);
831 CASE_S (DW_AT_GNU_tail_call);
832 CASE_S (DW_AT_GNU_all_tail_call_sites);
833 CASE_S (DW_AT_GNU_all_call_sites);
834 CASE_S (DW_AT_GNU_all_source_call_sites);
835 CASE_S (DW_AT_SUN_command_line);
836 CASE_S (DW_AT_SUN_func_offsets);
837 CASE_S (DW_AT_SUN_cf_kind);
838 CASE_S (DW_AT_SUN_func_offset);
839 CASE_S (DW_AT_SUN_memop_type_ref);
840 CASE_S (DW_AT_SUN_profile_id);
841 CASE_S (DW_AT_SUN_memop_signature);
842 CASE_S (DW_AT_SUN_obj_dir);
843 CASE_S (DW_AT_SUN_obj_file);
844 CASE_S (DW_AT_SUN_original_name);
845 CASE_S (DW_AT_SUN_link_name);
846 CASE_S (DW_AT_hi_user);
847 CASE_S (DW_AT_icc_flags);
848 default: s = NTXT ("???");
849 break;
851 snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
852 buf[sizeof (buf) - 1] = 0;
853 return buf;
856 char *
857 DwrCU::form2str (int tag)
859 static char buf[128];
860 char *s;
861 switch (tag)
863 CASE_S (DW_FORM_addr);
864 CASE_S (DW_FORM_block2);
865 CASE_S (DW_FORM_block4);
866 CASE_S (DW_FORM_data2);
867 CASE_S (DW_FORM_data4);
868 CASE_S (DW_FORM_data8);
869 CASE_S (DW_FORM_string);
870 CASE_S (DW_FORM_block);
871 CASE_S (DW_FORM_block1);
872 CASE_S (DW_FORM_data1);
873 CASE_S (DW_FORM_flag);
874 CASE_S (DW_FORM_sdata);
875 CASE_S (DW_FORM_strp);
876 CASE_S (DW_FORM_udata);
877 CASE_S (DW_FORM_ref_addr);
878 CASE_S (DW_FORM_ref1);
879 CASE_S (DW_FORM_ref2);
880 CASE_S (DW_FORM_ref4);
881 CASE_S (DW_FORM_ref8);
882 CASE_S (DW_FORM_ref_udata);
883 CASE_S (DW_FORM_indirect);
884 CASE_S (DW_FORM_sec_offset);
885 CASE_S (DW_FORM_exprloc);
886 CASE_S (DW_FORM_flag_present);
887 CASE_S (DW_FORM_ref_sig8);
888 default: s = NTXT ("???");
889 break;
891 snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
892 buf[sizeof (buf) - 1] = 0;
893 return buf;
896 void
897 Dwr_Tag::dump ()
899 Dprintf (DUMP_DWARFLIB,
900 "\n<%2d>:<0x%08llx> %-30s <abbrev %lld> offset=0x%llx %s\n",
901 (int) level, (long long) die, DwrCU::tag2str (tag), (long long) num,
902 (long long) offset,
903 hasChild ? NTXT ("DW_children_yes") : NTXT ("DW_children_no"));
904 for (int i1 = firstAttribute; i1 < lastAttribute; i1++)
906 Dwr_Attr *atrp = abbrevAtForm->get (i1);
907 Dprintf (DUMP_DWARFLIB, " %-30s ", DwrCU::at2str (atrp->at_name));
908 switch (atrp->at_form)
910 case DW_FORM_strp:
911 case DW_FORM_string:
912 Dprintf (DUMP_DWARFLIB, " \"%s\" len=%ld",
913 atrp->u.str ? atrp->u.str : NTXT ("<NULL>"),
914 (long) atrp->len);
915 break;
916 case DW_FORM_block:
917 case DW_FORM_block1:
918 case DW_FORM_block2:
919 case DW_FORM_block4:
920 Dprintf (DUMP_DWARFLIB, " len=%3ld %p", (long) atrp->len,
921 atrp->u.str);
922 break;
923 case DW_FORM_addr:
924 case DW_FORM_data2:
925 case DW_FORM_data4:
926 case DW_FORM_data8:
927 case DW_FORM_data1:
928 case DW_FORM_flag:
929 case DW_FORM_sdata:
930 case DW_FORM_udata:
931 case DW_FORM_ref_addr:
932 case DW_FORM_ref1:
933 case DW_FORM_ref2:
934 case DW_FORM_ref4:
935 case DW_FORM_ref8:
936 case DW_FORM_ref_udata:
937 case DW_FORM_indirect:
938 case DW_FORM_sec_offset:
939 case DW_FORM_exprloc:
940 case DW_FORM_ref_sig8:
941 case DW_FORM_flag_present:
942 Dprintf (DUMP_DWARFLIB, " 0x%llx (%lld)", (long long) atrp->u.val,
943 (long long) atrp->u.val);
944 break;
945 default:
946 DEBUG_CODE
948 Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
949 (long long) atrp->at_form, (long long) atrp->at_form);
950 assert (false);
953 Dprintf (DUMP_DWARFLIB, NTXT ("\n"));
958 //////////////////////////////////////////////////////////
959 // class DwrSec
961 DwrSec::DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32)
963 isCopy = false;
964 data = _data;
965 sizeSec = _size;
966 size = (data ? _size : 0);
967 offset = 0;
968 fmt64 = false;
969 reloc = NULL;
970 need_swap_endian = _need_swap_endian;
971 addr32 = _addr32;
974 DwrSec::DwrSec (DwrSec *secp, uint64_t _offset)
976 isCopy = true;
977 data = secp->data;
978 sizeSec = secp->sizeSec;
979 size = secp->size;
980 offset = _offset;
981 fmt64 = secp->fmt64;
982 reloc = secp->reloc;
983 need_swap_endian = secp->need_swap_endian;
984 addr32 = secp->addr32;
987 DwrSec::~DwrSec ()
989 if (!isCopy)
990 delete reloc;
993 bool
994 DwrSec::bounds_violation (uint64_t sz)
996 if (offset + sz > size)
998 Dprintf (DEBUG_ERR_MSG, "DwrSec::bounds_violation: offset=%lld + sz=%lld > size=%lld\n",
999 (long long) offset, (long long) sz, (long long) size);
1000 return true;
1002 return false;
1005 uint64_t
1006 DwrSec::ReadLength ()
1008 fmt64 = false;
1009 uint64_t val = Get_32 ();
1010 if (((uint32_t) val) == 0xffffffff)
1012 fmt64 = true;
1013 val = Get_64 ();
1015 size = (val + offset < sizeSec) ? val + offset : sizeSec;
1016 return size;
1019 unsigned char
1020 DwrSec::Get_8 ()
1022 unsigned char n = 0;
1023 if (bounds_violation (sizeof (char)))
1024 return n;
1025 n = data[offset];
1026 offset += sizeof (char);
1027 return n;
1030 unsigned short
1031 DwrSec::Get_16 ()
1033 unsigned short n = 0;
1034 if (bounds_violation (sizeof (short)))
1035 return n;
1036 memcpy ((char *) &n, data + offset, sizeof (short));
1037 offset += sizeof (short);
1038 if (need_swap_endian)
1039 SWAP_ENDIAN (n);
1040 return n;
1043 uint32_t
1044 DwrSec::Get_32 ()
1046 uint32_t n = 0;
1047 if (bounds_violation (sizeof (uint32_t)))
1048 return n;
1049 memcpy ((char *) &n, data + offset, sizeof (uint32_t));
1050 offset += sizeof (uint32_t);
1051 if (need_swap_endian)
1052 SWAP_ENDIAN (n);
1053 return n;
1056 uint64_t
1057 DwrSec::Get_64 ()
1059 uint64_t n = 0;
1060 if (bounds_violation (sizeof (uint64_t)))
1061 return n;
1062 memcpy ((char *) &n, data + offset, sizeof (uint64_t));
1063 offset += sizeof (uint64_t);
1064 if (need_swap_endian)
1065 SWAP_ENDIAN (n);
1066 return n;
1069 char *
1070 DwrSec::GetData (uint64_t len)
1072 char *s = ((char *) data) + offset;
1073 if (bounds_violation (len))
1074 s = NULL;
1075 offset += len;
1076 return s;
1079 char *
1080 DwrSec::GetString (uint64_t *lenp)
1082 if (offset < size)
1084 uint64_t len = 0;
1085 for (char *s = ((char *) data) + offset; offset + len < size; len++)
1087 if (s[len] == 0)
1088 { // '\0' is inside section
1089 offset += len + 1;
1090 if (len == 0)
1091 return NULL;
1092 if (lenp)
1093 *lenp = len + 1;
1094 return s;
1097 offset += len;
1098 return NULL; // The section is not '\0' terminated
1100 return NULL;
1103 uint64_t
1104 DwrSec::GetLong ()
1106 if (fmt64)
1107 return Get_64 ();
1108 return Get_32 ();
1111 uint64_t
1112 DwrSec::GetADDR_32 ()
1114 uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1115 res += Get_32 ();
1116 return res;
1119 uint64_t
1120 DwrSec::GetADDR_64 ()
1122 uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1123 res += Get_64 ();
1124 return res;
1127 uint64_t
1128 DwrSec::GetADDR ()
1130 if (addr32)
1131 return GetADDR_32 ();
1132 return GetADDR_64 ();
1135 uint64_t
1136 DwrSec::GetRef ()
1138 if (fmt64)
1139 return GetADDR_64 ();
1140 return GetADDR_32 ();
1143 ULEB128
1144 DwrSec::GetULEB128 ()
1146 ULEB128 res = 0;
1147 for (int shift = 0;; shift += 7)
1149 ULEB128 val = Get_8 ();
1150 res |= (val & 0x7f) << shift;
1151 if ((val & 0x80) == 0)
1152 break;
1154 return res;
1157 SLEB128
1158 DwrSec::GetSLEB128 ()
1160 ULEB128 res = 0, val = 0;
1161 size_t shift;
1162 for (shift = 0;;)
1164 val = Get_8 ();
1165 res |= (val & 0x7f) << shift;
1166 shift += 7;
1167 if ((val & 0x80) == 0)
1168 break;
1170 if ((val & 0x40) && (shift < 8 * sizeof (res)))
1171 res |= -(((ULEB128) 1) << shift);
1172 return (SLEB128) res;
1175 static void
1176 fillBuf (unsigned char *s, int len, int col, unsigned char *buf)
1178 const char *nameX = "0123456789abcdef";
1179 int i, n, posCh = 2 * col + col / 4 + 5;
1181 if (len >= col)
1182 len = col;
1183 for (i = n = 0; i < len; i++, n += 2)
1185 if ((i % 4) == 0 && i > 0)
1187 buf[n] = ' ';
1188 n++;
1190 buf[n] = nameX[s[i] >> 4];
1191 buf[n + 1] = nameX[s[i] & 0xf];
1192 buf[posCh + i] = isprint (s[i]) ? s[i] : ' ';
1194 buf[posCh + i] = 0;
1195 for (i = n; i < posCh; i++)
1196 buf[i] = ' ';
1199 static void
1200 dumpArr (unsigned char *s, int len, int col, int num)
1202 unsigned char buf[128];
1203 if (col <= 0)
1204 return;
1205 for (int i = 0; i < len; i += col, num += col)
1207 fillBuf (s + i, len - i, col, buf);
1208 Dprintf (DUMP_DWARFLIB, "%5d: %s\n", num, buf);
1212 void
1213 DwrSec::dump (char *msg)
1215 if (sizeSec > 0)
1217 Dprintf (DUMP_DWARFLIB, NTXT ("======= DwrSec::dump\n"));
1218 if (msg)
1219 Dprintf (DUMP_DWARFLIB, NTXT ("%s:\n"), msg);
1220 dumpArr (data, (int) sizeSec, 32, 0);
1221 Dprintf (DUMP_DWARFLIB, NTXT ("\n"));
1225 //////////////////////////////////////////////////////////
1226 // class DwrFileNames
1228 DwrFileName::DwrFileName (char *_fname)
1230 path = NULL;
1231 fname = _fname;
1232 dir_index = 0;
1233 timestamp = 0;
1234 file_size = 0;
1235 isUsed = false;
1238 DwrFileName::~DwrFileName ()
1240 if (path != fname)
1241 free (path);
1245 //////////////////////////////////////////////////////////
1246 // class DwrLine
1247 DwrLine::DwrLine ()
1249 address = 0;
1250 file = 0;
1251 line = 0;
1252 column = 0;
1255 DwrLine::~DwrLine () { }
1258 //////////////////////////////////////////////////////////
1259 // class DwrLineRegs
1260 static int
1261 LineRegsCmp (const void *a, const void *b)
1263 DwrLine *item1 = *((DwrLine **) a);
1264 DwrLine *item2 = *((DwrLine **) b);
1265 return item1->address == item2->address ? 0 :
1266 item1->address > item2->address ? 1 : -1;
1269 DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
1271 // `dwarfdump -vv -l` shows a line section (.debug_line)
1272 debug_lineSec = secp;
1273 uint64_t stmt_offset = debug_lineSec->offset;
1274 uint64_t next_cu_offset = debug_lineSec->ReadLength ();
1275 uint64_t header_offset = debug_lineSec->offset;
1276 debug_lineSec->size = next_cu_offset;
1277 version = debug_lineSec->Get_16 ();
1278 header_length = debug_lineSec->GetLong ();
1279 opcode_start = debug_lineSec->offset + header_length;
1280 minimum_instruction_length = debug_lineSec->Get_8 ();
1281 op_index_register = 0;
1282 if (version == 4)
1283 maximum_operations_per_instruction = debug_lineSec->Get_8 ();
1284 else
1285 maximum_operations_per_instruction = 1;
1286 default_is_stmt = debug_lineSec->Get_8 ();
1287 is_stmt = (default_is_stmt != 0);
1288 line_base = debug_lineSec->Get_8 ();
1289 line_range = debug_lineSec->Get_8 ();
1290 opcode_base = debug_lineSec->Get_8 ();
1291 standard_opcode_length = (Dwarf_Small*) debug_lineSec->GetData (opcode_base - 1);
1293 if (DUMP_DWR_LINE_REGS)
1295 Dprintf (DUMP_DWR_LINE_REGS,
1296 "\n.debug_line version=%d stmt_offset=0x%llx"
1297 "header_offset=0x%llx size=%lld dirname='%s'\n"
1298 " header_length=0x%llx opcode_start=0x%llx"
1299 "minimum_instruction_length=%d default_is_stmt=%d\n"
1300 " line_base=%d line_range=%d opcode_base=%d\n",
1301 (int) version, (long long) stmt_offset,
1302 (long long) header_offset,
1303 (long long) (next_cu_offset - header_offset), STR (dirName),
1304 (long long) header_length, (long long) opcode_start,
1305 (int) minimum_instruction_length, (int) default_is_stmt,
1306 (int) line_base, (int) line_range, (int) opcode_base);
1307 if (standard_opcode_length == NULL)
1308 Dprintf (DUMP_DWR_LINE_REGS, "ERROR: standard_opcode_length is NULL\n");
1309 for (int i = 0, sz = standard_opcode_length ? opcode_base - 1 : 0;
1310 i < sz; i++)
1311 Dprintf (DUMP_DWR_LINE_REGS, " opcode[%2d] length %2d\n", i,
1312 (int) standard_opcode_length[i]);
1315 include_directories = new Vector<char *>;
1316 include_directories->append (dirName);
1317 while (true)
1319 char *s = debug_lineSec->GetString (NULL);
1320 if (s == NULL)
1321 break;
1322 include_directories->append (s);
1325 file_names = new Vector<DwrFileName *>;
1326 while (true)
1328 char *s = debug_lineSec->GetString (NULL);
1329 if (s == NULL)
1330 break;
1331 DwrFileName *fnp = new DwrFileName (s);
1332 fnp->path = NULL;
1333 fnp->fname = s;
1334 fnp->dir_index = debug_lineSec->GetULEB128_32 ();
1335 fnp->timestamp = debug_lineSec->GetULEB128 ();
1336 fnp->file_size = debug_lineSec->GetULEB128 ();
1337 file_names->append (fnp);
1339 lines = NULL;
1340 dump ();
1343 DwrLineRegs::~DwrLineRegs ()
1345 Destroy (file_names);
1346 Destroy (lines);
1347 delete debug_lineSec;
1348 delete include_directories;
1351 void
1352 DwrLineRegs::dump ()
1354 if (!DUMP_DWR_LINE_REGS)
1355 return;
1356 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\ninclude_directories size=%lld\n"), (long long) VecSize (include_directories));
1357 for (long i = 0, sz = VecSize (include_directories); i < sz; i++)
1359 char *s = include_directories->get (i);
1360 Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %s\n"), (long long) i, STR (s));
1363 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\nfile_names size=%lld\n"), (long long) VecSize (file_names));
1364 for (long i = 0, sz = VecSize (file_names); i < sz; i++)
1366 DwrFileName *fnp = file_names->get (i);
1367 Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %-40s dir_index=%4lld timestamp=%8lld file_size=%lld\n"),
1368 (long long) i, STR (fnp->fname),
1369 (long long) fnp->dir_index, (long long) fnp->timestamp, (long long) fnp->file_size);
1371 if (lines)
1372 lines->dump (fname);
1373 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\n\n"));
1376 void
1377 DwrLineRegs::DoExtendedOpcode ()
1379 uint64_t size = debug_lineSec->GetULEB128 ();
1380 if (size == 0)
1382 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), NTXT ("ExtendedOpCode: size=0"));
1383 return;
1385 Dwarf_Small opcode = debug_lineSec->Get_8 ();
1386 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), extended_opcode2str (opcode));
1387 switch (opcode)
1389 case DW_LNE_end_sequence:
1390 end_sequence = true;
1391 reset ();
1392 break;
1393 case DW_LNE_set_address:
1394 address = debug_lineSec->GetADDR ();
1395 break;
1396 case DW_LNE_define_file:
1397 // TODO, add file to file list
1398 fname = debug_lineSec->GetString (NULL);
1399 dir_index = debug_lineSec->GetULEB128 ();
1400 timestamp = debug_lineSec->GetULEB128 ();
1401 file_size = debug_lineSec->GetULEB128 ();
1402 break;
1403 default:
1404 debug_lineSec->GetData (size - 1); // skip unknown opcode
1405 break;
1409 void
1410 DwrLineRegs::DoStandardOpcode (int opcode)
1412 switch (opcode)
1414 case DW_LNS_copy:
1415 basic_block = false;
1416 EmitLine ();
1417 break;
1418 case DW_LNS_advance_pc:
1419 address += debug_lineSec->GetULEB128 () * minimum_instruction_length;
1420 break;
1421 case DW_LNS_advance_line:
1422 line += (int) debug_lineSec->GetSLEB128 ();
1423 break;
1424 case DW_LNS_set_file:
1425 file = debug_lineSec->GetULEB128_32 ();
1426 break;
1427 case DW_LNS_set_column:
1428 column = debug_lineSec->GetULEB128_32 ();
1429 break;
1430 case DW_LNS_negate_stmt:
1431 is_stmt = -is_stmt;
1432 break;
1433 case DW_LNS_set_basic_block:
1434 basic_block = true;
1435 break;
1436 case DW_LNS_const_add_pc:
1437 address += ((255 - opcode_base) / line_range) * minimum_instruction_length;
1438 break;
1439 case DW_LNS_fixed_advance_pc:
1440 address += debug_lineSec->Get_16 ();
1441 break;
1442 default: // skip unknown opcode/operands
1443 debug_lineSec->GetData (standard_opcode_length ?
1444 standard_opcode_length[opcode] : 1);
1445 break;
1449 void
1450 DwrLineRegs::DoSpecialOpcode (int opcode)
1452 int max_op_per_instr = maximum_operations_per_instruction == 0 ? 1
1453 : maximum_operations_per_instruction;
1454 int operation_advance = (opcode / line_range);
1455 address += minimum_instruction_length * ((op_index_register + operation_advance) / max_op_per_instr);
1456 op_index_register = (op_index_register + operation_advance) % max_op_per_instr;
1457 line += line_base + (opcode % line_range);
1458 basic_block = false;
1459 EmitLine ();
1462 void
1463 DwrLineRegs::reset ()
1465 dir_index = 0;
1466 timestamp = 0;
1467 file_size = 0;
1468 address = 0;
1469 file = 1;
1470 line = 1;
1471 column = 0;
1472 is_stmt = (default_is_stmt != 0);
1473 basic_block = false;
1474 end_sequence = false;
1477 void
1478 DwrLineRegs::EmitLine ()
1480 DwrLine *lnp = new DwrLine;
1482 lnp->file = file;
1483 lnp->line = line;
1484 lnp->column = column;
1485 lnp->address = address;
1486 lines->append (lnp);
1487 if ((file > 0) && (file < VecSize (file_names)))
1489 DwrFileName *fnp = file_names->get (file);
1490 fnp->isUsed = true;
1494 Vector<DwrLine *> *
1495 DwrLineRegs::get_lines ()
1497 if (lines == NULL)
1499 lines = new Vector<DwrLine *>;
1500 debug_lineSec->offset = opcode_start;
1501 reset ();
1502 Dprintf (DUMP_DWR_LINE_REGS, "\n offset code address (file, line, column) stmt blck end_seq \n");
1503 while (debug_lineSec->offset < debug_lineSec->size)
1505 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("0x%08llx "),
1506 (long long) debug_lineSec->offset);
1507 Dwarf_Small opcode = debug_lineSec->Get_8 ();
1508 if (opcode == 0)
1509 DoExtendedOpcode ();
1510 else if (opcode < opcode_base)
1512 DoStandardOpcode (opcode);
1513 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), standard_opcode2str (opcode));
1515 else
1517 DoSpecialOpcode (opcode - opcode_base);
1518 Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"),
1519 special_opcode2str (opcode - opcode_base));
1521 Dprintf (DUMP_DWR_LINE_REGS,
1522 " 0x%08llx (%lld, %lld, %lld) %c %c %c\n",
1523 (long long) address, (long long) file, (long long) line,
1524 (long long) column, is_stmt ? 'T' : 'F',
1525 basic_block ? 'T' : 'F', end_sequence ? 'T' : 'F');
1527 lines->sort (LineRegsCmp);
1528 if (DUMP_DWR_LINE_REGS)
1529 lines->dump (fname);
1531 return lines;
1534 char *
1535 DwrLineRegs::getPath (int fn)
1537 fn--;
1538 if ((fn >= VecSize (file_names)) || (fn < 0))
1540 Dprintf (DEBUG_ERR_MSG, NTXT ("DwrLineRegs::getPath: fn=0x%lld file_names->size()=%lld\n"),
1541 (long long) fn, (long long) VecSize (file_names));
1542 return NULL;
1544 DwrFileName *fnp = file_names->fetch (fn);
1545 if (fnp->path)
1546 return fnp->path;
1548 char *dir = fnp->dir_index < include_directories->size () ?
1549 include_directories->fetch (fnp->dir_index) : NULL;
1550 if ((fnp->fname[0] == '/') || (dir == NULL) || (*dir == 0))
1552 fnp->path = fnp->fname;
1553 return fnp->path;
1556 StringBuilder sb;
1557 if (*dir != '/')
1558 { // not absolute
1559 char *s = include_directories->fetch (0);
1560 sb.append (s);
1561 sb.append ('/');
1563 sb.append (dir);
1564 sb.append ('/');
1565 sb.append (fnp->fname);
1566 fnp->path = canonical_path (sb.toString ());
1567 return fnp->path;
1570 DwrCU::DwrCU (Dwarf *_dwarf)
1572 dwarf = _dwarf;
1573 cu_offset = dwarf->debug_infoSec->offset;
1574 debug_infoSec = new DwrSec (dwarf->debug_infoSec, cu_offset);
1575 next_cu_offset = debug_infoSec->ReadLength ();
1576 if (next_cu_offset > debug_infoSec->sizeSec)
1578 Dprintf (DEBUG_ERR_MSG,
1579 "DwrCU::DwrCU: next_cu_offset(0x%llx) > debug_infoSec->sizeSec(%llx)\n",
1580 (long long) next_cu_offset, (long long) debug_infoSec->sizeSec);
1581 next_cu_offset = debug_infoSec->sizeSec;
1583 debug_infoSec->size = next_cu_offset;
1584 version = debug_infoSec->Get_16 ();
1585 debug_abbrev_offset = debug_infoSec->GetLong ();
1586 address_size = debug_infoSec->Get_8 ();
1587 cu_header_offset = debug_infoSec->offset;
1588 comp_dir = NULL;
1589 module = NULL;
1590 abbrevTable = NULL;
1591 dwrInlinedSubrs = NULL;
1592 srcFiles = NULL;
1593 stmt_list_offset = 0;
1594 dwrLineReg = NULL;
1595 isMemop = false;
1596 isGNU = false;
1597 dwrTag.level = 0;
1599 build_abbrevTable (dwarf->debug_abbrevSec, debug_abbrev_offset);
1600 #ifdef DEBUG
1601 if (DUMP_DWARFLIB)
1603 Dprintf (DUMP_DWARFLIB,
1604 "CU_HEADER: header_offset = 0x%08llx %lld"
1605 "next_header_offset=0x%08llx %lld\n"
1606 " abbrev_offset = 0x%08llx %lld\n"
1607 " unit_length = %lld\n"
1608 " version = %d\n"
1609 " address_size = %d\n"
1610 " fmt64 = %s\n"
1611 "debug_info: need_swap_endian=%s fmt64=%s addr32=%s\n",
1612 (long long) cu_offset, (long long) cu_offset,
1613 (long long) next_cu_offset, (long long) next_cu_offset,
1614 (long long) debug_abbrev_offset, (long long) debug_abbrev_offset,
1615 (long long) (next_cu_offset - cu_offset),
1616 (int) version, (int) address_size,
1617 debug_infoSec->fmt64 ? "true" : "false",
1618 debug_infoSec->need_swap_endian ? "true" : "false",
1619 debug_infoSec->fmt64 ? "true" : "false",
1620 debug_infoSec->addr32 ? "true" : "false");
1621 Dprintf (DUMP_DWARFLIB, "\n.debug_abbrev cnt=%d offset=0x%08llx %lld\n",
1622 (int) VecSize (abbrevTable), (long long) debug_abbrev_offset,
1623 (long long) debug_abbrev_offset);
1624 for (int i = 1, sz = VecSize (abbrevTable); i < sz; i++)
1626 DwrAbbrevTable *abbTbl = abbrevTable->get (i);
1627 Dprintf (DUMP_DWARFLIB, NTXT ("%5d: %-30s %-20s offset=0x%08llx\n"),
1628 (int) i, DwrCU::tag2str (abbTbl->tag),
1629 abbTbl->hasChild ? "DW_children_yes" : "DW_children_no",
1630 (long long) abbTbl->offset);
1631 for (int i1 = abbTbl->firstAtForm; i1 < abbTbl->lastAtForm; i1++)
1633 Dwr_Attr *atf = abbrevAtForm->get (i1);
1634 Dprintf (DUMP_DWARFLIB, " %-30s %s\n",
1635 DwrCU::at2str (atf->at_name),
1636 DwrCU::form2str (atf->at_form));
1640 #endif
1643 DwrCU::~DwrCU ()
1645 delete debug_infoSec;
1646 delete abbrevTable;
1647 delete abbrevAtForm;
1648 Destroy (dwrInlinedSubrs);
1649 delete srcFiles;
1650 delete dwrLineReg;
1651 free (comp_dir);
1654 void
1655 DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
1657 if (abbrevTable)
1658 return;
1659 DwrSec *debug_abbrevSec = new DwrSec (_debug_abbrevSec, _offset);
1660 abbrevTable = new DbeArray <DwrAbbrevTable>(128);
1661 abbrevAtForm = new DbeArray <Dwr_Attr>(512);
1662 abbrevTable->allocate (1); // skip first
1663 abbrevAtForm->allocate (1); // skip first
1664 for (int i = 1; debug_abbrevSec->offset < debug_abbrevSec->size; i++)
1666 DwrAbbrevTable abbTbl;
1667 abbTbl.offset = debug_abbrevSec->offset;
1668 abbTbl.code = debug_abbrevSec->GetULEB128_32 ();
1669 if (abbTbl.code == 0)
1670 break;
1671 else if (i != abbTbl.code)
1673 dwarf->elf->append_msg (CMSG_ERROR, GTXT ("%s: the abbreviations table is corrupted (%lld <--> %lld)\n"),
1674 get_basename (dwarf->elf->get_location ()),
1675 (long long) i, (long long) abbTbl.code);
1676 break;
1678 abbTbl.tag = debug_abbrevSec->GetULEB128_32 ();
1679 abbTbl.hasChild = (DW_children_yes == debug_abbrevSec->Get_8 ());
1680 abbTbl.firstAtForm = abbrevAtForm->size ();
1681 while (debug_abbrevSec->offset < debug_abbrevSec->size)
1683 Dwr_Attr atf;
1684 atf.at_name = debug_abbrevSec->GetULEB128_32 ();
1685 atf.at_form = debug_abbrevSec->GetULEB128_32 ();
1686 if (atf.at_name == 0 && atf.at_form == 0)
1687 break;
1688 abbrevAtForm->append (atf);
1690 abbTbl.lastAtForm = abbrevAtForm->size ();
1691 abbrevTable->append (abbTbl);
1693 delete debug_abbrevSec;
1697 DwrCU::set_die (Dwarf_Die die)
1699 if (die > 0)
1700 debug_infoSec->offset = die;
1701 if (debug_infoSec->offset < cu_header_offset
1702 || debug_infoSec->offset >= debug_infoSec->size)
1703 return DW_DLV_ERROR;
1704 dwrTag.offset = debug_infoSec->offset;
1705 dwrTag.die = debug_infoSec->offset - cu_offset;
1706 dwrTag.num = debug_infoSec->GetULEB128_32 ();
1707 if (dwrTag.num == 0)
1708 return DW_DLV_NO_ENTRY;
1709 dwrTag.abbrevAtForm = abbrevAtForm;
1710 DwrAbbrevTable *abbTbl = abbrevTable->get (dwrTag.num);
1711 if (abbTbl == NULL)
1712 { // corrupt dwarf
1713 dwarf->elf->append_msg (CMSG_ERROR, GTXT ("%s: the abbreviation code (%lld) does not match for the Dwarf entry (0x%llx)\n"),
1714 get_basename (dwarf->elf->get_location ()),
1715 (long long) dwrTag.num, (long long) dwrTag.offset);
1716 return DW_DLV_ERROR;
1718 dwrTag.tag = abbTbl->tag;
1719 dwrTag.hasChild = abbTbl->hasChild;
1720 dwrTag.firstAttribute = abbTbl->firstAtForm;
1721 dwrTag.lastAttribute = abbTbl->lastAtForm;
1722 for (int k = abbTbl->firstAtForm; k < abbTbl->lastAtForm; k++)
1724 Dwr_Attr *atf = abbrevAtForm->get (k);
1725 int at_form = atf->at_form;
1726 if (at_form == DW_FORM_indirect)
1727 at_form = debug_infoSec->GetULEB128_32 ();
1728 switch (at_form)
1730 case DW_FORM_addr:
1731 atf->u.offset = (address_size == 4) ? debug_infoSec->GetADDR_32 ()
1732 : debug_infoSec->GetADDR_64 ();
1733 break;
1734 case DW_FORM_flag:
1735 atf->u.offset = debug_infoSec->Get_8 ();
1736 break;
1737 case DW_FORM_block:
1738 atf->len = debug_infoSec->GetULEB128 ();
1739 atf->u.str = debug_infoSec->GetData (atf->len);
1740 break;
1741 case DW_FORM_block1:
1742 atf->len = debug_infoSec->Get_8 ();
1743 atf->u.str = debug_infoSec->GetData (atf->len);
1744 break;
1745 case DW_FORM_block2:
1746 atf->len = debug_infoSec->Get_16 ();
1747 atf->u.str = debug_infoSec->GetData (atf->len);
1748 break;
1749 case DW_FORM_block4:
1750 atf->len = debug_infoSec->Get_32 ();
1751 atf->u.str = debug_infoSec->GetData (atf->len);
1752 break;
1753 case DW_FORM_ref1:
1754 atf->u.offset = debug_infoSec->Get_8 ();
1755 break;
1756 case DW_FORM_ref2:
1757 atf->u.offset = debug_infoSec->Get_16 ();
1758 break;
1759 case DW_FORM_ref4:
1760 atf->u.offset = debug_infoSec->Get_32 ();
1761 break;
1762 case DW_FORM_ref8:
1763 atf->u.offset = debug_infoSec->Get_64 ();
1764 break;
1765 case DW_FORM_ref_udata:
1766 atf->u.offset = debug_infoSec->GetULEB128 ();
1767 break;
1768 case DW_FORM_data1:
1769 atf->u.offset = debug_infoSec->Get_8 ();
1770 break;
1771 case DW_FORM_data2:
1772 atf->u.offset = debug_infoSec->Get_16 ();
1773 break;
1774 case DW_FORM_data4:
1775 atf->u.offset = debug_infoSec->Get_32 ();
1776 break;
1777 case DW_FORM_data8:
1778 atf->u.offset = debug_infoSec->Get_64 ();
1779 break;
1780 case DW_FORM_string:
1781 atf->u.str = debug_infoSec->GetString (&atf->len);
1782 break;
1783 case DW_FORM_strp:
1784 atf->u.offset = debug_infoSec->GetRef ();
1785 if (dwarf->debug_strSec == NULL)
1787 atf->u.str = NULL;
1788 atf->len = 0;
1790 else
1792 dwarf->debug_strSec->offset = atf->u.offset;
1793 atf->u.str = dwarf->debug_strSec->GetString (&atf->len);
1795 break;
1796 case DW_FORM_sdata:
1797 atf->u.val = debug_infoSec->GetSLEB128 ();
1798 break;
1799 case DW_FORM_udata:
1800 atf->u.offset = debug_infoSec->GetULEB128 ();
1801 break;
1802 case DW_FORM_ref_addr:
1803 atf->u.offset = debug_infoSec->GetADDR ();
1804 break;
1805 case DW_FORM_sec_offset:
1806 atf->u.offset = debug_infoSec->GetRef ();
1807 break;
1808 case DW_FORM_exprloc:
1809 atf->u.offset = debug_infoSec->GetULEB128 ();
1810 debug_infoSec->offset += atf->u.offset;
1811 break;
1812 case DW_FORM_flag_present:
1813 atf->u.val = 1;
1814 break;
1815 case DW_FORM_ref_sig8:
1816 atf->u.offset = debug_infoSec->GetADDR_64 ();
1817 break;
1818 default:
1819 DEBUG_CODE
1821 Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
1822 (long long) atf->at_form, (long long) atf->at_form);
1823 assert (0);
1825 atf->u.str = NULL;
1826 atf->len = 0;
1827 break;
1830 dwrTag.dump ();
1831 return DW_DLV_OK;
1834 static char *
1835 composePath (char *dname, char *fname)
1837 char *s;
1838 if (*fname == '/' || dname == NULL)
1839 s = dbe_sprintf (NTXT ("%s"), fname);
1840 else
1841 s = dbe_sprintf (NTXT ("%s/%s"), dname, fname);
1842 return canonical_path (s);
1845 Module *
1846 DwrCU::parse_cu_header (LoadObject *lo)
1848 // Is tag always DW_TAG_compile_unit?
1849 if (dwrTag.tag != DW_TAG_compile_unit)
1851 Dprintf (DEBUG_ERR_MSG,
1852 "parse_cu_header: die=0x%llx tag=%lld is not DW_TAG_compile_unit\n",
1853 (long long) cu_offset, (long long) dwrTag.tag);
1854 return NULL;
1857 char *name = Dwarf_string (DW_AT_name);
1858 if (name == NULL)
1859 name = NTXT ("UnnamedUnit");
1860 stmt_list_offset = Dwarf_data (DW_AT_stmt_list);
1861 comp_dir = dbe_strdup (Dwarf_string (DW_AT_comp_dir));
1862 char *dir_name = comp_dir ? StrChr (comp_dir, ':') : NULL;
1863 char *orig_name = Dwarf_string (DW_AT_SUN_original_name);
1864 char *path = composePath (dir_name, orig_name ? orig_name : name);
1866 module = dwarf->stabs->append_Module (lo, path);
1867 free (path);
1868 if (module == NULL)
1869 return NULL;
1870 module->hasDwarf = true;
1871 if (orig_name)
1872 module->linkerStabName = composePath (dir_name, name);
1873 module->lang_code = Dwarf_lang ();
1874 module->comp_flags = dbe_strdup (Dwarf_string (DW_AT_SUN_command_line));
1875 if (module->comp_flags == NULL)
1876 module->comp_flags = dbe_strdup (Dwarf_string (DW_AT_icc_flags));
1877 module->comp_dir = dbe_strdup (dir_name);
1879 char *obj_file = Dwarf_string (DW_AT_SUN_obj_file);
1880 char *obj_dir = Dwarf_string (DW_AT_SUN_obj_dir);
1881 if (obj_dir && obj_file)
1883 // object information may not be available
1884 dir_name = StrChr (obj_dir, ':');
1885 path = composePath (dir_name, obj_file);
1886 if (module->dot_o_file == NULL)
1887 module->dot_o_file = module->createLoadObject (path);
1889 else
1890 path = dbe_strdup (dwarf->stabs->path);
1891 module->set_name (path);
1892 return module;
1895 Dwr_Attr *
1896 Dwr_Tag::get_attr (Dwarf_Half attr)
1898 for (long i = firstAttribute; i < lastAttribute; i++)
1900 Dwr_Attr *atf = abbrevAtForm->get (i);
1901 if (atf->at_name == attr)
1902 return atf;
1904 return NULL;
1907 char *
1908 DwrCU::Dwarf_string (Dwarf_Half attr)
1910 Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1911 return dwrAttr ? dwrAttr->u.str : NULL;
1914 uint64_t
1915 DwrCU::get_high_pc (uint64_t low_pc)
1917 Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_high_pc);
1918 if (dwrAttr)
1919 switch (dwrAttr->at_form)
1921 case DW_FORM_addr:
1922 return dwrAttr->u.offset;
1923 default:
1924 return dwrAttr->u.offset + low_pc;
1926 return 0;
1929 Dwarf_Addr
1930 DwrCU::Dwarf_addr (Dwarf_Half attr)
1932 Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1933 if (dwrAttr)
1934 switch (dwrAttr->at_form)
1936 case DW_FORM_addr:
1937 return dwrAttr->u.offset;
1939 return 0;
1942 DwrSec*
1943 DwrCU::Dwarf_block (Dwarf_Half attr)
1945 Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1946 if (dwrAttr && dwrAttr->u.block)
1947 switch (dwrAttr->at_form)
1949 case DW_FORM_block:
1950 case DW_FORM_block1:
1951 case DW_FORM_block2:
1952 case DW_FORM_block4:
1953 return new DwrSec (dwrAttr->u.block, dwrAttr->len,
1954 dwarf->elf->need_swap_endian,
1955 dwarf->elf->elf_getclass () == ELFCLASS32);
1957 return NULL;
1961 DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
1963 Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1964 if (dwrAttr)
1965 switch (dwrAttr->at_form)
1967 case DW_FORM_data1:
1968 case DW_FORM_data2:
1969 case DW_FORM_data4:
1970 case DW_FORM_data8:
1971 case DW_FORM_udata:
1972 case DW_FORM_sec_offset:
1973 *retVal = dwrAttr->u.val;
1974 return DW_DLV_OK;
1977 return DW_DLV_ERROR;
1981 DwrCU::read_ref_attr (Dwarf_Half attr, int64_t *retVal)
1983 Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1984 if (dwrAttr)
1985 switch (dwrAttr->at_form)
1987 case DW_FORM_ref1:
1988 case DW_FORM_ref2:
1989 case DW_FORM_ref4:
1990 case DW_FORM_ref8:
1991 case DW_FORM_ref_udata:
1992 case DW_FORM_sec_offset:
1993 case DW_FORM_exprloc:
1994 case DW_FORM_ref_sig8:
1995 *retVal = dwrAttr->u.val;
1996 return DW_DLV_OK;
1998 return DW_DLV_ERROR;
2001 int64_t
2002 DwrCU::Dwarf_data (Dwarf_Half attr)
2004 int64_t retVal;
2005 if (read_data_attr (attr, &retVal) == DW_DLV_OK)
2006 return retVal;
2007 return 0;
2010 int64_t
2011 DwrCU::Dwarf_ref (Dwarf_Half attr)
2013 int64_t retVal;
2014 if (read_ref_attr (attr, &retVal) == DW_DLV_OK)
2015 return retVal;
2016 return 0;
2019 Dwarf_Addr
2020 DwrCU::Dwarf_location (Dwarf_Attribute attr)
2022 DwrSec *secp = Dwarf_block (attr);
2023 if (secp)
2025 DwrLocation loc;
2026 DwrLocation *lp = dwr_get_location (secp, &loc);
2027 delete secp;
2028 if (lp)
2029 return lp->lc_number;
2031 return 0;
2034 void
2035 DwrCU::map_dwarf_lines (Module *mod)
2037 DwrLineRegs *lineReg = get_dwrLineReg ();
2038 long inlinedSubrCnt = VecSize (dwrInlinedSubrs);
2039 if (isGNU && (inlinedSubrCnt > 0))
2041 Function *func = NULL;
2042 mod->inlinedSubr = (InlinedSubr *) malloc (inlinedSubrCnt
2043 * sizeof (InlinedSubr));
2044 for (long i = 0; i < inlinedSubrCnt; i++)
2046 DwrInlinedSubr *inlinedSubr = dwrInlinedSubrs->get (i);
2047 uint64_t low_pc;
2048 Function *f = dwarf->stabs->map_PC_to_func (inlinedSubr->low_pc,
2049 low_pc, mod->functions);
2050 if (f == NULL)
2051 continue;
2052 if (func != f)
2054 func = f;
2055 func->inlinedSubrCnt = 0;
2056 func->inlinedSubr = mod->inlinedSubr + i;
2058 InlinedSubr *p = func->inlinedSubr + func->inlinedSubrCnt;
2059 func->inlinedSubrCnt++;
2060 int fileno = inlinedSubr->file - 1;
2061 SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ?
2062 srcFiles->get (fileno) : dbeSession->get_Unknown_Source ();
2063 p->dbeLine = sf->find_dbeline (inlinedSubr->line);
2064 p->high_pc = inlinedSubr->high_pc - low_pc;
2065 p->low_pc = inlinedSubr->low_pc - low_pc;
2066 p->level = inlinedSubr->level;
2067 p->func = NULL;
2068 p->fname = NULL;
2069 if (set_die (inlinedSubr->abstract_origin) == DW_DLV_OK)
2070 p->fname = dbe_strdup (Dwarf_string (DW_AT_name));
2071 if (p->fname)
2072 p->func = Stabs::find_func (p->fname, mod->functions,
2073 Stabs::is_fortran (mod->lang_code));
2076 Vector<DwrLine *> *lines = lineReg->get_lines ();
2078 Include *includes = new Include;
2079 includes->new_src_file (mod->getMainSrc (), 0, NULL);
2080 char *path = NULL;
2081 SourceFile *cur_src = NULL;
2082 Function *cur_func = NULL;
2083 for (long i = 0, sz = VecSize (lines); i < sz; i++)
2085 DwrLine *dwrLine = lines->get (i);
2086 char *filename = dwrLineReg->getPath (dwrLine->file);
2087 if (filename == NULL)
2088 continue;
2089 uint64_t pc = dwrLine->address;
2090 int lineno = dwrLine->line;
2091 if (path != filename)
2093 path = filename;
2094 char *name = StrChr (path, ':');
2095 SourceFile *src = mod->setIncludeFile (name);
2096 if (cur_src != src)
2098 includes->new_src_file (src, lineno, cur_func);
2099 cur_src = src;
2102 uint64_t low_pc;
2103 Function *func = dwarf->stabs->map_PC_to_func (pc, low_pc, mod->functions);
2104 if (func && (func->module == mod))
2106 if (func != cur_func)
2108 if (cur_func)
2109 while (cur_func->popSrcFile () != NULL)
2111 cur_func = func;
2112 includes->push_src_files (cur_func);
2114 cur_func->add_PC_info (pc - low_pc, lineno);
2117 if (cur_func)
2118 while (cur_func->popSrcFile ())
2120 delete includes;
2123 DwrLineRegs *
2124 DwrCU::get_dwrLineReg ()
2126 if (dwrLineReg == NULL)
2127 dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
2128 stmt_list_offset), comp_dir);
2129 return dwrLineReg;
2132 void
2133 DwrCU::parse_inlined_subroutine (Dwarf_cnt *ctx)
2135 int64_t abstract_origin = Dwarf_ref (DW_AT_abstract_origin);
2136 int fileno = (int) Dwarf_data (DW_AT_call_file);
2137 int lineno = (int) Dwarf_data (DW_AT_call_line);
2138 int level = ctx->inlinedSubr ? (ctx->inlinedSubr->level + 1) : 0;
2139 DwrInlinedSubr *inlinedSubr_old = ctx->inlinedSubr;
2141 if (dwrInlinedSubrs == NULL)
2142 dwrInlinedSubrs = new Vector<DwrInlinedSubr*>;
2143 Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges);
2144 if (dwrAttr)
2146 uint64_t ranges = Dwarf_ref (DW_AT_ranges);
2147 if (dwarf->debug_rangesSec && (ranges < dwarf->debug_rangesSec->size))
2149 dwarf->debug_rangesSec->offset = ranges;
2150 for (;;)
2152 uint64_t low_pc = dwarf->debug_rangesSec->GetADDR ();
2153 uint64_t high_pc = dwarf->debug_rangesSec->GetADDR ();
2154 if ((low_pc > 0) && (low_pc <= high_pc))
2156 DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin,
2157 low_pc, high_pc, fileno, lineno, level);
2158 dwrInlinedSubrs->append (p);
2159 ctx->inlinedSubr = p;
2161 else
2162 break;
2166 else
2168 uint64_t low_pc = Dwarf_addr (DW_AT_low_pc);
2169 uint64_t high_pc = get_high_pc (low_pc);
2170 if ((low_pc > 0) && (low_pc <= high_pc))
2172 DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin, low_pc,
2173 high_pc, fileno, lineno, level);
2174 dwrInlinedSubrs->append (p);
2175 ctx->inlinedSubr = p;
2178 parseChild (ctx);
2179 ctx->inlinedSubr = inlinedSubr_old;
2183 //////////////////////////////////////////////////////////
2184 // class DwrInlinedSubr
2185 DwrInlinedSubr::DwrInlinedSubr (int64_t _abstract_origin, uint64_t _low_pc,
2186 uint64_t _high_pc, int _file, int _line, int _level)
2188 abstract_origin = _abstract_origin;
2189 low_pc = _low_pc;
2190 high_pc = _high_pc;
2191 file = _file;
2192 line = _line;
2193 level = _level;
2196 void
2197 DwrInlinedSubr::dump ()
2199 Dprintf (DUMP_DWARFLIB,
2200 " level=%d 0x%08llx [0x%08llx - 0x%08llx] file=%d line=%d\n",
2201 (int) level, (long long) abstract_origin, (long long) low_pc,
2202 (long long) high_pc, (int) file, (int) line);