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