DWARFDebugInfoEntry.cpp revision 0963fdd2478c6404d11b96e7d5ae1f2de8b3bb1f
1//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "DWARFDebugInfoEntry.h" 11 12#include <assert.h> 13 14#include <algorithm> 15 16#include "lldb/Core/Stream.h" 17#include "lldb/Expression/DWARFExpression.h" 18#include "lldb/Symbol/ObjectFile.h" 19 20#include "DWARFCompileUnit.h" 21#include "SymbolFileDWARF.h" 22#include "DWARFDebugAbbrev.h" 23#include "DWARFDebugAranges.h" 24#include "DWARFDebugInfo.h" 25#include "DWARFDIECollection.h" 26#include "DWARFFormValue.h" 27#include "DWARFLocationDescription.h" 28#include "DWARFLocationList.h" 29#include "DWARFDebugRanges.h" 30 31using namespace lldb_private; 32using namespace std; 33extern int g_verbose; 34 35 36 37DWARFDebugInfoEntry::Attributes::Attributes() : 38 m_infos() 39{ 40} 41 42DWARFDebugInfoEntry::Attributes::~Attributes() 43{ 44} 45 46 47uint32_t 48DWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const 49{ 50 collection::const_iterator end = m_infos.end(); 51 collection::const_iterator beg = m_infos.begin(); 52 collection::const_iterator pos; 53 for (pos = beg; pos != end; ++pos) 54 { 55 if (pos->attr == attr) 56 return std::distance(beg, pos); 57 } 58 return UINT32_MAX; 59} 60 61void 62DWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form) 63{ 64 Info info = { cu, attr_die_offset, attr, form }; 65 m_infos.push_back(info); 66} 67 68bool 69DWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const 70{ 71 return FindAttributeIndex(attr) != UINT32_MAX; 72} 73 74bool 75DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr) 76{ 77 uint32_t attr_index = FindAttributeIndex(attr); 78 if (attr_index != UINT32_MAX) 79 { 80 m_infos.erase(m_infos.begin() + attr_index); 81 return true; 82 } 83 return false; 84} 85 86bool 87DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const 88{ 89 form_value.SetForm(FormAtIndex(i)); 90 dw_offset_t offset = DIEOffsetAtIndex(i); 91 return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i)); 92} 93 94uint64_t 95DWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const 96{ 97 DWARFFormValue form_value; 98 if (ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 99 return form_value.Reference(CompileUnitAtIndex(i)); 100 return fail_value; 101} 102 103 104 105bool 106DWARFDebugInfoEntry::FastExtract 107( 108 const DataExtractor& debug_info_data, 109 const DWARFCompileUnit* cu, 110 const uint8_t *fixed_form_sizes, 111 uint32_t* offset_ptr 112) 113{ 114 m_offset = *offset_ptr; 115 116 uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr); 117 assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); 118 m_abbr_idx = abbr_idx; 119 120 assert (fixed_form_sizes); // For best performance this should be specified! 121 122 if (m_abbr_idx) 123 { 124 uint32_t offset = *offset_ptr; 125 126 const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); 127 128 m_tag = abbrevDecl->Tag(); 129 m_has_children = abbrevDecl->HasChildren(); 130 // Skip all data in the .debug_info for the attributes 131 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 132 register uint32_t i; 133 register dw_form_t form; 134 for (i=0; i<numAttributes; ++i) 135 { 136 form = abbrevDecl->GetFormByIndexUnchecked(i); 137 138 const uint8_t fixed_skip_size = fixed_form_sizes [form]; 139 if (fixed_skip_size) 140 offset += fixed_skip_size; 141 else 142 { 143 bool form_is_indirect = false; 144 do 145 { 146 form_is_indirect = false; 147 register uint32_t form_size = 0; 148 switch (form) 149 { 150 // Blocks if inlined data that have a length field and the data bytes 151 // inlined in the .debug_info 152 case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break; 153 case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break; 154 case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break; 155 case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break; 156 157 // Inlined NULL terminated C-strings 158 case DW_FORM_string : 159 debug_info_data.GetCStr (&offset); 160 break; 161 162 // Compile unit address sized values 163 case DW_FORM_addr : 164 case DW_FORM_ref_addr : 165 form_size = cu->GetAddressByteSize(); 166 break; 167 168 // 1 byte values 169 case DW_FORM_data1 : 170 case DW_FORM_flag : 171 case DW_FORM_ref1 : 172 form_size = 1; 173 break; 174 175 // 2 byte values 176 case DW_FORM_data2 : 177 case DW_FORM_ref2 : 178 form_size = 2; 179 break; 180 181 // 4 byte values 182 case DW_FORM_strp : 183 case DW_FORM_data4 : 184 case DW_FORM_ref4 : 185 form_size = 4; 186 break; 187 188 // 8 byte values 189 case DW_FORM_data8 : 190 case DW_FORM_ref8 : 191 form_size = 8; 192 break; 193 194 // signed or unsigned LEB 128 values 195 case DW_FORM_sdata : 196 case DW_FORM_udata : 197 case DW_FORM_ref_udata : 198 debug_info_data.Skip_LEB128 (&offset); 199 break; 200 201 case DW_FORM_indirect : 202 form_is_indirect = true; 203 form = debug_info_data.GetULEB128 (&offset); 204 break; 205 206 default: 207 *offset_ptr = m_offset; 208 return false; 209 } 210 offset += form_size; 211 212 } while (form_is_indirect); 213 } 214 } 215 *offset_ptr = offset; 216 return true; 217 } 218 else 219 { 220 m_tag = 0; 221 m_has_children = false; 222 return true; // NULL debug tag entry 223 } 224 225 return false; 226} 227 228//---------------------------------------------------------------------- 229// Extract 230// 231// Extract a debug info entry for a given compile unit from the 232// .debug_info and .debug_abbrev data within the SymbolFileDWARF class 233// starting at the given offset 234//---------------------------------------------------------------------- 235bool 236DWARFDebugInfoEntry::Extract 237( 238 SymbolFileDWARF* dwarf2Data, 239 const DWARFCompileUnit* cu, 240 uint32_t* offset_ptr 241) 242{ 243 const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 244// const DataExtractor& debug_str_data = dwarf2Data->get_debug_str_data(); 245 const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); 246 const uint8_t cu_addr_size = cu->GetAddressByteSize(); 247 uint32_t offset = *offset_ptr; 248// if (offset >= cu_end_offset) 249// 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); 250 if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) 251 { 252 m_offset = offset; 253 254 const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); 255 assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); 256 m_abbr_idx = abbr_idx; 257 if (abbr_idx) 258 { 259 const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); 260 261 if (abbrevDecl) 262 { 263 m_tag = abbrevDecl->Tag(); 264 m_has_children = abbrevDecl->HasChildren(); 265 266 bool isCompileUnitTag = m_tag == DW_TAG_compile_unit; 267 if (cu && isCompileUnitTag) 268 ((DWARFCompileUnit*)cu)->SetBaseAddress(0); 269 270 // Skip all data in the .debug_info for the attributes 271 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 272 uint32_t i; 273 dw_attr_t attr; 274 dw_form_t form; 275 for (i=0; i<numAttributes; ++i) 276 { 277 abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 278 279 if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) 280 { 281 DWARFFormValue form_value(form); 282 if (form_value.ExtractValue(debug_info_data, &offset, cu)) 283 { 284 if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) 285 ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned()); 286 } 287 } 288 else 289 { 290 bool form_is_indirect = false; 291 do 292 { 293 form_is_indirect = false; 294 register uint32_t form_size = 0; 295 switch (form) 296 { 297 // Blocks if inlined data that have a length field and the data bytes 298 // inlined in the .debug_info 299 case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break; 300 case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break; 301 case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break; 302 case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break; 303 304 // Inlined NULL terminated C-strings 305 case DW_FORM_string : debug_info_data.GetCStr(&offset); break; 306 307 // Compile unit address sized values 308 case DW_FORM_addr : 309 case DW_FORM_ref_addr : 310 form_size = cu_addr_size; 311 break; 312 313 // 1 byte values 314 case DW_FORM_data1 : 315 case DW_FORM_flag : 316 case DW_FORM_ref1 : 317 form_size = 1; 318 break; 319 320 // 2 byte values 321 case DW_FORM_data2 : 322 case DW_FORM_ref2 : 323 form_size = 2; 324 break; 325 326 // 4 byte values 327 case DW_FORM_strp : 328 form_size = 4; 329 break; 330 331 case DW_FORM_data4 : 332 case DW_FORM_ref4 : 333 form_size = 4; 334 break; 335 336 // 8 byte values 337 case DW_FORM_data8 : 338 case DW_FORM_ref8 : 339 form_size = 8; 340 break; 341 342 // signed or unsigned LEB 128 values 343 case DW_FORM_sdata : 344 case DW_FORM_udata : 345 case DW_FORM_ref_udata : 346 debug_info_data.Skip_LEB128(&offset); 347 break; 348 349 case DW_FORM_indirect : 350 form = debug_info_data.GetULEB128(&offset); 351 form_is_indirect = true; 352 break; 353 354 default: 355 *offset_ptr = offset; 356 return false; 357 } 358 359 offset += form_size; 360 } while (form_is_indirect); 361 } 362 } 363 *offset_ptr = offset; 364 return true; 365 } 366 } 367 else 368 { 369 m_tag = 0; 370 m_has_children = false; 371 *offset_ptr = offset; 372 return true; // NULL debug tag entry 373 } 374 } 375 376 return false; 377} 378 379//---------------------------------------------------------------------- 380// DumpAncestry 381// 382// Dumps all of a debug information entries parents up until oldest and 383// all of it's attributes to the specified stream. 384//---------------------------------------------------------------------- 385void 386DWARFDebugInfoEntry::DumpAncestry 387( 388 SymbolFileDWARF* dwarf2Data, 389 const DWARFCompileUnit* cu, 390 const DWARFDebugInfoEntry* oldest, 391 Stream &s, 392 uint32_t recurse_depth 393) const 394{ 395 const DWARFDebugInfoEntry* parent = GetParent(); 396 if (parent && parent != oldest) 397 parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0); 398 Dump(dwarf2Data, cu, s, recurse_depth); 399} 400 401//---------------------------------------------------------------------- 402// Compare two DIE by comparing all their attributes values, and 403// following all DW_FORM_ref attributes and comparing their contents as 404// well (except for DW_AT_sibling attributes. 405// 406// DWARFDebugInfoEntry::CompareState compare_state; 407// int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true); 408//---------------------------------------------------------------------- 409//int 410//DWARFDebugInfoEntry::Compare 411//( 412// SymbolFileDWARF* dwarf2Data, 413// dw_offset_t a_die_offset, 414// dw_offset_t b_die_offset, 415// CompareState &compare_state, 416// bool compare_siblings, 417// bool compare_children 418//) 419//{ 420// if (a_die_offset == b_die_offset) 421// return 0; 422// 423// DWARFCompileUnitSP a_cu_sp; 424// DWARFCompileUnitSP b_cu_sp; 425// const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp); 426// const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp); 427// 428// return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children); 429//} 430// 431//int 432//DWARFDebugInfoEntry::Compare 433//( 434// SymbolFileDWARF* dwarf2Data, 435// DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 436// DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 437// CompareState &compare_state, 438// bool compare_siblings, 439// bool compare_children 440//) 441//{ 442// if (a_die == b_die) 443// return 0; 444// 445// if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset())) 446// { 447// // We are already comparing both of these types, so let 448// // compares complete for the real result 449// return 0; 450// } 451// 452// //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset()); 453// 454// // Do we have two valid DIEs? 455// if (a_die && b_die) 456// { 457// // Both DIE are valid 458// int result = 0; 459// 460// const dw_tag_t a_tag = a_die->Tag(); 461// const dw_tag_t b_tag = b_die->Tag(); 462// if (a_tag == 0 && b_tag == 0) 463// return 0; 464// 465// //printf(" comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag)); 466// 467// if (a_tag < b_tag) 468// return -1; 469// else if (a_tag > b_tag) 470// return 1; 471// 472// DWARFDebugInfoEntry::Attributes a_attrs; 473// DWARFDebugInfoEntry::Attributes b_attrs; 474// size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs); 475// size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs); 476// if (a_attr_count != b_attr_count) 477// { 478// a_attrs.RemoveAttribute(DW_AT_sibling); 479// b_attrs.RemoveAttribute(DW_AT_sibling); 480// } 481// 482// a_attr_count = a_attrs.Size(); 483// b_attr_count = b_attrs.Size(); 484// 485// DWARFFormValue a_form_value; 486// DWARFFormValue b_form_value; 487// 488// if (a_attr_count != b_attr_count) 489// { 490// uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration); 491// uint32_t a_name_index = UINT32_MAX; 492// uint32_t b_name_index = UINT32_MAX; 493// if (is_decl_index != UINT32_MAX) 494// { 495// if (a_attr_count == 2) 496// { 497// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); 498// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); 499// } 500// } 501// else 502// { 503// is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration); 504// if (is_decl_index != UINT32_MAX && a_attr_count == 2) 505// { 506// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); 507// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); 508// } 509// } 510// if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX) 511// { 512// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) && 513// b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value)) 514// { 515// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data()); 516// if (result == 0) 517// { 518// a_attr_count = b_attr_count = 0; 519// compare_children = false; 520// } 521// } 522// } 523// } 524// 525// if (a_attr_count < b_attr_count) 526// return -1; 527// if (a_attr_count > b_attr_count) 528// return 1; 529// 530// 531// // The number of attributes are the same... 532// if (a_attr_count > 0) 533// { 534// const DataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data(); 535// 536// uint32_t i; 537// for (i=0; i<a_attr_count; ++i) 538// { 539// const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i); 540// const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i); 541// //printf(" comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n", 542// // a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr), 543// // b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr)); 544// 545// if (a_attr < b_attr) 546// return -1; 547// else if (a_attr > b_attr) 548// return 1; 549// 550// switch (a_attr) 551// { 552// // Since we call a form of GetAttributes which inlines the 553// // attributes from DW_AT_abstract_origin and DW_AT_specification 554// // we don't care if their values mismatch... 555// case DW_AT_abstract_origin: 556// case DW_AT_specification: 557// case DW_AT_sibling: 558// case DW_AT_containing_type: 559// //printf(" action = IGNORE\n"); 560// result = 0; 561// break; // ignore 562// 563// default: 564// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) && 565// b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value)) 566// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr); 567// break; 568// } 569// 570// //printf("\t result = %i\n", result); 571// 572// if (result != 0) 573// { 574// // Attributes weren't equal, lets see if we care? 575// switch (a_attr) 576// { 577// case DW_AT_decl_file: 578// // TODO: add the ability to compare files in two different compile units 579// if (a_cu == b_cu) 580// { 581// //printf(" action = RETURN RESULT\n"); 582// return result; // Only return the compare results when the compile units are the same and the decl_file attributes can be compared 583// } 584// else 585// { 586// result = 0; 587// //printf(" action = IGNORE\n"); 588// } 589// break; 590// 591// default: 592// switch (a_attrs.FormAtIndex(i)) 593// { 594// case DW_FORM_ref1: 595// case DW_FORM_ref2: 596// case DW_FORM_ref4: 597// case DW_FORM_ref8: 598// case DW_FORM_ref_udata: 599// case DW_FORM_ref_addr: 600// //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)); 601// // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets... 602// result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true); 603// if (result != 0) 604// return result; 605// break; 606// 607// default: 608// // We do care that they were different, return this result... 609// //printf(" action = RETURN RESULT\n"); 610// return result; 611// } 612// } 613// } 614// } 615// } 616// //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)); 617// 618// if (compare_children) 619// { 620// bool a_has_children = a_die->HasChildren(); 621// bool b_has_children = b_die->HasChildren(); 622// if (a_has_children == b_has_children) 623// { 624// // Both either have kids or don't 625// if (a_has_children) 626// result = Compare( dwarf2Data, 627// a_cu, a_die->GetFirstChild(), 628// b_cu, b_die->GetFirstChild(), 629// compare_state, true, compare_children); 630// else 631// result = 0; 632// } 633// else if (!a_has_children) 634// result = -1; // A doesn't have kids, but B does 635// else 636// result = 1; // A has kids, but B doesn't 637// } 638// 639// if (compare_siblings) 640// { 641// result = Compare( dwarf2Data, 642// a_cu, a_die->GetSibling(), 643// b_cu, b_die->GetSibling(), 644// compare_state, true, compare_children); 645// } 646// 647// return result; 648// } 649// 650// if (a_die == NULL) 651// return -1; // a_die is NULL, yet b_die is non-NULL 652// else 653// return 1; // a_die is non-NULL, yet b_die is NULL 654// 655//} 656// 657// 658//int 659//DWARFDebugInfoEntry::Compare 660//( 661// SymbolFileDWARF* dwarf2Data, 662// const DWARFCompileUnit* cu_a, 663// const DWARFDebugInfoEntry* die_a, 664// const DWARFCompileUnit* cu_a, 665// const DWARFDebugInfoEntry* die_b, 666// CompareState &compare_state 667//) 668//{ 669//} 670 671//---------------------------------------------------------------------- 672// GetDIENamesAndRanges 673// 674// Gets the valid address ranges for a given DIE by looking for a 675// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges 676// attributes. 677//---------------------------------------------------------------------- 678bool 679DWARFDebugInfoEntry::GetDIENamesAndRanges 680( 681 SymbolFileDWARF* dwarf2Data, 682 const DWARFCompileUnit* cu, 683 const char * &name, 684 const char * &mangled, 685 DWARFDebugRanges::RangeList& ranges, 686 int& decl_file, 687 int& decl_line, 688 int& decl_column, 689 int& call_file, 690 int& call_line, 691 int& call_column, 692 DWARFExpression *frame_base 693) const 694{ 695 if (dwarf2Data == NULL) 696 return false; 697 698 dw_addr_t lo_pc = DW_INVALID_ADDRESS; 699 dw_addr_t hi_pc = DW_INVALID_ADDRESS; 700 std::vector<dw_offset_t> die_offsets; 701 bool set_frame_base_loclist_addr = false; 702 703 const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu); 704 705 if (abbrevDecl) 706 { 707 const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 708 uint32_t offset = m_offset; 709 710 if (!debug_info_data.ValidOffset(offset)) 711 return false; 712 713 // Skip the abbreviation code 714 debug_info_data.Skip_LEB128(&offset); 715 716 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 717 uint32_t i; 718 dw_attr_t attr; 719 dw_form_t form; 720 for (i=0; i<numAttributes; ++i) 721 { 722 abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 723 DWARFFormValue form_value(form); 724 if (form_value.ExtractValue(debug_info_data, &offset, cu)) 725 { 726 switch (attr) 727 { 728 case DW_AT_low_pc: 729 case DW_AT_entry_pc: 730 lo_pc = form_value.Unsigned(); 731 break; 732 733 case DW_AT_high_pc: 734 hi_pc = form_value.Unsigned(); 735 break; 736 737 case DW_AT_ranges: 738 { 739 const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); 740 debug_ranges->FindRanges(form_value.Unsigned(), ranges); 741 // All DW_AT_ranges are relative to the base address of the 742 // compile unit. We add the compile unit base address to make 743 // sure all the addresses are properly fixed up. 744 ranges.Slide(cu->GetBaseAddress()); 745 } 746 break; 747 748 case DW_AT_name: 749 if (name == NULL) 750 name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 751 break; 752 753 case DW_AT_MIPS_linkage_name: 754 if (mangled == NULL) 755 mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 756 break; 757 758 case DW_AT_abstract_origin: 759 die_offsets.push_back(form_value.Reference(cu)); 760 break; 761 762 case DW_AT_specification: 763 die_offsets.push_back(form_value.Reference(cu)); 764 break; 765 766 case DW_AT_decl_file: 767 if (decl_file == 0) 768 decl_file = form_value.Unsigned(); 769 break; 770 771 case DW_AT_decl_line: 772 if (decl_line == 0) 773 decl_line = form_value.Unsigned(); 774 break; 775 776 case DW_AT_decl_column: 777 if (decl_column == 0) 778 decl_column = form_value.Unsigned(); 779 break; 780 781 case DW_AT_call_file: 782 if (call_file == 0) 783 call_file = form_value.Unsigned(); 784 break; 785 786 case DW_AT_call_line: 787 if (call_line == 0) 788 call_line = form_value.Unsigned(); 789 break; 790 791 case DW_AT_call_column: 792 if (call_column == 0) 793 call_column = form_value.Unsigned(); 794 break; 795 796 case DW_AT_frame_base: 797 if (frame_base) 798 { 799 if (form_value.BlockData()) 800 { 801 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 802 uint32_t block_length = form_value.Unsigned(); 803 frame_base->SetOpcodeData(debug_info_data, block_offset, block_length); 804 } 805 else 806 { 807 const DataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data(); 808 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 809 810 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 811 if (loc_list_length > 0) 812 { 813 frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); 814 if (lo_pc != DW_INVALID_ADDRESS) 815 { 816 assert (lo_pc >= cu->GetBaseAddress()); 817 frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress()); 818 } 819 else 820 { 821 set_frame_base_loclist_addr = true; 822 } 823 } 824 } 825 } 826 break; 827 828 default: 829 break; 830 } 831 } 832 } 833 } 834 835 if (ranges.IsEmpty()) 836 { 837 if (lo_pc != DW_INVALID_ADDRESS) 838 { 839 if (hi_pc != DW_INVALID_ADDRESS && hi_pc > lo_pc) 840 ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc)); 841 else 842 ranges.Append(DWARFDebugRanges::Range (lo_pc, 0)); 843 } 844 } 845 846 if (set_frame_base_loclist_addr) 847 { 848 dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); 849 assert (lowest_range_pc >= cu->GetBaseAddress()); 850 frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress()); 851 } 852 853 if (ranges.IsEmpty() || name == NULL || mangled == NULL) 854 { 855 std::vector<dw_offset_t>::const_iterator pos; 856 std::vector<dw_offset_t>::const_iterator end = die_offsets.end(); 857 for (pos = die_offsets.begin(); pos != end; ++pos) 858 { 859 DWARFCompileUnitSP cu_sp_ptr; 860 const DWARFDebugInfoEntry* die = NULL; 861 dw_offset_t die_offset = *pos; 862 if (die_offset != DW_INVALID_OFFSET) 863 { 864 die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr); 865 if (die) 866 die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column); 867 } 868 } 869 } 870 return !ranges.IsEmpty(); 871} 872 873//---------------------------------------------------------------------- 874// Dump 875// 876// Dumps a debug information entry and all of it's attributes to the 877// specified stream. 878//---------------------------------------------------------------------- 879void 880DWARFDebugInfoEntry::Dump 881( 882 SymbolFileDWARF* dwarf2Data, 883 const DWARFCompileUnit* cu, 884 Stream &s, 885 uint32_t recurse_depth 886) const 887{ 888 const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 889 uint32_t offset = m_offset; 890 891 if (debug_info_data.ValidOffset(offset)) 892 { 893 dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset); 894 895 s.Printf("\n0x%8.8x: ", m_offset); 896 s.Indent(); 897 if (abbrCode) 898 { 899 const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu); 900 901 if (abbrevDecl) 902 { 903 s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); 904 s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' '); 905 906 // Dump all data in the .debug_info for the attributes 907 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 908 uint32_t i; 909 dw_attr_t attr; 910 dw_form_t form; 911 for (i=0; i<numAttributes; ++i) 912 { 913 abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); 914 915 DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form); 916 } 917 918 const DWARFDebugInfoEntry* child = GetFirstChild(); 919 if (recurse_depth > 0 && child) 920 { 921 s.IndentMore(); 922 923 while (child) 924 { 925 child->Dump(dwarf2Data, cu, s, recurse_depth-1); 926 child = child->GetSibling(); 927 } 928 s.IndentLess(); 929 } 930 } 931 else 932 s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode); 933 } 934 else 935 { 936 s.Printf( "NULL\n"); 937 } 938 } 939} 940 941void 942DWARFDebugInfoEntry::DumpLocation 943( 944 SymbolFileDWARF* dwarf2Data, 945 DWARFCompileUnit* cu, 946 Stream &s 947) const 948{ 949 const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly(); 950 const char *cu_name = NULL; 951 if (cu_die != NULL) 952 cu_name = cu_die->GetName (dwarf2Data, cu); 953 const char *obj_file_name = NULL; 954 ObjectFile *obj_file = dwarf2Data->GetObjectFile(); 955 if (obj_file) 956 obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString(); 957 const char *die_name = GetName (dwarf2Data, cu); 958 s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", 959 cu->GetOffset(), 960 GetOffset(), 961 die_name ? die_name : "", 962 cu_name ? cu_name : "<NULL>", 963 obj_file_name ? obj_file_name : "<NULL>"); 964} 965 966//---------------------------------------------------------------------- 967// DumpAttribute 968// 969// Dumps a debug information entry attribute along with it's form. Any 970// special display of attributes is done (disassemble location lists, 971// show enumeration values for attributes, etc). 972//---------------------------------------------------------------------- 973void 974DWARFDebugInfoEntry::DumpAttribute 975( 976 SymbolFileDWARF* dwarf2Data, 977 const DWARFCompileUnit* cu, 978 const DataExtractor& debug_info_data, 979 uint32_t* offset_ptr, 980 Stream &s, 981 dw_attr_t attr, 982 dw_form_t form 983) 984{ 985 bool verbose = s.GetVerbose(); 986 bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); 987 const DataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL; 988 if (verbose) 989 s.Offset (*offset_ptr); 990 else 991 s.Printf (" "); 992 s.Indent(DW_AT_value_to_name(attr)); 993 994 if (show_form) 995 { 996 s.Printf( "[%s", DW_FORM_value_to_name(form)); 997 } 998 999 DWARFFormValue form_value(form); 1000 1001 if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu)) 1002 return; 1003 1004 if (show_form) 1005 { 1006 if (form == DW_FORM_indirect) 1007 { 1008 s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form())); 1009 } 1010 1011 s.PutCString("] "); 1012 } 1013 1014 s.PutCString("( "); 1015 1016 // Always dump form value if verbose is enabled 1017 if (verbose) 1018 { 1019 form_value.Dump(s, debug_str_data, cu); 1020 } 1021 1022 1023 // Check to see if we have any special attribute formatters 1024 switch (attr) 1025 { 1026 case DW_AT_stmt_list: 1027 if ( verbose ) s.PutCString(" ( "); 1028 s.Printf( "0x%8.8llx", form_value.Unsigned()); 1029 if ( verbose ) s.PutCString(" )"); 1030 break; 1031 1032 case DW_AT_language: 1033 if ( verbose ) s.PutCString(" ( "); 1034 s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); 1035 if ( verbose ) s.PutCString(" )"); 1036 break; 1037 1038 case DW_AT_encoding: 1039 if ( verbose ) s.PutCString(" ( "); 1040 s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); 1041 if ( verbose ) s.PutCString(" )"); 1042 break; 1043 1044 case DW_AT_frame_base: 1045 case DW_AT_location: 1046 case DW_AT_data_member_location: 1047 { 1048 const uint8_t* blockData = form_value.BlockData(); 1049 if (blockData) 1050 { 1051 if (!verbose) 1052 form_value.Dump(s, debug_str_data, cu); 1053 1054 // Location description is inlined in data in the form value 1055 DataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); 1056 if ( verbose ) s.PutCString(" ( "); 1057 print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false); 1058 if ( verbose ) s.PutCString(" )"); 1059 } 1060 else 1061 { 1062 // We have a location list offset as the value that is 1063 // the offset into the .debug_loc section that describes 1064 // the value over it's lifetime 1065 uint64_t debug_loc_offset = form_value.Unsigned(); 1066 if (dwarf2Data) 1067 { 1068 if ( !verbose ) 1069 form_value.Dump(s, debug_str_data, cu); 1070 DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); 1071 } 1072 else 1073 { 1074 if ( !verbose ) 1075 form_value.Dump(s, NULL, cu); 1076 } 1077 } 1078 } 1079 break; 1080 1081 case DW_AT_abstract_origin: 1082 case DW_AT_specification: 1083 { 1084 uint64_t abstract_die_offset = form_value.Reference(cu); 1085 form_value.Dump(s, debug_str_data, cu); 1086 // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; 1087 if ( verbose ) s.PutCString(" ( "); 1088 GetName(dwarf2Data, cu, abstract_die_offset, s); 1089 if ( verbose ) s.PutCString(" )"); 1090 } 1091 break; 1092 1093 case DW_AT_type: 1094 { 1095 uint64_t type_die_offset = form_value.Reference(cu); 1096 if (!verbose) 1097 form_value.Dump(s, debug_str_data, cu); 1098 s.PutCString(" ( "); 1099 AppendTypeName(dwarf2Data, cu, type_die_offset, s); 1100 s.PutCString(" )"); 1101 } 1102 break; 1103 1104 case DW_AT_ranges: 1105 { 1106 if ( !verbose ) 1107 form_value.Dump(s, debug_str_data, cu); 1108 uint32_t ranges_offset = form_value.Unsigned(); 1109 dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; 1110 DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr); 1111 } 1112 break; 1113 1114 default: 1115 if ( !verbose ) 1116 form_value.Dump(s, debug_str_data, cu); 1117 break; 1118 } 1119 1120 s.PutCString(" )\n"); 1121} 1122 1123//---------------------------------------------------------------------- 1124// Get all attribute values for a given DIE, including following any 1125// specification or abstract origin attributes and including those in 1126// the results. Any duplicate attributes will have the first instance 1127// take precedence (this can happen for declaration attributes). 1128//---------------------------------------------------------------------- 1129size_t 1130DWARFDebugInfoEntry::GetAttributes 1131( 1132 SymbolFileDWARF* dwarf2Data, 1133 const DWARFCompileUnit* cu, 1134 const uint8_t *fixed_form_sizes, 1135 DWARFDebugInfoEntry::Attributes& attributes, 1136 uint32_t curr_depth 1137) const 1138{ 1139 const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu); 1140 1141 if (abbrevDecl) 1142 { 1143 if (fixed_form_sizes == NULL) 1144 fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize()); 1145 uint32_t offset = GetOffset(); 1146 const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 1147 1148 // Skip the abbreviation code so we are at the data for the attributes 1149 debug_info_data.Skip_LEB128(&offset); 1150 1151 const uint32_t num_attributes = abbrevDecl->NumAttributes(); 1152 uint32_t i; 1153 dw_attr_t attr; 1154 dw_form_t form; 1155 DWARFFormValue form_value; 1156 for (i=0; i<num_attributes; ++i) 1157 { 1158 abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form); 1159 1160 // If we are tracking down DW_AT_specification or DW_AT_abstract_origin 1161 // attributes, the depth will be non-zero. We need to omit certain 1162 // attributes that don't make sense. 1163 switch (attr) 1164 { 1165 case DW_AT_sibling: 1166 case DW_AT_declaration: 1167 if (curr_depth > 0) 1168 { 1169 // This attribute doesn't make sense when combined with 1170 // the DIE that references this DIE. We know a DIE is 1171 // referencing this DIE because curr_depth is not zero 1172 break; 1173 } 1174 // Fall through... 1175 default: 1176 attributes.Append(cu, offset, attr, form); 1177 break; 1178 } 1179 1180 if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) 1181 { 1182 form_value.SetForm(form); 1183 if (form_value.ExtractValue(debug_info_data, &offset, cu)) 1184 { 1185 const DWARFDebugInfoEntry* die = NULL; 1186 dw_offset_t die_offset = form_value.Reference(cu); 1187 if (cu->ContainsDIEOffset(die_offset)) 1188 { 1189 die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset); 1190 if (die) 1191 die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1); 1192 } 1193 else 1194 { 1195 DWARFCompileUnitSP cu_sp_ptr; 1196 die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr); 1197 if (die) 1198 die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1); 1199 } 1200 } 1201 } 1202 else 1203 { 1204 const uint8_t fixed_skip_size = fixed_form_sizes [form]; 1205 if (fixed_skip_size) 1206 offset += fixed_skip_size; 1207 else 1208 DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); 1209 } 1210 } 1211 } 1212 else 1213 { 1214 attributes.Clear(); 1215 } 1216 return attributes.Size(); 1217 1218} 1219 1220//---------------------------------------------------------------------- 1221// GetAttributeValue 1222// 1223// Get the value of an attribute and return the .debug_info offset of the 1224// attribute if it was properly extracted into form_value, or zero 1225// if we fail since an offset of zero is invalid for an attribute (it 1226// would be a compile unit header). 1227//---------------------------------------------------------------------- 1228dw_offset_t 1229DWARFDebugInfoEntry::GetAttributeValue 1230( 1231 SymbolFileDWARF* dwarf2Data, 1232 const DWARFCompileUnit* cu, 1233 const dw_attr_t attr, 1234 DWARFFormValue& form_value, 1235 dw_offset_t* end_attr_offset_ptr 1236) const 1237{ 1238 const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(cu); 1239 1240 if (abbrevDecl) 1241 { 1242 uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); 1243 1244 if (attr_idx != DW_INVALID_INDEX) 1245 { 1246 uint32_t offset = GetOffset(); 1247 1248 const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); 1249 1250 // Skip the abbreviation code so we are at the data for the attributes 1251 debug_info_data.Skip_LEB128(&offset); 1252 1253 uint32_t idx=0; 1254 while (idx<attr_idx) 1255 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu); 1256 1257 const dw_offset_t attr_offset = offset; 1258 form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); 1259 if (form_value.ExtractValue(debug_info_data, &offset, cu)) 1260 { 1261 if (end_attr_offset_ptr) 1262 *end_attr_offset_ptr = offset; 1263 return attr_offset; 1264 } 1265 } 1266 } 1267 1268 return 0; 1269} 1270 1271//---------------------------------------------------------------------- 1272// GetAttributeValueAsString 1273// 1274// Get the value of an attribute as a string return it. The resulting 1275// pointer to the string data exists within the supplied SymbolFileDWARF 1276// and will only be available as long as the SymbolFileDWARF is still around 1277// and it's content doesn't change. 1278//---------------------------------------------------------------------- 1279const char* 1280DWARFDebugInfoEntry::GetAttributeValueAsString 1281( 1282 SymbolFileDWARF* dwarf2Data, 1283 const DWARFCompileUnit* cu, 1284 const dw_attr_t attr, 1285 const char* fail_value) const 1286{ 1287 DWARFFormValue form_value; 1288 if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1289 return form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1290 return fail_value; 1291} 1292 1293//---------------------------------------------------------------------- 1294// GetAttributeValueAsUnsigned 1295// 1296// Get the value of an attribute as unsigned and return it. 1297//---------------------------------------------------------------------- 1298uint64_t 1299DWARFDebugInfoEntry::GetAttributeValueAsUnsigned 1300( 1301 SymbolFileDWARF* dwarf2Data, 1302 const DWARFCompileUnit* cu, 1303 const dw_attr_t attr, 1304 uint64_t fail_value 1305) const 1306{ 1307 DWARFFormValue form_value; 1308 if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1309 return form_value.Unsigned(); 1310 return fail_value; 1311} 1312 1313//---------------------------------------------------------------------- 1314// GetAttributeValueAsSigned 1315// 1316// Get the value of an attribute a signed value and return it. 1317//---------------------------------------------------------------------- 1318int64_t 1319DWARFDebugInfoEntry::GetAttributeValueAsSigned 1320( 1321 SymbolFileDWARF* dwarf2Data, 1322 const DWARFCompileUnit* cu, 1323 const dw_attr_t attr, 1324 int64_t fail_value 1325) const 1326{ 1327 DWARFFormValue form_value; 1328 if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1329 return form_value.Signed(); 1330 return fail_value; 1331} 1332 1333//---------------------------------------------------------------------- 1334// GetAttributeValueAsReference 1335// 1336// Get the value of an attribute as reference and fix up and compile 1337// unit relative offsets as needed. 1338//---------------------------------------------------------------------- 1339uint64_t 1340DWARFDebugInfoEntry::GetAttributeValueAsReference 1341( 1342 SymbolFileDWARF* dwarf2Data, 1343 const DWARFCompileUnit* cu, 1344 const dw_attr_t attr, 1345 uint64_t fail_value 1346) const 1347{ 1348 DWARFFormValue form_value; 1349 if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) 1350 return form_value.Reference(cu); 1351 return fail_value; 1352} 1353 1354//---------------------------------------------------------------------- 1355// GetAttributeValueAsLocation 1356// 1357// Get the value of an attribute as reference and fix up and compile 1358// unit relative offsets as needed. 1359//---------------------------------------------------------------------- 1360dw_offset_t 1361DWARFDebugInfoEntry::GetAttributeValueAsLocation 1362( 1363 SymbolFileDWARF* dwarf2Data, 1364 const DWARFCompileUnit* cu, 1365 const dw_attr_t attr, 1366 DataExtractor& location_data, 1367 uint32_t &block_size 1368) const 1369{ 1370 block_size = 0; 1371 DWARFFormValue form_value; 1372 1373 // Empty out data in case we don't find anything 1374 location_data.Clear(); 1375 dw_offset_t end_addr_offset = DW_INVALID_OFFSET; 1376 const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset); 1377 if (attr_offset) 1378 { 1379 const uint8_t* blockData = form_value.BlockData(); 1380 if (blockData) 1381 { 1382 // We have an inlined location list in the .debug_info section 1383 const DataExtractor& debug_info = dwarf2Data->get_debug_info_data(); 1384 dw_offset_t block_offset = blockData - debug_info.GetDataStart(); 1385 block_size = (end_addr_offset - attr_offset) - form_value.Unsigned(); 1386 location_data.SetData(debug_info, block_offset, block_size); 1387 } 1388 else 1389 { 1390 // We have a location list offset as the value that is 1391 // the offset into the .debug_loc section that describes 1392 // the value over it's lifetime 1393 dw_offset_t debug_loc_offset = form_value.Unsigned(); 1394 if (dwarf2Data) 1395 { 1396 assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize()); 1397 return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data); 1398 } 1399 } 1400 } 1401 return attr_offset; 1402} 1403 1404//---------------------------------------------------------------------- 1405// GetName 1406// 1407// Get value of the DW_AT_name attribute and return it if one exists, 1408// else return NULL. 1409//---------------------------------------------------------------------- 1410const char* 1411DWARFDebugInfoEntry::GetName 1412( 1413 SymbolFileDWARF* dwarf2Data, 1414 const DWARFCompileUnit* cu 1415) const 1416{ 1417 DWARFFormValue form_value; 1418 if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1419 return form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1420 return NULL; 1421} 1422 1423 1424//---------------------------------------------------------------------- 1425// GetMangledName 1426// 1427// Get value of the DW_AT_MIPS_linkage_name attribute and return it if 1428// one exists, else return the value of the DW_AT_name attribute 1429//---------------------------------------------------------------------- 1430const char* 1431DWARFDebugInfoEntry::GetMangledName 1432( 1433 SymbolFileDWARF* dwarf2Data, 1434 const DWARFCompileUnit* cu, 1435 bool substitute_name_allowed 1436) const 1437{ 1438 const char* name = NULL; 1439 DWARFFormValue form_value; 1440 1441 if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) 1442 name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1443 1444 if (substitute_name_allowed && name == NULL) 1445 { 1446 if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1447 name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1448 } 1449 return name; 1450} 1451 1452 1453//---------------------------------------------------------------------- 1454// GetPubname 1455// 1456// Get value the name for a DIE as it should appear for a 1457// .debug_pubnames or .debug_pubtypes section. 1458//---------------------------------------------------------------------- 1459const char* 1460DWARFDebugInfoEntry::GetPubname 1461( 1462 SymbolFileDWARF* dwarf2Data, 1463 const DWARFCompileUnit* cu 1464) const 1465{ 1466 const char* name = NULL; 1467 DWARFFormValue form_value; 1468 1469 if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) 1470 name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1471 else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1472 name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1473 else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) 1474 { 1475 // The specification DIE may be in another compile unit so we need 1476 // to get a die and its compile unit. 1477 DWARFCompileUnitSP cu_sp_ptr; 1478 const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr); 1479 if (die) 1480 return die->GetPubname(dwarf2Data, cu_sp_ptr.get()); 1481 } 1482 return name; 1483} 1484 1485 1486//---------------------------------------------------------------------- 1487// GetName 1488// 1489// Get value of the DW_AT_name attribute for a debug information entry 1490// that exists at offset "die_offset" and place that value into the 1491// supplied stream object. If the DIE is a NULL object "NULL" is placed 1492// into the stream, and if no DW_AT_name attribute exists for the DIE 1493// then nothing is printed. 1494//---------------------------------------------------------------------- 1495bool 1496DWARFDebugInfoEntry::GetName 1497( 1498 SymbolFileDWARF* dwarf2Data, 1499 const DWARFCompileUnit* cu, 1500 const uint32_t die_offset, 1501 Stream &s 1502) 1503{ 1504 DWARFDebugInfoEntry die; 1505 uint32_t offset = die_offset; 1506 if (die.Extract(dwarf2Data, cu, &offset)) 1507 { 1508 if (die.IsNULL()) 1509 { 1510 s.PutCString("NULL"); 1511 return true; 1512 } 1513 else 1514 { 1515 DWARFFormValue form_value; 1516 if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1517 { 1518 const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1519 if (name) 1520 { 1521 s.PutCString(name); 1522 return true; 1523 } 1524 } 1525 } 1526 } 1527 return false; 1528} 1529 1530//---------------------------------------------------------------------- 1531// AppendTypeName 1532// 1533// Follows the type name definition down through all needed tags to 1534// end up with a fully qualified type name and dump the results to 1535// the supplied stream. This is used to show the name of types given 1536// a type identifier. 1537//---------------------------------------------------------------------- 1538bool 1539DWARFDebugInfoEntry::AppendTypeName 1540( 1541 SymbolFileDWARF* dwarf2Data, 1542 const DWARFCompileUnit* cu, 1543 const uint32_t die_offset, 1544 Stream &s 1545) 1546{ 1547 DWARFDebugInfoEntry die; 1548 uint32_t offset = die_offset; 1549 if (die.Extract(dwarf2Data, cu, &offset)) 1550 { 1551 if (die.IsNULL()) 1552 { 1553 s.PutCString("NULL"); 1554 return true; 1555 } 1556 else 1557 { 1558 const char* name = die.GetPubname(dwarf2Data, cu); 1559 // if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) 1560 // name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); 1561 if (name) 1562 s.PutCString(name); 1563 else 1564 { 1565 bool result = true; 1566 const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(cu); 1567 1568 switch (abbrevDecl->Tag()) 1569 { 1570 case DW_TAG_array_type: break; // print out a "[]" after printing the full type of the element below 1571 case DW_TAG_base_type: s.PutCString("base "); break; 1572 case DW_TAG_class_type: s.PutCString("class "); break; 1573 case DW_TAG_const_type: s.PutCString("const "); break; 1574 case DW_TAG_enumeration_type: s.PutCString("enum "); break; 1575 case DW_TAG_file_type: s.PutCString("file "); break; 1576 case DW_TAG_interface_type: s.PutCString("interface "); break; 1577 case DW_TAG_packed_type: s.PutCString("packed "); break; 1578 case DW_TAG_pointer_type: break; // print out a '*' after printing the full type below 1579 case DW_TAG_ptr_to_member_type: break; // print out a '*' after printing the full type below 1580 case DW_TAG_reference_type: break; // print out a '&' after printing the full type below 1581 case DW_TAG_restrict_type: s.PutCString("restrict "); break; 1582 case DW_TAG_set_type: s.PutCString("set "); break; 1583 case DW_TAG_shared_type: s.PutCString("shared "); break; 1584 case DW_TAG_string_type: s.PutCString("string "); break; 1585 case DW_TAG_structure_type: s.PutCString("struct "); break; 1586 case DW_TAG_subrange_type: s.PutCString("subrange "); break; 1587 case DW_TAG_subroutine_type: s.PutCString("function "); break; 1588 case DW_TAG_thrown_type: s.PutCString("thrown "); break; 1589 case DW_TAG_union_type: s.PutCString("union "); break; 1590 case DW_TAG_unspecified_type: s.PutCString("unspecified "); break; 1591 case DW_TAG_volatile_type: s.PutCString("volatile "); break; 1592 default: 1593 return false; 1594 } 1595 1596 // Follow the DW_AT_type if possible 1597 DWARFFormValue form_value; 1598 if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) 1599 { 1600 uint64_t next_die_offset = form_value.Reference(cu); 1601 result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); 1602 } 1603 1604 switch (abbrevDecl->Tag()) 1605 { 1606 case DW_TAG_array_type: s.PutCString("[]"); break; 1607 case DW_TAG_pointer_type: s.PutChar('*'); break; 1608 case DW_TAG_ptr_to_member_type: s.PutChar('*'); break; 1609 case DW_TAG_reference_type: s.PutChar('&'); break; 1610 default: 1611 break; 1612 } 1613 return result; 1614 } 1615 } 1616 } 1617 return false; 1618} 1619 1620bool 1621DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const 1622{ 1623 if (die) 1624 { 1625 const dw_offset_t die_offset = die->GetOffset(); 1626 if (die_offset > GetOffset()) 1627 { 1628 const DWARFDebugInfoEntry *sibling = GetSibling(); 1629 assert (sibling); // TODO: take this out 1630 if (sibling) 1631 return die_offset < sibling->GetOffset(); 1632 } 1633 } 1634 return false; 1635} 1636 1637//---------------------------------------------------------------------- 1638// BuildAddressRangeTable 1639//---------------------------------------------------------------------- 1640void 1641DWARFDebugInfoEntry::BuildAddressRangeTable 1642( 1643 SymbolFileDWARF* dwarf2Data, 1644 const DWARFCompileUnit* cu, 1645 DWARFDebugAranges* debug_aranges 1646) const 1647{ 1648 if (m_tag) 1649 { 1650 if (m_tag == DW_TAG_subprogram) 1651 { 1652 dw_addr_t hi_pc = DW_INVALID_ADDRESS; 1653 dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 1654 if (lo_pc != DW_INVALID_ADDRESS) 1655 hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); 1656 if (hi_pc != DW_INVALID_ADDRESS) 1657 { 1658 /// 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); 1659 debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc); 1660 } 1661 } 1662 1663 1664 const DWARFDebugInfoEntry* child = GetFirstChild(); 1665 while (child) 1666 { 1667 child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges); 1668 child = child->GetSibling(); 1669 } 1670 } 1671} 1672 1673//---------------------------------------------------------------------- 1674// BuildFunctionAddressRangeTable 1675// 1676// This function is very similar to the BuildAddressRangeTable function 1677// except that the actual DIE offset for the function is placed in the 1678// table instead of the compile unit offset (which is the way the 1679// standard .debug_aranges section does it). 1680//---------------------------------------------------------------------- 1681void 1682DWARFDebugInfoEntry::BuildFunctionAddressRangeTable 1683( 1684 SymbolFileDWARF* dwarf2Data, 1685 const DWARFCompileUnit* cu, 1686 DWARFDebugAranges* debug_aranges 1687) const 1688{ 1689 if (m_tag) 1690 { 1691 if (m_tag == DW_TAG_subprogram) 1692 { 1693 dw_addr_t hi_pc = DW_INVALID_ADDRESS; 1694 dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 1695 if (lo_pc != DW_INVALID_ADDRESS) 1696 hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); 1697 if (hi_pc != DW_INVALID_ADDRESS) 1698 { 1699 // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY 1700 debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc); 1701 } 1702 } 1703 1704 const DWARFDebugInfoEntry* child = GetFirstChild(); 1705 while (child) 1706 { 1707 child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges); 1708 child = child->GetSibling(); 1709 } 1710 } 1711} 1712 1713 1714//---------------------------------------------------------------------- 1715// LookupAddress 1716//---------------------------------------------------------------------- 1717bool 1718DWARFDebugInfoEntry::LookupAddress 1719( 1720 const dw_addr_t address, 1721 SymbolFileDWARF* dwarf2Data, 1722 const DWARFCompileUnit* cu, 1723 DWARFDebugInfoEntry** function_die, 1724 DWARFDebugInfoEntry** block_die 1725) 1726{ 1727 bool found_address = false; 1728 if (m_tag) 1729 { 1730 bool check_children = false; 1731 bool match_addr_range = false; 1732 // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address); 1733 switch (m_tag) 1734 { 1735 case DW_TAG_array_type : break; 1736 case DW_TAG_class_type : check_children = true; break; 1737 case DW_TAG_entry_point : break; 1738 case DW_TAG_enumeration_type : break; 1739 case DW_TAG_formal_parameter : break; 1740 case DW_TAG_imported_declaration : break; 1741 case DW_TAG_label : break; 1742 case DW_TAG_lexical_block : check_children = true; match_addr_range = true; break; 1743 case DW_TAG_member : break; 1744 case DW_TAG_pointer_type : break; 1745 case DW_TAG_reference_type : break; 1746 case DW_TAG_compile_unit : match_addr_range = true; break; 1747 case DW_TAG_string_type : break; 1748 case DW_TAG_structure_type : check_children = true; break; 1749 case DW_TAG_subroutine_type : break; 1750 case DW_TAG_typedef : break; 1751 case DW_TAG_union_type : break; 1752 case DW_TAG_unspecified_parameters : break; 1753 case DW_TAG_variant : break; 1754 case DW_TAG_common_block : check_children = true; break; 1755 case DW_TAG_common_inclusion : break; 1756 case DW_TAG_inheritance : break; 1757 case DW_TAG_inlined_subroutine : check_children = true; match_addr_range = true; break; 1758 case DW_TAG_module : match_addr_range = true; break; 1759 case DW_TAG_ptr_to_member_type : break; 1760 case DW_TAG_set_type : break; 1761 case DW_TAG_subrange_type : break; 1762 case DW_TAG_with_stmt : break; 1763 case DW_TAG_access_declaration : break; 1764 case DW_TAG_base_type : break; 1765 case DW_TAG_catch_block : match_addr_range = true; break; 1766 case DW_TAG_const_type : break; 1767 case DW_TAG_constant : break; 1768 case DW_TAG_enumerator : break; 1769 case DW_TAG_file_type : break; 1770 case DW_TAG_friend : break; 1771 case DW_TAG_namelist : break; 1772 case DW_TAG_namelist_item : break; 1773 case DW_TAG_packed_type : break; 1774 case DW_TAG_subprogram : match_addr_range = true; break; 1775 case DW_TAG_template_type_parameter : break; 1776 case DW_TAG_template_value_parameter : break; 1777 case DW_TAG_thrown_type : break; 1778 case DW_TAG_try_block : match_addr_range = true; break; 1779 case DW_TAG_variant_part : break; 1780 case DW_TAG_variable : break; 1781 case DW_TAG_volatile_type : break; 1782 case DW_TAG_dwarf_procedure : break; 1783 case DW_TAG_restrict_type : break; 1784 case DW_TAG_interface_type : break; 1785 case DW_TAG_namespace : check_children = true; break; 1786 case DW_TAG_imported_module : break; 1787 case DW_TAG_unspecified_type : break; 1788 case DW_TAG_partial_unit : break; 1789 case DW_TAG_imported_unit : break; 1790 case DW_TAG_shared_type : break; 1791 default: break; 1792 } 1793 1794 if (match_addr_range) 1795 { 1796 dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 1797 if (lo_pc != DW_INVALID_ADDRESS) 1798 { 1799 dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); 1800 if (hi_pc != DW_INVALID_ADDRESS) 1801 { 1802 // 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); 1803 if ((lo_pc <= address) && (address < hi_pc)) 1804 { 1805 found_address = true; 1806 // puts("***MATCH***"); 1807 switch (m_tag) 1808 { 1809 case DW_TAG_compile_unit: // File 1810 check_children = ((function_die != NULL) || (block_die != NULL)); 1811 break; 1812 1813 case DW_TAG_subprogram: // Function 1814 if (function_die) 1815 *function_die = this; 1816 check_children = (block_die != NULL); 1817 break; 1818 1819 case DW_TAG_inlined_subroutine: // Inlined Function 1820 case DW_TAG_lexical_block: // Block { } in code 1821 if (block_die) 1822 { 1823 *block_die = this; 1824 check_children = true; 1825 } 1826 break; 1827 1828 default: 1829 check_children = true; 1830 break; 1831 } 1832 } 1833 } 1834 else 1835 { // compile units may not have a valid high/low pc when there 1836 // are address gaps in subroutines so we must always search 1837 // if there is no valid high and low PC 1838 check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL)); 1839 } 1840 } 1841 else 1842 { 1843 dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); 1844 if (debug_ranges_offset != DW_INVALID_OFFSET) 1845 { 1846 DWARFDebugRanges::RangeList ranges; 1847 DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); 1848 debug_ranges->FindRanges(debug_ranges_offset, ranges); 1849 // All DW_AT_ranges are relative to the base address of the 1850 // compile unit. We add the compile unit base address to make 1851 // sure all the addresses are properly fixed up. 1852 ranges.Slide (cu->GetBaseAddress()); 1853 if (ranges.FindEntryThatContains(address)) 1854 { 1855 found_address = true; 1856 // puts("***MATCH***"); 1857 switch (m_tag) 1858 { 1859 case DW_TAG_compile_unit: // File 1860 check_children = ((function_die != NULL) || (block_die != NULL)); 1861 break; 1862 1863 case DW_TAG_subprogram: // Function 1864 if (function_die) 1865 *function_die = this; 1866 check_children = (block_die != NULL); 1867 break; 1868 1869 case DW_TAG_inlined_subroutine: // Inlined Function 1870 case DW_TAG_lexical_block: // Block { } in code 1871 if (block_die) 1872 { 1873 *block_die = this; 1874 check_children = true; 1875 } 1876 break; 1877 1878 default: 1879 check_children = true; 1880 break; 1881 } 1882 } 1883 else 1884 { 1885 check_children = false; 1886 } 1887 } 1888 } 1889 } 1890 1891 1892 if (check_children) 1893 { 1894 // printf("checking children\n"); 1895 DWARFDebugInfoEntry* child = GetFirstChild(); 1896 while (child) 1897 { 1898 if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die)) 1899 return true; 1900 child = child->GetSibling(); 1901 } 1902 } 1903 } 1904 return found_address; 1905} 1906 1907const DWARFAbbreviationDeclaration* 1908DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (const DWARFCompileUnit *cu) const 1909{ 1910 if (m_abbr_idx) 1911 return cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx); 1912 return NULL; 1913} 1914 1915 1916bool 1917DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b) 1918{ 1919 return a.GetOffset() < b.GetOffset(); 1920} 1921 1922