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