DWARFCompileUnit.cpp revision 296417
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/StreamString.h" 16#include "lldb/Core/Timer.h" 17#include "lldb/Host/StringConvert.h" 18#include "lldb/Symbol/CompileUnit.h" 19#include "lldb/Symbol/LineTable.h" 20#include "lldb/Symbol/ObjectFile.h" 21#include "Plugins/Language/ObjC/ObjCLanguage.h" 22 23#include "DWARFDebugAbbrev.h" 24#include "DWARFDebugAranges.h" 25#include "DWARFDebugInfo.h" 26#include "DWARFDIECollection.h" 27#include "DWARFFormValue.h" 28#include "LogChannelDWARF.h" 29#include "NameToDIE.h" 30#include "SymbolFileDWARF.h" 31#include "SymbolFileDWARFDwo.h" 32#include "SymbolFileDWARFDebugMap.h" 33 34using namespace lldb; 35using namespace lldb_private; 36using namespace std; 37 38 39extern int g_verbose; 40 41DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : 42 m_dwarf2Data (dwarf2Data), 43 m_abbrevs (NULL), 44 m_user_data (NULL), 45 m_die_array (), 46 m_func_aranges_ap (), 47 m_base_addr (0), 48 m_offset (DW_INVALID_OFFSET), 49 m_length (0), 50 m_version (0), 51 m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()), 52 m_producer (eProducerInvalid), 53 m_producer_version_major (0), 54 m_producer_version_minor (0), 55 m_producer_version_update (0), 56 m_language_type (eLanguageTypeUnknown), 57 m_is_dwarf64 (false), 58 m_is_optimized (eLazyBoolCalculate), 59 m_addr_base (0), 60 m_base_obj_offset (DW_INVALID_OFFSET) 61{ 62} 63 64DWARFCompileUnit::~DWARFCompileUnit() 65{} 66 67void 68DWARFCompileUnit::Clear() 69{ 70 m_offset = DW_INVALID_OFFSET; 71 m_length = 0; 72 m_version = 0; 73 m_abbrevs = NULL; 74 m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); 75 m_base_addr = 0; 76 m_die_array.clear(); 77 m_func_aranges_ap.reset(); 78 m_user_data = NULL; 79 m_producer = eProducerInvalid; 80 m_language_type = eLanguageTypeUnknown; 81 m_is_dwarf64 = false; 82 m_is_optimized = eLazyBoolCalculate; 83 m_addr_base = 0; 84 m_base_obj_offset = DW_INVALID_OFFSET; 85} 86 87bool 88DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr) 89{ 90 Clear(); 91 92 m_offset = *offset_ptr; 93 94 if (debug_info.ValidOffset(*offset_ptr)) 95 { 96 dw_offset_t abbr_offset; 97 const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); 98 m_length = debug_info.GetDWARFInitialLength(offset_ptr); 99 m_is_dwarf64 = debug_info.IsDWARF64(); 100 m_version = debug_info.GetU16(offset_ptr); 101 abbr_offset = debug_info.GetDWARFOffset(offset_ptr); 102 m_addr_size = debug_info.GetU8 (offset_ptr); 103 104 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 105 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 106 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); 107 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 108 109 if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) 110 { 111 m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); 112 return true; 113 } 114 115 // reset the offset to where we tried to parse from if anything went wrong 116 *offset_ptr = m_offset; 117 } 118 119 return false; 120} 121 122 123void 124DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) 125{ 126 if (m_die_array.size() > 1) 127 { 128 // std::vectors never get any smaller when resized to a smaller size, 129 // or when clear() or erase() are called, the size will report that it 130 // is smaller, but the memory allocated remains intact (call capacity() 131 // to see this). So we need to create a temporary vector and swap the 132 // contents which will cause just the internal pointers to be swapped 133 // so that when "tmp_array" goes out of scope, it will destroy the 134 // contents. 135 136 // Save at least the compile unit DIE 137 DWARFDebugInfoEntry::collection tmp_array; 138 m_die_array.swap(tmp_array); 139 if (keep_compile_unit_die) 140 m_die_array.push_back(tmp_array.front()); 141 } 142 143 if (m_dwo_symbol_file) 144 m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die); 145} 146 147//---------------------------------------------------------------------- 148// ParseCompileUnitDIEsIfNeeded 149// 150// Parses a compile unit and indexes its DIEs if it hasn't already been 151// done. 152//---------------------------------------------------------------------- 153size_t 154DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) 155{ 156 const size_t initial_die_array_size = m_die_array.size(); 157 if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) 158 return 0; // Already parsed 159 160 Timer scoped_timer (__PRETTY_FUNCTION__, 161 "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", 162 m_offset, 163 cu_die_only); 164 165 // Set the offset to that of the first DIE and calculate the start of the 166 // next compilation unit header. 167 lldb::offset_t offset = GetFirstDIEOffset(); 168 lldb::offset_t next_cu_offset = GetNextCompileUnitOffset(); 169 170 DWARFDebugInfoEntry die; 171 // Keep a flat array of the DIE for binary lookup by DIE offset 172 if (!cu_die_only) 173 { 174 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS)); 175 if (log) 176 { 177 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, 178 "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]", 179 GetOffset()); 180 } 181 } 182 183 uint32_t depth = 0; 184 // We are in our compile unit, parse starting at the offset 185 // we were told to parse 186 const DWARFDataExtractor& debug_info_data = m_dwarf2Data->get_debug_info_data(); 187 std::vector<uint32_t> die_index_stack; 188 die_index_stack.reserve(32); 189 die_index_stack.push_back(0); 190 bool prev_die_had_children = false; 191 DWARFFormValue::FixedFormSizes fixed_form_sizes = 192 DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); 193 while (offset < next_cu_offset && 194 die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset)) 195 { 196// if (log) 197// log->Printf("0x%8.8x: %*.*s%s%s", 198// die.GetOffset(), 199// depth * 2, depth * 2, "", 200// DW_TAG_value_to_name (die.Tag()), 201// die.HasChildren() ? " *" : ""); 202 203 const bool null_die = die.IsNULL(); 204 if (depth == 0) 205 { 206 if (initial_die_array_size == 0) 207 AddCompileUnitDIE(die); 208 uint64_t base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 209 if (base_addr == LLDB_INVALID_ADDRESS) 210 base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_entry_pc, 0); 211 SetBaseAddress (base_addr); 212 if (cu_die_only) 213 return 1; 214 } 215 else 216 { 217 if (null_die) 218 { 219 if (prev_die_had_children) 220 { 221 // This will only happen if a DIE says is has children 222 // but all it contains is a NULL tag. Since we are removing 223 // the NULL DIEs from the list (saves up to 25% in C++ code), 224 // we need a way to let the DIE know that it actually doesn't 225 // have children. 226 if (!m_die_array.empty()) 227 m_die_array.back().SetEmptyChildren(true); 228 } 229 } 230 else 231 { 232 die.SetParentIndex(m_die_array.size() - die_index_stack[depth-1]); 233 234 if (die_index_stack.back()) 235 m_die_array[die_index_stack.back()].SetSiblingIndex(m_die_array.size()-die_index_stack.back()); 236 237 // Only push the DIE if it isn't a NULL DIE 238 m_die_array.push_back(die); 239 } 240 } 241 242 if (null_die) 243 { 244 // NULL DIE. 245 if (!die_index_stack.empty()) 246 die_index_stack.pop_back(); 247 248 if (depth > 0) 249 --depth; 250 if (depth == 0) 251 break; // We are done with this compile unit! 252 253 prev_die_had_children = false; 254 } 255 else 256 { 257 die_index_stack.back() = m_die_array.size() - 1; 258 // Normal DIE 259 const bool die_has_children = die.HasChildren(); 260 if (die_has_children) 261 { 262 die_index_stack.push_back(0); 263 ++depth; 264 } 265 prev_die_had_children = die_has_children; 266 } 267 } 268 269 // Give a little bit of info if we encounter corrupt DWARF (our offset 270 // should always terminate at or before the start of the next compilation 271 // unit header). 272 if (offset > next_cu_offset) 273 { 274 m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n", 275 GetOffset(), 276 offset); 277 } 278 279 // Since std::vector objects will double their size, we really need to 280 // make a new array with the perfect size so we don't end up wasting 281 // space. So here we copy and swap to make sure we don't have any extra 282 // memory taken up. 283 284 if (m_die_array.size () < m_die_array.capacity()) 285 { 286 DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end()); 287 exact_size_die_array.swap (m_die_array); 288 } 289 Log *verbose_log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE)); 290 if (verbose_log) 291 { 292 StreamString strm; 293 Dump(&strm); 294 if (m_die_array.empty()) 295 strm.Printf("error: no DIE for compile unit"); 296 else 297 m_die_array[0].Dump(m_dwarf2Data, this, strm, UINT32_MAX); 298 verbose_log->PutCString (strm.GetString().c_str()); 299 } 300 301 if (!m_dwo_symbol_file) 302 return m_die_array.size(); 303 304 DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit(); 305 size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only); 306 return m_die_array.size() + dwo_die_count - 1; // We have 2 CU die, but we waht to count it only as one 307} 308 309void 310DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die) 311{ 312 assert (m_die_array.empty() && "Compile unit DIE already added"); 313 AddDIE(die); 314 315 DWARFDebugInfoEntry& cu_die = m_die_array.front(); 316 317 const char* dwo_name = cu_die.GetAttributeValueAsString(m_dwarf2Data, 318 this, 319 DW_AT_GNU_dwo_name, 320 nullptr); 321 if (!dwo_name) 322 return; 323 324 FileSpec dwo_file(dwo_name, true); 325 if (dwo_file.IsRelative()) 326 { 327 const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data, 328 this, 329 DW_AT_comp_dir, 330 nullptr); 331 if (!comp_dir) 332 return; 333 334 dwo_file.SetFile(comp_dir, true); 335 dwo_file.AppendPathComponent(dwo_name); 336 } 337 338 if (!dwo_file.Exists()) 339 return; 340 341 DataBufferSP dwo_file_data_sp; 342 lldb::offset_t dwo_file_data_offset = 0; 343 ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(m_dwarf2Data->GetObjectFile()->GetModule(), 344 &dwo_file, 345 0 /* file_offset */, 346 dwo_file.GetByteSize(), 347 dwo_file_data_sp, 348 dwo_file_data_offset); 349 if (dwo_obj_file == nullptr) 350 return; 351 352 std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file(new SymbolFileDWARFDwo(dwo_obj_file, this)); 353 354 DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); 355 if (!dwo_cu) 356 return; // Can't fetch the compile unit from the dwo file. 357 358 DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); 359 if (!dwo_cu_die.IsValid()) 360 return; // Can't fetch the compile unit DIE from the dwo file. 361 362 uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, 363 this, 364 DW_AT_GNU_dwo_id, 365 0); 366 uint64_t sub_dwo_id = dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); 367 if (main_dwo_id != sub_dwo_id) 368 return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to a differectn compilation. 369 370 m_dwo_symbol_file = std::move(dwo_symbol_file); 371 372 dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, 373 this, 374 DW_AT_GNU_addr_base, 375 0); 376 dwo_cu->SetAddrBase(addr_base, m_offset); 377} 378 379dw_offset_t 380DWARFCompileUnit::GetAbbrevOffset() const 381{ 382 return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; 383} 384 385 386 387bool 388DWARFCompileUnit::Verify(Stream *s) const 389{ 390 const DWARFDataExtractor& debug_info = m_dwarf2Data->get_debug_info_data(); 391 bool valid_offset = debug_info.ValidOffset(m_offset); 392 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 393 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 394 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); 395 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 396 bool verbose = s->GetVerbose(); 397 if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK) 398 { 399 if (verbose) 400 s->Printf(" 0x%8.8x: OK\n", m_offset); 401 return true; 402 } 403 else 404 { 405 s->Printf(" 0x%8.8x: ", m_offset); 406 407 m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0); 408 s->EOL(); 409 if (valid_offset) 410 { 411 if (!length_OK) 412 s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length); 413 if (!version_OK) 414 s->Printf(" The 16 bit compile unit header version is not supported.\n"); 415 if (!abbr_offset_OK) 416 s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset()); 417 if (!addr_size_OK) 418 s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size); 419 } 420 else 421 s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n"); 422 } 423 return false; 424} 425 426 427void 428DWARFCompileUnit::Dump(Stream *s) const 429{ 430 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", 431 m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); 432} 433 434 435static uint8_t g_default_addr_size = 4; 436 437uint8_t 438DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) 439{ 440 if (cu) 441 return cu->GetAddressByteSize(); 442 return DWARFCompileUnit::GetDefaultAddressSize(); 443} 444 445bool 446DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit* cu) 447{ 448 if (cu) 449 return cu->IsDWARF64(); 450 return false; 451} 452 453uint8_t 454DWARFCompileUnit::GetDefaultAddressSize() 455{ 456 return g_default_addr_size; 457} 458 459void 460DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) 461{ 462 g_default_addr_size = addr_size; 463} 464 465lldb::user_id_t 466DWARFCompileUnit::GetID () const 467{ 468 dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset; 469 if (m_dwarf2Data) 470 return m_dwarf2Data->MakeUserID(local_id); 471 else 472 return local_id; 473} 474 475void 476DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, 477 DWARFDebugAranges* debug_aranges) 478{ 479 // This function is usually called if there in no .debug_aranges section 480 // in order to produce a compile unit level set of address ranges that 481 // is accurate. 482 483 size_t num_debug_aranges = debug_aranges->GetNumRanges(); 484 485 // First get the compile unit DIE only and check if it has a DW_AT_ranges 486 const DWARFDebugInfoEntry* die = GetCompileUnitDIEPtrOnly(); 487 488 const dw_offset_t cu_offset = GetOffset(); 489 if (die) 490 { 491 DWARFRangeList ranges; 492 const size_t num_ranges = die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false); 493 if (num_ranges > 0) 494 { 495 // This compile unit has DW_AT_ranges, assume this is correct if it 496 // is present since clang no longer makes .debug_aranges by default 497 // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does 498 // this with recent GCC builds. 499 for (size_t i=0; i<num_ranges; ++i) 500 { 501 const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); 502 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); 503 } 504 505 return; // We got all of our ranges from the DW_AT_ranges attribute 506 } 507 } 508 // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF 509 510 // If the DIEs weren't parsed, then we don't want all dies for all compile units 511 // to stay loaded when they weren't needed. So we can end up parsing the DWARF 512 // and then throwing them all away to keep memory usage down. 513 const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; 514 515 die = DIEPtr(); 516 if (die) 517 die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); 518 519 if (debug_aranges->GetNumRanges() == num_debug_aranges) 520 { 521 // We got nothing from the functions, maybe we have a line tables only 522 // situation. Check the line tables and build the arange table from this. 523 SymbolContext sc; 524 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 525 if (sc.comp_unit) 526 { 527 SymbolFileDWARFDebugMap *debug_map_sym_file = m_dwarf2Data->GetDebugMapSymfile(); 528 if (debug_map_sym_file == NULL) 529 { 530 LineTable *line_table = sc.comp_unit->GetLineTable(); 531 532 if (line_table) 533 { 534 LineTable::FileAddressRanges file_ranges; 535 const bool append = true; 536 const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); 537 for (uint32_t idx=0; idx<num_ranges; ++idx) 538 { 539 const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); 540 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); 541 } 542 } 543 } 544 else 545 debug_map_sym_file->AddOSOARanges(dwarf2Data,debug_aranges); 546 } 547 } 548 549 if (debug_aranges->GetNumRanges() == num_debug_aranges) 550 { 551 // We got nothing from the functions, maybe we have a line tables only 552 // situation. Check the line tables and build the arange table from this. 553 SymbolContext sc; 554 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 555 if (sc.comp_unit) 556 { 557 LineTable *line_table = sc.comp_unit->GetLineTable(); 558 559 if (line_table) 560 { 561 LineTable::FileAddressRanges file_ranges; 562 const bool append = true; 563 const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); 564 for (uint32_t idx=0; idx<num_ranges; ++idx) 565 { 566 const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); 567 debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); 568 } 569 } 570 } 571 } 572 573 // Keep memory down by clearing DIEs if this generate function 574 // caused them to be parsed 575 if (clear_dies) 576 ClearDIEs (true); 577 578} 579 580 581const DWARFDebugAranges & 582DWARFCompileUnit::GetFunctionAranges () 583{ 584 if (m_func_aranges_ap.get() == NULL) 585 { 586 m_func_aranges_ap.reset (new DWARFDebugAranges()); 587 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 588 589 if (log) 590 { 591 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 592 "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]", 593 GetOffset()); 594 } 595 const DWARFDebugInfoEntry* die = DIEPtr(); 596 if (die) 597 die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); 598 599 if (m_dwo_symbol_file) 600 { 601 DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit(); 602 const DWARFDebugInfoEntry* dwo_die = dwo_cu->DIEPtr(); 603 if (dwo_die) 604 dwo_die->BuildFunctionAddressRangeTable (m_dwo_symbol_file.get(), 605 dwo_cu, 606 m_func_aranges_ap.get()); 607 } 608 609 const bool minimize = false; 610 m_func_aranges_ap->Sort(minimize); 611 } 612 return *m_func_aranges_ap.get(); 613} 614 615DWARFDIE 616DWARFCompileUnit::LookupAddress (const dw_addr_t address) 617{ 618 if (DIE()) 619 { 620 const DWARFDebugAranges &func_aranges = GetFunctionAranges (); 621 622 // Re-check the aranges auto pointer contents in case it was created above 623 if (!func_aranges.IsEmpty()) 624 return GetDIE(func_aranges.FindAddress(address)); 625 } 626 return DWARFDIE(); 627} 628 629//---------------------------------------------------------------------- 630// Compare function DWARFDebugAranges::Range structures 631//---------------------------------------------------------------------- 632static bool CompareDIEOffset (const DWARFDebugInfoEntry& die, const dw_offset_t die_offset) 633{ 634 return die.GetOffset() < die_offset; 635} 636 637//---------------------------------------------------------------------- 638// GetDIE() 639// 640// Get the DIE (Debug Information Entry) with the specified offset by 641// first checking if the DIE is contained within this compile unit and 642// grabbing the DIE from this compile unit. Otherwise we grab the DIE 643// from the DWARF file. 644//---------------------------------------------------------------------- 645DWARFDIE 646DWARFCompileUnit::GetDIE (dw_offset_t die_offset) 647{ 648 if (die_offset != DW_INVALID_OFFSET) 649 { 650 if (m_dwo_symbol_file) 651 return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset); 652 653 if (ContainsDIEOffset(die_offset)) 654 { 655 ExtractDIEsIfNeeded (false); 656 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 657 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset); 658 if (pos != end) 659 { 660 if (die_offset == (*pos).GetOffset()) 661 return DWARFDIE(this, &(*pos)); 662 } 663 } 664 else 665 { 666 // Don't specify the compile unit offset as we don't know it because the DIE belongs to 667 // a different compile unit in the same symbol file. 668 return m_dwarf2Data->DebugInfo()->GetDIE (DIERef(die_offset)); 669 } 670 } 671 return DWARFDIE(); // Not found 672} 673 674size_t 675DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const 676{ 677 size_t old_size = dies.Size(); 678 DWARFDebugInfoEntry::const_iterator pos; 679 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 680 for (pos = m_die_array.begin(); pos != end; ++pos) 681 { 682 if (pos->Tag() == tag) 683 dies.Append (DWARFDIE(this, &(*pos))); 684 } 685 686 // Return the number of DIEs added to the collection 687 return dies.Size() - old_size; 688} 689 690//void 691//DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) 692//{ 693// m_global_die_indexes.push_back (die_idx); 694//} 695// 696// 697//void 698//DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) 699//{ 700// // Indexes to all file level global and static variables 701// m_global_die_indexes; 702// 703// if (m_die_array.empty()) 704// return; 705// 706// const DWARFDebugInfoEntry* first_die = &m_die_array[0]; 707// const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); 708// if (first_die <= die && die < end) 709// m_global_die_indexes.push_back (die - first_die); 710//} 711 712 713void 714DWARFCompileUnit::Index (NameToDIE& func_basenames, 715 NameToDIE& func_fullnames, 716 NameToDIE& func_methods, 717 NameToDIE& func_selectors, 718 NameToDIE& objc_class_selectors, 719 NameToDIE& globals, 720 NameToDIE& types, 721 NameToDIE& namespaces) 722{ 723 Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); 724 725 if (log) 726 { 727 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 728 "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", 729 GetOffset()); 730 } 731 732 const LanguageType cu_language = GetLanguageType(); 733 DWARFFormValue::FixedFormSizes fixed_form_sizes = 734 DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); 735 736 IndexPrivate(this, 737 cu_language, 738 fixed_form_sizes, 739 GetOffset(), 740 func_basenames, 741 func_fullnames, 742 func_methods, 743 func_selectors, 744 objc_class_selectors, 745 globals, 746 types, 747 namespaces); 748 749 SymbolFileDWARFDwo* dwo_symbol_file = GetDwoSymbolFile(); 750 if (dwo_symbol_file) 751 { 752 IndexPrivate(dwo_symbol_file->GetCompileUnit(), 753 cu_language, 754 fixed_form_sizes, 755 GetOffset(), 756 func_basenames, 757 func_fullnames, 758 func_methods, 759 func_selectors, 760 objc_class_selectors, 761 globals, 762 types, 763 namespaces); 764 } 765} 766 767void 768DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu, 769 const LanguageType cu_language, 770 const DWARFFormValue::FixedFormSizes& fixed_form_sizes, 771 const dw_offset_t cu_offset, 772 NameToDIE& func_basenames, 773 NameToDIE& func_fullnames, 774 NameToDIE& func_methods, 775 NameToDIE& func_selectors, 776 NameToDIE& objc_class_selectors, 777 NameToDIE& globals, 778 NameToDIE& types, 779 NameToDIE& namespaces) 780{ 781 DWARFDebugInfoEntry::const_iterator pos; 782 DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin(); 783 DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end(); 784 for (pos = begin; pos != end; ++pos) 785 { 786 const DWARFDebugInfoEntry &die = *pos; 787 788 const dw_tag_t tag = die.Tag(); 789 790 switch (tag) 791 { 792 case DW_TAG_subprogram: 793 case DW_TAG_inlined_subroutine: 794 case DW_TAG_base_type: 795 case DW_TAG_class_type: 796 case DW_TAG_constant: 797 case DW_TAG_enumeration_type: 798 case DW_TAG_string_type: 799 case DW_TAG_subroutine_type: 800 case DW_TAG_structure_type: 801 case DW_TAG_union_type: 802 case DW_TAG_typedef: 803 case DW_TAG_namespace: 804 case DW_TAG_variable: 805 case DW_TAG_unspecified_type: 806 break; 807 808 default: 809 continue; 810 } 811 812 DWARFAttributes attributes; 813 const char *name = NULL; 814 const char *mangled_cstr = NULL; 815 bool is_declaration = false; 816 //bool is_artificial = false; 817 bool has_address = false; 818 bool has_location_or_const_value = false; 819 bool is_global_or_static_variable = false; 820 821 DWARFFormValue specification_die_form; 822 const size_t num_attributes = die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes); 823 if (num_attributes > 0) 824 { 825 for (uint32_t i=0; i<num_attributes; ++i) 826 { 827 dw_attr_t attr = attributes.AttributeAtIndex(i); 828 DWARFFormValue form_value; 829 switch (attr) 830 { 831 case DW_AT_name: 832 if (attributes.ExtractFormValueAtIndex(i, form_value)) 833 name = form_value.AsCString(); 834 break; 835 836 case DW_AT_declaration: 837 if (attributes.ExtractFormValueAtIndex(i, form_value)) 838 is_declaration = form_value.Unsigned() != 0; 839 break; 840 841// case DW_AT_artificial: 842// if (attributes.ExtractFormValueAtIndex(i, form_value)) 843// is_artificial = form_value.Unsigned() != 0; 844// break; 845 846 case DW_AT_MIPS_linkage_name: 847 case DW_AT_linkage_name: 848 if (attributes.ExtractFormValueAtIndex(i, form_value)) 849 mangled_cstr = form_value.AsCString(); 850 break; 851 852 case DW_AT_low_pc: 853 case DW_AT_high_pc: 854 case DW_AT_ranges: 855 has_address = true; 856 break; 857 858 case DW_AT_entry_pc: 859 has_address = true; 860 break; 861 862 case DW_AT_location: 863 case DW_AT_const_value: 864 has_location_or_const_value = true; 865 if (tag == DW_TAG_variable) 866 { 867 const DWARFDebugInfoEntry* parent_die = die.GetParent(); 868 while ( parent_die != NULL ) 869 { 870 switch (parent_die->Tag()) 871 { 872 case DW_TAG_subprogram: 873 case DW_TAG_lexical_block: 874 case DW_TAG_inlined_subroutine: 875 // Even if this is a function level static, we don't add it. We could theoretically 876 // add these if we wanted to by introspecting into the DW_AT_location and seeing 877 // if the location describes a hard coded address, but we dont want the performance 878 // penalty of that right now. 879 is_global_or_static_variable = false; 880// if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 881// { 882// // If we have valid block data, then we have location expression bytes 883// // that are fixed (not a location list). 884// const uint8_t *block_data = form_value.BlockData(); 885// if (block_data) 886// { 887// uint32_t block_length = form_value.Unsigned(); 888// if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) 889// { 890// if (block_data[0] == DW_OP_addr) 891// add_die = true; 892// } 893// } 894// } 895 parent_die = NULL; // Terminate the while loop. 896 break; 897 898 case DW_TAG_compile_unit: 899 is_global_or_static_variable = true; 900 parent_die = NULL; // Terminate the while loop. 901 break; 902 903 default: 904 parent_die = parent_die->GetParent(); // Keep going in the while loop. 905 break; 906 } 907 } 908 } 909 break; 910 911 case DW_AT_specification: 912 if (attributes.ExtractFormValueAtIndex(i, form_value)) 913 specification_die_form = form_value; 914 break; 915 } 916 } 917 } 918 919 switch (tag) 920 { 921 case DW_TAG_subprogram: 922 if (has_address) 923 { 924 if (name) 925 { 926 ObjCLanguage::MethodName objc_method(name, true); 927 if (objc_method.IsValid(true)) 928 { 929 ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory()); 930 ConstString objc_selector_name (objc_method.GetSelector()); 931 ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true)); 932 ConstString objc_class_name_no_category (objc_method.GetClassName()); 933 func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 934 if (objc_class_name_with_category) 935 objc_class_selectors.Insert(objc_class_name_with_category, DIERef(cu_offset, die.GetOffset())); 936 if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category) 937 objc_class_selectors.Insert(objc_class_name_no_category, DIERef(cu_offset, die.GetOffset())); 938 if (objc_selector_name) 939 func_selectors.Insert (objc_selector_name, DIERef(cu_offset, die.GetOffset())); 940 if (objc_fullname_no_category_name) 941 func_fullnames.Insert (objc_fullname_no_category_name, DIERef(cu_offset, die.GetOffset())); 942 } 943 // If we have a mangled name, then the DW_AT_name attribute 944 // is usually the method name without the class or any parameters 945 const DWARFDebugInfoEntry *parent = die.GetParent(); 946 bool is_method = false; 947 if (parent) 948 { 949 dw_tag_t parent_tag = parent->Tag(); 950 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 951 { 952 is_method = true; 953 } 954 else 955 { 956 if (specification_die_form.IsValid()) 957 { 958 DWARFDIE specification_die = dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE (DIERef(specification_die_form)); 959 if (specification_die.GetParent().IsStructOrClass()) 960 is_method = true; 961 } 962 } 963 } 964 965 966 if (is_method) 967 func_methods.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 968 else 969 func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 970 971 if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) 972 func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 973 } 974 if (mangled_cstr) 975 { 976 // Make sure our mangled name isn't the same string table entry 977 // as our name. If it starts with '_', then it is ok, else compare 978 // the string to make sure it isn't the same and we don't end up 979 // with duplicate entries 980 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0))) 981 { 982 Mangled mangled (ConstString(mangled_cstr), true); 983 func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); 984 ConstString demangled = mangled.GetDemangledName(cu_language); 985 if (demangled) 986 func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset())); 987 } 988 } 989 } 990 break; 991 992 case DW_TAG_inlined_subroutine: 993 if (has_address) 994 { 995 if (name) 996 func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 997 if (mangled_cstr) 998 { 999 // Make sure our mangled name isn't the same string table entry 1000 // as our name. If it starts with '_', then it is ok, else compare 1001 // the string to make sure it isn't the same and we don't end up 1002 // with duplicate entries 1003 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 1004 { 1005 Mangled mangled (ConstString(mangled_cstr), true); 1006 func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); 1007 ConstString demangled = mangled.GetDemangledName(cu_language); 1008 if (demangled) 1009 func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset())); 1010 } 1011 } 1012 else 1013 func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 1014 } 1015 break; 1016 1017 case DW_TAG_base_type: 1018 case DW_TAG_class_type: 1019 case DW_TAG_constant: 1020 case DW_TAG_enumeration_type: 1021 case DW_TAG_string_type: 1022 case DW_TAG_subroutine_type: 1023 case DW_TAG_structure_type: 1024 case DW_TAG_union_type: 1025 case DW_TAG_typedef: 1026 case DW_TAG_unspecified_type: 1027 if (name && is_declaration == false) 1028 { 1029 types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 1030 } 1031 break; 1032 1033 case DW_TAG_namespace: 1034 if (name) 1035 namespaces.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 1036 break; 1037 1038 case DW_TAG_variable: 1039 if (name && has_location_or_const_value && is_global_or_static_variable) 1040 { 1041 globals.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); 1042 // Be sure to include variables by their mangled and demangled 1043 // names if they have any since a variable can have a basename 1044 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 1045 // mangled name "(anonymous namespace)::i"... 1046 1047 // Make sure our mangled name isn't the same string table entry 1048 // as our name. If it starts with '_', then it is ok, else compare 1049 // the string to make sure it isn't the same and we don't end up 1050 // with duplicate entries 1051 if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 1052 { 1053 Mangled mangled (ConstString(mangled_cstr), true); 1054 globals.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset())); 1055 ConstString demangled = mangled.GetDemangledName(cu_language); 1056 if (demangled) 1057 globals.Insert (demangled, DIERef(cu_offset, die.GetOffset())); 1058 } 1059 } 1060 break; 1061 1062 default: 1063 continue; 1064 } 1065 } 1066} 1067 1068bool 1069DWARFCompileUnit::Supports_unnamed_objc_bitfields () 1070{ 1071 if (GetProducer() == eProducerClang) 1072 { 1073 const uint32_t major_version = GetProducerVersionMajor(); 1074 if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13)) 1075 return true; 1076 else 1077 return false; 1078 } 1079 return true; // Assume all other compilers didn't have incorrect ObjC bitfield info 1080} 1081 1082bool 1083DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type () 1084{ 1085 if (GetProducer() == eProducerLLVMGCC) 1086 return false; 1087 return true; 1088} 1089 1090bool 1091DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() 1092{ 1093 // llvm-gcc makes completely invalid decl file attributes and won't ever 1094 // be fixed, so we need to know to ignore these. 1095 return GetProducer() == eProducerLLVMGCC; 1096} 1097 1098void 1099DWARFCompileUnit::ParseProducerInfo () 1100{ 1101 m_producer_version_major = UINT32_MAX; 1102 m_producer_version_minor = UINT32_MAX; 1103 m_producer_version_update = UINT32_MAX; 1104 1105 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 1106 if (die) 1107 { 1108 1109 const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); 1110 if (producer_cstr) 1111 { 1112 RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); 1113 if (llvm_gcc_regex.Execute (producer_cstr)) 1114 { 1115 m_producer = eProducerLLVMGCC; 1116 } 1117 else if (strstr(producer_cstr, "clang")) 1118 { 1119 static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"); 1120 RegularExpression::Match regex_match(3); 1121 if (g_clang_version_regex.Execute (producer_cstr, ®ex_match)) 1122 { 1123 std::string str; 1124 if (regex_match.GetMatchAtIndex (producer_cstr, 1, str)) 1125 m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1126 if (regex_match.GetMatchAtIndex (producer_cstr, 2, str)) 1127 m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1128 if (regex_match.GetMatchAtIndex (producer_cstr, 3, str)) 1129 m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1130 } 1131 m_producer = eProducerClang; 1132 } 1133 else if (strstr(producer_cstr, "GNU")) 1134 m_producer = eProducerGCC; 1135 } 1136 } 1137 if (m_producer == eProducerInvalid) 1138 m_producer = eProcucerOther; 1139} 1140 1141DWARFCompileUnit::Producer 1142DWARFCompileUnit::GetProducer () 1143{ 1144 if (m_producer == eProducerInvalid) 1145 ParseProducerInfo (); 1146 return m_producer; 1147} 1148 1149 1150uint32_t 1151DWARFCompileUnit::GetProducerVersionMajor() 1152{ 1153 if (m_producer_version_major == 0) 1154 ParseProducerInfo (); 1155 return m_producer_version_major; 1156} 1157 1158uint32_t 1159DWARFCompileUnit::GetProducerVersionMinor() 1160{ 1161 if (m_producer_version_minor == 0) 1162 ParseProducerInfo (); 1163 return m_producer_version_minor; 1164} 1165 1166uint32_t 1167DWARFCompileUnit::GetProducerVersionUpdate() 1168{ 1169 if (m_producer_version_update == 0) 1170 ParseProducerInfo (); 1171 return m_producer_version_update; 1172} 1173 1174LanguageType 1175DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) 1176{ 1177 // Note: user languages between lo_user and hi_user 1178 // must be handled explicitly here. 1179 switch (val) 1180 { 1181 case DW_LANG_Mips_Assembler: 1182 return eLanguageTypeMipsAssembler; 1183 case 0x8e57: // FIXME: needs to be added to llvm 1184 return eLanguageTypeExtRenderScript; 1185 default: 1186 return static_cast<LanguageType>(val); 1187 } 1188} 1189 1190LanguageType 1191DWARFCompileUnit::GetLanguageType() 1192{ 1193 if (m_language_type != eLanguageTypeUnknown) 1194 return m_language_type; 1195 1196 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 1197 if (die) 1198 m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); 1199 return m_language_type; 1200} 1201 1202bool 1203DWARFCompileUnit::IsDWARF64() const 1204{ 1205 return m_is_dwarf64; 1206} 1207 1208bool 1209DWARFCompileUnit::GetIsOptimized () 1210{ 1211 if (m_is_optimized == eLazyBoolCalculate) 1212 { 1213 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 1214 if (die) 1215 { 1216 m_is_optimized = eLazyBoolNo; 1217 if (die->GetAttributeValueAsUnsigned (m_dwarf2Data, this, DW_AT_APPLE_optimized, 0) == 1) 1218 { 1219 m_is_optimized = eLazyBoolYes; 1220 } 1221 } 1222 } 1223 if (m_is_optimized == eLazyBoolYes) 1224 { 1225 return true; 1226 } 1227 else 1228 { 1229 return false; 1230 } 1231} 1232 1233DWARFFormValue::FixedFormSizes 1234DWARFCompileUnit::GetFixedFormSizes () 1235{ 1236 return DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), IsDWARF64()); 1237} 1238 1239TypeSystem * 1240DWARFCompileUnit::GetTypeSystem () 1241{ 1242 if (m_dwarf2Data) 1243 return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType()); 1244 else 1245 return nullptr; 1246} 1247 1248void 1249DWARFCompileUnit::SetUserData(void *d) 1250{ 1251 m_user_data = d; 1252 if (m_dwo_symbol_file) 1253 m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); 1254} 1255 1256void 1257DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset) 1258{ 1259 m_addr_base = addr_base; 1260 m_base_obj_offset = base_obj_offset; 1261} 1262