1//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// 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#include "DWARFCompileUnit.h" 12#include "DWARFContext.h" 13#include "DWARFDebugAbbrev.h" 14#include "DWARFFormValue.h" 15#include "llvm/Support/Dwarf.h" 16#include "llvm/Support/Format.h" 17#include "llvm/Support/raw_ostream.h" 18using namespace llvm; 19using namespace dwarf; 20 21void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, 22 const DWARFCompileUnit *cu, 23 unsigned recurseDepth, 24 unsigned indent) const { 25 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 26 uint32_t offset = Offset; 27 28 if (debug_info_data.isValidOffset(offset)) { 29 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 30 31 OS << format("\n0x%8.8x: ", Offset); 32 if (abbrCode) { 33 if (AbbrevDecl) { 34 const char *tagString = TagString(getTag()); 35 if (tagString) 36 OS.indent(indent) << tagString; 37 else 38 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); 39 OS << format(" [%u] %c\n", abbrCode, 40 AbbrevDecl->hasChildren() ? '*' : ' '); 41 42 // Dump all data in the .debug_info for the attributes 43 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 44 for (uint32_t i = 0; i != numAttributes; ++i) { 45 uint16_t attr = AbbrevDecl->getAttrByIndex(i); 46 uint16_t form = AbbrevDecl->getFormByIndex(i); 47 dumpAttribute(OS, cu, &offset, attr, form, indent); 48 } 49 50 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 51 if (recurseDepth > 0 && child) { 52 while (child) { 53 child->dump(OS, cu, recurseDepth-1, indent+2); 54 child = child->getSibling(); 55 } 56 } 57 } else { 58 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 59 << abbrCode << '\n'; 60 } 61 } else { 62 OS.indent(indent) << "NULL\n"; 63 } 64 } 65} 66 67void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, 68 const DWARFCompileUnit *cu, 69 uint32_t* offset_ptr, 70 uint16_t attr, 71 uint16_t form, 72 unsigned indent) const { 73 OS << format("0x%8.8x: ", *offset_ptr); 74 OS.indent(indent+2); 75 const char *attrString = AttributeString(attr); 76 if (attrString) 77 OS << attrString; 78 else 79 OS << format("DW_AT_Unknown_%x", attr); 80 const char *formString = FormEncodingString(form); 81 if (formString) 82 OS << " [" << formString << ']'; 83 else 84 OS << format(" [DW_FORM_Unknown_%x]", form); 85 86 DWARFFormValue formValue(form); 87 88 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu)) 89 return; 90 91 OS << "\t("; 92 formValue.dump(OS, cu); 93 OS << ")\n"; 94} 95 96bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu, 97 const uint8_t *fixed_form_sizes, 98 uint32_t *offset_ptr) { 99 Offset = *offset_ptr; 100 101 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 102 uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr); 103 104 assert(fixed_form_sizes); // For best performance this should be specified! 105 106 if (abbrCode) { 107 uint32_t offset = *offset_ptr; 108 109 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); 110 111 // Skip all data in the .debug_info for the attributes 112 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 113 uint32_t i; 114 uint16_t form; 115 for (i=0; i<numAttributes; ++i) { 116 form = AbbrevDecl->getFormByIndex(i); 117 118 const uint8_t fixed_skip_size = fixed_form_sizes[form]; 119 if (fixed_skip_size) 120 offset += fixed_skip_size; 121 else { 122 bool form_is_indirect = false; 123 do { 124 form_is_indirect = false; 125 uint32_t form_size = 0; 126 switch (form) { 127 // Blocks if inlined data that have a length field and the data bytes 128 // inlined in the .debug_info. 129 case DW_FORM_exprloc: 130 case DW_FORM_block: 131 form_size = debug_info_data.getULEB128(&offset); 132 break; 133 case DW_FORM_block1: 134 form_size = debug_info_data.getU8(&offset); 135 break; 136 case DW_FORM_block2: 137 form_size = debug_info_data.getU16(&offset); 138 break; 139 case DW_FORM_block4: 140 form_size = debug_info_data.getU32(&offset); 141 break; 142 143 // Inlined NULL terminated C-strings 144 case DW_FORM_string: 145 debug_info_data.getCStr(&offset); 146 break; 147 148 // Compile unit address sized values 149 case DW_FORM_addr: 150 case DW_FORM_ref_addr: 151 form_size = cu->getAddressByteSize(); 152 break; 153 154 // 0 sized form. 155 case DW_FORM_flag_present: 156 form_size = 0; 157 break; 158 159 // 1 byte values 160 case DW_FORM_data1: 161 case DW_FORM_flag: 162 case DW_FORM_ref1: 163 form_size = 1; 164 break; 165 166 // 2 byte values 167 case DW_FORM_data2: 168 case DW_FORM_ref2: 169 form_size = 2; 170 break; 171 172 // 4 byte values 173 case DW_FORM_strp: 174 case DW_FORM_data4: 175 case DW_FORM_ref4: 176 form_size = 4; 177 break; 178 179 // 8 byte values 180 case DW_FORM_data8: 181 case DW_FORM_ref8: 182 case DW_FORM_ref_sig8: 183 form_size = 8; 184 break; 185 186 // signed or unsigned LEB 128 values 187 case DW_FORM_sdata: 188 case DW_FORM_udata: 189 case DW_FORM_ref_udata: 190 debug_info_data.getULEB128(&offset); 191 break; 192 193 case DW_FORM_indirect: 194 form_is_indirect = true; 195 form = debug_info_data.getULEB128(&offset); 196 break; 197 198 case DW_FORM_sec_offset: 199 if (cu->getAddressByteSize() == 4) 200 debug_info_data.getU32(offset_ptr); 201 else 202 debug_info_data.getU64(offset_ptr); 203 break; 204 205 default: 206 *offset_ptr = Offset; 207 return false; 208 } 209 offset += form_size; 210 211 } while (form_is_indirect); 212 } 213 } 214 *offset_ptr = offset; 215 return true; 216 } else { 217 AbbrevDecl = NULL; 218 return true; // NULL debug tag entry 219 } 220} 221 222bool 223DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu, 224 uint32_t *offset_ptr) { 225 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 226 const uint32_t cu_end_offset = cu->getNextCompileUnitOffset(); 227 const uint8_t cu_addr_size = cu->getAddressByteSize(); 228 uint32_t offset = *offset_ptr; 229 if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) { 230 Offset = offset; 231 232 uint64_t abbrCode = debug_info_data.getULEB128(&offset); 233 234 if (abbrCode) { 235 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); 236 237 if (AbbrevDecl) { 238 uint16_t tag = AbbrevDecl->getTag(); 239 240 bool isCompileUnitTag = tag == DW_TAG_compile_unit; 241 if(cu && isCompileUnitTag) 242 const_cast<DWARFCompileUnit*>(cu)->setBaseAddress(0); 243 244 // Skip all data in the .debug_info for the attributes 245 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 246 for (uint32_t i = 0; i != numAttributes; ++i) { 247 uint16_t attr = AbbrevDecl->getAttrByIndex(i); 248 uint16_t form = AbbrevDecl->getFormByIndex(i); 249 250 if (isCompileUnitTag && 251 ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { 252 DWARFFormValue form_value(form); 253 if (form_value.extractValue(debug_info_data, &offset, cu)) { 254 if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) 255 const_cast<DWARFCompileUnit*>(cu) 256 ->setBaseAddress(form_value.getUnsigned()); 257 } 258 } else { 259 bool form_is_indirect = false; 260 do { 261 form_is_indirect = false; 262 register uint32_t form_size = 0; 263 switch (form) { 264 // Blocks if inlined data that have a length field and the data 265 // bytes // inlined in the .debug_info 266 case DW_FORM_exprloc: 267 case DW_FORM_block: 268 form_size = debug_info_data.getULEB128(&offset); 269 break; 270 case DW_FORM_block1: 271 form_size = debug_info_data.getU8(&offset); 272 break; 273 case DW_FORM_block2: 274 form_size = debug_info_data.getU16(&offset); 275 break; 276 case DW_FORM_block4: 277 form_size = debug_info_data.getU32(&offset); 278 break; 279 280 // Inlined NULL terminated C-strings 281 case DW_FORM_string: 282 debug_info_data.getCStr(&offset); 283 break; 284 285 // Compile unit address sized values 286 case DW_FORM_addr: 287 case DW_FORM_ref_addr: 288 form_size = cu_addr_size; 289 break; 290 291 // 0 byte value 292 case DW_FORM_flag_present: 293 form_size = 0; 294 break; 295 296 // 1 byte values 297 case DW_FORM_data1: 298 case DW_FORM_flag: 299 case DW_FORM_ref1: 300 form_size = 1; 301 break; 302 303 // 2 byte values 304 case DW_FORM_data2: 305 case DW_FORM_ref2: 306 form_size = 2; 307 break; 308 309 // 4 byte values 310 case DW_FORM_strp: 311 form_size = 4; 312 break; 313 314 case DW_FORM_data4: 315 case DW_FORM_ref4: 316 form_size = 4; 317 break; 318 319 // 8 byte values 320 case DW_FORM_data8: 321 case DW_FORM_ref8: 322 case DW_FORM_ref_sig8: 323 form_size = 8; 324 break; 325 326 // signed or unsigned LEB 128 values 327 case DW_FORM_sdata: 328 case DW_FORM_udata: 329 case DW_FORM_ref_udata: 330 debug_info_data.getULEB128(&offset); 331 break; 332 333 case DW_FORM_indirect: 334 form = debug_info_data.getULEB128(&offset); 335 form_is_indirect = true; 336 break; 337 338 case DW_FORM_sec_offset: 339 if (cu->getAddressByteSize() == 4) 340 debug_info_data.getU32(offset_ptr); 341 else 342 debug_info_data.getU64(offset_ptr); 343 break; 344 345 default: 346 *offset_ptr = offset; 347 return false; 348 } 349 350 offset += form_size; 351 } while (form_is_indirect); 352 } 353 } 354 *offset_ptr = offset; 355 return true; 356 } 357 } else { 358 AbbrevDecl = NULL; 359 *offset_ptr = offset; 360 return true; // NULL debug tag entry 361 } 362 } 363 364 return false; 365} 366 367bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const { 368 return getTag() == DW_TAG_subprogram; 369} 370 371bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const { 372 uint32_t Tag = getTag(); 373 return Tag == DW_TAG_subprogram || 374 Tag == DW_TAG_inlined_subroutine; 375} 376 377uint32_t 378DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu, 379 const uint16_t attr, 380 DWARFFormValue &form_value, 381 uint32_t *end_attr_offset_ptr) 382 const { 383 if (AbbrevDecl) { 384 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr); 385 386 if (attr_idx != -1U) { 387 uint32_t offset = getOffset(); 388 389 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 390 391 // Skip the abbreviation code so we are at the data for the attributes 392 debug_info_data.getULEB128(&offset); 393 394 uint32_t idx = 0; 395 while (idx < attr_idx) 396 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++), 397 debug_info_data, &offset, cu); 398 399 const uint32_t attr_offset = offset; 400 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx)); 401 if (form_value.extractValue(debug_info_data, &offset, cu)) { 402 if (end_attr_offset_ptr) 403 *end_attr_offset_ptr = offset; 404 return attr_offset; 405 } 406 } 407 } 408 409 return 0; 410} 411 412const char* 413DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 414 const DWARFCompileUnit* cu, 415 const uint16_t attr, 416 const char* fail_value) const { 417 DWARFFormValue form_value; 418 if (getAttributeValue(cu, attr, form_value)) { 419 DataExtractor stringExtractor(cu->getContext().getStringSection(), 420 false, 0); 421 return form_value.getAsCString(&stringExtractor); 422 } 423 return fail_value; 424} 425 426uint64_t 427DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( 428 const DWARFCompileUnit* cu, 429 const uint16_t attr, 430 uint64_t fail_value) const { 431 DWARFFormValue form_value; 432 if (getAttributeValue(cu, attr, form_value)) 433 return form_value.getUnsigned(); 434 return fail_value; 435} 436 437int64_t 438DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned( 439 const DWARFCompileUnit* cu, 440 const uint16_t attr, 441 int64_t fail_value) const { 442 DWARFFormValue form_value; 443 if (getAttributeValue(cu, attr, form_value)) 444 return form_value.getSigned(); 445 return fail_value; 446} 447 448uint64_t 449DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 450 const DWARFCompileUnit* cu, 451 const uint16_t attr, 452 uint64_t fail_value) const { 453 DWARFFormValue form_value; 454 if (getAttributeValue(cu, attr, form_value)) 455 return form_value.getReference(cu); 456 return fail_value; 457} 458 459bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU, 460 uint64_t &LowPC, uint64_t &HighPC) const { 461 HighPC = -1ULL; 462 LowPC = getAttributeValueAsUnsigned(CU, DW_AT_low_pc, -1ULL); 463 if (LowPC != -1ULL) 464 HighPC = getAttributeValueAsUnsigned(CU, DW_AT_high_pc, -1ULL); 465 return (HighPC != -1ULL); 466} 467 468void 469DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU, 470 DWARFDebugAranges *DebugAranges) 471 const { 472 if (AbbrevDecl) { 473 if (isSubprogramDIE()) { 474 uint64_t LowPC, HighPC; 475 if (getLowAndHighPC(CU, LowPC, HighPC)) { 476 DebugAranges->appendRange(CU->getOffset(), LowPC, HighPC); 477 } 478 // FIXME: try to append ranges from .debug_ranges section. 479 } 480 481 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 482 while (child) { 483 child->buildAddressRangeTable(CU, DebugAranges); 484 child = child->getSibling(); 485 } 486 } 487} 488 489bool 490DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 491 const DWARFCompileUnit *CU, const uint64_t Address) const { 492 if (isNULL()) 493 return false; 494 uint64_t LowPC, HighPC; 495 if (getLowAndHighPC(CU, LowPC, HighPC)) 496 return (LowPC <= Address && Address <= HighPC); 497 // Try to get address ranges from .debug_ranges section. 498 uint32_t RangesOffset = getAttributeValueAsReference(CU, DW_AT_ranges, -1U); 499 if (RangesOffset != -1U) { 500 DWARFDebugRangeList RangeList; 501 if (CU->extractRangeList(RangesOffset, RangeList)) 502 return RangeList.containsAddress(CU->getBaseAddress(), Address); 503 } 504 return false; 505} 506 507const char* 508DWARFDebugInfoEntryMinimal::getSubroutineName( 509 const DWARFCompileUnit *CU) const { 510 if (!isSubroutineDIE()) 511 return 0; 512 // Try to get mangled name if possible. 513 if (const char *name = 514 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0)) 515 return name; 516 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0)) 517 return name; 518 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0)) 519 return name; 520 // Try to get name from specification DIE. 521 uint32_t spec_ref = 522 getAttributeValueAsReference(CU, DW_AT_specification, -1U); 523 if (spec_ref != -1U) { 524 DWARFDebugInfoEntryMinimal spec_die; 525 if (spec_die.extract(CU, &spec_ref)) { 526 if (const char *name = spec_die.getSubroutineName(CU)) 527 return name; 528 } 529 } 530 // Try to get name from abstract origin DIE. 531 uint32_t abs_origin_ref = 532 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U); 533 if (abs_origin_ref != -1U) { 534 DWARFDebugInfoEntryMinimal abs_origin_die; 535 if (abs_origin_die.extract(CU, &abs_origin_ref)) { 536 if (const char *name = abs_origin_die.getSubroutineName(CU)) 537 return name; 538 } 539 } 540 return 0; 541} 542 543void DWARFDebugInfoEntryMinimal::getCallerFrame( 544 const DWARFCompileUnit *CU, uint32_t &CallFile, uint32_t &CallLine, 545 uint32_t &CallColumn) const { 546 CallFile = getAttributeValueAsUnsigned(CU, DW_AT_call_file, 0); 547 CallLine = getAttributeValueAsUnsigned(CU, DW_AT_call_line, 0); 548 CallColumn = getAttributeValueAsUnsigned(CU, DW_AT_call_column, 0); 549} 550 551DWARFDebugInfoEntryMinimal::InlinedChain 552DWARFDebugInfoEntryMinimal::getInlinedChainForAddress( 553 const DWARFCompileUnit *CU, const uint64_t Address) const { 554 DWARFDebugInfoEntryMinimal::InlinedChain InlinedChain; 555 if (isNULL()) 556 return InlinedChain; 557 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) { 558 // Append current DIE to inlined chain only if it has correct tag 559 // (e.g. it is not a lexical block). 560 if (DIE->isSubroutineDIE()) { 561 InlinedChain.push_back(*DIE); 562 } 563 // Try to get child which also contains provided address. 564 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild(); 565 while (Child) { 566 if (Child->addressRangeContainsAddress(CU, Address)) { 567 // Assume there is only one such child. 568 break; 569 } 570 Child = Child->getSibling(); 571 } 572 DIE = Child; 573 } 574 // Reverse the obtained chain to make the root of inlined chain last. 575 std::reverse(InlinedChain.begin(), InlinedChain.end()); 576 return InlinedChain; 577} 578