X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFDebugInfoEntry.cpp;h=2e7a54aeb858b7c7001e3136829ad003433f7d9f;hb=b03916a88b336046be2ed14c61a5e35fa0b2f644;hp=9bb49df5d1309c5cdf661a4aa8b9569b7343c436;hpb=2e56d575b7ea507684935d5cd6d5aee96d72ceb4;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index 9bb49df5d13..2e7a54aeb85 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace dwarf; +typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth, @@ -40,11 +41,8 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, AbbrevDecl->hasChildren() ? '*' : ' '); // Dump all data in the DIE for the attributes. - const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); - for (uint32_t i = 0; i != numAttributes; ++i) { - uint16_t attr = AbbrevDecl->getAttrByIndex(i); - uint16_t form = AbbrevDecl->getFormByIndex(i); - dumpAttribute(OS, u, &offset, attr, form, indent); + for (const auto &AttrSpec : AbbrevDecl->attributes()) { + dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent); } const DWARFDebugInfoEntryMinimal *child = getFirstChild(); @@ -93,77 +91,37 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, } bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U, - const uint8_t *FixedFormSizes, uint32_t *OffsetPtr) { Offset = *OffsetPtr; DataExtractor DebugInfoData = U->getDebugInfoExtractor(); - uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); - if (0 == AbbrCode) { - // NULL debug tag entry. - AbbrevDecl = NULL; - return true; - } - AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); - assert(AbbrevDecl); - assert(FixedFormSizes); // For best performance this should be specified! - - // Skip all data in the .debug_info for the attributes - for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { - uint16_t Form = AbbrevDecl->getFormByIndex(i); - - // FIXME: Currently we're checking if this is less than the last - // entry in the fixed_form_sizes table, but this should be changed - // to use dynamic dispatch. - uint8_t FixedFormSize = - (Form < DW_FORM_ref_sig8) ? FixedFormSizes[Form] : 0; - if (FixedFormSize) - *OffsetPtr += FixedFormSize; - else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, - U)) { - // Restore the original offset. - *OffsetPtr = Offset; - return false; - } - } - return true; -} - -bool DWARFDebugInfoEntryMinimal::extract(const DWARFUnit *U, - uint32_t *OffsetPtr) { - DataExtractor DebugInfoData = U->getDebugInfoExtractor(); - const uint32_t UEndOffset = U->getNextUnitOffset(); - Offset = *OffsetPtr; - if ((Offset >= UEndOffset) || !DebugInfoData.isValidOffset(Offset)) + uint32_t UEndOffset = U->getNextUnitOffset(); + if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) return false; uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); if (0 == AbbrCode) { // NULL debug tag entry. - AbbrevDecl = NULL; + AbbrevDecl = nullptr; return true; } AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); - if (0 == AbbrevDecl) { + if (nullptr == AbbrevDecl) { // Restore the original offset. *OffsetPtr = Offset; return false; } - bool IsCompileUnitTag = (AbbrevDecl->getTag() == DW_TAG_compile_unit); - if (IsCompileUnitTag) - const_cast(U)->setBaseAddress(0); + ArrayRef FixedFormSizes = DWARFFormValue::getFixedFormSizes( + U->getAddressByteSize(), U->getVersion()); + assert(FixedFormSizes.size() > 0); // Skip all data in the .debug_info for the attributes - for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) { - uint16_t Attr = AbbrevDecl->getAttrByIndex(i); - uint16_t Form = AbbrevDecl->getFormByIndex(i); - - if (IsCompileUnitTag && - ((Attr == DW_AT_entry_pc) || (Attr == DW_AT_low_pc))) { - DWARFFormValue FormValue(Form); - if (FormValue.extractValue(DebugInfoData, OffsetPtr, U)) { - if (Attr == DW_AT_low_pc || Attr == DW_AT_entry_pc) - const_cast(U)->setBaseAddress(FormValue.getUnsigned()); - } - } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) { + for (const auto &AttrSpec : AbbrevDecl->attributes()) { + uint16_t Form = AttrSpec.Form; + + uint8_t FixedFormSize = + (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0; + if (FixedFormSize) + *OffsetPtr += FixedFormSize; + else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) { // Restore the original offset. *OffsetPtr = Offset; return false; @@ -210,101 +168,143 @@ bool DWARFDebugInfoEntryMinimal::getAttributeValue( const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString( const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const { DWARFFormValue FormValue; - if (getAttributeValue(U, Attr, FormValue)) - return FormValue.getAsCString(U); - return FailValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsCString(U); + return Result.hasValue() ? Result.getValue() : FailValue; } uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { DWARFFormValue FormValue; - if (getAttributeValue(U, Attr, FormValue)) - return FormValue.getAsAddress(U); - return FailValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsAddress(U); + return Result.hasValue() ? Result.getValue() : FailValue; } -uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( +uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant( const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { DWARFFormValue FormValue; - if (getAttributeValue(U, Attr, FormValue)) - return FormValue.getUnsigned(); - return FailValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsUnsignedConstant(); + return Result.hasValue() ? Result.getValue() : FailValue; } uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { DWARFFormValue FormValue; - if (getAttributeValue(U, Attr, FormValue)) - return FormValue.getReference(U); - return FailValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsReference(U); + return Result.hasValue() ? Result.getValue() : FailValue; +} + +uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset( + const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { + DWARFFormValue FormValue; + if (!getAttributeValue(U, Attr, FormValue)) + return FailValue; + Optional Result = FormValue.getAsSectionOffset(); + return Result.hasValue() ? Result.getValue() : FailValue; +} + +uint64_t +DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U, + uint64_t FailValue) const { + uint64_t Result = + getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL); + if (Result != -1ULL) + return Result; + return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue); } bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC, uint64_t &HighPC) const { - HighPC = -1ULL; LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL); - // FIXME: Check if HighPC is of class constant (it has different semantics). - if (LowPC != -1ULL) - HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); + if (LowPC == -1ULL) + return false; + HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); + if (HighPC == -1ULL) { + // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case + // it represents function size. + HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL); + if (HighPC != -1ULL) + HighPC += LowPC; + } return (HighPC != -1ULL); } -void DWARFDebugInfoEntryMinimal::buildAddressRangeTable( - const DWARFUnit *U, DWARFDebugAranges *DebugAranges, - uint32_t UOffsetInAranges) const { - if (AbbrevDecl) { - if (isSubprogramDIE()) { - uint64_t LowPC, HighPC; - if (getLowAndHighPC(U, LowPC, HighPC)) - DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC); - // FIXME: try to append ranges from .debug_ranges section. - } +DWARFAddressRangesVector +DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const { + if (isNULL()) + return DWARFAddressRangesVector(); + // Single range specified by low/high PC. + uint64_t LowPC, HighPC; + if (getLowAndHighPC(U, LowPC, HighPC)) { + return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); + } + // Multiple ranges from .debug_ranges section. + uint32_t RangesOffset = + getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U); + if (RangesOffset != -1U) { + DWARFDebugRangeList RangeList; + if (U->extractRangeList(RangesOffset, RangeList)) + return RangeList.getAbsoluteRanges(U->getBaseAddress()); + } + return DWARFAddressRangesVector(); +} - const DWARFDebugInfoEntryMinimal *Child = getFirstChild(); - while (Child) { - Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges); - Child = Child->getSibling(); - } +void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges( + const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const { + if (isNULL()) + return; + if (isSubprogramDIE()) { + const auto &DIERanges = getAddressRanges(U); + Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end()); + } + + const DWARFDebugInfoEntryMinimal *Child = getFirstChild(); + while (Child) { + Child->collectChildrenAddressRanges(U, Ranges); + Child = Child->getSibling(); } } bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( const DWARFUnit *U, const uint64_t Address) const { - if (isNULL()) - return false; - uint64_t LowPC, HighPC; - if (getLowAndHighPC(U, LowPC, HighPC)) - return (LowPC <= Address && Address <= HighPC); - // Try to get address ranges from .debug_ranges section. - uint32_t RangesOffset = getAttributeValueAsReference(U, DW_AT_ranges, -1U); - if (RangesOffset != -1U) { - DWARFDebugRangeList RangeList; - if (U->extractRangeList(RangesOffset, RangeList)) - return RangeList.containsAddress(U->getBaseAddress(), Address); + for (const auto& R : getAddressRanges(U)) { + if (R.first <= Address && Address < R.second) + return true; } return false; } const char * -DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { - if (!isSubroutineDIE()) - return 0; - // Try to get mangled name if possible. - if (const char *name = - getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, 0)) - return name; - if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name, 0)) - return name; - if (const char *name = getAttributeValueAsString(U, DW_AT_name, 0)) +DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, + FunctionNameKind Kind) const { + if (!isSubroutineDIE() || Kind == FunctionNameKind::None) + return nullptr; + // Try to get mangled name only if it was asked for. + if (Kind == FunctionNameKind::LinkageName) { + if (const char *name = + getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) + return name; + if (const char *name = + getAttributeValueAsString(U, DW_AT_linkage_name, nullptr)) + return name; + } + if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr)) return name; // Try to get name from specification DIE. uint32_t spec_ref = getAttributeValueAsReference(U, DW_AT_specification, -1U); if (spec_ref != -1U) { DWARFDebugInfoEntryMinimal spec_die; - if (spec_die.extract(U, &spec_ref)) { - if (const char *name = spec_die.getSubroutineName(U)) + if (spec_die.extractFast(U, &spec_ref)) { + if (const char *name = spec_die.getSubroutineName(U, Kind)) return name; } } @@ -313,21 +313,21 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const { getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); if (abs_origin_ref != -1U) { DWARFDebugInfoEntryMinimal abs_origin_die; - if (abs_origin_die.extract(U, &abs_origin_ref)) { - if (const char *name = abs_origin_die.getSubroutineName(U)) + if (abs_origin_die.extractFast(U, &abs_origin_ref)) { + if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) return name; } } - return 0; + return nullptr; } void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U, uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn) const { - CallFile = getAttributeValueAsUnsigned(U, DW_AT_call_file, 0); - CallLine = getAttributeValueAsUnsigned(U, DW_AT_call_line, 0); - CallColumn = getAttributeValueAsUnsigned(U, DW_AT_call_column, 0); + CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0); + CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0); + CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0); } DWARFDebugInfoEntryInlinedChain