DWARFDebugInfoEntry.cpp revision 263508
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" 19using namespace llvm; 20using namespace dwarf; 21 22void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, 23 unsigned recurseDepth, 24 unsigned indent) const { 25 DataExtractor debug_info_data = u->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 DIE 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, u, &offset, attr, form, indent); 48 } 49 50 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 51 if (recurseDepth > 0 && child) { 52 while (child) { 53 child->dump(OS, u, 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 DWARFUnit *u, 69 uint32_t *offset_ptr, 70 uint16_t attr, uint16_t form, 71 unsigned indent) const { 72 OS << " "; 73 OS.indent(indent+2); 74 const char *attrString = AttributeString(attr); 75 if (attrString) 76 OS << attrString; 77 else 78 OS << format("DW_AT_Unknown_%x", attr); 79 const char *formString = FormEncodingString(form); 80 if (formString) 81 OS << " [" << formString << ']'; 82 else 83 OS << format(" [DW_FORM_Unknown_%x]", form); 84 85 DWARFFormValue formValue(form); 86 87 if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u)) 88 return; 89 90 OS << "\t("; 91 formValue.dump(OS, u); 92 OS << ")\n"; 93} 94 95bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U, 96 uint32_t *OffsetPtr) { 97 Offset = *OffsetPtr; 98 DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 99 uint32_t UEndOffset = U->getNextUnitOffset(); 100 if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) 101 return false; 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 = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); 109 if (0 == AbbrevDecl) { 110 // Restore the original offset. 111 *OffsetPtr = Offset; 112 return false; 113 } 114 ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes( 115 U->getAddressByteSize(), U->getVersion()); 116 assert(FixedFormSizes.size() > 0); 117 118 // Skip all data in the .debug_info for the attributes 119 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { 120 uint16_t Form = AbbrevDecl->getFormByIndex(i); 121 122 uint8_t FixedFormSize = 123 (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0; 124 if (FixedFormSize) 125 *OffsetPtr += FixedFormSize; 126 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) { 127 // Restore the original offset. 128 *OffsetPtr = Offset; 129 return false; 130 } 131 } 132 return true; 133} 134 135bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const { 136 return getTag() == DW_TAG_subprogram; 137} 138 139bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const { 140 uint32_t Tag = getTag(); 141 return Tag == DW_TAG_subprogram || 142 Tag == DW_TAG_inlined_subroutine; 143} 144 145bool DWARFDebugInfoEntryMinimal::getAttributeValue( 146 const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const { 147 if (!AbbrevDecl) 148 return false; 149 150 uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr); 151 if (AttrIdx == -1U) 152 return false; 153 154 DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 155 uint32_t DebugInfoOffset = getOffset(); 156 157 // Skip the abbreviation code so we are at the data for the attributes 158 DebugInfoData.getULEB128(&DebugInfoOffset); 159 160 // Skip preceding attribute values. 161 for (uint32_t i = 0; i < AttrIdx; ++i) { 162 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i), 163 DebugInfoData, &DebugInfoOffset, U); 164 } 165 166 FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx)); 167 return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U); 168} 169 170const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 171 const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const { 172 DWARFFormValue FormValue; 173 if (!getAttributeValue(U, Attr, FormValue)) 174 return FailValue; 175 Optional<const char *> Result = FormValue.getAsCString(U); 176 return Result.hasValue() ? Result.getValue() : FailValue; 177} 178 179uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( 180 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 181 DWARFFormValue FormValue; 182 if (!getAttributeValue(U, Attr, FormValue)) 183 return FailValue; 184 Optional<uint64_t> Result = FormValue.getAsAddress(U); 185 return Result.hasValue() ? Result.getValue() : FailValue; 186} 187 188uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant( 189 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 190 DWARFFormValue FormValue; 191 if (!getAttributeValue(U, Attr, FormValue)) 192 return FailValue; 193 Optional<uint64_t> Result = FormValue.getAsUnsignedConstant(); 194 return Result.hasValue() ? Result.getValue() : FailValue; 195} 196 197uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 198 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 199 DWARFFormValue FormValue; 200 if (!getAttributeValue(U, Attr, FormValue)) 201 return FailValue; 202 Optional<uint64_t> Result = FormValue.getAsReference(U); 203 return Result.hasValue() ? Result.getValue() : FailValue; 204} 205 206uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset( 207 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 208 DWARFFormValue FormValue; 209 if (!getAttributeValue(U, Attr, FormValue)) 210 return FailValue; 211 Optional<uint64_t> Result = FormValue.getAsSectionOffset(); 212 return Result.hasValue() ? Result.getValue() : FailValue; 213} 214 215bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U, 216 uint64_t &LowPC, 217 uint64_t &HighPC) const { 218 LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL); 219 if (LowPC == -1ULL) 220 return false; 221 HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); 222 if (HighPC == -1ULL) { 223 // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case 224 // it represents function size. 225 HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL); 226 if (HighPC != -1ULL) 227 HighPC += LowPC; 228 } 229 return (HighPC != -1ULL); 230} 231 232void DWARFDebugInfoEntryMinimal::buildAddressRangeTable( 233 const DWARFUnit *U, DWARFDebugAranges *DebugAranges, 234 uint32_t UOffsetInAranges) const { 235 if (AbbrevDecl) { 236 if (isSubprogramDIE()) { 237 uint64_t LowPC, HighPC; 238 if (getLowAndHighPC(U, LowPC, HighPC)) 239 DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC); 240 // FIXME: try to append ranges from .debug_ranges section. 241 } 242 243 const DWARFDebugInfoEntryMinimal *Child = getFirstChild(); 244 while (Child) { 245 Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges); 246 Child = Child->getSibling(); 247 } 248 } 249} 250 251bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 252 const DWARFUnit *U, const uint64_t Address) const { 253 if (isNULL()) 254 return false; 255 uint64_t LowPC, HighPC; 256 if (getLowAndHighPC(U, LowPC, HighPC)) 257 return (LowPC <= Address && Address <= HighPC); 258 // Try to get address ranges from .debug_ranges section. 259 uint32_t RangesOffset = 260 getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U); 261 if (RangesOffset != -1U) { 262 DWARFDebugRangeList RangeList; 263 if (U->extractRangeList(RangesOffset, RangeList)) 264 return RangeList.containsAddress(U->getBaseAddress(), Address); 265 } 266 return false; 267} 268 269const char * 270DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { 271 if (!isSubroutineDIE()) 272 return 0; 273 // Try to get mangled name if possible. 274 if (const char *name = 275 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, 0)) 276 return name; 277 if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name, 0)) 278 return name; 279 if (const char *name = getAttributeValueAsString(U, DW_AT_name, 0)) 280 return name; 281 // Try to get name from specification DIE. 282 uint32_t spec_ref = 283 getAttributeValueAsReference(U, DW_AT_specification, -1U); 284 if (spec_ref != -1U) { 285 DWARFDebugInfoEntryMinimal spec_die; 286 if (spec_die.extractFast(U, &spec_ref)) { 287 if (const char *name = spec_die.getSubroutineName(U)) 288 return name; 289 } 290 } 291 // Try to get name from abstract origin DIE. 292 uint32_t abs_origin_ref = 293 getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); 294 if (abs_origin_ref != -1U) { 295 DWARFDebugInfoEntryMinimal abs_origin_die; 296 if (abs_origin_die.extractFast(U, &abs_origin_ref)) { 297 if (const char *name = abs_origin_die.getSubroutineName(U)) 298 return name; 299 } 300 } 301 return 0; 302} 303 304void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U, 305 uint32_t &CallFile, 306 uint32_t &CallLine, 307 uint32_t &CallColumn) const { 308 CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0); 309 CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0); 310 CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0); 311} 312 313DWARFDebugInfoEntryInlinedChain 314DWARFDebugInfoEntryMinimal::getInlinedChainForAddress( 315 const DWARFUnit *U, const uint64_t Address) const { 316 DWARFDebugInfoEntryInlinedChain InlinedChain; 317 InlinedChain.U = U; 318 if (isNULL()) 319 return InlinedChain; 320 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) { 321 // Append current DIE to inlined chain only if it has correct tag 322 // (e.g. it is not a lexical block). 323 if (DIE->isSubroutineDIE()) { 324 InlinedChain.DIEs.push_back(*DIE); 325 } 326 // Try to get child which also contains provided address. 327 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild(); 328 while (Child) { 329 if (Child->addressRangeContainsAddress(U, Address)) { 330 // Assume there is only one such child. 331 break; 332 } 333 Child = Child->getSibling(); 334 } 335 DIE = Child; 336 } 337 // Reverse the obtained chain to make the root of inlined chain last. 338 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end()); 339 return InlinedChain; 340} 341