forked from OSchip/llvm-project
[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:
parent
0173e024fd
commit
779d24e151
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue