1 //===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "DWARFCompileUnit.h" 11 12 #include "lldb/Core/Mangled.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/Stream.h" 15 #include "lldb/Core/Timer.h" 16 #include "lldb/Symbol/ObjectFile.h" 17 #include "lldb/Target/ObjCLanguageRuntime.h" 18 19 #include "DWARFDebugAbbrev.h" 20 #include "DWARFDebugAranges.h" 21 #include "DWARFDebugInfo.h" 22 #include "DWARFDIECollection.h" 23 #include "DWARFFormValue.h" 24 #include "LogChannelDWARF.h" 25 #include "NameToDIE.h" 26 #include "SymbolFileDWARF.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 using namespace std; 31 32 33 extern int g_verbose; 34 35 DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : 36 m_dwarf2Data (dwarf2Data), 37 m_abbrevs (NULL), 38 m_user_data (NULL), 39 m_die_array (), 40 m_func_aranges_ap (), 41 m_base_addr (0), 42 m_offset (DW_INVALID_OFFSET), 43 m_length (0), 44 m_version (0), 45 m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()), 46 m_producer (eProducerInvalid) 47 { 48 } 49 50 void 51 DWARFCompileUnit::Clear() 52 { 53 m_offset = DW_INVALID_OFFSET; 54 m_length = 0; 55 m_version = 0; 56 m_abbrevs = NULL; 57 m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); 58 m_base_addr = 0; 59 m_die_array.clear(); 60 m_func_aranges_ap.reset(); 61 m_user_data = NULL; 62 m_producer = eProducerInvalid; 63 } 64 65 bool 66 DWARFCompileUnit::Extract(const DataExtractor &debug_info, uint32_t* offset_ptr) 67 { 68 Clear(); 69 70 m_offset = *offset_ptr; 71 72 if (debug_info.ValidOffset(*offset_ptr)) 73 { 74 dw_offset_t abbr_offset; 75 const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); 76 m_length = debug_info.GetU32(offset_ptr); 77 m_version = debug_info.GetU16(offset_ptr); 78 abbr_offset = debug_info.GetU32(offset_ptr); 79 m_addr_size = debug_info.GetU8 (offset_ptr); 80 81 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 82 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 83 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); 84 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 85 86 if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) 87 { 88 m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); 89 return true; 90 } 91 92 // reset the offset to where we tried to parse from if anything went wrong 93 *offset_ptr = m_offset; 94 } 95 96 return false; 97 } 98 99 100 dw_offset_t 101 DWARFCompileUnit::Extract(dw_offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs) 102 { 103 Clear(); 104 105 m_offset = offset; 106 107 if (debug_info_data.ValidOffset(offset)) 108 { 109 m_length = debug_info_data.GetU32(&offset); 110 m_version = debug_info_data.GetU16(&offset); 111 bool abbrevs_OK = debug_info_data.GetU32(&offset) == abbrevs->GetOffset(); 112 m_abbrevs = abbrevs; 113 m_addr_size = debug_info_data.GetU8 (&offset); 114 115 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 116 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 117 118 if (version_OK && addr_size_OK && abbrevs_OK && debug_info_data.ValidOffset(offset)) 119 return offset; 120 } 121 return DW_INVALID_OFFSET; 122 } 123 124 void 125 DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) 126 { 127 if (m_die_array.size() > 1) 128 { 129 // std::vectors never get any smaller when resized to a smaller size, 130 // or when clear() or erase() are called, the size will report that it 131 // is smaller, but the memory allocated remains intact (call capacity() 132 // to see this). So we need to create a temporary vector and swap the 133 // contents which will cause just the internal pointers to be swapped 134 // so that when "tmp_array" goes out of scope, it will destroy the 135 // contents. 136 137 // Save at least the compile unit DIE 138 DWARFDebugInfoEntry::collection tmp_array; 139 m_die_array.swap(tmp_array); 140 if (keep_compile_unit_die) 141 m_die_array.push_back(tmp_array.front()); 142 } 143 } 144 145 //---------------------------------------------------------------------- 146 // ParseCompileUnitDIEsIfNeeded 147 // 148 // Parses a compile unit and indexes its DIEs if it hasn't already been 149 // done. 150 //---------------------------------------------------------------------- 151 size_t 152 DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) 153 { 154 const size_t initial_die_array_size = m_die_array.size(); 155 if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) 156 return 0; // Already parsed 157 158 Timer scoped_timer (__PRETTY_FUNCTION__, 159 "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", 160 m_offset, 161 cu_die_only); 162 163 // Set the offset to that of the first DIE and calculate the start of the 164 // next compilation unit header. 165 uint32_t offset = GetFirstDIEOffset(); 166 uint32_t next_cu_offset = GetNextCompileUnitOffset(); 167 168 DWARFDebugInfoEntry die; 169 // Keep a flat array of the DIE for binary lookup by DIE offset 170 if (!cu_die_only) 171 { 172 LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS)); 173 if (log) 174 { 175 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log.get(), 176 "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]", 177 GetOffset()); 178 } 179 } 180 181 uint32_t depth = 0; 182 // We are in our compile unit, parse starting at the offset 183 // we were told to parse 184 const DataExtractor& debug_info_data = m_dwarf2Data->get_debug_info_data(); 185 std::vector<uint32_t> die_index_stack; 186 die_index_stack.reserve(32); 187 die_index_stack.push_back(0); 188 bool prev_die_had_children = false; 189 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); 190 while (offset < next_cu_offset && 191 die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset)) 192 { 193 // if (log) 194 // log->Printf("0x%8.8x: %*.*s%s%s", 195 // die.GetOffset(), 196 // depth * 2, depth * 2, "", 197 // DW_TAG_value_to_name (die.Tag()), 198 // die.HasChildren() ? " *" : ""); 199 200 const bool null_die = die.IsNULL(); 201 if (depth == 0) 202 { 203 uint64_t base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 204 if (base_addr == LLDB_INVALID_ADDRESS) 205 base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_entry_pc, 0); 206 SetBaseAddress (base_addr); 207 if (initial_die_array_size == 0) 208 AddDIE (die); 209 if (cu_die_only) 210 return 1; 211 } 212 else 213 { 214 if (null_die) 215 { 216 if (prev_die_had_children) 217 { 218 // This will only happen if a DIE says is has children 219 // but all it contains is a NULL tag. Since we are removing 220 // the NULL DIEs from the list (saves up to 25% in C++ code), 221 // we need a way to let the DIE know that it actually doesn't 222 // have children. 223 if (!m_die_array.empty()) 224 m_die_array.back().SetEmptyChildren(true); 225 } 226 } 227 else 228 { 229 die.SetParentIndex(m_die_array.size() - die_index_stack[depth-1]); 230 231 if (die_index_stack.back()) 232 m_die_array[die_index_stack.back()].SetSiblingIndex(m_die_array.size()-die_index_stack.back()); 233 234 // Only push the DIE if it isn't a NULL DIE 235 m_die_array.push_back(die); 236 } 237 } 238 239 if (null_die) 240 { 241 // NULL DIE. 242 if (!die_index_stack.empty()) 243 die_index_stack.pop_back(); 244 245 if (depth > 0) 246 --depth; 247 if (depth == 0) 248 break; // We are done with this compile unit! 249 250 prev_die_had_children = false; 251 } 252 else 253 { 254 die_index_stack.back() = m_die_array.size() - 1; 255 // Normal DIE 256 const bool die_has_children = die.HasChildren(); 257 if (die_has_children) 258 { 259 die_index_stack.push_back(0); 260 ++depth; 261 } 262 prev_die_had_children = die_has_children; 263 } 264 } 265 266 // Give a little bit of info if we encounter corrupt DWARF (our offset 267 // should always terminate at or before the start of the next compilation 268 // unit header). 269 if (offset > next_cu_offset) 270 { 271 m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8x\n", 272 GetOffset(), 273 offset); 274 } 275 276 // Since std::vector objects will double their size, we really need to 277 // make a new array with the perfect size so we don't end up wasting 278 // space. So here we copy and swap to make sure we don't have any extra 279 // memory taken up. 280 281 if (m_die_array.size () < m_die_array.capacity()) 282 { 283 DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end()); 284 exact_size_die_array.swap (m_die_array); 285 } 286 LogSP log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE)); 287 if (log) 288 { 289 StreamString strm; 290 DWARFDebugInfoEntry::DumpDIECollection (strm, m_die_array); 291 log->PutCString (strm.GetString().c_str()); 292 } 293 294 return m_die_array.size(); 295 } 296 297 298 dw_offset_t 299 DWARFCompileUnit::GetAbbrevOffset() const 300 { 301 return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; 302 } 303 304 305 306 bool 307 DWARFCompileUnit::Verify(Stream *s) const 308 { 309 const DataExtractor& debug_info = m_dwarf2Data->get_debug_info_data(); 310 bool valid_offset = debug_info.ValidOffset(m_offset); 311 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 312 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 313 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); 314 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 315 bool verbose = s->GetVerbose(); 316 if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK) 317 { 318 if (verbose) 319 s->Printf(" 0x%8.8x: OK\n", m_offset); 320 return true; 321 } 322 else 323 { 324 s->Printf(" 0x%8.8x: ", m_offset); 325 326 m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0); 327 s->EOL(); 328 if (valid_offset) 329 { 330 if (!length_OK) 331 s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length); 332 if (!version_OK) 333 s->Printf(" The 16 bit compile unit header version is not supported.\n"); 334 if (!abbr_offset_OK) 335 s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset()); 336 if (!addr_size_OK) 337 s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size); 338 } 339 else 340 s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n"); 341 } 342 return false; 343 } 344 345 346 void 347 DWARFCompileUnit::Dump(Stream *s) const 348 { 349 s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n", 350 m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); 351 } 352 353 354 static uint8_t g_default_addr_size = 4; 355 356 uint8_t 357 DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) 358 { 359 if (cu) 360 return cu->GetAddressByteSize(); 361 return DWARFCompileUnit::GetDefaultAddressSize(); 362 } 363 364 uint8_t 365 DWARFCompileUnit::GetDefaultAddressSize() 366 { 367 return g_default_addr_size; 368 } 369 370 void 371 DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) 372 { 373 g_default_addr_size = addr_size; 374 } 375 376 void 377 DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, 378 DWARFDebugAranges* debug_aranges, 379 bool clear_dies_if_already_not_parsed) 380 { 381 // This function is usually called if there in no .debug_aranges section 382 // in order to produce a compile unit level set of address ranges that 383 // is accurate. If the DIEs weren't parsed, then we don't want all dies for 384 // all compile units to stay loaded when they weren't needed. So we can end 385 // up parsing the DWARF and then throwing them all away to keep memory usage 386 // down. 387 const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; 388 389 DIE()->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); 390 391 // Keep memory down by clearing DIEs if this generate function 392 // caused them to be parsed 393 if (clear_dies) 394 ClearDIEs (true); 395 396 } 397 398 399 const DWARFDebugAranges & 400 DWARFCompileUnit::GetFunctionAranges () 401 { 402 if (m_func_aranges_ap.get() == NULL) 403 { 404 m_func_aranges_ap.reset (new DWARFDebugAranges()); 405 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 406 407 if (log) 408 { 409 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log.get(), 410 "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]", 411 GetOffset()); 412 } 413 DIE()->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); 414 const bool minimize = false; 415 m_func_aranges_ap->Sort(minimize); 416 } 417 return *m_func_aranges_ap.get(); 418 } 419 420 bool 421 DWARFCompileUnit::LookupAddress 422 ( 423 const dw_addr_t address, 424 DWARFDebugInfoEntry** function_die_handle, 425 DWARFDebugInfoEntry** block_die_handle 426 ) 427 { 428 bool success = false; 429 430 if (function_die_handle != NULL && DIE()) 431 { 432 433 const DWARFDebugAranges &func_aranges = GetFunctionAranges (); 434 435 // Re-check the aranges auto pointer contents in case it was created above 436 if (!func_aranges.IsEmpty()) 437 { 438 *function_die_handle = GetDIEPtr(func_aranges.FindAddress(address)); 439 if (*function_die_handle != NULL) 440 { 441 success = true; 442 if (block_die_handle != NULL) 443 { 444 DWARFDebugInfoEntry* child = (*function_die_handle)->GetFirstChild(); 445 while (child) 446 { 447 if (child->LookupAddress(address, m_dwarf2Data, this, NULL, block_die_handle)) 448 break; 449 child = child->GetSibling(); 450 } 451 } 452 } 453 } 454 } 455 return success; 456 } 457 458 //---------------------------------------------------------------------- 459 // Compare function DWARFDebugAranges::Range structures 460 //---------------------------------------------------------------------- 461 static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2) 462 { 463 return die1.GetOffset() < die2.GetOffset(); 464 } 465 466 //---------------------------------------------------------------------- 467 // GetDIEPtr() 468 // 469 // Get the DIE (Debug Information Entry) with the specified offset. 470 //---------------------------------------------------------------------- 471 DWARFDebugInfoEntry* 472 DWARFCompileUnit::GetDIEPtr(dw_offset_t die_offset) 473 { 474 if (die_offset != DW_INVALID_OFFSET) 475 { 476 ExtractDIEsIfNeeded (false); 477 DWARFDebugInfoEntry compare_die; 478 compare_die.SetOffset(die_offset); 479 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 480 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); 481 if (pos != end) 482 { 483 if (die_offset == (*pos).GetOffset()) 484 return &(*pos); 485 } 486 } 487 return NULL; // Not found in any compile units 488 } 489 490 //---------------------------------------------------------------------- 491 // GetDIEPtrContainingOffset() 492 // 493 // Get the DIE (Debug Information Entry) that contains the specified 494 // .debug_info offset. 495 //---------------------------------------------------------------------- 496 const DWARFDebugInfoEntry* 497 DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset) 498 { 499 if (die_offset != DW_INVALID_OFFSET) 500 { 501 ExtractDIEsIfNeeded (false); 502 DWARFDebugInfoEntry compare_die; 503 compare_die.SetOffset(die_offset); 504 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 505 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); 506 if (pos != end) 507 { 508 if (die_offset >= (*pos).GetOffset()) 509 { 510 DWARFDebugInfoEntry::iterator next = pos + 1; 511 if (next != end) 512 { 513 if (die_offset < (*next).GetOffset()) 514 return &(*pos); 515 } 516 } 517 } 518 } 519 return NULL; // Not found in any compile units 520 } 521 522 523 524 size_t 525 DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const 526 { 527 size_t old_size = dies.Size(); 528 DWARFDebugInfoEntry::const_iterator pos; 529 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 530 for (pos = m_die_array.begin(); pos != end; ++pos) 531 { 532 if (pos->Tag() == tag) 533 dies.Append (&(*pos)); 534 } 535 536 // Return the number of DIEs added to the collection 537 return dies.Size() - old_size; 538 } 539 540 //void 541 //DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) 542 //{ 543 // m_global_die_indexes.push_back (die_idx); 544 //} 545 // 546 // 547 //void 548 //DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) 549 //{ 550 // // Indexes to all file level global and static variables 551 // m_global_die_indexes; 552 // 553 // if (m_die_array.empty()) 554 // return; 555 // 556 // const DWARFDebugInfoEntry* first_die = &m_die_array[0]; 557 // const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); 558 // if (first_die <= die && die < end) 559 // m_global_die_indexes.push_back (die - first_die); 560 //} 561 562 563 void 564 DWARFCompileUnit::Index (const uint32_t cu_idx, 565 NameToDIE& func_basenames, 566 NameToDIE& func_fullnames, 567 NameToDIE& func_methods, 568 NameToDIE& func_selectors, 569 NameToDIE& objc_class_selectors, 570 NameToDIE& globals, 571 NameToDIE& types, 572 NameToDIE& namespaces) 573 { 574 const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); 575 576 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); 577 578 LogSP log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); 579 580 if (log) 581 { 582 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log.get(), 583 "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", 584 GetOffset()); 585 } 586 587 DWARFDebugInfoEntry::const_iterator pos; 588 DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); 589 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 590 for (pos = begin; pos != end; ++pos) 591 { 592 const DWARFDebugInfoEntry &die = *pos; 593 594 const dw_tag_t tag = die.Tag(); 595 596 switch (tag) 597 { 598 case DW_TAG_subprogram: 599 case DW_TAG_inlined_subroutine: 600 case DW_TAG_base_type: 601 case DW_TAG_class_type: 602 case DW_TAG_constant: 603 case DW_TAG_enumeration_type: 604 case DW_TAG_string_type: 605 case DW_TAG_subroutine_type: 606 case DW_TAG_structure_type: 607 case DW_TAG_union_type: 608 case DW_TAG_typedef: 609 case DW_TAG_namespace: 610 case DW_TAG_variable: 611 case DW_TAG_unspecified_type: 612 break; 613 614 default: 615 continue; 616 } 617 618 DWARFDebugInfoEntry::Attributes attributes; 619 const char *name = NULL; 620 const char *mangled_cstr = NULL; 621 bool is_variable = false; 622 bool is_declaration = false; 623 bool is_artificial = false; 624 bool has_address = false; 625 bool has_location = false; 626 bool is_global_or_static_variable = false; 627 628 dw_offset_t specification_die_offset = DW_INVALID_OFFSET; 629 const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, fixed_form_sizes, attributes); 630 if (num_attributes > 0) 631 { 632 is_variable = tag == DW_TAG_variable; 633 634 for (uint32_t i=0; i<num_attributes; ++i) 635 { 636 dw_attr_t attr = attributes.AttributeAtIndex(i); 637 DWARFFormValue form_value; 638 switch (attr) 639 { 640 case DW_AT_name: 641 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 642 name = form_value.AsCString(debug_str); 643 break; 644 645 case DW_AT_declaration: 646 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 647 is_declaration = form_value.Unsigned() != 0; 648 break; 649 650 case DW_AT_artificial: 651 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 652 is_artificial = form_value.Unsigned() != 0; 653 break; 654 655 case DW_AT_MIPS_linkage_name: 656 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 657 mangled_cstr = form_value.AsCString(debug_str); 658 break; 659 660 case DW_AT_low_pc: 661 case DW_AT_high_pc: 662 case DW_AT_ranges: 663 has_address = true; 664 break; 665 666 case DW_AT_entry_pc: 667 has_address = true; 668 break; 669 670 case DW_AT_location: 671 has_location = true; 672 if (tag == DW_TAG_variable) 673 { 674 const DWARFDebugInfoEntry* parent_die = die.GetParent(); 675 while ( parent_die != NULL ) 676 { 677 switch (parent_die->Tag()) 678 { 679 case DW_TAG_subprogram: 680 case DW_TAG_lexical_block: 681 case DW_TAG_inlined_subroutine: 682 // Even if this is a function level static, we don't add it. We could theoretically 683 // add these if we wanted to by introspecting into the DW_AT_location and seeing 684 // if the location describes a hard coded address, but we dont want the performance 685 // penalty of that right now. 686 is_global_or_static_variable = false; 687 // if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 688 // { 689 // // If we have valid block data, then we have location expression bytes 690 // // that are fixed (not a location list). 691 // const uint8_t *block_data = form_value.BlockData(); 692 // if (block_data) 693 // { 694 // uint32_t block_length = form_value.Unsigned(); 695 // if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) 696 // { 697 // if (block_data[0] == DW_OP_addr) 698 // add_die = true; 699 // } 700 // } 701 // } 702 parent_die = NULL; // Terminate the while loop. 703 break; 704 705 case DW_TAG_compile_unit: 706 is_global_or_static_variable = true; 707 parent_die = NULL; // Terminate the while loop. 708 break; 709 710 default: 711 parent_die = parent_die->GetParent(); // Keep going in the while loop. 712 break; 713 } 714 } 715 } 716 break; 717 718 case DW_AT_specification: 719 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 720 specification_die_offset = form_value.Reference(this); 721 break; 722 } 723 } 724 } 725 726 switch (tag) 727 { 728 case DW_TAG_subprogram: 729 if (has_address) 730 { 731 if (name) 732 { 733 // Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the 734 // simple inlined check outside the call. 735 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name)) 736 { 737 ConstString objc_class_name; 738 ConstString objc_selector_name; 739 ConstString objc_fullname_no_category_name; 740 ConstString objc_class_name_no_category; 741 if (ObjCLanguageRuntime::ParseMethodName (name, 742 &objc_class_name, 743 &objc_selector_name, 744 &objc_fullname_no_category_name, 745 &objc_class_name_no_category)) 746 { 747 func_fullnames.Insert (ConstString(name), die.GetOffset()); 748 if (objc_class_name) 749 objc_class_selectors.Insert(objc_class_name, die.GetOffset()); 750 if (objc_class_name_no_category) 751 objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset()); 752 if (objc_selector_name) 753 func_selectors.Insert (objc_selector_name, die.GetOffset()); 754 if (objc_fullname_no_category_name) 755 func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset()); 756 } 757 } 758 // If we have a mangled name, then the DW_AT_name attribute 759 // is usually the method name without the class or any parameters 760 const DWARFDebugInfoEntry *parent = die.GetParent(); 761 bool is_method = false; 762 if (parent) 763 { 764 dw_tag_t parent_tag = parent->Tag(); 765 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 766 { 767 is_method = true; 768 } 769 else 770 { 771 if (specification_die_offset != DW_INVALID_OFFSET) 772 { 773 const DWARFDebugInfoEntry *specification_die = m_dwarf2Data->DebugInfo()->GetDIEPtr (specification_die_offset, NULL); 774 if (specification_die) 775 { 776 parent = specification_die->GetParent(); 777 if (parent) 778 { 779 parent_tag = parent->Tag(); 780 781 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 782 is_method = true; 783 } 784 } 785 } 786 } 787 } 788 789 790 if (is_method) 791 func_methods.Insert (ConstString(name), die.GetOffset()); 792 else 793 func_basenames.Insert (ConstString(name), die.GetOffset()); 794 } 795 if (mangled_cstr) 796 { 797 // Make sure our mangled name isn't the same string table entry 798 // as our name. If it starts with '_', then it is ok, else compare 799 // the string to make sure it isn't the same and we don't end up 800 // with duplicate entries 801 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 802 { 803 Mangled mangled (mangled_cstr, true); 804 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 805 if (mangled.GetDemangledName()) 806 func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); 807 } 808 } 809 } 810 break; 811 812 case DW_TAG_inlined_subroutine: 813 if (has_address) 814 { 815 if (name) 816 func_basenames.Insert (ConstString(name), die.GetOffset()); 817 if (mangled_cstr) 818 { 819 // Make sure our mangled name isn't the same string table entry 820 // as our name. If it starts with '_', then it is ok, else compare 821 // the string to make sure it isn't the same and we don't end up 822 // with duplicate entries 823 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 824 { 825 Mangled mangled (mangled_cstr, true); 826 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 827 if (mangled.GetDemangledName()) 828 func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); 829 } 830 } 831 } 832 break; 833 834 case DW_TAG_base_type: 835 case DW_TAG_class_type: 836 case DW_TAG_constant: 837 case DW_TAG_enumeration_type: 838 case DW_TAG_string_type: 839 case DW_TAG_subroutine_type: 840 case DW_TAG_structure_type: 841 case DW_TAG_union_type: 842 case DW_TAG_typedef: 843 case DW_TAG_unspecified_type: 844 if (name && is_declaration == false) 845 { 846 types.Insert (ConstString(name), die.GetOffset()); 847 } 848 break; 849 850 case DW_TAG_namespace: 851 if (name) 852 namespaces.Insert (ConstString(name), die.GetOffset()); 853 break; 854 855 case DW_TAG_variable: 856 if (name && has_location && is_global_or_static_variable) 857 { 858 globals.Insert (ConstString(name), die.GetOffset()); 859 // Be sure to include variables by their mangled and demangled 860 // names if they have any since a variable can have a basename 861 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 862 // mangled name "(anonymous namespace)::i"... 863 864 // Make sure our mangled name isn't the same string table entry 865 // as our name. If it starts with '_', then it is ok, else compare 866 // the string to make sure it isn't the same and we don't end up 867 // with duplicate entries 868 if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 869 { 870 Mangled mangled (mangled_cstr, true); 871 globals.Insert (mangled.GetMangledName(), die.GetOffset()); 872 if (mangled.GetDemangledName()) 873 globals.Insert (mangled.GetDemangledName(), die.GetOffset()); 874 } 875 } 876 break; 877 878 default: 879 continue; 880 } 881 } 882 } 883 884 bool 885 DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type () 886 { 887 if (GetProducer() == eProcucerLLVMGCC) 888 return false; 889 return true; 890 } 891 892 bool 893 DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() 894 { 895 // llvm-gcc makes completely invalid decl file attributes and won't ever 896 // be fixed, so we need to know to ignore these. 897 return GetProducer() == eProcucerLLVMGCC; 898 } 899 900 DWARFCompileUnit::Producer 901 DWARFCompileUnit::GetProducer () 902 { 903 if (m_producer == eProducerInvalid) 904 { 905 const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); 906 if (die) 907 { 908 const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); 909 if (producer_cstr) 910 { 911 RegularExpression g_llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); 912 if (g_llvm_gcc_regex.Execute (producer_cstr)) 913 m_producer = eProcucerLLVMGCC; 914 else if (strstr(producer_cstr, "clang")) 915 m_producer = eProducerClang; 916 else if (strstr(producer_cstr, "GNU")) 917 m_producer = eProducerGCC; 918 } 919 } 920 if (m_producer == eProducerInvalid) 921 m_producer = eProcucerOther; 922 } 923 return m_producer; 924 } 925 926 927 928