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