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 * 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 * 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 * 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 * 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 *> 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 *> 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 *> 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 * 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 173 ElfReloc::ElfReloc (Elf *_elf) 174 { 175 elf = _elf; 176 reloc = NULL; 177 cur_reloc_ind = 0; 178 } 179 180 ElfReloc::~ElfReloc () 181 { 182 if (reloc) 183 { 184 reloc->destroy (); 185 delete reloc; 186 } 187 } 188 189 void 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 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 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 * 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 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 * 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 * 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 * 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 * 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 * 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 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 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 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 1084 DwrSec::~DwrSec () 1085 { 1086 if (!isCopy) 1087 delete reloc; 1088 } 1089 1090 bool 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 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 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 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 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 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 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 * 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 * 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 1204 DwrSec::GetLong () 1205 { 1206 if (fmt64) 1207 return Get_64 (); 1208 return Get_32 (); 1209 } 1210 1211 uint64_t 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 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 1228 DwrSec::GetADDR () 1229 { 1230 if (addr32) 1231 return GetADDR_32 (); 1232 return GetADDR_64 (); 1233 } 1234 1235 uint64_t 1236 DwrSec::GetRef () 1237 { 1238 if (fmt64) 1239 return GetADDR_64 (); 1240 return GetADDR_32 (); 1241 } 1242 1243 ULEB128 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 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 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 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 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 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 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 1369 DwrFileName::~DwrFileName () 1370 { 1371 if (path != fname) 1372 free (path); 1373 } 1374 1375 1376 ////////////////////////////////////////////////////////// 1377 // class DwrLine 1378 DwrLine::DwrLine () 1379 { 1380 address = 0; 1381 file = 0; 1382 line = 0; 1383 column = 0; 1384 } 1385 1386 DwrLine::~DwrLine () { } 1387 1388 1389 ////////////////////////////////////////////////////////// 1390 // class DwrLineRegs 1391 static int 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 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 1490 DwrLineRegs::~DwrLineRegs () 1491 { 1492 Destroy (dir_names); 1493 Destroy (file_names); 1494 Destroy (lines); 1495 delete debug_lineSec; 1496 } 1497 1498 Vector <DwrFileName *> * 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 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 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 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 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 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 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 *> * 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 * 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 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 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 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 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 * 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 * 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 * 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 * 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 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 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* 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 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 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 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 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 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 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 * 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 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 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 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