]> Git Repo - binutils.git/blob - gprofng/src/DwarfLib.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / DwarfLib.cc
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2    Contributed by Oracle.
3
4    This file is part of GNU Binutils.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "config.h"
22 #include <ctype.h>
23
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"
33
34 #define CASE_S(x)   case x: s = (char *) #x; break
35
36 static char *
37 gelf_st_type2str (int type)
38 {
39   static char buf[128];
40   char *s;
41   switch (type)
42     {
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;
55     }
56   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type);
57   buf[sizeof (buf) - 1] = 0;
58   return buf;
59 }
60
61 static char *
62 special_opcode2str (int opcode)
63 {
64   static char buf[128];
65   snprintf (buf, sizeof (buf), NTXT ("SpecialOpcode: %3d"), opcode);
66   buf[sizeof (buf) - 1] = 0;
67   return buf;
68 }
69
70 static char *
71 extended_opcode2str (int opcode)
72 {
73   static char buf[128];
74   char *s;
75   switch (opcode)
76     {
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;
85     }
86   return s;
87 }
88
89 static char *
90 standard_opcode2str (int opcode)
91 {
92   static char buf[128];
93   char *s;
94   switch (opcode)
95     {
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;
110     }
111   return s;
112 }
113
114 template<> void Vector<DwrInlinedSubr *>
115 ::dump (const char *msg)
116 {
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++)
120     {
121       DwrInlinedSubr *p = get (i);
122       Dprintf (1, NTXT ("%ld: "), (long) i);
123       p->dump ();
124     }
125 }
126
127 template<> void Vector<DwrLine *>
128 ::dump (const char *msg)
129 {
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++)
133     {
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);
138     }
139   Dprintf (1, NTXT ("\n\n"));
140 }
141
142 //////////////////////////////////////////////////////////
143 //  class ElfReloc
144
145 ElfReloc::ElfReloc (Elf *_elf)
146 {
147   elf = _elf;
148   reloc = NULL;
149   cur_reloc_ind = 0;
150 }
151
152 ElfReloc::~ElfReloc ()
153 {
154   if (reloc)
155     {
156       reloc->destroy ();
157       delete reloc;
158     }
159 }
160
161 void
162 ElfReloc::dump_rela_debug_sec (int sec)
163 {
164   if (!DUMP_RELA_SEC)
165     return;
166   Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
167   if (shdr == NULL)
168     return;
169
170   Elf_Data *data = elf->elf_getdata (sec);
171   if (data == NULL)
172     return;
173
174   uint64_t ScnSize = data->d_size;
175   uint64_t EntSize = shdr->sh_entsize;
176   if (ScnSize == 0 || EntSize == 0)
177     return;
178
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);
187
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++)
197     {
198       if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
199         elf->elf_getrela (data, n, &rela);
200       else
201         {
202           elf->elf_getrel (data, n, &rela);
203           rela.r_addend = 0;
204         }
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))
214         {
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)
228             {
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));
232             }
233           break;
234         default:
235           break;
236         }
237       Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
238     }
239   Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
240 }
241
242 void
243 ElfReloc::dump ()
244 {
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++)
250     {
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));
255     }
256   Dprintf (DUMP_ELF_RELOC, NTXT ("\n"));
257 }
258
259 static int
260 DwrRelocOffsetCmp (const void *a, const void *b)
261 {
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;
266 }
267
268 ElfReloc *
269 ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
270 {
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;
280
281   Elf_Data *data = elfp->elf_getdata (sec);
282   if (data == NULL || data->d_size == 0)
283     return rlc;
284
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;
291
292   for (int n = 0; n < cnt; n++)
293     {
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
300         {
301           elfp->elf_getrel (data, n, &rela);
302           rela.r_addend = 0;
303         }
304       int ndx = (int) GELF_R_SYM (rela.r_info);
305       Elf_Internal_Sym sym;
306       elfp->elf_getsym (data_sym, ndx, &sym);
307
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))
313         {
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)
323             {
324               srlc->offset = rela.r_info;
325               srlc->value = secHdr->sh_offset + rela.r_addend;
326             }
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;
336         }
337       if (rlc == NULL)
338         {
339           rlc = new ElfReloc (elfp);
340           vp = rlc->reloc;
341         }
342       if (vp == NULL)
343         {
344           vp = new Vector<Sreloc*>;
345           rlc->reloc = vp;
346         }
347       vp->append (srlc);
348     }
349   if (vp)
350     vp->sort (DwrRelocOffsetCmp);
351   if (rlc)
352     {
353       rlc->dump_rela_debug_sec (sec);
354       rlc->dump ();
355     }
356   return rlc;
357 }
358
359 long long
360 ElfReloc::get_reloc_addr (long long offset)
361 {
362   Sreloc *srlc;
363   int i = cur_reloc_ind - 1;
364   if (i >= 0 && i < reloc->size ())
365     {
366       srlc = reloc->fetch (i);
367       if (srlc->offset > offset)  // need to reset
368         cur_reloc_ind = 0;
369     }
370   for (; cur_reloc_ind < reloc->size (); cur_reloc_ind++)
371     {
372       srlc = reloc->fetch (cur_reloc_ind);
373       if (srlc->offset == offset)
374         return srlc->value;
375       if (srlc->offset > offset)
376         return 0;
377     }
378   return 0;
379 }
380
381 DwrLocation *
382 DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp)
383 {
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)
389     {
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:
509       {
510         signed char x;
511         x = secp->Get_8 ();
512         lp->lc_number = x;
513       }
514       break;
515     case DW_OP_const2u:
516       lp->lc_number = secp->Get_16 ();
517       break;
518     case DW_OP_const2s:
519       {
520         signed short x;
521         x = secp->Get_16 ();
522         lp->lc_number = x;
523       }
524       break;
525     case DW_OP_const4u:
526       lp->lc_number = secp->Get_32 ();
527       break;
528     case DW_OP_const4s:
529       {
530         signed int x;
531         x = secp->Get_32 ();
532         lp->lc_number = x;
533       }
534       break;
535     case DW_OP_const8u:
536       lp->lc_number = secp->Get_64 ();
537       break;
538     case DW_OP_const8s:
539       {
540         signed long long x;
541         x = secp->Get_64 ();
542         lp->lc_number = x;
543       }
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;
552
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);
609     }
610   return lp;
611 }
612
613 char *
614 DwrCU::tag2str (int tag)
615 {
616   static char buf[128];
617   char *s;
618
619   switch (tag)
620     {
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;
691     }
692   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
693   buf[sizeof (buf) - 1] = 0;
694   return buf;
695 }
696
697 char *
698 DwrCU::at2str (int tag)
699 {
700   static char buf[128];
701   char *s;
702   switch (tag)
703     {
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;
850     }
851   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
852   buf[sizeof (buf) - 1] = 0;
853   return buf;
854 }
855
856 char *
857 DwrCU::form2str (int tag)
858 {
859   static char buf[128];
860   char *s;
861   switch (tag)
862     {
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;
890     }
891   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
892   buf[sizeof (buf) - 1] = 0;
893   return buf;
894 }
895
896 void
897 Dwr_Tag::dump ()
898 {
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++)
905     {
906       Dwr_Attr *atrp = abbrevAtForm->get (i1);
907       Dprintf (DUMP_DWARFLIB, "       %-30s ", DwrCU::at2str (atrp->at_name));
908       switch (atrp->at_form)
909         {
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
947           {
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);
951           }
952         }
953       Dprintf (DUMP_DWARFLIB, NTXT ("\n"));
954     }
955 }
956
957
958 //////////////////////////////////////////////////////////
959 //  class DwrSec
960
961 DwrSec::DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32)
962 {
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;
972 }
973
974 DwrSec::DwrSec (DwrSec *secp, uint64_t _offset)
975 {
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;
985 }
986
987 DwrSec::~DwrSec ()
988 {
989   if (!isCopy)
990     delete reloc;
991 }
992
993 bool
994 DwrSec::bounds_violation (uint64_t sz)
995 {
996   if (offset + sz > size)
997     {
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;
1001     }
1002   return false;
1003 }
1004
1005 uint64_t
1006 DwrSec::ReadLength ()
1007 {
1008   fmt64 = false;
1009   uint64_t val = Get_32 ();
1010   if (((uint32_t) val) == 0xffffffff)
1011     {
1012       fmt64 = true;
1013       val = Get_64 ();
1014     }
1015   size = (val + offset < sizeSec) ? val + offset : sizeSec;
1016   return size;
1017 }
1018
1019 unsigned char
1020 DwrSec::Get_8 ()
1021 {
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;
1028 }
1029
1030 unsigned short
1031 DwrSec::Get_16 ()
1032 {
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;
1041 }
1042
1043 uint32_t
1044 DwrSec::Get_32 ()
1045 {
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;
1054 }
1055
1056 uint64_t
1057 DwrSec::Get_64 ()
1058 {
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;
1067 }
1068
1069 char *
1070 DwrSec::GetData (uint64_t len)
1071 {
1072   char *s = ((char *) data) + offset;
1073   if (bounds_violation (len))
1074     s = NULL;
1075   offset += len;
1076   return s;
1077 }
1078
1079 char *
1080 DwrSec::GetString (uint64_t *lenp)
1081 {
1082   if (offset < size)
1083     {
1084       uint64_t len = 0;
1085       for (char *s = ((char *) data) + offset; offset + len < size; len++)
1086         {
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;
1095             }
1096         }
1097       offset += len;
1098       return NULL; // The section is not '\0' terminated
1099     }
1100   return NULL;
1101 }
1102
1103 uint64_t
1104 DwrSec::GetLong ()
1105 {
1106   if (fmt64)
1107     return Get_64 ();
1108   return Get_32 ();
1109 }
1110
1111 uint64_t
1112 DwrSec::GetADDR_32 ()
1113 {
1114   uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1115   res += Get_32 ();
1116   return res;
1117 }
1118
1119 uint64_t
1120 DwrSec::GetADDR_64 ()
1121 {
1122   uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1123   res += Get_64 ();
1124   return res;
1125 }
1126
1127 uint64_t
1128 DwrSec::GetADDR ()
1129 {
1130   if (addr32)
1131     return GetADDR_32 ();
1132   return GetADDR_64 ();
1133 }
1134
1135 uint64_t
1136 DwrSec::GetRef ()
1137 {
1138   if (fmt64)
1139     return GetADDR_64 ();
1140   return GetADDR_32 ();
1141 }
1142
1143 ULEB128
1144 DwrSec::GetULEB128 ()
1145 {
1146   ULEB128 res = 0;
1147   for (int shift = 0;; shift += 7)
1148     {
1149       ULEB128 val = Get_8 ();
1150       res |= (val & 0x7f) << shift;
1151       if ((val & 0x80) == 0)
1152         break;
1153     }
1154   return res;
1155 }
1156
1157 SLEB128
1158 DwrSec::GetSLEB128 ()
1159 {
1160   ULEB128 res = 0, val = 0;
1161   size_t shift;
1162   for (shift = 0;;)
1163     {
1164       val = Get_8 ();
1165       res |= (val & 0x7f) << shift;
1166       shift += 7;
1167       if ((val & 0x80) == 0)
1168         break;
1169     }
1170   if ((val & 0x40) && (shift < 8 * sizeof (res)))
1171     res |= -(((ULEB128) 1) << shift);
1172   return (SLEB128) res;
1173 }
1174
1175 static void
1176 fillBuf (unsigned char *s, int len, int col, unsigned char *buf)
1177 {
1178   const char *nameX = "0123456789abcdef";
1179   int i, n, posCh = 2 * col + col / 4 + 5;
1180
1181   if (len >= col)
1182     len = col;
1183   for (i = n = 0; i < len; i++, n += 2)
1184     {
1185       if ((i % 4) == 0 && i > 0)
1186         {
1187           buf[n] = ' ';
1188           n++;
1189         }
1190       buf[n] = nameX[s[i] >> 4];
1191       buf[n + 1] = nameX[s[i] & 0xf];
1192       buf[posCh + i] = isprint (s[i]) ? s[i] : ' ';
1193     }
1194   buf[posCh + i] = 0;
1195   for (i = n; i < posCh; i++)
1196     buf[i] = ' ';
1197 }
1198
1199 static void
1200 dumpArr (unsigned char *s, int len, int col, int num)
1201 {
1202   unsigned char buf[128];
1203   if (col <= 0)
1204     return;
1205   for (int i = 0; i < len; i += col, num += col)
1206     {
1207       fillBuf (s + i, len - i, col, buf);
1208       Dprintf (DUMP_DWARFLIB, "%5d: %s\n", num, buf);
1209     }
1210 }
1211
1212 void
1213 DwrSec::dump (char *msg)
1214 {
1215   if (sizeSec > 0)
1216     {
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"));
1222     }
1223 }
1224
1225 //////////////////////////////////////////////////////////
1226 //  class DwrFileNames
1227
1228 DwrFileName::DwrFileName (char *_fname)
1229 {
1230   path = NULL;
1231   fname = _fname;
1232   dir_index = 0;
1233   timestamp = 0;
1234   file_size = 0;
1235   isUsed = false;
1236 }
1237
1238 DwrFileName::~DwrFileName ()
1239 {
1240   if (path != fname)
1241     free (path);
1242 }
1243
1244
1245 //////////////////////////////////////////////////////////
1246 //  class DwrLine
1247 DwrLine::DwrLine ()
1248 {
1249   address = 0;
1250   file = 0;
1251   line = 0;
1252   column = 0;
1253 }
1254
1255 DwrLine::~DwrLine () { }
1256
1257
1258 //////////////////////////////////////////////////////////
1259 //  class DwrLineRegs
1260 static int
1261 LineRegsCmp (const void *a, const void *b)
1262 {
1263   DwrLine *item1 = *((DwrLine **) a);
1264   DwrLine *item2 = *((DwrLine **) b);
1265   return item1->address == item2->address ? 0 :
1266           item1->address > item2->address ? 1 : -1;
1267 }
1268
1269 DwrLineRegs::DwrLineRegs (DwrSec *secp, char *dirName)
1270 {
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);
1292
1293   if (DUMP_DWR_LINE_REGS)
1294     {
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]);
1313     }
1314
1315   include_directories = new Vector<char *>;
1316   include_directories->append (dirName);
1317   while (true)
1318     {
1319       char *s = debug_lineSec->GetString (NULL);
1320       if (s == NULL)
1321         break;
1322       include_directories->append (s);
1323     }
1324
1325   file_names = new Vector<DwrFileName *>;
1326   while (true)
1327     {
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);
1338     }
1339   lines = NULL;
1340   dump ();
1341 }
1342
1343 DwrLineRegs::~DwrLineRegs ()
1344 {
1345   Destroy (file_names);
1346   Destroy (lines);
1347   delete debug_lineSec;
1348   delete include_directories;
1349 }
1350
1351 void
1352 DwrLineRegs::dump ()
1353 {
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++)
1358     {
1359       char *s = include_directories->get (i);
1360       Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %s\n"), (long long) i, STR (s));
1361     }
1362
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++)
1365     {
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);
1370     }
1371   if (lines)
1372     lines->dump (fname);
1373   Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\n\n"));
1374 }
1375
1376 void
1377 DwrLineRegs::DoExtendedOpcode ()
1378 {
1379   uint64_t size = debug_lineSec->GetULEB128 ();
1380   if (size == 0)
1381     {
1382       Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), NTXT ("ExtendedOpCode: size=0"));
1383       return;
1384     }
1385   Dwarf_Small opcode = debug_lineSec->Get_8 ();
1386   Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), extended_opcode2str (opcode));
1387   switch (opcode)
1388     {
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;
1406     }
1407 }
1408
1409 void
1410 DwrLineRegs::DoStandardOpcode (int opcode)
1411 {
1412   switch (opcode)
1413     {
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;
1446     }
1447 }
1448
1449 void
1450 DwrLineRegs::DoSpecialOpcode (int opcode)
1451 {
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 ();
1460 }
1461
1462 void
1463 DwrLineRegs::reset ()
1464 {
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;
1475 }
1476
1477 void
1478 DwrLineRegs::EmitLine ()
1479 {
1480   DwrLine *lnp = new DwrLine;
1481
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)))
1488     {
1489       DwrFileName *fnp = file_names->get (file);
1490       fnp->isUsed = true;
1491     }
1492 }
1493
1494 Vector<DwrLine *> *
1495 DwrLineRegs::get_lines ()
1496 {
1497   if (lines == NULL)
1498     {
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)
1504         {
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)
1511             {
1512               DoStandardOpcode (opcode);
1513               Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), standard_opcode2str (opcode));
1514             }
1515           else
1516             {
1517               DoSpecialOpcode (opcode - opcode_base);
1518               Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"),
1519                        special_opcode2str (opcode - opcode_base));
1520             }
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');
1526         }
1527       lines->sort (LineRegsCmp);
1528       if (DUMP_DWR_LINE_REGS)
1529         lines->dump (fname);
1530     }
1531   return lines;
1532 }
1533
1534 char *
1535 DwrLineRegs::getPath (int fn)
1536 {
1537   fn--;
1538   if ((fn >= VecSize (file_names)) || (fn < 0))
1539     {
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;
1543     }
1544   DwrFileName *fnp = file_names->fetch (fn);
1545   if (fnp->path)
1546     return fnp->path;
1547
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))
1551     {
1552       fnp->path = fnp->fname;
1553       return fnp->path;
1554     }
1555
1556   StringBuilder sb;
1557   if (*dir != '/')
1558     { // not absolute
1559       char *s = include_directories->fetch (0);
1560       sb.append (s);
1561       sb.append ('/');
1562     }
1563   sb.append (dir);
1564   sb.append ('/');
1565   sb.append (fnp->fname);
1566   fnp->path = canonical_path (sb.toString ());
1567   return fnp->path;
1568 }
1569
1570 DwrCU::DwrCU (Dwarf *_dwarf)
1571 {
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)
1577     {
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;
1582     }
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;
1598
1599   build_abbrevTable (dwarf->debug_abbrevSec, debug_abbrev_offset);
1600 #ifdef DEBUG
1601   if (DUMP_DWARFLIB)
1602     {
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++)
1625         {
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++)
1632             {
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));
1637             }
1638         }
1639     }
1640 #endif
1641 }
1642
1643 DwrCU::~DwrCU ()
1644 {
1645   delete debug_infoSec;
1646   delete abbrevTable;
1647   delete abbrevAtForm;
1648   Destroy (dwrInlinedSubrs);
1649   delete srcFiles;
1650   delete dwrLineReg;
1651   free (comp_dir);
1652 }
1653
1654 void
1655 DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
1656 {
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++)
1665     {
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)
1672         {
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;
1677         }
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)
1682         {
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);
1689         }
1690       abbTbl.lastAtForm = abbrevAtForm->size ();
1691       abbrevTable->append (abbTbl);
1692     }
1693   delete debug_abbrevSec;
1694 }
1695
1696 int
1697 DwrCU::set_die (Dwarf_Die die)
1698 {
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;
1717     }
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++)
1723     {
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)
1729         {
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)
1786             {
1787               atf->u.str = NULL;
1788               atf->len = 0;
1789             }
1790           else
1791             {
1792               dwarf->debug_strSec->offset = atf->u.offset;
1793               atf->u.str = dwarf->debug_strSec->GetString (&atf->len);
1794             }
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
1820           {
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);
1824           }
1825           atf->u.str = NULL;
1826           atf->len = 0;
1827           break;
1828         }
1829     }
1830   dwrTag.dump ();
1831   return DW_DLV_OK;
1832 }
1833
1834 static char *
1835 composePath (char *dname, char *fname)
1836 {
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);
1843 }
1844
1845 Module *
1846 DwrCU::parse_cu_header (LoadObject *lo)
1847 {
1848   // Is tag always DW_TAG_compile_unit?
1849   if (dwrTag.tag != DW_TAG_compile_unit)
1850     {
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;
1855     }
1856
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);
1865
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);
1878
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)
1882     {
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);
1888     }
1889   else
1890     path = dbe_strdup (dwarf->stabs->path);
1891   module->set_name (path);
1892   return module;
1893 }
1894
1895 Dwr_Attr *
1896 Dwr_Tag::get_attr (Dwarf_Half attr)
1897 {
1898   for (long i = firstAttribute; i < lastAttribute; i++)
1899     {
1900       Dwr_Attr *atf = abbrevAtForm->get (i);
1901       if (atf->at_name == attr)
1902         return atf;
1903     }
1904   return NULL;
1905 }
1906
1907 char *
1908 DwrCU::Dwarf_string (Dwarf_Half attr)
1909 {
1910   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1911   return dwrAttr ? dwrAttr->u.str : NULL;
1912 }
1913
1914 uint64_t
1915 DwrCU::get_high_pc (uint64_t low_pc)
1916 {
1917   Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_high_pc);
1918   if (dwrAttr)
1919     switch (dwrAttr->at_form)
1920       {
1921       case DW_FORM_addr:
1922         return dwrAttr->u.offset;
1923       default:
1924         return dwrAttr->u.offset + low_pc;
1925       }
1926   return 0;
1927 }
1928
1929 Dwarf_Addr
1930 DwrCU::Dwarf_addr (Dwarf_Half attr)
1931 {
1932   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1933   if (dwrAttr)
1934     switch (dwrAttr->at_form)
1935       {
1936       case DW_FORM_addr:
1937         return dwrAttr->u.offset;
1938       }
1939   return 0;
1940 }
1941
1942 DwrSec*
1943 DwrCU::Dwarf_block (Dwarf_Half attr)
1944 {
1945   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1946   if (dwrAttr && dwrAttr->u.block)
1947     switch (dwrAttr->at_form)
1948       {
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);
1956       }
1957   return NULL;
1958 }
1959
1960 int
1961 DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
1962 {
1963   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1964   if (dwrAttr)
1965     switch (dwrAttr->at_form)
1966       {
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;
1975
1976       }
1977   return DW_DLV_ERROR;
1978 }
1979
1980 int
1981 DwrCU::read_ref_attr (Dwarf_Half attr, int64_t *retVal)
1982 {
1983   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
1984   if (dwrAttr)
1985     switch (dwrAttr->at_form)
1986       {
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;
1997       }
1998   return DW_DLV_ERROR;
1999 }
2000
2001 int64_t
2002 DwrCU::Dwarf_data (Dwarf_Half attr)
2003 {
2004   int64_t retVal;
2005   if (read_data_attr (attr, &retVal) == DW_DLV_OK)
2006     return retVal;
2007   return 0;
2008 }
2009
2010 int64_t
2011 DwrCU::Dwarf_ref (Dwarf_Half attr)
2012 {
2013   int64_t retVal;
2014   if (read_ref_attr (attr, &retVal) == DW_DLV_OK)
2015     return retVal;
2016   return 0;
2017 }
2018
2019 Dwarf_Addr
2020 DwrCU::Dwarf_location (Dwarf_Attribute attr)
2021 {
2022   DwrSec *secp = Dwarf_block (attr);
2023   if (secp)
2024     {
2025       DwrLocation loc;
2026       DwrLocation *lp = dwr_get_location (secp, &loc);
2027       delete secp;
2028       if (lp)
2029         return lp->lc_number;
2030     }
2031   return 0;
2032 }
2033
2034 void
2035 DwrCU::map_dwarf_lines (Module *mod)
2036 {
2037   DwrLineRegs *lineReg = get_dwrLineReg ();
2038   long inlinedSubrCnt = VecSize (dwrInlinedSubrs);
2039   if (isGNU && (inlinedSubrCnt > 0))
2040     {
2041       Function *func = NULL;
2042       mod->inlinedSubr = (InlinedSubr *) malloc (inlinedSubrCnt
2043                                                  * sizeof (InlinedSubr));
2044       for (long i = 0; i < inlinedSubrCnt; i++)
2045         {
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)
2053             {
2054               func = f;
2055               func->inlinedSubrCnt = 0;
2056               func->inlinedSubr = mod->inlinedSubr + i;
2057             }
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));
2074         }
2075     }
2076   Vector<DwrLine *> *lines = lineReg->get_lines ();
2077
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++)
2084     {
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)
2092         {
2093           path = filename;
2094           char *name = StrChr (path, ':');
2095           SourceFile *src = mod->setIncludeFile (name);
2096           if (cur_src != src)
2097             {
2098               includes->new_src_file (src, lineno, cur_func);
2099               cur_src = src;
2100             }
2101         }
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))
2105         {
2106           if (func != cur_func)
2107             {
2108               if (cur_func)
2109                 while (cur_func->popSrcFile () != NULL)
2110                   ;
2111               cur_func = func;
2112               includes->push_src_files (cur_func);
2113             }
2114           cur_func->add_PC_info (pc - low_pc, lineno);
2115         }
2116     }
2117   if (cur_func)
2118     while (cur_func->popSrcFile ())
2119       ;
2120   delete includes;
2121 }
2122
2123 DwrLineRegs *
2124 DwrCU::get_dwrLineReg ()
2125 {
2126   if (dwrLineReg == NULL)
2127     dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
2128                                               stmt_list_offset), comp_dir);
2129   return dwrLineReg;
2130 }
2131
2132 void
2133 DwrCU::parse_inlined_subroutine (Dwarf_cnt *ctx)
2134 {
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;
2140
2141   if (dwrInlinedSubrs == NULL)
2142     dwrInlinedSubrs = new Vector<DwrInlinedSubr*>;
2143   Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges);
2144   if (dwrAttr)
2145     {
2146       uint64_t ranges = Dwarf_ref (DW_AT_ranges);
2147       if (dwarf->debug_rangesSec && (ranges < dwarf->debug_rangesSec->size))
2148         {
2149           dwarf->debug_rangesSec->offset = ranges;
2150           for (;;)
2151             {
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))
2155                 {
2156                   DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin,
2157                                         low_pc, high_pc, fileno, lineno, level);
2158                   dwrInlinedSubrs->append (p);
2159                   ctx->inlinedSubr = p;
2160                 }
2161               else
2162                 break;
2163             }
2164         }
2165     }
2166   else
2167     {
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))
2171         {
2172           DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin, low_pc,
2173                                                 high_pc, fileno, lineno, level);
2174           dwrInlinedSubrs->append (p);
2175           ctx->inlinedSubr = p;
2176         }
2177     }
2178   parseChild (ctx);
2179   ctx->inlinedSubr = inlinedSubr_old;
2180 }
2181
2182
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)
2187 {
2188   abstract_origin = _abstract_origin;
2189   low_pc = _low_pc;
2190   high_pc = _high_pc;
2191   file = _file;
2192   line = _line;
2193   level = _level;
2194 }
2195
2196 void
2197 DwrInlinedSubr::dump ()
2198 {
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);
2203 }
This page took 0.143723 seconds and 4 git commands to generate.