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