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