DWARFDebugInfoEntry.cpp revision 276479
1254721Semaste//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "DWARFDebugInfoEntry.h" 11254721Semaste 12254721Semaste#include <assert.h> 13254721Semaste 14254721Semaste#include <algorithm> 15254721Semaste 16254721Semaste#include "lldb/Core/Module.h" 17254721Semaste#include "lldb/Core/Stream.h" 18254721Semaste#include "lldb/Expression/DWARFExpression.h" 19254721Semaste#include "lldb/Symbol/ObjectFile.h" 20254721Semaste 21254721Semaste#include "DWARFCompileUnit.h" 22254721Semaste#include "SymbolFileDWARF.h" 23254721Semaste#include "DWARFDebugAbbrev.h" 24254721Semaste#include "DWARFDebugAranges.h" 25254721Semaste#include "DWARFDebugInfo.h" 26254721Semaste#include "DWARFDeclContext.h" 27254721Semaste#include "DWARFDIECollection.h" 28254721Semaste#include "DWARFFormValue.h" 29254721Semaste#include "DWARFLocationDescription.h" 30254721Semaste#include "DWARFLocationList.h" 31254721Semaste#include "DWARFDebugRanges.h" 32254721Semaste 33254721Semasteusing namespace lldb_private; 34254721Semasteusing namespace std; 35254721Semasteextern int g_verbose; 36254721Semaste 37254721Semaste 38254721Semaste 39254721SemasteDWARFDebugInfoEntry::Attributes::Attributes() : 40254721Semaste m_infos() 41254721Semaste{ 42254721Semaste} 43254721Semaste 44254721SemasteDWARFDebugInfoEntry::Attributes::~Attributes() 45254721Semaste{ 46254721Semaste} 47254721Semaste 48254721Semaste 49254721Semasteuint32_t 50254721SemasteDWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const 51254721Semaste{ 52254721Semaste collection::const_iterator end = m_infos.end(); 53254721Semaste collection::const_iterator beg = m_infos.begin(); 54254721Semaste collection::const_iterator pos; 55254721Semaste for (pos = beg; pos != end; ++pos) 56254721Semaste { 57254721Semaste if (pos->attr == attr) 58254721Semaste return std::distance(beg, pos); 59254721Semaste } 60254721Semaste return UINT32_MAX; 61254721Semaste} 62254721Semaste 63254721Semastevoid 64254721SemasteDWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form) 65254721Semaste{ 66254721Semaste Info info = { cu, attr_die_offset, attr, form }; 67254721Semaste m_infos.push_back(info); 68254721Semaste} 69254721Semaste 70254721Semastebool 71254721SemasteDWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const 72254721Semaste{ 73254721Semaste return FindAttributeIndex(attr) != UINT32_MAX; 74254721Semaste} 75254721Semaste 76254721Semastebool 77254721SemasteDWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr) 78254721Semaste{ 79254721Semaste uint32_t attr_index = FindAttributeIndex(attr); 80254721Semaste if (attr_index != UINT32_MAX) 81254721Semaste { 82254721Semaste m_infos.erase(m_infos.begin() + attr_index); 83254721Semaste return true; 84254721Semaste } 85254721Semaste return false; 86254721Semaste} 87254721Semaste 88254721Semastebool 89254721SemasteDWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const 90254721Semaste{ 91254721Semaste form_value.SetForm(FormAtIndex(i)); 92254721Semaste lldb::offset_t offset = DIEOffsetAtIndex(i); 93254721Semaste return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i)); 94254721Semaste} 95254721Semaste 96254721Semasteuint64_t 97254721SemasteDWARFDebugInfoEntry::Attributes::FormValueAsUnsigned (SymbolFileDWARF* dwarf2Data, dw_attr_t attr, uint64_t fail_value) const 98254721Semaste{ 99254721Semaste const uint32_t attr_idx = FindAttributeIndex (attr); 100254721Semaste if (attr_idx != UINT32_MAX) 101254721Semaste return FormValueAsUnsignedAtIndex (dwarf2Data, attr_idx, fail_value); 102254721Semaste return fail_value; 103254721Semaste} 104254721Semaste 105254721Semasteuint64_t 106254721SemasteDWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const 107254721Semaste{ 108254721Semaste DWARFFormValue form_value; 109254721Semaste if (ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 110254721Semaste return form_value.Reference(CompileUnitAtIndex(i)); 111254721Semaste return fail_value; 112254721Semaste} 113254721Semaste 114254721Semaste 115254721Semaste 116254721Semastebool 117254721SemasteDWARFDebugInfoEntry::FastExtract 118254721Semaste( 119258054Semaste const DWARFDataExtractor& debug_info_data, 120254721Semaste const DWARFCompileUnit* cu, 121254721Semaste const uint8_t *fixed_form_sizes, 122254721Semaste lldb::offset_t *offset_ptr 123254721Semaste) 124254721Semaste{ 125254721Semaste m_offset = *offset_ptr; 126254721Semaste m_parent_idx = 0; 127254721Semaste m_sibling_idx = 0; 128254721Semaste m_empty_children = false; 129254721Semaste const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr); 130254721Semaste assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); 131254721Semaste m_abbr_idx = abbr_idx; 132254721Semaste 133254721Semaste //assert (fixed_form_sizes); // For best performance this should be specified! 134254721Semaste 135254721Semaste if (m_abbr_idx) 136254721Semaste { 137254721Semaste lldb::offset_t offset = *offset_ptr; 138254721Semaste 139254721Semaste const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); 140254721Semaste 141254721Semaste if (abbrevDecl == NULL) 142254721Semaste { 143254721Semaste cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message", 144254721Semaste m_offset, 145254721Semaste (unsigned)abbr_idx); 146254721Semaste // WE can't parse anymore if the DWARF is borked... 147254721Semaste *offset_ptr = UINT32_MAX; 148254721Semaste return false; 149254721Semaste } 150254721Semaste m_tag = abbrevDecl->Tag(); 151254721Semaste m_has_children = abbrevDecl->HasChildren(); 152254721Semaste // Skip all data in the .debug_info for the attributes 153254721Semaste const uint32_t numAttributes = abbrevDecl->NumAttributes(); 154258054Semaste uint32_t i; 155258054Semaste dw_form_t form; 156254721Semaste for (i=0; i<numAttributes; ++i) 157254721Semaste { 158254721Semaste form = abbrevDecl->GetFormByIndexUnchecked(i); 159254721Semaste 160254721Semaste const uint8_t fixed_skip_size = fixed_form_sizes [form]; 161254721Semaste if (fixed_skip_size) 162254721Semaste offset += fixed_skip_size; 163254721Semaste else 164254721Semaste { 165254721Semaste bool form_is_indirect = false; 166254721Semaste do 167254721Semaste { 168254721Semaste form_is_indirect = false; 169258054Semaste uint32_t form_size = 0; 170254721Semaste switch (form) 171254721Semaste { 172254721Semaste // Blocks if inlined data that have a length field and the data bytes 173254721Semaste // inlined in the .debug_info 174254721Semaste case DW_FORM_exprloc : 175254721Semaste case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break; 176254721Semaste case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break; 177254721Semaste case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break; 178254721Semaste case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break; 179254721Semaste 180254721Semaste // Inlined NULL terminated C-strings 181254721Semaste case DW_FORM_string : 182254721Semaste debug_info_data.GetCStr (&offset); 183254721Semaste break; 184254721Semaste 185254721Semaste // Compile unit address sized values 186254721Semaste case DW_FORM_addr : 187254721Semaste form_size = cu->GetAddressByteSize(); 188254721Semaste break; 189254721Semaste case DW_FORM_ref_addr : 190254721Semaste if (cu->GetVersion() <= 2) 191254721Semaste form_size = cu->GetAddressByteSize(); 192254721Semaste else 193254721Semaste form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet 194254721Semaste break; 195254721Semaste 196254721Semaste // 0 sized form 197254721Semaste case DW_FORM_flag_present: 198254721Semaste form_size = 0; 199254721Semaste break; 200254721Semaste 201254721Semaste // 1 byte values 202254721Semaste case DW_FORM_data1 : 203254721Semaste case DW_FORM_flag : 204254721Semaste case DW_FORM_ref1 : 205254721Semaste form_size = 1; 206254721Semaste break; 207254721Semaste 208254721Semaste // 2 byte values 209254721Semaste case DW_FORM_data2 : 210254721Semaste case DW_FORM_ref2 : 211254721Semaste form_size = 2; 212254721Semaste break; 213254721Semaste 214254721Semaste // 4 byte values 215254721Semaste case DW_FORM_strp : 216254721Semaste case DW_FORM_data4 : 217254721Semaste case DW_FORM_ref4 : 218254721Semaste form_size = 4; 219254721Semaste break; 220254721Semaste 221254721Semaste // 8 byte values 222254721Semaste case DW_FORM_data8 : 223254721Semaste case DW_FORM_ref8 : 224254721Semaste case DW_FORM_ref_sig8 : 225254721Semaste form_size = 8; 226254721Semaste break; 227254721Semaste 228254721Semaste // signed or unsigned LEB 128 values 229254721Semaste case DW_FORM_sdata : 230254721Semaste case DW_FORM_udata : 231254721Semaste case DW_FORM_ref_udata : 232254721Semaste debug_info_data.Skip_LEB128 (&offset); 233254721Semaste break; 234254721Semaste 235254721Semaste case DW_FORM_indirect : 236254721Semaste form_is_indirect = true; 237254721Semaste form = debug_info_data.GetULEB128 (&offset); 238254721Semaste break; 239254721Semaste 240254721Semaste case DW_FORM_sec_offset : 241254721Semaste if (cu->GetAddressByteSize () == 4) 242254721Semaste debug_info_data.GetU32 (offset_ptr); 243254721Semaste else 244254721Semaste debug_info_data.GetU64 (offset_ptr); 245254721Semaste break; 246254721Semaste 247254721Semaste default: 248254721Semaste *offset_ptr = m_offset; 249254721Semaste return false; 250254721Semaste } 251254721Semaste offset += form_size; 252254721Semaste 253254721Semaste } while (form_is_indirect); 254254721Semaste } 255254721Semaste } 256254721Semaste *offset_ptr = offset; 257254721Semaste return true; 258254721Semaste } 259254721Semaste else 260254721Semaste { 261254721Semaste m_tag = 0; 262254721Semaste m_has_children = false; 263254721Semaste return true; // NULL debug tag entry 264254721Semaste } 265254721Semaste 266254721Semaste return false; 267254721Semaste} 268254721Semaste 269254721Semaste//---------------------------------------------------------------------- 270254721Semaste// Extract 271254721Semaste// 272254721Semaste// Extract a debug info entry for a given compile unit from the 273254721Semaste// .debug_info and .debug_abbrev data within the SymbolFileDWARF class 274254721Semaste// starting at the given offset 275254721Semaste//---------------------------------------------------------------------- 276254721Semastebool 277254721SemasteDWARFDebugInfoEntry::Extract 278254721Semaste( 279254721Semaste SymbolFileDWARF* dwarf2Data, 280254721Semaste const DWARFCompileUnit* cu, 281254721Semaste lldb::offset_t *offset_ptr 282254721Semaste) 283254721Semaste{ 284258054Semaste const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 285258054Semaste// const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data(); 286254721Semaste const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); 287254721Semaste const uint8_t cu_addr_size = cu->GetAddressByteSize(); 288254721Semaste lldb::offset_t offset = *offset_ptr; 289254721Semaste// if (offset >= cu_end_offset) 290254721Semaste// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset); 291254721Semaste if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) 292254721Semaste { 293254721Semaste m_offset = offset; 294254721Semaste 295254721Semaste const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); 296254721Semaste assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); 297254721Semaste m_abbr_idx = abbr_idx; 298254721Semaste if (abbr_idx) 299254721Semaste { 300254721Semaste const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); 301254721Semaste 302254721Semaste if (abbrevDecl) 303254721Semaste { 304254721Semaste m_tag = abbrevDecl->Tag(); 305254721Semaste m_has_children = abbrevDecl->HasChildren(); 306254721Semaste 307254721Semaste bool isCompileUnitTag = m_tag == DW_TAG_compile_unit; 308254721Semaste if (cu && isCompileUnitTag) 309254721Semaste ((DWARFCompileUnit*)cu)->SetBaseAddress(0); 310254721Semaste 311254721Semaste // Skip all data in the .debug_info for the attributes 312254721Semaste const uint32_t numAttributes = abbrevDecl->NumAttributes(); 313254721Semaste uint32_t i; 314254721Semaste dw_attr_t attr; 315254721Semaste dw_form_t form; 316254721Semaste for (i=0; i<numAttributes; ++i) 317254721Semaste { 318254721Semaste abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 319254721Semaste 320254721Semaste if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) 321254721Semaste { 322254721Semaste DWARFFormValue form_value(form); 323254721Semaste if (form_value.ExtractValue(debug_info_data, &offset, cu)) 324254721Semaste { 325254721Semaste if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) 326254721Semaste ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned()); 327254721Semaste } 328254721Semaste } 329254721Semaste else 330254721Semaste { 331254721Semaste bool form_is_indirect = false; 332254721Semaste do 333254721Semaste { 334254721Semaste form_is_indirect = false; 335258054Semaste uint32_t form_size = 0; 336254721Semaste switch (form) 337254721Semaste { 338254721Semaste // Blocks if inlined data that have a length field and the data bytes 339254721Semaste // inlined in the .debug_info 340254721Semaste case DW_FORM_exprloc : 341254721Semaste case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break; 342254721Semaste case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break; 343254721Semaste case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break; 344254721Semaste case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break; 345254721Semaste 346254721Semaste // Inlined NULL terminated C-strings 347254721Semaste case DW_FORM_string : debug_info_data.GetCStr(&offset); break; 348254721Semaste 349254721Semaste // Compile unit address sized values 350254721Semaste case DW_FORM_addr : 351254721Semaste form_size = cu_addr_size; 352254721Semaste break; 353254721Semaste case DW_FORM_ref_addr : 354254721Semaste if (cu->GetVersion() <= 2) 355254721Semaste form_size = cu_addr_size; 356254721Semaste else 357254721Semaste form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet 358254721Semaste break; 359254721Semaste 360254721Semaste // 0 sized form 361254721Semaste case DW_FORM_flag_present: 362254721Semaste form_size = 0; 363254721Semaste break; 364254721Semaste 365254721Semaste // 1 byte values 366254721Semaste case DW_FORM_data1 : 367254721Semaste case DW_FORM_flag : 368254721Semaste case DW_FORM_ref1 : 369254721Semaste form_size = 1; 370254721Semaste break; 371254721Semaste 372254721Semaste // 2 byte values 373254721Semaste case DW_FORM_data2 : 374254721Semaste case DW_FORM_ref2 : 375254721Semaste form_size = 2; 376254721Semaste break; 377254721Semaste 378254721Semaste // 4 byte values 379254721Semaste case DW_FORM_strp : 380254721Semaste form_size = 4; 381254721Semaste break; 382254721Semaste 383254721Semaste case DW_FORM_data4 : 384254721Semaste case DW_FORM_ref4 : 385254721Semaste form_size = 4; 386254721Semaste break; 387254721Semaste 388254721Semaste // 8 byte values 389254721Semaste case DW_FORM_data8 : 390254721Semaste case DW_FORM_ref8 : 391254721Semaste case DW_FORM_ref_sig8 : 392254721Semaste form_size = 8; 393254721Semaste break; 394254721Semaste 395254721Semaste // signed or unsigned LEB 128 values 396254721Semaste case DW_FORM_sdata : 397254721Semaste case DW_FORM_udata : 398254721Semaste case DW_FORM_ref_udata : 399254721Semaste debug_info_data.Skip_LEB128(&offset); 400254721Semaste break; 401254721Semaste 402254721Semaste case DW_FORM_indirect : 403254721Semaste form = debug_info_data.GetULEB128(&offset); 404254721Semaste form_is_indirect = true; 405254721Semaste break; 406254721Semaste 407254721Semaste case DW_FORM_sec_offset : 408254721Semaste if (cu->GetAddressByteSize () == 4) 409254721Semaste debug_info_data.GetU32 (offset_ptr); 410254721Semaste else 411254721Semaste debug_info_data.GetU64 (offset_ptr); 412254721Semaste break; 413254721Semaste 414254721Semaste default: 415254721Semaste *offset_ptr = offset; 416254721Semaste return false; 417254721Semaste } 418254721Semaste 419254721Semaste offset += form_size; 420254721Semaste } while (form_is_indirect); 421254721Semaste } 422254721Semaste } 423254721Semaste *offset_ptr = offset; 424254721Semaste return true; 425254721Semaste } 426254721Semaste } 427254721Semaste else 428254721Semaste { 429254721Semaste m_tag = 0; 430254721Semaste m_has_children = false; 431254721Semaste *offset_ptr = offset; 432254721Semaste return true; // NULL debug tag entry 433254721Semaste } 434254721Semaste } 435254721Semaste 436254721Semaste return false; 437254721Semaste} 438254721Semaste 439254721Semaste//---------------------------------------------------------------------- 440254721Semaste// DumpAncestry 441254721Semaste// 442254721Semaste// Dumps all of a debug information entries parents up until oldest and 443254721Semaste// all of it's attributes to the specified stream. 444254721Semaste//---------------------------------------------------------------------- 445254721Semastevoid 446254721SemasteDWARFDebugInfoEntry::DumpAncestry 447254721Semaste( 448254721Semaste SymbolFileDWARF* dwarf2Data, 449254721Semaste const DWARFCompileUnit* cu, 450254721Semaste const DWARFDebugInfoEntry* oldest, 451254721Semaste Stream &s, 452254721Semaste uint32_t recurse_depth 453254721Semaste) const 454254721Semaste{ 455254721Semaste const DWARFDebugInfoEntry* parent = GetParent(); 456254721Semaste if (parent && parent != oldest) 457254721Semaste parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0); 458254721Semaste Dump(dwarf2Data, cu, s, recurse_depth); 459254721Semaste} 460254721Semaste 461254721Semaste//---------------------------------------------------------------------- 462254721Semaste// Compare two DIE by comparing all their attributes values, and 463254721Semaste// following all DW_FORM_ref attributes and comparing their contents as 464254721Semaste// well (except for DW_AT_sibling attributes. 465254721Semaste// 466254721Semaste// DWARFDebugInfoEntry::CompareState compare_state; 467254721Semaste// int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true); 468254721Semaste//---------------------------------------------------------------------- 469254721Semaste//int 470254721Semaste//DWARFDebugInfoEntry::Compare 471254721Semaste//( 472254721Semaste// SymbolFileDWARF* dwarf2Data, 473254721Semaste// dw_offset_t a_die_offset, 474254721Semaste// dw_offset_t b_die_offset, 475254721Semaste// CompareState &compare_state, 476254721Semaste// bool compare_siblings, 477254721Semaste// bool compare_children 478254721Semaste//) 479254721Semaste//{ 480254721Semaste// if (a_die_offset == b_die_offset) 481254721Semaste// return 0; 482254721Semaste// 483254721Semaste// DWARFCompileUnitSP a_cu_sp; 484254721Semaste// DWARFCompileUnitSP b_cu_sp; 485254721Semaste// const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp); 486254721Semaste// const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp); 487254721Semaste// 488254721Semaste// return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children); 489254721Semaste//} 490254721Semaste// 491254721Semaste//int 492254721Semaste//DWARFDebugInfoEntry::Compare 493254721Semaste//( 494254721Semaste// SymbolFileDWARF* dwarf2Data, 495254721Semaste// DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 496254721Semaste// DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 497254721Semaste// CompareState &compare_state, 498254721Semaste// bool compare_siblings, 499254721Semaste// bool compare_children 500254721Semaste//) 501254721Semaste//{ 502254721Semaste// if (a_die == b_die) 503254721Semaste// return 0; 504254721Semaste// 505254721Semaste// if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset())) 506254721Semaste// { 507254721Semaste// // We are already comparing both of these types, so let 508254721Semaste// // compares complete for the real result 509254721Semaste// return 0; 510254721Semaste// } 511254721Semaste// 512254721Semaste// //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset()); 513254721Semaste// 514254721Semaste// // Do we have two valid DIEs? 515254721Semaste// if (a_die && b_die) 516254721Semaste// { 517254721Semaste// // Both DIE are valid 518254721Semaste// int result = 0; 519254721Semaste// 520254721Semaste// const dw_tag_t a_tag = a_die->Tag(); 521254721Semaste// const dw_tag_t b_tag = b_die->Tag(); 522254721Semaste// if (a_tag == 0 && b_tag == 0) 523254721Semaste// return 0; 524254721Semaste// 525254721Semaste// //printf(" comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag)); 526254721Semaste// 527254721Semaste// if (a_tag < b_tag) 528254721Semaste// return -1; 529254721Semaste// else if (a_tag > b_tag) 530254721Semaste// return 1; 531254721Semaste// 532254721Semaste// DWARFDebugInfoEntry::Attributes a_attrs; 533254721Semaste// DWARFDebugInfoEntry::Attributes b_attrs; 534254721Semaste// size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs); 535254721Semaste// size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs); 536254721Semaste// if (a_attr_count != b_attr_count) 537254721Semaste// { 538254721Semaste// a_attrs.RemoveAttribute(DW_AT_sibling); 539254721Semaste// b_attrs.RemoveAttribute(DW_AT_sibling); 540254721Semaste// } 541254721Semaste// 542254721Semaste// a_attr_count = a_attrs.Size(); 543254721Semaste// b_attr_count = b_attrs.Size(); 544254721Semaste// 545254721Semaste// DWARFFormValue a_form_value; 546254721Semaste// DWARFFormValue b_form_value; 547254721Semaste// 548254721Semaste// if (a_attr_count != b_attr_count) 549254721Semaste// { 550254721Semaste// uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration); 551254721Semaste// uint32_t a_name_index = UINT32_MAX; 552254721Semaste// uint32_t b_name_index = UINT32_MAX; 553254721Semaste// if (is_decl_index != UINT32_MAX) 554254721Semaste// { 555254721Semaste// if (a_attr_count == 2) 556254721Semaste// { 557254721Semaste// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); 558254721Semaste// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); 559254721Semaste// } 560254721Semaste// } 561254721Semaste// else 562254721Semaste// { 563254721Semaste// is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration); 564254721Semaste// if (is_decl_index != UINT32_MAX && a_attr_count == 2) 565254721Semaste// { 566254721Semaste// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); 567254721Semaste// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); 568254721Semaste// } 569254721Semaste// } 570254721Semaste// if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX) 571254721Semaste// { 572254721Semaste// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) && 573254721Semaste// b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value)) 574254721Semaste// { 575254721Semaste// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data()); 576254721Semaste// if (result == 0) 577254721Semaste// { 578254721Semaste// a_attr_count = b_attr_count = 0; 579254721Semaste// compare_children = false; 580254721Semaste// } 581254721Semaste// } 582254721Semaste// } 583254721Semaste// } 584254721Semaste// 585254721Semaste// if (a_attr_count < b_attr_count) 586254721Semaste// return -1; 587254721Semaste// if (a_attr_count > b_attr_count) 588254721Semaste// return 1; 589254721Semaste// 590254721Semaste// 591254721Semaste// // The number of attributes are the same... 592254721Semaste// if (a_attr_count > 0) 593254721Semaste// { 594258054Semaste// const DWARFDataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data(); 595254721Semaste// 596254721Semaste// uint32_t i; 597254721Semaste// for (i=0; i<a_attr_count; ++i) 598254721Semaste// { 599254721Semaste// const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i); 600254721Semaste// const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i); 601254721Semaste// //printf(" comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n", 602254721Semaste// // a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr), 603254721Semaste// // b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr)); 604254721Semaste// 605254721Semaste// if (a_attr < b_attr) 606254721Semaste// return -1; 607254721Semaste// else if (a_attr > b_attr) 608254721Semaste// return 1; 609254721Semaste// 610254721Semaste// switch (a_attr) 611254721Semaste// { 612254721Semaste// // Since we call a form of GetAttributes which inlines the 613254721Semaste// // attributes from DW_AT_abstract_origin and DW_AT_specification 614254721Semaste// // we don't care if their values mismatch... 615254721Semaste// case DW_AT_abstract_origin: 616254721Semaste// case DW_AT_specification: 617254721Semaste// case DW_AT_sibling: 618254721Semaste// case DW_AT_containing_type: 619254721Semaste// //printf(" action = IGNORE\n"); 620254721Semaste// result = 0; 621254721Semaste// break; // ignore 622254721Semaste// 623254721Semaste// default: 624254721Semaste// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) && 625254721Semaste// b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value)) 626254721Semaste// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr); 627254721Semaste// break; 628254721Semaste// } 629254721Semaste// 630254721Semaste// //printf("\t result = %i\n", result); 631254721Semaste// 632254721Semaste// if (result != 0) 633254721Semaste// { 634254721Semaste// // Attributes weren't equal, lets see if we care? 635254721Semaste// switch (a_attr) 636254721Semaste// { 637254721Semaste// case DW_AT_decl_file: 638254721Semaste// // TODO: add the ability to compare files in two different compile units 639254721Semaste// if (a_cu == b_cu) 640254721Semaste// { 641254721Semaste// //printf(" action = RETURN RESULT\n"); 642254721Semaste// return result; // Only return the compare results when the compile units are the same and the decl_file attributes can be compared 643254721Semaste// } 644254721Semaste// else 645254721Semaste// { 646254721Semaste// result = 0; 647254721Semaste// //printf(" action = IGNORE\n"); 648254721Semaste// } 649254721Semaste// break; 650254721Semaste// 651254721Semaste// default: 652254721Semaste// switch (a_attrs.FormAtIndex(i)) 653254721Semaste// { 654254721Semaste// case DW_FORM_ref1: 655254721Semaste// case DW_FORM_ref2: 656254721Semaste// case DW_FORM_ref4: 657254721Semaste// case DW_FORM_ref8: 658254721Semaste// case DW_FORM_ref_udata: 659254721Semaste// case DW_FORM_ref_addr: 660254721Semaste// //printf(" action = COMPARE DIEs 0x%8.8x 0x%8.8x\n", (dw_offset_t)a_form_value.Reference(a_cu), (dw_offset_t)b_form_value.Reference(b_cu)); 661254721Semaste// // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets... 662254721Semaste// result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true); 663254721Semaste// if (result != 0) 664254721Semaste// return result; 665254721Semaste// break; 666254721Semaste// 667254721Semaste// default: 668254721Semaste// // We do care that they were different, return this result... 669254721Semaste// //printf(" action = RETURN RESULT\n"); 670254721Semaste// return result; 671254721Semaste// } 672254721Semaste// } 673254721Semaste// } 674254721Semaste// } 675254721Semaste// } 676254721Semaste// //printf(" SUCCESS\n\t\t0x%8.8x: %s\n\t\t0x%8.8x: %s\n", a_die->GetOffset(), DW_TAG_value_to_name(a_tag), b_die->GetOffset(), DW_TAG_value_to_name(b_tag)); 677254721Semaste// 678254721Semaste// if (compare_children) 679254721Semaste// { 680254721Semaste// bool a_has_children = a_die->HasChildren(); 681254721Semaste// bool b_has_children = b_die->HasChildren(); 682254721Semaste// if (a_has_children == b_has_children) 683254721Semaste// { 684254721Semaste// // Both either have kids or don't 685254721Semaste// if (a_has_children) 686254721Semaste// result = Compare( dwarf2Data, 687254721Semaste// a_cu, a_die->GetFirstChild(), 688254721Semaste// b_cu, b_die->GetFirstChild(), 689254721Semaste// compare_state, true, compare_children); 690254721Semaste// else 691254721Semaste// result = 0; 692254721Semaste// } 693254721Semaste// else if (!a_has_children) 694254721Semaste// result = -1; // A doesn't have kids, but B does 695254721Semaste// else 696254721Semaste// result = 1; // A has kids, but B doesn't 697254721Semaste// } 698254721Semaste// 699254721Semaste// if (compare_siblings) 700254721Semaste// { 701254721Semaste// result = Compare( dwarf2Data, 702254721Semaste// a_cu, a_die->GetSibling(), 703254721Semaste// b_cu, b_die->GetSibling(), 704254721Semaste// compare_state, true, compare_children); 705254721Semaste// } 706254721Semaste// 707254721Semaste// return result; 708254721Semaste// } 709254721Semaste// 710254721Semaste// if (a_die == NULL) 711254721Semaste// return -1; // a_die is NULL, yet b_die is non-NULL 712254721Semaste// else 713254721Semaste// return 1; // a_die is non-NULL, yet b_die is NULL 714254721Semaste// 715254721Semaste//} 716254721Semaste// 717254721Semaste// 718254721Semaste//int 719254721Semaste//DWARFDebugInfoEntry::Compare 720254721Semaste//( 721254721Semaste// SymbolFileDWARF* dwarf2Data, 722254721Semaste// const DWARFCompileUnit* cu_a, 723254721Semaste// const DWARFDebugInfoEntry* die_a, 724254721Semaste// const DWARFCompileUnit* cu_a, 725254721Semaste// const DWARFDebugInfoEntry* die_b, 726254721Semaste// CompareState &compare_state 727254721Semaste//) 728254721Semaste//{ 729254721Semaste//} 730254721Semaste 731254721Semaste//---------------------------------------------------------------------- 732254721Semaste// GetDIENamesAndRanges 733254721Semaste// 734254721Semaste// Gets the valid address ranges for a given DIE by looking for a 735254721Semaste// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges 736254721Semaste// attributes. 737254721Semaste//---------------------------------------------------------------------- 738254721Semastebool 739254721SemasteDWARFDebugInfoEntry::GetDIENamesAndRanges 740254721Semaste( 741254721Semaste SymbolFileDWARF* dwarf2Data, 742254721Semaste const DWARFCompileUnit* cu, 743254721Semaste const char * &name, 744254721Semaste const char * &mangled, 745254721Semaste DWARFDebugRanges::RangeList& ranges, 746254721Semaste int& decl_file, 747254721Semaste int& decl_line, 748254721Semaste int& decl_column, 749254721Semaste int& call_file, 750254721Semaste int& call_line, 751254721Semaste int& call_column, 752254721Semaste DWARFExpression *frame_base 753254721Semaste) const 754254721Semaste{ 755254721Semaste if (dwarf2Data == NULL) 756254721Semaste return false; 757254721Semaste 758254721Semaste dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 759254721Semaste dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 760254721Semaste std::vector<dw_offset_t> die_offsets; 761254721Semaste bool set_frame_base_loclist_addr = false; 762254721Semaste 763254721Semaste lldb::offset_t offset; 764254721Semaste const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); 765254721Semaste 766258054Semaste lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); 767258054Semaste 768254721Semaste if (abbrevDecl) 769254721Semaste { 770258054Semaste const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 771254721Semaste 772254721Semaste if (!debug_info_data.ValidOffset(offset)) 773254721Semaste return false; 774254721Semaste 775254721Semaste const uint32_t numAttributes = abbrevDecl->NumAttributes(); 776254721Semaste uint32_t i; 777254721Semaste dw_attr_t attr; 778254721Semaste dw_form_t form; 779254721Semaste bool do_offset = false; 780254721Semaste 781254721Semaste for (i=0; i<numAttributes; ++i) 782254721Semaste { 783254721Semaste abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 784254721Semaste DWARFFormValue form_value(form); 785254721Semaste if (form_value.ExtractValue(debug_info_data, &offset, cu)) 786254721Semaste { 787254721Semaste switch (attr) 788254721Semaste { 789254721Semaste case DW_AT_low_pc: 790254721Semaste lo_pc = form_value.Unsigned(); 791254721Semaste 792254721Semaste if (do_offset) 793254721Semaste hi_pc += lo_pc; 794254721Semaste do_offset = false; 795254721Semaste break; 796254721Semaste 797254721Semaste case DW_AT_entry_pc: 798254721Semaste lo_pc = form_value.Unsigned(); 799254721Semaste break; 800254721Semaste 801254721Semaste case DW_AT_high_pc: 802254721Semaste hi_pc = form_value.Unsigned(); 803254721Semaste if (form_value.Form() != DW_FORM_addr) 804254721Semaste { 805254721Semaste if (lo_pc == LLDB_INVALID_ADDRESS) 806254721Semaste do_offset = hi_pc != LLDB_INVALID_ADDRESS; 807254721Semaste else 808254721Semaste hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations 809254721Semaste } 810254721Semaste break; 811254721Semaste 812254721Semaste case DW_AT_ranges: 813254721Semaste { 814254721Semaste const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); 815254721Semaste debug_ranges->FindRanges(form_value.Unsigned(), ranges); 816254721Semaste // All DW_AT_ranges are relative to the base address of the 817254721Semaste // compile unit. We add the compile unit base address to make 818254721Semaste // sure all the addresses are properly fixed up. 819254721Semaste ranges.Slide(cu->GetBaseAddress()); 820254721Semaste } 821254721Semaste break; 822254721Semaste 823254721Semaste case DW_AT_name: 824254721Semaste if (name == NULL) 825254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 826254721Semaste break; 827254721Semaste 828254721Semaste case DW_AT_MIPS_linkage_name: 829254721Semaste case DW_AT_linkage_name: 830254721Semaste if (mangled == NULL) 831254721Semaste mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 832254721Semaste break; 833254721Semaste 834254721Semaste case DW_AT_abstract_origin: 835254721Semaste die_offsets.push_back(form_value.Reference(cu)); 836254721Semaste break; 837254721Semaste 838254721Semaste case DW_AT_specification: 839254721Semaste die_offsets.push_back(form_value.Reference(cu)); 840254721Semaste break; 841254721Semaste 842254721Semaste case DW_AT_decl_file: 843254721Semaste if (decl_file == 0) 844254721Semaste decl_file = form_value.Unsigned(); 845254721Semaste break; 846254721Semaste 847254721Semaste case DW_AT_decl_line: 848254721Semaste if (decl_line == 0) 849254721Semaste decl_line = form_value.Unsigned(); 850254721Semaste break; 851254721Semaste 852254721Semaste case DW_AT_decl_column: 853254721Semaste if (decl_column == 0) 854254721Semaste decl_column = form_value.Unsigned(); 855254721Semaste break; 856254721Semaste 857254721Semaste case DW_AT_call_file: 858254721Semaste if (call_file == 0) 859254721Semaste call_file = form_value.Unsigned(); 860254721Semaste break; 861254721Semaste 862254721Semaste case DW_AT_call_line: 863254721Semaste if (call_line == 0) 864254721Semaste call_line = form_value.Unsigned(); 865254721Semaste break; 866254721Semaste 867254721Semaste case DW_AT_call_column: 868254721Semaste if (call_column == 0) 869254721Semaste call_column = form_value.Unsigned(); 870254721Semaste break; 871254721Semaste 872254721Semaste case DW_AT_frame_base: 873254721Semaste if (frame_base) 874254721Semaste { 875254721Semaste if (form_value.BlockData()) 876254721Semaste { 877254721Semaste uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 878254721Semaste uint32_t block_length = form_value.Unsigned(); 879258054Semaste frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length); 880254721Semaste } 881254721Semaste else 882254721Semaste { 883258054Semaste const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data(); 884254721Semaste const dw_offset_t debug_loc_offset = form_value.Unsigned(); 885254721Semaste 886254721Semaste size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 887254721Semaste if (loc_list_length > 0) 888254721Semaste { 889258054Semaste frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); 890254721Semaste if (lo_pc != LLDB_INVALID_ADDRESS) 891254721Semaste { 892254721Semaste assert (lo_pc >= cu->GetBaseAddress()); 893254721Semaste frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress()); 894254721Semaste } 895254721Semaste else 896254721Semaste { 897254721Semaste set_frame_base_loclist_addr = true; 898254721Semaste } 899254721Semaste } 900254721Semaste } 901254721Semaste } 902254721Semaste break; 903254721Semaste 904254721Semaste default: 905254721Semaste break; 906254721Semaste } 907254721Semaste } 908254721Semaste } 909254721Semaste } 910254721Semaste 911254721Semaste if (ranges.IsEmpty()) 912254721Semaste { 913254721Semaste if (lo_pc != LLDB_INVALID_ADDRESS) 914254721Semaste { 915254721Semaste if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) 916254721Semaste ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc)); 917254721Semaste else 918254721Semaste ranges.Append(DWARFDebugRanges::Range (lo_pc, 0)); 919254721Semaste } 920254721Semaste } 921254721Semaste 922254721Semaste if (set_frame_base_loclist_addr) 923254721Semaste { 924254721Semaste dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); 925254721Semaste assert (lowest_range_pc >= cu->GetBaseAddress()); 926254721Semaste frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress()); 927254721Semaste } 928254721Semaste 929254721Semaste if (ranges.IsEmpty() || name == NULL || mangled == NULL) 930254721Semaste { 931254721Semaste std::vector<dw_offset_t>::const_iterator pos; 932254721Semaste std::vector<dw_offset_t>::const_iterator end = die_offsets.end(); 933254721Semaste for (pos = die_offsets.begin(); pos != end; ++pos) 934254721Semaste { 935254721Semaste DWARFCompileUnitSP cu_sp_ptr; 936254721Semaste const DWARFDebugInfoEntry* die = NULL; 937254721Semaste dw_offset_t die_offset = *pos; 938254721Semaste if (die_offset != DW_INVALID_OFFSET) 939254721Semaste { 940254721Semaste die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr); 941254721Semaste if (die) 942254721Semaste die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column); 943254721Semaste } 944254721Semaste } 945254721Semaste } 946254721Semaste return !ranges.IsEmpty(); 947254721Semaste} 948254721Semaste 949254721Semaste//---------------------------------------------------------------------- 950254721Semaste// Dump 951254721Semaste// 952254721Semaste// Dumps a debug information entry and all of it's attributes to the 953254721Semaste// specified stream. 954254721Semaste//---------------------------------------------------------------------- 955254721Semastevoid 956254721SemasteDWARFDebugInfoEntry::Dump 957254721Semaste( 958254721Semaste SymbolFileDWARF* dwarf2Data, 959254721Semaste const DWARFCompileUnit* cu, 960254721Semaste Stream &s, 961254721Semaste uint32_t recurse_depth 962254721Semaste) const 963254721Semaste{ 964258054Semaste const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 965254721Semaste lldb::offset_t offset = m_offset; 966254721Semaste 967254721Semaste if (debug_info_data.ValidOffset(offset)) 968254721Semaste { 969254721Semaste dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset); 970254721Semaste 971254721Semaste s.Printf("\n0x%8.8x: ", m_offset); 972254721Semaste s.Indent(); 973254721Semaste if (abbrCode != m_abbr_idx) 974254721Semaste { 975254721Semaste s.Printf( "error: DWARF has been modified\n"); 976254721Semaste } 977254721Semaste else if (abbrCode) 978254721Semaste { 979254721Semaste const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode); 980254721Semaste 981254721Semaste if (abbrevDecl) 982254721Semaste { 983254721Semaste s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); 984254721Semaste s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' '); 985254721Semaste 986254721Semaste // Dump all data in the .debug_info for the attributes 987254721Semaste const uint32_t numAttributes = abbrevDecl->NumAttributes(); 988254721Semaste uint32_t i; 989254721Semaste dw_attr_t attr; 990254721Semaste dw_form_t form; 991254721Semaste for (i=0; i<numAttributes; ++i) 992254721Semaste { 993254721Semaste abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 994254721Semaste 995254721Semaste DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form); 996254721Semaste } 997254721Semaste 998254721Semaste const DWARFDebugInfoEntry* child = GetFirstChild(); 999254721Semaste if (recurse_depth > 0 && child) 1000254721Semaste { 1001254721Semaste s.IndentMore(); 1002254721Semaste 1003254721Semaste while (child) 1004254721Semaste { 1005254721Semaste child->Dump(dwarf2Data, cu, s, recurse_depth-1); 1006254721Semaste child = child->GetSibling(); 1007254721Semaste } 1008254721Semaste s.IndentLess(); 1009254721Semaste } 1010254721Semaste } 1011254721Semaste else 1012254721Semaste s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode); 1013254721Semaste } 1014254721Semaste else 1015254721Semaste { 1016254721Semaste s.Printf( "NULL\n"); 1017254721Semaste } 1018254721Semaste } 1019254721Semaste} 1020254721Semaste 1021254721Semastevoid 1022254721SemasteDWARFDebugInfoEntry::DumpLocation 1023254721Semaste( 1024254721Semaste SymbolFileDWARF* dwarf2Data, 1025254721Semaste DWARFCompileUnit* cu, 1026254721Semaste Stream &s 1027254721Semaste) const 1028254721Semaste{ 1029254721Semaste const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly(); 1030254721Semaste const char *cu_name = NULL; 1031254721Semaste if (cu_die != NULL) 1032254721Semaste cu_name = cu_die->GetName (dwarf2Data, cu); 1033254721Semaste const char *obj_file_name = NULL; 1034254721Semaste ObjectFile *obj_file = dwarf2Data->GetObjectFile(); 1035254721Semaste if (obj_file) 1036254721Semaste obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString(); 1037254721Semaste const char *die_name = GetName (dwarf2Data, cu); 1038254721Semaste s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", 1039254721Semaste cu->GetOffset(), 1040254721Semaste GetOffset(), 1041254721Semaste die_name ? die_name : "", 1042254721Semaste cu_name ? cu_name : "<NULL>", 1043254721Semaste obj_file_name ? obj_file_name : "<NULL>"); 1044254721Semaste} 1045254721Semaste 1046254721Semaste//---------------------------------------------------------------------- 1047254721Semaste// DumpAttribute 1048254721Semaste// 1049254721Semaste// Dumps a debug information entry attribute along with it's form. Any 1050254721Semaste// special display of attributes is done (disassemble location lists, 1051254721Semaste// show enumeration values for attributes, etc). 1052254721Semaste//---------------------------------------------------------------------- 1053254721Semastevoid 1054254721SemasteDWARFDebugInfoEntry::DumpAttribute 1055254721Semaste( 1056254721Semaste SymbolFileDWARF* dwarf2Data, 1057254721Semaste const DWARFCompileUnit* cu, 1058258054Semaste const DWARFDataExtractor& debug_info_data, 1059254721Semaste lldb::offset_t *offset_ptr, 1060254721Semaste Stream &s, 1061254721Semaste dw_attr_t attr, 1062254721Semaste dw_form_t form 1063254721Semaste) 1064254721Semaste{ 1065254721Semaste bool verbose = s.GetVerbose(); 1066254721Semaste bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); 1067254721Semaste 1068258054Semaste const DWARFDataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL; 1069254721Semaste if (verbose) 1070254721Semaste s.Offset (*offset_ptr); 1071254721Semaste else 1072254721Semaste s.Printf (" "); 1073254721Semaste s.Indent(DW_AT_value_to_name(attr)); 1074254721Semaste 1075254721Semaste if (show_form) 1076254721Semaste { 1077254721Semaste s.Printf( "[%s", DW_FORM_value_to_name(form)); 1078254721Semaste } 1079254721Semaste 1080254721Semaste DWARFFormValue form_value(form); 1081254721Semaste 1082254721Semaste if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu)) 1083254721Semaste return; 1084254721Semaste 1085254721Semaste if (show_form) 1086254721Semaste { 1087254721Semaste if (form == DW_FORM_indirect) 1088254721Semaste { 1089254721Semaste s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form())); 1090254721Semaste } 1091254721Semaste 1092254721Semaste s.PutCString("] "); 1093254721Semaste } 1094254721Semaste 1095254721Semaste s.PutCString("( "); 1096254721Semaste 1097254721Semaste // Always dump form value if verbose is enabled 1098254721Semaste if (verbose) 1099254721Semaste { 1100254721Semaste form_value.Dump(s, debug_str_data, cu); 1101254721Semaste } 1102254721Semaste 1103254721Semaste 1104254721Semaste // Check to see if we have any special attribute formatters 1105254721Semaste switch (attr) 1106254721Semaste { 1107254721Semaste case DW_AT_stmt_list: 1108254721Semaste if ( verbose ) s.PutCString(" ( "); 1109254721Semaste s.Printf( "0x%8.8" PRIx64, form_value.Unsigned()); 1110254721Semaste if ( verbose ) s.PutCString(" )"); 1111254721Semaste break; 1112254721Semaste 1113254721Semaste case DW_AT_language: 1114254721Semaste if ( verbose ) s.PutCString(" ( "); 1115254721Semaste s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); 1116254721Semaste if ( verbose ) s.PutCString(" )"); 1117254721Semaste break; 1118254721Semaste 1119254721Semaste case DW_AT_encoding: 1120254721Semaste if ( verbose ) s.PutCString(" ( "); 1121254721Semaste s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); 1122254721Semaste if ( verbose ) s.PutCString(" )"); 1123254721Semaste break; 1124254721Semaste 1125254721Semaste case DW_AT_frame_base: 1126254721Semaste case DW_AT_location: 1127254721Semaste case DW_AT_data_member_location: 1128254721Semaste { 1129254721Semaste const uint8_t* blockData = form_value.BlockData(); 1130254721Semaste if (blockData) 1131254721Semaste { 1132254721Semaste if (!verbose) 1133254721Semaste form_value.Dump(s, debug_str_data, cu); 1134254721Semaste 1135254721Semaste // Location description is inlined in data in the form value 1136258054Semaste DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); 1137254721Semaste if ( verbose ) s.PutCString(" ( "); 1138254721Semaste print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false); 1139254721Semaste if ( verbose ) s.PutCString(" )"); 1140254721Semaste } 1141254721Semaste else 1142254721Semaste { 1143254721Semaste // We have a location list offset as the value that is 1144254721Semaste // the offset into the .debug_loc section that describes 1145254721Semaste // the value over it's lifetime 1146254721Semaste uint64_t debug_loc_offset = form_value.Unsigned(); 1147254721Semaste if (dwarf2Data) 1148254721Semaste { 1149254721Semaste if ( !verbose ) 1150254721Semaste form_value.Dump(s, debug_str_data, cu); 1151254721Semaste DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); 1152254721Semaste } 1153254721Semaste else 1154254721Semaste { 1155254721Semaste if ( !verbose ) 1156254721Semaste form_value.Dump(s, NULL, cu); 1157254721Semaste } 1158254721Semaste } 1159254721Semaste } 1160254721Semaste break; 1161254721Semaste 1162254721Semaste case DW_AT_abstract_origin: 1163254721Semaste case DW_AT_specification: 1164254721Semaste { 1165254721Semaste uint64_t abstract_die_offset = form_value.Reference(cu); 1166254721Semaste form_value.Dump(s, debug_str_data, cu); 1167254721Semaste // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; 1168254721Semaste if ( verbose ) s.PutCString(" ( "); 1169254721Semaste GetName(dwarf2Data, cu, abstract_die_offset, s); 1170254721Semaste if ( verbose ) s.PutCString(" )"); 1171254721Semaste } 1172254721Semaste break; 1173254721Semaste 1174254721Semaste case DW_AT_type: 1175254721Semaste { 1176254721Semaste uint64_t type_die_offset = form_value.Reference(cu); 1177254721Semaste if (!verbose) 1178254721Semaste form_value.Dump(s, debug_str_data, cu); 1179254721Semaste s.PutCString(" ( "); 1180254721Semaste AppendTypeName(dwarf2Data, cu, type_die_offset, s); 1181254721Semaste s.PutCString(" )"); 1182254721Semaste } 1183254721Semaste break; 1184254721Semaste 1185254721Semaste case DW_AT_ranges: 1186254721Semaste { 1187254721Semaste if ( !verbose ) 1188254721Semaste form_value.Dump(s, debug_str_data, cu); 1189254721Semaste lldb::offset_t ranges_offset = form_value.Unsigned(); 1190254721Semaste dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; 1191254721Semaste if (dwarf2Data) 1192254721Semaste DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr); 1193254721Semaste } 1194254721Semaste break; 1195254721Semaste 1196254721Semaste default: 1197254721Semaste if ( !verbose ) 1198254721Semaste form_value.Dump(s, debug_str_data, cu); 1199254721Semaste break; 1200254721Semaste } 1201254721Semaste 1202254721Semaste s.PutCString(" )\n"); 1203254721Semaste} 1204254721Semaste 1205254721Semaste//---------------------------------------------------------------------- 1206254721Semaste// Get all attribute values for a given DIE, including following any 1207254721Semaste// specification or abstract origin attributes and including those in 1208254721Semaste// the results. Any duplicate attributes will have the first instance 1209254721Semaste// take precedence (this can happen for declaration attributes). 1210254721Semaste//---------------------------------------------------------------------- 1211254721Semastesize_t 1212254721SemasteDWARFDebugInfoEntry::GetAttributes 1213254721Semaste( 1214254721Semaste SymbolFileDWARF* dwarf2Data, 1215254721Semaste const DWARFCompileUnit* cu, 1216254721Semaste const uint8_t *fixed_form_sizes, 1217254721Semaste DWARFDebugInfoEntry::Attributes& attributes, 1218254721Semaste uint32_t curr_depth 1219254721Semaste) const 1220254721Semaste{ 1221254721Semaste lldb::offset_t offset; 1222254721Semaste const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); 1223254721Semaste 1224254721Semaste if (abbrevDecl) 1225254721Semaste { 1226258054Semaste const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 1227254721Semaste 1228254721Semaste if (fixed_form_sizes == NULL) 1229254721Semaste fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize()); 1230254721Semaste 1231254721Semaste const uint32_t num_attributes = abbrevDecl->NumAttributes(); 1232254721Semaste uint32_t i; 1233254721Semaste dw_attr_t attr; 1234254721Semaste dw_form_t form; 1235254721Semaste DWARFFormValue form_value; 1236254721Semaste for (i=0; i<num_attributes; ++i) 1237254721Semaste { 1238254721Semaste abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form); 1239254721Semaste 1240254721Semaste // If we are tracking down DW_AT_specification or DW_AT_abstract_origin 1241254721Semaste // attributes, the depth will be non-zero. We need to omit certain 1242254721Semaste // attributes that don't make sense. 1243254721Semaste switch (attr) 1244254721Semaste { 1245254721Semaste case DW_AT_sibling: 1246254721Semaste case DW_AT_declaration: 1247254721Semaste if (curr_depth > 0) 1248254721Semaste { 1249254721Semaste // This attribute doesn't make sense when combined with 1250254721Semaste // the DIE that references this DIE. We know a DIE is 1251254721Semaste // referencing this DIE because curr_depth is not zero 1252254721Semaste break; 1253254721Semaste } 1254254721Semaste // Fall through... 1255254721Semaste default: 1256254721Semaste attributes.Append(cu, offset, attr, form); 1257254721Semaste break; 1258254721Semaste } 1259254721Semaste 1260254721Semaste if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) 1261254721Semaste { 1262254721Semaste form_value.SetForm(form); 1263254721Semaste if (form_value.ExtractValue(debug_info_data, &offset, cu)) 1264254721Semaste { 1265254721Semaste const DWARFDebugInfoEntry* die = NULL; 1266254721Semaste dw_offset_t die_offset = form_value.Reference(cu); 1267254721Semaste if (cu->ContainsDIEOffset(die_offset)) 1268254721Semaste { 1269254721Semaste die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset); 1270254721Semaste if (die) 1271254721Semaste die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1); 1272254721Semaste } 1273254721Semaste else 1274254721Semaste { 1275254721Semaste DWARFCompileUnitSP cu_sp_ptr; 1276254721Semaste die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr); 1277254721Semaste if (die) 1278254721Semaste die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1); 1279254721Semaste } 1280254721Semaste } 1281254721Semaste } 1282254721Semaste else 1283254721Semaste { 1284254721Semaste const uint8_t fixed_skip_size = fixed_form_sizes [form]; 1285254721Semaste if (fixed_skip_size) 1286254721Semaste offset += fixed_skip_size; 1287254721Semaste else 1288254721Semaste DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); 1289254721Semaste } 1290254721Semaste } 1291254721Semaste } 1292254721Semaste else 1293254721Semaste { 1294254721Semaste attributes.Clear(); 1295254721Semaste } 1296254721Semaste return attributes.Size(); 1297254721Semaste 1298254721Semaste} 1299254721Semaste 1300254721Semaste//---------------------------------------------------------------------- 1301254721Semaste// GetAttributeValue 1302254721Semaste// 1303254721Semaste// Get the value of an attribute and return the .debug_info offset of the 1304254721Semaste// attribute if it was properly extracted into form_value, or zero 1305254721Semaste// if we fail since an offset of zero is invalid for an attribute (it 1306254721Semaste// would be a compile unit header). 1307254721Semaste//---------------------------------------------------------------------- 1308254721Semastedw_offset_t 1309254721SemasteDWARFDebugInfoEntry::GetAttributeValue 1310254721Semaste( 1311254721Semaste SymbolFileDWARF* dwarf2Data, 1312254721Semaste const DWARFCompileUnit* cu, 1313254721Semaste const dw_attr_t attr, 1314254721Semaste DWARFFormValue& form_value, 1315254721Semaste dw_offset_t* end_attr_offset_ptr 1316254721Semaste) const 1317254721Semaste{ 1318254721Semaste lldb::offset_t offset; 1319254721Semaste const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); 1320254721Semaste 1321254721Semaste if (abbrevDecl) 1322254721Semaste { 1323254721Semaste uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); 1324254721Semaste 1325254721Semaste if (attr_idx != DW_INVALID_INDEX) 1326254721Semaste { 1327258054Semaste const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 1328254721Semaste 1329254721Semaste uint32_t idx=0; 1330254721Semaste while (idx<attr_idx) 1331254721Semaste DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu); 1332254721Semaste 1333254721Semaste const dw_offset_t attr_offset = offset; 1334254721Semaste form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); 1335254721Semaste if (form_value.ExtractValue(debug_info_data, &offset, cu)) 1336254721Semaste { 1337254721Semaste if (end_attr_offset_ptr) 1338254721Semaste *end_attr_offset_ptr = offset; 1339254721Semaste return attr_offset; 1340254721Semaste } 1341254721Semaste } 1342254721Semaste } 1343254721Semaste 1344254721Semaste return 0; 1345254721Semaste} 1346254721Semaste 1347254721Semaste//---------------------------------------------------------------------- 1348254721Semaste// GetAttributeValueAsString 1349254721Semaste// 1350254721Semaste// Get the value of an attribute as a string return it. The resulting 1351254721Semaste// pointer to the string data exists within the supplied SymbolFileDWARF 1352254721Semaste// and will only be available as long as the SymbolFileDWARF is still around 1353254721Semaste// and it's content doesn't change. 1354254721Semaste//---------------------------------------------------------------------- 1355254721Semasteconst char* 1356254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsString 1357254721Semaste( 1358254721Semaste SymbolFileDWARF* dwarf2Data, 1359254721Semaste const DWARFCompileUnit* cu, 1360254721Semaste const dw_attr_t attr, 1361254721Semaste const char* fail_value) const 1362254721Semaste{ 1363254721Semaste DWARFFormValue form_value; 1364254721Semaste if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1365254721Semaste return form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1366254721Semaste return fail_value; 1367254721Semaste} 1368254721Semaste 1369254721Semaste//---------------------------------------------------------------------- 1370254721Semaste// GetAttributeValueAsUnsigned 1371254721Semaste// 1372254721Semaste// Get the value of an attribute as unsigned and return it. 1373254721Semaste//---------------------------------------------------------------------- 1374254721Semasteuint64_t 1375254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsUnsigned 1376254721Semaste( 1377254721Semaste SymbolFileDWARF* dwarf2Data, 1378254721Semaste const DWARFCompileUnit* cu, 1379254721Semaste const dw_attr_t attr, 1380254721Semaste uint64_t fail_value 1381254721Semaste) const 1382254721Semaste{ 1383254721Semaste DWARFFormValue form_value; 1384254721Semaste if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1385254721Semaste return form_value.Unsigned(); 1386254721Semaste return fail_value; 1387254721Semaste} 1388254721Semaste 1389254721Semaste//---------------------------------------------------------------------- 1390254721Semaste// GetAttributeValueAsSigned 1391254721Semaste// 1392254721Semaste// Get the value of an attribute a signed value and return it. 1393254721Semaste//---------------------------------------------------------------------- 1394254721Semasteint64_t 1395254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsSigned 1396254721Semaste( 1397254721Semaste SymbolFileDWARF* dwarf2Data, 1398254721Semaste const DWARFCompileUnit* cu, 1399254721Semaste const dw_attr_t attr, 1400254721Semaste int64_t fail_value 1401254721Semaste) const 1402254721Semaste{ 1403254721Semaste DWARFFormValue form_value; 1404254721Semaste if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1405254721Semaste return form_value.Signed(); 1406254721Semaste return fail_value; 1407254721Semaste} 1408254721Semaste 1409254721Semaste//---------------------------------------------------------------------- 1410254721Semaste// GetAttributeValueAsReference 1411254721Semaste// 1412254721Semaste// Get the value of an attribute as reference and fix up and compile 1413254721Semaste// unit relative offsets as needed. 1414254721Semaste//---------------------------------------------------------------------- 1415254721Semasteuint64_t 1416254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsReference 1417254721Semaste( 1418254721Semaste SymbolFileDWARF* dwarf2Data, 1419254721Semaste const DWARFCompileUnit* cu, 1420254721Semaste const dw_attr_t attr, 1421254721Semaste uint64_t fail_value 1422254721Semaste) const 1423254721Semaste{ 1424254721Semaste DWARFFormValue form_value; 1425254721Semaste if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1426254721Semaste return form_value.Reference(cu); 1427254721Semaste return fail_value; 1428254721Semaste} 1429254721Semaste 1430254721Semaste//---------------------------------------------------------------------- 1431254721Semaste// GetAttributeHighPC 1432254721Semaste// 1433254721Semaste// Get the hi_pc, adding hi_pc to lo_pc when specified 1434254721Semaste// as an <offset-from-low-pc>. 1435254721Semaste// 1436254721Semaste// Returns the hi_pc or fail_value. 1437254721Semaste//---------------------------------------------------------------------- 1438254721Semastedw_addr_t 1439254721SemasteDWARFDebugInfoEntry::GetAttributeHighPC 1440254721Semaste( 1441254721Semaste SymbolFileDWARF* dwarf2Data, 1442254721Semaste const DWARFCompileUnit* cu, 1443254721Semaste dw_addr_t lo_pc, 1444254721Semaste uint64_t fail_value 1445254721Semaste) const 1446254721Semaste{ 1447254721Semaste DWARFFormValue form_value; 1448254721Semaste 1449254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value)) 1450254721Semaste { 1451254721Semaste dw_addr_t hi_pc = form_value.Unsigned(); 1452254721Semaste if (form_value.Form() != DW_FORM_addr) 1453254721Semaste hi_pc += lo_pc; // DWARF4 can specify the hi_pc as an <offset-from-lowpc> 1454254721Semaste return hi_pc; 1455254721Semaste } 1456254721Semaste return fail_value; 1457254721Semaste} 1458254721Semaste 1459254721Semaste//---------------------------------------------------------------------- 1460254721Semaste// GetAttributeAddressRange 1461254721Semaste// 1462254721Semaste// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified 1463254721Semaste// as an <offset-from-low-pc>. 1464254721Semaste// 1465254721Semaste// Returns true or sets lo_pc and hi_pc to fail_value. 1466254721Semaste//---------------------------------------------------------------------- 1467254721Semastebool 1468254721SemasteDWARFDebugInfoEntry::GetAttributeAddressRange 1469254721Semaste( 1470254721Semaste SymbolFileDWARF* dwarf2Data, 1471254721Semaste const DWARFCompileUnit* cu, 1472254721Semaste dw_addr_t& lo_pc, 1473254721Semaste dw_addr_t& hi_pc, 1474254721Semaste uint64_t fail_value 1475254721Semaste) const 1476254721Semaste{ 1477254721Semaste lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value); 1478254721Semaste if (lo_pc != fail_value) 1479254721Semaste { 1480254721Semaste hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value); 1481254721Semaste if (hi_pc != fail_value) 1482254721Semaste return true; 1483254721Semaste } 1484254721Semaste lo_pc = fail_value; 1485254721Semaste hi_pc = fail_value; 1486254721Semaste return false; 1487254721Semaste} 1488276479Sdim 1489276479Sdimsize_t 1490276479SdimDWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data, 1491276479Sdim const DWARFCompileUnit* cu, 1492276479Sdim DWARFDebugRanges::RangeList &ranges, 1493276479Sdim bool check_hi_lo_pc) const 1494276479Sdim{ 1495276479Sdim ranges.Clear(); 1496276479Sdim 1497276479Sdim dw_offset_t ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); 1498276479Sdim if (ranges_offset != DW_INVALID_OFFSET) 1499276479Sdim { 1500276479Sdim dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); 1501276479Sdim if (debug_ranges_offset != DW_INVALID_OFFSET) 1502276479Sdim { 1503276479Sdim DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); 1504276479Sdim 1505276479Sdim debug_ranges->FindRanges(debug_ranges_offset, ranges); 1506276479Sdim ranges.Slide (cu->GetBaseAddress()); 1507276479Sdim } 1508276479Sdim } 1509276479Sdim else if (check_hi_lo_pc) 1510276479Sdim { 1511276479Sdim dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 1512276479Sdim dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 1513276479Sdim if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) 1514276479Sdim { 1515276479Sdim if (lo_pc < hi_pc) 1516276479Sdim ranges.Append(DWARFDebugRanges::RangeList::Entry(lo_pc, hi_pc - lo_pc)); 1517276479Sdim } 1518276479Sdim } 1519276479Sdim return ranges.GetSize(); 1520276479Sdim} 1521276479Sdim 1522254721Semaste//---------------------------------------------------------------------- 1523254721Semaste// GetAttributeValueAsLocation 1524254721Semaste// 1525254721Semaste// Get the value of an attribute as reference and fix up and compile 1526254721Semaste// unit relative offsets as needed. 1527254721Semaste//---------------------------------------------------------------------- 1528254721Semastedw_offset_t 1529254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsLocation 1530254721Semaste( 1531254721Semaste SymbolFileDWARF* dwarf2Data, 1532254721Semaste const DWARFCompileUnit* cu, 1533254721Semaste const dw_attr_t attr, 1534258054Semaste DWARFDataExtractor& location_data, 1535254721Semaste uint32_t &block_size 1536254721Semaste) const 1537254721Semaste{ 1538254721Semaste block_size = 0; 1539254721Semaste DWARFFormValue form_value; 1540254721Semaste 1541254721Semaste // Empty out data in case we don't find anything 1542254721Semaste location_data.Clear(); 1543254721Semaste dw_offset_t end_addr_offset = DW_INVALID_OFFSET; 1544254721Semaste const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset); 1545254721Semaste if (attr_offset) 1546254721Semaste { 1547254721Semaste const uint8_t* blockData = form_value.BlockData(); 1548254721Semaste if (blockData) 1549254721Semaste { 1550254721Semaste // We have an inlined location list in the .debug_info section 1551258054Semaste const DWARFDataExtractor& debug_info = dwarf2Data->get_debug_info_data(); 1552254721Semaste dw_offset_t block_offset = blockData - debug_info.GetDataStart(); 1553254721Semaste block_size = (end_addr_offset - attr_offset) - form_value.Unsigned(); 1554254721Semaste location_data.SetData(debug_info, block_offset, block_size); 1555254721Semaste } 1556254721Semaste else 1557254721Semaste { 1558254721Semaste // We have a location list offset as the value that is 1559254721Semaste // the offset into the .debug_loc section that describes 1560254721Semaste // the value over it's lifetime 1561254721Semaste lldb::offset_t debug_loc_offset = form_value.Unsigned(); 1562254721Semaste if (dwarf2Data) 1563254721Semaste { 1564254721Semaste assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize()); 1565254721Semaste return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data); 1566254721Semaste } 1567254721Semaste } 1568254721Semaste } 1569254721Semaste return attr_offset; 1570254721Semaste} 1571254721Semaste 1572254721Semaste//---------------------------------------------------------------------- 1573254721Semaste// GetName 1574254721Semaste// 1575254721Semaste// Get value of the DW_AT_name attribute and return it if one exists, 1576254721Semaste// else return NULL. 1577254721Semaste//---------------------------------------------------------------------- 1578254721Semasteconst char* 1579254721SemasteDWARFDebugInfoEntry::GetName 1580254721Semaste( 1581254721Semaste SymbolFileDWARF* dwarf2Data, 1582254721Semaste const DWARFCompileUnit* cu 1583254721Semaste) const 1584254721Semaste{ 1585254721Semaste DWARFFormValue form_value; 1586254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1587254721Semaste return form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1588254721Semaste else 1589254721Semaste { 1590254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) 1591254721Semaste { 1592254721Semaste DWARFCompileUnitSP cu_sp_ptr; 1593254721Semaste const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr); 1594254721Semaste if (die) 1595254721Semaste return die->GetName(dwarf2Data, cu_sp_ptr.get()); 1596254721Semaste } 1597254721Semaste } 1598254721Semaste return NULL; 1599254721Semaste} 1600254721Semaste 1601254721Semaste 1602254721Semaste//---------------------------------------------------------------------- 1603254721Semaste// GetMangledName 1604254721Semaste// 1605254721Semaste// Get value of the DW_AT_MIPS_linkage_name attribute and return it if 1606254721Semaste// one exists, else return the value of the DW_AT_name attribute 1607254721Semaste//---------------------------------------------------------------------- 1608254721Semasteconst char* 1609254721SemasteDWARFDebugInfoEntry::GetMangledName 1610254721Semaste( 1611254721Semaste SymbolFileDWARF* dwarf2Data, 1612254721Semaste const DWARFCompileUnit* cu, 1613254721Semaste bool substitute_name_allowed 1614254721Semaste) const 1615254721Semaste{ 1616254721Semaste const char* name = NULL; 1617254721Semaste DWARFFormValue form_value; 1618254721Semaste 1619254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) 1620254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1621254721Semaste 1622254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value)) 1623254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1624254721Semaste 1625254721Semaste if (substitute_name_allowed && name == NULL) 1626254721Semaste { 1627254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1628254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1629254721Semaste } 1630254721Semaste return name; 1631254721Semaste} 1632254721Semaste 1633254721Semaste 1634254721Semaste//---------------------------------------------------------------------- 1635254721Semaste// GetPubname 1636254721Semaste// 1637254721Semaste// Get value the name for a DIE as it should appear for a 1638254721Semaste// .debug_pubnames or .debug_pubtypes section. 1639254721Semaste//---------------------------------------------------------------------- 1640254721Semasteconst char* 1641254721SemasteDWARFDebugInfoEntry::GetPubname 1642254721Semaste( 1643254721Semaste SymbolFileDWARF* dwarf2Data, 1644254721Semaste const DWARFCompileUnit* cu 1645254721Semaste) const 1646254721Semaste{ 1647254721Semaste const char* name = NULL; 1648254721Semaste if (!dwarf2Data) 1649254721Semaste return name; 1650254721Semaste 1651254721Semaste DWARFFormValue form_value; 1652254721Semaste 1653254721Semaste if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) 1654254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1655254721Semaste else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value)) 1656254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1657254721Semaste else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1658254721Semaste name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1659254721Semaste else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) 1660254721Semaste { 1661254721Semaste // The specification DIE may be in another compile unit so we need 1662254721Semaste // to get a die and its compile unit. 1663254721Semaste DWARFCompileUnitSP cu_sp_ptr; 1664254721Semaste const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr); 1665254721Semaste if (die) 1666254721Semaste return die->GetPubname(dwarf2Data, cu_sp_ptr.get()); 1667254721Semaste } 1668254721Semaste return name; 1669254721Semaste} 1670254721Semaste 1671254721Semaste 1672254721Semaste//---------------------------------------------------------------------- 1673254721Semaste// GetName 1674254721Semaste// 1675254721Semaste// Get value of the DW_AT_name attribute for a debug information entry 1676254721Semaste// that exists at offset "die_offset" and place that value into the 1677254721Semaste// supplied stream object. If the DIE is a NULL object "NULL" is placed 1678254721Semaste// into the stream, and if no DW_AT_name attribute exists for the DIE 1679254721Semaste// then nothing is printed. 1680254721Semaste//---------------------------------------------------------------------- 1681254721Semastebool 1682254721SemasteDWARFDebugInfoEntry::GetName 1683254721Semaste( 1684254721Semaste SymbolFileDWARF* dwarf2Data, 1685254721Semaste const DWARFCompileUnit* cu, 1686254721Semaste const dw_offset_t die_offset, 1687254721Semaste Stream &s 1688254721Semaste) 1689254721Semaste{ 1690254721Semaste if (dwarf2Data == NULL) 1691254721Semaste { 1692254721Semaste s.PutCString("NULL"); 1693254721Semaste return false; 1694254721Semaste } 1695254721Semaste 1696254721Semaste DWARFDebugInfoEntry die; 1697254721Semaste lldb::offset_t offset = die_offset; 1698254721Semaste if (die.Extract(dwarf2Data, cu, &offset)) 1699254721Semaste { 1700254721Semaste if (die.IsNULL()) 1701254721Semaste { 1702254721Semaste s.PutCString("NULL"); 1703254721Semaste return true; 1704254721Semaste } 1705254721Semaste else 1706254721Semaste { 1707254721Semaste DWARFFormValue form_value; 1708254721Semaste if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1709254721Semaste { 1710254721Semaste const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1711254721Semaste if (name) 1712254721Semaste { 1713254721Semaste s.PutCString(name); 1714254721Semaste return true; 1715254721Semaste } 1716254721Semaste } 1717254721Semaste } 1718254721Semaste } 1719254721Semaste return false; 1720254721Semaste} 1721254721Semaste 1722254721Semaste//---------------------------------------------------------------------- 1723254721Semaste// AppendTypeName 1724254721Semaste// 1725254721Semaste// Follows the type name definition down through all needed tags to 1726254721Semaste// end up with a fully qualified type name and dump the results to 1727254721Semaste// the supplied stream. This is used to show the name of types given 1728254721Semaste// a type identifier. 1729254721Semaste//---------------------------------------------------------------------- 1730254721Semastebool 1731254721SemasteDWARFDebugInfoEntry::AppendTypeName 1732254721Semaste( 1733254721Semaste SymbolFileDWARF* dwarf2Data, 1734254721Semaste const DWARFCompileUnit* cu, 1735254721Semaste const dw_offset_t die_offset, 1736254721Semaste Stream &s 1737254721Semaste) 1738254721Semaste{ 1739254721Semaste if (dwarf2Data == NULL) 1740254721Semaste { 1741254721Semaste s.PutCString("NULL"); 1742254721Semaste return false; 1743254721Semaste } 1744254721Semaste 1745254721Semaste DWARFDebugInfoEntry die; 1746254721Semaste lldb::offset_t offset = die_offset; 1747254721Semaste if (die.Extract(dwarf2Data, cu, &offset)) 1748254721Semaste { 1749254721Semaste if (die.IsNULL()) 1750254721Semaste { 1751254721Semaste s.PutCString("NULL"); 1752254721Semaste return true; 1753254721Semaste } 1754254721Semaste else 1755254721Semaste { 1756254721Semaste const char* name = die.GetPubname(dwarf2Data, cu); 1757254721Semaste // if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1758254721Semaste // name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1759254721Semaste if (name) 1760254721Semaste s.PutCString(name); 1761254721Semaste else 1762254721Semaste { 1763254721Semaste bool result = true; 1764254721Semaste const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset); 1765254721Semaste 1766254721Semaste if (abbrevDecl == NULL) 1767254721Semaste return false; 1768254721Semaste 1769254721Semaste switch (abbrevDecl->Tag()) 1770254721Semaste { 1771254721Semaste case DW_TAG_array_type: break; // print out a "[]" after printing the full type of the element below 1772254721Semaste case DW_TAG_base_type: s.PutCString("base "); break; 1773254721Semaste case DW_TAG_class_type: s.PutCString("class "); break; 1774254721Semaste case DW_TAG_const_type: s.PutCString("const "); break; 1775254721Semaste case DW_TAG_enumeration_type: s.PutCString("enum "); break; 1776254721Semaste case DW_TAG_file_type: s.PutCString("file "); break; 1777254721Semaste case DW_TAG_interface_type: s.PutCString("interface "); break; 1778254721Semaste case DW_TAG_packed_type: s.PutCString("packed "); break; 1779254721Semaste case DW_TAG_pointer_type: break; // print out a '*' after printing the full type below 1780254721Semaste case DW_TAG_ptr_to_member_type: break; // print out a '*' after printing the full type below 1781254721Semaste case DW_TAG_reference_type: break; // print out a '&' after printing the full type below 1782254721Semaste case DW_TAG_restrict_type: s.PutCString("restrict "); break; 1783254721Semaste case DW_TAG_set_type: s.PutCString("set "); break; 1784254721Semaste case DW_TAG_shared_type: s.PutCString("shared "); break; 1785254721Semaste case DW_TAG_string_type: s.PutCString("string "); break; 1786254721Semaste case DW_TAG_structure_type: s.PutCString("struct "); break; 1787254721Semaste case DW_TAG_subrange_type: s.PutCString("subrange "); break; 1788254721Semaste case DW_TAG_subroutine_type: s.PutCString("function "); break; 1789254721Semaste case DW_TAG_thrown_type: s.PutCString("thrown "); break; 1790254721Semaste case DW_TAG_union_type: s.PutCString("union "); break; 1791254721Semaste case DW_TAG_unspecified_type: s.PutCString("unspecified "); break; 1792254721Semaste case DW_TAG_volatile_type: s.PutCString("volatile "); break; 1793254721Semaste default: 1794254721Semaste return false; 1795254721Semaste } 1796254721Semaste 1797254721Semaste // Follow the DW_AT_type if possible 1798254721Semaste DWARFFormValue form_value; 1799254721Semaste if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) 1800254721Semaste { 1801254721Semaste uint64_t next_die_offset = form_value.Reference(cu); 1802254721Semaste result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); 1803254721Semaste } 1804254721Semaste 1805254721Semaste switch (abbrevDecl->Tag()) 1806254721Semaste { 1807254721Semaste case DW_TAG_array_type: s.PutCString("[]"); break; 1808254721Semaste case DW_TAG_pointer_type: s.PutChar('*'); break; 1809254721Semaste case DW_TAG_ptr_to_member_type: s.PutChar('*'); break; 1810254721Semaste case DW_TAG_reference_type: s.PutChar('&'); break; 1811254721Semaste default: 1812254721Semaste break; 1813254721Semaste } 1814254721Semaste return result; 1815254721Semaste } 1816254721Semaste } 1817254721Semaste } 1818254721Semaste return false; 1819254721Semaste} 1820254721Semaste 1821254721Semastebool 1822254721SemasteDWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const 1823254721Semaste{ 1824254721Semaste if (die) 1825254721Semaste { 1826254721Semaste const dw_offset_t die_offset = die->GetOffset(); 1827254721Semaste if (die_offset > GetOffset()) 1828254721Semaste { 1829254721Semaste const DWARFDebugInfoEntry *sibling = GetSibling(); 1830254721Semaste assert (sibling); // TODO: take this out 1831254721Semaste if (sibling) 1832254721Semaste return die_offset < sibling->GetOffset(); 1833254721Semaste } 1834254721Semaste } 1835254721Semaste return false; 1836254721Semaste} 1837254721Semaste 1838254721Semaste//---------------------------------------------------------------------- 1839254721Semaste// BuildAddressRangeTable 1840254721Semaste//---------------------------------------------------------------------- 1841254721Semastevoid 1842254721SemasteDWARFDebugInfoEntry::BuildAddressRangeTable 1843254721Semaste( 1844254721Semaste SymbolFileDWARF* dwarf2Data, 1845254721Semaste const DWARFCompileUnit* cu, 1846254721Semaste DWARFDebugAranges* debug_aranges 1847254721Semaste) const 1848254721Semaste{ 1849254721Semaste if (m_tag) 1850254721Semaste { 1851254721Semaste if (m_tag == DW_TAG_subprogram) 1852254721Semaste { 1853254721Semaste dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 1854254721Semaste dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 1855254721Semaste if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) 1856254721Semaste { 1857254721Semaste /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); 1858254721Semaste debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc); 1859254721Semaste } 1860254721Semaste } 1861254721Semaste 1862254721Semaste 1863254721Semaste const DWARFDebugInfoEntry* child = GetFirstChild(); 1864254721Semaste while (child) 1865254721Semaste { 1866254721Semaste child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); 1867254721Semaste child = child->GetSibling(); 1868254721Semaste } 1869254721Semaste } 1870254721Semaste} 1871254721Semaste 1872254721Semaste//---------------------------------------------------------------------- 1873254721Semaste// BuildFunctionAddressRangeTable 1874254721Semaste// 1875254721Semaste// This function is very similar to the BuildAddressRangeTable function 1876254721Semaste// except that the actual DIE offset for the function is placed in the 1877254721Semaste// table instead of the compile unit offset (which is the way the 1878254721Semaste// standard .debug_aranges section does it). 1879254721Semaste//---------------------------------------------------------------------- 1880254721Semastevoid 1881254721SemasteDWARFDebugInfoEntry::BuildFunctionAddressRangeTable 1882254721Semaste( 1883254721Semaste SymbolFileDWARF* dwarf2Data, 1884254721Semaste const DWARFCompileUnit* cu, 1885254721Semaste DWARFDebugAranges* debug_aranges 1886254721Semaste) const 1887254721Semaste{ 1888254721Semaste if (m_tag) 1889254721Semaste { 1890254721Semaste if (m_tag == DW_TAG_subprogram) 1891254721Semaste { 1892254721Semaste dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 1893254721Semaste dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 1894254721Semaste if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) 1895254721Semaste { 1896254721Semaste // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY 1897254721Semaste debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc); 1898254721Semaste } 1899254721Semaste } 1900254721Semaste 1901254721Semaste const DWARFDebugInfoEntry* child = GetFirstChild(); 1902254721Semaste while (child) 1903254721Semaste { 1904254721Semaste child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); 1905254721Semaste child = child->GetSibling(); 1906254721Semaste } 1907254721Semaste } 1908254721Semaste} 1909254721Semaste 1910254721Semastevoid 1911254721SemasteDWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data, 1912254721Semaste DWARFCompileUnit* cu, 1913254721Semaste DWARFDIECollection &decl_context_dies) const 1914254721Semaste{ 1915254721Semaste const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); 1916254721Semaste if (parent_decl_ctx_die && parent_decl_ctx_die != this) 1917254721Semaste { 1918254721Semaste decl_context_dies.Append(parent_decl_ctx_die); 1919254721Semaste parent_decl_ctx_die->GetDeclContextDIEs (dwarf2Data, cu, decl_context_dies); 1920254721Semaste } 1921254721Semaste} 1922254721Semaste 1923254721Semastevoid 1924254721SemasteDWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, 1925254721Semaste DWARFCompileUnit* cu, 1926254721Semaste DWARFDeclContext &dwarf_decl_ctx) const 1927254721Semaste{ 1928254721Semaste const dw_tag_t tag = Tag(); 1929254721Semaste if (tag != DW_TAG_compile_unit) 1930254721Semaste { 1931254721Semaste dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); 1932254721Semaste const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); 1933254721Semaste if (parent_decl_ctx_die && parent_decl_ctx_die != this) 1934254721Semaste { 1935254721Semaste if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit) 1936254721Semaste parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx); 1937254721Semaste } 1938254721Semaste } 1939254721Semaste} 1940254721Semaste 1941254721Semaste 1942254721Semastebool 1943254721SemasteDWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data, 1944254721Semaste DWARFCompileUnit* cu, 1945254721Semaste const DWARFDeclContext &dwarf_decl_ctx) const 1946254721Semaste{ 1947254721Semaste 1948254721Semaste DWARFDeclContext this_dwarf_decl_ctx; 1949254721Semaste GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx); 1950254721Semaste return this_dwarf_decl_ctx == dwarf_decl_ctx; 1951254721Semaste} 1952254721Semaste 1953254721Semasteconst DWARFDebugInfoEntry * 1954254721SemasteDWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 1955254721Semaste DWARFCompileUnit* cu) const 1956254721Semaste{ 1957254721Semaste DWARFDebugInfoEntry::Attributes attributes; 1958254721Semaste GetAttributes(dwarf2Data, cu, NULL, attributes); 1959254721Semaste return GetParentDeclContextDIE (dwarf2Data, cu, attributes); 1960254721Semaste} 1961254721Semaste 1962254721Semasteconst DWARFDebugInfoEntry * 1963254721SemasteDWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 1964254721Semaste DWARFCompileUnit* cu, 1965254721Semaste const DWARFDebugInfoEntry::Attributes& attributes) const 1966254721Semaste{ 1967254721Semaste const DWARFDebugInfoEntry * die = this; 1968254721Semaste 1969254721Semaste while (die != NULL) 1970254721Semaste { 1971254721Semaste // If this is the original DIE that we are searching for a declaration 1972254721Semaste // for, then don't look in the cache as we don't want our own decl 1973254721Semaste // context to be our decl context... 1974254721Semaste if (die != this) 1975254721Semaste { 1976254721Semaste switch (die->Tag()) 1977254721Semaste { 1978254721Semaste case DW_TAG_compile_unit: 1979254721Semaste case DW_TAG_namespace: 1980254721Semaste case DW_TAG_structure_type: 1981254721Semaste case DW_TAG_union_type: 1982254721Semaste case DW_TAG_class_type: 1983254721Semaste return die; 1984254721Semaste 1985254721Semaste default: 1986254721Semaste break; 1987254721Semaste } 1988254721Semaste } 1989254721Semaste 1990254721Semaste dw_offset_t die_offset; 1991254721Semaste 1992254721Semaste die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_specification, DW_INVALID_OFFSET); 1993254721Semaste if (die_offset != DW_INVALID_OFFSET) 1994254721Semaste { 1995254721Semaste const DWARFDebugInfoEntry *spec_die = cu->GetDIEPtr (die_offset); 1996254721Semaste if (spec_die) 1997254721Semaste { 1998254721Semaste const DWARFDebugInfoEntry *spec_die_decl_ctx_die = spec_die->GetParentDeclContextDIE (dwarf2Data, cu); 1999254721Semaste if (spec_die_decl_ctx_die) 2000254721Semaste return spec_die_decl_ctx_die; 2001254721Semaste } 2002254721Semaste } 2003254721Semaste 2004254721Semaste die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_abstract_origin, DW_INVALID_OFFSET); 2005254721Semaste if (die_offset != DW_INVALID_OFFSET) 2006254721Semaste { 2007254721Semaste const DWARFDebugInfoEntry *abs_die = cu->GetDIEPtr (die_offset); 2008254721Semaste if (abs_die) 2009254721Semaste { 2010254721Semaste const DWARFDebugInfoEntry *abs_die_decl_ctx_die = abs_die->GetParentDeclContextDIE (dwarf2Data, cu); 2011254721Semaste if (abs_die_decl_ctx_die) 2012254721Semaste return abs_die_decl_ctx_die; 2013254721Semaste } 2014254721Semaste } 2015254721Semaste 2016254721Semaste die = die->GetParent(); 2017254721Semaste } 2018254721Semaste return NULL; 2019254721Semaste} 2020254721Semaste 2021254721Semaste 2022254721Semasteconst char * 2023254721SemasteDWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, 2024254721Semaste DWARFCompileUnit* cu, 2025254721Semaste std::string &storage) const 2026254721Semaste{ 2027254721Semaste DWARFDebugInfoEntry::Attributes attributes; 2028254721Semaste GetAttributes(dwarf2Data, cu, NULL, attributes); 2029254721Semaste return GetQualifiedName (dwarf2Data, cu, attributes, storage); 2030254721Semaste} 2031254721Semaste 2032254721Semasteconst char* 2033254721SemasteDWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data, 2034254721Semaste DWARFCompileUnit* cu, 2035254721Semaste const DWARFDebugInfoEntry::Attributes& attributes, 2036254721Semaste std::string &storage) const 2037254721Semaste{ 2038254721Semaste 2039254721Semaste const char *name = GetName (dwarf2Data, cu); 2040254721Semaste 2041254721Semaste if (name) 2042254721Semaste { 2043254721Semaste const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); 2044254721Semaste storage.clear(); 2045254721Semaste // TODO: change this to get the correct decl context parent.... 2046254721Semaste while (parent_decl_ctx_die) 2047254721Semaste { 2048254721Semaste const dw_tag_t parent_tag = parent_decl_ctx_die->Tag(); 2049254721Semaste switch (parent_tag) 2050254721Semaste { 2051254721Semaste case DW_TAG_namespace: 2052254721Semaste { 2053254721Semaste const char *namespace_name = parent_decl_ctx_die->GetName (dwarf2Data, cu); 2054254721Semaste if (namespace_name) 2055254721Semaste { 2056254721Semaste storage.insert (0, "::"); 2057254721Semaste storage.insert (0, namespace_name); 2058254721Semaste } 2059254721Semaste else 2060254721Semaste { 2061254721Semaste storage.insert (0, "(anonymous namespace)::"); 2062254721Semaste } 2063254721Semaste parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu); 2064254721Semaste } 2065254721Semaste break; 2066254721Semaste 2067254721Semaste case DW_TAG_class_type: 2068254721Semaste case DW_TAG_structure_type: 2069254721Semaste case DW_TAG_union_type: 2070254721Semaste { 2071254721Semaste const char *class_union_struct_name = parent_decl_ctx_die->GetName (dwarf2Data, cu); 2072254721Semaste 2073254721Semaste if (class_union_struct_name) 2074254721Semaste { 2075254721Semaste storage.insert (0, "::"); 2076254721Semaste storage.insert (0, class_union_struct_name); 2077254721Semaste } 2078254721Semaste parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu); 2079254721Semaste } 2080254721Semaste break; 2081254721Semaste 2082254721Semaste default: 2083254721Semaste parent_decl_ctx_die = NULL; 2084254721Semaste break; 2085254721Semaste } 2086254721Semaste } 2087254721Semaste 2088254721Semaste if (storage.empty()) 2089254721Semaste storage.append ("::"); 2090254721Semaste 2091254721Semaste storage.append (name); 2092254721Semaste } 2093254721Semaste if (storage.empty()) 2094254721Semaste return NULL; 2095254721Semaste return storage.c_str(); 2096254721Semaste} 2097254721Semaste 2098254721Semaste 2099254721Semaste//---------------------------------------------------------------------- 2100254721Semaste// LookupAddress 2101254721Semaste//---------------------------------------------------------------------- 2102254721Semastebool 2103254721SemasteDWARFDebugInfoEntry::LookupAddress 2104254721Semaste( 2105254721Semaste const dw_addr_t address, 2106254721Semaste SymbolFileDWARF* dwarf2Data, 2107254721Semaste const DWARFCompileUnit* cu, 2108254721Semaste DWARFDebugInfoEntry** function_die, 2109254721Semaste DWARFDebugInfoEntry** block_die 2110254721Semaste) 2111254721Semaste{ 2112254721Semaste bool found_address = false; 2113254721Semaste if (m_tag) 2114254721Semaste { 2115254721Semaste bool check_children = false; 2116254721Semaste bool match_addr_range = false; 2117254721Semaste // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address); 2118254721Semaste switch (m_tag) 2119254721Semaste { 2120254721Semaste case DW_TAG_array_type : break; 2121254721Semaste case DW_TAG_class_type : check_children = true; break; 2122254721Semaste case DW_TAG_entry_point : break; 2123254721Semaste case DW_TAG_enumeration_type : break; 2124254721Semaste case DW_TAG_formal_parameter : break; 2125254721Semaste case DW_TAG_imported_declaration : break; 2126254721Semaste case DW_TAG_label : break; 2127254721Semaste case DW_TAG_lexical_block : check_children = true; match_addr_range = true; break; 2128254721Semaste case DW_TAG_member : break; 2129254721Semaste case DW_TAG_pointer_type : break; 2130254721Semaste case DW_TAG_reference_type : break; 2131254721Semaste case DW_TAG_compile_unit : match_addr_range = true; break; 2132254721Semaste case DW_TAG_string_type : break; 2133254721Semaste case DW_TAG_structure_type : check_children = true; break; 2134254721Semaste case DW_TAG_subroutine_type : break; 2135254721Semaste case DW_TAG_typedef : break; 2136254721Semaste case DW_TAG_union_type : break; 2137254721Semaste case DW_TAG_unspecified_parameters : break; 2138254721Semaste case DW_TAG_variant : break; 2139254721Semaste case DW_TAG_common_block : check_children = true; break; 2140254721Semaste case DW_TAG_common_inclusion : break; 2141254721Semaste case DW_TAG_inheritance : break; 2142254721Semaste case DW_TAG_inlined_subroutine : check_children = true; match_addr_range = true; break; 2143254721Semaste case DW_TAG_module : match_addr_range = true; break; 2144254721Semaste case DW_TAG_ptr_to_member_type : break; 2145254721Semaste case DW_TAG_set_type : break; 2146254721Semaste case DW_TAG_subrange_type : break; 2147254721Semaste case DW_TAG_with_stmt : break; 2148254721Semaste case DW_TAG_access_declaration : break; 2149254721Semaste case DW_TAG_base_type : break; 2150254721Semaste case DW_TAG_catch_block : match_addr_range = true; break; 2151254721Semaste case DW_TAG_const_type : break; 2152254721Semaste case DW_TAG_constant : break; 2153254721Semaste case DW_TAG_enumerator : break; 2154254721Semaste case DW_TAG_file_type : break; 2155254721Semaste case DW_TAG_friend : break; 2156254721Semaste case DW_TAG_namelist : break; 2157254721Semaste case DW_TAG_namelist_item : break; 2158254721Semaste case DW_TAG_packed_type : break; 2159254721Semaste case DW_TAG_subprogram : match_addr_range = true; break; 2160254721Semaste case DW_TAG_template_type_parameter : break; 2161254721Semaste case DW_TAG_template_value_parameter : break; 2162254721Semaste case DW_TAG_thrown_type : break; 2163254721Semaste case DW_TAG_try_block : match_addr_range = true; break; 2164254721Semaste case DW_TAG_variant_part : break; 2165254721Semaste case DW_TAG_variable : break; 2166254721Semaste case DW_TAG_volatile_type : break; 2167254721Semaste case DW_TAG_dwarf_procedure : break; 2168254721Semaste case DW_TAG_restrict_type : break; 2169254721Semaste case DW_TAG_interface_type : break; 2170254721Semaste case DW_TAG_namespace : check_children = true; break; 2171254721Semaste case DW_TAG_imported_module : break; 2172254721Semaste case DW_TAG_unspecified_type : break; 2173254721Semaste case DW_TAG_partial_unit : break; 2174254721Semaste case DW_TAG_imported_unit : break; 2175254721Semaste case DW_TAG_shared_type : break; 2176254721Semaste default: break; 2177254721Semaste } 2178254721Semaste 2179254721Semaste if (match_addr_range) 2180254721Semaste { 2181254721Semaste dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 2182254721Semaste if (lo_pc != LLDB_INVALID_ADDRESS) 2183254721Semaste { 2184254721Semaste dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS); 2185254721Semaste if (hi_pc != LLDB_INVALID_ADDRESS) 2186254721Semaste { 2187254721Semaste // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); 2188254721Semaste if ((lo_pc <= address) && (address < hi_pc)) 2189254721Semaste { 2190254721Semaste found_address = true; 2191254721Semaste // puts("***MATCH***"); 2192254721Semaste switch (m_tag) 2193254721Semaste { 2194254721Semaste case DW_TAG_compile_unit: // File 2195254721Semaste check_children = ((function_die != NULL) || (block_die != NULL)); 2196254721Semaste break; 2197254721Semaste 2198254721Semaste case DW_TAG_subprogram: // Function 2199254721Semaste if (function_die) 2200254721Semaste *function_die = this; 2201254721Semaste check_children = (block_die != NULL); 2202254721Semaste break; 2203254721Semaste 2204254721Semaste case DW_TAG_inlined_subroutine: // Inlined Function 2205254721Semaste case DW_TAG_lexical_block: // Block { } in code 2206254721Semaste if (block_die) 2207254721Semaste { 2208254721Semaste *block_die = this; 2209254721Semaste check_children = true; 2210254721Semaste } 2211254721Semaste break; 2212254721Semaste 2213254721Semaste default: 2214254721Semaste check_children = true; 2215254721Semaste break; 2216254721Semaste } 2217254721Semaste } 2218254721Semaste } 2219254721Semaste else 2220254721Semaste { // compile units may not have a valid high/low pc when there 2221254721Semaste // are address gaps in subroutines so we must always search 2222254721Semaste // if there is no valid high and low PC 2223254721Semaste check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL)); 2224254721Semaste } 2225254721Semaste } 2226254721Semaste else 2227254721Semaste { 2228254721Semaste dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); 2229254721Semaste if (debug_ranges_offset != DW_INVALID_OFFSET) 2230254721Semaste { 2231254721Semaste DWARFDebugRanges::RangeList ranges; 2232254721Semaste DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); 2233254721Semaste debug_ranges->FindRanges(debug_ranges_offset, ranges); 2234254721Semaste // All DW_AT_ranges are relative to the base address of the 2235254721Semaste // compile unit. We add the compile unit base address to make 2236254721Semaste // sure all the addresses are properly fixed up. 2237254721Semaste ranges.Slide (cu->GetBaseAddress()); 2238254721Semaste if (ranges.FindEntryThatContains(address)) 2239254721Semaste { 2240254721Semaste found_address = true; 2241254721Semaste // puts("***MATCH***"); 2242254721Semaste switch (m_tag) 2243254721Semaste { 2244254721Semaste case DW_TAG_compile_unit: // File 2245254721Semaste check_children = ((function_die != NULL) || (block_die != NULL)); 2246254721Semaste break; 2247254721Semaste 2248254721Semaste case DW_TAG_subprogram: // Function 2249254721Semaste if (function_die) 2250254721Semaste *function_die = this; 2251254721Semaste check_children = (block_die != NULL); 2252254721Semaste break; 2253254721Semaste 2254254721Semaste case DW_TAG_inlined_subroutine: // Inlined Function 2255254721Semaste case DW_TAG_lexical_block: // Block { } in code 2256254721Semaste if (block_die) 2257254721Semaste { 2258254721Semaste *block_die = this; 2259254721Semaste check_children = true; 2260254721Semaste } 2261254721Semaste break; 2262254721Semaste 2263254721Semaste default: 2264254721Semaste check_children = true; 2265254721Semaste break; 2266254721Semaste } 2267254721Semaste } 2268254721Semaste else 2269254721Semaste { 2270254721Semaste check_children = false; 2271254721Semaste } 2272254721Semaste } 2273254721Semaste } 2274254721Semaste } 2275254721Semaste 2276254721Semaste 2277254721Semaste if (check_children) 2278254721Semaste { 2279254721Semaste // printf("checking children\n"); 2280254721Semaste DWARFDebugInfoEntry* child = GetFirstChild(); 2281254721Semaste while (child) 2282254721Semaste { 2283254721Semaste if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die)) 2284254721Semaste return true; 2285254721Semaste child = child->GetSibling(); 2286254721Semaste } 2287254721Semaste } 2288254721Semaste } 2289254721Semaste return found_address; 2290254721Semaste} 2291254721Semaste 2292254721Semasteconst DWARFAbbreviationDeclaration* 2293254721SemasteDWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, 2294254721Semaste const DWARFCompileUnit *cu, 2295254721Semaste lldb::offset_t &offset) const 2296254721Semaste{ 2297254721Semaste if (dwarf2Data) 2298254721Semaste { 2299254721Semaste offset = GetOffset(); 2300254721Semaste 2301254721Semaste const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx); 2302254721Semaste if (abbrev_decl) 2303254721Semaste { 2304254721Semaste // Make sure the abbreviation code still matches. If it doesn't and 2305254721Semaste // the DWARF data was mmap'ed, the backing file might have been modified 2306254721Semaste // which is bad news. 2307254721Semaste const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset); 2308254721Semaste 2309254721Semaste if (abbrev_decl->Code() == abbrev_code) 2310254721Semaste return abbrev_decl; 2311254721Semaste 2312254721Semaste dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)", 2313254721Semaste GetOffset(), 2314254721Semaste (uint32_t)abbrev_decl->Code(), 2315254721Semaste (uint32_t)abbrev_code); 2316254721Semaste } 2317254721Semaste } 2318254721Semaste offset = DW_INVALID_OFFSET; 2319254721Semaste return NULL; 2320254721Semaste} 2321254721Semaste 2322254721Semaste 2323254721Semastebool 2324254721SemasteDWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b) 2325254721Semaste{ 2326254721Semaste return a.GetOffset() < b.GetOffset(); 2327254721Semaste} 2328254721Semaste 2329254721Semastevoid 2330254721SemasteDWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection) 2331254721Semaste{ 2332254721Semaste DWARFDebugInfoEntry::const_iterator pos; 2333254721Semaste DWARFDebugInfoEntry::const_iterator end = die_collection.end(); 2334254721Semaste strm.PutCString("\noffset parent sibling child\n"); 2335254721Semaste strm.PutCString("-------- -------- -------- --------\n"); 2336254721Semaste for (pos = die_collection.begin(); pos != end; ++pos) 2337254721Semaste { 2338254721Semaste const DWARFDebugInfoEntry& die_ref = *pos; 2339254721Semaste const DWARFDebugInfoEntry* p = die_ref.GetParent(); 2340254721Semaste const DWARFDebugInfoEntry* s = die_ref.GetSibling(); 2341254721Semaste const DWARFDebugInfoEntry* c = die_ref.GetFirstChild(); 2342254721Semaste strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", 2343254721Semaste die_ref.GetOffset(), 2344254721Semaste p ? p->GetOffset() : 0, 2345254721Semaste s ? s->GetOffset() : 0, 2346254721Semaste c ? c->GetOffset() : 0, 2347254721Semaste die_ref.Tag(), 2348254721Semaste DW_TAG_value_to_name(die_ref.Tag()), 2349254721Semaste die_ref.HasChildren() ? " *" : ""); 2350254721Semaste } 2351254721Semaste} 2352254721Semaste 2353254721Semaste 2354