1*061da546Spatrick //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// 2*061da546Spatrick // 3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*061da546Spatrick // 7*061da546Spatrick //===----------------------------------------------------------------------===// 8*061da546Spatrick 9*061da546Spatrick #include "DWARFDebugInfoEntry.h" 10*061da546Spatrick 11*061da546Spatrick #include <assert.h> 12*061da546Spatrick 13*061da546Spatrick #include <algorithm> 14*061da546Spatrick 15*061da546Spatrick #include "llvm/Support/LEB128.h" 16*061da546Spatrick 17*061da546Spatrick #include "lldb/Core/Module.h" 18*061da546Spatrick #include "lldb/Expression/DWARFExpression.h" 19*061da546Spatrick #include "lldb/Symbol/ObjectFile.h" 20*061da546Spatrick #include "lldb/Utility/Stream.h" 21*061da546Spatrick 22*061da546Spatrick #include "DWARFCompileUnit.h" 23*061da546Spatrick #include "DWARFDebugAbbrev.h" 24*061da546Spatrick #include "DWARFDebugAranges.h" 25*061da546Spatrick #include "DWARFDebugInfo.h" 26*061da546Spatrick #include "DWARFDebugRanges.h" 27*061da546Spatrick #include "DWARFDeclContext.h" 28*061da546Spatrick #include "DWARFFormValue.h" 29*061da546Spatrick #include "DWARFUnit.h" 30*061da546Spatrick #include "SymbolFileDWARF.h" 31*061da546Spatrick #include "SymbolFileDWARFDwo.h" 32*061da546Spatrick 33*061da546Spatrick using namespace lldb_private; 34*061da546Spatrick using namespace std; 35*061da546Spatrick extern int g_verbose; 36*061da546Spatrick 37*061da546Spatrick // Extract a debug info entry for a given DWARFUnit from the data 38*061da546Spatrick // starting at the offset in offset_ptr 39*061da546Spatrick bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data, 40*061da546Spatrick const DWARFUnit *cu, 41*061da546Spatrick lldb::offset_t *offset_ptr) { 42*061da546Spatrick m_offset = *offset_ptr; 43*061da546Spatrick m_parent_idx = 0; 44*061da546Spatrick m_sibling_idx = 0; 45*061da546Spatrick const uint64_t abbr_idx = data.GetULEB128(offset_ptr); 46*061da546Spatrick lldbassert(abbr_idx <= UINT16_MAX); 47*061da546Spatrick m_abbr_idx = abbr_idx; 48*061da546Spatrick 49*061da546Spatrick // assert (fixed_form_sizes); // For best performance this should be 50*061da546Spatrick // specified! 51*061da546Spatrick 52*061da546Spatrick if (m_abbr_idx) { 53*061da546Spatrick lldb::offset_t offset = *offset_ptr; 54*061da546Spatrick const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); 55*061da546Spatrick if (abbrevDecl == nullptr) { 56*061da546Spatrick cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 57*061da546Spatrick "{0x%8.8x}: invalid abbreviation code %u, please file a bug and " 58*061da546Spatrick "attach the file at the start of this error message", 59*061da546Spatrick m_offset, (unsigned)abbr_idx); 60*061da546Spatrick // WE can't parse anymore if the DWARF is borked... 61*061da546Spatrick *offset_ptr = UINT32_MAX; 62*061da546Spatrick return false; 63*061da546Spatrick } 64*061da546Spatrick m_tag = abbrevDecl->Tag(); 65*061da546Spatrick m_has_children = abbrevDecl->HasChildren(); 66*061da546Spatrick // Skip all data in the .debug_info or .debug_types for the attributes 67*061da546Spatrick const uint32_t numAttributes = abbrevDecl->NumAttributes(); 68*061da546Spatrick uint32_t i; 69*061da546Spatrick dw_form_t form; 70*061da546Spatrick for (i = 0; i < numAttributes; ++i) { 71*061da546Spatrick form = abbrevDecl->GetFormByIndexUnchecked(i); 72*061da546Spatrick llvm::Optional<uint8_t> fixed_skip_size = 73*061da546Spatrick DWARFFormValue::GetFixedSize(form, cu); 74*061da546Spatrick if (fixed_skip_size) 75*061da546Spatrick offset += *fixed_skip_size; 76*061da546Spatrick else { 77*061da546Spatrick bool form_is_indirect = false; 78*061da546Spatrick do { 79*061da546Spatrick form_is_indirect = false; 80*061da546Spatrick uint32_t form_size = 0; 81*061da546Spatrick switch (form) { 82*061da546Spatrick // Blocks if inlined data that have a length field and the data bytes 83*061da546Spatrick // inlined in the .debug_info/.debug_types 84*061da546Spatrick case DW_FORM_exprloc: 85*061da546Spatrick case DW_FORM_block: 86*061da546Spatrick form_size = data.GetULEB128(&offset); 87*061da546Spatrick break; 88*061da546Spatrick case DW_FORM_block1: 89*061da546Spatrick form_size = data.GetU8_unchecked(&offset); 90*061da546Spatrick break; 91*061da546Spatrick case DW_FORM_block2: 92*061da546Spatrick form_size = data.GetU16_unchecked(&offset); 93*061da546Spatrick break; 94*061da546Spatrick case DW_FORM_block4: 95*061da546Spatrick form_size = data.GetU32_unchecked(&offset); 96*061da546Spatrick break; 97*061da546Spatrick 98*061da546Spatrick // Inlined NULL terminated C-strings 99*061da546Spatrick case DW_FORM_string: 100*061da546Spatrick data.GetCStr(&offset); 101*061da546Spatrick break; 102*061da546Spatrick 103*061da546Spatrick // Compile unit address sized values 104*061da546Spatrick case DW_FORM_addr: 105*061da546Spatrick form_size = cu->GetAddressByteSize(); 106*061da546Spatrick break; 107*061da546Spatrick case DW_FORM_ref_addr: 108*061da546Spatrick if (cu->GetVersion() <= 2) 109*061da546Spatrick form_size = cu->GetAddressByteSize(); 110*061da546Spatrick else 111*061da546Spatrick form_size = 4; 112*061da546Spatrick break; 113*061da546Spatrick 114*061da546Spatrick // 0 sized form 115*061da546Spatrick case DW_FORM_flag_present: 116*061da546Spatrick form_size = 0; 117*061da546Spatrick break; 118*061da546Spatrick 119*061da546Spatrick // 1 byte values 120*061da546Spatrick case DW_FORM_addrx1: 121*061da546Spatrick case DW_FORM_data1: 122*061da546Spatrick case DW_FORM_flag: 123*061da546Spatrick case DW_FORM_ref1: 124*061da546Spatrick case DW_FORM_strx1: 125*061da546Spatrick form_size = 1; 126*061da546Spatrick break; 127*061da546Spatrick 128*061da546Spatrick // 2 byte values 129*061da546Spatrick case DW_FORM_addrx2: 130*061da546Spatrick case DW_FORM_data2: 131*061da546Spatrick case DW_FORM_ref2: 132*061da546Spatrick case DW_FORM_strx2: 133*061da546Spatrick form_size = 2; 134*061da546Spatrick break; 135*061da546Spatrick 136*061da546Spatrick // 3 byte values 137*061da546Spatrick case DW_FORM_addrx3: 138*061da546Spatrick case DW_FORM_strx3: 139*061da546Spatrick form_size = 3; 140*061da546Spatrick break; 141*061da546Spatrick 142*061da546Spatrick // 4 byte values 143*061da546Spatrick case DW_FORM_addrx4: 144*061da546Spatrick case DW_FORM_data4: 145*061da546Spatrick case DW_FORM_ref4: 146*061da546Spatrick case DW_FORM_strx4: 147*061da546Spatrick form_size = 4; 148*061da546Spatrick break; 149*061da546Spatrick 150*061da546Spatrick // 8 byte values 151*061da546Spatrick case DW_FORM_data8: 152*061da546Spatrick case DW_FORM_ref8: 153*061da546Spatrick case DW_FORM_ref_sig8: 154*061da546Spatrick form_size = 8; 155*061da546Spatrick break; 156*061da546Spatrick 157*061da546Spatrick // signed or unsigned LEB 128 values 158*061da546Spatrick case DW_FORM_addrx: 159*061da546Spatrick case DW_FORM_loclistx: 160*061da546Spatrick case DW_FORM_rnglistx: 161*061da546Spatrick case DW_FORM_sdata: 162*061da546Spatrick case DW_FORM_udata: 163*061da546Spatrick case DW_FORM_ref_udata: 164*061da546Spatrick case DW_FORM_GNU_addr_index: 165*061da546Spatrick case DW_FORM_GNU_str_index: 166*061da546Spatrick case DW_FORM_strx: 167*061da546Spatrick data.Skip_LEB128(&offset); 168*061da546Spatrick break; 169*061da546Spatrick 170*061da546Spatrick case DW_FORM_indirect: 171*061da546Spatrick form_is_indirect = true; 172*061da546Spatrick form = data.GetULEB128(&offset); 173*061da546Spatrick break; 174*061da546Spatrick 175*061da546Spatrick case DW_FORM_strp: 176*061da546Spatrick case DW_FORM_sec_offset: 177*061da546Spatrick data.GetU32(&offset); 178*061da546Spatrick break; 179*061da546Spatrick 180*061da546Spatrick case DW_FORM_implicit_const: 181*061da546Spatrick form_size = 0; 182*061da546Spatrick break; 183*061da546Spatrick 184*061da546Spatrick default: 185*061da546Spatrick *offset_ptr = m_offset; 186*061da546Spatrick return false; 187*061da546Spatrick } 188*061da546Spatrick offset += form_size; 189*061da546Spatrick 190*061da546Spatrick } while (form_is_indirect); 191*061da546Spatrick } 192*061da546Spatrick } 193*061da546Spatrick *offset_ptr = offset; 194*061da546Spatrick return true; 195*061da546Spatrick } else { 196*061da546Spatrick m_tag = llvm::dwarf::DW_TAG_null; 197*061da546Spatrick m_has_children = false; 198*061da546Spatrick return true; // NULL debug tag entry 199*061da546Spatrick } 200*061da546Spatrick 201*061da546Spatrick return false; 202*061da546Spatrick } 203*061da546Spatrick 204*061da546Spatrick static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, 205*061da546Spatrick const DWARFDebugInfoEntry &die, 206*061da546Spatrick const DWARFFormValue &value) { 207*061da546Spatrick llvm::Expected<DWARFRangeList> expected_ranges = 208*061da546Spatrick (value.Form() == DW_FORM_rnglistx) 209*061da546Spatrick ? unit.FindRnglistFromIndex(value.Unsigned()) 210*061da546Spatrick : unit.FindRnglistFromOffset(value.Unsigned()); 211*061da546Spatrick if (expected_ranges) 212*061da546Spatrick return std::move(*expected_ranges); 213*061da546Spatrick unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 214*061da546Spatrick "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but " 215*061da546Spatrick "range extraction failed (%s), please file a bug " 216*061da546Spatrick "and attach the file at the start of this error message", 217*061da546Spatrick die.GetOffset(), value.Unsigned(), 218*061da546Spatrick toString(expected_ranges.takeError()).c_str()); 219*061da546Spatrick return DWARFRangeList(); 220*061da546Spatrick } 221*061da546Spatrick 222*061da546Spatrick // GetDIENamesAndRanges 223*061da546Spatrick // 224*061da546Spatrick // Gets the valid address ranges for a given DIE by looking for a 225*061da546Spatrick // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. 226*061da546Spatrick bool DWARFDebugInfoEntry::GetDIENamesAndRanges( 227*061da546Spatrick DWARFUnit *cu, const char *&name, const char *&mangled, 228*061da546Spatrick DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column, 229*061da546Spatrick int &call_file, int &call_line, int &call_column, 230*061da546Spatrick DWARFExpression *frame_base) const { 231*061da546Spatrick dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 232*061da546Spatrick dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 233*061da546Spatrick std::vector<DWARFDIE> dies; 234*061da546Spatrick bool set_frame_base_loclist_addr = false; 235*061da546Spatrick 236*061da546Spatrick const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); 237*061da546Spatrick 238*061da546Spatrick SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF(); 239*061da546Spatrick lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule(); 240*061da546Spatrick 241*061da546Spatrick if (abbrevDecl) { 242*061da546Spatrick const DWARFDataExtractor &data = cu->GetData(); 243*061da546Spatrick lldb::offset_t offset = GetFirstAttributeOffset(); 244*061da546Spatrick 245*061da546Spatrick if (!data.ValidOffset(offset)) 246*061da546Spatrick return false; 247*061da546Spatrick 248*061da546Spatrick const uint32_t numAttributes = abbrevDecl->NumAttributes(); 249*061da546Spatrick bool do_offset = false; 250*061da546Spatrick 251*061da546Spatrick for (uint32_t i = 0; i < numAttributes; ++i) { 252*061da546Spatrick DWARFFormValue form_value(cu); 253*061da546Spatrick dw_attr_t attr; 254*061da546Spatrick abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 255*061da546Spatrick 256*061da546Spatrick if (form_value.ExtractValue(data, &offset)) { 257*061da546Spatrick switch (attr) { 258*061da546Spatrick case DW_AT_low_pc: 259*061da546Spatrick lo_pc = form_value.Address(); 260*061da546Spatrick 261*061da546Spatrick if (do_offset) 262*061da546Spatrick hi_pc += lo_pc; 263*061da546Spatrick do_offset = false; 264*061da546Spatrick break; 265*061da546Spatrick 266*061da546Spatrick case DW_AT_entry_pc: 267*061da546Spatrick lo_pc = form_value.Address(); 268*061da546Spatrick break; 269*061da546Spatrick 270*061da546Spatrick case DW_AT_high_pc: 271*061da546Spatrick if (form_value.Form() == DW_FORM_addr || 272*061da546Spatrick form_value.Form() == DW_FORM_addrx || 273*061da546Spatrick form_value.Form() == DW_FORM_GNU_addr_index) { 274*061da546Spatrick hi_pc = form_value.Address(); 275*061da546Spatrick } else { 276*061da546Spatrick hi_pc = form_value.Unsigned(); 277*061da546Spatrick if (lo_pc == LLDB_INVALID_ADDRESS) 278*061da546Spatrick do_offset = hi_pc != LLDB_INVALID_ADDRESS; 279*061da546Spatrick else 280*061da546Spatrick hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save 281*061da546Spatrick // on relocations 282*061da546Spatrick } 283*061da546Spatrick break; 284*061da546Spatrick 285*061da546Spatrick case DW_AT_ranges: 286*061da546Spatrick ranges = GetRangesOrReportError(*cu, *this, form_value); 287*061da546Spatrick break; 288*061da546Spatrick 289*061da546Spatrick case DW_AT_name: 290*061da546Spatrick if (name == nullptr) 291*061da546Spatrick name = form_value.AsCString(); 292*061da546Spatrick break; 293*061da546Spatrick 294*061da546Spatrick case DW_AT_MIPS_linkage_name: 295*061da546Spatrick case DW_AT_linkage_name: 296*061da546Spatrick if (mangled == nullptr) 297*061da546Spatrick mangled = form_value.AsCString(); 298*061da546Spatrick break; 299*061da546Spatrick 300*061da546Spatrick case DW_AT_abstract_origin: 301*061da546Spatrick dies.push_back(form_value.Reference()); 302*061da546Spatrick break; 303*061da546Spatrick 304*061da546Spatrick case DW_AT_specification: 305*061da546Spatrick dies.push_back(form_value.Reference()); 306*061da546Spatrick break; 307*061da546Spatrick 308*061da546Spatrick case DW_AT_decl_file: 309*061da546Spatrick if (decl_file == 0) 310*061da546Spatrick decl_file = form_value.Unsigned(); 311*061da546Spatrick break; 312*061da546Spatrick 313*061da546Spatrick case DW_AT_decl_line: 314*061da546Spatrick if (decl_line == 0) 315*061da546Spatrick decl_line = form_value.Unsigned(); 316*061da546Spatrick break; 317*061da546Spatrick 318*061da546Spatrick case DW_AT_decl_column: 319*061da546Spatrick if (decl_column == 0) 320*061da546Spatrick decl_column = form_value.Unsigned(); 321*061da546Spatrick break; 322*061da546Spatrick 323*061da546Spatrick case DW_AT_call_file: 324*061da546Spatrick if (call_file == 0) 325*061da546Spatrick call_file = form_value.Unsigned(); 326*061da546Spatrick break; 327*061da546Spatrick 328*061da546Spatrick case DW_AT_call_line: 329*061da546Spatrick if (call_line == 0) 330*061da546Spatrick call_line = form_value.Unsigned(); 331*061da546Spatrick break; 332*061da546Spatrick 333*061da546Spatrick case DW_AT_call_column: 334*061da546Spatrick if (call_column == 0) 335*061da546Spatrick call_column = form_value.Unsigned(); 336*061da546Spatrick break; 337*061da546Spatrick 338*061da546Spatrick case DW_AT_frame_base: 339*061da546Spatrick if (frame_base) { 340*061da546Spatrick if (form_value.BlockData()) { 341*061da546Spatrick uint32_t block_offset = 342*061da546Spatrick form_value.BlockData() - data.GetDataStart(); 343*061da546Spatrick uint32_t block_length = form_value.Unsigned(); 344*061da546Spatrick *frame_base = DWARFExpression( 345*061da546Spatrick module, DataExtractor(data, block_offset, block_length), cu); 346*061da546Spatrick } else { 347*061da546Spatrick DataExtractor data = cu->GetLocationData(); 348*061da546Spatrick const dw_offset_t offset = form_value.Unsigned(); 349*061da546Spatrick if (data.ValidOffset(offset)) { 350*061da546Spatrick data = DataExtractor(data, offset, data.GetByteSize() - offset); 351*061da546Spatrick *frame_base = DWARFExpression(module, data, cu); 352*061da546Spatrick if (lo_pc != LLDB_INVALID_ADDRESS) { 353*061da546Spatrick assert(lo_pc >= cu->GetBaseAddress()); 354*061da546Spatrick frame_base->SetLocationListAddresses(cu->GetBaseAddress(), 355*061da546Spatrick lo_pc); 356*061da546Spatrick } else { 357*061da546Spatrick set_frame_base_loclist_addr = true; 358*061da546Spatrick } 359*061da546Spatrick } 360*061da546Spatrick } 361*061da546Spatrick } 362*061da546Spatrick break; 363*061da546Spatrick 364*061da546Spatrick default: 365*061da546Spatrick break; 366*061da546Spatrick } 367*061da546Spatrick } 368*061da546Spatrick } 369*061da546Spatrick } 370*061da546Spatrick 371*061da546Spatrick if (ranges.IsEmpty()) { 372*061da546Spatrick if (lo_pc != LLDB_INVALID_ADDRESS) { 373*061da546Spatrick if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) 374*061da546Spatrick ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); 375*061da546Spatrick else 376*061da546Spatrick ranges.Append(DWARFRangeList::Entry(lo_pc, 0)); 377*061da546Spatrick } 378*061da546Spatrick } 379*061da546Spatrick 380*061da546Spatrick if (set_frame_base_loclist_addr) { 381*061da546Spatrick dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); 382*061da546Spatrick assert(lowest_range_pc >= cu->GetBaseAddress()); 383*061da546Spatrick frame_base->SetLocationListAddresses(cu->GetBaseAddress(), lowest_range_pc); 384*061da546Spatrick } 385*061da546Spatrick 386*061da546Spatrick if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) { 387*061da546Spatrick for (const DWARFDIE &die : dies) { 388*061da546Spatrick if (die) { 389*061da546Spatrick die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges, 390*061da546Spatrick decl_file, decl_line, decl_column, 391*061da546Spatrick call_file, call_line, call_column); 392*061da546Spatrick } 393*061da546Spatrick } 394*061da546Spatrick } 395*061da546Spatrick return !ranges.IsEmpty(); 396*061da546Spatrick } 397*061da546Spatrick 398*061da546Spatrick // Dump 399*061da546Spatrick // 400*061da546Spatrick // Dumps a debug information entry and all of it's attributes to the specified 401*061da546Spatrick // stream. 402*061da546Spatrick void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, 403*061da546Spatrick uint32_t recurse_depth) const { 404*061da546Spatrick const DWARFDataExtractor &data = cu->GetData(); 405*061da546Spatrick lldb::offset_t offset = m_offset; 406*061da546Spatrick 407*061da546Spatrick if (data.ValidOffset(offset)) { 408*061da546Spatrick dw_uleb128_t abbrCode = data.GetULEB128(&offset); 409*061da546Spatrick 410*061da546Spatrick s.Printf("\n0x%8.8x: ", m_offset); 411*061da546Spatrick s.Indent(); 412*061da546Spatrick if (abbrCode != m_abbr_idx) { 413*061da546Spatrick s.Printf("error: DWARF has been modified\n"); 414*061da546Spatrick } else if (abbrCode) { 415*061da546Spatrick const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); 416*061da546Spatrick if (abbrevDecl) { 417*061da546Spatrick s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); 418*061da546Spatrick s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); 419*061da546Spatrick 420*061da546Spatrick // Dump all data in the .debug_info/.debug_types for the attributes 421*061da546Spatrick const uint32_t numAttributes = abbrevDecl->NumAttributes(); 422*061da546Spatrick for (uint32_t i = 0; i < numAttributes; ++i) { 423*061da546Spatrick DWARFFormValue form_value(cu); 424*061da546Spatrick dw_attr_t attr; 425*061da546Spatrick abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 426*061da546Spatrick 427*061da546Spatrick DumpAttribute(cu, data, &offset, s, attr, form_value); 428*061da546Spatrick } 429*061da546Spatrick 430*061da546Spatrick const DWARFDebugInfoEntry *child = GetFirstChild(); 431*061da546Spatrick if (recurse_depth > 0 && child) { 432*061da546Spatrick s.IndentMore(); 433*061da546Spatrick 434*061da546Spatrick while (child) { 435*061da546Spatrick child->Dump(cu, s, recurse_depth - 1); 436*061da546Spatrick child = child->GetSibling(); 437*061da546Spatrick } 438*061da546Spatrick s.IndentLess(); 439*061da546Spatrick } 440*061da546Spatrick } else 441*061da546Spatrick s.Printf("Abbreviation code note found in 'debug_abbrev' class for " 442*061da546Spatrick "code: %u\n", 443*061da546Spatrick abbrCode); 444*061da546Spatrick } else { 445*061da546Spatrick s.Printf("NULL\n"); 446*061da546Spatrick } 447*061da546Spatrick } 448*061da546Spatrick } 449*061da546Spatrick 450*061da546Spatrick // DumpAttribute 451*061da546Spatrick // 452*061da546Spatrick // Dumps a debug information entry attribute along with it's form. Any special 453*061da546Spatrick // display of attributes is done (disassemble location lists, show enumeration 454*061da546Spatrick // values for attributes, etc). 455*061da546Spatrick void DWARFDebugInfoEntry::DumpAttribute( 456*061da546Spatrick const DWARFUnit *cu, const DWARFDataExtractor &data, 457*061da546Spatrick lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr, 458*061da546Spatrick DWARFFormValue &form_value) { 459*061da546Spatrick bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); 460*061da546Spatrick 461*061da546Spatrick s.Printf(" "); 462*061da546Spatrick s.Indent(DW_AT_value_to_name(attr)); 463*061da546Spatrick 464*061da546Spatrick if (show_form) { 465*061da546Spatrick s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); 466*061da546Spatrick } 467*061da546Spatrick 468*061da546Spatrick if (!form_value.ExtractValue(data, offset_ptr)) 469*061da546Spatrick return; 470*061da546Spatrick 471*061da546Spatrick if (show_form) { 472*061da546Spatrick if (form_value.Form() == DW_FORM_indirect) { 473*061da546Spatrick s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); 474*061da546Spatrick } 475*061da546Spatrick 476*061da546Spatrick s.PutCString("] "); 477*061da546Spatrick } 478*061da546Spatrick 479*061da546Spatrick s.PutCString("( "); 480*061da546Spatrick 481*061da546Spatrick // Check to see if we have any special attribute formatters 482*061da546Spatrick switch (attr) { 483*061da546Spatrick case DW_AT_stmt_list: 484*061da546Spatrick s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); 485*061da546Spatrick break; 486*061da546Spatrick 487*061da546Spatrick case DW_AT_language: 488*061da546Spatrick s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); 489*061da546Spatrick break; 490*061da546Spatrick 491*061da546Spatrick case DW_AT_encoding: 492*061da546Spatrick s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); 493*061da546Spatrick break; 494*061da546Spatrick 495*061da546Spatrick case DW_AT_frame_base: 496*061da546Spatrick case DW_AT_location: 497*061da546Spatrick case DW_AT_data_member_location: { 498*061da546Spatrick const uint8_t *blockData = form_value.BlockData(); 499*061da546Spatrick if (blockData) { 500*061da546Spatrick // Location description is inlined in data in the form value 501*061da546Spatrick DWARFDataExtractor locationData(data, 502*061da546Spatrick (*offset_ptr) - form_value.Unsigned(), 503*061da546Spatrick form_value.Unsigned()); 504*061da546Spatrick DWARFExpression::PrintDWARFExpression( 505*061da546Spatrick s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false); 506*061da546Spatrick } else { 507*061da546Spatrick // We have a location list offset as the value that is the offset into 508*061da546Spatrick // the .debug_loc section that describes the value over it's lifetime 509*061da546Spatrick uint64_t debug_loc_offset = form_value.Unsigned(); 510*061da546Spatrick DWARFExpression::PrintDWARFLocationList(s, cu, cu->GetLocationData(), 511*061da546Spatrick debug_loc_offset); 512*061da546Spatrick } 513*061da546Spatrick } break; 514*061da546Spatrick 515*061da546Spatrick case DW_AT_abstract_origin: 516*061da546Spatrick case DW_AT_specification: { 517*061da546Spatrick DWARFDIE abstract_die = form_value.Reference(); 518*061da546Spatrick form_value.Dump(s); 519*061da546Spatrick // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; 520*061da546Spatrick abstract_die.GetName(s); 521*061da546Spatrick } break; 522*061da546Spatrick 523*061da546Spatrick case DW_AT_type: { 524*061da546Spatrick DWARFDIE type_die = form_value.Reference(); 525*061da546Spatrick s.PutCString(" ( "); 526*061da546Spatrick type_die.AppendTypeName(s); 527*061da546Spatrick s.PutCString(" )"); 528*061da546Spatrick } break; 529*061da546Spatrick 530*061da546Spatrick default: 531*061da546Spatrick break; 532*061da546Spatrick } 533*061da546Spatrick 534*061da546Spatrick s.PutCString(" )\n"); 535*061da546Spatrick } 536*061da546Spatrick 537*061da546Spatrick // Get all attribute values for a given DIE, including following any 538*061da546Spatrick // specification or abstract origin attributes and including those in the 539*061da546Spatrick // results. Any duplicate attributes will have the first instance take 540*061da546Spatrick // precedence (this can happen for declaration attributes). 541*061da546Spatrick size_t DWARFDebugInfoEntry::GetAttributes( 542*061da546Spatrick const DWARFUnit *cu, DWARFAttributes &attributes, 543*061da546Spatrick uint32_t curr_depth) const { 544*061da546Spatrick const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); 545*061da546Spatrick if (abbrevDecl) { 546*061da546Spatrick const DWARFDataExtractor &data = cu->GetData(); 547*061da546Spatrick lldb::offset_t offset = GetFirstAttributeOffset(); 548*061da546Spatrick 549*061da546Spatrick const uint32_t num_attributes = abbrevDecl->NumAttributes(); 550*061da546Spatrick for (uint32_t i = 0; i < num_attributes; ++i) { 551*061da546Spatrick DWARFFormValue form_value(cu); 552*061da546Spatrick dw_attr_t attr; 553*061da546Spatrick abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 554*061da546Spatrick const dw_form_t form = form_value.Form(); 555*061da546Spatrick 556*061da546Spatrick // If we are tracking down DW_AT_specification or DW_AT_abstract_origin 557*061da546Spatrick // attributes, the depth will be non-zero. We need to omit certain 558*061da546Spatrick // attributes that don't make sense. 559*061da546Spatrick switch (attr) { 560*061da546Spatrick case DW_AT_sibling: 561*061da546Spatrick case DW_AT_declaration: 562*061da546Spatrick if (curr_depth > 0) { 563*061da546Spatrick // This attribute doesn't make sense when combined with the DIE that 564*061da546Spatrick // references this DIE. We know a DIE is referencing this DIE because 565*061da546Spatrick // curr_depth is not zero 566*061da546Spatrick break; 567*061da546Spatrick } 568*061da546Spatrick LLVM_FALLTHROUGH; 569*061da546Spatrick default: 570*061da546Spatrick attributes.Append(cu, offset, attr, form); 571*061da546Spatrick break; 572*061da546Spatrick } 573*061da546Spatrick 574*061da546Spatrick if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { 575*061da546Spatrick if (form_value.ExtractValue(data, &offset)) { 576*061da546Spatrick DWARFDIE spec_die = form_value.Reference(); 577*061da546Spatrick if (spec_die) 578*061da546Spatrick spec_die.GetAttributes(attributes, curr_depth + 1); 579*061da546Spatrick } 580*061da546Spatrick } else { 581*061da546Spatrick llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); 582*061da546Spatrick if (fixed_skip_size) 583*061da546Spatrick offset += *fixed_skip_size; 584*061da546Spatrick else 585*061da546Spatrick DWARFFormValue::SkipValue(form, data, &offset, cu); 586*061da546Spatrick } 587*061da546Spatrick } 588*061da546Spatrick } else { 589*061da546Spatrick attributes.Clear(); 590*061da546Spatrick } 591*061da546Spatrick return attributes.Size(); 592*061da546Spatrick } 593*061da546Spatrick 594*061da546Spatrick // GetAttributeValue 595*061da546Spatrick // 596*061da546Spatrick // Get the value of an attribute and return the .debug_info or .debug_types 597*061da546Spatrick // offset of the attribute if it was properly extracted into form_value, 598*061da546Spatrick // or zero if we fail since an offset of zero is invalid for an attribute (it 599*061da546Spatrick // would be a compile unit header). 600*061da546Spatrick dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( 601*061da546Spatrick const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value, 602*061da546Spatrick dw_offset_t *end_attr_offset_ptr, 603*061da546Spatrick bool check_specification_or_abstract_origin) const { 604*061da546Spatrick if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) { 605*061da546Spatrick uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); 606*061da546Spatrick 607*061da546Spatrick if (attr_idx != DW_INVALID_INDEX) { 608*061da546Spatrick const DWARFDataExtractor &data = cu->GetData(); 609*061da546Spatrick lldb::offset_t offset = GetFirstAttributeOffset(); 610*061da546Spatrick 611*061da546Spatrick uint32_t idx = 0; 612*061da546Spatrick while (idx < attr_idx) 613*061da546Spatrick DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), 614*061da546Spatrick data, &offset, cu); 615*061da546Spatrick 616*061da546Spatrick const dw_offset_t attr_offset = offset; 617*061da546Spatrick form_value.SetUnit(cu); 618*061da546Spatrick form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); 619*061da546Spatrick if (form_value.ExtractValue(data, &offset)) { 620*061da546Spatrick if (end_attr_offset_ptr) 621*061da546Spatrick *end_attr_offset_ptr = offset; 622*061da546Spatrick return attr_offset; 623*061da546Spatrick } 624*061da546Spatrick } 625*061da546Spatrick } 626*061da546Spatrick 627*061da546Spatrick if (check_specification_or_abstract_origin) { 628*061da546Spatrick if (GetAttributeValue(cu, DW_AT_specification, form_value)) { 629*061da546Spatrick DWARFDIE die = form_value.Reference(); 630*061da546Spatrick if (die) { 631*061da546Spatrick dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( 632*061da546Spatrick die.GetCU(), attr, form_value, end_attr_offset_ptr, false); 633*061da546Spatrick if (die_offset) 634*061da546Spatrick return die_offset; 635*061da546Spatrick } 636*061da546Spatrick } 637*061da546Spatrick 638*061da546Spatrick if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) { 639*061da546Spatrick DWARFDIE die = form_value.Reference(); 640*061da546Spatrick if (die) { 641*061da546Spatrick dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( 642*061da546Spatrick die.GetCU(), attr, form_value, end_attr_offset_ptr, false); 643*061da546Spatrick if (die_offset) 644*061da546Spatrick return die_offset; 645*061da546Spatrick } 646*061da546Spatrick } 647*061da546Spatrick } 648*061da546Spatrick return 0; 649*061da546Spatrick } 650*061da546Spatrick 651*061da546Spatrick // GetAttributeValueAsString 652*061da546Spatrick // 653*061da546Spatrick // Get the value of an attribute as a string return it. The resulting pointer 654*061da546Spatrick // to the string data exists within the supplied SymbolFileDWARF and will only 655*061da546Spatrick // be available as long as the SymbolFileDWARF is still around and it's content 656*061da546Spatrick // doesn't change. 657*061da546Spatrick const char *DWARFDebugInfoEntry::GetAttributeValueAsString( 658*061da546Spatrick const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, 659*061da546Spatrick bool check_specification_or_abstract_origin) const { 660*061da546Spatrick DWARFFormValue form_value; 661*061da546Spatrick if (GetAttributeValue(cu, attr, form_value, nullptr, 662*061da546Spatrick check_specification_or_abstract_origin)) 663*061da546Spatrick return form_value.AsCString(); 664*061da546Spatrick return fail_value; 665*061da546Spatrick } 666*061da546Spatrick 667*061da546Spatrick // GetAttributeValueAsUnsigned 668*061da546Spatrick // 669*061da546Spatrick // Get the value of an attribute as unsigned and return it. 670*061da546Spatrick uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned( 671*061da546Spatrick const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 672*061da546Spatrick bool check_specification_or_abstract_origin) const { 673*061da546Spatrick DWARFFormValue form_value; 674*061da546Spatrick if (GetAttributeValue(cu, attr, form_value, nullptr, 675*061da546Spatrick check_specification_or_abstract_origin)) 676*061da546Spatrick return form_value.Unsigned(); 677*061da546Spatrick return fail_value; 678*061da546Spatrick } 679*061da546Spatrick 680*061da546Spatrick // GetAttributeValueAsReference 681*061da546Spatrick // 682*061da546Spatrick // Get the value of an attribute as reference and fix up and compile unit 683*061da546Spatrick // relative offsets as needed. 684*061da546Spatrick DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference( 685*061da546Spatrick const DWARFUnit *cu, const dw_attr_t attr, 686*061da546Spatrick bool check_specification_or_abstract_origin) const { 687*061da546Spatrick DWARFFormValue form_value; 688*061da546Spatrick if (GetAttributeValue(cu, attr, form_value, nullptr, 689*061da546Spatrick check_specification_or_abstract_origin)) 690*061da546Spatrick return form_value.Reference(); 691*061da546Spatrick return {}; 692*061da546Spatrick } 693*061da546Spatrick 694*061da546Spatrick uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress( 695*061da546Spatrick const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 696*061da546Spatrick bool check_specification_or_abstract_origin) const { 697*061da546Spatrick DWARFFormValue form_value; 698*061da546Spatrick if (GetAttributeValue(cu, attr, form_value, nullptr, 699*061da546Spatrick check_specification_or_abstract_origin)) 700*061da546Spatrick return form_value.Address(); 701*061da546Spatrick return fail_value; 702*061da546Spatrick } 703*061da546Spatrick 704*061da546Spatrick // GetAttributeHighPC 705*061da546Spatrick // 706*061da546Spatrick // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low- 707*061da546Spatrick // pc>. 708*061da546Spatrick // 709*061da546Spatrick // Returns the hi_pc or fail_value. 710*061da546Spatrick dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( 711*061da546Spatrick const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, 712*061da546Spatrick bool check_specification_or_abstract_origin) const { 713*061da546Spatrick DWARFFormValue form_value; 714*061da546Spatrick if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr, 715*061da546Spatrick check_specification_or_abstract_origin)) { 716*061da546Spatrick dw_form_t form = form_value.Form(); 717*061da546Spatrick if (form == DW_FORM_addr || form == DW_FORM_addrx || 718*061da546Spatrick form == DW_FORM_GNU_addr_index) 719*061da546Spatrick return form_value.Address(); 720*061da546Spatrick 721*061da546Spatrick // DWARF4 can specify the hi_pc as an <offset-from-lowpc> 722*061da546Spatrick return lo_pc + form_value.Unsigned(); 723*061da546Spatrick } 724*061da546Spatrick return fail_value; 725*061da546Spatrick } 726*061da546Spatrick 727*061da546Spatrick // GetAttributeAddressRange 728*061da546Spatrick // 729*061da546Spatrick // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset- 730*061da546Spatrick // from-low-pc>. 731*061da546Spatrick // 732*061da546Spatrick // Returns true or sets lo_pc and hi_pc to fail_value. 733*061da546Spatrick bool DWARFDebugInfoEntry::GetAttributeAddressRange( 734*061da546Spatrick const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc, 735*061da546Spatrick uint64_t fail_value, bool check_specification_or_abstract_origin) const { 736*061da546Spatrick lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value, 737*061da546Spatrick check_specification_or_abstract_origin); 738*061da546Spatrick if (lo_pc != fail_value) { 739*061da546Spatrick hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value, 740*061da546Spatrick check_specification_or_abstract_origin); 741*061da546Spatrick if (hi_pc != fail_value) 742*061da546Spatrick return true; 743*061da546Spatrick } 744*061da546Spatrick lo_pc = fail_value; 745*061da546Spatrick hi_pc = fail_value; 746*061da546Spatrick return false; 747*061da546Spatrick } 748*061da546Spatrick 749*061da546Spatrick size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( 750*061da546Spatrick DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, 751*061da546Spatrick bool check_specification_or_abstract_origin) const { 752*061da546Spatrick ranges.Clear(); 753*061da546Spatrick 754*061da546Spatrick DWARFFormValue form_value; 755*061da546Spatrick if (GetAttributeValue(cu, DW_AT_ranges, form_value)) { 756*061da546Spatrick ranges = GetRangesOrReportError(*cu, *this, form_value); 757*061da546Spatrick } else if (check_hi_lo_pc) { 758*061da546Spatrick dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 759*061da546Spatrick dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 760*061da546Spatrick if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, 761*061da546Spatrick check_specification_or_abstract_origin)) { 762*061da546Spatrick if (lo_pc < hi_pc) 763*061da546Spatrick ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); 764*061da546Spatrick } 765*061da546Spatrick } 766*061da546Spatrick return ranges.GetSize(); 767*061da546Spatrick } 768*061da546Spatrick 769*061da546Spatrick // GetName 770*061da546Spatrick // 771*061da546Spatrick // Get value of the DW_AT_name attribute and return it if one exists, else 772*061da546Spatrick // return NULL. 773*061da546Spatrick const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const { 774*061da546Spatrick return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 775*061da546Spatrick } 776*061da546Spatrick 777*061da546Spatrick // GetMangledName 778*061da546Spatrick // 779*061da546Spatrick // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one 780*061da546Spatrick // exists, else return the value of the DW_AT_name attribute 781*061da546Spatrick const char * 782*061da546Spatrick DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu, 783*061da546Spatrick bool substitute_name_allowed) const { 784*061da546Spatrick const char *name = nullptr; 785*061da546Spatrick 786*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); 787*061da546Spatrick if (name) 788*061da546Spatrick return name; 789*061da546Spatrick 790*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); 791*061da546Spatrick if (name) 792*061da546Spatrick return name; 793*061da546Spatrick 794*061da546Spatrick if (!substitute_name_allowed) 795*061da546Spatrick return nullptr; 796*061da546Spatrick 797*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 798*061da546Spatrick return name; 799*061da546Spatrick } 800*061da546Spatrick 801*061da546Spatrick // GetPubname 802*061da546Spatrick // 803*061da546Spatrick // Get value the name for a DIE as it should appear for a .debug_pubnames or 804*061da546Spatrick // .debug_pubtypes section. 805*061da546Spatrick const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { 806*061da546Spatrick const char *name = nullptr; 807*061da546Spatrick if (!cu) 808*061da546Spatrick return name; 809*061da546Spatrick 810*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); 811*061da546Spatrick if (name) 812*061da546Spatrick return name; 813*061da546Spatrick 814*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); 815*061da546Spatrick if (name) 816*061da546Spatrick return name; 817*061da546Spatrick 818*061da546Spatrick name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 819*061da546Spatrick return name; 820*061da546Spatrick } 821*061da546Spatrick 822*061da546Spatrick // BuildAddressRangeTable 823*061da546Spatrick void DWARFDebugInfoEntry::BuildAddressRangeTable( 824*061da546Spatrick const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { 825*061da546Spatrick if (m_tag) { 826*061da546Spatrick if (m_tag == DW_TAG_subprogram) { 827*061da546Spatrick dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 828*061da546Spatrick dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 829*061da546Spatrick if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { 830*061da546Spatrick /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 831*061da546Spatrick /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); 832*061da546Spatrick debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); 833*061da546Spatrick } 834*061da546Spatrick } 835*061da546Spatrick 836*061da546Spatrick const DWARFDebugInfoEntry *child = GetFirstChild(); 837*061da546Spatrick while (child) { 838*061da546Spatrick child->BuildAddressRangeTable(cu, debug_aranges); 839*061da546Spatrick child = child->GetSibling(); 840*061da546Spatrick } 841*061da546Spatrick } 842*061da546Spatrick } 843*061da546Spatrick 844*061da546Spatrick // BuildFunctionAddressRangeTable 845*061da546Spatrick // 846*061da546Spatrick // This function is very similar to the BuildAddressRangeTable function except 847*061da546Spatrick // that the actual DIE offset for the function is placed in the table instead 848*061da546Spatrick // of the compile unit offset (which is the way the standard .debug_aranges 849*061da546Spatrick // section does it). 850*061da546Spatrick void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( 851*061da546Spatrick const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { 852*061da546Spatrick if (m_tag) { 853*061da546Spatrick if (m_tag == DW_TAG_subprogram) { 854*061da546Spatrick dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 855*061da546Spatrick dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 856*061da546Spatrick if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { 857*061da546Spatrick // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 858*061da546Spatrick // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY 859*061da546Spatrick debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); 860*061da546Spatrick } 861*061da546Spatrick } 862*061da546Spatrick 863*061da546Spatrick const DWARFDebugInfoEntry *child = GetFirstChild(); 864*061da546Spatrick while (child) { 865*061da546Spatrick child->BuildFunctionAddressRangeTable(cu, debug_aranges); 866*061da546Spatrick child = child->GetSibling(); 867*061da546Spatrick } 868*061da546Spatrick } 869*061da546Spatrick } 870*061da546Spatrick 871*061da546Spatrick void DWARFDebugInfoEntry::GetDWARFDeclContext( 872*061da546Spatrick DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const { 873*061da546Spatrick const dw_tag_t tag = Tag(); 874*061da546Spatrick if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) { 875*061da546Spatrick dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu)); 876*061da546Spatrick DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); 877*061da546Spatrick if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { 878*061da546Spatrick if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit && 879*061da546Spatrick parent_decl_ctx_die.Tag() != DW_TAG_partial_unit) 880*061da546Spatrick parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( 881*061da546Spatrick parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); 882*061da546Spatrick } 883*061da546Spatrick } 884*061da546Spatrick } 885*061da546Spatrick 886*061da546Spatrick DWARFDIE 887*061da546Spatrick DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { 888*061da546Spatrick DWARFAttributes attributes; 889*061da546Spatrick GetAttributes(cu, attributes); 890*061da546Spatrick return GetParentDeclContextDIE(cu, attributes); 891*061da546Spatrick } 892*061da546Spatrick 893*061da546Spatrick DWARFDIE 894*061da546Spatrick DWARFDebugInfoEntry::GetParentDeclContextDIE( 895*061da546Spatrick DWARFUnit *cu, const DWARFAttributes &attributes) const { 896*061da546Spatrick DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); 897*061da546Spatrick 898*061da546Spatrick while (die) { 899*061da546Spatrick // If this is the original DIE that we are searching for a declaration for, 900*061da546Spatrick // then don't look in the cache as we don't want our own decl context to be 901*061da546Spatrick // our decl context... 902*061da546Spatrick if (die.GetDIE() != this) { 903*061da546Spatrick switch (die.Tag()) { 904*061da546Spatrick case DW_TAG_compile_unit: 905*061da546Spatrick case DW_TAG_partial_unit: 906*061da546Spatrick case DW_TAG_namespace: 907*061da546Spatrick case DW_TAG_structure_type: 908*061da546Spatrick case DW_TAG_union_type: 909*061da546Spatrick case DW_TAG_class_type: 910*061da546Spatrick return die; 911*061da546Spatrick 912*061da546Spatrick default: 913*061da546Spatrick break; 914*061da546Spatrick } 915*061da546Spatrick } 916*061da546Spatrick 917*061da546Spatrick DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification); 918*061da546Spatrick if (spec_die) { 919*061da546Spatrick DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE(); 920*061da546Spatrick if (decl_ctx_die) 921*061da546Spatrick return decl_ctx_die; 922*061da546Spatrick } 923*061da546Spatrick 924*061da546Spatrick DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin); 925*061da546Spatrick if (abs_die) { 926*061da546Spatrick DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE(); 927*061da546Spatrick if (decl_ctx_die) 928*061da546Spatrick return decl_ctx_die; 929*061da546Spatrick } 930*061da546Spatrick 931*061da546Spatrick die = die.GetParent(); 932*061da546Spatrick } 933*061da546Spatrick return DWARFDIE(); 934*061da546Spatrick } 935*061da546Spatrick 936*061da546Spatrick const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, 937*061da546Spatrick std::string &storage) const { 938*061da546Spatrick DWARFAttributes attributes; 939*061da546Spatrick GetAttributes(cu, attributes); 940*061da546Spatrick return GetQualifiedName(cu, attributes, storage); 941*061da546Spatrick } 942*061da546Spatrick 943*061da546Spatrick const char * 944*061da546Spatrick DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, 945*061da546Spatrick const DWARFAttributes &attributes, 946*061da546Spatrick std::string &storage) const { 947*061da546Spatrick 948*061da546Spatrick const char *name = GetName(cu); 949*061da546Spatrick 950*061da546Spatrick if (name) { 951*061da546Spatrick DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); 952*061da546Spatrick storage.clear(); 953*061da546Spatrick // TODO: change this to get the correct decl context parent.... 954*061da546Spatrick while (parent_decl_ctx_die) { 955*061da546Spatrick const dw_tag_t parent_tag = parent_decl_ctx_die.Tag(); 956*061da546Spatrick switch (parent_tag) { 957*061da546Spatrick case DW_TAG_namespace: { 958*061da546Spatrick const char *namespace_name = parent_decl_ctx_die.GetName(); 959*061da546Spatrick if (namespace_name) { 960*061da546Spatrick storage.insert(0, "::"); 961*061da546Spatrick storage.insert(0, namespace_name); 962*061da546Spatrick } else { 963*061da546Spatrick storage.insert(0, "(anonymous namespace)::"); 964*061da546Spatrick } 965*061da546Spatrick parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); 966*061da546Spatrick } break; 967*061da546Spatrick 968*061da546Spatrick case DW_TAG_class_type: 969*061da546Spatrick case DW_TAG_structure_type: 970*061da546Spatrick case DW_TAG_union_type: { 971*061da546Spatrick const char *class_union_struct_name = parent_decl_ctx_die.GetName(); 972*061da546Spatrick 973*061da546Spatrick if (class_union_struct_name) { 974*061da546Spatrick storage.insert(0, "::"); 975*061da546Spatrick storage.insert(0, class_union_struct_name); 976*061da546Spatrick } 977*061da546Spatrick parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); 978*061da546Spatrick } break; 979*061da546Spatrick 980*061da546Spatrick default: 981*061da546Spatrick parent_decl_ctx_die.Clear(); 982*061da546Spatrick break; 983*061da546Spatrick } 984*061da546Spatrick } 985*061da546Spatrick 986*061da546Spatrick if (storage.empty()) 987*061da546Spatrick storage.append("::"); 988*061da546Spatrick 989*061da546Spatrick storage.append(name); 990*061da546Spatrick } 991*061da546Spatrick if (storage.empty()) 992*061da546Spatrick return nullptr; 993*061da546Spatrick return storage.c_str(); 994*061da546Spatrick } 995*061da546Spatrick 996*061da546Spatrick bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu, 997*061da546Spatrick DWARFDebugInfoEntry **function_die, 998*061da546Spatrick DWARFDebugInfoEntry **block_die) { 999*061da546Spatrick bool found_address = false; 1000*061da546Spatrick if (m_tag) { 1001*061da546Spatrick bool check_children = false; 1002*061da546Spatrick bool match_addr_range = false; 1003*061da546Spatrick // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, 1004*061da546Spatrick // DW_TAG_value_to_name(tag), address); 1005*061da546Spatrick switch (m_tag) { 1006*061da546Spatrick case DW_TAG_array_type: 1007*061da546Spatrick break; 1008*061da546Spatrick case DW_TAG_class_type: 1009*061da546Spatrick check_children = true; 1010*061da546Spatrick break; 1011*061da546Spatrick case DW_TAG_entry_point: 1012*061da546Spatrick case DW_TAG_enumeration_type: 1013*061da546Spatrick case DW_TAG_formal_parameter: 1014*061da546Spatrick case DW_TAG_imported_declaration: 1015*061da546Spatrick case DW_TAG_label: 1016*061da546Spatrick break; 1017*061da546Spatrick case DW_TAG_lexical_block: 1018*061da546Spatrick check_children = true; 1019*061da546Spatrick match_addr_range = true; 1020*061da546Spatrick break; 1021*061da546Spatrick case DW_TAG_member: 1022*061da546Spatrick case DW_TAG_pointer_type: 1023*061da546Spatrick case DW_TAG_reference_type: 1024*061da546Spatrick break; 1025*061da546Spatrick case DW_TAG_compile_unit: 1026*061da546Spatrick match_addr_range = true; 1027*061da546Spatrick break; 1028*061da546Spatrick case DW_TAG_string_type: 1029*061da546Spatrick break; 1030*061da546Spatrick case DW_TAG_structure_type: 1031*061da546Spatrick check_children = true; 1032*061da546Spatrick break; 1033*061da546Spatrick case DW_TAG_subroutine_type: 1034*061da546Spatrick case DW_TAG_typedef: 1035*061da546Spatrick case DW_TAG_union_type: 1036*061da546Spatrick case DW_TAG_unspecified_parameters: 1037*061da546Spatrick case DW_TAG_variant: 1038*061da546Spatrick break; 1039*061da546Spatrick case DW_TAG_common_block: 1040*061da546Spatrick check_children = true; 1041*061da546Spatrick break; 1042*061da546Spatrick case DW_TAG_common_inclusion: 1043*061da546Spatrick case DW_TAG_inheritance: 1044*061da546Spatrick break; 1045*061da546Spatrick case DW_TAG_inlined_subroutine: 1046*061da546Spatrick check_children = true; 1047*061da546Spatrick match_addr_range = true; 1048*061da546Spatrick break; 1049*061da546Spatrick case DW_TAG_module: 1050*061da546Spatrick match_addr_range = true; 1051*061da546Spatrick break; 1052*061da546Spatrick case DW_TAG_ptr_to_member_type: 1053*061da546Spatrick case DW_TAG_set_type: 1054*061da546Spatrick case DW_TAG_subrange_type: 1055*061da546Spatrick case DW_TAG_with_stmt: 1056*061da546Spatrick case DW_TAG_access_declaration: 1057*061da546Spatrick case DW_TAG_base_type: 1058*061da546Spatrick break; 1059*061da546Spatrick case DW_TAG_catch_block: 1060*061da546Spatrick match_addr_range = true; 1061*061da546Spatrick break; 1062*061da546Spatrick case DW_TAG_const_type: 1063*061da546Spatrick case DW_TAG_constant: 1064*061da546Spatrick case DW_TAG_enumerator: 1065*061da546Spatrick case DW_TAG_file_type: 1066*061da546Spatrick case DW_TAG_friend: 1067*061da546Spatrick case DW_TAG_namelist: 1068*061da546Spatrick case DW_TAG_namelist_item: 1069*061da546Spatrick case DW_TAG_packed_type: 1070*061da546Spatrick break; 1071*061da546Spatrick case DW_TAG_subprogram: 1072*061da546Spatrick match_addr_range = true; 1073*061da546Spatrick break; 1074*061da546Spatrick case DW_TAG_template_type_parameter: 1075*061da546Spatrick case DW_TAG_template_value_parameter: 1076*061da546Spatrick case DW_TAG_GNU_template_parameter_pack: 1077*061da546Spatrick case DW_TAG_thrown_type: 1078*061da546Spatrick break; 1079*061da546Spatrick case DW_TAG_try_block: 1080*061da546Spatrick match_addr_range = true; 1081*061da546Spatrick break; 1082*061da546Spatrick case DW_TAG_variant_part: 1083*061da546Spatrick case DW_TAG_variable: 1084*061da546Spatrick case DW_TAG_volatile_type: 1085*061da546Spatrick case DW_TAG_dwarf_procedure: 1086*061da546Spatrick case DW_TAG_restrict_type: 1087*061da546Spatrick case DW_TAG_interface_type: 1088*061da546Spatrick break; 1089*061da546Spatrick case DW_TAG_namespace: 1090*061da546Spatrick check_children = true; 1091*061da546Spatrick break; 1092*061da546Spatrick case DW_TAG_imported_module: 1093*061da546Spatrick case DW_TAG_unspecified_type: 1094*061da546Spatrick break; 1095*061da546Spatrick case DW_TAG_partial_unit: 1096*061da546Spatrick match_addr_range = true; 1097*061da546Spatrick break; 1098*061da546Spatrick case DW_TAG_imported_unit: 1099*061da546Spatrick case DW_TAG_shared_type: 1100*061da546Spatrick default: 1101*061da546Spatrick break; 1102*061da546Spatrick } 1103*061da546Spatrick 1104*061da546Spatrick if (match_addr_range) { 1105*061da546Spatrick dw_addr_t lo_pc = 1106*061da546Spatrick GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 1107*061da546Spatrick if (lo_pc != LLDB_INVALID_ADDRESS) { 1108*061da546Spatrick dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS); 1109*061da546Spatrick if (hi_pc != LLDB_INVALID_ADDRESS) { 1110*061da546Spatrick // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", 1111*061da546Spatrick // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); 1112*061da546Spatrick if ((lo_pc <= address) && (address < hi_pc)) { 1113*061da546Spatrick found_address = true; 1114*061da546Spatrick // puts("***MATCH***"); 1115*061da546Spatrick switch (m_tag) { 1116*061da546Spatrick case DW_TAG_compile_unit: // File 1117*061da546Spatrick case DW_TAG_partial_unit: // File 1118*061da546Spatrick check_children = 1119*061da546Spatrick ((function_die != nullptr) || (block_die != nullptr)); 1120*061da546Spatrick break; 1121*061da546Spatrick 1122*061da546Spatrick case DW_TAG_subprogram: // Function 1123*061da546Spatrick if (function_die) 1124*061da546Spatrick *function_die = this; 1125*061da546Spatrick check_children = (block_die != nullptr); 1126*061da546Spatrick break; 1127*061da546Spatrick 1128*061da546Spatrick case DW_TAG_inlined_subroutine: // Inlined Function 1129*061da546Spatrick case DW_TAG_lexical_block: // Block { } in code 1130*061da546Spatrick if (block_die) { 1131*061da546Spatrick *block_die = this; 1132*061da546Spatrick check_children = true; 1133*061da546Spatrick } 1134*061da546Spatrick break; 1135*061da546Spatrick 1136*061da546Spatrick default: 1137*061da546Spatrick check_children = true; 1138*061da546Spatrick break; 1139*061da546Spatrick } 1140*061da546Spatrick } 1141*061da546Spatrick } else { 1142*061da546Spatrick // Compile units may not have a valid high/low pc when there 1143*061da546Spatrick // are address gaps in subroutines so we must always search 1144*061da546Spatrick // if there is no valid high and low PC. 1145*061da546Spatrick check_children = 1146*061da546Spatrick (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && 1147*061da546Spatrick ((function_die != nullptr) || (block_die != nullptr)); 1148*061da546Spatrick } 1149*061da546Spatrick } else { 1150*061da546Spatrick DWARFRangeList ranges; 1151*061da546Spatrick if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) && 1152*061da546Spatrick ranges.FindEntryThatContains(address)) { 1153*061da546Spatrick found_address = true; 1154*061da546Spatrick // puts("***MATCH***"); 1155*061da546Spatrick switch (m_tag) { 1156*061da546Spatrick case DW_TAG_compile_unit: // File 1157*061da546Spatrick case DW_TAG_partial_unit: // File 1158*061da546Spatrick check_children = 1159*061da546Spatrick ((function_die != nullptr) || (block_die != nullptr)); 1160*061da546Spatrick break; 1161*061da546Spatrick 1162*061da546Spatrick case DW_TAG_subprogram: // Function 1163*061da546Spatrick if (function_die) 1164*061da546Spatrick *function_die = this; 1165*061da546Spatrick check_children = (block_die != nullptr); 1166*061da546Spatrick break; 1167*061da546Spatrick 1168*061da546Spatrick case DW_TAG_inlined_subroutine: // Inlined Function 1169*061da546Spatrick case DW_TAG_lexical_block: // Block { } in code 1170*061da546Spatrick if (block_die) { 1171*061da546Spatrick *block_die = this; 1172*061da546Spatrick check_children = true; 1173*061da546Spatrick } 1174*061da546Spatrick break; 1175*061da546Spatrick 1176*061da546Spatrick default: 1177*061da546Spatrick check_children = true; 1178*061da546Spatrick break; 1179*061da546Spatrick } 1180*061da546Spatrick } else { 1181*061da546Spatrick check_children = false; 1182*061da546Spatrick } 1183*061da546Spatrick } 1184*061da546Spatrick } 1185*061da546Spatrick 1186*061da546Spatrick if (check_children) { 1187*061da546Spatrick // printf("checking children\n"); 1188*061da546Spatrick DWARFDebugInfoEntry *child = GetFirstChild(); 1189*061da546Spatrick while (child) { 1190*061da546Spatrick if (child->LookupAddress(address, cu, function_die, block_die)) 1191*061da546Spatrick return true; 1192*061da546Spatrick child = child->GetSibling(); 1193*061da546Spatrick } 1194*061da546Spatrick } 1195*061da546Spatrick } 1196*061da546Spatrick return found_address; 1197*061da546Spatrick } 1198*061da546Spatrick 1199*061da546Spatrick lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { 1200*061da546Spatrick return GetOffset() + llvm::getULEB128Size(m_abbr_idx); 1201*061da546Spatrick } 1202*061da546Spatrick 1203*061da546Spatrick const DWARFAbbreviationDeclaration * 1204*061da546Spatrick DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { 1205*061da546Spatrick if (cu) { 1206*061da546Spatrick const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); 1207*061da546Spatrick if (abbrev_set) 1208*061da546Spatrick return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx); 1209*061da546Spatrick } 1210*061da546Spatrick return nullptr; 1211*061da546Spatrick } 1212*061da546Spatrick 1213*061da546Spatrick bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { 1214*061da546Spatrick return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && 1215*061da546Spatrick m_sibling_idx == rhs.m_sibling_idx && 1216*061da546Spatrick m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children && 1217*061da546Spatrick m_tag == rhs.m_tag; 1218*061da546Spatrick } 1219*061da546Spatrick 1220*061da546Spatrick bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const { 1221*061da546Spatrick return !(*this == rhs); 1222*061da546Spatrick } 1223