LLVM API Documentation
00001 //===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "DWARFDebugInfoEntry.h" 00011 #include "DWARFCompileUnit.h" 00012 #include "DWARFContext.h" 00013 #include "DWARFDebugAbbrev.h" 00014 #include "llvm/DebugInfo/DWARFFormValue.h" 00015 #include "llvm/Support/Debug.h" 00016 #include "llvm/Support/Dwarf.h" 00017 #include "llvm/Support/Format.h" 00018 #include "llvm/Support/raw_ostream.h" 00019 using namespace llvm; 00020 using namespace dwarf; 00021 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; 00022 00023 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, 00024 unsigned recurseDepth, 00025 unsigned indent) const { 00026 DataExtractor debug_info_data = u->getDebugInfoExtractor(); 00027 uint32_t offset = Offset; 00028 00029 if (debug_info_data.isValidOffset(offset)) { 00030 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 00031 00032 OS << format("\n0x%8.8x: ", Offset); 00033 if (abbrCode) { 00034 if (AbbrevDecl) { 00035 const char *tagString = TagString(getTag()); 00036 if (tagString) 00037 OS.indent(indent) << tagString; 00038 else 00039 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); 00040 OS << format(" [%u] %c\n", abbrCode, 00041 AbbrevDecl->hasChildren() ? '*' : ' '); 00042 00043 // Dump all data in the DIE for the attributes. 00044 for (const auto &AttrSpec : AbbrevDecl->attributes()) { 00045 dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent); 00046 } 00047 00048 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 00049 if (recurseDepth > 0 && child) { 00050 while (child) { 00051 child->dump(OS, u, recurseDepth-1, indent+2); 00052 child = child->getSibling(); 00053 } 00054 } 00055 } else { 00056 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 00057 << abbrCode << '\n'; 00058 } 00059 } else { 00060 OS.indent(indent) << "NULL\n"; 00061 } 00062 } 00063 } 00064 00065 void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, 00066 const DWARFUnit *u, 00067 uint32_t *offset_ptr, 00068 uint16_t attr, uint16_t form, 00069 unsigned indent) const { 00070 OS << " "; 00071 OS.indent(indent+2); 00072 const char *attrString = AttributeString(attr); 00073 if (attrString) 00074 OS << attrString; 00075 else 00076 OS << format("DW_AT_Unknown_%x", attr); 00077 const char *formString = FormEncodingString(form); 00078 if (formString) 00079 OS << " [" << formString << ']'; 00080 else 00081 OS << format(" [DW_FORM_Unknown_%x]", form); 00082 00083 DWARFFormValue formValue(form); 00084 00085 if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u)) 00086 return; 00087 00088 OS << "\t("; 00089 00090 const char *Name = nullptr; 00091 if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant()) 00092 Name = AttributeValueString(attr, *Val); 00093 00094 if (Name) { 00095 OS << Name; 00096 } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) { 00097 OS << *formValue.getAsUnsignedConstant(); 00098 } else { 00099 formValue.dump(OS, u); 00100 } 00101 00102 OS << ")\n"; 00103 } 00104 00105 bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U, 00106 uint32_t *OffsetPtr) { 00107 Offset = *OffsetPtr; 00108 DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 00109 uint32_t UEndOffset = U->getNextUnitOffset(); 00110 if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) 00111 return false; 00112 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); 00113 if (0 == AbbrCode) { 00114 // NULL debug tag entry. 00115 AbbrevDecl = nullptr; 00116 return true; 00117 } 00118 AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); 00119 if (nullptr == AbbrevDecl) { 00120 // Restore the original offset. 00121 *OffsetPtr = Offset; 00122 return false; 00123 } 00124 ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes( 00125 U->getAddressByteSize(), U->getVersion()); 00126 assert(FixedFormSizes.size() > 0); 00127 00128 // Skip all data in the .debug_info for the attributes 00129 for (const auto &AttrSpec : AbbrevDecl->attributes()) { 00130 uint16_t Form = AttrSpec.Form; 00131 00132 uint8_t FixedFormSize = 00133 (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0; 00134 if (FixedFormSize) 00135 *OffsetPtr += FixedFormSize; 00136 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) { 00137 // Restore the original offset. 00138 *OffsetPtr = Offset; 00139 return false; 00140 } 00141 } 00142 return true; 00143 } 00144 00145 bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const { 00146 return getTag() == DW_TAG_subprogram; 00147 } 00148 00149 bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const { 00150 uint32_t Tag = getTag(); 00151 return Tag == DW_TAG_subprogram || 00152 Tag == DW_TAG_inlined_subroutine; 00153 } 00154 00155 bool DWARFDebugInfoEntryMinimal::getAttributeValue( 00156 const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const { 00157 if (!AbbrevDecl) 00158 return false; 00159 00160 uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr); 00161 if (AttrIdx == -1U) 00162 return false; 00163 00164 DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 00165 uint32_t DebugInfoOffset = getOffset(); 00166 00167 // Skip the abbreviation code so we are at the data for the attributes 00168 DebugInfoData.getULEB128(&DebugInfoOffset); 00169 00170 // Skip preceding attribute values. 00171 for (uint32_t i = 0; i < AttrIdx; ++i) { 00172 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i), 00173 DebugInfoData, &DebugInfoOffset, U); 00174 } 00175 00176 FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx)); 00177 return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U); 00178 } 00179 00180 const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 00181 const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const { 00182 DWARFFormValue FormValue; 00183 if (!getAttributeValue(U, Attr, FormValue)) 00184 return FailValue; 00185 Optional<const char *> Result = FormValue.getAsCString(U); 00186 return Result.hasValue() ? Result.getValue() : FailValue; 00187 } 00188 00189 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( 00190 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 00191 DWARFFormValue FormValue; 00192 if (!getAttributeValue(U, Attr, FormValue)) 00193 return FailValue; 00194 Optional<uint64_t> Result = FormValue.getAsAddress(U); 00195 return Result.hasValue() ? Result.getValue() : FailValue; 00196 } 00197 00198 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant( 00199 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 00200 DWARFFormValue FormValue; 00201 if (!getAttributeValue(U, Attr, FormValue)) 00202 return FailValue; 00203 Optional<uint64_t> Result = FormValue.getAsUnsignedConstant(); 00204 return Result.hasValue() ? Result.getValue() : FailValue; 00205 } 00206 00207 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 00208 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 00209 DWARFFormValue FormValue; 00210 if (!getAttributeValue(U, Attr, FormValue)) 00211 return FailValue; 00212 Optional<uint64_t> Result = FormValue.getAsReference(U); 00213 return Result.hasValue() ? Result.getValue() : FailValue; 00214 } 00215 00216 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset( 00217 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 00218 DWARFFormValue FormValue; 00219 if (!getAttributeValue(U, Attr, FormValue)) 00220 return FailValue; 00221 Optional<uint64_t> Result = FormValue.getAsSectionOffset(); 00222 return Result.hasValue() ? Result.getValue() : FailValue; 00223 } 00224 00225 uint64_t 00226 DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U, 00227 uint64_t FailValue) const { 00228 uint64_t Result = 00229 getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL); 00230 if (Result != -1ULL) 00231 return Result; 00232 return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue); 00233 } 00234 00235 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U, 00236 uint64_t &LowPC, 00237 uint64_t &HighPC) const { 00238 LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL); 00239 if (LowPC == -1ULL) 00240 return false; 00241 HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); 00242 if (HighPC == -1ULL) { 00243 // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case 00244 // it represents function size. 00245 HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL); 00246 if (HighPC != -1ULL) 00247 HighPC += LowPC; 00248 } 00249 return (HighPC != -1ULL); 00250 } 00251 00252 DWARFAddressRangesVector 00253 DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const { 00254 if (isNULL()) 00255 return DWARFAddressRangesVector(); 00256 // Single range specified by low/high PC. 00257 uint64_t LowPC, HighPC; 00258 if (getLowAndHighPC(U, LowPC, HighPC)) { 00259 return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); 00260 } 00261 // Multiple ranges from .debug_ranges section. 00262 uint32_t RangesOffset = 00263 getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U); 00264 if (RangesOffset != -1U) { 00265 DWARFDebugRangeList RangeList; 00266 if (U->extractRangeList(RangesOffset, RangeList)) 00267 return RangeList.getAbsoluteRanges(U->getBaseAddress()); 00268 } 00269 return DWARFAddressRangesVector(); 00270 } 00271 00272 void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges( 00273 const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const { 00274 if (isNULL()) 00275 return; 00276 if (isSubprogramDIE()) { 00277 const auto &DIERanges = getAddressRanges(U); 00278 Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end()); 00279 } 00280 00281 const DWARFDebugInfoEntryMinimal *Child = getFirstChild(); 00282 while (Child) { 00283 Child->collectChildrenAddressRanges(U, Ranges); 00284 Child = Child->getSibling(); 00285 } 00286 } 00287 00288 bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 00289 const DWARFUnit *U, const uint64_t Address) const { 00290 for (const auto& R : getAddressRanges(U)) { 00291 if (R.first <= Address && Address < R.second) 00292 return true; 00293 } 00294 return false; 00295 } 00296 00297 const char * 00298 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, 00299 FunctionNameKind Kind) const { 00300 if (!isSubroutineDIE() || Kind == FunctionNameKind::None) 00301 return nullptr; 00302 // Try to get mangled name only if it was asked for. 00303 if (Kind == FunctionNameKind::LinkageName) { 00304 if (const char *name = 00305 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) 00306 return name; 00307 if (const char *name = 00308 getAttributeValueAsString(U, DW_AT_linkage_name, nullptr)) 00309 return name; 00310 } 00311 if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr)) 00312 return name; 00313 // Try to get name from specification DIE. 00314 uint32_t spec_ref = 00315 getAttributeValueAsReference(U, DW_AT_specification, -1U); 00316 if (spec_ref != -1U) { 00317 DWARFDebugInfoEntryMinimal spec_die; 00318 if (spec_die.extractFast(U, &spec_ref)) { 00319 if (const char *name = spec_die.getSubroutineName(U, Kind)) 00320 return name; 00321 } 00322 } 00323 // Try to get name from abstract origin DIE. 00324 uint32_t abs_origin_ref = 00325 getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); 00326 if (abs_origin_ref != -1U) { 00327 DWARFDebugInfoEntryMinimal abs_origin_die; 00328 if (abs_origin_die.extractFast(U, &abs_origin_ref)) { 00329 if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) 00330 return name; 00331 } 00332 } 00333 return nullptr; 00334 } 00335 00336 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U, 00337 uint32_t &CallFile, 00338 uint32_t &CallLine, 00339 uint32_t &CallColumn) const { 00340 CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0); 00341 CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0); 00342 CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0); 00343 } 00344 00345 DWARFDebugInfoEntryInlinedChain 00346 DWARFDebugInfoEntryMinimal::getInlinedChainForAddress( 00347 const DWARFUnit *U, const uint64_t Address) const { 00348 DWARFDebugInfoEntryInlinedChain InlinedChain; 00349 InlinedChain.U = U; 00350 if (isNULL()) 00351 return InlinedChain; 00352 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) { 00353 // Append current DIE to inlined chain only if it has correct tag 00354 // (e.g. it is not a lexical block). 00355 if (DIE->isSubroutineDIE()) { 00356 InlinedChain.DIEs.push_back(*DIE); 00357 } 00358 // Try to get child which also contains provided address. 00359 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild(); 00360 while (Child) { 00361 if (Child->addressRangeContainsAddress(U, Address)) { 00362 // Assume there is only one such child. 00363 break; 00364 } 00365 Child = Child->getSibling(); 00366 } 00367 DIE = Child; 00368 } 00369 // Reverse the obtained chain to make the root of inlined chain last. 00370 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end()); 00371 return InlinedChain; 00372 }