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 "llvm/DebugInfo/DWARFFormValue.h" 15 #include "llvm/Support/Debug.h" 16 #include "llvm/Support/Dwarf.h" 17 #include "llvm/Support/Format.h" 18 #include "llvm/Support/raw_ostream.h" 19 using namespace llvm; 20 using namespace dwarf; 21 22 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, 23 const DWARFCompileUnit *cu, 24 unsigned recurseDepth, 25 unsigned indent) const { 26 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 27 uint32_t offset = Offset; 28 29 if (debug_info_data.isValidOffset(offset)) { 30 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 31 32 OS << format("\n0x%8.8x: ", Offset); 33 if (abbrCode) { 34 if (AbbrevDecl) { 35 const char *tagString = TagString(getTag()); 36 if (tagString) 37 OS.indent(indent) << tagString; 38 else 39 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); 40 OS << format(" [%u] %c\n", abbrCode, 41 AbbrevDecl->hasChildren() ? '*' : ' '); 42 43 // Dump all data in the DIE for the attributes. 44 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 45 for (uint32_t i = 0; i != numAttributes; ++i) { 46 uint16_t attr = AbbrevDecl->getAttrByIndex(i); 47 uint16_t form = AbbrevDecl->getFormByIndex(i); 48 dumpAttribute(OS, cu, &offset, attr, form, indent); 49 } 50 51 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 52 if (recurseDepth > 0 && child) { 53 while (child) { 54 child->dump(OS, cu, recurseDepth-1, indent+2); 55 child = child->getSibling(); 56 } 57 } 58 } else { 59 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 60 << abbrCode << '\n'; 61 } 62 } else { 63 OS.indent(indent) << "NULL\n"; 64 } 65 } 66 } 67 68 void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, 69 const DWARFCompileUnit *cu, 70 uint32_t* offset_ptr, 71 uint16_t attr, 72 uint16_t form, 73 unsigned indent) const { 74 OS << format("0x%8.8x: ", *offset_ptr); 75 OS.indent(indent+2); 76 const char *attrString = AttributeString(attr); 77 if (attrString) 78 OS << attrString; 79 else 80 OS << format("DW_AT_Unknown_%x", attr); 81 const char *formString = FormEncodingString(form); 82 if (formString) 83 OS << " [" << formString << ']'; 84 else 85 OS << format(" [DW_FORM_Unknown_%x]", form); 86 87 DWARFFormValue formValue(form); 88 89 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu)) 90 return; 91 92 OS << "\t("; 93 formValue.dump(OS, cu); 94 OS << ")\n"; 95 } 96 97 bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *CU, 98 const uint8_t *FixedFormSizes, 99 uint32_t *OffsetPtr) { 100 Offset = *OffsetPtr; 101 DataExtractor DebugInfoData = CU->getDebugInfoExtractor(); 102 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); 103 if (0 == AbbrCode) { 104 // NULL debug tag entry. 105 AbbrevDecl = NULL; 106 return true; 107 } 108 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); 109 assert(AbbrevDecl); 110 assert(FixedFormSizes); // For best performance this should be specified! 111 112 // Skip all data in the .debug_info for the attributes 113 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { 114 uint16_t Form = AbbrevDecl->getFormByIndex(i); 115 116 // FIXME: Currently we're checking if this is less than the last 117 // entry in the fixed_form_sizes table, but this should be changed 118 // to use dynamic dispatch. 119 uint8_t FixedFormSize = 120 (Form < DW_FORM_ref_sig8) ? FixedFormSizes[Form] : 0; 121 if (FixedFormSize) 122 *OffsetPtr += FixedFormSize; 123 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, 124 CU)) { 125 // Restore the original offset. 126 *OffsetPtr = Offset; 127 return false; 128 } 129 } 130 return true; 131 } 132 133 bool 134 DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *CU, 135 uint32_t *OffsetPtr) { 136 DataExtractor DebugInfoData = CU->getDebugInfoExtractor(); 137 const uint32_t CUEndOffset = CU->getNextCompileUnitOffset(); 138 Offset = *OffsetPtr; 139 if ((Offset >= CUEndOffset) || !DebugInfoData.isValidOffset(Offset)) 140 return false; 141 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); 142 if (0 == AbbrCode) { 143 // NULL debug tag entry. 144 AbbrevDecl = NULL; 145 return true; 146 } 147 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); 148 if (0 == AbbrevDecl) { 149 // Restore the original offset. 150 *OffsetPtr = Offset; 151 return false; 152 } 153 bool IsCompileUnitTag = (AbbrevDecl->getTag() == DW_TAG_compile_unit); 154 if (IsCompileUnitTag) 155 const_cast<DWARFCompileUnit*>(CU)->setBaseAddress(0); 156 157 // Skip all data in the .debug_info for the attributes 158 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { 159 uint16_t Attr = AbbrevDecl->getAttrByIndex(i); 160 uint16_t Form = AbbrevDecl->getFormByIndex(i); 161 162 if (IsCompileUnitTag && 163 ((Attr == DW_AT_entry_pc) || (Attr == DW_AT_low_pc))) { 164 DWARFFormValue FormValue(Form); 165 if (FormValue.extractValue(DebugInfoData, OffsetPtr, CU)) { 166 if (Attr == DW_AT_low_pc || Attr == DW_AT_entry_pc) 167 const_cast<DWARFCompileUnit*>(CU) 168 ->setBaseAddress(FormValue.getUnsigned()); 169 } 170 } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, 171 CU)) { 172 // Restore the original offset. 173 *OffsetPtr = Offset; 174 return false; 175 } 176 } 177 return true; 178 } 179 180 bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const { 181 return getTag() == DW_TAG_subprogram; 182 } 183 184 bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const { 185 uint32_t Tag = getTag(); 186 return Tag == DW_TAG_subprogram || 187 Tag == DW_TAG_inlined_subroutine; 188 } 189 190 uint32_t 191 DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu, 192 const uint16_t attr, 193 DWARFFormValue &form_value, 194 uint32_t *end_attr_offset_ptr) 195 const { 196 if (AbbrevDecl) { 197 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr); 198 199 if (attr_idx != -1U) { 200 uint32_t offset = getOffset(); 201 202 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 203 204 // Skip the abbreviation code so we are at the data for the attributes 205 debug_info_data.getULEB128(&offset); 206 207 uint32_t idx = 0; 208 while (idx < attr_idx) 209 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++), 210 debug_info_data, &offset, cu); 211 212 const uint32_t attr_offset = offset; 213 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx)); 214 if (form_value.extractValue(debug_info_data, &offset, cu)) { 215 if (end_attr_offset_ptr) 216 *end_attr_offset_ptr = offset; 217 return attr_offset; 218 } 219 } 220 } 221 222 return 0; 223 } 224 225 const char* 226 DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 227 const DWARFCompileUnit* cu, 228 const uint16_t attr, 229 const char* fail_value) 230 const { 231 DWARFFormValue form_value; 232 if (getAttributeValue(cu, attr, form_value)) { 233 DataExtractor stringExtractor(cu->getStringSection(), false, 0); 234 return form_value.getAsCString(&stringExtractor); 235 } 236 return fail_value; 237 } 238 239 uint64_t 240 DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( 241 const DWARFCompileUnit* cu, 242 const uint16_t attr, 243 uint64_t fail_value) const { 244 DWARFFormValue form_value; 245 if (getAttributeValue(cu, attr, form_value)) 246 return form_value.getUnsigned(); 247 return fail_value; 248 } 249 250 int64_t 251 DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned( 252 const DWARFCompileUnit* cu, 253 const uint16_t attr, 254 int64_t fail_value) const { 255 DWARFFormValue form_value; 256 if (getAttributeValue(cu, attr, form_value)) 257 return form_value.getSigned(); 258 return fail_value; 259 } 260 261 uint64_t 262 DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 263 const DWARFCompileUnit* cu, 264 const uint16_t attr, 265 uint64_t fail_value) 266 const { 267 DWARFFormValue form_value; 268 if (getAttributeValue(cu, attr, form_value)) 269 return form_value.getReference(cu); 270 return fail_value; 271 } 272 273 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU, 274 uint64_t &LowPC, 275 uint64_t &HighPC) const { 276 HighPC = -1ULL; 277 LowPC = getAttributeValueAsUnsigned(CU, DW_AT_low_pc, -1ULL); 278 if (LowPC != -1ULL) 279 HighPC = getAttributeValueAsUnsigned(CU, DW_AT_high_pc, -1ULL); 280 return (HighPC != -1ULL); 281 } 282 283 void 284 DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU, 285 DWARFDebugAranges *DebugAranges) 286 const { 287 if (AbbrevDecl) { 288 if (isSubprogramDIE()) { 289 uint64_t LowPC, HighPC; 290 if (getLowAndHighPC(CU, LowPC, HighPC)) { 291 DebugAranges->appendRange(CU->getOffset(), LowPC, HighPC); 292 } 293 // FIXME: try to append ranges from .debug_ranges section. 294 } 295 296 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 297 while (child) { 298 child->buildAddressRangeTable(CU, DebugAranges); 299 child = child->getSibling(); 300 } 301 } 302 } 303 304 bool 305 DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 306 const DWARFCompileUnit *CU, 307 const uint64_t Address) 308 const { 309 if (isNULL()) 310 return false; 311 uint64_t LowPC, HighPC; 312 if (getLowAndHighPC(CU, LowPC, HighPC)) 313 return (LowPC <= Address && Address <= HighPC); 314 // Try to get address ranges from .debug_ranges section. 315 uint32_t RangesOffset = getAttributeValueAsReference(CU, DW_AT_ranges, -1U); 316 if (RangesOffset != -1U) { 317 DWARFDebugRangeList RangeList; 318 if (CU->extractRangeList(RangesOffset, RangeList)) 319 return RangeList.containsAddress(CU->getBaseAddress(), Address); 320 } 321 return false; 322 } 323 324 const char* 325 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFCompileUnit *CU) 326 const { 327 if (!isSubroutineDIE()) 328 return 0; 329 // Try to get mangled name if possible. 330 if (const char *name = 331 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0)) 332 return name; 333 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0)) 334 return name; 335 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0)) 336 return name; 337 // Try to get name from specification DIE. 338 uint32_t spec_ref = 339 getAttributeValueAsReference(CU, DW_AT_specification, -1U); 340 if (spec_ref != -1U) { 341 DWARFDebugInfoEntryMinimal spec_die; 342 if (spec_die.extract(CU, &spec_ref)) { 343 if (const char *name = spec_die.getSubroutineName(CU)) 344 return name; 345 } 346 } 347 // Try to get name from abstract origin DIE. 348 uint32_t abs_origin_ref = 349 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U); 350 if (abs_origin_ref != -1U) { 351 DWARFDebugInfoEntryMinimal abs_origin_die; 352 if (abs_origin_die.extract(CU, &abs_origin_ref)) { 353 if (const char *name = abs_origin_die.getSubroutineName(CU)) 354 return name; 355 } 356 } 357 return 0; 358 } 359 360 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFCompileUnit *CU, 361 uint32_t &CallFile, 362 uint32_t &CallLine, 363 uint32_t &CallColumn) const { 364 CallFile = getAttributeValueAsUnsigned(CU, DW_AT_call_file, 0); 365 CallLine = getAttributeValueAsUnsigned(CU, DW_AT_call_line, 0); 366 CallColumn = getAttributeValueAsUnsigned(CU, DW_AT_call_column, 0); 367 } 368 369 DWARFDebugInfoEntryInlinedChain 370 DWARFDebugInfoEntryMinimal::getInlinedChainForAddress( 371 const DWARFCompileUnit *CU, const uint64_t Address) const { 372 DWARFDebugInfoEntryInlinedChain InlinedChain; 373 InlinedChain.CU = CU; 374 if (isNULL()) 375 return InlinedChain; 376 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) { 377 // Append current DIE to inlined chain only if it has correct tag 378 // (e.g. it is not a lexical block). 379 if (DIE->isSubroutineDIE()) { 380 InlinedChain.DIEs.push_back(*DIE); 381 } 382 // Try to get child which also contains provided address. 383 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild(); 384 while (Child) { 385 if (Child->addressRangeContainsAddress(CU, Address)) { 386 // Assume there is only one such child. 387 break; 388 } 389 Child = Child->getSibling(); 390 } 391 DIE = Child; 392 } 393 // Reverse the obtained chain to make the root of inlined chain last. 394 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end()); 395 return InlinedChain; 396 } 397