[DWARF] Find offset of attribute.

This is used by BOLT to do patching of DebugInfo section, and Line Table. Directly by using find, and through getAttrFieldOffsetForUnit.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D107874
This commit is contained in:
Alexander Yermolovich 2021-09-01 11:13:34 -07:00
parent 0173e024fd
commit 779d24e151
3 changed files with 58 additions and 13 deletions

View File

@ -144,6 +144,27 @@ public:
const dwarf::Attribute Attr,
const DWARFUnit &U) const;
/// Compute an offset from a DIE specified by DIE offset and attribute index.
///
/// \param AttrIndex an index of DWARF attribute.
/// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
/// code in the .debug_info data.
/// \param U the DWARFUnit the contains the DIE.
/// \returns an offset of the attribute.
uint64_t getAttributeOffsetFromIndex(uint32_t AttrIndex, uint64_t DIEOffset,
const DWARFUnit &U) const;
/// Extract a DWARF form value from a DIE speccified by attribute index and
/// its offset.
///
/// \param AttrIndex an index of DWARF attribute.
/// \param Offset offset of the attribute.
/// \param U the DWARFUnit the contains the DIE.
/// \returns Optional DWARF form value if the attribute was extracted.
Optional<DWARFFormValue>
getAttributeValueFromOffset(uint32_t AttrIndex, uint64_t Offset,
const DWARFUnit &U) const;
bool extract(DataExtractor Data, uint64_t* OffsetPtr);
void dump(raw_ostream &OS) const;

View File

@ -147,41 +147,57 @@ DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
return None;
}
Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
const uint64_t DIEOffset, const dwarf::Attribute Attr,
const DWARFUnit &U) const {
// Check if this abbreviation has this attribute without needing to skip
// any data so we can return quickly if it doesn't.
Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
if (!MatchAttrIndex)
return None;
auto DebugInfoData = U.getDebugInfoExtractor();
uint64_t DWARFAbbreviationDeclaration::getAttributeOffsetFromIndex(
uint32_t AttrIndex, uint64_t DIEOffset, const DWARFUnit &U) const {
DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
// Add the byte size of ULEB that for the abbrev Code so we can start
// skipping the attribute data.
uint64_t Offset = DIEOffset + CodeByteSize;
for (uint32_t CurAttrIdx = 0; CurAttrIdx != *MatchAttrIndex; ++CurAttrIdx)
for (uint32_t CurAttrIdx = 0; CurAttrIdx != AttrIndex; ++CurAttrIdx)
// Match Offset along until we get to the attribute we want.
if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
Offset += *FixedSize;
else
DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
&Offset, U.getFormParams());
return Offset;
}
Optional<DWARFFormValue>
DWARFAbbreviationDeclaration::getAttributeValueFromOffset(
uint32_t AttrIndex, uint64_t Offset, const DWARFUnit &U) const {
assert(AttributeSpecs.size() > AttrIndex &&
"Attribute Index is out of bounds.");
// We have arrived at the attribute to extract, extract if from Offset.
const AttributeSpec &Spec = AttributeSpecs[*MatchAttrIndex];
const AttributeSpec &Spec = AttributeSpecs[AttrIndex];
if (Spec.isImplicitConst())
return DWARFFormValue::createFromSValue(Spec.Form,
Spec.getImplicitConstValue());
DWARFFormValue FormValue(Spec.Form);
DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
return FormValue;
return None;
}
Optional<DWARFFormValue>
DWARFAbbreviationDeclaration::getAttributeValue(const uint64_t DIEOffset,
const dwarf::Attribute Attr,
const DWARFUnit &U) const {
// Check if this abbreviation has this attribute without needing to skip
// any data so we can return quickly if it doesn't.
Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
if (!MatchAttrIndex)
return None;
uint64_t Offset = getAttributeOffsetFromIndex(*MatchAttrIndex, DIEOffset, U);
return getAttributeValueFromOffset(*MatchAttrIndex, Offset, U);
}
size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
const DWARFUnit &U) const {
size_t ByteSize = NumBytes;

View File

@ -1783,6 +1783,14 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
auto A = it->getAttrByIndex(0);
EXPECT_EQ(A, Attr);
Optional<uint32_t> AttrIndex = it->findAttributeIndex(A);
EXPECT_TRUE((bool)AttrIndex);
EXPECT_EQ(*AttrIndex, 0u);
uint64_t OffsetVal =
it->getAttributeOffsetFromIndex(*AttrIndex, /* offset */ 0, *U);
EXPECT_TRUE(
it->getAttributeValueFromOffset(*AttrIndex, OffsetVal, *U).hasValue());
auto FormValue = it->getAttributeValue(/* offset */ 0, A, *U);
EXPECT_TRUE((bool)FormValue);
EXPECT_EQ(FormValue->getForm(), dwarf::DW_FORM_implicit_const);