xref: /netbsd-src/external/gpl3/binutils/dist/gprofng/src/DwarfLib.cc (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* Copyright (C) 2021-2024 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 NO_STMT_LIST ((uint64_t) -1)
35 #define CASE_S(x)   case x: s = (char *) #x; break
36 
37 static char *
gelf_st_type2str(int type)38 gelf_st_type2str (int type)
39 {
40   static char buf[128];
41   char *s;
42   switch (type)
43     {
44       CASE_S (STT_NOTYPE);
45       CASE_S (STT_OBJECT);
46       CASE_S (STT_FUNC);
47       CASE_S (STT_SECTION);
48       CASE_S (STT_FILE);
49       CASE_S (STT_COMMON);
50       CASE_S (STT_TLS);
51       //    CASE_S(STT_NUM);
52       CASE_S (STT_LOPROC);
53       CASE_S (STT_HIPROC);
54     default: s = NTXT ("???");
55       break;
56     }
57   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type);
58   buf[sizeof (buf) - 1] = 0;
59   return buf;
60 }
61 
62 static char *
special_opcode2str(int opcode)63 special_opcode2str (int opcode)
64 {
65   static char buf[128];
66   snprintf (buf, sizeof (buf), NTXT ("SpecialOpcode: %3d"), opcode);
67   buf[sizeof (buf) - 1] = 0;
68   return buf;
69 }
70 
71 static char *
extended_opcode2str(int opcode)72 extended_opcode2str (int opcode)
73 {
74   static char buf[128];
75   char *s;
76   switch (opcode)
77     {
78       CASE_S (DW_LNE_end_sequence);
79       CASE_S (DW_LNE_set_address);
80       CASE_S (DW_LNE_define_file);
81     default:
82       snprintf (buf, sizeof (buf), NTXT ("??? (%d)"), opcode);
83       buf[sizeof (buf) - 1] = 0;
84       s = buf;
85       break;
86     }
87   return s;
88 }
89 
90 static char *
standard_opcode2str(int opcode)91 standard_opcode2str (int opcode)
92 {
93   static char buf[128];
94   char *s;
95   switch (opcode)
96     {
97       CASE_S (DW_LNS_copy);
98       CASE_S (DW_LNS_advance_pc);
99       CASE_S (DW_LNS_advance_line);
100       CASE_S (DW_LNS_set_file);
101       CASE_S (DW_LNS_set_column);
102       CASE_S (DW_LNS_negate_stmt);
103       CASE_S (DW_LNS_set_basic_block);
104       CASE_S (DW_LNS_const_add_pc);
105       CASE_S (DW_LNS_fixed_advance_pc);
106     default:
107       snprintf (buf, sizeof (buf), NTXT ("??? (%d)"), opcode);
108       buf[sizeof (buf) - 1] = 0;
109       s = buf;
110       break;
111     }
112   return s;
113 }
114 
115 template<> void Vector<DwrInlinedSubr *>
dump(const char * msg)116 ::dump (const char *msg)
117 {
118   Dprintf (1, NTXT ("%s Vector<DwrInlinedSubr *> [%lld]\n"),
119 	   msg ? msg : NTXT (""), (long long) size ());
120   for (long i = 0, sz = size (); i < sz; i++)
121     {
122       DwrInlinedSubr *p = get (i);
123       Dprintf (1, NTXT ("%ld: "), (long) i);
124       p->dump ();
125     }
126 }
127 
128 template<> void Vector<DwrLine *>
dump(const char * msg)129 ::dump (const char *msg)
130 {
131   Dprintf (1, "%s Vector<DwrLine *> [%lld]:\n    address [file line column]\n",
132 	   msg ? msg : NTXT (""), (long long) size ());
133   for (long i = 0, sz = size (); i < sz; i++)
134     {
135       DwrLine *lnp = get (i);
136       Dprintf (1, NTXT (" %2lld 0x%08llx  [ %2lld, %lld, %lld ] \n"),
137 	       (long long) i, (long long) lnp->address, (long long) lnp->file,
138 	       (long long) lnp->line, (long long) lnp->column);
139     }
140   Dprintf (1, NTXT ("\n\n"));
141 }
142 
143 template<> void Vector<DwrFileName *>
dump(const char * msg)144 ::dump (const char *msg)
145 {
146   Dprintf (1, "\n%s Vector<DwrFileName *> [%lld]:  [dir_ind tstamp fsize]\n",
147 	   msg ? msg : NTXT (""), (long long) size ());
148   for (long i = 0, sz = size (); i < sz; i++)
149     {
150       DwrFileName *fnp = get (i);
151       Dprintf (1, " %2ld %3lld %8lld %8lld %s\n", i, (long long) fnp->dir_index,
152 	       (long long) fnp->timestamp, (long long) fnp->file_size,
153 	       STR (fnp->fname));
154     }
155   Dprintf (1, "\n");
156 }
157 
158 static char *
get_string(DwrSec * sec,uint64_t off)159 get_string (DwrSec *sec, uint64_t off)
160 {
161   if (sec)
162     {
163       sec->offset = off;
164       return sec->GetString ();
165     }
166   return NULL;
167 }
168 
169 
170 //////////////////////////////////////////////////////////
171 //  class ElfReloc
172 
ElfReloc(Elf * _elf)173 ElfReloc::ElfReloc (Elf *_elf)
174 {
175   elf = _elf;
176   reloc = NULL;
177   cur_reloc_ind = 0;
178 }
179 
~ElfReloc()180 ElfReloc::~ElfReloc ()
181 {
182   if (reloc)
183     {
184       reloc->destroy ();
185       delete reloc;
186     }
187 }
188 
189 void
dump_rela_debug_sec(int sec)190 ElfReloc::dump_rela_debug_sec (int sec)
191 {
192   if (!DUMP_RELA_SEC)
193     return;
194   Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
195   if (shdr == NULL)
196     return;
197 
198   Elf_Data *data = elf->elf_getdata (sec);
199   if (data == NULL)
200     return;
201 
202   uint64_t ScnSize = data->d_size;
203   uint64_t EntSize = shdr->sh_entsize;
204   if (ScnSize == 0 || EntSize == 0)
205     return;
206 
207   Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
208   if (shdr_sym == NULL)
209     return;
210   Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
211   Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
212   char *Strtab = data_str ? (char*) data_str->d_buf : NULL;
213   Elf_Internal_Rela rela;
214   int n, cnt = (int) (ScnSize / EntSize);
215 
216   char *sec_name = elf->get_sec_name (sec);
217   if (sec_name == NULL) // It can not be, but let's check
218     return;
219   Dprintf (DUMP_RELA_SEC,
220 	   "======= DwarfLib::dump_rela_debug_sec  Section:%2d  '%s'\n",
221 	   sec, sec_name);
222   Dprintf (DUMP_RELA_SEC,
223 	   " N |addend|   offset   |       r_info      |    stt_type   |\n");
224   for (n = 0; n < cnt; n++)
225     {
226       if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
227 	elf->elf_getrela (data, n, &rela);
228       else
229 	{
230 	  elf->elf_getrel (data, n, &rela);
231 	  rela.r_addend = 0;
232 	}
233       int ndx = (int) GELF_R_SYM (rela.r_info);
234       Elf_Internal_Shdr *secHdr;
235       Elf_Internal_Sym sym;
236       elf->elf_getsym (data_sym, ndx, &sym);
237       Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
238 	       n, (int) rela.r_addend,
239 	       (long long) rela.r_offset, (long long) rela.r_info,
240 	       gelf_st_type2str ((int) GELF_ST_TYPE (sym.st_info)));
241       switch (GELF_ST_TYPE (sym.st_info))
242 	{
243 	case STT_FUNC:
244 	case STT_OBJECT:
245 	case STT_NOTYPE:
246 	  secHdr = elf->get_shdr (sym.st_shndx);
247 	  if (secHdr)
248 	    Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
249 		     (long long) (sym.st_value + secHdr->sh_offset));
250 	  if (Strtab && sym.st_name)
251 	    Dprintf (DUMP_RELA_SEC, NTXT ("  %s"), Strtab + sym.st_name);
252 	  break;
253 	case STT_SECTION:
254 	  secHdr = elf->get_shdr (sym.st_shndx);
255 	  if (secHdr)
256 	    {
257 	      Dprintf (DUMP_RELA_SEC, NTXT ("       value=0x%016llx (%lld)"),
258 		       (long long) (secHdr->sh_offset + rela.r_addend),
259 		       (long long) (secHdr->sh_offset + rela.r_addend));
260 	    }
261 	  break;
262 	default:
263 	  break;
264 	}
265       Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
266     }
267   Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
268 }
269 
270 void
dump()271 ElfReloc::dump ()
272 {
273   if (!DUMP_ELF_RELOC || (reloc == NULL) || (reloc->size () == 0))
274     return;
275   Dprintf (DUMP_ELF_RELOC, NTXT ("======= ElfReloc::dump\n"));
276   Dprintf (DUMP_ELF_RELOC, NTXT (" N |   offset   |    value   | STT_TYPE\n"));
277   for (int i = 0; i < reloc->size (); i++)
278     {
279       Sreloc *srlc = reloc->fetch (i);
280       Dprintf (DUMP_ELF_RELOC, NTXT ("%3d:%11lld |%11lld | %s\n"),
281 	       i, (long long) srlc->offset, (long long) srlc->value,
282 	       gelf_st_type2str (srlc->stt_type));
283     }
284   Dprintf (DUMP_ELF_RELOC, NTXT ("\n"));
285 }
286 
287 static int
DwrRelocOffsetCmp(const void * a,const void * b)288 DwrRelocOffsetCmp (const void *a, const void *b)
289 {
290   ElfReloc::Sreloc *item1 = *((ElfReloc::Sreloc **) a);
291   ElfReloc::Sreloc *item2 = *((ElfReloc::Sreloc **) b);
292   return item1->offset < item2->offset ? -1 :
293 	 item1->offset == item2->offset ? 0 : 1;
294 }
295 
296 ElfReloc *
get_elf_reloc(Elf * elfp,char * sec_name,ElfReloc * rlc)297 ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
298 {
299   int et = elfp->elf_getehdr ()->e_type;
300   if (et == ET_EXEC || et == ET_DYN)
301     return rlc;
302   int sec = elfp->elf_get_sec_num (sec_name);
303   if (sec == 0)
304     return rlc;
305   Elf_Internal_Shdr *shdr = elfp->get_shdr (sec);
306   if (shdr == NULL || shdr->sh_entsize == 0)
307     return rlc;
308 
309   Elf_Data *data = elfp->elf_getdata (sec);
310   if (data == NULL || data->d_size == 0)
311     return rlc;
312 
313   int cnt = (int) (data->d_size / shdr->sh_entsize);
314   Elf_Internal_Shdr *shdr_sym = elfp->get_shdr (shdr->sh_link);
315   if (shdr_sym == NULL)
316     return rlc;
317   Elf_Data *data_sym = elfp->elf_getdata (shdr->sh_link);
318   Vector<Sreloc *> *vp = NULL;
319 
320   for (int n = 0; n < cnt; n++)
321     {
322       Elf_Internal_Shdr *secHdr;
323       Sreloc *srlc;
324       Elf_Internal_Rela rela;
325       if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
326 	elfp->elf_getrela (data, n, &rela);
327       else
328 	{
329 	  elfp->elf_getrel (data, n, &rela);
330 	  rela.r_addend = 0;
331 	}
332       int ndx = (int) GELF_R_SYM (rela.r_info);
333       Elf_Internal_Sym sym;
334       elfp->elf_getsym (data_sym, ndx, &sym);
335 
336       srlc = new Sreloc;
337       srlc->offset = rela.r_offset;
338       srlc->value = 0;
339       srlc->stt_type = (int) GELF_ST_TYPE (sym.st_info);
340       switch (GELF_ST_TYPE (sym.st_info))
341 	{
342 	case STT_FUNC:
343 	  secHdr = elfp->get_shdr (sym.st_shndx);
344 	  if (secHdr)
345 	    srlc->value = secHdr->sh_offset + sym.st_value;
346 	  break;
347 	case STT_OBJECT:
348 	case STT_NOTYPE:
349 	  secHdr = elfp->get_shdr (shdr->sh_info);
350 	  if (secHdr)
351 	    {
352 	      srlc->offset = rela.r_info;
353 	      srlc->value = secHdr->sh_offset + rela.r_addend;
354 	    }
355 	  break;
356 	case STT_SECTION:
357 	  secHdr = elfp->get_shdr (sym.st_shndx);
358 	  if (secHdr)
359 	    srlc->value = rela.r_addend;
360 	  break;
361 	default:
362 	  srlc->value = 0;
363 	  break;
364 	}
365       if (rlc == NULL)
366 	{
367 	  rlc = new ElfReloc (elfp);
368 	  vp = rlc->reloc;
369 	}
370       if (vp == NULL)
371 	{
372 	  vp = new Vector<Sreloc*>;
373 	  rlc->reloc = vp;
374 	}
375       vp->append (srlc);
376     }
377   if (vp)
378     vp->sort (DwrRelocOffsetCmp);
379   if (rlc)
380     {
381       rlc->dump_rela_debug_sec (sec);
382       rlc->dump ();
383     }
384   return rlc;
385 }
386 
387 long long
get_reloc_addr(long long offset)388 ElfReloc::get_reloc_addr (long long offset)
389 {
390   Sreloc *srlc;
391   int i = cur_reloc_ind - 1;
392   if (i >= 0 && i < reloc->size ())
393     {
394       srlc = reloc->fetch (i);
395       if (srlc->offset > offset)  // need to reset
396 	cur_reloc_ind = 0;
397     }
398   for (; cur_reloc_ind < reloc->size (); cur_reloc_ind++)
399     {
400       srlc = reloc->fetch (cur_reloc_ind);
401       if (srlc->offset == offset)
402 	return srlc->value;
403       if (srlc->offset > offset)
404 	return 0;
405     }
406   return 0;
407 }
408 
409 DwrLocation *
dwr_get_location(DwrSec * secp,DwrLocation * lp)410 DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp)
411 {
412   lp->offset = secp->offset;
413   lp->lc_number = 0;
414   lp->lc_number2 = 0;
415   lp->op = secp->Get_8 ();
416   switch (lp->op)
417     {
418       // registers
419     case DW_OP_reg0:
420     case DW_OP_reg1:
421     case DW_OP_reg2:
422     case DW_OP_reg3:
423     case DW_OP_reg4:
424     case DW_OP_reg5:
425     case DW_OP_reg6:
426     case DW_OP_reg7:
427     case DW_OP_reg8:
428     case DW_OP_reg9:
429     case DW_OP_reg10:
430     case DW_OP_reg11:
431     case DW_OP_reg12:
432     case DW_OP_reg13:
433     case DW_OP_reg14:
434     case DW_OP_reg15:
435     case DW_OP_reg16:
436     case DW_OP_reg17:
437     case DW_OP_reg18:
438     case DW_OP_reg19:
439     case DW_OP_reg20:
440     case DW_OP_reg21:
441     case DW_OP_reg22:
442     case DW_OP_reg23:
443     case DW_OP_reg24:
444     case DW_OP_reg25:
445     case DW_OP_reg26:
446     case DW_OP_reg27:
447     case DW_OP_reg28:
448     case DW_OP_reg29:
449     case DW_OP_reg30:
450     case DW_OP_reg31:
451       break;
452     case DW_OP_regx:
453       lp->lc_number = secp->GetULEB128 ();
454       break;
455     case DW_OP_breg0:
456     case DW_OP_breg1:
457     case DW_OP_breg2:
458     case DW_OP_breg3:
459     case DW_OP_breg4:
460     case DW_OP_breg5:
461     case DW_OP_breg6:
462     case DW_OP_breg7:
463     case DW_OP_breg8:
464     case DW_OP_breg9:
465     case DW_OP_breg10:
466     case DW_OP_breg11:
467     case DW_OP_breg12:
468     case DW_OP_breg13:
469     case DW_OP_breg14:
470     case DW_OP_breg15:
471     case DW_OP_breg16:
472     case DW_OP_breg17:
473     case DW_OP_breg18:
474     case DW_OP_breg19:
475     case DW_OP_breg20:
476     case DW_OP_breg21:
477     case DW_OP_breg22:
478     case DW_OP_breg23:
479     case DW_OP_breg24:
480     case DW_OP_breg25:
481     case DW_OP_breg26:
482     case DW_OP_breg27:
483     case DW_OP_breg28:
484     case DW_OP_breg29:
485     case DW_OP_breg30:
486     case DW_OP_breg31:
487       lp->lc_number = secp->GetSLEB128 ();
488       break;
489     case DW_OP_fbreg:
490       lp->lc_number = secp->GetSLEB128 ();
491       break;
492     case DW_OP_bregx:
493       lp->lc_number = secp->GetULEB128 ();
494       lp->lc_number2 = secp->GetSLEB128 ();
495       break;
496     case DW_OP_lit0:
497     case DW_OP_lit1:
498     case DW_OP_lit2:
499     case DW_OP_lit3:
500     case DW_OP_lit4:
501     case DW_OP_lit5:
502     case DW_OP_lit6:
503     case DW_OP_lit7:
504     case DW_OP_lit8:
505     case DW_OP_lit9:
506     case DW_OP_lit10:
507     case DW_OP_lit11:
508     case DW_OP_lit12:
509     case DW_OP_lit13:
510     case DW_OP_lit14:
511     case DW_OP_lit15:
512     case DW_OP_lit16:
513     case DW_OP_lit17:
514     case DW_OP_lit18:
515     case DW_OP_lit19:
516     case DW_OP_lit20:
517     case DW_OP_lit21:
518     case DW_OP_lit22:
519     case DW_OP_lit23:
520     case DW_OP_lit24:
521     case DW_OP_lit25:
522     case DW_OP_lit26:
523     case DW_OP_lit27:
524     case DW_OP_lit28:
525     case DW_OP_lit29:
526     case DW_OP_lit30:
527     case DW_OP_lit31:
528       lp->lc_number = lp->op - DW_OP_lit0;
529       break;
530     case DW_OP_addr:
531       lp->lc_number = secp->GetADDR ();
532       break;
533     case DW_OP_const1u:
534       lp->lc_number = secp->Get_8 ();
535       break;
536     case DW_OP_const1s:
537       {
538 	signed char x;
539 	x = secp->Get_8 ();
540 	lp->lc_number = x;
541       }
542       break;
543     case DW_OP_const2u:
544       lp->lc_number = secp->Get_16 ();
545       break;
546     case DW_OP_const2s:
547       {
548 	signed short x;
549 	x = secp->Get_16 ();
550 	lp->lc_number = x;
551       }
552       break;
553     case DW_OP_const4u:
554       lp->lc_number = secp->Get_32 ();
555       break;
556     case DW_OP_const4s:
557       {
558 	signed int x;
559 	x = secp->Get_32 ();
560 	lp->lc_number = x;
561       }
562       break;
563     case DW_OP_const8u:
564       lp->lc_number = secp->Get_64 ();
565       break;
566     case DW_OP_const8s:
567       {
568 	signed long long x;
569 	x = secp->Get_64 ();
570 	lp->lc_number = x;
571       }
572       break;
573     case DW_OP_plus_uconst:
574     case DW_OP_constu:
575       lp->lc_number = secp->GetULEB128 ();
576       break;
577     case DW_OP_consts:
578       lp->lc_number = secp->GetSLEB128 ();
579       break;
580 
581       // Stack operations
582     case DW_OP_pick:
583     case DW_OP_deref_size:
584     case DW_OP_xderef_size:
585       lp->lc_number = secp->Get_8 ();
586       break;
587     case DW_OP_dup:
588     case DW_OP_drop:
589     case DW_OP_over:
590     case DW_OP_swap:
591     case DW_OP_rot:
592     case DW_OP_deref:
593     case DW_OP_xderef:
594       // Arithmetic and Logical Operations
595     case DW_OP_abs:
596     case DW_OP_and:
597     case DW_OP_div:
598     case DW_OP_minus:
599     case DW_OP_mod:
600     case DW_OP_mul:
601     case DW_OP_neg:
602     case DW_OP_not:
603     case DW_OP_or:
604     case DW_OP_plus:
605     case DW_OP_shl:
606     case DW_OP_shr:
607     case DW_OP_shra:
608     case DW_OP_xor:
609     case DW_OP_le:
610     case DW_OP_ge:
611     case DW_OP_eq:
612     case DW_OP_lt:
613     case DW_OP_gt:
614     case DW_OP_ne:
615     case DW_OP_nop:
616       break;
617     case DW_OP_skip:
618     case DW_OP_bra:
619       lp->lc_number = secp->Get_16 ();
620       break;
621     case DW_OP_piece:
622       lp->lc_number = secp->GetULEB128 ();
623       break;
624     case DW_OP_push_object_address: /* DWARF3 */
625       break;
626     case DW_OP_call2: /* DWARF3 */
627       lp->lc_number = secp->Get_16 ();
628       break;
629     case DW_OP_call4: /* DWARF3 */
630       lp->lc_number = secp->Get_32 ();
631       break;
632     case DW_OP_call_ref: /* DWARF3 */
633       lp->lc_number = secp->GetADDR ();
634       break;
635     default:
636       return (NULL);
637     }
638   return lp;
639 }
640 
641 char *
tag2str(int tag)642 DwrCU::tag2str (int tag)
643 {
644   static char buf[128];
645   char *s;
646 
647   switch (tag)
648     {
649       CASE_S (DW_TAG_array_type);
650       CASE_S (DW_TAG_class_type);
651       CASE_S (DW_TAG_entry_point);
652       CASE_S (DW_TAG_enumeration_type);
653       CASE_S (DW_TAG_formal_parameter);
654       CASE_S (DW_TAG_imported_declaration);
655       CASE_S (DW_TAG_label);
656       CASE_S (DW_TAG_lexical_block);
657       CASE_S (DW_TAG_member);
658       CASE_S (DW_TAG_pointer_type);
659       CASE_S (DW_TAG_reference_type);
660       CASE_S (DW_TAG_compile_unit);
661       CASE_S (DW_TAG_string_type);
662       CASE_S (DW_TAG_structure_type);
663       CASE_S (DW_TAG_subroutine_type);
664       CASE_S (DW_TAG_typedef);
665       CASE_S (DW_TAG_union_type);
666       CASE_S (DW_TAG_unspecified_parameters);
667       CASE_S (DW_TAG_variant);
668       CASE_S (DW_TAG_common_block);
669       CASE_S (DW_TAG_common_inclusion);
670       CASE_S (DW_TAG_inheritance);
671       CASE_S (DW_TAG_inlined_subroutine);
672       CASE_S (DW_TAG_module);
673       CASE_S (DW_TAG_ptr_to_member_type);
674       CASE_S (DW_TAG_set_type);
675       CASE_S (DW_TAG_subrange_type);
676       CASE_S (DW_TAG_with_stmt);
677       CASE_S (DW_TAG_access_declaration);
678       CASE_S (DW_TAG_base_type);
679       CASE_S (DW_TAG_catch_block);
680       CASE_S (DW_TAG_const_type);
681       CASE_S (DW_TAG_constant);
682       CASE_S (DW_TAG_enumerator);
683       CASE_S (DW_TAG_file_type);
684       CASE_S (DW_TAG_friend);
685       CASE_S (DW_TAG_namelist);
686       CASE_S (DW_TAG_namelist_item);
687       CASE_S (DW_TAG_packed_type);
688       CASE_S (DW_TAG_subprogram);
689       CASE_S (DW_TAG_template_type_param);
690       CASE_S (DW_TAG_template_value_param);
691       CASE_S (DW_TAG_thrown_type);
692       CASE_S (DW_TAG_try_block);
693       CASE_S (DW_TAG_variant_part);
694       CASE_S (DW_TAG_variable);
695       CASE_S (DW_TAG_volatile_type);
696       CASE_S (DW_TAG_dwarf_procedure);
697       CASE_S (DW_TAG_restrict_type);
698       CASE_S (DW_TAG_interface_type);
699       CASE_S (DW_TAG_namespace);
700       CASE_S (DW_TAG_imported_module);
701       CASE_S (DW_TAG_unspecified_type);
702       CASE_S (DW_TAG_partial_unit);
703       CASE_S (DW_TAG_imported_unit);
704       CASE_S (DW_TAG_lo_user);
705       CASE_S (DW_TAG_MIPS_loop);
706       CASE_S (DW_TAG_format_label);
707       CASE_S (DW_TAG_function_template);
708       CASE_S (DW_TAG_class_template);
709       CASE_S (DW_TAG_GNU_BINCL);
710       CASE_S (DW_TAG_GNU_EINCL);
711       CASE_S (DW_TAG_GNU_call_site);
712       CASE_S (DW_TAG_GNU_call_site_parameter);
713       CASE_S (DW_TAG_SUN_codeflags);
714       CASE_S (DW_TAG_SUN_memop_info);
715       CASE_S (DW_TAG_hi_user);
716       CASE_S (DW_TAG_icc_compile_unit);
717       CASE_S (DW_TAG_rvalue_reference_type);
718       CASE_S (DW_TAG_coarray_type);
719       CASE_S (DW_TAG_generic_subrange);
720       CASE_S (DW_TAG_dynamic_type);
721       CASE_S (DW_TAG_atomic_type);
722       CASE_S (DW_TAG_call_site);
723       CASE_S (DW_TAG_call_site_parameter);
724       CASE_S (DW_TAG_skeleton_unit);
725       CASE_S (DW_TAG_immutable_type);
726       CASE_S (0);
727     default: s = NTXT ("???");
728       break;
729     }
730   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
731   buf[sizeof (buf) - 1] = 0;
732   return buf;
733 }
734 
735 char *
at2str(int tag)736 DwrCU::at2str (int tag)
737 {
738   static char buf[128];
739   char *s;
740   switch (tag)
741     {
742       CASE_S (DW_AT_sibling);
743       CASE_S (DW_AT_location);
744       CASE_S (DW_AT_name);
745       CASE_S (DW_AT_ordering);
746       CASE_S (DW_AT_subscr_data);
747       CASE_S (DW_AT_byte_size);
748       CASE_S (DW_AT_bit_offset);
749       CASE_S (DW_AT_bit_size);
750       CASE_S (DW_AT_element_list);
751       CASE_S (DW_AT_stmt_list);
752       CASE_S (DW_AT_low_pc);
753       CASE_S (DW_AT_high_pc);
754       CASE_S (DW_AT_language);
755       CASE_S (DW_AT_member);
756       CASE_S (DW_AT_discr);
757       CASE_S (DW_AT_discr_value);
758       CASE_S (DW_AT_visibility);
759       CASE_S (DW_AT_import);
760       CASE_S (DW_AT_string_length);
761       CASE_S (DW_AT_common_reference);
762       CASE_S (DW_AT_comp_dir);
763       CASE_S (DW_AT_const_value);
764       CASE_S (DW_AT_containing_type);
765       CASE_S (DW_AT_default_value);
766       CASE_S (DW_AT_inline);
767       CASE_S (DW_AT_is_optional);
768       CASE_S (DW_AT_lower_bound);
769       CASE_S (DW_AT_producer);
770       CASE_S (DW_AT_prototyped);
771       CASE_S (DW_AT_return_addr);
772       CASE_S (DW_AT_start_scope);
773       CASE_S (DW_AT_stride_size);
774       CASE_S (DW_AT_upper_bound);
775       CASE_S (DW_AT_abstract_origin);
776       CASE_S (DW_AT_accessibility);
777       CASE_S (DW_AT_address_class);
778       CASE_S (DW_AT_artificial);
779       CASE_S (DW_AT_base_types);
780       CASE_S (DW_AT_calling_convention);
781       CASE_S (DW_AT_count);
782       CASE_S (DW_AT_data_member_location);
783       CASE_S (DW_AT_decl_column);
784       CASE_S (DW_AT_decl_file);
785       CASE_S (DW_AT_decl_line);
786       CASE_S (DW_AT_declaration);
787       CASE_S (DW_AT_discr_list);
788       CASE_S (DW_AT_encoding);
789       CASE_S (DW_AT_external);
790       CASE_S (DW_AT_frame_base);
791       CASE_S (DW_AT_friend);
792       CASE_S (DW_AT_identifier_case);
793       CASE_S (DW_AT_macro_info);
794       CASE_S (DW_AT_namelist_item);
795       CASE_S (DW_AT_priority);
796       CASE_S (DW_AT_segment);
797       CASE_S (DW_AT_specification);
798       CASE_S (DW_AT_static_link);
799       CASE_S (DW_AT_type);
800       CASE_S (DW_AT_use_location);
801       CASE_S (DW_AT_variable_parameter);
802       CASE_S (DW_AT_virtuality);
803       CASE_S (DW_AT_vtable_elem_location);
804       CASE_S (DW_AT_allocated);
805       CASE_S (DW_AT_associated);
806       CASE_S (DW_AT_data_location);
807       CASE_S (DW_AT_byte_stride);
808       CASE_S (DW_AT_entry_pc);
809       CASE_S (DW_AT_use_UTF8);
810       CASE_S (DW_AT_extension);
811       CASE_S (DW_AT_ranges);
812       CASE_S (DW_AT_trampoline);
813       CASE_S (DW_AT_call_column);
814       CASE_S (DW_AT_call_file);
815       CASE_S (DW_AT_call_line);
816       CASE_S (DW_AT_description);
817       CASE_S (DW_AT_binary_scale);
818       CASE_S (DW_AT_decimal_scale);
819       CASE_S (DW_AT_small);
820       CASE_S (DW_AT_decimal_sign);
821       CASE_S (DW_AT_digit_count);
822       CASE_S (DW_AT_picture_string);
823       CASE_S (DW_AT_mutable);
824       CASE_S (DW_AT_threads_scaled);
825       CASE_S (DW_AT_explicit);
826       CASE_S (DW_AT_object_pointer);
827       CASE_S (DW_AT_endianity);
828       CASE_S (DW_AT_elemental);
829       CASE_S (DW_AT_pure);
830       CASE_S (DW_AT_recursive);
831       CASE_S (DW_AT_signature);
832       CASE_S (DW_AT_main_subprogram);
833       CASE_S (DW_AT_data_bit_offset);
834       CASE_S (DW_AT_const_expr);
835       CASE_S (DW_AT_enum_class);
836       CASE_S (DW_AT_linkage_name);
837       CASE_S (DW_AT_lo_user);
838       CASE_S (DW_AT_MIPS_fde);
839       CASE_S (DW_AT_MIPS_loop_begin);
840       CASE_S (DW_AT_MIPS_tail_loop_begin);
841       CASE_S (DW_AT_MIPS_epilog_begin);
842       CASE_S (DW_AT_MIPS_loop_unroll_factor);
843       CASE_S (DW_AT_MIPS_software_pipeline_depth);
844       CASE_S (DW_AT_MIPS_linkage_name);
845       CASE_S (DW_AT_MIPS_stride);
846       CASE_S (DW_AT_MIPS_abstract_name);
847       CASE_S (DW_AT_MIPS_clone_origin);
848       CASE_S (DW_AT_MIPS_has_inlines);
849       CASE_S (DW_AT_sf_names);
850       CASE_S (DW_AT_src_info);
851       CASE_S (DW_AT_mac_info);
852       CASE_S (DW_AT_src_coords);
853       CASE_S (DW_AT_body_begin);
854       CASE_S (DW_AT_body_end);
855       CASE_S (DW_AT_GNU_vector);
856       CASE_S (DW_AT_GNU_guarded_by);
857       CASE_S (DW_AT_GNU_pt_guarded_by);
858       CASE_S (DW_AT_GNU_guarded);
859       CASE_S (DW_AT_GNU_pt_guarded);
860       CASE_S (DW_AT_GNU_locks_excluded);
861       CASE_S (DW_AT_GNU_exclusive_locks_required);
862       CASE_S (DW_AT_GNU_shared_locks_required);
863       CASE_S (DW_AT_GNU_odr_signature);
864       CASE_S (DW_AT_GNU_template_name);
865       CASE_S (DW_AT_GNU_call_site_value);
866       CASE_S (DW_AT_GNU_call_site_data_value);
867       CASE_S (DW_AT_GNU_call_site_target);
868       CASE_S (DW_AT_GNU_call_site_target_clobbered);
869       CASE_S (DW_AT_GNU_tail_call);
870       CASE_S (DW_AT_GNU_all_tail_call_sites);
871       CASE_S (DW_AT_GNU_all_call_sites);
872       CASE_S (DW_AT_GNU_all_source_call_sites);
873       CASE_S (DW_AT_GNU_locviews);
874       CASE_S (DW_AT_GNU_entry_view);
875       CASE_S (DW_AT_SUN_command_line);
876       CASE_S (DW_AT_SUN_func_offsets);
877       CASE_S (DW_AT_SUN_cf_kind);
878       CASE_S (DW_AT_SUN_func_offset);
879       CASE_S (DW_AT_SUN_memop_type_ref);
880       CASE_S (DW_AT_SUN_profile_id);
881       CASE_S (DW_AT_SUN_memop_signature);
882       CASE_S (DW_AT_SUN_obj_dir);
883       CASE_S (DW_AT_SUN_obj_file);
884       CASE_S (DW_AT_SUN_original_name);
885       CASE_S (DW_AT_SUN_link_name);
886       CASE_S (DW_AT_hi_user);
887       CASE_S (DW_AT_icc_flags);
888       CASE_S (DW_AT_string_length_bit_size);
889       CASE_S (DW_AT_string_length_byte_size);
890       CASE_S (DW_AT_rank);
891       CASE_S (DW_AT_str_offsets_base);
892       CASE_S (DW_AT_addr_base);
893       CASE_S (DW_AT_rnglists_base);
894       CASE_S (DW_AT_dwo_name);
895       CASE_S (DW_AT_reference);
896       CASE_S (DW_AT_rvalue_reference);
897       CASE_S (DW_AT_macros);
898       CASE_S (DW_AT_call_all_calls);
899       CASE_S (DW_AT_call_all_source_calls);
900       CASE_S (DW_AT_call_all_tail_calls);
901       CASE_S (DW_AT_call_return_pc);
902       CASE_S (DW_AT_call_value);
903       CASE_S (DW_AT_call_origin);
904       CASE_S (DW_AT_call_parameter);
905       CASE_S (DW_AT_call_pc);
906       CASE_S (DW_AT_call_tail_call);
907       CASE_S (DW_AT_call_target);
908       CASE_S (DW_AT_call_target_clobbered);
909       CASE_S (DW_AT_call_data_location);
910       CASE_S (DW_AT_call_data_value);
911       CASE_S (DW_AT_noreturn);
912       CASE_S (DW_AT_alignment);
913       CASE_S (DW_AT_export_symbols);
914       CASE_S (DW_AT_deleted);
915       CASE_S (DW_AT_defaulted);
916       CASE_S (DW_AT_loclists_base);
917 
918     default: s = NTXT ("???");
919       break;
920     }
921   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
922   buf[sizeof (buf) - 1] = 0;
923   return buf;
924 }
925 
926 char *
form2str(int tag)927 DwrCU::form2str (int tag)
928 {
929   static char buf[128];
930   char *s;
931   switch (tag)
932     {
933       CASE_S (DW_FORM_addr);
934       CASE_S (DW_FORM_block2);
935       CASE_S (DW_FORM_block4);
936       CASE_S (DW_FORM_data2);
937       CASE_S (DW_FORM_data4);
938       CASE_S (DW_FORM_data8);
939       CASE_S (DW_FORM_data16);
940       CASE_S (DW_FORM_line_strp);
941       CASE_S (DW_FORM_implicit_const);
942       CASE_S (DW_FORM_string);
943       CASE_S (DW_FORM_block);
944       CASE_S (DW_FORM_block1);
945       CASE_S (DW_FORM_data1);
946       CASE_S (DW_FORM_flag);
947       CASE_S (DW_FORM_sdata);
948       CASE_S (DW_FORM_strp);
949       CASE_S (DW_FORM_udata);
950       CASE_S (DW_FORM_ref_addr);
951       CASE_S (DW_FORM_ref1);
952       CASE_S (DW_FORM_ref2);
953       CASE_S (DW_FORM_ref4);
954       CASE_S (DW_FORM_ref8);
955       CASE_S (DW_FORM_ref_udata);
956       CASE_S (DW_FORM_indirect);
957       CASE_S (DW_FORM_sec_offset);
958       CASE_S (DW_FORM_exprloc);
959       CASE_S (DW_FORM_flag_present);
960       CASE_S (DW_FORM_ref_sig8);
961     default: s = NTXT ("???");
962       break;
963     }
964   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, tag);
965   buf[sizeof (buf) - 1] = 0;
966   return buf;
967 }
968 
969 char *
lnct2str(int ty)970 DwrCU::lnct2str (int ty)
971 {
972   static char buf[128];
973   char *s;
974   switch (ty)
975     {
976       CASE_S (DW_LNCT_path);
977       CASE_S (DW_LNCT_directory_index);
978       CASE_S (DW_LNCT_timestamp);
979       CASE_S (DW_LNCT_size);
980       CASE_S (DW_LNCT_MD5);
981       CASE_S (DW_LNCT_lo_user);
982       CASE_S (DW_LNCT_hi_user);
983     default: s = NTXT ("???");
984       break;
985     }
986   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, ty);
987   buf[sizeof (buf) - 1] = 0;
988   return buf;
989 }
990 
991 void
dump()992 Dwr_Tag::dump ()
993 {
994   Dprintf (DUMP_DWARFLIB,
995 	   "\n<%2d>:<0x%08llx> %-30s <abbrev %lld> offset=0x%llx %s\n",
996 	   (int) level, (long long) die, DwrCU::tag2str (tag), (long long) num,
997 	   (long long) offset,
998 	   hasChild ? NTXT ("DW_children_yes") : NTXT ("DW_children_no"));
999   for (int i1 = firstAttribute; i1 < lastAttribute; i1++)
1000     {
1001       Dwr_Attr *atrp = abbrevAtForm->get (i1);
1002       Dprintf (DUMP_DWARFLIB, "       %-30s ", DwrCU::at2str (atrp->at_name));
1003       switch (atrp->at_form)
1004 	{
1005 	case DW_FORM_strp:
1006 	case DW_FORM_string:
1007 	case DW_FORM_line_strp:
1008 	case DW_FORM_strp_sup:
1009 	case DW_FORM_implicit_const:
1010 	  Dprintf (DUMP_DWARFLIB, "  \"%s\"", atrp->u.str ? atrp->u.str : "<NULL>");
1011 	  break;
1012 	case DW_FORM_block:
1013 	case DW_FORM_block1:
1014 	case DW_FORM_block2:
1015 	case DW_FORM_block4:
1016 	case DW_FORM_data16:
1017 	  Dprintf (DUMP_DWARFLIB, "  len=%3ld  %p", (long) atrp->len,
1018 		   atrp->u.str);
1019 	  break;
1020 	case DW_FORM_addr:
1021 	case DW_FORM_data2:
1022 	case DW_FORM_data4:
1023 	case DW_FORM_data8:
1024 	case DW_FORM_data1:
1025 	case DW_FORM_flag:
1026 	case DW_FORM_sdata:
1027 	case DW_FORM_udata:
1028 	case DW_FORM_ref_addr:
1029 	case DW_FORM_ref1:
1030 	case DW_FORM_ref2:
1031 	case DW_FORM_ref4:
1032 	case DW_FORM_ref8:
1033 	case DW_FORM_ref_udata:
1034 	case DW_FORM_indirect:
1035 	case DW_FORM_sec_offset:
1036 	case DW_FORM_exprloc:
1037 	case DW_FORM_ref_sig8:
1038 	case DW_FORM_flag_present:
1039 	  Dprintf (DUMP_DWARFLIB, "  0x%llx (%lld)", (long long) atrp->u.val,
1040 		   (long long) atrp->u.val);
1041 	  break;
1042 	default:
1043 	  DEBUG_CODE
1044 	  {
1045 	    Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
1046 		     (long long) atrp->at_form, (long long) atrp->at_form);
1047 	    assert (false);
1048 	  }
1049 	}
1050       Dprintf (DUMP_DWARFLIB, NTXT ("\n"));
1051     }
1052 }
1053 
1054 
1055 //////////////////////////////////////////////////////////
1056 //  class DwrSec
1057 
DwrSec(unsigned char * _data,uint64_t _size,bool _need_swap_endian,bool _addr32)1058 DwrSec::DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32)
1059 {
1060   isCopy = false;
1061   data = _data;
1062   sizeSec = _size;
1063   size = (data ? _size : 0);
1064   offset = 0;
1065   fmt64 = false;
1066   reloc = NULL;
1067   need_swap_endian = _need_swap_endian;
1068   addr32 = _addr32;
1069 }
1070 
DwrSec(DwrSec * secp,uint64_t _offset)1071 DwrSec::DwrSec (DwrSec *secp, uint64_t _offset)
1072 {
1073   isCopy = true;
1074   data = secp->data;
1075   sizeSec = secp->sizeSec;
1076   size = secp->size;
1077   offset = _offset;
1078   fmt64 = secp->fmt64;
1079   reloc = secp->reloc;
1080   need_swap_endian = secp->need_swap_endian;
1081   addr32 = secp->addr32;
1082 }
1083 
~DwrSec()1084 DwrSec::~DwrSec ()
1085 {
1086   if (!isCopy)
1087     delete reloc;
1088 }
1089 
1090 bool
bounds_violation(uint64_t sz)1091 DwrSec::bounds_violation (uint64_t sz)
1092 {
1093   if (offset + sz > size)
1094     {
1095       Dprintf (DEBUG_ERR_MSG, "DwrSec::bounds_violation: offset=%lld + sz=%lld > size=%lld\n",
1096 	       (long long) offset, (long long) sz, (long long) size);
1097       return true;
1098     }
1099   return false;
1100 }
1101 
1102 uint64_t
ReadLength()1103 DwrSec::ReadLength ()
1104 {
1105   fmt64 = false;
1106   uint64_t val = Get_32 ();
1107   if (((uint32_t) val) == 0xffffffff)
1108     {
1109       fmt64 = true;
1110       val = Get_64 ();
1111     }
1112   size = (val + offset < sizeSec) ? val + offset : sizeSec;
1113   return size;
1114 }
1115 
1116 unsigned char
Get_8()1117 DwrSec::Get_8 ()
1118 {
1119   unsigned char n = 0;
1120   if (bounds_violation (sizeof (char)))
1121     return n;
1122   n = data[offset];
1123   offset += sizeof (char);
1124   return n;
1125 }
1126 
1127 unsigned short
Get_16()1128 DwrSec::Get_16 ()
1129 {
1130   unsigned short n = 0;
1131   if (bounds_violation (sizeof (short)))
1132     return n;
1133   memcpy ((char *) &n, data + offset, sizeof (short));
1134   offset += sizeof (short);
1135   if (need_swap_endian)
1136     SWAP_ENDIAN (n);
1137   return n;
1138 }
1139 
1140 uint32_t
Get_24()1141 DwrSec::Get_24 ()
1142 {
1143   uint32_t n = 0;
1144   if (bounds_violation (3))
1145     return n;
1146   memcpy ((char *) &n, data + offset, 3);
1147   offset += 3;
1148   if (need_swap_endian)
1149     SWAP_ENDIAN (n);
1150   return n;
1151 }
1152 
1153 uint32_t
Get_32()1154 DwrSec::Get_32 ()
1155 {
1156   uint32_t n = 0;
1157   if (bounds_violation (sizeof (uint32_t)))
1158     return n;
1159   memcpy ((char *) &n, data + offset, sizeof (uint32_t));
1160   offset += sizeof (uint32_t);
1161   if (need_swap_endian)
1162     SWAP_ENDIAN (n);
1163   return n;
1164 }
1165 
1166 uint64_t
Get_64()1167 DwrSec::Get_64 ()
1168 {
1169   uint64_t n = 0;
1170   if (bounds_violation (sizeof (uint64_t)))
1171     return n;
1172   memcpy ((char *) &n, data + offset, sizeof (uint64_t));
1173   offset += sizeof (uint64_t);
1174   if (need_swap_endian)
1175     SWAP_ENDIAN (n);
1176   return n;
1177 }
1178 
1179 char *
GetData(uint64_t len)1180 DwrSec::GetData (uint64_t len)
1181 {
1182   char *s = ((char *) data) + offset;
1183   if (bounds_violation (len))
1184     s = NULL;
1185   offset += len;
1186   return s;
1187 }
1188 
1189 char *
GetString()1190 DwrSec::GetString ()
1191 {
1192   uint64_t off = offset;
1193   while (offset < size)
1194     if (data[offset++] == 0)
1195       { // '\0' is inside section
1196 	if (off + 1 == offset)
1197 	  return NULL;
1198 	return ((char *) data) + off;
1199       }
1200   return NULL; // The section is not '\0' terminated
1201 }
1202 
1203 uint64_t
GetLong()1204 DwrSec::GetLong ()
1205 {
1206   if (fmt64)
1207     return Get_64 ();
1208   return Get_32 ();
1209 }
1210 
1211 uint64_t
GetADDR_32()1212 DwrSec::GetADDR_32 ()
1213 {
1214   uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1215   res += Get_32 ();
1216   return res;
1217 }
1218 
1219 uint64_t
GetADDR_64()1220 DwrSec::GetADDR_64 ()
1221 {
1222   uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
1223   res += Get_64 ();
1224   return res;
1225 }
1226 
1227 uint64_t
GetADDR()1228 DwrSec::GetADDR ()
1229 {
1230   if (addr32)
1231     return GetADDR_32 ();
1232   return GetADDR_64 ();
1233 }
1234 
1235 uint64_t
GetRef()1236 DwrSec::GetRef ()
1237 {
1238   if (fmt64)
1239     return GetADDR_64 ();
1240   return GetADDR_32 ();
1241 }
1242 
1243 ULEB128
GetULEB128()1244 DwrSec::GetULEB128 ()
1245 {
1246   ULEB128 res = 0;
1247   for (int shift = 0;; shift += 7)
1248     {
1249       ULEB128 val = Get_8 ();
1250       res |= (val & 0x7f) << shift;
1251       if ((val & 0x80) == 0)
1252 	break;
1253     }
1254   return res;
1255 }
1256 
1257 SLEB128
GetSLEB128()1258 DwrSec::GetSLEB128 ()
1259 {
1260   ULEB128 res = 0, val = 0;
1261   size_t shift;
1262   for (shift = 0;;)
1263     {
1264       val = Get_8 ();
1265       res |= (val & 0x7f) << shift;
1266       shift += 7;
1267       if ((val & 0x80) == 0)
1268 	break;
1269     }
1270   if ((val & 0x40) && (shift < 8 * sizeof (res)))
1271     res |= -(((ULEB128) 1) << shift);
1272   return (SLEB128) res;
1273 }
1274 
1275 uint64_t
get_value(int dw_form)1276 DwrSec::get_value (int dw_form)
1277 {
1278   uint64_t v;
1279   switch (dw_form)
1280     {
1281     case DW_FORM_line_strp:
1282     case DW_FORM_strp:
1283     case DW_FORM_strp_sup:
1284       return GetRef ();
1285     case DW_FORM_data1:
1286       return Get_8 ();
1287     case DW_FORM_data2:
1288       return Get_16 ();
1289     case DW_FORM_data4:
1290       return Get_32 ();
1291     case DW_FORM_data8:
1292       return Get_64 ();
1293     case DW_FORM_udata:
1294       return GetULEB128 ();
1295     case DW_FORM_data16:
1296       offset += 16;
1297       return offset - 16;
1298     case DW_FORM_block:
1299       v = GetULEB128 ();
1300       offset += v;
1301       return offset - v;
1302     }
1303   return 0;
1304 }
1305 
1306 static void
fillBuf(unsigned char * s,int len,int col,unsigned char * buf)1307 fillBuf (unsigned char *s, int len, int col, unsigned char *buf)
1308 {
1309   const char *nameX = "0123456789abcdef";
1310   int i, n, posCh = 2 * col + col / 4 + 5;
1311 
1312   if (len >= col)
1313     len = col;
1314   for (i = n = 0; i < len; i++, n += 2)
1315     {
1316       if ((i % 4) == 0 && i > 0)
1317 	{
1318 	  buf[n] = ' ';
1319 	  n++;
1320 	}
1321       buf[n] = nameX[s[i] >> 4];
1322       buf[n + 1] = nameX[s[i] & 0xf];
1323       buf[posCh + i] = isprint (s[i]) ? s[i] : ' ';
1324     }
1325   buf[posCh + i] = 0;
1326   for (i = n; i < posCh; i++)
1327     buf[i] = ' ';
1328 }
1329 
1330 static void
dumpArr(unsigned char * s,int len,int col,int num)1331 dumpArr (unsigned char *s, int len, int col, int num)
1332 {
1333   unsigned char buf[128];
1334   if (col <= 0)
1335     return;
1336   for (int i = 0; i < len; i += col, num += col)
1337     {
1338       fillBuf (s + i, len - i, col, buf);
1339       Dprintf (DUMP_DWARFLIB, "%5d: %s\n", num, buf);
1340     }
1341 }
1342 
1343 void
dump(char * msg)1344 DwrSec::dump (char *msg)
1345 {
1346   if (sizeSec > 0)
1347     {
1348       Dprintf (DUMP_DWARFLIB, NTXT ("======= DwrSec::dump\n"));
1349       if (msg)
1350 	Dprintf (DUMP_DWARFLIB, NTXT ("%s:\n"), msg);
1351       dumpArr (data, (int) sizeSec, 32, 0);
1352       Dprintf (DUMP_DWARFLIB, NTXT ("\n"));
1353     }
1354 }
1355 
1356 //////////////////////////////////////////////////////////
1357 //  class DwrFileNames
1358 
DwrFileName(char * _fname)1359 DwrFileName::DwrFileName (char *_fname)
1360 {
1361   path = NULL;
1362   fname = dbe_strdup (_fname);
1363   dir_index = 0;
1364   timestamp = 0;
1365   file_size = 0;
1366   isUsed = false;
1367 }
1368 
~DwrFileName()1369 DwrFileName::~DwrFileName ()
1370 {
1371   if (path != fname)
1372     free (path);
1373 }
1374 
1375 
1376 //////////////////////////////////////////////////////////
1377 //  class DwrLine
DwrLine()1378 DwrLine::DwrLine ()
1379 {
1380   address = 0;
1381   file = 0;
1382   line = 0;
1383   column = 0;
1384 }
1385 
~DwrLine()1386 DwrLine::~DwrLine () { }
1387 
1388 
1389 //////////////////////////////////////////////////////////
1390 //  class DwrLineRegs
1391 static int
LineRegsCmp(const void * a,const void * b)1392 LineRegsCmp (const void *a, const void *b)
1393 {
1394   DwrLine *item1 = *((DwrLine **) a);
1395   DwrLine *item2 = *((DwrLine **) b);
1396   return item1->address == item2->address ? 0 :
1397 	  item1->address > item2->address ? 1 : -1;
1398 }
1399 
DwrLineRegs(Dwarf * _dwarf,DwrSec * secp,char * dirName)1400 DwrLineRegs::DwrLineRegs (Dwarf *_dwarf, DwrSec *secp, char *dirName)
1401 {
1402   dwarf = _dwarf;
1403   dir_names = NULL;
1404   file_names = NULL;
1405   lines = NULL;
1406   fname = NULL;
1407   // `dwarfdump -vv -l` shows a line section (.debug_line)
1408   debug_lineSec = secp;
1409   uint64_t stmt_offset = debug_lineSec->offset;
1410   uint64_t next_cu_offset = debug_lineSec->ReadLength ();
1411   uint64_t header_offset = debug_lineSec->offset;
1412   debug_lineSec->size = next_cu_offset;
1413   version = debug_lineSec->Get_16 ();
1414   if (version == 5)
1415     {
1416       debug_lineSec->address_size = debug_lineSec->Get_8();
1417       debug_lineSec->segment_selector_size = debug_lineSec->Get_8();
1418     }
1419   header_length = debug_lineSec->GetLong ();
1420   opcode_start = debug_lineSec->offset + header_length;
1421   minimum_instruction_length = debug_lineSec->Get_8 ();
1422   op_index_register = 0;
1423   if (version >= 4)
1424     maximum_operations_per_instruction = debug_lineSec->Get_8 ();
1425   else
1426     maximum_operations_per_instruction = 1;
1427   default_is_stmt = debug_lineSec->Get_8 ();
1428   is_stmt = (default_is_stmt != 0);
1429   line_base = debug_lineSec->Get_8 ();
1430   line_range = debug_lineSec->Get_8 ();
1431   opcode_base = debug_lineSec->Get_8 ();
1432   standard_opcode_length = (Dwarf_Small*) debug_lineSec->GetData (opcode_base - 1);
1433 
1434   if (DUMP_DWR_LINE_REGS)
1435     {
1436       Dprintf (DUMP_DWR_LINE_REGS,
1437 	       "\n.debug_line  version=%d stmt_offset=0x%llx"
1438 	       "  header_offset=0x%llx size=%lld dirname='%s'\n"
1439 	       "    header_length=0x%llx  opcode_start=0x%llx"
1440 	       "  minimum_instruction_length=%d default_is_stmt=%d\n"
1441 	       "    line_base=%d  line_range=%d  opcode_base=%d\n",
1442 	       (int) version, (long long) stmt_offset,
1443 	       (long long) header_offset,
1444 	       (long long) (next_cu_offset - header_offset), STR (dirName),
1445 	       (long long) header_length, (long long) opcode_start,
1446 	       (int) minimum_instruction_length, (int) default_is_stmt,
1447 	       (int) line_base, (int) line_range, (int) opcode_base);
1448       if (standard_opcode_length == NULL)
1449 	Dprintf (DUMP_DWR_LINE_REGS, "ERROR: standard_opcode_length is NULL\n");
1450       for (int i = 0, sz = standard_opcode_length ? opcode_base - 1 : 0;
1451 	      i < sz; i++)
1452 	Dprintf (DUMP_DWR_LINE_REGS, "  opcode[%2d] length %2d\n", i,
1453 		 (int) standard_opcode_length[i]);
1454     }
1455 
1456   if (version == 5)
1457     {
1458       dir_names = read_file_names_dwarf5 ();
1459       file_names = read_file_names_dwarf5 ();
1460     }
1461   else
1462     {
1463       dir_names = new Vector<DwrFileName *>;
1464       dir_names->append (new DwrFileName (dirName));
1465       while (true)
1466 	{
1467 	  char *s = debug_lineSec->GetString ();
1468 	  if (s == NULL)
1469 	    break;
1470 	  dir_names->append (new DwrFileName (s));
1471 	}
1472 
1473       file_names = new Vector<DwrFileName *>;
1474       file_names->append (new DwrFileName (dirName));
1475       while (true)
1476 	{
1477 	  char *s = debug_lineSec->GetString ();
1478 	  if (s == NULL)
1479 	    break;
1480 	  DwrFileName *fnp = new DwrFileName (s);
1481 	  fnp->dir_index = debug_lineSec->GetULEB128_32 ();
1482 	  fnp->timestamp = debug_lineSec->GetULEB128 ();
1483 	  fnp->file_size = debug_lineSec->GetULEB128 ();
1484 	  file_names->append (fnp);
1485 	}
1486     }
1487   dump ();
1488 }
1489 
~DwrLineRegs()1490 DwrLineRegs::~DwrLineRegs ()
1491 {
1492   Destroy (dir_names);
1493   Destroy (file_names);
1494   Destroy (lines);
1495   delete debug_lineSec;
1496 }
1497 
1498 Vector <DwrFileName *> *
read_file_names_dwarf5()1499 DwrLineRegs::read_file_names_dwarf5 ()
1500 {
1501 
1502   typedef struct
1503   {
1504     int type_code;
1505     int form_code;
1506   } t_entry_fmt;
1507 
1508   int efmt_cnt = debug_lineSec->Get_8 ();
1509   Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx entry_fmt_cnt=%d\n",
1510 	   (long long) debug_lineSec->offset, efmt_cnt);
1511   if (efmt_cnt == 0)
1512     return NULL;
1513   t_entry_fmt *efmt = (t_entry_fmt *) malloc (sizeof (t_entry_fmt) * efmt_cnt);
1514   for (int i = 0; i < efmt_cnt; i++)
1515     {
1516       efmt[i].type_code = debug_lineSec->GetULEB128 ();
1517       efmt[i].form_code = debug_lineSec->GetULEB128 ();
1518       Dprintf (DUMP_DWR_LINE_REGS, "  %2d  %20s  %s\n", i,
1519 	       DwrCU::lnct2str (efmt[i].type_code),
1520 	       DwrCU::form2str (efmt[i].form_code));
1521     }
1522 
1523   int cnt = debug_lineSec->GetULEB128_32 ();
1524   Dprintf (DUMP_DWR_LINE_REGS, "\nRead names: offset=0x%llx names_cnt=%d\n",
1525 	   (long long) debug_lineSec->offset, cnt);
1526   Vector<DwrFileName *> *fnames = new Vector<DwrFileName *> (cnt);
1527   for (int i = 0; i < cnt; i++)
1528     {
1529       int ind = 0;
1530       uint64_t off = 0;
1531       uint64_t tstamp = 0;
1532       uint64_t fsize = 0;
1533       char *nm = NULL;
1534       for (int k = 0; k < efmt_cnt; k++)
1535 	switch (efmt[k].type_code)
1536 	  {
1537 	  case DW_LNCT_path:
1538 	    if (efmt[k].form_code == DW_FORM_string)
1539 	      nm = debug_lineSec->GetString ();
1540 	    else
1541 	      {
1542 		off = debug_lineSec->get_value (efmt[k].form_code);
1543 		if (efmt[k].form_code == DW_FORM_line_strp)
1544 		  nm = get_string (dwarf->debug_line_strSec, off);
1545 		else if (efmt[k].form_code == DW_FORM_strp)
1546 		  nm = get_string (dwarf->debug_strSec, off);
1547 	      }
1548 	    break;
1549 	  case DW_LNCT_directory_index:
1550 	    ind = debug_lineSec->get_value (efmt[k].form_code);
1551 	    break;
1552 	  case DW_LNCT_timestamp:
1553 	    tstamp = debug_lineSec->get_value (efmt[k].form_code);
1554 	    break;
1555 	  case DW_LNCT_size:
1556 	    fsize = debug_lineSec->get_value (efmt[k].form_code);
1557 	    break;
1558 	  case DW_LNCT_MD5:
1559 	    (void) debug_lineSec->get_value (efmt[k].form_code);
1560 	    break;
1561 	  }
1562       Dprintf (DUMP_DWR_LINE_REGS, " %3d ind=%d off=0x%08llx  %s\n",
1563 	       i, ind, (long long) off, STR (nm));
1564       DwrFileName *fnp = new DwrFileName (nm);
1565       fnp->dir_index = ind;
1566       fnp->timestamp = tstamp;
1567       fnp->file_size = fsize;
1568       fnames->append (fnp);
1569     }
1570   free (efmt);
1571   return fnames;
1572 }
1573 
1574 void
dump()1575 DwrLineRegs::dump ()
1576 {
1577   if (!DUMP_DWR_LINE_REGS)
1578     return;
1579   if (dir_names)
1580     dir_names->dump ("dir_names");
1581   if (file_names)
1582     file_names->dump ("file_names");
1583 
1584   Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\nfile_names size=%lld\n"), (long long) VecSize (file_names));
1585   for (long i = 0, sz = VecSize (file_names); i < sz; i++)
1586     {
1587       DwrFileName *fnp = file_names->get (i);
1588       Dprintf (DUMP_DWR_LINE_REGS, NTXT (" %2lld %-40s dir_index=%4lld  timestamp=%8lld file_size=%lld\n"),
1589 	       (long long) i, STR (fnp->fname),
1590 	       (long long) fnp->dir_index, (long long) fnp->timestamp, (long long) fnp->file_size);
1591     }
1592   if (lines)
1593     lines->dump (fname);
1594   Dprintf (DUMP_DWR_LINE_REGS, NTXT ("\n\n"));
1595 }
1596 
1597 void
DoExtendedOpcode()1598 DwrLineRegs::DoExtendedOpcode ()
1599 {
1600   uint64_t size = debug_lineSec->GetULEB128 ();
1601   if (size == 0)
1602     {
1603       Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), NTXT ("ExtendedOpCode: size=0"));
1604       return;
1605     }
1606   Dwarf_Small opcode = debug_lineSec->Get_8 ();
1607   Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), extended_opcode2str (opcode));
1608   switch (opcode)
1609     {
1610     case DW_LNE_end_sequence:
1611       end_sequence = true;
1612       reset ();
1613       break;
1614     case DW_LNE_set_address:
1615       address = debug_lineSec->GetADDR ();
1616       break;
1617     case DW_LNE_define_file:
1618       // TODO, add file to file list
1619       fname = debug_lineSec->GetString ();
1620       dir_index = debug_lineSec->GetULEB128 ();
1621       timestamp = debug_lineSec->GetULEB128 ();
1622       file_size = debug_lineSec->GetULEB128 ();
1623       break;
1624     default:
1625       debug_lineSec->GetData (size - 1); // skip unknown opcode
1626       break;
1627     }
1628 }
1629 
1630 void
DoStandardOpcode(int opcode)1631 DwrLineRegs::DoStandardOpcode (int opcode)
1632 {
1633   switch (opcode)
1634     {
1635     case DW_LNS_copy:
1636       basic_block = false;
1637       EmitLine ();
1638       break;
1639     case DW_LNS_advance_pc:
1640       address += debug_lineSec->GetULEB128 () * minimum_instruction_length;
1641       break;
1642     case DW_LNS_advance_line:
1643       line += (int) debug_lineSec->GetSLEB128 ();
1644       break;
1645     case DW_LNS_set_file:
1646       file = debug_lineSec->GetULEB128_32 ();
1647       break;
1648     case DW_LNS_set_column:
1649       column = debug_lineSec->GetULEB128_32 ();
1650       break;
1651     case DW_LNS_negate_stmt:
1652       is_stmt = -is_stmt;
1653       break;
1654     case DW_LNS_set_basic_block:
1655       basic_block = true;
1656       break;
1657     case DW_LNS_const_add_pc:
1658       address += ((255 - opcode_base) / line_range) * minimum_instruction_length;
1659       break;
1660     case DW_LNS_fixed_advance_pc:
1661       address += debug_lineSec->Get_16 ();
1662       break;
1663     default:    // skip unknown opcode/operands
1664       debug_lineSec->GetData (standard_opcode_length ?
1665 			      standard_opcode_length[opcode] : 1);
1666       break;
1667     }
1668 }
1669 
1670 void
DoSpecialOpcode(int opcode)1671 DwrLineRegs::DoSpecialOpcode (int opcode)
1672 {
1673   int max_op_per_instr = maximum_operations_per_instruction == 0 ? 1
1674 	  : maximum_operations_per_instruction;
1675   int operation_advance = (opcode / line_range);
1676   address += minimum_instruction_length * ((op_index_register + operation_advance) / max_op_per_instr);
1677   op_index_register = (op_index_register + operation_advance) % max_op_per_instr;
1678   line += line_base + (opcode % line_range);
1679   basic_block = false;
1680   EmitLine ();
1681 }
1682 
1683 void
reset()1684 DwrLineRegs::reset ()
1685 {
1686   dir_index = 0;
1687   timestamp = 0;
1688   file_size = 0;
1689   address = 0;
1690   file = 1;
1691   line = 1;
1692   column = 0;
1693   is_stmt = (default_is_stmt != 0);
1694   basic_block = false;
1695   end_sequence = false;
1696 }
1697 
1698 void
EmitLine()1699 DwrLineRegs::EmitLine ()
1700 {
1701   DwrLine *lnp = new DwrLine;
1702 
1703   lnp->file = file;
1704   lnp->line = line;
1705   lnp->column = column;
1706   lnp->address = address;
1707   lines->append (lnp);
1708   if ((file > 0) && (file < VecSize (file_names)))
1709     {
1710       DwrFileName *fnp = file_names->get (file);
1711       fnp->isUsed = true;
1712     }
1713 }
1714 
1715 Vector<DwrLine *> *
get_lines()1716 DwrLineRegs::get_lines ()
1717 {
1718   if (lines == NULL)
1719     {
1720       lines = new Vector<DwrLine *>;
1721       debug_lineSec->offset = opcode_start;
1722       reset ();
1723       Dprintf (DUMP_DWR_LINE_REGS, "\n  offset        code             address (file, line, column) stmt blck end_seq \n");
1724       while (debug_lineSec->offset < debug_lineSec->size)
1725 	{
1726 	  Dprintf (DUMP_DWR_LINE_REGS, NTXT ("0x%08llx "),
1727 		   (long long) debug_lineSec->offset);
1728 	  Dwarf_Small opcode = debug_lineSec->Get_8 ();
1729 	  if (opcode == 0)
1730 	    DoExtendedOpcode ();
1731 	  else if (opcode < opcode_base)
1732 	    {
1733 	      DoStandardOpcode (opcode);
1734 	      Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"), standard_opcode2str (opcode));
1735 	    }
1736 	  else
1737 	    {
1738 	      DoSpecialOpcode (opcode - opcode_base);
1739 	      Dprintf (DUMP_DWR_LINE_REGS, NTXT ("%-20s"),
1740 		       special_opcode2str (opcode - opcode_base));
1741 	    }
1742 	  Dprintf (DUMP_DWR_LINE_REGS,
1743 		   "  0x%08llx  (%lld, %lld, %lld)  %c %c %c\n",
1744 		   (long long) address, (long long) file, (long long) line,
1745 		   (long long) column, is_stmt ? 'T' : 'F',
1746 		   basic_block ? 'T' : 'F', end_sequence ? 'T' : 'F');
1747 	}
1748       lines->sort (LineRegsCmp);
1749       if (DUMP_DWR_LINE_REGS)
1750 	lines->dump (fname);
1751     }
1752   return lines;
1753 }
1754 
1755 char *
getPath(int fn)1756 DwrLineRegs::getPath (int fn)
1757 {
1758   if (fn >= VecSize (file_names) || fn < 0)
1759     {
1760       Dprintf (DEBUG_ERR_MSG, NTXT ("DwrLineRegs::getPath: fn=0x%lld file_names->size()=%lld\n"),
1761 	       (long long) fn, (long long) VecSize (file_names));
1762       return NULL;
1763     }
1764   DwrFileName *fnp = file_names->fetch (fn);
1765   if (fnp->fname == NULL)
1766     return NULL;
1767   if (fnp->path)
1768     return fnp->path;
1769 
1770   fnp->path = fnp->fname;
1771   if (fnp->fname[0] == '/')
1772     return fnp->path;
1773 
1774   char *dir = NULL;
1775   if (dir_names)
1776     {
1777       if (fnp->dir_index < dir_names->size () && fnp->dir_index >= 0)
1778 	dir = dir_names->get (fnp->dir_index)->fname;
1779     }
1780   if (dir == NULL || *dir == 0)
1781     return fnp->path;
1782 
1783   char *dir1 = NULL;
1784   if (*dir != '/')
1785     dir1 = dir_names->get(0)->fname;
1786   if (dir1 && *dir != 0)
1787     fnp->path = dbe_sprintf ("%s/%s/%s", dir1, dir, fnp->fname);
1788   else
1789     fnp->path = dbe_sprintf ("%s/%s", dir, fnp->fname);
1790   fnp->path = canonical_path (fnp->path);
1791   return fnp->path;
1792 }
1793 
DwrCU(Dwarf * _dwarf)1794 DwrCU::DwrCU (Dwarf *_dwarf)
1795 {
1796   dwarf = _dwarf;
1797   cu_offset = dwarf->debug_infoSec->offset;
1798   debug_infoSec = new DwrSec (dwarf->debug_infoSec, cu_offset);
1799   next_cu_offset = debug_infoSec->ReadLength ();
1800   if (next_cu_offset > debug_infoSec->sizeSec)
1801     {
1802       Dprintf (DEBUG_ERR_MSG,
1803 	"DwrCU::DwrCU: next_cu_offset(0x%llx) > debug_infoSec->sizeSec(%llx)\n",
1804 	       (long long) next_cu_offset, (long long) debug_infoSec->sizeSec);
1805       next_cu_offset = debug_infoSec->sizeSec;
1806     }
1807   debug_infoSec->size = next_cu_offset;
1808   version = debug_infoSec->Get_16 ();
1809   if (version == 5)
1810     {
1811       unit_type = debug_infoSec->Get_8 ();
1812       address_size = debug_infoSec->Get_8 ();
1813       debug_abbrev_offset = debug_infoSec->GetLong ();
1814     }
1815   else
1816     {
1817       unit_type = DW_UT_compile;
1818       debug_abbrev_offset = debug_infoSec->GetLong ();
1819       address_size = debug_infoSec->Get_8 ();
1820     }
1821   cu_header_offset = debug_infoSec->offset;
1822   comp_dir = NULL;
1823   module = NULL;
1824   abbrevTable = NULL;
1825   dwrInlinedSubrs = NULL;
1826   srcFiles = NULL;
1827   stmt_list_offset = NO_STMT_LIST;
1828   dwrLineReg = NULL;
1829   isMemop = false;
1830   isGNU = false;
1831   dwrTag.level = 0;
1832 
1833   build_abbrevTable (dwarf->debug_abbrevSec, debug_abbrev_offset);
1834 #ifdef DEBUG
1835   if (DUMP_DWARFLIB)
1836     {
1837       Dprintf (DUMP_DWARFLIB,
1838 	       "CU_HEADER: header_offset = 0x%08llx %lld"
1839 	       " next_header_offset=0x%08llx %lld\n"
1840 	       "    abbrev_offset = 0x%08llx %lld\n"
1841 	       "    unit_length   = %lld\n"
1842 	       "    version       = %d\n"
1843 	       "    address_size  = %d\n"
1844 	       "    fmt64         = %s\n"
1845 	       "debug_info:   need_swap_endian=%s  fmt64=%s addr32=%s\n",
1846 	       (long long) cu_offset, (long long) cu_offset,
1847 	       (long long) next_cu_offset, (long long) next_cu_offset,
1848 	       (long long) debug_abbrev_offset, (long long) debug_abbrev_offset,
1849 	       (long long) (next_cu_offset - cu_offset),
1850 	       (int) version, (int) address_size,
1851 	       debug_infoSec->fmt64 ? "true" : "false",
1852 	       debug_infoSec->need_swap_endian ? "true" : "false",
1853 	       debug_infoSec->fmt64 ? "true" : "false",
1854 	       debug_infoSec->addr32 ? "true" : "false");
1855       Dprintf (DUMP_DWARFLIB, "\n.debug_abbrev  cnt=%d  offset=0x%08llx %lld\n",
1856 	       (int) VecSize (abbrevTable), (long long) debug_abbrev_offset,
1857 	       (long long) debug_abbrev_offset);
1858       for (int i = 1, sz = VecSize (abbrevTable); i < sz; i++)
1859 	{
1860 	  DwrAbbrevTable *abbTbl = abbrevTable->get (i);
1861 	  Dprintf (DUMP_DWARFLIB, NTXT ("%5d: %-30s %-20s offset=0x%08llx\n"),
1862 		   (int) i, DwrCU::tag2str (abbTbl->tag),
1863 		   abbTbl->hasChild ? "DW_children_yes" : "DW_children_no",
1864 		   (long long) abbTbl->offset);
1865 	  for (int i1 = abbTbl->firstAtForm; i1 < abbTbl->lastAtForm; i1++)
1866 	    {
1867 	      Dwr_Attr *atf = abbrevAtForm->get (i1);
1868 	      Dprintf (DUMP_DWARFLIB, "       %-30s %s\n",
1869 		       DwrCU::at2str (atf->at_name),
1870 		       DwrCU::form2str (atf->at_form));
1871 	    }
1872 	}
1873     }
1874 #endif
1875 }
1876 
~DwrCU()1877 DwrCU::~DwrCU ()
1878 {
1879   delete debug_infoSec;
1880   delete abbrevTable;
1881   delete abbrevAtForm;
1882   Destroy (dwrInlinedSubrs);
1883   delete srcFiles;
1884   delete dwrLineReg;
1885   free (comp_dir);
1886 }
1887 
1888 void
build_abbrevTable(DwrSec * _debug_abbrevSec,uint64_t _offset)1889 DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
1890 {
1891   if (abbrevTable)
1892     return;
1893   DwrSec *debug_abbrevSec = new DwrSec (_debug_abbrevSec, _offset);
1894   abbrevTable = new DbeArray <DwrAbbrevTable>(128);
1895   abbrevAtForm = new DbeArray <Dwr_Attr>(512);
1896   abbrevTable->allocate (1); // skip first
1897   abbrevAtForm->allocate (1); // skip first
1898   for (int i = 1; debug_abbrevSec->offset < debug_abbrevSec->size; i++)
1899     {
1900       DwrAbbrevTable abbTbl;
1901       abbTbl.offset = debug_abbrevSec->offset;
1902       abbTbl.code = debug_abbrevSec->GetULEB128_32 ();
1903       if (abbTbl.code == 0)
1904 	break;
1905       else if (i != abbTbl.code)
1906 	{
1907 	  dwarf->elf->append_msg (CMSG_ERROR, GTXT ("%s: the abbreviations table is corrupted (%lld <--> %lld)\n"),
1908 				  get_basename (dwarf->elf->get_location ()),
1909 				  (long long) i, (long long) abbTbl.code);
1910 	  break;
1911 	}
1912       abbTbl.tag = debug_abbrevSec->GetULEB128_32 ();
1913       abbTbl.hasChild = (DW_children_yes == debug_abbrevSec->Get_8 ());
1914       abbTbl.firstAtForm = abbrevAtForm->size ();
1915       while (debug_abbrevSec->offset < debug_abbrevSec->size)
1916 	{
1917 	  Dwr_Attr atf;
1918 	  atf.len = 0;
1919 	  atf.u.str = NULL;
1920 	  atf.at_name = debug_abbrevSec->GetULEB128_32 ();
1921 	  atf.at_form = debug_abbrevSec->GetULEB128_32 ();
1922 	  if (atf.at_name == 0 && atf.at_form == 0)
1923 	    break;
1924 	  switch (atf.at_form)
1925 	    {
1926 	    case DW_FORM_implicit_const:
1927 	      atf.len = debug_abbrevSec->GetSLEB128 ();
1928 	      break;
1929 	    }
1930 	  abbrevAtForm->append (atf);
1931 	}
1932       abbTbl.lastAtForm = abbrevAtForm->size ();
1933       abbrevTable->append (abbTbl);
1934     }
1935   delete debug_abbrevSec;
1936 }
1937 
1938 int
set_die(Dwarf_Die die)1939 DwrCU::set_die (Dwarf_Die die)
1940 {
1941   if (die > 0)
1942     debug_infoSec->offset = die;
1943   if (debug_infoSec->offset < cu_header_offset
1944       || debug_infoSec->offset >= debug_infoSec->size)
1945     return DW_DLV_ERROR;
1946   dwrTag.offset = debug_infoSec->offset;
1947   dwrTag.die = debug_infoSec->offset - cu_offset;
1948   dwrTag.num = debug_infoSec->GetULEB128_32 ();
1949   if (dwrTag.num == 0)
1950     return DW_DLV_NO_ENTRY;
1951   dwrTag.abbrevAtForm = abbrevAtForm;
1952   DwrAbbrevTable *abbTbl = abbrevTable->get (dwrTag.num);
1953   if (abbTbl == NULL)
1954     { // corrupt dwarf
1955       dwarf->elf->append_msg (CMSG_ERROR, GTXT ("%s: the abbreviation code (%lld) does not match for the Dwarf entry (0x%llx)\n"),
1956 			      get_basename (dwarf->elf->get_location ()),
1957 			     (long long) dwrTag.num, (long long) dwrTag.offset);
1958       return DW_DLV_ERROR;
1959     }
1960   dwrTag.tag = abbTbl->tag;
1961   dwrTag.hasChild = abbTbl->hasChild;
1962   dwrTag.firstAttribute = abbTbl->firstAtForm;
1963   dwrTag.lastAttribute = abbTbl->lastAtForm;
1964   for (int k = abbTbl->firstAtForm; k < abbTbl->lastAtForm; k++)
1965     {
1966       Dwr_Attr *atf = abbrevAtForm->get (k);
1967       int at_form = atf->at_form;
1968       if (at_form == DW_FORM_indirect)
1969 	at_form = debug_infoSec->GetULEB128_32 ();
1970       switch (at_form)
1971 	{
1972 	case DW_FORM_addr:
1973 	  atf->u.offset = (address_size == 4) ? debug_infoSec->GetADDR_32 ()
1974 		  : debug_infoSec->GetADDR_64 ();
1975 	  break;
1976 	case DW_FORM_flag:
1977 	  atf->u.offset = debug_infoSec->Get_8 ();
1978 	  break;
1979 	case DW_FORM_block:
1980 	  atf->len = debug_infoSec->GetULEB128 ();
1981 	  atf->u.str = debug_infoSec->GetData (atf->len);
1982 	  break;
1983 	case DW_FORM_block1:
1984 	  atf->len = debug_infoSec->Get_8 ();
1985 	  atf->u.str = debug_infoSec->GetData (atf->len);
1986 	  break;
1987 	case DW_FORM_block2:
1988 	  atf->len = debug_infoSec->Get_16 ();
1989 	  atf->u.str = debug_infoSec->GetData (atf->len);
1990 	  break;
1991 	case DW_FORM_block4:
1992 	  atf->len = debug_infoSec->Get_32 ();
1993 	  atf->u.str = debug_infoSec->GetData (atf->len);
1994 	  break;
1995 	case DW_FORM_ref1:
1996 	  atf->u.offset = debug_infoSec->Get_8 ();
1997 	  break;
1998 	case DW_FORM_ref2:
1999 	  atf->u.offset = debug_infoSec->Get_16 ();
2000 	  break;
2001 	case DW_FORM_ref4:
2002 	  atf->u.offset = debug_infoSec->Get_32 ();
2003 	  break;
2004 	case DW_FORM_ref8:
2005 	  atf->u.offset = debug_infoSec->Get_64 ();
2006 	  break;
2007 	case DW_FORM_ref_udata:
2008 	  atf->u.offset = debug_infoSec->GetULEB128 ();
2009 	  break;
2010 	case DW_FORM_data1:
2011 	  atf->u.offset = debug_infoSec->Get_8 ();
2012 	  break;
2013 	case DW_FORM_data2:
2014 	  atf->u.offset = debug_infoSec->Get_16 ();
2015 	  break;
2016 	case DW_FORM_data4:
2017 	  atf->u.offset = debug_infoSec->Get_32 ();
2018 	  break;
2019 	case DW_FORM_data8:
2020 	  atf->u.offset = debug_infoSec->Get_64 ();
2021 	  break;
2022 	case DW_FORM_string:
2023 	  atf->u.offset = debug_infoSec->offset;
2024 	  atf->u.str = debug_infoSec->GetString ();
2025 	  break;
2026 	case DW_FORM_strp:
2027 	  atf->u.offset = debug_infoSec->GetRef ();
2028 	  atf->u.str = get_string (dwarf->debug_strSec, atf->u.offset);
2029 	  break;
2030 	case DW_FORM_sdata:
2031 	  atf->u.val = debug_infoSec->GetSLEB128 ();
2032 	  break;
2033 	case DW_FORM_udata:
2034 	  atf->u.offset = debug_infoSec->GetULEB128 ();
2035 	  break;
2036 	case DW_FORM_ref_addr:
2037 	  if (version > 2)
2038 	    atf->u.offset = debug_infoSec->GetRef ();
2039 	  else
2040 	    atf->u.offset = debug_infoSec->GetADDR ();
2041 	  break;
2042 	case DW_FORM_sec_offset:
2043 	  atf->u.offset = debug_infoSec->GetRef ();
2044 	  break;
2045 	case DW_FORM_exprloc:
2046 	  atf->u.offset = debug_infoSec->GetULEB128 ();
2047 	  debug_infoSec->offset += atf->u.offset;
2048 	  break;
2049 	case DW_FORM_flag_present:
2050 	  atf->u.val = 1;
2051 	  break;
2052 	case DW_FORM_ref_sig8:
2053 	  atf->u.offset = debug_infoSec->GetADDR_64 ();
2054 	  break;
2055 	case DW_FORM_data16:	// we never use this data. Skip 16 bytes
2056 	  atf->len = 16;
2057 	  (void) debug_infoSec->Get_64 ();
2058 	  (void) debug_infoSec->Get_64 ();
2059 	  break;
2060 	case DW_FORM_addrx:
2061 	case DW_FORM_strx:
2062 	case DW_FORM_loclistx:
2063 	case DW_FORM_rnglistx:
2064 	  atf->u.offset = debug_infoSec->GetULEB128 ();
2065 	  break;
2066 	case DW_FORM_addrx1:
2067 	case DW_FORM_strx1:
2068 	  atf->u.offset = debug_infoSec->Get_8 ();
2069 	  break;
2070 	case DW_FORM_addrx2:
2071 	case DW_FORM_strx2:
2072 	  atf->u.offset = debug_infoSec->Get_16 ();
2073 	  break;
2074 	case DW_FORM_addrx3:
2075 	case DW_FORM_strx3:
2076 	  atf->u.offset = debug_infoSec->Get_24 ();
2077 	  break;
2078 	case DW_FORM_addrx4:
2079 	case DW_FORM_strx4:
2080 	case DW_FORM_ref_sup4:
2081 	  atf->u.offset = debug_infoSec->Get_32 ();
2082 	  break;
2083 	case DW_FORM_ref_sup8:
2084 	  atf->u.offset = debug_infoSec->Get_64 ();
2085 	  break;
2086 	case DW_FORM_line_strp:
2087 	  atf->u.offset = debug_infoSec->GetRef ();
2088 	  atf->u.str = get_string (dwarf->debug_line_strSec, atf->u.offset);
2089 	  break;
2090 	case DW_FORM_strp_sup:
2091 	  atf->u.offset = debug_infoSec->GetRef ();
2092 	  atf->u.str = NULL;
2093 	  atf->len = 0;
2094 	  break;
2095 	case DW_FORM_implicit_const:
2096 	  atf->u.str = NULL;
2097 	  break;
2098 	default:
2099 	  DEBUG_CODE
2100 	  {
2101 	    Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
2102 		     (long long) atf->at_form, (long long) atf->at_form);
2103 	    assert (0);
2104 	  }
2105 	  atf->u.str = NULL;
2106 	  atf->len = 0;
2107 	  break;
2108 	}
2109     }
2110   dwrTag.dump ();
2111   return DW_DLV_OK;
2112 }
2113 
2114 static char *
composePath(char * dname,char * fname)2115 composePath (char *dname, char *fname)
2116 {
2117   char *s;
2118   if (*fname == '/' || dname == NULL)
2119     s = dbe_sprintf (NTXT ("%s"), fname);
2120   else
2121     s = dbe_sprintf (NTXT ("%s/%s"), dname, fname);
2122   return canonical_path (s);
2123 }
2124 
2125 Module *
parse_cu_header(LoadObject * lo)2126 DwrCU::parse_cu_header (LoadObject *lo)
2127 {
2128   // Is tag always DW_TAG_compile_unit?
2129   if (dwrTag.tag != DW_TAG_compile_unit)
2130     {
2131       Dprintf (DEBUG_ERR_MSG,
2132 	    "parse_cu_header: die=0x%llx tag=%lld is not DW_TAG_compile_unit\n",
2133 	       (long long) cu_offset, (long long) dwrTag.tag);
2134       return NULL;
2135     }
2136 
2137   char *name = Dwarf_string (DW_AT_name);
2138   if (name == NULL)
2139     name = NTXT ("UnnamedUnit");
2140   int64_t v;
2141   if (read_data_attr(DW_AT_stmt_list, &v) == DW_DLV_OK)
2142     stmt_list_offset = v;
2143   comp_dir = dbe_strdup (Dwarf_string (DW_AT_comp_dir));
2144   char *dir_name = comp_dir ? StrChr (comp_dir, ':') : NULL;
2145   char *orig_name = Dwarf_string (DW_AT_SUN_original_name);
2146   char *path = composePath (dir_name, orig_name ? orig_name : name);
2147 
2148   module = dwarf->stabs->append_Module (lo, path);
2149   free (path);
2150   if (module == NULL)
2151     return NULL;
2152   module->hasDwarf = true;
2153   if (orig_name)
2154     module->linkerStabName = composePath (dir_name, name);
2155   module->lang_code = Dwarf_lang ();
2156   module->comp_flags = dbe_strdup (Dwarf_string (DW_AT_SUN_command_line));
2157   if (module->comp_flags == NULL)
2158     module->comp_flags = dbe_strdup (Dwarf_string (DW_AT_icc_flags));
2159   module->comp_dir = dbe_strdup (dir_name);
2160 
2161   char *obj_file = Dwarf_string (DW_AT_SUN_obj_file);
2162   char *obj_dir = Dwarf_string (DW_AT_SUN_obj_dir);
2163   if (obj_dir && obj_file)
2164     {
2165       // object information may not be available
2166       dir_name = StrChr (obj_dir, ':');
2167       path = composePath (dir_name, obj_file);
2168       if (module->dot_o_file == NULL)
2169 	module->dot_o_file = module->createLoadObject (path);
2170     }
2171   else
2172     path = dbe_strdup (dwarf->stabs->path);
2173   module->set_name (path);
2174   return module;
2175 }
2176 
2177 Dwr_Attr *
get_attr(Dwarf_Half attr)2178 Dwr_Tag::get_attr (Dwarf_Half attr)
2179 {
2180   for (long i = firstAttribute; i < lastAttribute; i++)
2181     {
2182       Dwr_Attr *atf = abbrevAtForm->get (i);
2183       if (atf->at_name == attr)
2184 	return atf;
2185     }
2186   return NULL;
2187 }
2188 
2189 char *
Dwarf_string(Dwarf_Half attr)2190 DwrCU::Dwarf_string (Dwarf_Half attr)
2191 {
2192   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
2193   return dwrAttr ? dwrAttr->u.str : NULL;
2194 }
2195 
2196 uint64_t
get_high_pc(uint64_t low_pc)2197 DwrCU::get_high_pc (uint64_t low_pc)
2198 {
2199   Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_high_pc);
2200   if (dwrAttr)
2201     switch (dwrAttr->at_form)
2202       {
2203       case DW_FORM_addr:
2204 	return dwrAttr->u.offset;
2205       default:
2206 	return dwrAttr->u.offset + low_pc;
2207       }
2208   return 0;
2209 }
2210 
2211 Dwarf_Addr
Dwarf_addr(Dwarf_Half attr)2212 DwrCU::Dwarf_addr (Dwarf_Half attr)
2213 {
2214   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
2215   if (dwrAttr)
2216     switch (dwrAttr->at_form)
2217       {
2218       case DW_FORM_addr:
2219 	return dwrAttr->u.offset;
2220       }
2221   return 0;
2222 }
2223 
2224 DwrSec*
Dwarf_block(Dwarf_Half attr)2225 DwrCU::Dwarf_block (Dwarf_Half attr)
2226 {
2227   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
2228   if (dwrAttr && dwrAttr->u.block)
2229     switch (dwrAttr->at_form)
2230       {
2231       case DW_FORM_block:
2232       case DW_FORM_block1:
2233       case DW_FORM_block2:
2234       case DW_FORM_block4:
2235 	return new DwrSec (dwrAttr->u.block, dwrAttr->len,
2236 			   dwarf->elf->need_swap_endian,
2237 			   dwarf->elf->elf_getclass () == ELFCLASS32);
2238       }
2239   return NULL;
2240 }
2241 
2242 int
read_data_attr(Dwarf_Half attr,int64_t * retVal)2243 DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
2244 {
2245   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
2246   if (dwrAttr)
2247     switch (dwrAttr->at_form)
2248       {
2249       case DW_FORM_data1:
2250       case DW_FORM_data2:
2251       case DW_FORM_data4:
2252       case DW_FORM_data8:
2253       case DW_FORM_data16:
2254       case DW_FORM_udata:
2255       case DW_FORM_sec_offset:
2256 	*retVal = dwrAttr->u.val;
2257 	return DW_DLV_OK;
2258 
2259       }
2260   return DW_DLV_ERROR;
2261 }
2262 
2263 int
read_ref_attr(Dwarf_Half attr,int64_t * retVal)2264 DwrCU::read_ref_attr (Dwarf_Half attr, int64_t *retVal)
2265 {
2266   Dwr_Attr *dwrAttr = dwrTag.get_attr (attr);
2267   if (dwrAttr)
2268     switch (dwrAttr->at_form)
2269       {
2270       case DW_FORM_ref1:
2271       case DW_FORM_ref2:
2272       case DW_FORM_ref4:
2273       case DW_FORM_ref8:
2274       case DW_FORM_ref_udata:
2275       case DW_FORM_sec_offset:
2276       case DW_FORM_exprloc:
2277       case DW_FORM_ref_sig8:
2278 	*retVal = dwrAttr->u.val;
2279 	return DW_DLV_OK;
2280       }
2281   return DW_DLV_ERROR;
2282 }
2283 
2284 int64_t
Dwarf_data(Dwarf_Half attr)2285 DwrCU::Dwarf_data (Dwarf_Half attr)
2286 {
2287   int64_t retVal;
2288   if (read_data_attr (attr, &retVal) == DW_DLV_OK)
2289     return retVal;
2290   return 0;
2291 }
2292 
2293 int64_t
Dwarf_ref(Dwarf_Half attr)2294 DwrCU::Dwarf_ref (Dwarf_Half attr)
2295 {
2296   int64_t retVal;
2297   if (read_ref_attr (attr, &retVal) == DW_DLV_OK)
2298     return retVal;
2299   return 0;
2300 }
2301 
2302 Dwarf_Addr
Dwarf_location(Dwarf_Attribute attr)2303 DwrCU::Dwarf_location (Dwarf_Attribute attr)
2304 {
2305   DwrSec *secp = Dwarf_block (attr);
2306   if (secp)
2307     {
2308       DwrLocation loc;
2309       DwrLocation *lp = dwr_get_location (secp, &loc);
2310       delete secp;
2311       if (lp)
2312 	return lp->lc_number;
2313     }
2314   return 0;
2315 }
2316 
2317 void
map_dwarf_lines(Module * mod)2318 DwrCU::map_dwarf_lines (Module *mod)
2319 {
2320   DwrLineRegs *lineReg = get_dwrLineReg ();
2321   long inlinedSubrCnt = VecSize (dwrInlinedSubrs);
2322   if (isGNU && (inlinedSubrCnt > 0))
2323     {
2324       Function *func = NULL;
2325       mod->inlinedSubr = (InlinedSubr *) malloc (inlinedSubrCnt
2326 						 * sizeof (InlinedSubr));
2327       for (long i = 0; i < inlinedSubrCnt; i++)
2328 	{
2329 	  DwrInlinedSubr *inlinedSubr = dwrInlinedSubrs->get (i);
2330 	  uint64_t low_pc;
2331 	  Function *f = dwarf->stabs->map_PC_to_func (inlinedSubr->low_pc,
2332 						      low_pc, mod->functions);
2333 	  if (f == NULL)
2334 	    continue;
2335 	  if (func != f)
2336 	    {
2337 	      func = f;
2338 	      func->inlinedSubrCnt = 0;
2339 	      func->inlinedSubr = mod->inlinedSubr + i;
2340 	    }
2341 	  InlinedSubr *p = func->inlinedSubr + func->inlinedSubrCnt;
2342 	  func->inlinedSubrCnt++;
2343 	  int fileno = inlinedSubr->file - 1;
2344 	  SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ?
2345 		  srcFiles->get (fileno) : dbeSession->get_Unknown_Source ();
2346 	  p->dbeLine = sf->find_dbeline (inlinedSubr->line);
2347 	  p->high_pc = inlinedSubr->high_pc - low_pc;
2348 	  p->low_pc = inlinedSubr->low_pc - low_pc;
2349 	  p->level = inlinedSubr->level;
2350 	  p->func = NULL;
2351 	  p->fname = NULL;
2352 	  if (set_die (inlinedSubr->abstract_origin) == DW_DLV_OK)
2353 	    p->fname = dbe_strdup (Dwarf_string (DW_AT_name));
2354 	  if (p->fname)
2355 	    p->func = Stabs::find_func (p->fname, mod->functions,
2356 					Stabs::is_fortran (mod->lang_code));
2357 	}
2358     }
2359   if (lineReg == NULL)
2360     return;
2361   Vector<DwrLine *> *lines = lineReg->get_lines ();
2362 
2363   Include *includes = new Include;
2364   includes->new_src_file (mod->getMainSrc (), 0, NULL);
2365   char *path = NULL;
2366   SourceFile *cur_src = NULL;
2367   Function *cur_func = NULL;
2368   for (long i = 0, sz = VecSize (lines); i < sz; i++)
2369     {
2370       DwrLine *dwrLine = lines->get (i);
2371       char *filename = lineReg->getPath (dwrLine->file);
2372       if (filename == NULL)
2373 	continue;
2374       uint64_t pc = dwrLine->address;
2375       int lineno = dwrLine->line;
2376       if (path != filename)
2377 	{
2378 	  path = filename;
2379 	  char *name = StrChr (path, ':');
2380 	  SourceFile *src = mod->setIncludeFile (name);
2381 	  if (cur_src != src)
2382 	    {
2383 	      includes->new_src_file (src, lineno, cur_func);
2384 	      cur_src = src;
2385 	    }
2386 	}
2387       uint64_t low_pc;
2388       Function *func = dwarf->stabs->map_PC_to_func (pc, low_pc, mod->functions);
2389       if (func && (func->module == mod))
2390 	{
2391 	  if (func != cur_func)
2392 	    {
2393 	      if (cur_func)
2394 		while (cur_func->popSrcFile () != NULL)
2395 		  ;
2396 	      cur_func = func;
2397 	      includes->push_src_files (cur_func);
2398 	    }
2399 	  cur_func->add_PC_info (pc - low_pc, lineno);
2400 	}
2401     }
2402   if (cur_func)
2403     while (cur_func->popSrcFile ())
2404       ;
2405   delete includes;
2406 }
2407 
2408 DwrLineRegs *
get_dwrLineReg()2409 DwrCU::get_dwrLineReg ()
2410 {
2411   if (dwrLineReg == NULL && stmt_list_offset != NO_STMT_LIST)
2412     dwrLineReg = new DwrLineRegs (dwarf, new DwrSec (dwarf->debug_lineSec,
2413 					      stmt_list_offset), comp_dir);
2414   return dwrLineReg;
2415 }
2416 
2417 void
parse_inlined_subroutine(Dwarf_cnt * ctx)2418 DwrCU::parse_inlined_subroutine (Dwarf_cnt *ctx)
2419 {
2420   int64_t abstract_origin = Dwarf_ref (DW_AT_abstract_origin);
2421   int fileno = (int) Dwarf_data (DW_AT_call_file);
2422   int lineno = (int) Dwarf_data (DW_AT_call_line);
2423   int level = ctx->inlinedSubr ? (ctx->inlinedSubr->level + 1) : 0;
2424   DwrInlinedSubr *inlinedSubr_old = ctx->inlinedSubr;
2425 
2426   if (dwrInlinedSubrs == NULL)
2427     dwrInlinedSubrs = new Vector<DwrInlinedSubr*>;
2428   Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges);
2429   if (dwrAttr)
2430     {
2431       uint64_t ranges = Dwarf_ref (DW_AT_ranges);
2432       if (dwarf->debug_rangesSec && (ranges < dwarf->debug_rangesSec->size))
2433 	{
2434 	  dwarf->debug_rangesSec->offset = ranges;
2435 	  for (;;)
2436 	    {
2437 	      uint64_t low_pc = dwarf->debug_rangesSec->GetADDR ();
2438 	      uint64_t high_pc = dwarf->debug_rangesSec->GetADDR ();
2439 	      if ((low_pc > 0) && (low_pc <= high_pc))
2440 		{
2441 		  DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin,
2442 					low_pc, high_pc, fileno, lineno, level);
2443 		  dwrInlinedSubrs->append (p);
2444 		  ctx->inlinedSubr = p;
2445 		}
2446 	      else
2447 		break;
2448 	    }
2449 	}
2450     }
2451   else
2452     {
2453       uint64_t low_pc = Dwarf_addr (DW_AT_low_pc);
2454       uint64_t high_pc = get_high_pc (low_pc);
2455       if ((low_pc > 0) && (low_pc <= high_pc))
2456 	{
2457 	  DwrInlinedSubr *p = new DwrInlinedSubr (abstract_origin, low_pc,
2458 						high_pc, fileno, lineno, level);
2459 	  dwrInlinedSubrs->append (p);
2460 	  ctx->inlinedSubr = p;
2461 	}
2462     }
2463   parseChild (ctx);
2464   ctx->inlinedSubr = inlinedSubr_old;
2465 }
2466 
2467 
2468 //////////////////////////////////////////////////////////
2469 //  class DwrInlinedSubr
DwrInlinedSubr(int64_t _abstract_origin,uint64_t _low_pc,uint64_t _high_pc,int _file,int _line,int _level)2470 DwrInlinedSubr::DwrInlinedSubr (int64_t _abstract_origin, uint64_t _low_pc,
2471 			    uint64_t _high_pc, int _file, int _line, int _level)
2472 {
2473   abstract_origin = _abstract_origin;
2474   low_pc = _low_pc;
2475   high_pc = _high_pc;
2476   file = _file;
2477   line = _line;
2478   level = _level;
2479 }
2480 
2481 void
dump()2482 DwrInlinedSubr::dump ()
2483 {
2484   Dprintf (DUMP_DWARFLIB,
2485 	   "  level=%d  0x%08llx [0x%08llx - 0x%08llx]  file=%d line=%d\n",
2486 	   (int) level, (long long) abstract_origin, (long long) low_pc,
2487 	   (long long) high_pc, (int) file, (int) line);
2488 }
2489