DWARFDebugInfoEntry.cpp revision 3887a902a1b8e5a6aad4fc822479845ce3ba0dfe
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 367uint32_t 368DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu, 369 const uint16_t attr, 370 DWARFFormValue &form_value, 371 uint32_t *end_attr_offset_ptr) 372 const { 373 if (AbbrevDecl) { 374 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr); 375 376 if (attr_idx != -1U) { 377 uint32_t offset = getOffset(); 378 379 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 380 381 // Skip the abbreviation code so we are at the data for the attributes 382 debug_info_data.getULEB128(&offset); 383 384 uint32_t idx = 0; 385 while (idx < attr_idx) 386 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++), 387 debug_info_data, &offset, cu); 388 389 const uint32_t attr_offset = offset; 390 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx)); 391 if (form_value.extractValue(debug_info_data, &offset, cu)) { 392 if (end_attr_offset_ptr) 393 *end_attr_offset_ptr = offset; 394 return attr_offset; 395 } 396 } 397 } 398 399 return 0; 400} 401 402const char* 403DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 404 const DWARFCompileUnit* cu, 405 const uint16_t attr, 406 const char* fail_value) const { 407 DWARFFormValue form_value; 408 if (getAttributeValue(cu, attr, form_value)) { 409 DataExtractor stringExtractor(cu->getContext().getStringSection(), 410 false, 0); 411 return form_value.getAsCString(&stringExtractor); 412 } 413 return fail_value; 414} 415 416uint64_t 417DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( 418 const DWARFCompileUnit* cu, 419 const uint16_t attr, 420 uint64_t fail_value) const { 421 DWARFFormValue form_value; 422 if (getAttributeValue(cu, attr, form_value)) 423 return form_value.getUnsigned(); 424 return fail_value; 425} 426 427int64_t 428DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned( 429 const DWARFCompileUnit* cu, 430 const uint16_t attr, 431 int64_t fail_value) const { 432 DWARFFormValue form_value; 433 if (getAttributeValue(cu, attr, form_value)) 434 return form_value.getSigned(); 435 return fail_value; 436} 437 438uint64_t 439DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 440 const DWARFCompileUnit* cu, 441 const uint16_t attr, 442 uint64_t fail_value) const { 443 DWARFFormValue form_value; 444 if (getAttributeValue(cu, attr, form_value)) 445 return form_value.getReference(cu); 446 return fail_value; 447} 448 449void 450DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu, 451 DWARFDebugAranges *debug_aranges) 452 const { 453 if (AbbrevDecl) { 454 uint16_t tag = AbbrevDecl->getTag(); 455 if (tag == DW_TAG_subprogram) { 456 uint64_t hi_pc = -1ULL; 457 uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL); 458 if (lo_pc != -1ULL) 459 hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL); 460 if (hi_pc != -1ULL) 461 debug_aranges->appendRange(cu->getOffset(), lo_pc, hi_pc); 462 } 463 464 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 465 while (child) { 466 child->buildAddressRangeTable(cu, debug_aranges); 467 child = child->getSibling(); 468 } 469 } 470} 471 472bool 473DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 474 const DWARFCompileUnit *cu, const uint64_t address) const { 475 if (!isNULL() && getTag() == DW_TAG_subprogram) { 476 uint64_t hi_pc = -1ULL; 477 uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL); 478 if (lo_pc != -1ULL) 479 hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL); 480 if (hi_pc != -1ULL) { 481 return (lo_pc <= address && address < hi_pc); 482 } 483 } 484 return false; 485} 486 487const char* 488DWARFDebugInfoEntryMinimal::getSubprogramName( 489 const DWARFCompileUnit *cu) const { 490 if (isNULL() || getTag() != DW_TAG_subprogram) 491 return 0; 492 // Try to get mangled name if possible. 493 if (const char *name = 494 getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0)) 495 return name; 496 if (const char *name = getAttributeValueAsString(cu, DW_AT_linkage_name, 0)) 497 return name; 498 if (const char *name = getAttributeValueAsString(cu, DW_AT_name, 0)) 499 return name; 500 // Try to get name from specification DIE. 501 uint32_t spec_ref = 502 getAttributeValueAsReference(cu, DW_AT_specification, -1U); 503 if (spec_ref != -1U) { 504 DWARFDebugInfoEntryMinimal spec_die; 505 if (spec_die.extract(cu, &spec_ref)) { 506 if (const char *name = spec_die.getSubprogramName(cu)) 507 return name; 508 } 509 } 510 // Try to get name from abstract origin DIE. 511 uint32_t abs_origin_ref = 512 getAttributeValueAsReference(cu, DW_AT_abstract_origin, -1U); 513 if (abs_origin_ref != -1U) { 514 DWARFDebugInfoEntryMinimal abs_origin_die; 515 if (abs_origin_die.extract(cu, &abs_origin_ref)) { 516 if (const char *name = abs_origin_die.getSubprogramName(cu)) 517 return name; 518 } 519 } 520 return 0; 521} 522