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