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_ranges_base(0), 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 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 bool verbose = s->GetVerbose(); 328 if (valid_offset && length_OK && version_OK && addr_size_OK && 329 abbr_offset_OK) { 330 if (verbose) 331 s->Printf(" 0x%8.8x: OK\n", m_offset); 332 return true; 333 } else { 334 s->Printf(" 0x%8.8x: ", m_offset); 335 336 m_dwarf2Data->get_debug_info_data().Dump(s, m_offset, lldb::eFormatHex, 1, 337 Size(), 32, LLDB_INVALID_ADDRESS, 338 0, 0); 339 s->EOL(); 340 if (valid_offset) { 341 if (!length_OK) 342 s->Printf(" The length (0x%8.8x) for this compile unit is too " 343 "large for the .debug_info provided.\n", 344 m_length); 345 if (!version_OK) 346 s->Printf(" The 16 bit compile unit header version is not " 347 "supported.\n"); 348 if (!abbr_offset_OK) 349 s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) " 350 "is not valid.\n", 351 GetAbbrevOffset()); 352 if (!addr_size_OK) 353 s->Printf(" The address size is unsupported: 0x%2.2x\n", 354 m_addr_size); 355 } else 356 s->Printf(" The start offset of the compile unit header in the " 357 ".debug_info is invalid.\n"); 358 } 359 return false; 360 } 361 362 void DWARFCompileUnit::Dump(Stream *s) const { 363 s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, " 364 "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at " 365 "{0x%8.8x})\n", 366 m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, 367 GetNextCompileUnitOffset()); 368 } 369 370 static uint8_t g_default_addr_size = 4; 371 372 uint8_t DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit *cu) { 373 if (cu) 374 return cu->GetAddressByteSize(); 375 return DWARFCompileUnit::GetDefaultAddressSize(); 376 } 377 378 bool DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit *cu) { 379 if (cu) 380 return cu->IsDWARF64(); 381 return false; 382 } 383 384 uint8_t DWARFCompileUnit::GetDefaultAddressSize() { 385 return g_default_addr_size; 386 } 387 388 void DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) { 389 g_default_addr_size = addr_size; 390 } 391 392 lldb::user_id_t DWARFCompileUnit::GetID() const { 393 dw_offset_t local_id = 394 m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset; 395 if (m_dwarf2Data) 396 return DIERef(local_id, local_id).GetUID(m_dwarf2Data); 397 else 398 return local_id; 399 } 400 401 void DWARFCompileUnit::BuildAddressRangeTable( 402 SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges) { 403 // This function is usually called if there in no .debug_aranges section 404 // in order to produce a compile unit level set of address ranges that 405 // is accurate. 406 407 size_t num_debug_aranges = debug_aranges->GetNumRanges(); 408 409 // First get the compile unit DIE only and check if it has a DW_AT_ranges 410 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 411 412 const dw_offset_t cu_offset = GetOffset(); 413 if (die) { 414 DWARFRangeList ranges; 415 const size_t num_ranges = 416 die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false); 417 if (num_ranges > 0) { 418 // This compile unit has DW_AT_ranges, assume this is correct if it 419 // is present since clang no longer makes .debug_aranges by default 420 // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does 421 // this with recent GCC builds. 422 for (size_t i = 0; i < num_ranges; ++i) { 423 const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); 424 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), 425 range.GetRangeEnd()); 426 } 427 428 return; // We got all of our ranges from the DW_AT_ranges attribute 429 } 430 } 431 // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF 432 433 // If the DIEs weren't parsed, then we don't want all dies for all compile 434 // units 435 // to stay loaded when they weren't needed. So we can end up parsing the DWARF 436 // and then throwing them all away to keep memory usage down. 437 const bool clear_dies = ExtractDIEsIfNeeded(false) > 1; 438 439 die = DIEPtr(); 440 if (die) 441 die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); 442 443 if (debug_aranges->GetNumRanges() == num_debug_aranges) { 444 // We got nothing from the functions, maybe we have a line tables only 445 // situation. Check the line tables and build the arange table from this. 446 SymbolContext sc; 447 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 448 if (sc.comp_unit) { 449 SymbolFileDWARFDebugMap *debug_map_sym_file = 450 m_dwarf2Data->GetDebugMapSymfile(); 451 if (debug_map_sym_file == NULL) { 452 LineTable *line_table = sc.comp_unit->GetLineTable(); 453 454 if (line_table) { 455 LineTable::FileAddressRanges file_ranges; 456 const bool append = true; 457 const size_t num_ranges = 458 line_table->GetContiguousFileAddressRanges(file_ranges, append); 459 for (uint32_t idx = 0; idx < num_ranges; ++idx) { 460 const LineTable::FileAddressRanges::Entry &range = 461 file_ranges.GetEntryRef(idx); 462 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), 463 range.GetRangeEnd()); 464 } 465 } 466 } else 467 debug_map_sym_file->AddOSOARanges(dwarf2Data, debug_aranges); 468 } 469 } 470 471 if (debug_aranges->GetNumRanges() == num_debug_aranges) { 472 // We got nothing from the functions, maybe we have a line tables only 473 // situation. Check the line tables and build the arange table from this. 474 SymbolContext sc; 475 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 476 if (sc.comp_unit) { 477 LineTable *line_table = sc.comp_unit->GetLineTable(); 478 479 if (line_table) { 480 LineTable::FileAddressRanges file_ranges; 481 const bool append = true; 482 const size_t num_ranges = 483 line_table->GetContiguousFileAddressRanges(file_ranges, append); 484 for (uint32_t idx = 0; idx < num_ranges; ++idx) { 485 const LineTable::FileAddressRanges::Entry &range = 486 file_ranges.GetEntryRef(idx); 487 debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), 488 range.GetRangeEnd()); 489 } 490 } 491 } 492 } 493 494 // Keep memory down by clearing DIEs if this generate function 495 // caused them to be parsed 496 if (clear_dies) 497 ClearDIEs(true); 498 } 499 500 const DWARFDebugAranges &DWARFCompileUnit::GetFunctionAranges() { 501 if (m_func_aranges_ap.get() == NULL) { 502 m_func_aranges_ap.reset(new DWARFDebugAranges()); 503 Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 504 505 if (log) { 506 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage( 507 log, "DWARFCompileUnit::GetFunctionAranges() for compile unit at " 508 ".debug_info[0x%8.8x]", 509 GetOffset()); 510 } 511 const DWARFDebugInfoEntry *die = DIEPtr(); 512 if (die) 513 die->BuildFunctionAddressRangeTable(m_dwarf2Data, this, 514 m_func_aranges_ap.get()); 515 516 if (m_dwo_symbol_file) { 517 DWARFCompileUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); 518 const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); 519 if (dwo_die) 520 dwo_die->BuildFunctionAddressRangeTable(m_dwo_symbol_file.get(), dwo_cu, 521 m_func_aranges_ap.get()); 522 } 523 524 const bool minimize = false; 525 m_func_aranges_ap->Sort(minimize); 526 } 527 return *m_func_aranges_ap.get(); 528 } 529 530 DWARFDIE 531 DWARFCompileUnit::LookupAddress(const dw_addr_t address) { 532 if (DIE()) { 533 const DWARFDebugAranges &func_aranges = GetFunctionAranges(); 534 535 // Re-check the aranges auto pointer contents in case it was created above 536 if (!func_aranges.IsEmpty()) 537 return GetDIE(func_aranges.FindAddress(address)); 538 } 539 return DWARFDIE(); 540 } 541 542 //---------------------------------------------------------------------- 543 // Compare function DWARFDebugAranges::Range structures 544 //---------------------------------------------------------------------- 545 static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, 546 const dw_offset_t die_offset) { 547 return die.GetOffset() < die_offset; 548 } 549 550 //---------------------------------------------------------------------- 551 // GetDIE() 552 // 553 // Get the DIE (Debug Information Entry) with the specified offset by 554 // first checking if the DIE is contained within this compile unit and 555 // grabbing the DIE from this compile unit. Otherwise we grab the DIE 556 // from the DWARF file. 557 //---------------------------------------------------------------------- 558 DWARFDIE 559 DWARFCompileUnit::GetDIE(dw_offset_t die_offset) { 560 if (die_offset != DW_INVALID_OFFSET) { 561 if (m_dwo_symbol_file) 562 return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset); 563 564 if (ContainsDIEOffset(die_offset)) { 565 ExtractDIEsIfNeeded(false); 566 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 567 DWARFDebugInfoEntry::iterator pos = 568 lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset); 569 if (pos != end) { 570 if (die_offset == (*pos).GetOffset()) 571 return DWARFDIE(this, &(*pos)); 572 } 573 } else { 574 // Don't specify the compile unit offset as we don't know it because the 575 // DIE belongs to 576 // a different compile unit in the same symbol file. 577 return m_dwarf2Data->DebugInfo()->GetDIEForDIEOffset(die_offset); 578 } 579 } 580 return DWARFDIE(); // Not found 581 } 582 583 size_t DWARFCompileUnit::AppendDIEsWithTag(const dw_tag_t tag, 584 DWARFDIECollection &dies, 585 uint32_t depth) const { 586 size_t old_size = dies.Size(); 587 DWARFDebugInfoEntry::const_iterator pos; 588 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 589 for (pos = m_die_array.begin(); pos != end; ++pos) { 590 if (pos->Tag() == tag) 591 dies.Append(DWARFDIE(this, &(*pos))); 592 } 593 594 // Return the number of DIEs added to the collection 595 return dies.Size() - old_size; 596 } 597 598 // void 599 // DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) 600 //{ 601 // m_global_die_indexes.push_back (die_idx); 602 //} 603 // 604 // 605 // void 606 // DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) 607 //{ 608 // // Indexes to all file level global and static variables 609 // m_global_die_indexes; 610 // 611 // if (m_die_array.empty()) 612 // return; 613 // 614 // const DWARFDebugInfoEntry* first_die = &m_die_array[0]; 615 // const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); 616 // if (first_die <= die && die < end) 617 // m_global_die_indexes.push_back (die - first_die); 618 //} 619 620 void DWARFCompileUnit::Index(NameToDIE &func_basenames, 621 NameToDIE &func_fullnames, NameToDIE &func_methods, 622 NameToDIE &func_selectors, 623 NameToDIE &objc_class_selectors, 624 NameToDIE &globals, NameToDIE &types, 625 NameToDIE &namespaces) { 626 Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 627 628 if (log) { 629 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage( 630 log, 631 "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", 632 GetOffset()); 633 } 634 635 const LanguageType cu_language = GetLanguageType(); 636 DWARFFormValue::FixedFormSizes fixed_form_sizes = 637 DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), 638 m_is_dwarf64); 639 640 IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames, 641 func_fullnames, func_methods, func_selectors, 642 objc_class_selectors, globals, types, namespaces); 643 644 SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile(); 645 if (dwo_symbol_file) { 646 IndexPrivate(dwo_symbol_file->GetCompileUnit(), cu_language, 647 fixed_form_sizes, GetOffset(), func_basenames, func_fullnames, 648 func_methods, func_selectors, objc_class_selectors, globals, 649 types, namespaces); 650 } 651 } 652 653 void DWARFCompileUnit::IndexPrivate( 654 DWARFCompileUnit *dwarf_cu, const LanguageType cu_language, 655 const DWARFFormValue::FixedFormSizes &fixed_form_sizes, 656 const dw_offset_t cu_offset, NameToDIE &func_basenames, 657 NameToDIE &func_fullnames, NameToDIE &func_methods, 658 NameToDIE &func_selectors, NameToDIE &objc_class_selectors, 659 NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) { 660 DWARFDebugInfoEntry::const_iterator pos; 661 DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin(); 662 DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end(); 663 for (pos = begin; pos != end; ++pos) { 664 const DWARFDebugInfoEntry &die = *pos; 665 666 const dw_tag_t tag = die.Tag(); 667 668 switch (tag) { 669 case DW_TAG_array_type: 670 case DW_TAG_base_type: 671 case DW_TAG_class_type: 672 case DW_TAG_constant: 673 case DW_TAG_enumeration_type: 674 case DW_TAG_inlined_subroutine: 675 case DW_TAG_namespace: 676 case DW_TAG_string_type: 677 case DW_TAG_structure_type: 678 case DW_TAG_subprogram: 679 case DW_TAG_subroutine_type: 680 case DW_TAG_typedef: 681 case DW_TAG_union_type: 682 case DW_TAG_unspecified_type: 683 case DW_TAG_variable: 684 break; 685 686 default: 687 continue; 688 } 689 690 DWARFAttributes attributes; 691 const char *name = NULL; 692 const char *mangled_cstr = NULL; 693 bool is_declaration = false; 694 // bool is_artificial = false; 695 bool has_address = false; 696 bool has_location_or_const_value = false; 697 bool is_global_or_static_variable = false; 698 699 DWARFFormValue specification_die_form; 700 const size_t num_attributes = 701 die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes); 702 if (num_attributes > 0) { 703 for (uint32_t i = 0; i < num_attributes; ++i) { 704 dw_attr_t attr = attributes.AttributeAtIndex(i); 705 DWARFFormValue form_value; 706 switch (attr) { 707 case DW_AT_name: 708 if (attributes.ExtractFormValueAtIndex(i, form_value)) 709 name = form_value.AsCString(); 710 break; 711 712 case DW_AT_declaration: 713 if (attributes.ExtractFormValueAtIndex(i, form_value)) 714 is_declaration = form_value.Unsigned() != 0; 715 break; 716 717 // case DW_AT_artificial: 718 // if (attributes.ExtractFormValueAtIndex(i, 719 // form_value)) 720 // is_artificial = form_value.Unsigned() != 0; 721 // break; 722 723 case DW_AT_MIPS_linkage_name: 724 case DW_AT_linkage_name: 725 if (attributes.ExtractFormValueAtIndex(i, form_value)) 726 mangled_cstr = form_value.AsCString(); 727 break; 728 729 case DW_AT_low_pc: 730 case DW_AT_high_pc: 731 case DW_AT_ranges: 732 has_address = true; 733 break; 734 735 case DW_AT_entry_pc: 736 has_address = true; 737 break; 738 739 case DW_AT_location: 740 case DW_AT_const_value: 741 has_location_or_const_value = true; 742 if (tag == DW_TAG_variable) { 743 const DWARFDebugInfoEntry *parent_die = die.GetParent(); 744 while (parent_die != NULL) { 745 switch (parent_die->Tag()) { 746 case DW_TAG_subprogram: 747 case DW_TAG_lexical_block: 748 case DW_TAG_inlined_subroutine: 749 // Even if this is a function level static, we don't add it. We 750 // could theoretically 751 // add these if we wanted to by introspecting into the 752 // DW_AT_location and seeing 753 // if the location describes a hard coded address, but we dont 754 // want the performance 755 // penalty of that right now. 756 is_global_or_static_variable = false; 757 // if 758 // (attributes.ExtractFormValueAtIndex(dwarf2Data, 759 // i, form_value)) 760 // { 761 // // If we have valid block 762 // data, then we have location 763 // expression bytes 764 // // that are fixed (not a 765 // location list). 766 // const uint8_t *block_data = 767 // form_value.BlockData(); 768 // if (block_data) 769 // { 770 // uint32_t block_length = 771 // form_value.Unsigned(); 772 // if (block_length == 1 + 773 // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) 774 // { 775 // if (block_data[0] == 776 // DW_OP_addr) 777 // add_die = true; 778 // } 779 // } 780 // } 781 parent_die = NULL; // Terminate the while loop. 782 break; 783 784 case DW_TAG_compile_unit: 785 is_global_or_static_variable = true; 786 parent_die = NULL; // Terminate the while loop. 787 break; 788 789 default: 790 parent_die = 791 parent_die->GetParent(); // Keep going in the while loop. 792 break; 793 } 794 } 795 } 796 break; 797 798 case DW_AT_specification: 799 if (attributes.ExtractFormValueAtIndex(i, form_value)) 800 specification_die_form = form_value; 801 break; 802 } 803 } 804 } 805 806 switch (tag) { 807 case DW_TAG_subprogram: 808 if (has_address) { 809 if (name) { 810 ObjCLanguage::MethodName objc_method(name, true); 811 if (objc_method.IsValid(true)) { 812 ConstString objc_class_name_with_category( 813 objc_method.GetClassNameWithCategory()); 814 ConstString objc_selector_name(objc_method.GetSelector()); 815 ConstString objc_fullname_no_category_name( 816 objc_method.GetFullNameWithoutCategory(true)); 817 ConstString objc_class_name_no_category(objc_method.GetClassName()); 818 func_fullnames.Insert(ConstString(name), 819 DIERef(cu_offset, die.GetOffset())); 820 if (objc_class_name_with_category) 821 objc_class_selectors.Insert(objc_class_name_with_category, 822 DIERef(cu_offset, die.GetOffset())); 823 if (objc_class_name_no_category && 824 objc_class_name_no_category != objc_class_name_with_category) 825 objc_class_selectors.Insert(objc_class_name_no_category, 826 DIERef(cu_offset, die.GetOffset())); 827 if (objc_selector_name) 828 func_selectors.Insert(objc_selector_name, 829 DIERef(cu_offset, die.GetOffset())); 830 if (objc_fullname_no_category_name) 831 func_fullnames.Insert(objc_fullname_no_category_name, 832 DIERef(cu_offset, die.GetOffset())); 833 } 834 // If we have a mangled name, then the DW_AT_name attribute 835 // is usually the method name without the class or any parameters 836 const DWARFDebugInfoEntry *parent = die.GetParent(); 837 bool is_method = false; 838 if (parent) { 839 dw_tag_t parent_tag = parent->Tag(); 840 if (parent_tag == DW_TAG_class_type || 841 parent_tag == DW_TAG_structure_type) { 842 is_method = true; 843 } else { 844 if (specification_die_form.IsValid()) { 845 DWARFDIE specification_die = 846 dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE( 847 DIERef(specification_die_form)); 848 if (specification_die.GetParent().IsStructOrClass()) 849 is_method = true; 850 } 851 } 852 } 853 854 if (is_method) 855 func_methods.Insert(ConstString(name), 856 DIERef(cu_offset, die.GetOffset())); 857 else 858 func_basenames.Insert(ConstString(name), 859 DIERef(cu_offset, die.GetOffset())); 860 861 if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) 862 func_fullnames.Insert(ConstString(name), 863 DIERef(cu_offset, die.GetOffset())); 864 } 865 if (mangled_cstr) { 866 // Make sure our mangled name isn't the same string table entry 867 // as our name. If it starts with '_', then it is ok, else compare 868 // the string to make sure it isn't the same and we don't end up 869 // with duplicate entries 870 if (name && name != mangled_cstr && 871 ((mangled_cstr[0] == '_') || 872 (::strcmp(name, mangled_cstr) != 0))) { 873 Mangled mangled(ConstString(mangled_cstr), true); 874 func_fullnames.Insert(mangled.GetMangledName(), 875 DIERef(cu_offset, die.GetOffset())); 876 ConstString demangled = mangled.GetDemangledName(cu_language); 877 if (demangled) 878 func_fullnames.Insert(demangled, 879 DIERef(cu_offset, die.GetOffset())); 880 } 881 } 882 } 883 break; 884 885 case DW_TAG_inlined_subroutine: 886 if (has_address) { 887 if (name) 888 func_basenames.Insert(ConstString(name), 889 DIERef(cu_offset, die.GetOffset())); 890 if (mangled_cstr) { 891 // Make sure our mangled name isn't the same string table entry 892 // as our name. If it starts with '_', then it is ok, else compare 893 // the string to make sure it isn't the same and we don't end up 894 // with duplicate entries 895 if (name && name != mangled_cstr && 896 ((mangled_cstr[0] == '_') || 897 (::strcmp(name, mangled_cstr) != 0))) { 898 Mangled mangled(ConstString(mangled_cstr), true); 899 func_fullnames.Insert(mangled.GetMangledName(), 900 DIERef(cu_offset, die.GetOffset())); 901 ConstString demangled = mangled.GetDemangledName(cu_language); 902 if (demangled) 903 func_fullnames.Insert(demangled, 904 DIERef(cu_offset, die.GetOffset())); 905 } 906 } else 907 func_fullnames.Insert(ConstString(name), 908 DIERef(cu_offset, die.GetOffset())); 909 } 910 break; 911 912 case DW_TAG_array_type: 913 case DW_TAG_base_type: 914 case DW_TAG_class_type: 915 case DW_TAG_constant: 916 case DW_TAG_enumeration_type: 917 case DW_TAG_string_type: 918 case DW_TAG_structure_type: 919 case DW_TAG_subroutine_type: 920 case DW_TAG_typedef: 921 case DW_TAG_union_type: 922 case DW_TAG_unspecified_type: 923 if (name && !is_declaration) 924 types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); 925 if (mangled_cstr && !is_declaration) 926 types.Insert(ConstString(mangled_cstr), 927 DIERef(cu_offset, die.GetOffset())); 928 break; 929 930 case DW_TAG_namespace: 931 if (name) 932 namespaces.Insert(ConstString(name), 933 DIERef(cu_offset, die.GetOffset())); 934 break; 935 936 case DW_TAG_variable: 937 if (name && has_location_or_const_value && is_global_or_static_variable) { 938 globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); 939 // Be sure to include variables by their mangled and demangled 940 // names if they have any since a variable can have a basename 941 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 942 // mangled name "(anonymous namespace)::i"... 943 944 // Make sure our mangled name isn't the same string table entry 945 // as our name. If it starts with '_', then it is ok, else compare 946 // the string to make sure it isn't the same and we don't end up 947 // with duplicate entries 948 if (mangled_cstr && name != mangled_cstr && 949 ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { 950 Mangled mangled(ConstString(mangled_cstr), true); 951 globals.Insert(mangled.GetMangledName(), 952 DIERef(cu_offset, die.GetOffset())); 953 ConstString demangled = mangled.GetDemangledName(cu_language); 954 if (demangled) 955 globals.Insert(demangled, DIERef(cu_offset, die.GetOffset())); 956 } 957 } 958 break; 959 960 default: 961 continue; 962 } 963 } 964 } 965 966 bool DWARFCompileUnit::Supports_unnamed_objc_bitfields() { 967 if (GetProducer() == eProducerClang) { 968 const uint32_t major_version = GetProducerVersionMajor(); 969 if (major_version > 425 || 970 (major_version == 425 && GetProducerVersionUpdate() >= 13)) 971 return true; 972 else 973 return false; 974 } 975 return true; // Assume all other compilers didn't have incorrect ObjC bitfield 976 // info 977 } 978 979 bool DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type() { 980 if (GetProducer() == eProducerLLVMGCC) 981 return false; 982 return true; 983 } 984 985 bool DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() { 986 // llvm-gcc makes completely invalid decl file attributes and won't ever 987 // be fixed, so we need to know to ignore these. 988 return GetProducer() == eProducerLLVMGCC; 989 } 990 991 void DWARFCompileUnit::ParseProducerInfo() { 992 m_producer_version_major = UINT32_MAX; 993 m_producer_version_minor = UINT32_MAX; 994 m_producer_version_update = UINT32_MAX; 995 996 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 997 if (die) { 998 999 const char *producer_cstr = die->GetAttributeValueAsString( 1000 m_dwarf2Data, this, DW_AT_producer, NULL); 1001 if (producer_cstr) { 1002 RegularExpression llvm_gcc_regex( 1003 llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple " 1004 "Inc\\. build [0-9]+\\) \\(LLVM build " 1005 "[\\.0-9]+\\)$")); 1006 if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) { 1007 m_producer = eProducerLLVMGCC; 1008 } else if (strstr(producer_cstr, "clang")) { 1009 static RegularExpression g_clang_version_regex( 1010 llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)")); 1011 RegularExpression::Match regex_match(3); 1012 if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr), 1013 ®ex_match)) { 1014 std::string str; 1015 if (regex_match.GetMatchAtIndex(producer_cstr, 1, str)) 1016 m_producer_version_major = 1017 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1018 if (regex_match.GetMatchAtIndex(producer_cstr, 2, str)) 1019 m_producer_version_minor = 1020 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1021 if (regex_match.GetMatchAtIndex(producer_cstr, 3, str)) 1022 m_producer_version_update = 1023 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1024 } 1025 m_producer = eProducerClang; 1026 } else if (strstr(producer_cstr, "GNU")) 1027 m_producer = eProducerGCC; 1028 } 1029 } 1030 if (m_producer == eProducerInvalid) 1031 m_producer = eProcucerOther; 1032 } 1033 1034 DWARFCompileUnit::Producer DWARFCompileUnit::GetProducer() { 1035 if (m_producer == eProducerInvalid) 1036 ParseProducerInfo(); 1037 return m_producer; 1038 } 1039 1040 uint32_t DWARFCompileUnit::GetProducerVersionMajor() { 1041 if (m_producer_version_major == 0) 1042 ParseProducerInfo(); 1043 return m_producer_version_major; 1044 } 1045 1046 uint32_t DWARFCompileUnit::GetProducerVersionMinor() { 1047 if (m_producer_version_minor == 0) 1048 ParseProducerInfo(); 1049 return m_producer_version_minor; 1050 } 1051 1052 uint32_t DWARFCompileUnit::GetProducerVersionUpdate() { 1053 if (m_producer_version_update == 0) 1054 ParseProducerInfo(); 1055 return m_producer_version_update; 1056 } 1057 1058 LanguageType DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) { 1059 // Note: user languages between lo_user and hi_user 1060 // must be handled explicitly here. 1061 switch (val) { 1062 case DW_LANG_Mips_Assembler: 1063 return eLanguageTypeMipsAssembler; 1064 case DW_LANG_GOOGLE_RenderScript: 1065 return eLanguageTypeExtRenderScript; 1066 default: 1067 return static_cast<LanguageType>(val); 1068 } 1069 } 1070 1071 LanguageType DWARFCompileUnit::GetLanguageType() { 1072 if (m_language_type != eLanguageTypeUnknown) 1073 return m_language_type; 1074 1075 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 1076 if (die) 1077 m_language_type = LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned( 1078 m_dwarf2Data, this, DW_AT_language, 0)); 1079 return m_language_type; 1080 } 1081 1082 bool DWARFCompileUnit::IsDWARF64() const { return m_is_dwarf64; } 1083 1084 bool DWARFCompileUnit::GetIsOptimized() { 1085 if (m_is_optimized == eLazyBoolCalculate) { 1086 const DWARFDebugInfoEntry *die = GetCompileUnitDIEPtrOnly(); 1087 if (die) { 1088 m_is_optimized = eLazyBoolNo; 1089 if (die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, 1090 DW_AT_APPLE_optimized, 0) == 1) { 1091 m_is_optimized = eLazyBoolYes; 1092 } 1093 } 1094 } 1095 if (m_is_optimized == eLazyBoolYes) { 1096 return true; 1097 } else { 1098 return false; 1099 } 1100 } 1101 1102 DWARFFormValue::FixedFormSizes DWARFCompileUnit::GetFixedFormSizes() { 1103 return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), 1104 IsDWARF64()); 1105 } 1106 1107 TypeSystem *DWARFCompileUnit::GetTypeSystem() { 1108 if (m_dwarf2Data) 1109 return m_dwarf2Data->GetTypeSystemForLanguage(GetLanguageType()); 1110 else 1111 return nullptr; 1112 } 1113 1114 void DWARFCompileUnit::SetUserData(void *d) { 1115 m_user_data = d; 1116 if (m_dwo_symbol_file) 1117 m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); 1118 } 1119 1120 void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, 1121 dw_addr_t ranges_base, 1122 dw_offset_t base_obj_offset) { 1123 m_addr_base = addr_base; 1124 m_ranges_base = ranges_base; 1125 m_base_obj_offset = base_obj_offset; 1126 } 1127 1128 lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const { 1129 return m_dwarf2Data->GetObjectFile()->GetByteOrder(); 1130 } 1131