Changeset d8eef0a in rtems-tools
- Timestamp:
- 05/10/18 18:12:27 (4 years ago)
- Branches:
- 5, master
- Children:
- 1c5206b
- Parents:
- 1318c11
- git-author:
- Chris Johns <chrisj@…> (05/10/18 18:12:27)
- git-committer:
- Chris Johns <chrisj@…> (06/18/18 02:26:16)
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
linkers/rtems-addr2line.cpp
r1318c11 rd8eef0a 55 55 { "verbose", no_argument, NULL, 'v' }, 56 56 { "executable", required_argument, NULL, 'e' }, 57 { "functions" , no_argument, NULL, 'f' }, 57 58 { "addresses", no_argument, NULL, 'a' }, 58 59 { "pretty-print", no_argument, NULL, 'p' }, … … 70 71 << " -v : verbose (trace import parts), can supply multiple times" << std::endl 71 72 << " to increase verbosity (also --verbose)" << std::endl 72 << " -e : executable (also --executablewarn)" << std::endl 73 << " -e : executable (also --executable)" << std::endl 74 << " -f : show function names (also --functions)" << std::endl 73 75 << " -a : show addresses (also --addresses)" << std::endl 74 76 << " -p : human readable format (also --pretty-print)" << std::endl … … 128 130 { 129 131 std::string exe_name = "a.out"; 132 bool show_functions = false; 130 133 bool show_addresses = false; 131 134 bool pretty_print = false; … … 136 139 while (true) 137 140 { 138 int opt = ::getopt_long (argc, argv, "hvVe: aps", rld_opts, NULL);141 int opt = ::getopt_long (argc, argv, "hvVe:faps", rld_opts, NULL); 139 142 if (opt < 0) 140 143 break; … … 155 158 case 'e': 156 159 exe_name = optarg; 160 break; 161 162 case 'f': 163 show_functions = true; 157 164 break; 158 165 … … 214 221 debug.begin (exe.elf ()); 215 222 debug.load_debug (); 223 debug.load_types (); 224 debug.load_functions (); 216 225 217 226 for (int arg = 0; arg < argc; ++arg) … … 243 252 else 244 253 std::cout << std::endl; 254 } 255 256 if (show_functions) 257 { 258 std::string function; 259 debug.get_function (location, function); 260 std::cout << function << " at "; 245 261 } 246 262 -
linkers/rtems-exeinfo.cpp
r1318c11 rd8eef0a 294 294 exe.load_symbols (symbols, true); 295 295 debug.load_debug (); 296 debug.load_types (); 296 297 symbols.globals (addresses); 297 298 symbols.weaks (addresses); … … 322 323 "-fbuilding-libgcc", 323 324 "-fno-implicit-templates", 325 "-fimplicit-templates", 324 326 "-ffunction-sections", 325 327 "-fdata-sections", -
rtemstoolkit/elftoolchain/libdwarf/dwarf_die.c
r1318c11 rd8eef0a 79 79 80 80 ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; 81 cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; 81 if (die != NULL && die->die_cu != NULL) 82 cu = die->die_cu; 83 else 84 cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; 82 85 83 86 if (cu == NULL) { -
rtemstoolkit/rld-dwarf-types.h
r1318c11 rd8eef0a 36 36 * Hide the types from libdwarf we use. 37 37 */ 38 typedef ::Dwarf_Debug dwarf; 39 typedef ::Dwarf_Handler dwarf_handler; 40 typedef ::Dwarf_Error dwarf_error; 41 typedef ::Dwarf_Die dwarf_die; 42 typedef ::Dwarf_Line dwarf_line; 43 typedef ::Dwarf_Ptr dwarf_pointer; 44 typedef ::Dwarf_Addr dwarf_address; 45 typedef ::Dwarf_Off dwarf_offset; 46 typedef ::Dwarf_Half dwarf_half; 47 typedef ::Dwarf_Signed dwarf_signed; 48 typedef ::Dwarf_Unsigned dwarf_unsigned; 49 typedef ::Dwarf_Bool dwarf_bool; 50 typedef ::Dwarf_Sig8 dwarf_sig8; 51 typedef ::Dwarf_Line dwarf_line; 52 typedef ::Dwarf_Half dwarf_tag; 53 typedef ::Dwarf_Half dwarf_attr; 38 typedef ::Dwarf_Debug dwarf; 39 typedef ::Dwarf_Handler dwarf_handler; 40 typedef ::Dwarf_Error dwarf_error; 41 typedef ::Dwarf_Die dwarf_die; 42 typedef ::Dwarf_Line dwarf_line; 43 typedef ::Dwarf_Ptr dwarf_pointer; 44 typedef ::Dwarf_Addr dwarf_address; 45 typedef ::Dwarf_Off dwarf_offset; 46 typedef ::Dwarf_Half dwarf_half; 47 typedef ::Dwarf_Signed dwarf_signed; 48 typedef ::Dwarf_Unsigned dwarf_unsigned; 49 typedef ::Dwarf_Bool dwarf_bool; 50 typedef ::Dwarf_Sig8 dwarf_sig8; 51 typedef ::Dwarf_Line dwarf_line; 52 typedef ::Dwarf_Half dwarf_tag; 53 typedef ::Dwarf_Attribute dwarf_attribute; 54 typedef ::Dwarf_Half dwarf_attr; 55 typedef ::Dwarf_Ranges dwarf_ranges; 56 typedef enum ::Dwarf_Ranges_Entry_Type dwarf_ranges_type; 57 typedef enum ::Dwarf_Form_Class dwarf_form_class; 58 typedef ::Dwarf_Type dwarf_type; 54 59 } 55 60 } -
rtemstoolkit/rld-dwarf.cpp
r1318c11 rd8eef0a 38 38 namespace dwarf 39 39 { 40 typedef std::vector < dwarf_die > dies_active; 41 dies_active active_dies; 42 43 bool active_dies_present (dwarf_die die) 44 { 45 return std::find (active_dies.begin(), active_dies.end(), die) != active_dies.end(); 46 } 47 48 void dies_active_add (dwarf_die die) 49 { 50 if (active_dies_present (die)) 51 { 52 std::cout << "DDdd : dup : " << die << std::endl; 53 } 54 else 55 { 56 active_dies.push_back (die); 57 } 58 } 59 60 void dies_active_remove (dwarf_die die) 61 { 62 dies_active::iterator di = std::find (active_dies.begin(), active_dies.end(), die); 63 if (di == active_dies.end ()) 64 { 65 std::cout << "DDdd : no found : " << die << std::endl; 66 } 67 else 68 { 69 active_dies.erase (di); 70 } 71 } 72 40 73 /** 41 74 * The libdwarf error. … … 202 235 } 203 236 237 range::range (const dwarf_ranges* range) 238 : range_ (range) 239 { 240 } 241 242 range::range (const range& orig) 243 : range_ (orig.range_) 244 { 245 } 246 247 range::~range () 248 { 249 } 250 251 dwarf_unsigned 252 range::addr1 () const 253 { 254 if (range_ == nullptr) 255 throw rld::error ("No valid range", "rld:dwarf:range:addr1"); 256 return range_->dwr_addr1; 257 } 258 259 dwarf_unsigned 260 range::addr2 () const 261 { 262 if (range_ == nullptr) 263 throw rld::error ("No valid range", "rld:dwarf:range:addr2"); 264 return range_->dwr_addr2; 265 } 266 267 dwarf_ranges_type 268 range::type () const 269 { 270 if (range_ == nullptr) 271 throw rld::error ("No valid range", "rld:dwarf:range:type"); 272 return range_->dwr_type; 273 } 274 275 bool 276 range::empty () const 277 { 278 /** 279 * See DWARF 2.17.3. 280 * 281 * A bounded range entry whose beginning and ending address offsets are 282 * equal (including zero) indicates an empty range and may be ignored. 283 */ 284 return type () == DW_RANGES_ENTRY && addr1 () == addr2 (); 285 } 286 287 bool 288 range::end () const 289 { 290 return type () == DW_RANGES_END; 291 } 292 293 range& 294 range::operator = (const range& rhs) 295 { 296 if (this != &rhs) 297 range_ = rhs.range_; 298 return *this; 299 } 300 301 void 302 range::dump () 303 { 304 dwarf_ranges_type type_ = type (); 305 const char* type_s = "invalid"; 306 const char* type_labels[] = { 307 "BOUNDED", 308 "BASE", 309 "END" 310 }; 311 if (type_ <= DW_RANGES_END) 312 type_s = type_labels[type_]; 313 std::cout << type_s << '-' 314 << std::hex << std::setfill ('0') 315 << "0x" << std::setw (8) << addr1 () 316 << ":0x" << std::setw (8) << addr2 (); 317 } 318 319 address_ranges::address_ranges (file& debug) 320 : debug (debug), 321 offset (-1), 322 dranges (nullptr), 323 dranges_count (0) 324 { 325 } 326 327 address_ranges::address_ranges (debug_info_entry& die) 328 : debug (die.get_debug ()), 329 offset (-1), 330 dranges (nullptr), 331 dranges_count (0) 332 { 333 load (die); 334 } 335 336 address_ranges::address_ranges (file& debug, dwarf_offset offset) 337 : debug (debug), 338 offset (offset), 339 dranges (nullptr), 340 dranges_count (0) 341 { 342 load (offset); 343 } 344 345 address_ranges::address_ranges (const address_ranges& orig) 346 : debug (orig.debug), 347 offset (orig.offset) 348 { 349 load (orig.offset); 350 } 351 352 address_ranges::~address_ranges () 353 { 354 if (dranges != nullptr) 355 { 356 ::dwarf_ranges_dealloc (debug, dranges, dranges_count); 357 dranges = nullptr; 358 dranges_count = 0; 359 ranges_.clear (); 360 } 361 } 362 363 bool 364 address_ranges::load (debug_info_entry& die, bool error) 365 { 366 dwarf_attribute attr; 367 dwarf_error de; 368 int dr; 369 dr = ::dwarf_attr (die, DW_AT_ranges, &attr, &de); 370 if (dr != DW_DLV_OK) 371 { 372 if (!error) 373 return false; 374 libdwarf_error_check ("rld:dwarf::address_ranges:load", dr, de); 375 } 376 dr = ::dwarf_global_formref (attr, &offset, &de); 377 if (dr != DW_DLV_OK) 378 { 379 if (!error) 380 return false; 381 libdwarf_error_check ("rld:dwarf::address_ranges:load", dr, de); 382 } 383 load (offset); 384 return true; 385 } 386 387 bool 388 address_ranges::load (dwarf_offset offset_, bool error) 389 { 390 if (offset_ > 0) 391 { 392 if (dranges != nullptr) 393 ::dwarf_ranges_dealloc (debug, dranges, dranges_count); 394 395 dranges = nullptr; 396 dranges_count = 0; 397 398 offset = offset_; 399 400 dwarf_error de; 401 int dr; 402 403 dr = ::dwarf_get_ranges (debug, offset, 404 &dranges, &dranges_count, nullptr, &de); 405 if (dr != DW_DLV_OK) 406 { 407 if (!error) 408 return false; 409 libdwarf_error_check ("rld:dwarf::ranges:load", dr, de); 410 } 411 412 if (dranges != nullptr && dranges_count > 0) 413 { 414 for (dwarf_signed r = 0; r < dranges_count; ++r) 415 ranges_.push_back (range (&dranges[r])); 416 } 417 } 418 419 return true; 420 } 421 422 const ranges& 423 address_ranges::get () const 424 { 425 return ranges_; 426 } 427 428 bool 429 address_ranges::empty () const 430 { 431 return ranges_.empty (); 432 } 433 434 address_ranges& 435 address_ranges::operator = (const address_ranges& rhs) 436 { 437 if (this != &rhs) 438 { 439 if (debug != rhs.debug) 440 throw rld::error ("invalid debug", "address_ranges:="); 441 load (rhs.offset); 442 } 443 return *this; 444 } 445 446 void 447 address_ranges::dump () 448 { 449 bool first = true; 450 std::cout << '['; 451 for (auto& r : ranges_) 452 { 453 if (!first) 454 std::cout << ','; 455 r.dump (); 456 first = false; 457 } 458 std::cout << ']'; 459 } 460 204 461 line_addresses::line_addresses (file& debug, 205 462 debug_info_entry& die) … … 313 570 } 314 571 572 573 function::function (file& debug, debug_info_entry& die) 574 : debug (debug), 575 machine_code_ (false), 576 external_ (false), 577 declaration_ (false), 578 inline_ (DW_INL_not_inlined), 579 pc_low_ (0), 580 pc_high_ (0), 581 ranges_ (debug) 582 { 583 dwarf_bool db; 584 585 if (die.attribute (DW_AT_external, db, false)) 586 external_ = db ? true : false; 587 588 if (die.attribute (DW_AT_declaration, db, false)) 589 declaration_ = db ? true : false; 590 591 die.attribute (DW_AT_linkage_name, linkage_name_, false); 592 593 if (!die.attribute (DW_AT_inline, inline_, false)) 594 inline_ = DW_INL_not_inlined; 595 596 if (inline_ == DW_INL_declared_inlined) 597 { 598 die_dump_children (die, " +"); 599 } 600 601 /* 602 * If ranges are not found see if the PC low and PC high attributes 603 * can be found. 604 */ 605 ranges_.load (die, false); 606 if (ranges_.empty ()) 607 { 608 bool is_address; 609 if (die.get_lowpc (pc_low_) && die.get_highpc (pc_high_, is_address)) 610 { 611 machine_code_ = true; 612 if (!is_address) 613 pc_high_ += pc_low_; 614 } 615 } 616 else 617 { 618 for (auto& r : ranges_.get ()) 619 { 620 if (!r.end () && !r.empty ()) 621 { 622 machine_code_ = true; 623 break; 624 } 625 } 626 } 627 628 if (declaration_) 629 { 630 die.attribute (DW_AT_name, name_); 631 } 632 else 633 { 634 /* 635 * Get the name attribute. (if present) 636 */ 637 if (!die.attribute (DW_AT_name, name_, false)) 638 { 639 bool found = false; 640 641 /* 642 * For inlined function, the actual name is probably in the DIE 643 * referenced by DW_AT_abstract_origin. (if present) 644 */ 645 dwarf_attribute abst_at; 646 if (die.attribute (DW_AT_abstract_origin, abst_at, false)) 647 { 648 dwarf_offset abst_at_die_offset; 649 dwarf_error de; 650 int dr; 651 dr = ::dwarf_global_formref (abst_at, &abst_at_die_offset, &de); 652 if (dr == DW_DLV_OK) 653 { 654 debug_info_entry abst_at_die (debug, abst_at_die_offset); 655 if (abst_at_die.attribute (DW_AT_name, name_, false)) 656 found = true; 657 } 658 } 659 660 /* 661 * If DW_AT_name is not present, but DW_AT_specification is present, 662 * then probably the actual name is in the DIE referenced by 663 * DW_AT_specification. 664 */ 665 if (!found) 666 { 667 dwarf_attribute spec; 668 if (die.attribute (DW_AT_specification, spec, false)) 669 { 670 dwarf_offset spec_die_offset; 671 dwarf_error de; 672 int dr; 673 dr = ::dwarf_global_formref (abst_at, &spec_die_offset, &de); 674 if (dr == DW_DLV_OK) 675 { 676 debug_info_entry spec_die (debug, spec_die_offset); 677 if (spec_die.attribute (DW_AT_name, name_, false)) 678 found = true; 679 } 680 } 681 } 682 } 683 684 if (die.tag () == DW_TAG_inlined_subroutine) 685 { 686 die.attribute (DW_AT_call_file, call_file_, false); 687 } 688 } 689 690 if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) 691 { 692 std::cout << "dwarf::function: "; 693 if (name_.empty ()) 694 std::cout << "NO NAME"; 695 else 696 std::cout << name_; 697 if (!has_machine_code ()) 698 std::cout << " NO MACHINE CODE"; 699 else 700 std::cout << std::hex << std::setfill ('0') 701 << " pc_low = 0x" << std::setw (8) << pc_low () 702 << " pc_high = 0x" << std::setw (8) << pc_high () 703 << std::dec << std::setfill (' '); 704 std::cout << std::endl; 705 } 706 } 707 708 function::~function () 709 { 710 } 711 712 std::string 713 function::name () const 714 { 715 return name_; 716 } 717 718 const address_ranges& 719 function::get_ranges () const 720 { 721 return ranges_; 722 } 723 724 dwarf_unsigned 725 function::pc_low () const 726 { 727 if (ranges_.empty ()) 728 return pc_low_; 729 dwarf_address addr = ~0; 730 for (auto& r : ranges_.get ()) 731 { 732 if (!r.end () && !r.empty () && r.addr1 () < addr) 733 addr = r.addr1 (); 734 } 735 return addr; 736 } 737 738 dwarf_unsigned 739 function::pc_high () const 740 { 741 if (ranges_.empty ()) 742 return pc_high_; 743 dwarf_address addr = 0; 744 for (auto& r : ranges_.get ()) 745 { 746 if (!r.end () && !r.empty () && r.addr2 () > addr) 747 addr = r.addr1 (); 748 } 749 return addr; 750 } 751 752 bool 753 function::has_machine_code () const 754 { 755 return machine_code_; 756 } 757 758 bool 759 function::is_external () const 760 { 761 return external_; 762 } 763 764 bool 765 function::is_declaration () const 766 { 767 return declaration_; 768 } 769 770 bool 771 function::is_inlined () const 772 { 773 return inline_ == DW_INL_declared_inlined; 774 } 775 776 std::string 777 function::call_file () const 778 { 779 return call_file_; 780 } 781 782 bool 783 function::inside (dwarf_address addr) const 784 { 785 return !name_.empty () && has_machine_code () && 786 addr >= pc_low () && addr <= pc_high (); 787 } 788 315 789 debug_info_entry::debug_info_entry (file& debug) 316 790 : debug (debug), … … 335 809 offset_ (offset__) 336 810 { 811 dwarf_die ddie; 812 dwarf_error de; 813 int dr; 814 dr = ::dwarf_offdie (debug, offset_, &ddie, &de); 815 libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de); 816 die = ddie; 817 } 818 819 debug_info_entry::debug_info_entry (const debug_info_entry& orig) 820 : debug (orig.debug), 821 die (nullptr), 822 tag_ (orig.tag_), 823 offset_ (orig.offset_) 824 { 825 if (offset_ != 0) 826 { 827 dwarf_die ddie; 337 828 dwarf_error de; 338 829 int dr; 339 dr = ::dwarf_offdie (debug, offset_, &d ie, &de);830 dr = ::dwarf_offdie (debug, offset_, &ddie, &de); 340 831 libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de); 832 die = ddie; 833 } 341 834 } 342 835 … … 379 872 } 380 873 874 debug_info_entry& 875 debug_info_entry::operator = (dwarf_offset offset__) 876 { 877 dealloc (); 878 if (offset__ != 0) 879 { 880 dwarf_die ddie; 881 dwarf_error de; 882 int dr; 883 offset_ = offset__; 884 tag_ = 0; 885 dr = ::dwarf_offdie (debug, offset_, &ddie, &de); 886 libdwarf_error_check ("debug_info_entry:operator=", dr, de); 887 die = ddie; 888 } 889 return *this; 890 } 891 381 892 bool 382 893 debug_info_entry::operator == (debug_info_entry& rhs) const … … 399 910 dwarf_error de; 400 911 int dr; 401 dr = ::dwarf_tag (die, &tag_, &de);912 dr = ::dwarf_tag (die, &tag_, &de); 402 913 libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de); 403 914 } … … 419 930 420 931 bool 932 debug_info_entry::get_lowpc (dwarf_address& addr, bool error) const 933 { 934 dwarf_error de; 935 int dr; 936 dr = ::dwarf_lowpc (die, &addr, &de); 937 if (error) 938 libdwarf_error_check ("debug_info_entry:lowpc", dr, de); 939 return dr == DW_DLV_OK; 940 } 941 942 bool 943 debug_info_entry::get_highpc (dwarf_address& addr, 944 bool& is_address, 945 bool error) const 946 { 947 dwarf_half form; 948 dwarf_form_class class_; 949 dwarf_error de; 950 int dr; 951 dr = ::dwarf_highpc_b (die, &addr, &form, &class_, &de); 952 if (error) 953 libdwarf_error_check ("debug_info_entry:highpc", dr, de); 954 is_address = class_ == DW_FORM_CLASS_ADDRESS; 955 return dr == DW_DLV_OK; 956 } 957 958 bool 959 debug_info_entry::attribute (dwarf_attr attr, 960 dwarf_attribute& value, 961 bool error) const 962 { 963 dwarf_error de; 964 int dr; 965 dr = ::dwarf_attr (die, attr, &value, &de); 966 if (error) 967 libdwarf_error_check ("debug_info_entry:attribute(attr)", dr, de); 968 return dr == DW_DLV_OK; 969 } 970 971 bool 972 debug_info_entry::attribute (dwarf_attr attr, 973 dwarf_bool& value, 974 bool error) const 975 { 976 dwarf_error de; 977 int dr; 978 dr = ::dwarf_attrval_flag (die, attr, &value, &de); 979 if (error) 980 libdwarf_error_check ("debug_info_entry:attribute(flag)", dr, de); 981 return dr == DW_DLV_OK; 982 } 983 984 bool 421 985 debug_info_entry::attribute (dwarf_attr attr, 422 986 dwarf_unsigned& value, … … 427 991 dr = ::dwarf_attrval_unsigned (die, attr, &value, &de); 428 992 if (error) 429 libdwarf_error_check ("debug_info_entry:attribute 993 libdwarf_error_check ("debug_info_entry:attribute(unsigned)", dr, de); 430 994 return dr == DW_DLV_OK; 431 995 } … … 442 1006 dr = ::dwarf_attrval_string (die, attr, &s, &de); 443 1007 if (error) 444 libdwarf_error_check ("debug_info_entry:attribute 1008 libdwarf_error_check ("debug_info_entry:attribute(string)", dr, de); 445 1009 if (s != nullptr) 446 1010 value = s; … … 474 1038 } 475 1039 1040 bool 1041 debug_info_entry::ranges (dwarf_ranges*& ranges, 1042 dwarf_signed& rangescount) const 1043 { 1044 dwarf_unsigned ranges_off; 1045 if (attribute (DW_AT_ranges, ranges_off, false)) 1046 { 1047 dwarf_error de; 1048 int dr; 1049 dr = ::dwarf_get_ranges (debug, ranges_off, 1050 &ranges, &rangescount, nullptr, &de); 1051 libdwarf_error_check ("debug_info_entry:ranges ", dr, de); 1052 return ranges != nullptr && rangescount > 0; 1053 } 1054 return false; 1055 } 1056 1057 bool 1058 debug_info_entry::get_child (debug_info_entry& child_die) 1059 { 1060 dwarf_error de; 1061 int dr; 1062 dr = ::dwarf_child (die, child_die, &de); 1063 return dr == DW_DLV_OK; 1064 } 1065 1066 bool 1067 debug_info_entry::get_sibling (debug_info_entry& sibling_die) 1068 { 1069 dwarf_error de; 1070 int dr; 1071 dr = ::dwarf_siblingof (debug, die, sibling_die, &de); 1072 if (dr == DW_DLV_NO_ENTRY) 1073 return false; 1074 libdwarf_error_check ("compilation_unit::sibling", dr, de); 1075 return true; 1076 } 1077 1078 file& 1079 debug_info_entry::get_debug () 1080 { 1081 return debug; 1082 } 1083 476 1084 void 477 1085 debug_info_entry::dealloc () … … 480 1088 ::dwarf_dealloc (debug, die, DW_DLA_DIE); 481 1089 die = nullptr; 1090 } 1091 } 1092 1093 void 1094 debug_info_entry::dump (std::string prefix, bool newline) 1095 { 1096 const char* s; 1097 ::dwarf_get_TAG_name (tag (), &s); 1098 std::cout << prefix << s << std::endl; 1099 1100 dwarf_attribute* attributes; 1101 dwarf_signed attr_count; 1102 dwarf_error de; 1103 int dr; 1104 1105 dr = ::dwarf_attrlist (die, &attributes, &attr_count, &de); 1106 if (dr == DW_DLV_OK) 1107 { 1108 for (int a = 0; a < attr_count; ++a) 1109 { 1110 dwarf_attr attr; 1111 dr = ::dwarf_whatattr (attributes[a], &attr, &de); 1112 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1113 dwarf_half form; 1114 dr = ::dwarf_whatform (attributes[a], &form, &de); 1115 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1116 const char* f; 1117 dwarf_get_FORM_name (form, &f); 1118 dwarf_get_AT_name (attr, &s); 1119 if (a > 0) 1120 std::cout << std::endl; 1121 std::cout << prefix << " - " << s << " (" << attr << ") [" << f << ']'; 1122 debug_info_entry v_die (debug); 1123 address_ranges v_ranges (debug); 1124 dwarf_unsigned v_unsigned; 1125 dwarf_bool v_bool; 1126 dwarf_offset v_offset; 1127 switch (form) 1128 { 1129 case DW_FORM_block: 1130 case DW_FORM_block1: 1131 case DW_FORM_block2: 1132 case DW_FORM_block4: 1133 break; 1134 case DW_FORM_addr: 1135 case DW_FORM_data1: 1136 case DW_FORM_data2: 1137 case DW_FORM_data4: 1138 case DW_FORM_data8: 1139 case DW_FORM_udata: 1140 dr = ::dwarf_attrval_unsigned (die, attr, &v_unsigned, &de); 1141 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1142 std::cout << " : " 1143 << std::hex << std::setfill ('0') 1144 << std::setw (8) << v_unsigned 1145 << std::dec << std::setfill (' ') 1146 << " (" << v_unsigned << ')'; 1147 break; 1148 case DW_FORM_ref1: 1149 case DW_FORM_ref2: 1150 case DW_FORM_ref4: 1151 case DW_FORM_ref8: 1152 case DW_FORM_ref_udata: 1153 dr = ::dwarf_global_formref (attributes[a], &v_offset, &de); 1154 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1155 std::cout << " : " 1156 << std::hex << std::setfill ('0') 1157 << std::setw (8) << v_offset 1158 << std::dec << std::setfill (' ') 1159 << " (" << v_offset << ')'; 1160 switch (attr) 1161 { 1162 case DW_AT_abstract_origin: 1163 case DW_AT_specification: 1164 v_die = v_offset; 1165 std::cout << std::endl; 1166 v_die.dump (' ' + prefix, false); 1167 break; 1168 default: 1169 break; 1170 } 1171 break; 1172 case DW_FORM_exprloc: 1173 break; 1174 case DW_FORM_flag: 1175 case DW_FORM_flag_present: 1176 dr = ::dwarf_attrval_flag (die, attr, &v_bool, &de); 1177 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1178 std::cout << " : " << v_bool; 1179 break; 1180 break; 1181 case DW_FORM_string: 1182 case DW_FORM_strp: 1183 dr = ::dwarf_attrval_string (die, attr, &s, &de); 1184 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1185 std::cout << " : " << s; 1186 break; 1187 case DW_FORM_sec_offset: 1188 switch (attr) 1189 { 1190 case DW_AT_ranges: 1191 dr = ::dwarf_global_formref (attributes[a], &v_offset, &de); 1192 libdwarf_error_check ("debug_info_entry::dump", dr, de); 1193 std::cout << ' '; 1194 v_ranges.load (v_offset); 1195 v_ranges.dump (); 1196 break; 1197 default: 1198 break; 1199 } 1200 break; 1201 case DW_FORM_indirect: 1202 case DW_FORM_ref_addr: 1203 case DW_FORM_ref_sig8: 1204 case DW_FORM_sdata: 1205 break; 1206 } 1207 } 1208 if (newline) 1209 std::cout << std::endl; 1210 } 1211 } 1212 1213 void 1214 die_dump_children (debug_info_entry die, 1215 std::string prefix, 1216 int nesting, 1217 int depth) 1218 { 1219 debug_info_entry child (die.get_debug ()); 1220 if (die.get_child (child)) 1221 die_dump (child, prefix, nesting, depth); 1222 } 1223 1224 void 1225 die_dump (debug_info_entry die, 1226 std::string prefix, 1227 int nesting, 1228 int depth) 1229 { 1230 ++nesting; 1231 1232 for (int n = 0; n < nesting; ++n) 1233 prefix += ' '; 1234 1235 while (true) 1236 { 1237 die.dump (prefix); 1238 1239 if (depth < 0 || nesting < depth) 1240 die_dump_children (die, prefix); 1241 1242 debug_info_entry next (die.get_debug ()); 1243 1244 if (!die.get_sibling (next)) 1245 break; 1246 1247 die = next; 482 1248 } 483 1249 } … … 490 1256 pc_low_ (0), 491 1257 pc_high_ (0), 1258 ranges_ (debug), 492 1259 die_offset (die.offset ()), 493 1260 source_ (debug, die_offset) … … 498 1265 die.attribute (DW_AT_producer, producer_); 499 1266 500 die.attribute (DW_AT_low_pc, pc_low_, false); 501 502 if (!die.attribute (DW_AT_high_pc, pc_high_, false)) 503 pc_high_ = ~0U; 504 505 if (pc_high_ < pc_low_) 506 pc_high_ += pc_low_; 1267 ranges_.load (die, false); 1268 1269 if (ranges_.empty ()) 1270 { 1271 bool is_address; 1272 die.get_lowpc (pc_low_); 1273 if (die.get_highpc (pc_high_, is_address)) 1274 { 1275 if (!is_address) 1276 pc_high_ += pc_low_; 1277 } 1278 else 1279 pc_high_ = ~0U; 1280 } 1281 else 1282 { 1283 pc_low_ = ~0U; 1284 for (auto& r : ranges_.get ()) 1285 { 1286 if (!r.end () && !r.empty () && r.addr1 () < pc_low_) 1287 pc_low_ = r.addr1 (); 1288 } 1289 pc_high_ = 0U; 1290 for (auto& r : ranges_.get ()) 1291 { 1292 if (!r.end () && !r.empty () && r.addr2 () > pc_high_) 1293 pc_high_ = r.addr2 (); 1294 } 1295 } 507 1296 508 1297 if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) … … 513 1302 << ": (0x" << std::setw (8) << offset_ << ") "; 514 1303 if (pc_low_ != 0 && pc_high_ != ~0U) 515 std::cout << "pc_low = " << std::setw (8) << pc_low_516 << " pc_high = " << std::setw (8) << pc_high_;1304 std::cout << "pc_low = 0x" << std::setw (8) << pc_low_ 1305 << " pc_high = 0x" << std::setw (8) << pc_high_; 517 1306 std::cout << std::setfill (' ') << std::dec 518 1307 << std::endl … … 611 1400 pc_low_ (orig.pc_low_), 612 1401 pc_high_ (orig.pc_high_), 1402 ranges_ (orig.ranges_), 613 1403 die_offset (orig.die_offset), 614 1404 source_ (debug, die_offset) … … 621 1411 compilation_unit::~compilation_unit () 622 1412 { 1413 } 1414 1415 void 1416 compilation_unit::load_types () 1417 { 1418 //dump_die (); 1419 } 1420 1421 void 1422 compilation_unit::load_functions () 1423 { 1424 debug_info_entry die (debug, die_offset); 1425 debug_info_entry ret_die (debug); 1426 dwarf_error de; 1427 int dr; 1428 dr = ::dwarf_child(die, ret_die, &de); 1429 if (dr == DW_DLV_OK) 1430 load_functions (ret_die); 1431 } 1432 1433 void 1434 compilation_unit::load_functions (debug_info_entry& die) 1435 { 1436 while (true) 1437 { 1438 if (die.tag () == DW_TAG_subprogram || 1439 die.tag () == DW_TAG_entry_point || 1440 die.tag () == DW_TAG_inlined_subroutine) 1441 { 1442 function func (debug, die); 1443 if (func.has_machine_code () && 1444 func.pc_low () >= pc_low_ && func.pc_high () <= pc_high_) 1445 { 1446 functions_.push_back (func); 1447 } 1448 } 1449 1450 debug_info_entry ret_die (debug); 1451 dwarf_error de; 1452 int dr; 1453 1454 dr = ::dwarf_child(die, ret_die, &de); 1455 if (dr == DW_DLV_OK) 1456 load_functions (ret_die); 1457 1458 dr = ::dwarf_siblingof (debug, die, ret_die, &de); 1459 if (dr == DW_DLV_NO_ENTRY) 1460 break; 1461 libdwarf_error_check ("compilation_unit:load_functions", dr, de); 1462 1463 die = ret_die; 1464 } 623 1465 } 624 1466 … … 670 1512 } 671 1513 1514 functions& 1515 compilation_unit::get_functions () 1516 { 1517 return functions_; 1518 } 1519 672 1520 bool 673 1521 compilation_unit::inside (dwarf_unsigned addr) const 674 1522 { 675 if (!addr_lines_.empty ())676 {677 auto first = addr_lines_.begin ();678 auto last = addr_lines_.end () - 1;679 return first->location () <= addr && addr <= last->location ();680 }681 1523 return addr >= pc_low_ && addr < pc_high_; 682 1524 } … … 701 1543 pc_low_ = rhs.pc_low_; 702 1544 pc_high_ = rhs.pc_high_; 1545 ranges_ = rhs.ranges_; 703 1546 die_offset = rhs.die_offset; 704 1547 } 705 1548 return *this; 1549 } 1550 1551 void 1552 compilation_unit::dump_die () 1553 { 1554 debug_info_entry die (debug, die_offset); 1555 std::cout << "CU @ 0x" << std::hex << offset_ << std::dec << std::endl; 1556 die_dump_children (die, ""); 706 1557 } 707 1558 … … 737 1588 : debug (nullptr), 738 1589 elf_ (nullptr) 739 1590 { 740 1591 } 741 1592 … … 831 1682 832 1683 /* 833 * F nd the CU DIE.1684 * Find the CU DIE. 834 1685 */ 835 1686 debug_info_entry die (*this); … … 853 1704 cu_offset = cu_next_offset; 854 1705 } 1706 } 1707 1708 void 1709 file::load_types () 1710 { 1711 for (auto& cu : cus) 1712 cu.load_types (); 1713 } 1714 1715 void 1716 file::load_functions () 1717 { 1718 for (auto& cu : cus) 1719 cu.load_functions (); 855 1720 } 856 1721 … … 899 1764 } 900 1765 1766 bool 1767 file::get_function (const unsigned int addr, 1768 std::string& name) 1769 { 1770 name = "unknown"; 1771 1772 for (auto& cu : cus) 1773 { 1774 for (auto& func : cu.get_functions ()) 1775 { 1776 if (func.inside (addr)) 1777 { 1778 name = func.name (); 1779 return true; 1780 } 1781 } 1782 } 1783 1784 return false; 1785 } 1786 901 1787 void 902 1788 file::get_producer_sources (producer_sources& producers) -
rtemstoolkit/rld-dwarf.h
r1318c11 rd8eef0a 115 115 116 116 /** 117 * Range, one entry in an address range container. 118 */ 119 class range 120 { 121 public: 122 range (const dwarf_ranges* range); 123 range (const range& orig); 124 ~range (); 125 126 /** 127 * Address 1 in the range. 128 */ 129 dwarf_unsigned addr1 () const; 130 dwarf_unsigned addr2 () const; 131 132 /** 133 * Get the type of range. 134 */ 135 dwarf_ranges_type type () const; 136 137 /** 138 * Is the range the end? 139 */ 140 bool end () const; 141 142 /** 143 * Is the range empty? See DWARF 2.17.3. 144 */ 145 bool empty () const; 146 147 /** 148 * Assigment operator. 149 */ 150 range& operator = (const range& rhs); 151 152 /** 153 * Dump the range. 154 */ 155 void dump (); 156 157 private: 158 159 const dwarf_ranges* range_; 160 }; 161 162 typedef std::vector < range > ranges; 163 164 /** 165 * Address ranges, is a range of addresses. 166 */ 167 class address_ranges 168 { 169 public: 170 address_ranges (file& debug); 171 address_ranges (debug_info_entry& die); 172 address_ranges (file& debug, dwarf_offset offset); 173 address_ranges (const address_ranges& orig); 174 ~address_ranges (); 175 176 /** 177 * Load the ranges from the DIE. 178 */ 179 bool load (debug_info_entry& die, bool error = true); 180 181 /** 182 * Load the ranges from the debug info. 183 */ 184 bool load (dwarf_offset offset, bool error = true); 185 186 /** 187 * Get the container. 188 */ 189 const ranges& get () const; 190 191 /** 192 * Address range empty? 193 */ 194 bool empty () const; 195 196 /** 197 * Assigment operator. 198 */ 199 address_ranges& operator = (const address_ranges& rhs); 200 201 /** 202 * Dump the address ranges. 203 */ 204 void dump (); 205 206 private: 207 208 file& debug; 209 dwarf_offset offset; 210 dwarf_ranges* dranges; 211 dwarf_signed dranges_count; 212 ranges ranges_; 213 }; 214 215 /** 117 216 * Line addresses. 118 217 */ … … 151 250 sources (file& debug, dwarf_offset die_offset); 152 251 sources (const sources& orig); 153 //sources (sources&& orig);154 252 ~sources (); 155 253 … … 178 276 179 277 /** 278 * Function. 279 */ 280 class function 281 { 282 public: 283 function (file& debug, debug_info_entry& die); 284 ~function (); 285 286 /** 287 * Get the name of the function. 288 */ 289 std::string name () const; 290 291 /** 292 * Get the linkage name of the function. 293 */ 294 std::string linkage_name () const; 295 296 /** 297 * Get the ranges for the funcion, if empty the PC low and PC high values 298 * will be valid. 299 */ 300 const address_ranges& get_ranges () const; 301 302 /** 303 * Get the PC low address, valid if ranges is empty. 304 */ 305 dwarf_unsigned pc_low () const; 306 307 /** 308 * Get the PC high address, valid if ranges is empty. 309 */ 310 dwarf_unsigned pc_high () const; 311 312 /** 313 * Does the function have machine code in the image? 314 */ 315 bool has_machine_code () const; 316 317 /** 318 * Is the function external? 319 */ 320 bool is_external () const; 321 322 /** 323 * Is this just a declaration? 324 */ 325 bool is_declaration () const; 326 327 /** 328 * Is the function inlined? 329 */ 330 bool is_inlined () const; 331 332 /** 333 * Get the call file of the inlined function. 334 */ 335 std::string call_file () const; 336 337 /** 338 * Is the address inside the function. 339 */ 340 bool inside (dwarf_address addr) const; 341 342 private: 343 344 file& debug; 345 bool machine_code_; 346 bool external_; 347 bool declaration_; 348 dwarf_unsigned inline_; 349 dwarf_unsigned pc_low_; 350 dwarf_unsigned pc_high_; 351 address_ranges ranges_; 352 std::string name_; 353 std::string linkage_name_; 354 std::string call_file_; 355 }; 356 357 typedef std::vector < function > functions; 358 359 /** 180 360 * Debug Information Element (DIE). 181 361 * … … 191 371 debug_info_entry (file& debug, dwarf_die& die); 192 372 debug_info_entry (file& debug, dwarf_offset offset); 373 debug_info_entry (const debug_info_entry& orig); 193 374 194 375 /** … … 212 393 */ 213 394 debug_info_entry& operator = (debug_info_entry& rhs); 395 debug_info_entry& operator = (dwarf_offset offset); 214 396 215 397 /** … … 228 410 */ 229 411 dwarf_offset offset (); 412 413 /** 414 * Get the low PC. 415 */ 416 bool get_lowpc (dwarf_address& addr, bool error = false) const; 417 418 /** 419 * Get the high PC. 420 */ 421 bool get_highpc (dwarf_address& addr, 422 bool& is_address, 423 bool error = false) const; 424 425 /** 426 * Get an attribute. 427 */ 428 bool attribute (dwarf_attr attr, 429 dwarf_attribute& value, 430 bool error = true) const; 431 432 /** 433 * Get a flag. 434 */ 435 bool attribute (dwarf_attr attr, 436 dwarf_bool& value, 437 bool error = true) const; 230 438 231 439 /** … … 258 466 259 467 /** 468 * Get the ranges. 469 */ 470 bool ranges (dwarf_ranges*& ranges, dwarf_signed& rangescount) const; 471 472 /** 473 * Get the child. 474 */ 475 bool get_child (debug_info_entry& child_die); 476 477 /** 478 * Get the silbing 479 */ 480 bool get_sibling (debug_info_entry& sibling_die); 481 482 /** 483 * Get the debug info for this DIE. 484 */ 485 file& get_debug (); 486 487 /** 260 488 * deallocate the DIE. 261 489 */ 262 490 void dealloc (); 491 492 /** 493 * Dump this DIE. 494 */ 495 void dump (std::string prefix, bool newline = true); 263 496 264 497 private: … … 270 503 271 504 }; 505 506 /** 507 * Dump the DIE and all it's children and siblings. 508 */ 509 void die_dump_children (debug_info_entry die, 510 std::string prefix, 511 int nesting = 0, 512 int depth = -1); 513 514 /** 515 * Dump the DIE and all it's children and siblings. 516 */ 517 void die_dump (debug_info_entry die, 518 std::string prefix, 519 int nesting = 0, 520 int depth = -1); 272 521 273 522 /** … … 284 533 285 534 /** 535 * Load the types. 536 */ 537 void load_types (); 538 539 /** 540 * Load the functions. 541 */ 542 void load_functions (); 543 544 /** 286 545 * Name of the CU. 287 546 */ … … 312 571 313 572 /** 573 * Get the functions. 574 */ 575 functions& get_functions (); 576 577 /** 314 578 * Is the address inside the CU? If the PC low and high attributes are 315 579 * valid they are used or the lines are checked. … … 322 586 compilation_unit& operator = (const compilation_unit& rhs); 323 587 324 private: 588 /** 589 * Output the DIE tree. 590 */ 591 void dump_die (); 592 593 private: 594 595 void load_functions (debug_info_entry& die); 325 596 326 597 file& debug; ///< The DWARF debug handle. … … 330 601 dwarf_unsigned pc_low_; ///< The PC low address 331 602 dwarf_unsigned pc_high_; ///< The PC high address. 603 address_ranges ranges_; ///< Non-continous address range. 332 604 333 605 dwarf_offset die_offset; ///< The offset of the DIE in the image. … … 335 607 sources source_; ///< Sources table for this CU. 336 608 addresses addr_lines_; ///< Address table. 609 610 functions functions_; ///< The functions in the CU. 337 611 }; 338 612 … … 413 687 414 688 /** 689 * Load the DWARF type information. 690 */ 691 void load_types (); 692 693 /** 694 * Load the DWARF functions information. 695 */ 696 void load_functions (); 697 698 /** 415 699 * Get the source location given an address. 416 700 */ … … 420 704 421 705 /** 706 * Get the function given an address. 707 */ 708 bool get_function (const unsigned int address, 709 std::string& name); 710 711 /** 422 712 * Get the producer sources from the compilation units. 423 713 */
Note: See TracChangeset
for help on using the changeset viewer.