xref: /netbsd-src/external/gpl3/binutils.old/dist/gprofng/src/DwarfLib.cc (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
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 *
gelf_st_type2str(int type)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 *
special_opcode2str(int opcode)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 *
extended_opcode2str(int opcode)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 *
standard_opcode2str(int opcode)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 *>
dump(const char * msg)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 *>
dump(const char * msg)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 
ElfReloc(Elf * _elf)145 ElfReloc::ElfReloc (Elf *_elf)
146 {
147   elf = _elf;
148   reloc = NULL;
149   cur_reloc_ind = 0;
150 }
151 
~ElfReloc()152 ElfReloc::~ElfReloc ()
153 {
154   if (reloc)
155     {
156       reloc->destroy ();
157       delete reloc;
158     }
159 }
160 
161 void
dump_rela_debug_sec(int sec)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
dump()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
DwrRelocOffsetCmp(const void * a,const void * b)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 *
get_elf_reloc(Elf * elfp,char * sec_name,ElfReloc * rlc)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
get_reloc_addr(long long offset)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 *
dwr_get_location(DwrSec * secp,DwrLocation * lp)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 *
tag2str(int tag)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 *
at2str(int tag)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 *
form2str(int tag)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
dump()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 
DwrSec(unsigned char * _data,uint64_t _size,bool _need_swap_endian,bool _addr32)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 
DwrSec(DwrSec * secp,uint64_t _offset)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 
~DwrSec()987 DwrSec::~DwrSec ()
988 {
989   if (!isCopy)
990     delete reloc;
991 }
992 
993 bool
bounds_violation(uint64_t sz)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
ReadLength()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
Get_8()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
Get_16()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
Get_32()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
Get_64()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 *
GetData(uint64_t len)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 *
GetString(uint64_t * lenp)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
GetLong()1104 DwrSec::GetLong ()
1105 {
1106   if (fmt64)
1107     return Get_64 ();
1108   return Get_32 ();
1109 }
1110 
1111 uint64_t
GetADDR_32()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
GetADDR_64()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
GetADDR()1128 DwrSec::GetADDR ()
1129 {
1130   if (addr32)
1131     return GetADDR_32 ();
1132   return GetADDR_64 ();
1133 }
1134 
1135 uint64_t
GetRef()1136 DwrSec::GetRef ()
1137 {
1138   if (fmt64)
1139     return GetADDR_64 ();
1140   return GetADDR_32 ();
1141 }
1142 
1143 ULEB128
GetULEB128()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
GetSLEB128()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
fillBuf(unsigned char * s,int len,int col,unsigned char * buf)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
dumpArr(unsigned char * s,int len,int col,int num)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
dump(char * msg)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 
DwrFileName(char * _fname)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 
~DwrFileName()1238 DwrFileName::~DwrFileName ()
1239 {
1240   if (path != fname)
1241     free (path);
1242 }
1243 
1244 
1245 //////////////////////////////////////////////////////////
1246 //  class DwrLine
DwrLine()1247 DwrLine::DwrLine ()
1248 {
1249   address = 0;
1250   file = 0;
1251   line = 0;
1252   column = 0;
1253 }
1254 
~DwrLine()1255 DwrLine::~DwrLine () { }
1256 
1257 
1258 //////////////////////////////////////////////////////////
1259 //  class DwrLineRegs
1260 static int
LineRegsCmp(const void * a,const void * b)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 
DwrLineRegs(DwrSec * secp,char * dirName)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 
~DwrLineRegs()1343 DwrLineRegs::~DwrLineRegs ()
1344 {
1345   Destroy (file_names);
1346   Destroy (lines);
1347   delete debug_lineSec;
1348   delete include_directories;
1349 }
1350 
1351 void
dump()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
DoExtendedOpcode()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
DoStandardOpcode(int opcode)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
DoSpecialOpcode(int opcode)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
reset()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
EmitLine()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 *> *
get_lines()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 *
getPath(int fn)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 
DwrCU(Dwarf * _dwarf)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 
~DwrCU()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
build_abbrevTable(DwrSec * _debug_abbrevSec,uint64_t _offset)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
set_die(Dwarf_Die die)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 *
composePath(char * dname,char * fname)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 *
parse_cu_header(LoadObject * lo)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 *
get_attr(Dwarf_Half 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 *
Dwarf_string(Dwarf_Half attr)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
get_high_pc(uint64_t low_pc)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
Dwarf_addr(Dwarf_Half attr)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*
Dwarf_block(Dwarf_Half attr)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
read_data_attr(Dwarf_Half attr,int64_t * retVal)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
read_ref_attr(Dwarf_Half attr,int64_t * retVal)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
Dwarf_data(Dwarf_Half attr)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
Dwarf_ref(Dwarf_Half attr)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
Dwarf_location(Dwarf_Attribute attr)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
map_dwarf_lines(Module * mod)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 *
get_dwrLineReg()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
parse_inlined_subroutine(Dwarf_cnt * ctx)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
DwrInlinedSubr(int64_t _abstract_origin,uint64_t _low_pc,uint64_t _high_pc,int _file,int _line,int _level)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
dump()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 }
2204