diff options
author | Paul Robinson <paul.robinson@sony.com> | 2017-06-26 18:43:01 +0000 |
---|---|---|
committer | Paul Robinson <paul.robinson@sony.com> | 2017-06-26 18:43:01 +0000 |
commit | 75c068c50bf8ce761b51344ffa09418c280cd27b (patch) | |
tree | 3d9634e7c1388de2b0a6b011bb18307bd24d1f57 /llvm/lib/DebugInfo | |
parent | d58f05179270e38fd7346e8a53a2a915eb27d041 (diff) | |
download | bcm5719-llvm-75c068c50bf8ce761b51344ffa09418c280cd27b.tar.gz bcm5719-llvm-75c068c50bf8ce761b51344ffa09418c280cd27b.zip |
[DWARF] NFC: Collect info used by DWARFFormValue into a helper.
Some forms have sizes that depend on the DWARF version, DWARF format
(32/64-bit), or the size of an address. Collect these into a struct
to simplify passing them around. Require callers to provide one when
they query a form's size.
Differential Revision: http://reviews.llvm.org/D34570
llvm-svn: 306315
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp | 80 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 95 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 32 |
5 files changed, 99 insertions, 150 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index 57eac91f8c1..bb475a669ef 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -65,46 +65,52 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, if (A && F) { Optional<int64_t> V; bool IsImplicitConst = (F == DW_FORM_implicit_const); - if (IsImplicitConst) + if (IsImplicitConst) { V = Data.getSLEB128(OffsetPtr); - else if (auto Size = DWARFFormValue::getFixedByteSize(F)) - V = *Size; - AttributeSpecs.push_back(AttributeSpec(A, F, V)); - if (IsImplicitConst) + AttributeSpecs.push_back(AttributeSpec(A, F, V)); continue; + } // If this abbrevation still has a fixed byte size, then update the // FixedAttributeSize as needed. - if (FixedAttributeSize) { - if (V) - FixedAttributeSize->NumBytes += *V; - else { - switch (F) { - case DW_FORM_addr: - ++FixedAttributeSize->NumAddrs; - break; - - case DW_FORM_ref_addr: - ++FixedAttributeSize->NumRefAddrs; - break; - - case DW_FORM_strp: - case DW_FORM_GNU_ref_alt: - case DW_FORM_GNU_strp_alt: - case DW_FORM_line_strp: - case DW_FORM_sec_offset: - case DW_FORM_strp_sup: - ++FixedAttributeSize->NumDwarfOffsets; - break; - - default: - // Indicate we no longer have a fixed byte size for this - // abbreviation by clearing the FixedAttributeSize optional value - // so it doesn't have a value. - FixedAttributeSize.reset(); - break; - } + switch (F) { + case DW_FORM_addr: + if (FixedAttributeSize) + ++FixedAttributeSize->NumAddrs; + break; + + case DW_FORM_ref_addr: + if (FixedAttributeSize) + ++FixedAttributeSize->NumRefAddrs; + break; + + case DW_FORM_strp: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: + case DW_FORM_line_strp: + case DW_FORM_sec_offset: + case DW_FORM_strp_sup: + if (FixedAttributeSize) + ++FixedAttributeSize->NumDwarfOffsets; + break; + + default: + // The form has a byte size that doesn't depend on Params. + // If it's a fixed size, keep track of it. + if (auto Size = + DWARFFormValue::getFixedByteSize(F, DWARFFormParams())) { + V = *Size; + if (FixedAttributeSize) + FixedAttributeSize->NumBytes += *V; + break; } + // Indicate we no longer have a fixed byte size for this + // abbreviation by clearing the FixedAttributeSize optional value + // so it doesn't have a value. + FixedAttributeSize.reset(); + break; } + // Record this attribute and its fixed size if it has one. + AttributeSpecs.push_back(AttributeSpec(A, F, V)); } else if (A == 0 && F == 0) { // We successfully reached the end of this abbreviation declaration // since both attribute and form are zero. @@ -186,7 +192,8 @@ Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue( if (auto FixedSize = Spec.getByteSize(U)) Offset += *FixedSize; else - DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset, &U); + DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset, + U.getFormParams()); ++AttrIndex; } return None; @@ -211,7 +218,8 @@ Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize( if (ByteSizeOrValue) return ByteSizeOrValue; Optional<int64_t> S; - auto FixedByteSize = DWARFFormValue::getFixedByteSize(Form, &U); + auto FixedByteSize = + DWARFFormValue::getFixedByteSize(Form, U.getFormParams()); if (FixedByteSize) S = *FixedByteSize; return S; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index dbcc64fc083..1551974b822 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -59,7 +59,7 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, // Attribute byte size if fixed, just add the size to the offset. *OffsetPtr += *FixedSize; } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData, - OffsetPtr, &U)) { + OffsetPtr, U.getFormParams())) { // We failed to skip this attribute's value, restore the original offset // and return the failure status. *OffsetPtr = Offset; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 72d8760751d..ad5647f3e03 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -44,11 +44,11 @@ using ContentDescriptors = SmallVector<ContentDescriptor, 4>; DWARFDebugLine::Prologue::Prologue() { clear(); } void DWARFDebugLine::Prologue::clear() { - TotalLength = Version = PrologueLength = 0; - AddressSize = SegSelectorSize = 0; + TotalLength = PrologueLength = 0; + SegSelectorSize = 0; MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; OpcodeBase = 0; - IsDWARF64 = false; + FormParams = DWARFFormParams({0, 0, DWARF32}); StandardOpcodeLengths.clear(); IncludeDirectories.clear(); FileNames.clear(); @@ -57,12 +57,13 @@ void DWARFDebugLine::Prologue::clear() { void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { OS << "Line table prologue:\n" << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength) - << format(" version: %u\n", Version) - << format(Version >= 5 ? " address_size: %u\n" : "", AddressSize) - << format(Version >= 5 ? " seg_select_size: %u\n" : "", SegSelectorSize) - << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) + << format(" version: %u\n", getVersion()); + if (getVersion() >= 5) + OS << format(" address_size: %u\n", getAddressSize()) + << format(" seg_select_size: %u\n", SegSelectorSize); + OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength) << format(" min_inst_length: %u\n", MinInstLength) - << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) + << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) << format(" default_is_stmt: %u\n", DefaultIsStmt) << format(" line_base: %i\n", LineBase) << format(" line_range: %u\n", LineRange) @@ -143,6 +144,7 @@ parseV5EntryFormat(DataExtractor DebugLineData, uint32_t *OffsetPtr, static bool parseV5DirFileTables(DataExtractor DebugLineData, uint32_t *OffsetPtr, uint64_t EndPrologueOffset, + const DWARFFormParams &FormParams, std::vector<StringRef> &IncludeDirectories, std::vector<DWARFDebugLine::FileNameEntry> &FileNames) { // Get the directory entry description. @@ -165,7 +167,7 @@ parseV5DirFileTables(DataExtractor DebugLineData, uint32_t *OffsetPtr, IncludeDirectories.push_back(Value.getAsCString().getValue()); break; default: - if (!Value.skipValue(DebugLineData, OffsetPtr, nullptr)) + if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams)) return false; } } @@ -217,24 +219,26 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor DebugLineData, clear(); TotalLength = DebugLineData.getU32(OffsetPtr); if (TotalLength == UINT32_MAX) { - IsDWARF64 = true; + FormParams.Format = dwarf::DWARF64; TotalLength = DebugLineData.getU64(OffsetPtr); - } else if (TotalLength > 0xffffff00) { + } else if (TotalLength >= 0xffffff00) { return false; } - Version = DebugLineData.getU16(OffsetPtr); - if (Version < 2) + FormParams.Version = DebugLineData.getU16(OffsetPtr); + if (getVersion() < 2) return false; - if (Version >= 5) { - AddressSize = DebugLineData.getU8(OffsetPtr); + if (getVersion() >= 5) { + FormParams.AddrSize = DebugLineData.getU8(OffsetPtr); + assert(getAddressSize() == DebugLineData.getAddressSize() && + "Line table header and data extractor disagree"); SegSelectorSize = DebugLineData.getU8(OffsetPtr); } PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength()); const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr; MinInstLength = DebugLineData.getU8(OffsetPtr); - if (Version >= 4) + if (getVersion() >= 4) MaxOpsPerInst = DebugLineData.getU8(OffsetPtr); DefaultIsStmt = DebugLineData.getU8(OffsetPtr); LineBase = DebugLineData.getU8(OffsetPtr); @@ -247,9 +251,9 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor DebugLineData, StandardOpcodeLengths.push_back(OpLen); } - if (Version >= 5) { + if (getVersion() >= 5) { if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, - IncludeDirectories, FileNames)) { + getFormParams(), IncludeDirectories, FileNames)) { fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 " found an invalid directory or file table description at" diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 39c1f5fd5c5..dda4a0cdb31 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -59,48 +59,13 @@ static const DWARFFormValue::FormClass DWARF4FormClasses[] = { DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present }; -namespace { - -/// A helper class that can be used in DWARFFormValue.cpp functions that need -/// to know the byte size of DW_FORM values that vary in size depending on the -/// DWARF version, address byte size, or DWARF32 or DWARF64. -class FormSizeHelper { - uint16_t Version; - uint8_t AddrSize; - llvm::dwarf::DwarfFormat Format; - -public: - FormSizeHelper(uint16_t V, uint8_t A, llvm::dwarf::DwarfFormat F) - : Version(V), AddrSize(A), Format(F) {} - - uint8_t getAddressByteSize() const { return AddrSize; } - - uint8_t getRefAddrByteSize() const { - if (Version == 2) - return AddrSize; - return getDwarfOffsetByteSize(); - } - - uint8_t getDwarfOffsetByteSize() const { - switch (Format) { - case dwarf::DwarfFormat::DWARF32: - return 4; - case dwarf::DwarfFormat::DWARF64: - return 8; - } - llvm_unreachable("Invalid Format value"); - } -}; - -} // end anonymous namespace - -template <class T> -static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) { +Optional<uint8_t> +DWARFFormValue::getFixedByteSize(dwarf::Form Form, + const DWARFFormParams &Params) { switch (Form) { case DW_FORM_addr: - if (U) - return U->getAddressByteSize(); - return None; + assert(Params.Version && Params.AddrSize && "Invalid Params for form"); + return Params.AddrSize; case DW_FORM_block: // ULEB128 length L followed by L bytes. case DW_FORM_block1: // 1 byte length L followed by L bytes. @@ -121,9 +86,8 @@ static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) { return None; case DW_FORM_ref_addr: - if (U) - return U->getRefAddrByteSize(); - return None; + assert(Params.Version && Params.AddrSize && "Invalid Params for form"); + return Params.getRefAddrByteSize(); case DW_FORM_flag: case DW_FORM_data1: @@ -154,9 +118,8 @@ static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) { case DW_FORM_line_strp: case DW_FORM_sec_offset: case DW_FORM_strp_sup: - if (U) - return U->getDwarfOffsetByteSize(); - return None; + assert(Params.Version && Params.AddrSize && "Invalid Params for form"); + return Params.getDwarfOffsetByteSize(); case DW_FORM_data8: case DW_FORM_ref8: @@ -181,9 +144,9 @@ static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) { return None; } -template <class T> -static bool skipFormValue(dwarf::Form Form, const DataExtractor &DebugInfoData, - uint32_t *OffsetPtr, const T *U) { +bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, + uint32_t *OffsetPtr, + const DWARFFormParams &Params) { bool Indirect = false; do { switch (Form) { @@ -243,7 +206,8 @@ static bool skipFormValue(dwarf::Form Form, const DataExtractor &DebugInfoData, case DW_FORM_line_strp: case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: - if (Optional<uint8_t> FixedSize = ::getFixedByteSize(Form, U)) { + if (Optional<uint8_t> FixedSize = + DWARFFormValue::getFixedByteSize(Form, Params)) { *OffsetPtr += *FixedSize; return true; } @@ -277,19 +241,6 @@ static bool skipFormValue(dwarf::Form Form, const DataExtractor &DebugInfoData, return true; } -Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form Form, - const DWARFUnit *U) { - return ::getFixedByteSize(Form, U); -} - -Optional<uint8_t> -DWARFFormValue::getFixedByteSize(dwarf::Form Form, uint16_t Version, - uint8_t AddrSize, - llvm::dwarf::DwarfFormat Format) { - FormSizeHelper FSH(Version, AddrSize, Format); - return ::getFixedByteSize(Form, &FSH); -} - bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { // First, check DWARF4 form classes. if (Form < makeArrayRef(DWARF4FormClasses).size() && @@ -448,24 +399,6 @@ bool DWARFFormValue::extractValue(const DataExtractor &Data, return true; } -bool DWARFFormValue::skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, - const DWARFUnit *U) const { - return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U); -} - -bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, const DWARFUnit *U) { - return skipFormValue(Form, DebugInfoData, OffsetPtr, U); -} - -bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, uint16_t Version, - uint8_t AddrSize, - llvm::dwarf::DwarfFormat Format) { - FormSizeHelper FSH(Version, AddrSize, Format); - return skipFormValue(Form, DebugInfoData, OffsetPtr, &FSH); -} - void DWARFFormValue::dump(raw_ostream &OS) const { uint64_t UValue = Value.uval; bool CURelativeOffset = false; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index ded9b2abf64..fd9c7c2b1d4 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -62,11 +62,13 @@ DWARFUnit::~DWARFUnit() = default; bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const { - uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize; - if (AddrOffsetSection->Data.size() < Offset + AddrSize) + uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); + if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) return false; - DataExtractor DA(AddrOffsetSection->Data, isLittleEndian, AddrSize); - Result = getRelocatedValue(DA, AddrSize, &Offset, &AddrOffsetSection->Relocs); + DataExtractor DA(AddrOffsetSection->Data, isLittleEndian, + getAddressByteSize()); + Result = getRelocatedValue(DA, getAddressByteSize(), &Offset, + &AddrOffsetSection->Relocs); return true; } @@ -92,15 +94,17 @@ uint64_t DWARFUnit::getStringOffsetSectionRelocation(uint32_t Index) const { bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { Length = debug_info.getU32(offset_ptr); - Version = debug_info.getU16(offset_ptr); + // FIXME: Support DWARF64. + FormParams.Format = DWARF32; + FormParams.Version = debug_info.getU16(offset_ptr); uint64_t AbbrOffset; - if (Version >= 5) { + if (FormParams.Version >= 5) { UnitType = debug_info.getU8(offset_ptr); - AddrSize = debug_info.getU8(offset_ptr); + FormParams.AddrSize = debug_info.getU8(offset_ptr); AbbrOffset = debug_info.getU32(offset_ptr); } else { AbbrOffset = debug_info.getU32(offset_ptr); - AddrSize = debug_info.getU8(offset_ptr); + FormParams.AddrSize = debug_info.getU8(offset_ptr); } if (IndexEntry) { if (AbbrOffset) @@ -115,14 +119,14 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { } bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1); - bool VersionOK = DWARFContext::isSupportedVersion(Version); - bool AddrSizeOK = AddrSize == 4 || AddrSize == 8; + bool VersionOK = DWARFContext::isSupportedVersion(getVersion()); + bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8; if (!LengthOK || !VersionOK || !AddrSizeOK) return false; // Keep track of the highest DWARF version we encounter across all units. - Context.setMaxVersionIfGreater(Version); + Context.setMaxVersionIfGreater(getVersion()); Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); return Abbrevs != nullptr; @@ -148,7 +152,8 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const { // Require that compile unit is extracted. assert(!DieArray.empty()); - DataExtractor RangesData(RangeSection->Data, isLittleEndian, AddrSize); + DataExtractor RangesData(RangeSection->Data, isLittleEndian, + getAddressByteSize()); uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; return RangeList.extract(RangesData, &ActualRangeListOffset, RangeSection->Relocs); @@ -157,9 +162,8 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset, void DWARFUnit::clear() { Offset = 0; Length = 0; - Version = 0; Abbrevs = nullptr; - AddrSize = 0; + FormParams = DWARFFormParams({0, 0, DWARF32}); BaseAddr = 0; RangeSectionBase = 0; AddrOffsetSectionBase = 0; |